diff --git a/.github/actions/install-wasi-sdk/action.yml b/.github/actions/install-wasi-sdk/action.yml index 48c4be0a3..741e51656 100644 --- a/.github/actions/install-wasi-sdk/action.yml +++ b/.github/actions/install-wasi-sdk/action.yml @@ -5,22 +5,22 @@ runs: using: composite steps: - run: | - curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-linux.tar.gz -L | tar xzvf - - echo "WASI_SDK_PATH=`pwd`/wasi-sdk-22.0" >> $GITHUB_ENV + curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sdk-24.0-x86_64-linux.tar.gz -L | tar xzvf - + echo "WASI_SDK_PATH=`pwd`/wasi-sdk-24.0-x86_64-linux" >> $GITHUB_ENV if: runner.os == 'Linux' shell: bash - run: | - curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-macos.tar.gz -L | tar xzvf - - echo "WASI_SDK_PATH=`pwd`/wasi-sdk-22.0" >> $GITHUB_ENV + curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sdk-24.0-x86_64-macos.tar.gz -L | tar xzvf - + echo "WASI_SDK_PATH=`pwd`/wasi-sdk-24.0-x86_64-macos" >> $GITHUB_ENV if: runner.os == 'macOS' shell: bash - run: | - curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0.m-mingw64.tar.gz -L | tar xzvf - - echo "WASI_SDK_PATH=`pwd`/wasi-sdk-22.0+m" >> $GITHUB_ENV + curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sdk-24.0-x86_64-windows.tar.gz -L | tar xzvf - + echo "WASI_SDK_PATH=`pwd`/wasi-sdk-24.0-x86_64-windows" >> $GITHUB_ENV if: runner.os == 'Windows' shell: bash - name: Setup `wasm-tools` uses: bytecodealliance/actions/wasm-tools/setup@v1 with: - version: "1.0.60" + version: "1.215.0" github_token: ${{ github.token }} diff --git a/Cargo.lock b/Cargo.lock index ce94dfc0a..0caca6c6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2294,7 +2294,7 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.29.0" +version = "0.30.0" dependencies = [ "wit-bindgen-rt", "wit-bindgen-rust-macro", @@ -2302,7 +2302,7 @@ dependencies = [ [[package]] name = "wit-bindgen-c" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2317,7 +2317,7 @@ dependencies = [ [[package]] name = "wit-bindgen-cli" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2340,7 +2340,7 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "heck 0.5.0", @@ -2349,7 +2349,7 @@ dependencies = [ [[package]] name = "wit-bindgen-csharp" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2366,7 +2366,7 @@ dependencies = [ [[package]] name = "wit-bindgen-go" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2378,7 +2378,7 @@ dependencies = [ [[package]] name = "wit-bindgen-markdown" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2390,14 +2390,14 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.29.0" +version = "0.30.0" dependencies = [ "bitflags", ] [[package]] name = "wit-bindgen-rust" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", @@ -2416,7 +2416,7 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "prettyplease", @@ -2429,7 +2429,7 @@ dependencies = [ [[package]] name = "wit-bindgen-teavm-java" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 30cc628e6..ddb8f7a47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ resolver = "2" [workspace.package] edition = "2021" -version = "0.29.0" +version = "0.30.0" license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT" repository = "https://github.com/bytecodealliance/wasi-rs" @@ -38,14 +38,14 @@ wasm-encoder = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "v1.215. wit-parser = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "v1.215.0" } wit-component = { git = "https://github.com/wasmfx/wasmfx-tools", tag = "v1.215.0" } -wit-bindgen-core = { path = 'crates/core', version = '0.29.0' } -wit-bindgen-c = { path = 'crates/c', version = '0.29.0' } -wit-bindgen-rust = { path = "crates/rust", version = "0.29.0" } -wit-bindgen-teavm-java = { path = 'crates/teavm-java', version = '0.29.0' } -wit-bindgen-go = { path = 'crates/go', version = '0.29.0' } -wit-bindgen-csharp = { path = 'crates/csharp', version = '0.29.0' } -wit-bindgen-markdown = { path = 'crates/markdown', version = '0.29.0' } -wit-bindgen = { path = 'crates/guest-rust', version = '0.29.0', default-features = false } +wit-bindgen-core = { path = 'crates/core', version = '0.30.0' } +wit-bindgen-c = { path = 'crates/c', version = '0.30.0' } +wit-bindgen-rust = { path = "crates/rust", version = "0.30.0" } +wit-bindgen-teavm-java = { path = 'crates/teavm-java', version = '0.30.0' } +wit-bindgen-go = { path = 'crates/go', version = '0.30.0' } +wit-bindgen-csharp = { path = 'crates/csharp', version = '0.30.0' } +wit-bindgen-markdown = { path = 'crates/markdown', version = '0.30.0' } +wit-bindgen = { path = 'crates/guest-rust', version = '0.30.0', default-features = false } [[bin]] name = "wit-bindgen" diff --git a/crates/csharp/src/component_type_object.rs b/crates/csharp/src/component_type_object.rs deleted file mode 100644 index 671d1dd95..000000000 --- a/crates/csharp/src/component_type_object.rs +++ /dev/null @@ -1,58 +0,0 @@ -use anyhow::Result; -use heck::ToSnakeCase; -use wasm_encoder::{ - CodeSection, CustomSection, Function, FunctionSection, LinkingSection, Module, SymbolTable, - TypeSection, -}; -use wit_bindgen_core::wit_parser::{Resolve, WorldId}; -use wit_component::StringEncoding; - -pub fn linking_symbol(name: &str) -> String { - let snake = name.to_snake_case(); - format!("__component_type_object_force_link_{snake}") -} - -pub fn object(resolve: &Resolve, world: WorldId, encoding: StringEncoding) -> Result> { - let mut module = Module::new(); - - // Build a module with one function that's a "dummy function" - let mut types = TypeSection::new(); - types.function([], []); - module.section(&types); - let mut funcs = FunctionSection::new(); - funcs.function(0); - module.section(&funcs); - let mut code = CodeSection::new(); - code.function(&Function::new([])); - module.section(&code); - - let mut producers = wasm_metadata::Producers::empty(); - producers.add( - "processed-by", - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION"), - ); - let data = wit_component::metadata::encode(resolve, world, encoding, Some(&producers)).unwrap(); - - // The custom section name here must start with "component-type" but - // otherwise is attempted to be unique here to ensure that this doesn't get - // concatenated to other custom sections by LLD by accident since LLD will - // concatenate custom sections of the same name. - let world_name = &resolve.worlds[world].name; - let section_name = format!("component-type:{world_name}"); - - // Add our custom section - module.section(&CustomSection { - name: std::borrow::Cow::Borrowed(§ion_name), - data: std::borrow::Cow::Borrowed(data.as_slice()), - }); - - // Append the linking section, so that lld knows the custom section's symbol name - let mut linking = LinkingSection::new(); - let mut symbols = SymbolTable::new(); - symbols.function(0, 0, Some(&linking_symbol(&world_name))); - linking.symbol_table(&symbols); - module.section(&linking); - - Ok(module.finish()) -} diff --git a/crates/csharp/src/csproj.rs b/crates/csharp/src/csproj.rs index e6f62e10d..626e89df2 100644 --- a/crates/csharp/src/csproj.rs +++ b/crates/csharp/src/csproj.rs @@ -77,51 +77,27 @@ impl CSProjectLLVMBuilder { true {name} + - - + - + " ); if self.aot { - //TODO: Is this handled by the source generator? (Temporary just to test with numbers and strings) csproj.push_str( r#" - - - - - - - - + + - - - - - "#, ); - csproj.push_str(&format!(" - - - - " - )); - fs::write( self.dir.join("nuget.config"), r#" diff --git a/crates/csharp/src/lib.rs b/crates/csharp/src/lib.rs index 0c584dfcb..12f8ad6e9 100644 --- a/crates/csharp/src/lib.rs +++ b/crates/csharp/src/lib.rs @@ -1,5 +1,3 @@ -mod component_type_object; - use anyhow::Result; use heck::{ToLowerCamelCase, ToShoutySnakeCase, ToUpperCamelCase}; use indexmap::IndexMap; @@ -692,31 +690,6 @@ impl WorldGenerator for CSharp { } if !self.opts.skip_support_files { - let cabi_relloc_src = r#" - #include - - /* Done in C so we can avoid initializing the dotnet runtime and hence WASI libc */ - /* It would be preferable to do this in C# but the constraints of cabi_realloc and the demands */ - /* of WASI libc prevent us doing so. */ - /* See https://github.com/bytecodealliance/wit-bindgen/issues/777 */ - /* and https://github.com/WebAssembly/wasi-libc/issues/452 */ - /* The component model `start` function might be an alternative to this depending on whether it */ - /* has the same constraints as `cabi_realloc` */ - __attribute__((__weak__, __export_name__("cabi_realloc"))) - void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) { - (void) old_size; - if (new_size == 0) return (void*) align; - void *ret = realloc(ptr, new_size); - if (!ret) abort(); - return ret; - } - "#; - - files.push( - &format!("{name}World_cabi_realloc.c"), - indent(cabi_relloc_src).as_bytes(), - ); - //TODO: This is currently needed for mono even if it's built as a library. if self.opts.runtime == CSharpRuntime::Mono { files.push( @@ -779,13 +752,6 @@ impl WorldGenerator for CSharp { ); } - files.push( - &format!("{world_namespace}_component_type.o",), - component_type_object::object(resolve, id, self.opts.string_encoding) - .unwrap() - .as_slice(), - ); - // TODO: remove when we switch to dotnet 9 let mut wasm_import_linakge_src = String::new(); @@ -1012,6 +978,8 @@ impl InterfaceGenerator<'_> { } }; + let access = self.gen.access_modifier(); + let extra_modifiers = extra_modifiers(func, &camel_name); let interop_camel_name = func.item_name().to_upper_camel_case(); @@ -1140,7 +1108,7 @@ impl InterfaceGenerator<'_> { uwrite!( target, r#" - internal {extra_modifiers} {modifiers} unsafe {result_type} {camel_name}({params}) + {access} {extra_modifiers} {modifiers} unsafe {result_type} {camel_name}({params}) {{ {src} //TODO: free alloc handle (interopString) if exists diff --git a/crates/guest-rust/Cargo.toml b/crates/guest-rust/Cargo.toml index 1dd9b8e93..d24fc4000 100644 --- a/crates/guest-rust/Cargo.toml +++ b/crates/guest-rust/Cargo.toml @@ -12,8 +12,8 @@ Used when compiling Rust programs to the component model. """ [dependencies] -wit-bindgen-rust-macro = { path = "./macro", optional = true, version = "0.29.0" } -wit-bindgen-rt = { path = "./rt", version = "0.29.0", features = ["bitflags"] } +wit-bindgen-rust-macro = { path = "./macro", optional = true, version = "0.30.0" } +wit-bindgen-rt = { path = "./rt", version = "0.30.0", features = ["bitflags"] } [features] default = ["macros", "realloc"] diff --git a/crates/guest-rust/macro/src/lib.rs b/crates/guest-rust/macro/src/lib.rs index e9a6151b6..c6cb439be 100644 --- a/crates/guest-rust/macro/src/lib.rs +++ b/crates/guest-rust/macro/src/lib.rs @@ -137,6 +137,9 @@ impl Parse for Config { Opt::Features(f) => { features.extend(f.into_iter().map(|f| f.value())); } + Opt::DisableCustomSectionLinkHelpers(disable) => { + opts.disable_custom_section_link_helpers = disable.value(); + } } } } else { @@ -309,6 +312,7 @@ mod kw { syn::custom_keyword!(pub_export_macro); syn::custom_keyword!(generate_unused_types); syn::custom_keyword!(features); + syn::custom_keyword!(disable_custom_section_link_helpers); } #[derive(Clone)] @@ -361,6 +365,7 @@ enum Opt { PubExportMacro(syn::LitBool), GenerateUnusedTypes(syn::LitBool), Features(Vec), + DisableCustomSectionLinkHelpers(syn::LitBool), } impl Parse for Opt { @@ -504,6 +509,10 @@ impl Parse for Opt { syn::bracketed!(contents in input); let list = Punctuated::<_, Token![,]>::parse_terminated(&contents)?; Ok(Opt::Features(list.into_iter().collect())) + } else if l.peek(kw::disable_custom_section_link_helpers) { + input.parse::()?; + input.parse::()?; + Ok(Opt::DisableCustomSectionLinkHelpers(input.parse()?)) } else { Err(l.error()) } diff --git a/crates/guest-rust/rt/src/cabi_realloc.c b/crates/guest-rust/rt/src/cabi_realloc.c index 4e8fbb3a3..f452b3619 100644 --- a/crates/guest-rust/rt/src/cabi_realloc.c +++ b/crates/guest-rust/rt/src/cabi_realloc.c @@ -2,9 +2,9 @@ #include -extern void *cabi_realloc_wit_bindgen_0_29_0(void *ptr, size_t old_size, size_t align, size_t new_size); +extern void *cabi_realloc_wit_bindgen_0_30_0(void *ptr, size_t old_size, size_t align, size_t new_size); __attribute__((__weak__, __export_name__("cabi_realloc"))) void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) { - return cabi_realloc_wit_bindgen_0_29_0(ptr, old_size, align, new_size); + return cabi_realloc_wit_bindgen_0_30_0(ptr, old_size, align, new_size); } diff --git a/crates/guest-rust/rt/src/cabi_realloc.o b/crates/guest-rust/rt/src/cabi_realloc.o index 1c1e8ef76..a649d0c96 100644 Binary files a/crates/guest-rust/rt/src/cabi_realloc.o and b/crates/guest-rust/rt/src/cabi_realloc.o differ diff --git a/crates/guest-rust/rt/src/cabi_realloc.rs b/crates/guest-rust/rt/src/cabi_realloc.rs index 63a22fba5..6a1fb8fe5 100644 --- a/crates/guest-rust/rt/src/cabi_realloc.rs +++ b/crates/guest-rust/rt/src/cabi_realloc.rs @@ -1,7 +1,7 @@ // This file is generated by ./ci/rebuild-libcabi-realloc.sh #[no_mangle] -pub unsafe extern "C" fn cabi_realloc_wit_bindgen_0_29_0( +pub unsafe extern "C" fn cabi_realloc_wit_bindgen_0_30_0( old_ptr: *mut u8, old_len: usize, align: usize, diff --git a/crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a b/crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a index 38c36c501..411378115 100644 Binary files a/crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a and b/crates/guest-rust/rt/src/libwit_bindgen_cabi_realloc.a differ diff --git a/crates/guest-rust/src/lib.rs b/crates/guest-rust/src/lib.rs index f58b6c121..a804cfa58 100644 --- a/crates/guest-rust/src/lib.rs +++ b/crates/guest-rust/src/lib.rs @@ -812,6 +812,12 @@ /// // /// // By default this is an empty list. /// features: ["foo", "bar", "baz"], +/// +/// // Disables generation of a `#[used]` static to try harder to get the +/// // custom section describing WIT types linked into the binary when +/// // used in library-like situations. This is `false` by default with +/// // `#[used]` statics being emitted. +/// disable_custom_section_link_helpers: false, /// }); /// ``` /// diff --git a/crates/rust/src/interface.rs b/crates/rust/src/interface.rs index 2eb5dc870..98d2465bf 100644 --- a/crates/rust/src/interface.rs +++ b/crates/rust/src/interface.rs @@ -425,14 +425,23 @@ macro_rules! {macro_name} {{ pub fn finish_append_submodule(mut self, snake: &str, module_path: Vec) { let module = self.finish(); let path_to_root = self.path_to_root(); + let used_static = if self.gen.opts.disable_custom_section_link_helpers { + String::new() + } else { + format!( + "\ + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = + {path_to_root}__link_custom_section_describing_imports; + " + ) + }; let module = format!( "\ #[allow(dead_code, clippy::all)] pub mod {snake} {{ - #[used] - #[doc(hidden)] - #[cfg(target_arch = \"wasm32\")] - static __FORCE_SECTION_REF: fn() = {path_to_root}__link_custom_section_describing_imports; + {used_static} {module} }} ", @@ -1988,7 +1997,7 @@ impl {camel} {{ use core::any::TypeId; static mut LAST_TYPE: Option = None; unsafe {{ - assert!(!cfg!(target_feature = "threads")); + assert!(!cfg!(target_feature = "atomics")); let id = TypeId::of::(); match LAST_TYPE {{ Some(ty) => assert!(ty == id, "cannot use two types with this resource type"), diff --git a/crates/rust/src/lib.rs b/crates/rust/src/lib.rs index de76c75e8..f5d055132 100644 --- a/crates/rust/src/lib.rs +++ b/crates/rust/src/lib.rs @@ -226,6 +226,14 @@ pub struct Opts { /// Whether to generate unused structures, not generated by default (false) #[cfg_attr(feature = "clap", arg(long))] pub generate_unused_types: bool, + + /// Whether or not to generate helper function/constants to help link custom + /// sections into the final output. + /// + /// Disabling this can shave a few bytes off a binary but makes + /// library-based usage of `generate!` prone to breakage. + #[cfg_attr(feature = "clap", arg(long))] + pub disable_custom_section_link_helpers: bool, } impl Opts { @@ -816,7 +824,6 @@ macro_rules! __export_{world_name}_impl {{ " #[inline(never)] #[doc(hidden)] - #[cfg(target_arch = \"wasm32\")] pub fn {func_name}() {{ {rt}::maybe_link_cabi_realloc(); }} @@ -1075,7 +1082,11 @@ impl WorldGenerator for RustWasm { resolve_to_encode, world_to_encode, "encoded world", - Some("__link_custom_section_describing_imports"), + if self.opts.disable_custom_section_link_helpers { + None + } else { + Some("__link_custom_section_describing_imports") + }, ); if self.opts.stubs { diff --git a/crates/rust/tests/codegen.rs b/crates/rust/tests/codegen.rs index f68491f5d..b5757b3df 100644 --- a/crates/rust/tests/codegen.rs +++ b/crates/rust/tests/codegen.rs @@ -572,3 +572,19 @@ mod multiple_paths { generate_all, }); } + +#[allow(unused)] +mod generate_custom_section_link_helpers { + wit_bindgen::generate!({ + inline: r#" + package a:b; + + world test { + import a: interface { + x: func(); + } + } + "#, + disable_custom_section_link_helpers: true, + }); +} diff --git a/tests/runtime/main.rs b/tests/runtime/main.rs index d85cf3502..238dc22e1 100644 --- a/tests/runtime/main.rs +++ b/tests/runtime/main.rs @@ -749,25 +749,7 @@ fn tests(name: &str, dir_name: &str) -> Result> { panic!("failed to compile"); } - // Translate the canonical ABI module into a component. - - let module = fs::read(&wasm_filename).expect("failed to read wasm file"); - let component = ComponentEncoder::default() - .module(module.as_slice()) - .expect("pull custom sections from module") - .validate(true) - .adapter("wasi_snapshot_preview1", &wasi_adapter) - .expect("adapter failed to get loaded") - .realloc_via_memory_grow(true) - .encode() - .expect(&format!( - "module {:?} can be translated to a component", - out_wasm - )); - let component_path = out_wasm.with_extension("component.wasm"); - fs::write(&component_path, component).expect("write component to disk"); - - result.push(component_path); + result.push(wasm_filename); } }