diff --git a/Cargo.lock b/Cargo.lock index ecbbf57c0..428d6b7bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2046,6 +2046,7 @@ dependencies = [ "wit-bindgen-core", "wit-bindgen-gen-rust-lib", "wit-bindgen-guest-rust", + "wit-component", ] [[package]] diff --git a/crates/gen-guest-rust/Cargo.toml b/crates/gen-guest-rust/Cargo.toml index 905eed65c..e79a16add 100644 --- a/crates/gen-guest-rust/Cargo.toml +++ b/crates/gen-guest-rust/Cargo.toml @@ -11,6 +11,7 @@ doctest = false [dependencies] wit-bindgen-core = { workspace = true } wit-bindgen-gen-rust-lib = { workspace = true } +wit-component = { workspace = true } heck = { workspace = true } clap = { workspace = true, optional = true } diff --git a/crates/gen-guest-rust/src/lib.rs b/crates/gen-guest-rust/src/lib.rs index cbf815329..0de50dc1a 100644 --- a/crates/gen-guest-rust/src/lib.rs +++ b/crates/gen-guest-rust/src/lib.rs @@ -468,6 +468,28 @@ impl Generator for RustWasm { )); } + let component_type = wit_component::InterfaceEncoder::new(iface) + .encode() + .expect(&format!( + "encoding interface {} as a component type", + iface.name + )); + let direction = match dir { + Direction::Import => "import", + Direction::Export => "export", + }; + let iface_name = &iface.name; + + self.src.push_str("#[cfg(target_arch = \"wasm32\")]\n"); + self.src.push_str(&format!( + "#[link_section = \"component-type:{direction}:{iface_name}\"]\n" + )); + self.src.push_str(&format!( + "pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; {}] = ", + component_type.len() + )); + self.src.push_str(&format!("{:?};\n", component_type)); + // For standalone generation, close the export! macro if self.opts.standalone && dir == Direction::Export { self.src.push_str("});\n"); diff --git a/crates/test-helpers/build.rs b/crates/test-helpers/build.rs index 93da1f183..c8e5df3ba 100644 --- a/crates/test-helpers/build.rs +++ b/crates/test-helpers/build.rs @@ -3,6 +3,7 @@ use std::fs; use std::path::PathBuf; use std::process::Command; use wit_bindgen_core::{wit_parser::Interface, Direction, Generator}; +use wit_component::ComponentEncoder; fn main() { let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); @@ -13,14 +14,20 @@ fn main() { let mut cmd = Command::new("cargo"); cmd.arg("build") .current_dir("../test-rust-wasm") - .arg("--target=wasm32-wasi") + // TODO: this should go back to wasm32-wasi once we have an adapter + // for snapshot 1 to a component + .arg("--target=wasm32-unknown-unknown") .env("CARGO_TARGET_DIR", &out_dir) .env("CARGO_PROFILE_DEV_DEBUG", "1") .env("RUSTFLAGS", "-Clink-args=--export-table") .env_remove("CARGO_ENCODED_RUSTFLAGS"); let status = cmd.status().unwrap(); assert!(status.success()); - for file in out_dir.join("wasm32-wasi/debug").read_dir().unwrap() { + for file in out_dir + .join("wasm32-unknown-unknown/debug") + .read_dir() + .unwrap() + { let file = file.unwrap().path(); if file.extension().and_then(|s| s.to_str()) != Some("wasm") { continue; @@ -31,6 +38,22 @@ fn main() { file.to_str().unwrap().to_string(), )); + // The "invalid" test doesn't actually use the rust-guest macro + // and doesn't put the custom sections in, so component translation + // will fail. + if file.file_stem().unwrap().to_str().unwrap() != "invalid" { + // Validate that the module can be translated to a component, using + // the component-type custom sections. We don't yet consume this component + // anywhere. + let module = fs::read(&file).expect("failed to read wasm file"); + ComponentEncoder::default() + .module(module.as_slice()) + .expect("pull custom sections from module") + .validate(true) + .encode() + .expect("module can be translated to a component"); + } + let dep_file = file.with_extension("d"); let deps = fs::read_to_string(&dep_file).expect("failed to read dep file"); for dep in deps diff --git a/crates/wit-component/src/cli.rs b/crates/wit-component/src/cli.rs index cef566ca7..e0d375b1e 100644 --- a/crates/wit-component/src/cli.rs +++ b/crates/wit-component/src/cli.rs @@ -139,7 +139,7 @@ impl WitComponentApp { .with_context(|| format!("failed to parse module `{}`", self.module.display()))?; let mut encoder = ComponentEncoder::default() - .module(&module) + .module(&module)? .imports(&self.imports) .exports(&self.exports) .validate(!self.skip_validation); diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index b236915b6..afa080c0c 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -53,6 +53,7 @@ //! component model. use crate::{ + decode_interface_component, validation::{ expected_export_name, validate_adapter_module, validate_module, ValidatedAdapter, ValidatedModule, @@ -2097,9 +2098,9 @@ impl<'a> ImportEncoder<'a> { pub struct ComponentEncoder<'a> { module: &'a [u8], encoding: StringEncoding, - interface: Option<&'a Interface>, - imports: &'a [Interface], - exports: &'a [Interface], + interface: Option, + imports: Vec, + exports: Vec, validate: bool, types_only: bool, adapters: IndexMap<&'a str, (&'a [u8], &'a Interface)>, @@ -2107,9 +2108,43 @@ pub struct ComponentEncoder<'a> { impl<'a> ComponentEncoder<'a> { /// Set the core module to encode as a component. - pub fn module(mut self, module: &'a [u8]) -> Self { + /// This method will also parse any component type information stored in custom sections + /// inside the module, and add them as the interface, imports, and exports. + pub fn module(mut self, module: &'a [u8]) -> Result { + for payload in wasmparser::Parser::new(0).parse_all(&module) { + match payload.context("decoding item in module")? { + wasmparser::Payload::CustomSection(cs) => { + if let Some(export) = cs.name().strip_prefix("component-type:export:") { + let mut i = decode_interface_component(cs.data()).with_context(|| { + format!("decoding component-type in export section {}", export) + })?; + i.name = export.to_owned(); + self.interface = Some(i); + } else if let Some(import) = cs.name().strip_prefix("component-type:import:") { + let mut i = decode_interface_component(cs.data()).with_context(|| { + format!("decoding component-type in import section {}", import) + })?; + i.name = import.to_owned(); + self.imports.push(i); + } else if let Some(export_instance) = + cs.name().strip_prefix("component-type:export-instance:") + { + let mut i = decode_interface_component(cs.data()).with_context(|| { + format!( + "decoding component-type in export-instance section {}", + export_instance + ) + })?; + i.name = export_instance.to_owned(); + self.exports.push(i); + } + } + _ => {} + } + } + self.module = module; - self + Ok(self) } /// Set the string encoding expected by the core module. @@ -2126,19 +2161,23 @@ impl<'a> ComponentEncoder<'a> { /// Set the default interface exported by the component. pub fn interface(mut self, interface: &'a Interface) -> Self { - self.interface = Some(interface); + self.interface = Some(interface.clone()); self } /// Set the interfaces the component imports. pub fn imports(mut self, imports: &'a [Interface]) -> Self { - self.imports = imports; + for i in imports { + self.imports.push(i.clone()) + } self } /// Set the interfaces the component exports. pub fn exports(mut self, exports: &'a [Interface]) -> Self { - self.exports = exports; + for e in exports { + self.exports.push(e.clone()) + } self } @@ -2171,8 +2210,8 @@ impl<'a> ComponentEncoder<'a> { validate_module( self.module, &self.interface, - self.imports, - self.exports, + &self.imports, + &self.exports, &adapters, )? } else { @@ -2182,7 +2221,6 @@ impl<'a> ComponentEncoder<'a> { let exports = self .interface .iter() - .copied() .map(|i| (i, true)) .chain(self.exports.iter().map(|i| (i, false))); @@ -2190,7 +2228,7 @@ impl<'a> ComponentEncoder<'a> { let mut types = TypeEncoder::default(); let mut imports = ImportEncoder::default(); types.encode_func_types(exports.clone(), false)?; - types.encode_instance_imports(self.imports, &info, &mut imports)?; + types.encode_instance_imports(&self.imports, &info, &mut imports)?; if self.types_only { if !self.module.is_empty() { diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index d42fc16ce..d309f1803 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -86,7 +86,7 @@ pub struct ValidatedModule<'a> { /// for this module. pub fn validate_module<'a>( bytes: &'a [u8], - interface: &Option<&Interface>, + interface: &Option, imports: &[Interface], exports: &[Interface], adapters: &IndexSet<&str>, diff --git a/crates/wit-component/tests/components.rs b/crates/wit-component/tests/components.rs index ded443b0b..31040c8e8 100644 --- a/crates/wit-component/tests/components.rs +++ b/crates/wit-component/tests/components.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Context, Result}; use pretty_assertions::assert_eq; use std::{fs, path::Path}; -use wit_component::ComponentEncoder; +use wit_component::{ComponentEncoder, InterfaceEncoder}; use wit_parser::Interface; fn read_interface(path: &Path) -> Result { @@ -78,7 +78,7 @@ fn read_adapters(dir: &Path) -> Result, Interface)>> { /// Run the test with the environment variable `BLESS` set to update /// either `component.wat` or `error.txt` depending on the outcome of the encoding. #[test] -fn component_encoding() -> Result<()> { +fn component_encoding_via_flags() -> Result<()> { drop(env_logger::try_init()); for entry in fs::read_dir("tests/components")? { @@ -105,7 +105,7 @@ fn component_encoding() -> Result<()> { let adapters = read_adapters(&path)?; let mut encoder = ComponentEncoder::default() - .module(&module) + .module(&module)? .imports(&imports) .exports(&exports) .validate(true); @@ -119,6 +119,112 @@ fn component_encoding() -> Result<()> { } let r = encoder.encode(); + + let (output, baseline_path) = if error_path.is_file() { + match r { + Ok(_) => bail!("encoding should fail for test case `{}`", test_case), + Err(e) => (e.to_string(), &error_path), + } + } else { + ( + wasmprinter::print_bytes( + &r.with_context(|| format!("failed to encode for test case `{}`", test_case))?, + ) + .with_context(|| { + format!( + "failed to print component bytes for test case `{}`", + test_case + ) + })?, + &component_path, + ) + }; + + if std::env::var_os("BLESS").is_some() { + fs::write(&baseline_path, output)?; + } else { + assert_eq!( + fs::read_to_string(&baseline_path)?.replace("\r\n", "\n"), + output, + "failed baseline comparison for test case `{}` ({})", + test_case, + baseline_path.display(), + ); + } + } + + Ok(()) +} + +/// Tests the encoding of components. +/// +/// This test looks in the `components/` directory for test cases. It parses +/// the inputs to the test out of that directly exactly like +/// `component_encoding_via_flags` does in this same file. +/// +/// Rather than pass the default interface, imports, and exports directly to +/// the `ComponentEncoder`, this test encodes those Interfaces as component +/// types in custom sections of the wasm Module. +/// +/// This simulates the flow that toolchains which don't yet know how to +/// emit a Component will emit a canonical ABI Module containing these custom sections, +/// and those will then be translated by wit-component to a Component without +/// needing the wit files passed in as well. +#[test] +fn component_encoding_via_custom_sections() -> Result<()> { + use wasm_encoder::{Encode, Section}; + + for entry in fs::read_dir("tests/components")? { + let path = entry?.path(); + if !path.is_dir() { + continue; + } + + let test_case = path.file_stem().unwrap().to_str().unwrap(); + + let module_path = path.join("module.wat"); + let interface_path = path.join("default.wit"); + let component_path = path.join("component.wat"); + let error_path = path.join("error.txt"); + + let mut module = wat::parse_file(&module_path) + .with_context(|| format!("expected file `{}`", module_path.display()))?; + + fn encode_interface(i: &Interface, module: &mut Vec, kind: &str) -> Result<()> { + let name = &format!("component-type:{}:{}", kind, i.name); + let contents = InterfaceEncoder::new(&i).validate(true).encode()?; + let section = wasm_encoder::CustomSection { + name, + data: &contents, + }; + module.push(section.id()); + section.encode(module); + Ok(()) + } + + // Encode the interface, exports, and imports into the module, instead of + // passing them to the ComponentEncoder explicitly. + if interface_path.is_file() { + let i = read_interface(&interface_path)?; + encode_interface(&i, &mut module, "export")?; + } + for i in read_interfaces(&path, "import-*.wit")? { + encode_interface(&i, &mut module, "import")?; + } + for i in read_interfaces(&path, "export-*.wit")? { + encode_interface(&i, &mut module, "export-instance")?; + } + // + let adapters = read_adapters(&path)?; + + let mut encoder = ComponentEncoder::default().module(&module)?.validate(true); + + for (name, wasm, interface) in adapters.iter() { + encoder = encoder.adapter(name, wasm, interface); + } + + let r = encoder.encode(); + let (output, baseline_path) = if error_path.is_file() { match r { Ok(_) => bail!("encoding should fail for test case `{}`", test_case), diff --git a/tests/runtime/flavorful/exports.wit b/tests/runtime/flavorful/exports.wit index be79aace7..558acb826 100644 --- a/tests/runtime/flavorful/exports.wit +++ b/tests/runtime/flavorful/exports.wit @@ -6,21 +6,21 @@ record list-in-record3 { a: string } record list-in-record4 { a: string } type list-in-alias = list-in-record4 -list-in-record1: func(a: list-in-record1) -list-in-record2: func() -> list-in-record2 -list-in-record3: func(a: list-in-record3) -> list-in-record3 -list-in-record4: func(a: list-in-alias) -> list-in-alias +f-list-in-record1: func(a: list-in-record1) +f-list-in-record2: func() -> list-in-record2 +f-list-in-record3: func(a: list-in-record3) -> list-in-record3 +f-list-in-record4: func(a: list-in-alias) -> list-in-alias type list-in-variant1-v1 = option type list-in-variant1-v2 = result<_, string> union list-in-variant1-v3 { string, float32 } -list-in-variant1: func(a: list-in-variant1-v1, b: list-in-variant1-v2, c: list-in-variant1-v3) +f-list-in-variant1: func(a: list-in-variant1-v1, b: list-in-variant1-v2, c: list-in-variant1-v3) type list-in-variant2 = option -list-in-variant2: func() -> list-in-variant2 +f-list-in-variant2: func() -> list-in-variant2 type list-in-variant3 = option -list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 +f-list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 enum my-errno { success, a, b } errno-result: func() -> result<_, my-errno> diff --git a/tests/runtime/flavorful/host.py b/tests/runtime/flavorful/host.py index 010e03840..355404caf 100644 --- a/tests/runtime/flavorful/host.py +++ b/tests/runtime/flavorful/host.py @@ -7,29 +7,29 @@ import wasmtime class MyImports: - def list_in_record1(self, a: i.ListInRecord1) -> None: + def f_list_in_record1(self, a: i.ListInRecord1) -> None: pass - def list_in_record2(self) -> i.ListInRecord2: + def f_list_in_record2(self) -> i.ListInRecord2: return i.ListInRecord2('list_in_record2') - def list_in_record3(self, a: i.ListInRecord3) -> i.ListInRecord3: + def f_list_in_record3(self, a: i.ListInRecord3) -> i.ListInRecord3: assert(a.a == 'list_in_record3 input') return i.ListInRecord3('list_in_record3 output') - def list_in_record4(self, a: i.ListInAlias) -> i.ListInAlias: + def f_list_in_record4(self, a: i.ListInAlias) -> i.ListInAlias: assert(a.a == 'input4') return i.ListInRecord4('result4') - def list_in_variant1(self, a: i.ListInVariant1V1, b: i.ListInVariant1V2, c: i.ListInVariant1V3) -> None: + def f_list_in_variant1(self, a: i.ListInVariant1V1, b: i.ListInVariant1V2, c: i.ListInVariant1V3) -> None: assert(a == 'foo') assert(b == i.Err('bar')) assert(c == 'baz') - def list_in_variant2(self) -> i.ListInVariant2: + def f_list_in_variant2(self) -> i.ListInVariant2: return 'list_in_variant2' - def list_in_variant3(self, a: i.ListInVariant3) -> i.ListInVariant3: + def f_list_in_variant3(self, a: i.ListInVariant3) -> i.ListInVariant3: assert(a == 'input3') return 'output3' @@ -66,15 +66,15 @@ def run(wasm_file: str) -> None: wasm = Exports(store, linker, module) wasm.test_imports(store) - wasm.list_in_record1(store, e.ListInRecord1("list_in_record1")) - assert(wasm.list_in_record2(store) == e.ListInRecord2(a="list_in_record2")) + wasm.f_list_in_record1(store, e.ListInRecord1("list_in_record1")) + assert(wasm.f_list_in_record2(store) == e.ListInRecord2(a="list_in_record2")) - assert(wasm.list_in_record3(store, e.ListInRecord3("list_in_record3 input")).a == "list_in_record3 output") - assert(wasm.list_in_record4(store, e.ListInRecord4("input4")).a == "result4") + assert(wasm.f_list_in_record3(store, e.ListInRecord3("list_in_record3 input")).a == "list_in_record3 output") + assert(wasm.f_list_in_record4(store, e.ListInRecord4("input4")).a == "result4") - wasm.list_in_variant1(store, "foo", e.Err("bar"), 'baz') - assert(wasm.list_in_variant2(store) == "list_in_variant2") - assert(wasm.list_in_variant3(store, "input3") == "output3") + wasm.f_list_in_variant1(store, "foo", e.Err("bar"), 'baz') + assert(wasm.f_list_in_variant2(store) == "list_in_variant2") + assert(wasm.f_list_in_variant3(store, "input3") == "output3") assert(isinstance(wasm.errno_result(store), e.Err)) diff --git a/tests/runtime/flavorful/host.rs b/tests/runtime/flavorful/host.rs index a4b192041..9c72b5aba 100644 --- a/tests/runtime/flavorful/host.rs +++ b/tests/runtime/flavorful/host.rs @@ -8,31 +8,31 @@ use imports::*; pub struct MyImports; impl Imports for MyImports { - fn list_in_record1(&mut self, ty: ListInRecord1<'_>) { + fn f_list_in_record1(&mut self, ty: ListInRecord1<'_>) { assert_eq!(ty.a, "list_in_record1"); } - fn list_in_record2(&mut self) -> ListInRecord2 { + fn f_list_in_record2(&mut self) -> ListInRecord2 { ListInRecord2 { a: "list_in_record2".to_string(), } } - fn list_in_record3(&mut self, a: ListInRecord3Param<'_>) -> ListInRecord3Result { + fn f_list_in_record3(&mut self, a: ListInRecord3Param<'_>) -> ListInRecord3Result { assert_eq!(a.a, "list_in_record3 input"); ListInRecord3Result { a: "list_in_record3 output".to_string(), } } - fn list_in_record4(&mut self, a: ListInAliasParam<'_>) -> ListInAliasResult { + fn f_list_in_record4(&mut self, a: ListInAliasParam<'_>) -> ListInAliasResult { assert_eq!(a.a, "input4"); ListInRecord4Result { a: "result4".to_string(), } } - fn list_in_variant1( + fn f_list_in_variant1( &mut self, a: ListInVariant1V1<'_>, b: ListInVariant1V2<'_>, @@ -46,11 +46,11 @@ impl Imports for MyImports { } } - fn list_in_variant2(&mut self) -> Option { + fn f_list_in_variant2(&mut self) -> Option { Some("list_in_variant2".to_string()) } - fn list_in_variant3(&mut self, a: ListInVariant3Param<'_>) -> Option { + fn f_list_in_variant3(&mut self, a: ListInVariant3Param<'_>) -> Option { assert_eq!(a.unwrap(), "input3"); Some("output3".to_string()) } @@ -104,17 +104,17 @@ fn run(wasm: &str) -> Result<()> { exports.test_imports(&mut store)?; - exports.list_in_record1( + exports.f_list_in_record1( &mut store, ListInRecord1 { a: "list_in_record1", }, )?; - assert_eq!(exports.list_in_record2(&mut store)?.a, "list_in_record2"); + assert_eq!(exports.f_list_in_record2(&mut store)?.a, "list_in_record2"); assert_eq!( exports - .list_in_record3( + .f_list_in_record3( &mut store, ListInRecord3Param { a: "list_in_record3 input" @@ -126,23 +126,23 @@ fn run(wasm: &str) -> Result<()> { assert_eq!( exports - .list_in_record4(&mut store, ListInAliasParam { a: "input4" })? + .f_list_in_record4(&mut store, ListInAliasParam { a: "input4" })? .a, "result4" ); - exports.list_in_variant1( + exports.f_list_in_variant1( &mut store, Some("foo"), Err("bar"), ListInVariant1V3::String("baz"), )?; assert_eq!( - exports.list_in_variant2(&mut store)?, + exports.f_list_in_variant2(&mut store)?, Some("list_in_variant2".to_string()) ); assert_eq!( - exports.list_in_variant3(&mut store, Some("input3"))?, + exports.f_list_in_variant3(&mut store, Some("input3"))?, Some("output3".to_string()) ); diff --git a/tests/runtime/flavorful/host.ts b/tests/runtime/flavorful/host.ts index 1548505e8..277b288cb 100644 --- a/tests/runtime/flavorful/host.ts +++ b/tests/runtime/flavorful/host.ts @@ -8,23 +8,23 @@ import * as assert from 'assert'; async function run() { const importObj = {}; const imports: Imports = { - listInRecord1(x) {}, - listInRecord2() { return { a: 'list_in_record2' }; }, - listInRecord3(x) { + fListInRecord1(x) {}, + fListInRecord2() { return { a: 'list_in_record2' }; }, + fListInRecord3(x) { assert.strictEqual(x.a, 'list_in_record3 input'); return { a: 'list_in_record3 output' }; }, - listInRecord4(x) { + fListInRecord4(x) { assert.strictEqual(x.a, 'input4'); return { a: 'result4' }; }, - listInVariant1(a, b, c) { + fListInVariant1(a, b, c) { assert.strictEqual(a, 'foo'); assert.deepStrictEqual(b, { tag: 'err', val: 'bar' }); assert.deepStrictEqual(c, { tag: 0, val: 'baz' }); }, - listInVariant2() { return 'list_in_variant2'; }, - listInVariant3(x) { + fListInVariant2() { return 'list_in_variant2'; }, + fListInVariant3(x) { assert.strictEqual(x, 'input3'); return 'output3'; }, @@ -57,23 +57,23 @@ async function run() { instance = wasm.instance; wasm.testImports(); - wasm.listInRecord1({ a: "list_in_record1" }); - assert.deepStrictEqual(wasm.listInRecord2(), { a: "list_in_record2" }); + wasm.fListInRecord1({ a: "list_in_record1" }); + assert.deepStrictEqual(wasm.fListInRecord2(), { a: "list_in_record2" }); assert.deepStrictEqual( - wasm.listInRecord3({ a: "list_in_record3 input" }), + wasm.fListInRecord3({ a: "list_in_record3 input" }), { a: "list_in_record3 output" }, ); assert.deepStrictEqual( - wasm.listInRecord4({ a: "input4" }), + wasm.fListInRecord4({ a: "input4" }), { a: "result4" }, ); - wasm.listInVariant1("foo", { tag: 'err', val: 'bar' }, { tag: 0, val: 'baz' }); + wasm.fListInVariant1("foo", { tag: 'err', val: 'bar' }, { tag: 0, val: 'baz' }); - assert.deepStrictEqual(wasm.listInVariant2(), "list_in_variant2"); - assert.deepStrictEqual(wasm.listInVariant3("input3"), "output3"); + assert.deepStrictEqual(wasm.fListInVariant2(), "list_in_variant2"); + assert.deepStrictEqual(wasm.fListInVariant3("input3"), "output3"); assert.deepStrictEqual(wasm.errnoResult().tag, 'err'); diff --git a/tests/runtime/flavorful/imports.wit b/tests/runtime/flavorful/imports.wit index 242d95433..d2b92dca0 100644 --- a/tests/runtime/flavorful/imports.wit +++ b/tests/runtime/flavorful/imports.wit @@ -4,21 +4,21 @@ record list-in-record3 { a: string } record list-in-record4 { a: string } type list-in-alias = list-in-record4 -list-in-record1: func(a: list-in-record1) -list-in-record2: func() -> list-in-record2 -list-in-record3: func(a: list-in-record3) -> list-in-record3 -list-in-record4: func(a: list-in-alias) -> list-in-alias +f-list-in-record1: func(a: list-in-record1) +f-list-in-record2: func() -> list-in-record2 +f-list-in-record3: func(a: list-in-record3) -> list-in-record3 +f-list-in-record4: func(a: list-in-alias) -> list-in-alias type list-in-variant1-v1 = option type list-in-variant1-v2 = result<_, string> union list-in-variant1-v3 { string, float32 } -list-in-variant1: func(a: list-in-variant1-v1, b: list-in-variant1-v2, c: list-in-variant1-v3) +f-list-in-variant1: func(a: list-in-variant1-v1, b: list-in-variant1-v2, c: list-in-variant1-v3) type list-in-variant2 = option -list-in-variant2: func() -> list-in-variant2 +f-list-in-variant2: func() -> list-in-variant2 type list-in-variant3 = option -list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 +f-list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 enum my-errno { success, a, b } errno-result: func() -> result<_, my-errno> diff --git a/tests/runtime/flavorful/wasm.c b/tests/runtime/flavorful/wasm.c index 360809bc3..0ea2c62e1 100644 --- a/tests/runtime/flavorful/wasm.c +++ b/tests/runtime/flavorful/wasm.c @@ -8,10 +8,10 @@ void exports_test_imports() { { imports_list_in_record1_t a; imports_string_set(&a.a, "list_in_record1"); - imports_list_in_record1(&a); + imports_f_list_in_record1(&a); imports_list_in_record2_t b; - imports_list_in_record2(&b); + imports_f_list_in_record2(&b); assert(memcmp(b.a.ptr, "list_in_record2", b.a.len) == 0); imports_list_in_record2_free(&b); } @@ -19,7 +19,7 @@ void exports_test_imports() { { imports_list_in_record3_t a, b; imports_string_set(&a.a, "list_in_record3 input"); - imports_list_in_record3(&a, &b); + imports_f_list_in_record3(&a, &b); assert(memcmp(b.a.ptr, "list_in_record3 output", b.a.len) == 0); imports_list_in_record3_free(&b); } @@ -27,7 +27,7 @@ void exports_test_imports() { { imports_list_in_record4_t a, b; imports_string_set(&a.a, "input4"); - imports_list_in_record4(&a, &b); + imports_f_list_in_record4(&a, &b); assert(memcmp(b.a.ptr, "result4", b.a.len) == 0); imports_list_in_record4_free(&b); } @@ -42,12 +42,12 @@ void exports_test_imports() { imports_string_set(&b.val.err, "bar"); c.tag = 0; imports_string_set(&c.val.f0, "baz"); - imports_list_in_variant1(&a, &b, &c); + imports_f_list_in_variant1(&a, &b, &c); } { imports_string_t a; - assert(imports_list_in_variant2(&a)); + assert(imports_f_list_in_variant2(&a)); assert(memcmp(a.ptr, "list_in_variant2", a.len) == 0); imports_string_free(&a); } @@ -57,7 +57,7 @@ void exports_test_imports() { a.is_some = true; imports_string_set(&a.val, "input3"); imports_string_t b; - assert(imports_list_in_variant3(&a, &b)); + assert(imports_f_list_in_variant3(&a, &b)); assert(memcmp(b.ptr, "output3", b.len) == 0); imports_string_free(&b); } @@ -127,28 +127,28 @@ void exports_test_imports() { } } -void exports_list_in_record1(exports_list_in_record1_t *a) { +void exports_f_list_in_record1(exports_list_in_record1_t *a) { assert(memcmp(a->a.ptr, "list_in_record1", a->a.len) == 0); exports_list_in_record1_free(a); } -void exports_list_in_record2(exports_list_in_record2_t *ret0) { +void exports_f_list_in_record2(exports_list_in_record2_t *ret0) { exports_string_dup(&ret0->a, "list_in_record2"); } -void exports_list_in_record3(exports_list_in_record3_t *a, exports_list_in_record3_t *ret0) { +void exports_f_list_in_record3(exports_list_in_record3_t *a, exports_list_in_record3_t *ret0) { assert(memcmp(a->a.ptr, "list_in_record3 input", a->a.len) == 0); exports_list_in_record3_free(a); exports_string_dup(&ret0->a, "list_in_record3 output"); } -void exports_list_in_record4(exports_list_in_alias_t *a, exports_list_in_alias_t *ret0) { +void exports_f_list_in_record4(exports_list_in_alias_t *a, exports_list_in_alias_t *ret0) { assert(memcmp(a->a.ptr, "input4", a->a.len) == 0); exports_list_in_alias_free(a); exports_string_dup(&ret0->a, "result4"); } -void exports_list_in_variant1(exports_list_in_variant1_v1_t *a, exports_list_in_variant1_v2_t *b, exports_list_in_variant1_v3_t *c) { +void exports_f_list_in_variant1(exports_list_in_variant1_v1_t *a, exports_list_in_variant1_v2_t *b, exports_list_in_variant1_v3_t *c) { assert(a->is_some); assert(memcmp(a->val.ptr, "foo", a->val.len) == 0); exports_list_in_variant1_v1_free(a); @@ -162,12 +162,12 @@ void exports_list_in_variant1(exports_list_in_variant1_v1_t *a, exports_list_in_ exports_list_in_variant1_v3_free(c); } -bool exports_list_in_variant2(exports_string_t *ret0) { +bool exports_f_list_in_variant2(exports_string_t *ret0) { exports_string_dup(ret0, "list_in_variant2"); return true; } -bool exports_list_in_variant3(exports_list_in_variant3_t *a, exports_string_t *ret0) { +bool exports_f_list_in_variant3(exports_list_in_variant3_t *a, exports_string_t *ret0) { assert(a->is_some); assert(memcmp(a->val.ptr, "input3", a->val.len) == 0); exports_list_in_variant3_free(a); diff --git a/tests/runtime/flavorful/wasm.rs b/tests/runtime/flavorful/wasm.rs index 719630901..4783923d3 100644 --- a/tests/runtime/flavorful/wasm.rs +++ b/tests/runtime/flavorful/wasm.rs @@ -11,13 +11,13 @@ impl exports::Exports for Exports { let _guard = test_rust_wasm::guard(); - list_in_record1(ListInRecord1 { + f_list_in_record1(ListInRecord1 { a: "list_in_record1", }); - assert_eq!(list_in_record2().a, "list_in_record2"); + assert_eq!(f_list_in_record2().a, "list_in_record2"); assert_eq!( - list_in_record3(ListInRecord3Param { + f_list_in_record3(ListInRecord3Param { a: "list_in_record3 input" }) .a, @@ -25,14 +25,14 @@ impl exports::Exports for Exports { ); assert_eq!( - list_in_record4(ListInAliasParam { a: "input4" }).a, + f_list_in_record4(ListInAliasParam { a: "input4" }).a, "result4" ); - list_in_variant1(Some("foo"), Err("bar"), ListInVariant1V3::String("baz")); - assert_eq!(list_in_variant2(), Some("list_in_variant2".to_string())); + f_list_in_variant1(Some("foo"), Err("bar"), ListInVariant1V3::String("baz")); + assert_eq!(f_list_in_variant2(), Some("list_in_variant2".to_string())); assert_eq!( - list_in_variant3(Some("input3")), + f_list_in_variant3(Some("input3")), Some("output3".to_string()) ); @@ -57,31 +57,31 @@ impl exports::Exports for Exports { assert_eq!(c, [MyErrno::A, MyErrno::B]); } - fn list_in_record1(ty: ListInRecord1) { + fn f_list_in_record1(ty: ListInRecord1) { assert_eq!(ty.a, "list_in_record1"); } - fn list_in_record2() -> ListInRecord2 { + fn f_list_in_record2() -> ListInRecord2 { ListInRecord2 { a: "list_in_record2".to_string(), } } - fn list_in_record3(a: ListInRecord3) -> ListInRecord3 { + fn f_list_in_record3(a: ListInRecord3) -> ListInRecord3 { assert_eq!(a.a, "list_in_record3 input"); ListInRecord3 { a: "list_in_record3 output".to_string(), } } - fn list_in_record4(a: ListInAlias) -> ListInAlias { + fn f_list_in_record4(a: ListInAlias) -> ListInAlias { assert_eq!(a.a, "input4"); ListInRecord4 { a: "result4".to_string(), } } - fn list_in_variant1(a: ListInVariant1V1, b: ListInVariant1V2, c: ListInVariant1V3) { + fn f_list_in_variant1(a: ListInVariant1V1, b: ListInVariant1V2, c: ListInVariant1V3) { assert_eq!(a.unwrap(), "foo"); assert_eq!(b.unwrap_err(), "bar"); match c { @@ -90,11 +90,11 @@ impl exports::Exports for Exports { } } - fn list_in_variant2() -> Option { + fn f_list_in_variant2() -> Option { Some("list_in_variant2".to_string()) } - fn list_in_variant3(a: ListInVariant3) -> Option { + fn f_list_in_variant3(a: ListInVariant3) -> Option { assert_eq!(a.unwrap(), "input3"); Some("output3".to_string()) }