profile
viewpoint

alexcrichton/AudioStreamer 70

A streaming audio player class (AudioStreamer) for Mac OS X and iPhone.

alexcrichton/bzip2-rs 48

libbz2 (bzip2 compression) bindings for Rust

alexcrichton/bufstream 30

A buffered I/O stream for Rust

alexcrichton/brotli2-rs 23

Brotli encoders/decoers for Rust

alexcrichton/ars 1

ar in Rust

alexcrichton/atty 1

are you or are you not a tty?

alexcrichton/binaryen 1

Compiler infrastructure and toolchain library for WebAssembly, in C++

alexcrichton/bzip2-ruby 1

Original libbz2 ruby C bindings from Guy Decoux, with some new love

alexcrichton/1password-teams-open-source 0

Get a free 1Password Teams membership for your open source project

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 91d0ee3ea31b77f1724793c0e0e96c51b798e4b1

Deploy f6d5b8772c90d40e0a7a1e0c0885935a04faf2ca to gh-pages

view details

push time in 3 hours

delete branch alexcrichton/wasmtime

delete branch : compress-mem

delete time in 4 hours

push eventbytecodealliance/wasmtime

Alex Crichton

commit sha f6d5b8772c90d40e0a7a1e0c0885935a04faf2ca

Compress in-memory representation of `FunctionAddressMap` (#2321) This commit compresses `FunctionAddressMap` by performing a simple coalescing of adjacent `InstructionAddressMap` descriptors if they describe the same source location. This is intended to handle the common case where a sequene of machine instructions describes a high-level wasm instruction. For the module on #2318 this reduces the cache entry size from 306MB to 161MB.

view details

push time in 4 hours

PR merged bytecodealliance/wasmtime

Compress in-memory representation of `FunctionAddressMap`

This commit compresses FunctionAddressMap by performing a simple coalescing of adjacent InstructionAddressMap descriptors if they describe the same source location. This is intended to handle the common case where a sequene of machine instructions describes a high-level wasm instruction.

For the module on #2318 this reduces the cache entry size from 306MB to 161MB.

+38 -16

1 comment

1 changed file

alexcrichton

pr closed time in 4 hours

pull request commentrust-lang/compiler-builtins

Set the "asm" feature flag by default

I don't really mind how this works myself, I think it just needs to solve the constraint of "it should be able to compile this crate in libstd without asm!". However that works I don't really mind myself.

If this is enabled by default (as in this PR), is there an example of how to disable this feature as part of building libstd?

josephlr

comment created time in 5 hours

issue commentrustwasm/wasm-bindgen

Unable to export js_name = round unless type is f64

This is a bit unfortunate, but the way linkage and symbols work with LLD and LLVM right now you can't duplicate symbols, and symbols are tied to function exports as well. The round function is actually typically something from libm which provides support for various floating-point operations, and which for Rust is located in the compiler-builtins crate.

Unfortunately there's not really much that can be done about this I think. There's a similar issue with functions named log or similarly. Until a better story is figured out for exporting a function in a wasm module with a different name than the symbol itself our hands here are sort of tied :(

If possible, can a different function be used?

jramsley

comment created time in 5 hours

pull request commentrust-lang/compiler-builtins

math: add {fmin,fmax}{f,} for thumb*-none-eabi*

👍

jordens

comment created time in 6 hours

push eventrust-lang/compiler-builtins

Robert Jördens

commit sha 0f2271e566f78dbe7aa3441c9e497c655592acef

math: add {fmin,fmax}{f,} for thumb*-none-eabi* (#389) These are exposed in core::f32 close #354 c.f. rust-lang/rust#62729 Patch from @whitequark (https://paste.debian.net/1168430/)

view details

push time in 6 hours

PR merged rust-lang/compiler-builtins

math: add {fmin,fmax}{f,} for thumb*-none-eabi*

These are exposed in core::f32

close #354 c.f. rust-lang/rust#62729 Patch from @whitequark (https://paste.debian.net/1168430/)

+4 -0

0 comment

1 changed file

jordens

pr closed time in 6 hours

issue closedrust-lang/compiler-builtins

ARM Thumb targets need fmax*/fmin* intrinsics

core::f32 and core::f64 expose max and min, but these use the fmax*/fmin* intrinsics, which aren't exposed for the Thumb targets https://github.com/rust-lang/compiler-builtins/blob/cde22bc180391e75de1c189fe29f442ada86ccde/src/math.rs#L92-L99

https://rust.godbolt.org/z/B4tB6w

#![no_std]

pub fn maxf(a: f32, b: f32) -> f32 {
    a.max(b)
}

pub fn minf(a: f32, b: f32) -> f32 {
    a.min(b)
}

pub fn max(a: f64, b: f64) -> f64 {
    a.max(b)
}

pub fn min(a: f64, b: f64) -> f64 {
    a.min(b)
}
example::maxf:
        b       fmaxf

example::minf:
        b       fminf

example::max:
        b       fmax

example::min:
        b       fmin

closed time in 6 hours

saleemrashid

push eventrust-lang/flate2-rs

Alex Crichton

commit sha 301e53cc8c08bd1fa34ae7814108ec5e36583416

Clarify performance in README Closes #254

view details

push time in 6 hours

issue closedrust-lang/flate2-rs

Clarify backend performance

The readme says:

The default miniz_oxide backend has the advantage of being pure Rust, but it has relatively low performance.

The crate docs say:

The compression ratios and performance of each of these feature should be roughly comparable

Which one of these is correct?

closed time in 6 hours

mahkoh

pull request commentbytecodealliance/wasmtime

Add an initial wasi-nn implementation for Wasmtime

Seems reasonable to me, but are you thinking we should land all the support in this repository? I may have misunderstood but it sounded like we were shooting instead for landing this as a separate repository with integration hooks provided here.

abrown

comment created time in 6 hours

issue commentrust-lang/flate2-rs

Implement Clone on the GzDecoder

I think it'd be great to implement Clone! I'm not entirely sure if the libz library has support for this, however, so we'd need to make sure all the backends support it.

Kerollmops

comment created time in 6 hours

push eventrust-lang/backtrace-rs

Alex Crichton

commit sha cb8c0618c1438f68b9005e183a3242fbbd4298a2

Refactor gimli implementation to avoid `mk!` macro This commit refactors a bit to avoid using a macro for constructing a `Mapping` and instead adds a dedicated function. This is a bit easier to navigate and will hopefully help deduplicate construction of a `Mapping` as well.

view details

push time in 6 hours

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 58dd5370d7ec789aae4fd9ab65c1a6e79c61bdf5

Deploy 27233857c534a3ae3e9f8fa3a7a3a0fb563e1f4d to gh-pages

view details

push time in 7 hours

PullRequestReviewEvent

delete branch alexcrichton/wasmtime

delete branch : bincode-varint

delete time in 7 hours

push eventbytecodealliance/wasmtime

Alex Crichton

commit sha 27233857c534a3ae3e9f8fa3a7a3a0fb563e1f4d

Encode modules with variable-length integers (#2322) Update `Module::{serialize,deserialize}` to use variable-length integers with `bincode` to make the output artifacts smaller. Locally this reduces the size of #2318 from 160 to 110 MB, a 30% decrease in size! Deserialization performance is slightly slower, but seemingly within the range of noise locally for me.

view details

push time in 7 hours

PR merged bytecodealliance/wasmtime

Encode modules with variable-length integers wasmtime:api

Update Module::{serialize,deserialize} to use variable-length integers with bincode to make the output artifacts smaller. Locally this reduces the size of #2318 from 160 to 110 MB, a 30% decrease in size! Deserialization performance is slightly slower, but seemingly within the range of noise locally for me.

+16 -6

1 comment

1 changed file

alexcrichton

pr closed time in 7 hours

issue openedrust-lang/promote-release

Test with rustup before deploying to production

The automatic deployment process for nightly/beta should look like:

  • Deploy artifacts to dev
  • Download latest rustup
  • Ensure rustup works against artifacts in dev
  • Deploy artifacts to prod

created time in 12 hours

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 450320b176cf630a4418efb93a5fa9a24bbafedf

Deploy c15d9bd61b8c1ac38cf30bf659ac8722298905a3 to gh-pages

view details

push time in 12 hours

PR opened bytecodealliance/wasmtime

Encode modules with variable-length integers

Update Module::{serialize,deserialize} to use variable-length integers with bincode to make the output artifacts smaller. Locally this reduces the size of #2318 from 160 to 110 MB, a 30% decrease in size! Deserialization performance is slightly slower, but seemingly within the range of noise locally for me.

+16 -6

0 comment

1 changed file

pr created time in 21 hours

create barnchalexcrichton/wasmtime

branch : bincode-varint

created branch time in 21 hours

issue commentbytecodealliance/wasmtime

Serialized wasmtime modules are extremely large

Oh and after that PR, the breakdown looks like:

module:                  152817        
obj:                   56236896        
funcs:                 97596780        
  funcs(traps):                24182940
  funcs(address_map):          73224640
  funcs(stack_maps):             189216
data_initializers:      2880584        
unwind_info:            4611040        
total:                161478126        
whitequark

comment created time in a day

issue commentbytecodealliance/wasmtime

Serialized wasmtime modules are extremely large

The cache entry size is effectively the bincode-coded size of this structure, which I believe is roughly analagous to the in-memory size of that structure. Adding some simple instrumentation I was able to get the encoded byte size of each of the fields:

module:                  152817        
obj:                   56236896        
funcs:                242146780        
  funcs(traps):                24182940
  funcs(address_map):         217774640
  funcs(stack_maps):             189216
data_initializers:      2880584        
unwind_info:            4611040        
total:                306028126        

clearly funcs is the massive field (too much so), and the worst offenders are the traps and address_maps maps. Neither of these maps really justifies taking up so much space, and longer-term we need to have a more serious refactoring to probably encode these entirely different in a much more compact fashion. The consumer, however, relies on random-access right now (or at least the ability to do a binary search), so it won't be immediately trivial to restructure these data structures. In the meantime https://github.com/bytecodealliance/wasmtime/pull/2321 should be a band-aid for now to make it a bit more reasonable (although still pretty unreasonable).

I've yet to investigate the Windows discrepancy here, that's quite worrisome too!

whitequark

comment created time in a day

PR opened bytecodealliance/wasmtime

Compress in-memory representation of `FunctionAddressMap`

This commit compresses FunctionAddressMap by performing a simple coalescing of adjacent InstructionAddressMap descriptors if they describe the same source location. This is intended to handle the common case where a sequene of machine instructions describes a high-level wasm instruction.

For the module on #2318 this reduces the cache entry size from 306MB to 161MB.

+38 -16

0 comment

1 changed file

pr created time in a day

create barnchalexcrichton/wasmtime

branch : compress-mem

created branch time in a day

push eventalexcrichton/wasmtime

Alex Crichton

commit sha 1df680d7149b657da4f67ba62c05c90e4e5a2696

Refactor how signatures/trampolines are stored in `Store` This commit refactors where trampolines and signature information is stored within a `Store`, namely moving them from `wasmtime_runtime::Instance` instead to `Store` itself. The goal here is to remove an allocation inside of an `Instance` and make them a bit cheaper to create. Additionally this should open up future possibilities like not creating duplicate trampolines for signatures already in the `Store` when using `Func::new`.

view details

push time in a day

PR opened bytecodealliance/wasmtime

Refactor how signatures/trampolines are stored in `Store`

This commit refactors where trampolines and signature information is stored within a Store, namely moving them from wasmtime_runtime::Instance instead to Store itself. The goal here is to remove an allocation inside of an Instance and make them a bit cheaper to create. Additionally this should open up future possibilities like not creating duplicate trampolines for signatures already in the Store when using Func::new.

+127 -182

0 comment

13 changed files

pr created time in a day

create barnchalexcrichton/wasmtime

branch : remove-trampolines-from-instance

created branch time in a day

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))                 });             }         }-+        if let Some((object_cx, object_addr)) = cx.object.search_object_map(addr as u64) {

I played around with this a bit locally, ideally we'd deduplciate this and the above find_frames loop since I think they're basically identical. Unfortunately I kept running into lifetime errors. It may mean that the lazily-populated map for objects should perhaps use interior mutability, or ideally something like LazyCell, although that's not stable yet.

philipc

comment created time in a day

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 impl<'a> Object<'a> {         let (sym, _addr) = self.syms.get(i)?;         Some(sym)     }++    /// Try to load a context for an object file.+    ///+    /// If dsymutil was not run, then the DWARF may be found in the source object files.+    pub(super) fn search_object_map<'b>(&'b mut self, addr: u64) -> Option<(&Context<'b>, u64)> {+        // `object_map` contains a map from addresses to symbols and object paths.+        // Look up the address and get a mapping for the object.+        let object_map = self.object_map.as_ref()?;+        let symbol = object_map.get(addr)?;+        let object_index = symbol.object_index();+        let mapping = self.object_mappings.get_mut(object_index)?;+        if mapping.is_none() {+            // No cached mapping, so create it.+            *mapping = Some(object_mapping(object_map.objects().get(object_index)?));+        }+        let cx: &'b Context<'static> = &mapping.as_ref()?.as_ref()?.cx;+        // Don't leak the `'static` lifetime, make sure it's scoped to just ourselves.+        let cx = unsafe { core::mem::transmute::<&'b Context<'static>, &'b Context<'b>>(cx) };++        // We must translate the address in order to be able to look it up+        // in the DWARF in the object file.+        let object_symbol = cx.object.syms.iter().find(|sym| sym.0 == symbol.name())?;+        let object_addr = addr+            .wrapping_sub(symbol.address())+            .wrapping_add(object_symbol.1);+        Some((cx, object_addr))+    }+}++fn object_mapping(path: &[u8]) -> Option<Mapping> {+    use super::mystd::ffi::OsStr;+    use super::mystd::os::unix::prelude::*;++    // `N_OSO` symbol names can be either `/path/to/object.o` or `/path/to/archive.a(object.o)`.+    if let Some((archive_path, member_name)) = split_archive_path(path) {+        let map = super::mmap(Path::new(OsStr::from_bytes(archive_path)))?;+        let archive = object::read::archive::ArchiveFile::parse(&map).ok()?;+        for member in archive.members() {+            let member = member.ok()?;+            if member.name() == member_name {+                let (macho, data) = find_header(Bytes(member.data()))?;+                let endian = macho.endian().ok()?;+                let object = Object::parse(macho, endian, data)?;+                let stash = Stash::new();+                let inner = super::cx(&stash, object)?;+                return Some(mk!(Mapping { map, inner, stash }));

After reading this I was hoping that we could deduplicate this construction of a Mapping and I ended up with https://github.com/rust-lang/backtrace-rs/pull/379. I don't think it'll help a ton but it might be good to add a helper somewhere in this file to encapsulate the Object::parse and find_header calls and such.

philipc

comment created time in a day

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 pub struct Object<'a> {     data: Bytes<'a>,     dwarf: Option<&'a [MachSection]>,     syms: Vec<(&'a [u8], u64)>,+    object_map: Option<object::ObjectMap<'a>>,

Mind adding a comment here that this is only for "non object files"?

philipc

comment created time in a day

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 pub struct Object<'a> {     data: Bytes<'a>,     dwarf: Option<&'a [MachSection]>,     syms: Vec<(&'a [u8], u64)>,+    object_map: Option<object::ObjectMap<'a>>,+    object_mappings: Vec<Option<Option<Mapping>>>,

Could this be Box<[...]> to emphasize that it doesn't change?

philipc

comment created time in a day

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 impl<'a> Object<'a> {         let (sym, _addr) = self.syms.get(i)?;         Some(sym)     }++    /// Try to load a context for an object file.+    ///+    /// If dsymutil was not run, then the DWARF may be found in the source object files.+    pub(super) fn search_object_map<'b>(&'b mut self, addr: u64) -> Option<(&Context<'b>, u64)> {+        // `object_map` contains a map from addresses to symbols and object paths.+        // Look up the address and get a mapping for the object.+        let object_map = self.object_map.as_ref()?;+        let symbol = object_map.get(addr)?;+        let object_index = symbol.object_index();+        let mapping = self.object_mappings.get_mut(object_index)?;+        if mapping.is_none() {+            // No cached mapping, so create it.+            *mapping = Some(object_mapping(object_map.objects().get(object_index)?));+        }+        let cx: &'b Context<'static> = &mapping.as_ref()?.as_ref()?.cx;+        // Don't leak the `'static` lifetime, make sure it's scoped to just ourselves.+        let cx = unsafe { core::mem::transmute::<&'b Context<'static>, &'b Context<'b>>(cx) };++        // We must translate the address in order to be able to look it up+        // in the DWARF in the object file.+        let object_symbol = cx.object.syms.iter().find(|sym| sym.0 == symbol.name())?;+        let object_addr = addr+            .wrapping_sub(symbol.address())+            .wrapping_add(object_symbol.1);+        Some((cx, object_addr))+    }+}++fn object_mapping(path: &[u8]) -> Option<Mapping> {+    use super::mystd::ffi::OsStr;+    use super::mystd::os::unix::prelude::*;++    // `N_OSO` symbol names can be either `/path/to/object.o` or `/path/to/archive.a(object.o)`.+    if let Some((archive_path, member_name)) = split_archive_path(path) {+        let map = super::mmap(Path::new(OsStr::from_bytes(archive_path)))?;+        let archive = object::read::archive::ArchiveFile::parse(&map).ok()?;+        for member in archive.members() {+            let member = member.ok()?;+            if member.name() == member_name {+                let (macho, data) = find_header(Bytes(member.data()))?;+                let endian = macho.endian().ok()?;+                let object = Object::parse(macho, endian, data)?;+                let stash = Stash::new();+                let inner = super::cx(&stash, object)?;+                return Some(mk!(Mapping { map, inner, stash }));+            }+        }+        None+    } else {+        let map = super::mmap(Path::new(OsStr::from_bytes(path)))?;+        let (macho, data) = find_header(Bytes(&map))?;+        let endian = macho.endian().ok()?;+        let object = Object::parse(macho, endian, data)?;+        let stash = Stash::new();+        let inner = super::cx(&stash, object)?;+        Some(mk!(Mapping { map, inner, stash }))+    }

Could this be refactored to deduplicate the two branches?

let map;                                                                                    
                                                                                            
// `N_OSO` symbol names can be either `/path/to/object.o` or `/path/to/archive.a(object.o)`.
let data = if let Some((archive_path, member_name)) = split_archive_path(path) {            
    map = super::mmap(Path::new(OsStr::from_bytes(archive_path)))?;                         
    let archive = object::read::archive::ArchiveFile::parse(&map).ok()?;                    
    let member = archive                                                                    
        .members()                                                                          
        .filter_map(|m| m.ok())                                                             
        .find(|m| m.name() == member_name)?;                                                
    Bytes(member.data())                                                                    
} else {                                                                                    
    map = super::mmap(Path::new(OsStr::from_bytes(path)))?;                                 
    Bytes(&map)                                                                             
};                                                                                          
                                                                                            
let (macho, data) = find_header(data)?;                                                     
let endian = macho.endian().ok()?;                                                          
let object = Object::parse(macho, endian, data)?;                                           
let stash = Stash::new();                                                                   
let inner = super::cx(&stash, object)?;                                                     
Some(mk!(Mapping { map, inner, stash }))                                                    
philipc

comment created time in a day

PullRequestReviewEvent
PullRequestReviewEvent

PR opened rust-lang/backtrace-rs

Refactor gimli implementation to avoid `mk!` macro

This commit refactors a bit to avoid using a macro for constructing a Mapping and instead adds a dedicated function. This is a bit easier to navigate and will hopefully help deduplicate construction of a Mapping as well.

+84 -69

0 comment

5 changed files

pr created time in a day

create barnchrust-lang/backtrace-rs

branch : no-macros

created branch time in a day

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 89f725aa8a724d8ac1f35f60dbdd7c7c8393bc00

Deploy fc1cedb2ff43e4b31bcc8f99ef069d5a2d189899 to gh-pages

view details

push time in a day

pull request commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

Er carry on, what this PR does now is exactly what I was thinking 👍

philipc

comment created time in a day

pull request commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

For testing I think yeah -Zrun-dsymutil=no should probably be good enough. I at least don't know how to test much more myself!

Given what you're saying, could perhaps each object file internally have a list of dwarf debug sections, and we have a mapping from the object index to the position in the vector? That way if it's in the original file itself it'll be at index 0, and otherwise later indexes are populated by lazily loading the object indices.

I'm not sure if that makes sense, but I can try pushing up a commit with what I'm thinking if it doesn't.

philipc

comment created time in a day

pull request commentrust-lang/cargo

Remove some unused code.

@bors: r+

ehuss

comment created time in a day

pull request commentbytecodealliance/wasmtime-py

Add bindings for `Module.{serialize,deserialize}`

At this point we haven't put in any effort to optimizing the cache format, so there's likely some low hanging fruit. That being said we'll probably never get as small as the wasm file itself. The default wasmtime implementation also runs zstd compression over the cache object, since it should be pretty compressible (but then time is spent decompressing it).

17 -> 600 is pretty huge though, would you be able to open an issue on the wasmtime repo with the wasm file so we can investigate?

alexcrichton

comment created time in a day

push eventbytecodealliance/wasmtime

Till Schneidereit

commit sha fc1cedb2ff43e4b31bcc8f99ef069d5a2d189899

Add docs.wasmtime.dev as a CNAME for the Wasmtime docs (#2317) * Update version of mdbook used in CI * Configure cname for wasmtime docs

view details

push time in a day

PR merged bytecodealliance/wasmtime

Add docs.wasmtime.dev as a CNAME for the Wasmtime docs wasmtime:docs

As luck would have it, mdbook just recently gained support for configuring a CNAME, so we don't need to manually create the CNAME file in the CI action.

+4 -1

0 comment

2 changed files

tschneidereit

pr closed time in a day

PullRequestReviewEvent

pull request commentbytecodealliance/wasmtime-py

Add bindings for `Module.{serialize,deserialize}`

Nice! Glad it was able to work so well :)

alexcrichton

comment created time in a day

pull request commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

What do you think it would take to not need to be gated?

Oh not much probably! If you'd prefer to land it ungated I don't mind reviewing accordingly. I think though it's nothing really out of the ordinary, just a thorough review, tests, CI, etc.

Yeah, that's the kind of thing I was expecting. By "infinitely-sized", were you expecting that we'd do a linear scan for the object file name?

Would it be possible to have some sort of indexed-by-address map of some sort? I'm not really sure how this debuginfo stuff works, but can we always say that everything within a range of addresses will lie in the same object file? Ideally we could have a Vec of objects which is sorted by the addresses they show up at, and then we can just lookup an address in this list first to find the dwarf info for a symbol. Failing that we could try the main file or loading the object lazily.

philipc

comment created time in 2 days

issue commentrustwasm/wasm-bindgen

General Project Status Update

I personally have been and plan to continue maintaining wasm-bindgen, primarily making sure small enough PRs get merged and bugs get fixed. I have less time/motivation these days for new features, however. I'm not personally developing new features and would find it difficult to review/collaborate on a large new feature.

I would be happy to invite others to help maintain this crate if they'd like, however!

The Rust and WebAssembly Working Group no longer has the vibrance it once had, so there's not necessarily a group of folks helping drive the vision for Rust and WebAssembly. I would be the first to list out the issues we currently have with the various rustwasm repositories we have, but unfortunately I'm not entirely sure of the best way forward. It would probably be good to get some folks on board with helping to maintain the book, but I suspect that wasm-bindgen won't be living inside of this GitHub organization indefinitely.

Perhaps the biggest thing I'd like to fix is better tooling around running the wasm-bindgen CLI. I don't think wasm-pack is living up to its promise and would love to have a replacement tool to suggest. Unfortunately though I don't have the time to pioneer this myself. I worked on cargo-wasi awhile back which I think might be a good template for how a wrapper tool might work, and I've reserved the cargo-wasm name on crates.io if needed, but in any case work needs to be done and we'd have to find someone to do it primarily!

pauldorehill

comment created time in 2 days

push eventbytecodealliance/wasm-tools

Alex Crichton

commit sha 0708a9db4dbb692efe99120d7cad6737ab428300

Add a link to a wabt issue for block to get removed

view details

push time in 2 days

push eventbytecodealliance/wasm-tools

Alex Crichton

commit sha dc01365382d722daf7175c6a92de51c51a856e87

Fix bug where `externref` is used without reference types The `if` cases were swapped by accident!

view details

push time in 2 days

issue commentalexcrichton/socket2-rs

Move to a new home?

I'm not sure, let's find out

alexcrichton

comment created time in 2 days

PullRequestReviewEvent

push eventrust-lang/compiler-builtins

Joseph Richey

commit sha 33ad3669db0ac78a917aee787304d1391b6dc676

Use REP MOVSQ/STOSQ on x86_64 (#365) * mem: Move mem* functions to separate directory Signed-off-by: Joe Richey <joerichey@google.com> * memcpy: Create separate memcpy.rs file Signed-off-by: Joe Richey <joerichey@google.com> * benches: Add benchmarks for mem* functions This allows comparing the "normal" implementations to the implementations provided by this crate. Signed-off-by: Joe Richey <joerichey@google.com> * mem: Add REP MOVSB/STOSB implementations The assembly generated seems correct: https://rust.godbolt.org/z/GGnec8 Signed-off-by: Joe Richey <joerichey@google.com> * mem: Add documentations for REP string insturctions Signed-off-by: Joe Richey <joerichey@google.com> * Use quad-word rep string instructions Signed-off-by: Joe Richey <joerichey@google.com> * Prevent panic when compiled in debug mode Signed-off-by: Joe Richey <joerichey@google.com> * Add tests for mem* functions Signed-off-by: Joe Richey <joerichey@google.com> * Add build/test with the "asm" feature Signed-off-by: Joe Richey <joerichey@google.com> * Add byte length to Bencher Signed-off-by: Joe Richey <joerichey@google.com>

view details

push time in 2 days

PR merged rust-lang/compiler-builtins

Use REP MOVSQ/STOSQ on x86_64

Addresses part of #339 (see also https://github.com/rust-osdev/cargo-xbuild/issues/77)

The implementations for these functions are quite simple and (on many recent processors) are the fastest way to implement memcpy/memmove/memset. The implementations in MUSL and in the Linux kernel were used for inspiration.

Benchmarks for the memory functions were also added in this PR, and can be invoked by running cargo bench --package=testcrate. The results of running this benchmarks on different hardware show that the qword-based variants are almost always faster than the byte-based variants.

While the implementations for memcmp/bcmp could be made faster though use of SIMD intrinsics, using rep cmpsb/rep cmpsq makes them slower, so they are left as-is in this PR.

Note that #164 added some optimized versions for memcmp on ARM.

+423 -39

27 comments

6 changed files

josephlr

pr closed time in 2 days

pull request commentrust-lang/compiler-builtins

Use REP MOVSQ/STOSQ on x86_64

Hm yeah ideally that would change but that's probably best left to another PR, thanks again!

josephlr

comment created time in 2 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 8790dad64ff5b0f4328bb38ad92f572a1d1324da

Deploy 6ebbab61b92de0d79b263469a163cfb88c7e4ae6 to gh-pages

view details

push time in 3 days

PullRequestReviewEvent

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 9cb8684d581d752d901ad185130665f648c18901

Deploy de4af90af661e4c186c181aeeed41b8b7d60a1ec to gh-pages

view details

push time in 3 days

Pull request review commentrust-lang/cargo

New namespaced features implementation.

 where             .push(dep);     } -    let mut map = BTreeMap::new();-    for (feature, list) in features.iter() {-        // If namespaced features is active and the key is the same as that of an-        // optional dependency, that dependency must be included in the values.-        // Thus, if a `feature` is found that has the same name as a dependency, we-        // (a) bail out if the dependency is non-optional, and (b) we track if the-        // feature requirements include the dependency `crate:feature` in the list.-        // This is done with the `dependency_found` variable, which can only be-        // false if features are namespaced and the current feature key is the same-        // as the name of an optional dependency. If so, it gets set to true during-        // iteration over the list if the dependency is found in the list.-        let mut dependency_found = if namespaced {-            match dep_map.get(feature.borrow()) {-                Some(dep_data) => {-                    if !dep_data.iter().any(|d| d.is_optional()) {-                        anyhow::bail!(-                            "Feature `{}` includes the dependency of the same name, but this is \-                             left implicit in the features included by this feature.\n\-                             Additionally, the dependency must be marked as optional to be \-                             included in the feature definition.\n\-                             Consider adding `crate:{}` to this feature's requirements \-                             and marking the dependency as `optional = true`",-                            feature,-                            feature-                        )-                    } else {-                        false-                    }-                }-                None => true,-            }-        } else {-            true+    let mut map: FeatureMap = features+        .iter()+        .map(|(feature, list)| {+            let fvs: Vec<_> = list+                .iter()+                .map(|feat_value| FeatureValue::new(*feat_value))+                .collect();+            (*feature, fvs)+        })+        .collect();+    let has_namespaced_features = map.values().flatten().any(|fv| fv.is_explicit_crate());++    // Add implicit features for optional dependencies if they weren't+    // explicitly listed anywhere.+    let explicitly_listed: HashSet<_> = map+        .values()+        .flatten()+        .filter_map(|fv| match fv {+            Crate { dep_name }+            | CrateFeature {+                dep_name,+                explicit: true,+                ..+            } => Some(*dep_name),+            _ => None,+        })+        .collect();+    for dep in dependencies {+        if !dep.is_optional() {+            continue;+        }+        let dep_name_in_toml = dep.name_in_toml();+        if features.contains_key(&dep_name_in_toml) || explicitly_listed.contains(&dep_name_in_toml)+        {+            continue;+        }+        let fv = Crate {+            dep_name: dep_name_in_toml,         };+        map.insert(dep_name_in_toml, vec![fv]);+    } -        let mut values = vec![];-        for dep in list {-            let val = FeatureValue::build(-                InternedString::new(dep.as_ref()),-                |fs| features.contains_key(fs.as_str()),-                namespaced,+    // Validate features are listed properly.+    for (feature, fvs) in &map {+        if feature.starts_with("crate:") {+            bail!(+                "feature named `{}` is not allowed to start with `crate:`",+                feature             );-+        }+        for fv in fvs {             // Find data for the referenced dependency...             let dep_data = {-                match val {-                    Feature(ref dep_name) | Crate(ref dep_name) | CrateFeature(ref dep_name, _) => {-                        dep_map.get(dep_name.as_str())+                match fv {+                    Feature(dep_name) | Crate { dep_name, .. } | CrateFeature { dep_name, .. } => {+                        dep_map.get(dep_name)                     }                 }             };             let is_optional_dep = dep_data                 .iter()                 .flat_map(|d| d.iter())                 .any(|d| d.is_optional());-            if let FeatureValue::Crate(ref dep_name) = val {-                // If we have a dependency value, check if this is the dependency named-                // the same as the feature that we were looking for.-                if !dependency_found && feature.borrow() == dep_name.as_str() {-                    dependency_found = true;-                }-            }--            match (&val, dep_data.is_some(), is_optional_dep) {-                // The value is a feature. If features are namespaced, this just means-                // it's not prefixed with `crate:`, so we have to check whether the-                // feature actually exist. If the feature is not defined *and* an optional-                // dependency of the same name exists, the feature is defined implicitly-                // here by adding it to the feature map, pointing to the dependency.-                // If features are not namespaced, it's been validated as a feature already-                // while instantiating the `FeatureValue` in `FeatureValue::build()`, so-                // we don't have to do so here.-                (&Feature(feat), _, true) => {-                    if namespaced && !features.contains_key(&*feat) {-                        map.insert(feat, vec![FeatureValue::Crate(feat)]);-                    }-                }-                // If features are namespaced and the value is not defined as a feature-                // and there is no optional dependency of the same name, error out.-                // If features are not namespaced, there must be an existing feature-                // here (checked by `FeatureValue::build()`), so it will always be defined.-                (&Feature(feat), dep_exists, false) => {-                    if namespaced && !features.contains_key(&*feat) {-                        if dep_exists {-                            anyhow::bail!(-                                "Feature `{}` includes `{}` which is not defined as a feature.\n\-                                 A non-optional dependency of the same name is defined; consider \-                                 adding `optional = true` to its definition",+            let is_any_dep = dep_data.is_some();+            match fv {+                Feature(f) => {+                    if !features.contains_key(f) {+                        if !is_any_dep {+                            bail!(+                                "feature `{}` includes `{}` which is neither a dependency \+                                 nor another feature",                                 feature,-                                feat-                            )+                                fv+                            );+                        }+                        if is_optional_dep {+                            if !map.contains_key(f) {+                                bail!(+                                    "feature `{}` includes `{}`, but `{}` is an \+                                     optional dependency without an implicit feature\n\+                                     Use `crate:{}` to enable the dependency.",+                                    feature,+                                    fv,+                                    f,+                                    f+                                );+                            }                         } else {-                            anyhow::bail!(-                                "Feature `{}` includes `{}` which is not defined as a feature",-                                feature,-                                feat-                            )+                            bail!("feature `{}` includes `{}`, but `{}` is not an optional dependency\n\+                                A non-optional dependency of the same name is defined; \+                                consider adding `optional = true` to its definition.",+                                feature, fv, f);                         }                     }                 }-                // The value is a dependency. If features are namespaced, it is explicitly-                // tagged as such (`crate:value`). If features are not namespaced, any value-                // not recognized as a feature is pegged as a `Crate`. Here we handle the case-                // where the dependency exists but is non-optional. It branches on namespaced-                // just to provide the correct string for the crate dependency in the error.-                (&Crate(ref dep), true, false) => {-                    if namespaced {-                        anyhow::bail!(-                            "Feature `{}` includes `crate:{}` which is not an \-                             optional dependency.\nConsider adding \-                             `optional = true` to the dependency",+                Crate { dep_name } => {+                    if !is_any_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not listed as a dependency",                             feature,-                            dep-                        )-                    } else {-                        anyhow::bail!(-                            "Feature `{}` depends on `{}` which is not an \-                             optional dependency.\nConsider adding \-                             `optional = true` to the dependency",+                            fv,+                            dep_name+                        );+                    }+                    if !is_optional_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not an optional dependency\n\+                             A non-optional dependency of the same name is defined; \+                             consider adding `optional = true` to its definition.",                             feature,-                            dep-                        )+                            fv,+                            dep_name+                        );                     }                 }-                // If namespaced, the value was tagged as a dependency; if not namespaced,-                // this could be anything not defined as a feature. This handles the case-                // where no such dependency is actually defined; again, the branch on-                // namespaced here is just to provide the correct string in the error.-                (&Crate(ref dep), false, _) => {-                    if namespaced {-                        anyhow::bail!(-                            "Feature `{}` includes `crate:{}` which is not a known \-                             dependency",-                            feature,-                            dep-                        )-                    } else {-                        anyhow::bail!(-                            "Feature `{}` includes `{}` which is neither a dependency nor \-                             another feature",+                CrateFeature { dep_name, .. } => {+                    // Validation of the feature name will be performed in the resolver.+                    if !is_any_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not a dependency",                             feature,-                            dep-                        )+                            fv,+                            dep_name+                        );                     }                 }-                (&Crate(_), true, true) => {}-                // If the value is a feature for one of the dependencies, bail out if no such-                // dependency is actually defined in the manifest.-                (&CrateFeature(ref dep, _), false, _) => anyhow::bail!(-                    "Feature `{}` requires a feature of `{}` which is not a \-                     dependency",-                    feature,-                    dep-                ),-                (&CrateFeature(_, _), true, _) => {}             }-            values.push(val);-        }--        if !dependency_found {-            // If we have not found the dependency of the same-named feature, we should-            // bail here.-            anyhow::bail!(-                "Feature `{}` includes the optional dependency of the \-                 same name, but this is left implicit in the features \-                 included by this feature.\nConsider adding \-                 `crate:{}` to this feature's requirements.",-                feature,-                feature-            )         }+    } -        map.insert(InternedString::new(feature.borrow()), values);+    // Make sure every optional dep is mentioned at least once.+    let used: HashSet<_> = map+        .values()+        .flatten()+        .filter_map(|fv| match fv {+            Crate { dep_name } | CrateFeature { dep_name, .. } => Some(dep_name),+            _ => None,+        })+        .collect();+    if let Some(dep) = dependencies+        .iter()+        .find(|dep| dep.is_optional() && !used.contains(&dep.name_in_toml()))+    {+        bail!(+            "optional dependency `{}` is not included in any feature\n\+            Make sure that `crate:{}` is included in one of features in the [features] table.",+            dep.name_in_toml(),+            dep.name_in_toml(),+        );     }-    Ok(map)++    Ok((map, has_namespaced_features)) } -/// FeatureValue represents the types of dependencies a feature can have:-///-/// * Another feature-/// * An optional dependency-/// * A feature in a dependency-///-/// The selection between these 3 things happens as part of the construction of the FeatureValue.+/// FeatureValue represents the types of dependencies a feature can have. #[derive(Clone, Debug)] pub enum FeatureValue {+    /// A feature enabling another feature.     Feature(InternedString),-    Crate(InternedString),-    CrateFeature(InternedString, InternedString),+    /// A feature enabling a dependency with `crate:dep_name` syntax.+    Crate { dep_name: InternedString },+    /// A feature enabling a feature on a dependency with `crate_name/feat_name` syntax.+    CrateFeature {+        dep_name: InternedString,+        dep_feature: InternedString,+        /// If this is true, then the feature used the `crate:` prefix, which+        /// prevents enabling the feature named `dep_name`.+        explicit: bool,

The term explicit here seemed a bit confusing to me given this documentation of what it means, perhaps something like crate_prefix or something like that?

ehuss

comment created time in 3 days

Pull request review commentrust-lang/cargo

New namespaced features implementation.

 where             .push(dep);     } -    let mut map = BTreeMap::new();-    for (feature, list) in features.iter() {-        // If namespaced features is active and the key is the same as that of an-        // optional dependency, that dependency must be included in the values.-        // Thus, if a `feature` is found that has the same name as a dependency, we-        // (a) bail out if the dependency is non-optional, and (b) we track if the-        // feature requirements include the dependency `crate:feature` in the list.-        // This is done with the `dependency_found` variable, which can only be-        // false if features are namespaced and the current feature key is the same-        // as the name of an optional dependency. If so, it gets set to true during-        // iteration over the list if the dependency is found in the list.-        let mut dependency_found = if namespaced {-            match dep_map.get(feature.borrow()) {-                Some(dep_data) => {-                    if !dep_data.iter().any(|d| d.is_optional()) {-                        anyhow::bail!(-                            "Feature `{}` includes the dependency of the same name, but this is \-                             left implicit in the features included by this feature.\n\-                             Additionally, the dependency must be marked as optional to be \-                             included in the feature definition.\n\-                             Consider adding `crate:{}` to this feature's requirements \-                             and marking the dependency as `optional = true`",-                            feature,-                            feature-                        )-                    } else {-                        false-                    }-                }-                None => true,-            }-        } else {-            true+    let mut map: FeatureMap = features+        .iter()+        .map(|(feature, list)| {+            let fvs: Vec<_> = list+                .iter()+                .map(|feat_value| FeatureValue::new(*feat_value))+                .collect();+            (*feature, fvs)+        })+        .collect();+    let has_namespaced_features = map.values().flatten().any(|fv| fv.is_explicit_crate());++    // Add implicit features for optional dependencies if they weren't+    // explicitly listed anywhere.+    let explicitly_listed: HashSet<_> = map+        .values()+        .flatten()+        .filter_map(|fv| match fv {+            Crate { dep_name }+            | CrateFeature {+                dep_name,+                explicit: true,+                ..+            } => Some(*dep_name),+            _ => None,+        })+        .collect();+    for dep in dependencies {+        if !dep.is_optional() {+            continue;+        }+        let dep_name_in_toml = dep.name_in_toml();+        if features.contains_key(&dep_name_in_toml) || explicitly_listed.contains(&dep_name_in_toml)+        {+            continue;+        }+        let fv = Crate {+            dep_name: dep_name_in_toml,         };+        map.insert(dep_name_in_toml, vec![fv]);+    } -        let mut values = vec![];-        for dep in list {-            let val = FeatureValue::build(-                InternedString::new(dep.as_ref()),-                |fs| features.contains_key(fs.as_str()),-                namespaced,+    // Validate features are listed properly.+    for (feature, fvs) in &map {+        if feature.starts_with("crate:") {+            bail!(+                "feature named `{}` is not allowed to start with `crate:`",+                feature             );-+        }+        for fv in fvs {             // Find data for the referenced dependency...             let dep_data = {-                match val {-                    Feature(ref dep_name) | Crate(ref dep_name) | CrateFeature(ref dep_name, _) => {-                        dep_map.get(dep_name.as_str())+                match fv {+                    Feature(dep_name) | Crate { dep_name, .. } | CrateFeature { dep_name, .. } => {+                        dep_map.get(dep_name)                     }                 }             };             let is_optional_dep = dep_data                 .iter()                 .flat_map(|d| d.iter())                 .any(|d| d.is_optional());-            if let FeatureValue::Crate(ref dep_name) = val {-                // If we have a dependency value, check if this is the dependency named-                // the same as the feature that we were looking for.-                if !dependency_found && feature.borrow() == dep_name.as_str() {-                    dependency_found = true;-                }-            }--            match (&val, dep_data.is_some(), is_optional_dep) {-                // The value is a feature. If features are namespaced, this just means-                // it's not prefixed with `crate:`, so we have to check whether the-                // feature actually exist. If the feature is not defined *and* an optional-                // dependency of the same name exists, the feature is defined implicitly-                // here by adding it to the feature map, pointing to the dependency.-                // If features are not namespaced, it's been validated as a feature already-                // while instantiating the `FeatureValue` in `FeatureValue::build()`, so-                // we don't have to do so here.-                (&Feature(feat), _, true) => {-                    if namespaced && !features.contains_key(&*feat) {-                        map.insert(feat, vec![FeatureValue::Crate(feat)]);-                    }-                }-                // If features are namespaced and the value is not defined as a feature-                // and there is no optional dependency of the same name, error out.-                // If features are not namespaced, there must be an existing feature-                // here (checked by `FeatureValue::build()`), so it will always be defined.-                (&Feature(feat), dep_exists, false) => {-                    if namespaced && !features.contains_key(&*feat) {-                        if dep_exists {-                            anyhow::bail!(-                                "Feature `{}` includes `{}` which is not defined as a feature.\n\-                                 A non-optional dependency of the same name is defined; consider \-                                 adding `optional = true` to its definition",+            let is_any_dep = dep_data.is_some();+            match fv {+                Feature(f) => {+                    if !features.contains_key(f) {+                        if !is_any_dep {+                            bail!(+                                "feature `{}` includes `{}` which is neither a dependency \+                                 nor another feature",                                 feature,-                                feat-                            )+                                fv+                            );+                        }+                        if is_optional_dep {+                            if !map.contains_key(f) {+                                bail!(+                                    "feature `{}` includes `{}`, but `{}` is an \+                                     optional dependency without an implicit feature\n\+                                     Use `crate:{}` to enable the dependency.",+                                    feature,+                                    fv,+                                    f,+                                    f+                                );+                            }                         } else {-                            anyhow::bail!(-                                "Feature `{}` includes `{}` which is not defined as a feature",-                                feature,-                                feat-                            )+                            bail!("feature `{}` includes `{}`, but `{}` is not an optional dependency\n\+                                A non-optional dependency of the same name is defined; \+                                consider adding `optional = true` to its definition.",+                                feature, fv, f);                         }                     }                 }-                // The value is a dependency. If features are namespaced, it is explicitly-                // tagged as such (`crate:value`). If features are not namespaced, any value-                // not recognized as a feature is pegged as a `Crate`. Here we handle the case-                // where the dependency exists but is non-optional. It branches on namespaced-                // just to provide the correct string for the crate dependency in the error.-                (&Crate(ref dep), true, false) => {-                    if namespaced {-                        anyhow::bail!(-                            "Feature `{}` includes `crate:{}` which is not an \-                             optional dependency.\nConsider adding \-                             `optional = true` to the dependency",+                Crate { dep_name } => {+                    if !is_any_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not listed as a dependency",                             feature,-                            dep-                        )-                    } else {-                        anyhow::bail!(-                            "Feature `{}` depends on `{}` which is not an \-                             optional dependency.\nConsider adding \-                             `optional = true` to the dependency",+                            fv,+                            dep_name+                        );+                    }+                    if !is_optional_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not an optional dependency\n\+                             A non-optional dependency of the same name is defined; \+                             consider adding `optional = true` to its definition.",                             feature,-                            dep-                        )+                            fv,+                            dep_name+                        );                     }                 }-                // If namespaced, the value was tagged as a dependency; if not namespaced,-                // this could be anything not defined as a feature. This handles the case-                // where no such dependency is actually defined; again, the branch on-                // namespaced here is just to provide the correct string in the error.-                (&Crate(ref dep), false, _) => {-                    if namespaced {-                        anyhow::bail!(-                            "Feature `{}` includes `crate:{}` which is not a known \-                             dependency",-                            feature,-                            dep-                        )-                    } else {-                        anyhow::bail!(-                            "Feature `{}` includes `{}` which is neither a dependency nor \-                             another feature",+                CrateFeature { dep_name, .. } => {+                    // Validation of the feature name will be performed in the resolver.+                    if !is_any_dep {+                        bail!(+                            "feature `{}` includes `{}`, but `{}` is not a dependency",                             feature,-                            dep-                        )+                            fv,+                            dep_name+                        );                     }                 }-                (&Crate(_), true, true) => {}-                // If the value is a feature for one of the dependencies, bail out if no such-                // dependency is actually defined in the manifest.-                (&CrateFeature(ref dep, _), false, _) => anyhow::bail!(-                    "Feature `{}` requires a feature of `{}` which is not a \-                     dependency",-                    feature,-                    dep-                ),-                (&CrateFeature(_, _), true, _) => {}             }-            values.push(val);-        }--        if !dependency_found {-            // If we have not found the dependency of the same-named feature, we should-            // bail here.-            anyhow::bail!(-                "Feature `{}` includes the optional dependency of the \-                 same name, but this is left implicit in the features \-                 included by this feature.\nConsider adding \-                 `crate:{}` to this feature's requirements.",-                feature,-                feature-            )         }+    } -        map.insert(InternedString::new(feature.borrow()), values);+    // Make sure every optional dep is mentioned at least once.+    let used: HashSet<_> = map+        .values()+        .flatten()+        .filter_map(|fv| match fv {+            Crate { dep_name } | CrateFeature { dep_name, .. } => Some(dep_name),+            _ => None,+        })+        .collect();+    if let Some(dep) = dependencies+        .iter()+        .find(|dep| dep.is_optional() && !used.contains(&dep.name_in_toml()))+    {+        bail!(+            "optional dependency `{}` is not included in any feature\n\+            Make sure that `crate:{}` is included in one of features in the [features] table.",+            dep.name_in_toml(),+            dep.name_in_toml(),+        );     }-    Ok(map)++    Ok((map, has_namespaced_features)) } -/// FeatureValue represents the types of dependencies a feature can have:-///-/// * Another feature-/// * An optional dependency-/// * A feature in a dependency-///-/// The selection between these 3 things happens as part of the construction of the FeatureValue.+/// FeatureValue represents the types of dependencies a feature can have. #[derive(Clone, Debug)] pub enum FeatureValue {+    /// A feature enabling another feature.     Feature(InternedString),-    Crate(InternedString),-    CrateFeature(InternedString, InternedString),+    /// A feature enabling a dependency with `crate:dep_name` syntax.+    Crate { dep_name: InternedString },+    /// A feature enabling a feature on a dependency with `crate_name/feat_name` syntax.+    CrateFeature {+        dep_name: InternedString,+        dep_feature: InternedString,+        /// If this is true, then the feature used the `crate:` prefix, which+        /// prevents enabling the feature named `dep_name`.+        explicit: bool,+    }, }  impl FeatureValue {-    fn build<T>(feature: InternedString, is_feature: T, namespaced: bool) -> FeatureValue-    where-        T: Fn(InternedString) -> bool,-    {-        match (feature.find('/'), namespaced) {-            (Some(pos), _) => {+    pub fn new(feature: InternedString) -> FeatureValue {+        match feature.find('/') {+            Some(pos) => {                 let (dep, dep_feat) = feature.split_at(pos);                 let dep_feat = &dep_feat[1..];-                FeatureValue::CrateFeature(InternedString::new(dep), InternedString::new(dep_feat))-            }-            (None, true) if feature.starts_with("crate:") => {-                FeatureValue::Crate(InternedString::new(&feature[6..]))-            }-            (None, true) => FeatureValue::Feature(feature),-            (None, false) if is_feature(feature) => FeatureValue::Feature(feature),-            (None, false) => FeatureValue::Crate(feature),-        }-    }--    pub fn new(feature: InternedString, s: &Summary) -> FeatureValue {-        Self::build(-            feature,-            |fs| s.features().contains_key(&fs),-            s.namespaced_features(),-        )-    }--    pub fn to_string(&self, s: &Summary) -> String {-        use self::FeatureValue::*;-        match *self {-            Feature(ref f) => f.to_string(),-            Crate(ref c) => {-                if s.namespaced_features() {-                    format!("crate:{}", &c)+                let (dep, explicit) = if dep.starts_with("crate:") {

I think strip_prefix is a stable thing to use now?

ehuss

comment created time in 3 days

Pull request review commentrust-lang/cargo

New namespaced features implementation.

+//! Tests for namespaced features.++use cargo_test_support::project;+use cargo_test_support::registry::{Dependency, Package};++#[cargo_test]+fn gated() {+    // Need namespaced-features to use `crate:` syntax.+    Package::new("bar", "1.0.0").publish();+    let p = project()+        .file(+            "Cargo.toml",+            r#"+                [package]+                name = "foo"+                version = "0.1.0"++                [dependencies]+                bar = { version = "1.0", optional = true }++                [features]+                foo = ["crate:bar"]+            "#,+        )+        .file("src/lib.rs", "")+        .build();++    p.cargo("check")+        .with_status(101)+        .with_stderr(+            "\+[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`++Caused by:+  namespaced features with the `crate:` prefix are only allowed on the nightly channel \+  and requires the `-Z namespaced-features` flag on the command-line+",+        )+        .run();+}++#[cargo_test]+fn dependency_gate_ignored() {+    // Dependencies with `crate:` features are ignored in the registry if not on nightly.+    Package::new("baz", "1.0.0").publish();+    Package::new("bar", "1.0.0")+        .add_dep(Dependency::new("baz", "1.0").optional(true))+        .feature("feat", &["crate:baz"])+        .publish();+    let p = project()+        .file(+            "Cargo.toml",+            r#"+                [package]+                name = "foo"+                version = "0.1.0"++                [dependencies]+                bar = "1.0"+            "#,+        )+        .file("src/lib.rs", "")+        .build();++    p.cargo("check")+        .masquerade_as_nightly_cargo()+        .with_status(101)+        .with_stderr(+            "\+[UPDATING] [..]+[ERROR] no matching package named `bar` found+location searched: registry `https://github.com/rust-lang/crates.io-index`+required by package `foo v0.1.0 ([..]/foo)`+",+        )+        .run();++    // Publish a version without namespaced features, it should ignore 1.0.0+    // an use this instead.+    Package::new("bar", "1.0.1")+        .add_dep(Dependency::new("baz", "1.0").optional(true))+        .feature("feat", &["baz"])+        .publish();+    p.cargo("check")+        .masquerade_as_nightly_cargo()+        .with_stderr(+            "\+[UPDATING] [..]+[DOWNLOADING] crates ...+[DOWNLOADED] bar [..]+[CHECKING] bar v1.0.1+[CHECKING] foo v0.1.0 [..]+[FINISHED] [..]+",+        )+        .run();+}++#[cargo_test]+fn dependency_with_crate_syntax() {+    // Registry dependency uses crate: syntax.+    Package::new("baz", "1.0.0").publish();+    Package::new("bar", "1.0.0")+        .add_dep(Dependency::new("baz", "1.0").optional(true))+        .feature("feat", &["crate:baz"])

As a reminder to us, crates.io probably rejects this syntax today in the frontend so we'll likely need to update that to publish packages like this.

ehuss

comment created time in 3 days

Pull request review commentrust-lang/cargo

New namespaced features implementation.

 impl<'a, 'cfg> FeatureResolver<'a, 'cfg> {                         }                         if dep.is_optional() {                             // Activate the crate on self.-                            let fv = FeatureValue::Crate(*dep_name);+                            let fv = FeatureValue::Crate {+                                dep_name: *dep_name,+                                // explicit: *explicit,

leftover?

ehuss

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent
PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-lang/backtrace-rs

Support Mach-O backtraces without dsymutil

 impl<'a> Object<'a> {         let (sym, _addr) = self.syms.get(i)?;         Some(sym)     }++    pub(super) fn object_mapping(&self, addr: u64) -> Option<(Mapping, u64)> {+        let object_map = self.object_map.as_ref()?;+        let symbol = object_map.get(addr)?;+        let object_path = symbol.object(object_map);+        if let Some((archive_path, member_name)) = split(object_path) {+            let map = super::mmap(Path::new(archive_path))?;+            let archive = object::read::archive::ArchiveFile::parse(&map).ok()?;+            let mut members = archive.members();+            while let Ok(Some(member)) = members.next() {+                if member.name() == member_name.as_bytes() {+                    let (macho, data) = find_header(Bytes(member.data()))?;+                    let endian = macho.endian().ok()?;+                    let object = Object::parse(macho, endian, data)?;+                    for object_symbol in &object.syms {+                        if object_symbol.0 == symbol.name().as_bytes() {+                            let object_addr = addr.wrapping_sub(symbol.address()).wrapping_add(object_symbol.1);+                            let stash = Stash::new();+                            let inner = super::cx(&stash, object)?;+                            return Some((mk!(Mapping { map, inner, stash }), object_addr));+                        }+                    }+                }+            }+        } else {+            let map = super::mmap(Path::new(object_path))?;+            let (macho, data) = find_header(Bytes(&map))?;+            let endian = macho.endian().ok()?;+            let object = Object::parse(macho, endian, data)?;+            for object_symbol in &object.syms {+                if object_symbol.0 == symbol.name().as_bytes() {+                    let object_addr = addr.wrapping_sub(symbol.address()).wrapping_add(object_symbol.1);+                    let stash = Stash::new();+                    let inner = super::cx(&stash, object)?;+                    return Some((mk!(Mapping { map, inner, stash }), object_addr));+                }+            }+        }+        None+    }+}++fn split(path: &str) -> Option<(&str, &str)> {+    let index = path.find('(')?;+    let (archive, rest) = path.split_at(index);

oh wow it's literally libfoo.a(foo.o)!

philipc

comment created time in 3 days

pull request commentrust-lang/compiler-builtins

Use REP MOVSQ/STOSQ on x86_64

Thanks again for this! This all looks great to me. As one final thing, though, I'm not sure if the asm feature is actually ever enabled on CI, so could you add a line here to test the feature?

josephlr

comment created time in 3 days

issue commentalexcrichton/cc-rs

`cc` doesn't seem to respect `CARGO_TARGET_{TARGET_TRIPLE}_LINKER` on Android

AFAIK this crate has never read that env var, it's always expected CC to be set

JohnTitor

comment created time in 3 days

issue commentrust-lang/cargo

beta: cargo metadata uses inconsistent encodings of ids with `branch = master` dependencies

Sorry I haven't been able to investigate this more. It was somewhat expected that branch=master and not would be somewhat of a "soup" internally in Cargo, but the hope was that it wouldn't actually cause user-facing problems (except where warnings are emitted). Is cargo metadata the only location for issues expected? If so it seems reasonable to apply a specific fix there to just always drop branch=master for now perhaps?

Nemo157

comment created time in 3 days

issue openedalexcrichton/socket2-rs

Move to a new home?

@Thomasdezeeuw @stjepang y'all have been doing a great job maintaining this crate, and I clearly don't have time for it, so I was wondering if y'all would prefer it live somewhere else? I don't think it's helping much living under my name right now!

created time in 3 days

pull request commentbytecodealliance/wasmtime

Add Trap::trap_code

Thanks for the PR! I don't think we'll want to expose the cranelift-internal TrapCode as part of the public API of the wasmtime crate, though. That's an internal implementation detail of wasmtime, so I think it'd be best to instead have a public #[non_exhaustive] enum perhaps defined in wasmtime itself?

leoyvens

comment created time in 3 days

pull request commentrust-lang/cargo

Some minor clippy fixes.

@bors: r+

ehuss

comment created time in 3 days

issue closedalexcrichton/rustc-demangle

Objective-C symbols cannot be demangled

such as "_ZNSt3__110__function6__funcIZ38+[WCTStatistics SetGlobalErrorReport:]E3$0NS_9allocatorIS2_EEFvRKN4WCDB5ErrorEEEclES8",any solution?

closed time in 3 days

highlystuff

issue commentalexcrichton/rustc-demangle

Objective-C symbols cannot be demangled

Thanks for the report! This crate is only intended to demangle Rust symbols, however, so I don't think this is an issue for this crate.

highlystuff

comment created time in 3 days

push eventalexcrichton/wasm-tools

Alex Crichton

commit sha ebae1741372f0603e85aabba4fffa2fd85098e07

wasm-smith: Implement reference types support This commit implements the reference types proposal for the wasm-smith crate, generating modules which use reference types. It covers the new instructions, multiple-tables, and new kinds of element segments. Support is gated through `Config::max_tables` and `Config::reference_types_enabled`.

view details

push time in 3 days

issue commentrust-lang/backtrace-rs

Gimli doesn't support iOS

Ok makes sense, thanks for the info! In light of that I think I'll leave this open until we can get line numbers and filenames working on iOS

alexcrichton

comment created time in 3 days

pull request commentbytecodealliance/wasm-tools

wasm-smith: Implement reference types support

Er actually that's easy enough to back out, I've reverted the changes to roundtrip-valid-module using SwarmConfig, now it's back to only testing MVP modules which means this should be good to go.

alexcrichton

comment created time in 4 days

push eventalexcrichton/wasm-tools

Alex Crichton

commit sha 8f34a508786572660fb50273be768e3c6764506b

wasm-smith: Implement reference types support This commit implements the reference types proposal for the wasm-smith crate, generating modules which use reference types. It covers the new instructions, multiple-tables, and new kinds of element segments. Support is gated through `Config::max_tables` and `Config::reference_types_enabled`.

view details

push time in 4 days

pull request commentbytecodealliance/wasm-tools

wasm-smith: Implement reference types support

Note that this isn't quite ready for merging yet. Running the fuzzers locally it discovered that this module doesn't round-trip:

(module (elem declare funcref))

This is due to this block which currently serves as compatibility with wabt. I'll file an issue with wabt tomorrow to see if we can sort that out on their side and be able to round trip the above module.

alexcrichton

comment created time in 4 days

PR opened bytecodealliance/wasm-tools

wasm-smith: Implement reference types support

This commit implements the reference types proposal for the wasm-smith crate, generating modules which use reference types. It covers the new instructions, multiple-tables, and new kinds of element segments. Support is gated through Config::max_tables and Config::reference_types_enabled.

+726 -99

0 comment

7 changed files

pr created time in 4 days

create barnchalexcrichton/wasm-tools

branch : reference-types

created branch time in 4 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 3cf7c85d1ed78b36c8c2fcd0a1520d1b79345396

Deploy 2702942050ade76c103c13a01826c03ee1604e0b to gh-pages

view details

push time in 4 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha b2103d540aeeebc61590614426d2379988b3a980

Deploy b10e027fef0d21d5d02b9444f833fcc559f6eb39 to gh-pages

view details

push time in 4 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha a2c193c28221cd15ec94be26c8214f81857e9572

Deploy 4f104d3a4e08bc8af276d3e7ea26902b4d353cd0 to gh-pages

view details

push time in 4 days

push eventbytecodealliance/wasmtime

Nick Fitzgerald

commit sha 4f104d3a4e08bc8af276d3e7ea26902b4d353cd0

CI: fix rebuilding peepmatic peephole optimizers (#2311) The test that triggers the rebuild of the peephole optimizers is in the `cranelift-codegen` crate, not the umbrella cranelift crate. This was previously successfully running zero tests, and then successfully reporting no `git diff` because no peephole optimizers were ever rebuilt. This change fixes it so that we run the correct test that triggers the rebuilding of the peephole optimizers.

view details

push time in 4 days

PR merged bytecodealliance/wasmtime

Reviewers
CI: fix rebuilding peepmatic peephole optimizers

The test that triggers the rebuild of the peephole optimizers is in the cranelift-codegen crate, not the umbrella cranelift crate. This was previously successfully running zero tests, and then successfully reporting no git diff because no peephole optimizers were ever rebuilt.

This change fixes it so that we run the correct test that triggers the rebuilding of the peephole optimizers.

<!--

Please ensure that the following steps are all taken care of before submitting the PR.

  • [ ] This has been discussed in issue #..., or if not, please tell us why here.
  • [ ] A short description of what this does, why it is needed; if the description becomes long, the matter should probably be discussed in an issue first.
  • [ ] This PR contains test cases, if meaningful.
  • [ ] A reviewer from the core maintainer team has been assigned for this PR. If you don't know who could review this, please indicate so. The list of suggested reviewers on the right can help you.

Please ensure all communication adheres to the code of conduct. -->

+2 -2

0 comment

1 changed file

fitzgen

pr closed time in 4 days

pull request commentrust-lang/backtrace-rs

Enable Mach-O on iOS in gimli.

Thanks!

cutsoy

comment created time in 4 days

push eventrust-lang/backtrace-rs

Tim

commit sha 8b8ea53b56f519dd7780defdd4254daaec892584

Enable Mach-O on iOS in gimli. (#378) * Enable Mach-O on iOS in gimli. * Enable Mach-O on tvOS and watchOS in gimli.

view details

push time in 4 days

PR merged rust-lang/backtrace-rs

Enable Mach-O on iOS in gimli.

Fixes for iOS rust-lang/rust#78184.

iOS uses the same Mach-O format as macOS does. I have confirmed that this fix works on x86_64-apple-ios (tier 2). I expect it will also work on aarch64-apple-ios (tier 2), armv7-apple-ios, armv7s-apple-ios, i386-apple-ios, x86_64-apple-ios-macabi (tier 3), but I don't have the hardware to test on all of those archs.

Tier 2:

  • [x] x86_64-apple-ios compiles and works
  • [x] aarch64-apple-ios compiles

Tier 3:

  • [ ] armv7-apple-ios
  • [ ] armv7s-apple-ios
  • [ ] i386-apple-ios
  • [ ] x86_64-apple-ios-macabi
  • [ ] aarch64-apple-tvos
  • [ ] x86_64-apple-tvos

Nightly?:

  • [ ] armv7k-apple-watchos
  • [ ] i386-apple-watchos
  • [ ] x86_64-apple-watchos

(Thanks @bjorn3!)

+6 -1

2 comments

1 changed file

cutsoy

pr closed time in 4 days

push eventrustwasm/wasm-bindgen

Deploy from CI

commit sha 5696355f6135d1f378377012b9223443f6cba789

Deploy a314c86a0c50331d4571d2fa4e66403ef1aededf to gh-pages

view details

push time in 4 days

push eventrustwasm/wasm-bindgen

Paolo Barbolini

commit sha a314c86a0c50331d4571d2fa4e66403ef1aededf

Bump cfg-if to 1.0 (#2336)

view details

push time in 4 days

PR merged rustwasm/wasm-bindgen

Bump cfg-if to 1.0

Not sure why #2326 didn't do it

+1 -1

1 comment

1 changed file

paolobarbolini

pr closed time in 4 days

pull request commentrustwasm/wasm-bindgen

Bump cfg-if to 1.0

Thanks!

paolobarbolini

comment created time in 4 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha d1eff9a7f2fc5daf37a2c1f7285f1f7110eeed8e

Deploy c5a2bd32150be705531a388300d006cd7ef92944 to gh-pages

view details

push time in 5 days

pull request commentrust-lang/cargo

Add a `--crate-type` override to build and check.

Sorry to clarify the feature I'm talking about isn't configuring all crate types at once, just having the ability to configure crate types for all crates. I also agree that this is a small feature, but as maintainers of Cargo it's our job to figure out how it fits into the big picture (or rather make sure it does). If Cargo was just a bunch of tiny additions over time it would not be a pleasant tool to use.

I think whatever we do in this arena will be unstable at first. There are a number of various mechanisms Cargo has to control the usage of unstable features, but the main one is -Zunstable-options for this probably.

cutsoy

comment created time in 5 days

push eventbytecodealliance/wasmtime

Deploy from CI

commit sha 6654b70a86ce52ad9463f982b874420d18e4b1e9

Deploy aa04917ddf2f5eadc9297bab57b5cf38516758ff to gh-pages

view details

push time in 5 days

more