From 48dadcf90c4f86b4d607f86271250b953ecd48da Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 9 Sep 2022 08:54:38 -0700 Subject: [PATCH 1/5] Rename `canonical_abi_realloc` to `cabi_realloc`. This follows the current Canonical ABI. This doesn't rename `canonical_abi_free`, as that's expected to be removed when post-return functions are implemented. --- crates/gen-guest-c/src/lib.rs | 6 +++--- .../spidermonkey-wasm/bindgen.cpp | 2 +- crates/gen-guest-spidermonkey-js/src/lib.rs | 6 +++--- crates/guest-rust/src/lib.rs | 2 +- crates/wit-component/src/encoding.rs | 4 ++-- crates/wit-component/src/validation.rs | 6 +++--- .../components/ensure-default-type-exports/component.wat | 4 ++-- .../components/ensure-default-type-exports/module.wat | 2 +- .../wit-component/tests/components/exports/component.wat | 4 ++-- crates/wit-component/tests/components/exports/module.wat | 2 +- .../tests/components/import-conflict/component.wat | 4 ++-- .../tests/components/import-conflict/module.wat | 2 +- .../tests/components/import-export/component.wat | 4 ++-- .../tests/components/import-export/module.wat | 2 +- .../wit-component/tests/components/imports/component.wat | 4 ++-- crates/wit-component/tests/components/imports/module.wat | 2 +- .../tests/components/lift-options/component.wat | 4 ++-- .../tests/components/lift-options/module.wat | 2 +- .../tests/components/lower-options/component.wat | 4 ++-- .../tests/components/lower-options/module.wat | 2 +- .../wit-component/tests/components/simple/component.wat | 6 +++--- crates/wit-component/tests/components/simple/module.wat | 2 +- crates/wit-parser/src/abi.rs | 4 ++-- tests/runtime/lists/wasm.c | 8 ++++---- 24 files changed, 44 insertions(+), 44 deletions(-) diff --git a/crates/gen-guest-c/src/lib.rs b/crates/gen-guest-c/src/lib.rs index c9875af0f..9aafdecef 100644 --- a/crates/gen-guest-c/src/lib.rs +++ b/crates/gen-guest-c/src/lib.rs @@ -411,8 +411,8 @@ impl C { // Note that these intrinsics are declared as `weak` so they can be // overridden from some other symbol. self.src.c(" - __attribute__((weak, export_name(\"canonical_abi_realloc\"))) - void *canonical_abi_realloc( + __attribute__((weak, export_name(\"cabi_realloc\"))) + void *cabi_realloc( void *ptr, size_t orig_size, size_t org_align, @@ -1279,7 +1279,7 @@ impl Generator for C { void {0}_string_dup({0}_string_t *ret, const char *s) {{ ret->len = strlen(s); - ret->ptr = canonical_abi_realloc(NULL, 0, 1, ret->len); + ret->ptr = cabi_realloc(NULL, 0, 1, ret->len); memcpy(ret->ptr, s, ret->len); }} diff --git a/crates/gen-guest-spidermonkey-js/spidermonkey-wasm/bindgen.cpp b/crates/gen-guest-spidermonkey-js/spidermonkey-wasm/bindgen.cpp index 95ddbf377..e82371c2f 100644 --- a/crates/gen-guest-spidermonkey-js/spidermonkey-wasm/bindgen.cpp +++ b/crates/gen-guest-spidermonkey-js/spidermonkey-wasm/bindgen.cpp @@ -109,7 +109,7 @@ void canonical_abi_free(void* ptr, size_t size, size_t align) { } WASM_EXPORT -void* canonical_abi_realloc(void* ptr, size_t old_size, size_t align, size_t new_size) { +void* cabi_realloc(void* ptr, size_t old_size, size_t align, size_t new_size) { (void) old_size; (void) align; return realloc(ptr, new_size); diff --git a/crates/gen-guest-spidermonkey-js/src/lib.rs b/crates/gen-guest-spidermonkey-js/src/lib.rs index 905fad25b..b585bec99 100644 --- a/crates/gen-guest-spidermonkey-js/src/lib.rs +++ b/crates/gen-guest-spidermonkey-js/src/lib.rs @@ -63,7 +63,7 @@ lazy_static! { }, ), ( - "canonical_abi_realloc", + "cabi_realloc", WasmSignature { params: vec![WasmType::I32, WasmType::I32, WasmType::I32, WasmType::I32], results: vec![WasmType::I32], @@ -1139,8 +1139,8 @@ impl Generator for SpiderMonkeyWasm<'_> { wasm_encoder::Export::Function(self.spidermonkey_import("canonical_abi_free")), ); self.exports.export( - "canonical_abi_realloc", - wasm_encoder::Export::Function(self.spidermonkey_import("canonical_abi_realloc")), + "cabi_realloc", + wasm_encoder::Export::Function(self.spidermonkey_import("cabi_realloc")), ); // Add the WIT function imports (add their import glue functions) to diff --git a/crates/guest-rust/src/lib.rs b/crates/guest-rust/src/lib.rs index 6326cfd11..e61f53af1 100644 --- a/crates/guest-rust/src/lib.rs +++ b/crates/guest-rust/src/lib.rs @@ -126,7 +126,7 @@ pub mod rt { use std::alloc::{self, Layout}; #[no_mangle] - unsafe extern "C" fn canonical_abi_realloc( + unsafe extern "C" fn cabi_realloc( old_ptr: *mut u8, old_len: usize, align: usize, diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 4c341f8df..3f042c2b1 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -912,7 +912,7 @@ impl RequiredOptions { } iter.push(CanonicalOption::Realloc(realloc_index.ok_or_else( - || anyhow!("module does not export a function named `canonical_abi_realloc`"), + || anyhow!("module does not export a function named `cabi_realloc`"), )?)); if self == RequiredOptions::Realloc { @@ -1356,7 +1356,7 @@ impl EncodingState { &mut aliases, instance_index, ExportKind::Func, - "canonical_abi_realloc", + "cabi_realloc", )); } diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index acd4f7c21..c4267dcdf 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -15,7 +15,7 @@ fn is_wasi(name: &str) -> bool { } fn is_canonical_function(name: &str) -> bool { - name.starts_with("canonical_abi_") + name.starts_with("cabi_") } pub fn expected_export_name<'a>(interface: Option<&str>, func: &'a str) -> Cow<'a, str> { @@ -115,8 +115,8 @@ pub fn validate_module<'a>( match export.kind { ExternalKind::Func => { if is_canonical_function(export.name) { - if export.name == "canonical_abi_realloc" { - // TODO: validate that the canonical_abi_realloc function is [i32, i32, i32, i32] -> [i32] + if export.name == "cabi_realloc" { + // TODO: validate that the cabi_realloc function is [i32, i32, i32, i32] -> [i32] has_realloc = true; } continue; diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat index 9877f0950..41b7cf466 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat +++ b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat @@ -23,7 +23,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 1)) + (export "cabi_realloc" (func 1)) (export "a" (func 2)) ) (alias export 0 "a" (func (;0;))) @@ -36,7 +36,7 @@ ) ) (core alias export 1 "memory" (memory (;0;))) - (core alias export 1 "canonical_abi_realloc" (func (;1;))) + (core alias export 1 "cabi_realloc" (func (;1;))) (core alias export 1 "a" (func (;2;))) (func (;1;) (type 2) (canon lift (core func 2))) (export "a" (func 1)) diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/module.wat b/crates/wit-component/tests/components/ensure-default-type-exports/module.wat index 78c731484..4ddbbd471 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/module.wat +++ b/crates/wit-component/tests/components/ensure-default-type-exports/module.wat @@ -1,6 +1,6 @@ (module (import "foo" "a" (func (param i32))) (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func (export "a") (param i32) unreachable) ) diff --git a/crates/wit-component/tests/components/exports/component.wat b/crates/wit-component/tests/components/exports/component.wat index 75c61b4e5..af82b26a4 100644 --- a/crates/wit-component/tests/components/exports/component.wat +++ b/crates/wit-component/tests/components/exports/component.wat @@ -42,7 +42,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 0)) + (export "cabi_realloc" (func 0)) (export "a" (func 1)) (export "b" (func 2)) (export "c" (func 3)) @@ -53,7 +53,7 @@ ) (core instance (;0;) (instantiate 0)) (core alias export 0 "memory" (memory (;0;))) - (core alias export 0 "canonical_abi_realloc" (func (;0;))) + (core alias export 0 "cabi_realloc" (func (;0;))) (core alias export 0 "a" (func (;1;))) (core alias export 0 "b" (func (;2;))) (core alias export 0 "c" (func (;3;))) diff --git a/crates/wit-component/tests/components/exports/module.wat b/crates/wit-component/tests/components/exports/module.wat index e01316a0d..b8c45365c 100644 --- a/crates/wit-component/tests/components/exports/module.wat +++ b/crates/wit-component/tests/components/exports/module.wat @@ -1,6 +1,6 @@ (module (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func (export "a") unreachable) (func (export "b") (param i32 i32 i32 i64) (result i32) unreachable) (func (export "c") (result i32) unreachable) diff --git a/crates/wit-component/tests/components/import-conflict/component.wat b/crates/wit-component/tests/components/import-conflict/component.wat index b7d14af4e..817566313 100644 --- a/crates/wit-component/tests/components/import-conflict/component.wat +++ b/crates/wit-component/tests/components/import-conflict/component.wat @@ -37,7 +37,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 3)) + (export "cabi_realloc" (func 3)) ) (core module (;1;) (type (;0;) (func (param i64 i32 i32))) @@ -90,7 +90,7 @@ ) ) (core alias export 4 "memory" (memory (;0;))) - (core alias export 4 "canonical_abi_realloc" (func (;3;))) + (core alias export 4 "cabi_realloc" (func (;3;))) (core alias export 0 "$imports" (table (;0;))) (alias export 0 "a" (func (;1;))) (alias export 1 "baz" (func (;2;))) diff --git a/crates/wit-component/tests/components/import-conflict/module.wat b/crates/wit-component/tests/components/import-conflict/module.wat index f58dc5d69..b7cacf1a0 100644 --- a/crates/wit-component/tests/components/import-conflict/module.wat +++ b/crates/wit-component/tests/components/import-conflict/module.wat @@ -3,5 +3,5 @@ (import "bar" "a" (func (param i64 i32 i32))) (import "baz" "baz" (func (param i32 i32 i32))) (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/import-export/component.wat b/crates/wit-component/tests/components/import-export/component.wat index cec59b6f9..647bc603c 100644 --- a/crates/wit-component/tests/components/import-export/component.wat +++ b/crates/wit-component/tests/components/import-export/component.wat @@ -31,7 +31,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 1)) + (export "cabi_realloc" (func 1)) (export "a" (func 2)) (export "bar#a" (func 3)) (export "bar#b" (func 4)) @@ -63,7 +63,7 @@ ) ) (core alias export 2 "memory" (memory (;0;))) - (core alias export 2 "canonical_abi_realloc" (func (;1;))) + (core alias export 2 "cabi_realloc" (func (;1;))) (core alias export 0 "$imports" (table (;0;))) (alias export 0 "a" (func (;0;))) (core func (;2;) (canon lower (func 0) (memory 0) (realloc 1) string-encoding=utf8)) diff --git a/crates/wit-component/tests/components/import-export/module.wat b/crates/wit-component/tests/components/import-export/module.wat index 1d7c3998c..ebc538ade 100644 --- a/crates/wit-component/tests/components/import-export/module.wat +++ b/crates/wit-component/tests/components/import-export/module.wat @@ -1,7 +1,7 @@ (module (import "foo" "a" (func (param i32))) (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func (export "a") (param i32 i32) (result i32) unreachable) (func (export "bar#a") unreachable) (func (export "bar#b") (result i32) unreachable) diff --git a/crates/wit-component/tests/components/imports/component.wat b/crates/wit-component/tests/components/imports/component.wat index fe05fa4b5..7c38a436f 100644 --- a/crates/wit-component/tests/components/imports/component.wat +++ b/crates/wit-component/tests/components/imports/component.wat @@ -59,7 +59,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 8)) + (export "cabi_realloc" (func 8)) ) (core module (;1;) (type (;0;) (func (param i32 i32))) @@ -123,7 +123,7 @@ ) ) (core alias export 4 "memory" (memory (;0;))) - (core alias export 4 "canonical_abi_realloc" (func (;8;))) + (core alias export 4 "cabi_realloc" (func (;8;))) (core alias export 0 "$imports" (table (;0;))) (alias export 0 "bar1" (func (;6;))) (alias export 1 "baz1" (func (;7;))) diff --git a/crates/wit-component/tests/components/imports/module.wat b/crates/wit-component/tests/components/imports/module.wat index 19d3bca84..8887f9118 100644 --- a/crates/wit-component/tests/components/imports/module.wat +++ b/crates/wit-component/tests/components/imports/module.wat @@ -8,5 +8,5 @@ (import "baz" "baz2" (func)) (import "baz" "baz3" (func (param i32))) (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/lift-options/component.wat b/crates/wit-component/tests/components/lift-options/component.wat index 484fe905c..756ddd98f 100644 --- a/crates/wit-component/tests/components/lift-options/component.wat +++ b/crates/wit-component/tests/components/lift-options/component.wat @@ -89,7 +89,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 0)) + (export "cabi_realloc" (func 0)) (export "a" (func 1)) (export "b" (func 2)) (export "c" (func 3)) @@ -109,7 +109,7 @@ ) (core instance (;0;) (instantiate 0)) (core alias export 0 "memory" (memory (;0;))) - (core alias export 0 "canonical_abi_realloc" (func (;0;))) + (core alias export 0 "cabi_realloc" (func (;0;))) (core alias export 0 "a" (func (;1;))) (core alias export 0 "b" (func (;2;))) (core alias export 0 "c" (func (;3;))) diff --git a/crates/wit-component/tests/components/lift-options/module.wat b/crates/wit-component/tests/components/lift-options/module.wat index 77fded3cd..19ea512a0 100644 --- a/crates/wit-component/tests/components/lift-options/module.wat +++ b/crates/wit-component/tests/components/lift-options/module.wat @@ -1,6 +1,6 @@ (module (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func (export "a") unreachable) (func (export "b") (param i32 i32) unreachable) (func (export "c") (param i32 i32) unreachable) diff --git a/crates/wit-component/tests/components/lower-options/component.wat b/crates/wit-component/tests/components/lower-options/component.wat index 6b8c28034..7a04c2106 100644 --- a/crates/wit-component/tests/components/lower-options/component.wat +++ b/crates/wit-component/tests/components/lower-options/component.wat @@ -90,7 +90,7 @@ ) (memory (;0;) 1) (export "memory" (memory 0)) - (export "canonical_abi_realloc" (func 16)) + (export "cabi_realloc" (func 16)) ) (core module (;1;) (type (;0;) (func (param i32 i32))) @@ -235,7 +235,7 @@ ) ) (core alias export 2 "memory" (memory (;0;))) - (core alias export 2 "canonical_abi_realloc" (func (;16;))) + (core alias export 2 "cabi_realloc" (func (;16;))) (core alias export 0 "$imports" (table (;0;))) (alias export 0 "b" (func (;5;))) (alias export 0 "c" (func (;6;))) diff --git a/crates/wit-component/tests/components/lower-options/module.wat b/crates/wit-component/tests/components/lower-options/module.wat index 7950a6367..4a44c57b3 100644 --- a/crates/wit-component/tests/components/lower-options/module.wat +++ b/crates/wit-component/tests/components/lower-options/module.wat @@ -16,5 +16,5 @@ (import "foo" "o" (func (param i32))) (import "foo" "p" (func (param i32))) (memory (export "memory") 1) - (func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/simple/component.wat b/crates/wit-component/tests/components/simple/component.wat index f2d6dfb41..a3662a696 100644 --- a/crates/wit-component/tests/components/simple/component.wat +++ b/crates/wit-component/tests/components/simple/component.wat @@ -11,7 +11,7 @@ (type (;2;) (func (result i32))) (type (;3;) (func (param i32 i32) (result i32))) (type (;4;) (func (param i32 i32))) - (func $canonical_abi_realloc (;0;) (type 0) (param i32 i32 i32 i32) (result i32) + (func $cabi_realloc (;0;) (type 0) (param i32 i32 i32 i32) (result i32) unreachable ) (func $a (;1;) (type 1) @@ -28,7 +28,7 @@ ) (memory $memory (;0;) 1) (export "memory" (memory $memory)) - (export "canonical_abi_realloc" (func $canonical_abi_realloc)) + (export "cabi_realloc" (func $cabi_realloc)) (export "a" (func $a)) (export "b" (func $b)) (export "c" (func $c)) @@ -36,7 +36,7 @@ ) (core instance (;0;) (instantiate 0)) (core alias export 0 "memory" (memory (;0;))) - (core alias export 0 "canonical_abi_realloc" (func (;0;))) + (core alias export 0 "cabi_realloc" (func (;0;))) (core alias export 0 "a" (func (;1;))) (core alias export 0 "b" (func (;2;))) (core alias export 0 "c" (func (;3;))) diff --git a/crates/wit-component/tests/components/simple/module.wat b/crates/wit-component/tests/components/simple/module.wat index a7aebe353..48abd4a20 100644 --- a/crates/wit-component/tests/components/simple/module.wat +++ b/crates/wit-component/tests/components/simple/module.wat @@ -1,6 +1,6 @@ (module (memory $memory (export "memory") 1) - (func $canonical_abi_realloc (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) + (func $cabi_realloc (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func $a (export "a") unreachable) (func $b (export "b") (result i32) unreachable) (func $c (export "c") (param i32 i32) (result i32) unreachable) diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs index b1c5fda30..493bbadd5 100644 --- a/crates/wit-parser/src/abi.rs +++ b/crates/wit-parser/src/abi.rs @@ -1047,7 +1047,7 @@ impl<'a, B: Bindgen> Generator<'a, B> { // malloc needs to be called. AbiVariant::GuestExport => { self.emit(&Instruction::Malloc { - realloc: "canonical_abi_realloc", + realloc: "cabi_realloc", size, align, }); @@ -1469,7 +1469,7 @@ impl<'a, B: Bindgen> Generator<'a, B> { // ownership in all other cases. match (self.variant, self.lift_lower) { (AbiVariant::GuestImport, LiftLower::LowerArgsLiftResults) => None, - _ => Some("canonical_abi_realloc"), + _ => Some("cabi_realloc"), } } diff --git a/tests/runtime/lists/wasm.c b/tests/runtime/lists/wasm.c index 9079a93b9..e5833608c 100644 --- a/tests/runtime/lists/wasm.c +++ b/tests/runtime/lists/wasm.c @@ -12,8 +12,8 @@ static size_t ALLOCATED_BYTES = 0; -__attribute__((export_name("canonical_abi_realloc"))) -void *canonical_abi_realloc( void *ptr, size_t orig_size, size_t orig_align, size_t new_size) { +__attribute__((export_name("cabi_realloc"))) +void *cabi_realloc( void *ptr, size_t orig_size, size_t orig_align, size_t new_size) { void *ret = realloc(ptr, new_size); if (!ret) abort(); @@ -306,7 +306,7 @@ void exports_list_param4(exports_list_list_string_t *a) { } void exports_list_result(exports_list_u8_t *ret0) { - ret0->ptr = canonical_abi_realloc(NULL, 0, 1, 5); + ret0->ptr = cabi_realloc(NULL, 0, 1, 5); ret0->len = 5; ret0->ptr[0] = 1; ret0->ptr[1] = 2; @@ -321,7 +321,7 @@ void exports_list_result2(exports_string_t *ret0) { void exports_list_result3(exports_list_string_t *ret0) { ret0->len = 2; - ret0->ptr = canonical_abi_realloc(NULL, 0, alignof(exports_string_t), 2 * sizeof(exports_string_t)); + ret0->ptr = cabi_realloc(NULL, 0, alignof(exports_string_t), 2 * sizeof(exports_string_t)); exports_string_dup(&ret0->ptr[0], "hello,"); exports_string_dup(&ret0->ptr[1], "world!"); From bb0cc5af976ebc035d345b09d2b682414ea26e27 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 9 Sep 2022 15:05:31 -0700 Subject: [PATCH 2/5] Rename the "expected" type to "result". This follows the current Canonical ABI. --- TODO.md | 2 +- crates/bindgen-core/src/lib.rs | 18 +-- crates/gen-guest-c/src/lib.rs | 112 +++++++++--------- crates/gen-guest-rust/src/lib.rs | 10 +- crates/gen-guest-spidermonkey-js/src/lib.rs | 12 +- crates/gen-host-js/src/lib.rs | 20 ++-- .../gen-host-wasmtime-py/src/dependencies.rs | 6 +- crates/gen-host-wasmtime-py/src/lib.rs | 16 +-- crates/gen-host-wasmtime-py/src/source.rs | 10 +- crates/gen-host-wasmtime-rust/src/lib.rs | 18 +-- .../gen-host-wasmtime-rust/tests/codegen.rs | 4 +- crates/gen-markdown/src/lib.rs | 18 +-- crates/gen-rust-lib/src/lib.rs | 18 +-- crates/test-helpers/src/lib.rs | 6 +- crates/wit-bindgen-demo/demo.wit | 2 +- crates/wit-component/src/decoding.rs | 6 +- crates/wit-component/src/encoding.rs | 34 +++--- crates/wit-component/src/printing.rs | 28 ++--- .../tests/interfaces/variants/variants.wit | 14 +-- crates/wit-parser/src/abi.rs | 52 ++++---- crates/wit-parser/src/ast.rs | 10 +- crates/wit-parser/src/ast/lex.rs | 6 +- crates/wit-parser/src/ast/resolve.rs | 22 ++-- crates/wit-parser/src/lib.rs | 12 +- crates/wit-parser/src/sizealign.rs | 2 +- crates/wit-parser/tests/all.rs | 8 +- crates/wit-parser/tests/ui/functions.wit | 2 +- .../wit-parser/tests/ui/functions.wit.result | 2 +- crates/wit-parser/tests/ui/types.wit | 8 +- crates/wit-parser/tests/ui/types.wit.result | 8 +- crates/wit-parser/tests/ui/wasi-clock.wit | 4 +- .../wit-parser/tests/ui/wasi-clock.wit.result | 2 +- crates/wit-parser/tests/ui/wasi-http.wit | 7 +- .../wit-parser/tests/ui/wasi-http.wit.result | 2 +- tests/codegen/small-anonymous.wit | 2 +- tests/codegen/variants.wit | 38 +++--- tests/runtime/flavorful/exports.wit | 4 +- tests/runtime/flavorful/host.py | 4 +- tests/runtime/flavorful/imports.wit | 6 +- tests/runtime/flavorful/wasm.c | 8 +- tests/runtime/handles/exports.wit | 4 +- tests/runtime/handles/imports.wit | 4 +- tests/runtime/variants/exports.wit | 4 +- tests/runtime/variants/host.py | 4 +- tests/runtime/variants/imports.wit | 6 +- tests/runtime/variants/wasm.c | 8 +- 46 files changed, 293 insertions(+), 300 deletions(-) diff --git a/TODO.md b/TODO.md index cdde2d52c..5d08da9df 100644 --- a/TODO.md +++ b/TODO.md @@ -25,7 +25,7 @@ * Is there a better representation for flags than simply an integer? -* Should functions returning `expected` get translated in JS to functions +* Should functions returning `result` get translated in JS to functions that return `T` and throw `E`? * Adding imports to an import object is clunky because you need to also pass in diff --git a/crates/bindgen-core/src/lib.rs b/crates/bindgen-core/src/lib.rs index 6588dc984..b2f90b335 100644 --- a/crates/bindgen-core/src/lib.rs +++ b/crates/bindgen-core/src/lib.rs @@ -74,12 +74,12 @@ pub trait Generator { payload: &Type, docs: &Docs, ); - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ); fn type_union(&mut self, iface: &Interface, id: TypeId, name: &str, union: &Union, docs: &Docs); @@ -122,7 +122,7 @@ pub trait Generator { self.type_variant(iface, id, name, variant, &ty.docs) } TypeDefKind::Option(t) => self.type_option(iface, id, name, t, &ty.docs), - TypeDefKind::Expected(e) => self.type_expected(iface, id, name, e, &ty.docs), + TypeDefKind::Result(r) => self.type_result(iface, id, name, r, &ty.docs), TypeDefKind::Union(u) => self.type_union(iface, id, name, u, &ty.docs), TypeDefKind::List(t) => self.type_list(iface, id, name, t, &ty.docs), TypeDefKind::Type(t) => self.type_alias(iface, id, name, t, &ty.docs), @@ -245,9 +245,9 @@ impl Types { TypeDefKind::Option(ty) => { info = self.type_info(iface, ty); } - TypeDefKind::Expected(e) => { - info = self.type_info(iface, &e.ok); - info |= self.type_info(iface, &e.err); + TypeDefKind::Result(r) => { + info = self.type_info(iface, &r.ok); + info |= self.type_info(iface, &r.err); } TypeDefKind::Union(u) => { for case in u.cases.iter() { @@ -299,9 +299,9 @@ impl Types { TypeDefKind::List(ty) | TypeDefKind::Type(ty) | TypeDefKind::Option(ty) => { self.set_param_result_ty(iface, ty, param, result) } - TypeDefKind::Expected(e) => { - self.set_param_result_ty(iface, &e.ok, param, result); - self.set_param_result_ty(iface, &e.err, param, result); + TypeDefKind::Result(r) => { + self.set_param_result_ty(iface, &r.ok, param, result); + self.set_param_result_ty(iface, &r.err, param, result); } TypeDefKind::Union(u) => { for case in u.cases.iter() { diff --git a/crates/gen-guest-c/src/lib.rs b/crates/gen-guest-c/src/lib.rs index 9aafdecef..91adc28d9 100644 --- a/crates/gen-guest-c/src/lib.rs +++ b/crates/gen-guest-c/src/lib.rs @@ -73,7 +73,7 @@ struct CSig { enum Scalar { Void, OptionBool(Type), - ExpectedEnum { err: TypeId, max_err: usize }, + ResultEnum { err: TypeId, max_err: usize }, Type(Type), } @@ -113,7 +113,7 @@ impl C { match &ret.scalar { None | Some(Scalar::Void) => self.src.h("void"), Some(Scalar::OptionBool(_id)) => self.src.h("bool"), - Some(Scalar::ExpectedEnum { err, .. }) => self.print_ty(iface, &Type::Id(*err)), + Some(Scalar::ResultEnum { err, .. }) => self.print_ty(iface, &Type::Id(*err)), Some(Scalar::Type(ty)) => self.print_ty(iface, ty), } self.src.h(" "); @@ -169,7 +169,7 @@ impl C { TypeDefKind::Variant(_) => true, TypeDefKind::Union(_) => true, TypeDefKind::Option(_) => true, - TypeDefKind::Expected(_) => true, + TypeDefKind::Result(_) => true, TypeDefKind::Enum(_) => false, TypeDefKind::Flags(_) => false, TypeDefKind::Tuple(_) | TypeDefKind::Record(_) | TypeDefKind::List(_) => true, @@ -305,11 +305,11 @@ impl C { self.src.h("option_"); self.print_ty_name(iface, ty); } - TypeDefKind::Expected(e) => { - self.src.h("expected_"); - self.print_ty_name(iface, &e.ok); + TypeDefKind::Result(r) => { + self.src.h("result_"); + self.print_ty_name(iface, &r.ok); self.src.h("_"); - self.print_ty_name(iface, &e.err); + self.print_ty_name(iface, &r.err); } TypeDefKind::List(t) => { self.src.h("list_"); @@ -360,17 +360,17 @@ impl C { } self.src.h("}"); } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { self.src.h("struct { bool is_err; union { "); - if !self.is_empty_type(iface, &e.ok) { - self.print_ty(iface, &e.ok); + if !self.is_empty_type(iface, &r.ok) { + self.print_ty(iface, &r.ok); self.src.h(" ok;\n"); } - if !self.is_empty_type(iface, &e.err) { - self.print_ty(iface, &e.err); + if !self.is_empty_type(iface, &r.err) { + self.print_ty(iface, &r.err); self.src.h(" err;\n"); } self.src.h("} val;\n"); @@ -535,14 +535,14 @@ impl C { self.src.c("}\n"); } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { self.src.c("if (!ptr->is_err) {\n"); - if self.owns_anything(iface, &e.ok) { - self.free(iface, &e.ok, "&ptr->val.ok"); + if self.owns_anything(iface, &r.ok) { + self.free(iface, &r.ok, "&ptr->val.ok"); } - if self.owns_anything(iface, &e.err) { + if self.owns_anything(iface, &r.err) { self.src.c("} else {\n"); - self.free(iface, &e.err, "&ptr->val.err"); + self.free(iface, &r.err, "&ptr->val.err"); } self.src.c("}\n"); } @@ -572,8 +572,8 @@ impl C { .iter() .any(|case| self.owns_anything(iface, &case.ty)), TypeDefKind::Option(t) => self.owns_anything(iface, t), - TypeDefKind::Expected(e) => { - self.owns_anything(iface, &e.ok) || self.owns_anything(iface, &e.err) + TypeDefKind::Result(r) => { + self.owns_anything(iface, &r.ok) || self.owns_anything(iface, &r.err) } TypeDefKind::Future(_) => todo!("owns_anything for future"), TypeDefKind::Stream(_) => todo!("owns_anything for stream"), @@ -654,17 +654,17 @@ impl Return { self.retptrs.push(*ty); } - // Unpack `expected` returns where `E` looks like an enum + // Unpack `result` returns where `E` looks like an enum // so we can return that in the scalar return and have `T` get // returned through the normal returns. - TypeDefKind::Expected(e) => { - if let Type::Id(err) = e.err { + TypeDefKind::Result(r) => { + if let Type::Id(err) = r.err { if let TypeDefKind::Enum(enum_) = &iface.types[err].kind { - self.scalar = Some(Scalar::ExpectedEnum { + self.scalar = Some(Scalar::ResultEnum { err, max_err: enum_.cases.len(), }); - self.splat_tuples(iface, &e.ok, &e.ok); + self.splat_tuples(iface, &r.ok, &r.ok); return; } } @@ -887,12 +887,12 @@ impl Generator for C { self.types.insert(id, mem::replace(&mut self.src.h, prev)); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { let prev = mem::take(&mut self.src.h); @@ -901,12 +901,12 @@ impl Generator for C { self.src.h("typedef struct {\n"); self.src.h("bool is_err;\n"); self.src.h("union {\n"); - if !self.is_empty_type(iface, &expected.ok) { - self.print_ty(iface, &expected.ok); + if !self.is_empty_type(iface, &result.ok) { + self.print_ty(iface, &result.ok); self.src.h(" ok;\n"); } - if !self.is_empty_type(iface, &expected.err) { - self.print_ty(iface, &expected.err); + if !self.is_empty_type(iface, &result.err) { + self.print_ty(iface, &result.err); self.src.h(" err;\n"); } self.src.h("} val;\n"); @@ -1856,9 +1856,9 @@ impl Bindgen for FunctionBindgen<'_> { results.push(result); } - Instruction::ExpectedLower { + Instruction::ResultLower { results: result_types, - expected, + result, .. } => { let (mut err, err_results) = self.blocks.pop().unwrap(); @@ -1867,7 +1867,7 @@ impl Bindgen for FunctionBindgen<'_> { let ok_payload = self.payloads.pop().unwrap(); for (i, ty) in result_types.iter().enumerate() { - let name = self.locals.tmp("expected"); + let name = self.locals.tmp("result"); results.push(name.clone()); self.src.push_str(wasm_type(*ty)); self.src.push_str(" "); @@ -1880,14 +1880,14 @@ impl Bindgen for FunctionBindgen<'_> { } let op0 = &operands[0]; - let ok_ty = self.gen.type_string(iface, &expected.ok); - let err_ty = self.gen.type_string(iface, &expected.err); - let bind_ok = if self.gen.is_empty_type(iface, &expected.ok) { + let ok_ty = self.gen.type_string(iface, &result.ok); + let err_ty = self.gen.type_string(iface, &result.err); + let bind_ok = if self.gen.is_empty_type(iface, &result.ok) { String::new() } else { format!("const {ok_ty} *{ok_payload} = &({op0}).val.ok;") }; - let bind_err = if self.gen.is_empty_type(iface, &expected.err) { + let bind_err = if self.gen.is_empty_type(iface, &result.err) { String::new() } else { format!("const {err_ty} *{err_payload} = &({op0}).val.err;") @@ -1906,7 +1906,7 @@ impl Bindgen for FunctionBindgen<'_> { ); } - Instruction::ExpectedLift { expected, ty, .. } => { + Instruction::ResultLift { result, ty, .. } => { let (err, err_results) = self.blocks.pop().unwrap(); assert!(err_results.len() == 1); let err_result = &err_results[0]; @@ -1914,39 +1914,39 @@ impl Bindgen for FunctionBindgen<'_> { assert!(ok_results.len() == 1); let ok_result = &ok_results[0]; - let result = self.locals.tmp("expected"); - let set_ok = if self.gen.is_empty_type(iface, &expected.ok) { + let result_tmp = self.locals.tmp("result"); + let set_ok = if self.gen.is_empty_type(iface, &result.ok) { String::new() } else { - format!("{result}.val.ok = {ok_result};") + format!("{result_tmp}.val.ok = {ok_result};") }; - let set_err = if self.gen.is_empty_type(iface, &expected.err) { + let set_err = if self.gen.is_empty_type(iface, &result.err) { String::new() } else { - format!("{result}.val.err = {err_result};") + format!("{result_tmp}.val.err = {err_result};") }; let ty = self.gen.type_string(iface, &Type::Id(*ty)); - uwriteln!(self.src, "{ty} {result};"); + uwriteln!(self.src, "{ty} {result_tmp};"); let op0 = &operands[0]; uwrite!( self.src, "switch ({op0}) {{ case 0: {{ - {result}.is_err = false; + {result_tmp}.is_err = false; {ok} {set_ok} break; }} case 1: {{ - {result}.is_err = true; + {result_tmp}.is_err = true; {err} {set_err} break; }} }}" ); - results.push(result); + results.push(result_tmp); } Instruction::EnumLower { .. } => results.push(format!("(int32_t) {}", operands[0])), @@ -2088,7 +2088,7 @@ impl Bindgen for FunctionBindgen<'_> { ); results.push(option_ret); } - Some(Scalar::ExpectedEnum { err, max_err }) => { + Some(Scalar::ResultEnum { err, max_err }) => { let ret = self.locals.tmp("ret"); let mut ok_names = Vec::new(); for ty in self.sig.ret.retptrs.iter() { @@ -2111,8 +2111,8 @@ impl Bindgen for FunctionBindgen<'_> { self.sig.name, args, ); - let expected_ty = self.gen.type_string(iface, &func.result); - let expected_ret = self.locals.tmp("ret"); + let result_ty = self.gen.type_string(iface, &func.result); + let result_ret = self.locals.tmp("ret"); uwrite!( self.src, " @@ -2125,8 +2125,8 @@ impl Bindgen for FunctionBindgen<'_> { {set_ok} }} ", - ty = expected_ty, - ret = expected_ret, + ty = result_ty, + ret = result_ret, tag = ret, max = max_err, set_ok = if self.sig.ret.retptrs.len() == 0 { @@ -2134,15 +2134,15 @@ impl Bindgen for FunctionBindgen<'_> { } else if self.sig.ret.splat_tuple { let mut s = String::new(); for (i, name) in ok_names.iter().enumerate() { - uwriteln!(s, "{}.val.ok.f{} = {};", expected_ret, i, name,); + uwriteln!(s, "{}.val.ok.f{} = {};", result_ret, i, name,); } s } else { let name = ok_names.pop().unwrap(); - format!("{}.val.ok = {};", expected_ret, name) + format!("{}.val.ok = {};", result_ret, name) }, ); - results.push(expected_ret); + results.push(result_ret); } } } @@ -2165,7 +2165,7 @@ impl Bindgen for FunctionBindgen<'_> { self.src.push_str(&variant); self.src.push_str(".is_some;\n"); } - Some(Scalar::ExpectedEnum { .. }) => { + Some(Scalar::ResultEnum { .. }) => { assert_eq!(operands.len(), 1); let variant = &operands[0]; if self.sig.retptrs.len() > 0 { diff --git a/crates/gen-guest-rust/src/lib.rs b/crates/gen-guest-rust/src/lib.rs index a380c0fd7..6e2ae13bc 100644 --- a/crates/gen-guest-rust/src/lib.rs +++ b/crates/gen-guest-rust/src/lib.rs @@ -267,15 +267,15 @@ impl Generator for RustWasm { self.print_typedef_option(iface, id, payload, docs); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, _name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { - self.print_typedef_expected(iface, id, expected, docs); + self.print_typedef_result(iface, id, result, docs); } fn type_enum(&mut self, _iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) { @@ -1202,7 +1202,7 @@ impl Bindgen for FunctionBindgen<'_> { )); } - Instruction::ExpectedLower { + Instruction::ResultLower { results: result_types, .. } => { @@ -1218,7 +1218,7 @@ impl Bindgen for FunctionBindgen<'_> { )); } - Instruction::ExpectedLift { .. } => { + Instruction::ResultLift { .. } => { let err = self.blocks.pop().unwrap(); let ok = self.blocks.pop().unwrap(); let operand = &operands[0]; diff --git a/crates/gen-guest-spidermonkey-js/src/lib.rs b/crates/gen-guest-spidermonkey-js/src/lib.rs index b585bec99..bf51d5629 100644 --- a/crates/gen-guest-spidermonkey-js/src/lib.rs +++ b/crates/gen-guest-spidermonkey-js/src/lib.rs @@ -16,7 +16,7 @@ use wasm_encoder::Instruction; use wit_bindgen_core::{ wit_parser::{ abi::{self, AbiVariant, WasmSignature, WasmType}, - Docs, Enum, Expected, Flags, Function, Interface, Record, ResourceId, SizeAlign, Tuple, + Docs, Enum, Flags, Function, Interface, Record, ResourceId, Result_, SizeAlign, Tuple, Type, TypeId, Union, Variant, }, Direction, Files, Generator, @@ -1012,15 +1012,15 @@ impl Generator for SpiderMonkeyWasm<'_> { todo!() } - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { - let _ = (iface, id, name, expected, docs); + let _ = (iface, id, name, result, docs); todo!() } @@ -1965,8 +1965,8 @@ impl abi::Bindgen for Bindgen<'_, '_> { } => todo!(), abi::Instruction::OptionLower { .. } => todo!(), abi::Instruction::OptionLift { .. } => todo!(), - abi::Instruction::ExpectedLower { .. } => todo!(), - abi::Instruction::ExpectedLift { .. } => todo!(), + abi::Instruction::ResultLower { .. } => todo!(), + abi::Instruction::ResultLift { .. } => todo!(), abi::Instruction::UnionLower { .. } => todo!(), abi::Instruction::UnionLift { .. } => todo!(), abi::Instruction::EnumLower { diff --git a/crates/gen-host-js/src/lib.rs b/crates/gen-host-js/src/lib.rs index 4da41d097..573b0a5d7 100644 --- a/crates/gen-host-js/src/lib.rs +++ b/crates/gen-host-js/src/lib.rs @@ -201,12 +201,12 @@ impl Js { self.src.ts(" | null"); } } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { self.needs_ty_result = true; self.src.ts("Result<"); - self.print_ty(iface, &e.ok); + self.print_ty(iface, &r.ok); self.src.ts(", "); - self.print_ty(iface, &e.err); + self.print_ty(iface, &r.err); self.src.ts(">"); } TypeDefKind::Variant(_) => panic!("anonymous variant"), @@ -512,21 +512,21 @@ impl Generator for Js { self.src.ts(";\n"); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, _id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { self.docs(docs); let name = name.to_camel_case(); self.needs_ty_result = true; self.src.ts(&format!("export type {name} = Result<")); - self.print_ty(iface, &expected.ok); + self.print_ty(iface, &result.ok); self.src.ts(", "); - self.print_ty(iface, &expected.err); + self.print_ty(iface, &result.err); self.src.ts(">;\n"); } @@ -1856,7 +1856,7 @@ impl Bindgen for FunctionBindgen<'_> { results.push(format!("variant{tmp}")); } - Instruction::ExpectedLower { + Instruction::ResultLower { results: result_types, .. } => { @@ -1891,14 +1891,14 @@ impl Bindgen for FunctionBindgen<'_> { break; }} default: {{ - throw new RangeError(\"invalid variant specified for expected\"); + throw new RangeError(\"invalid variant specified for result\"); }} }} " )); } - Instruction::ExpectedLift { .. } => { + Instruction::ResultLift { .. } => { let (err, err_results) = self.blocks.pop().unwrap(); let (ok, ok_results) = self.blocks.pop().unwrap(); let err_result = &err_results[0]; diff --git a/crates/gen-host-wasmtime-py/src/dependencies.rs b/crates/gen-host-wasmtime-py/src/dependencies.rs index 3e4689bb7..f7a48ca14 100644 --- a/crates/gen-host-wasmtime-py/src/dependencies.rs +++ b/crates/gen-host-wasmtime-py/src/dependencies.rs @@ -9,7 +9,7 @@ pub struct Dependencies { pub needs_store: bool, pub needs_load: bool, pub needs_validate_guest_char: bool, - pub needs_expected: bool, + pub needs_result: bool, pub needs_i32_to_f32: bool, pub needs_f32_to_i32: bool, pub needs_i64_to_f64: bool, @@ -112,7 +112,7 @@ impl Dependencies { ", ); } - if self.needs_expected { + if self.needs_result { self.pyimport("dataclasses", "dataclass"); self.pyimport("typing", "TypeVar"); self.pyimport("typing", "Generic"); @@ -128,7 +128,7 @@ impl Dependencies { class Err(Generic[E]): value: E - Expected = Union[Ok[T], Err[E]] + Result = Union[Ok[T], Err[E]] ", ); } diff --git a/crates/gen-host-wasmtime-py/src/lib.rs b/crates/gen-host-wasmtime-py/src/lib.rs index 35591b958..80366f5c5 100644 --- a/crates/gen-host-wasmtime-py/src/lib.rs +++ b/crates/gen-host-wasmtime-py/src/lib.rs @@ -279,22 +279,22 @@ impl Generator for WasmtimePy { builder.push_str("]\n\n"); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, _id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { - self.deps.needs_expected = true; + self.deps.needs_result = true; let mut builder = self.src.builder(&mut self.deps, iface); builder.comment(docs); - builder.push_str(&format!("{} = Expected[", name.to_camel_case())); - builder.print_ty(&expected.ok, true); + builder.push_str(&format!("{} = Result[", name.to_camel_case())); + builder.print_ty(&result.ok, true); builder.push_str(", "); - builder.print_ty(&expected.err, true); + builder.print_ty(&result.err, true); builder.push_str("]\n\n"); } @@ -1455,7 +1455,7 @@ impl Bindgen for FunctionBindgen<'_> { results.push(result); } - Instruction::ExpectedLower { + Instruction::ResultLower { results: result_types, .. } => { @@ -1494,7 +1494,7 @@ impl Bindgen for FunctionBindgen<'_> { builder.dedent(); } - Instruction::ExpectedLift { ty, .. } => { + Instruction::ResultLift { ty, .. } => { let (err, err_results) = self.blocks.pop().unwrap(); let (ok, ok_results) = self.blocks.pop().unwrap(); assert!(err_results.len() == 1); diff --git a/crates/gen-host-wasmtime-py/src/source.rs b/crates/gen-host-wasmtime-py/src/source.rs index 3909f32e1..7a4ff1594 100644 --- a/crates/gen-host-wasmtime-py/src/source.rs +++ b/crates/gen-host-wasmtime-py/src/source.rs @@ -218,12 +218,12 @@ impl<'s, 'd, 'i> SourceBuilder<'s, 'd, 'i> { self.print_ty(t, true); self.push_str("]"); } - TypeDefKind::Expected(e) => { - self.deps.needs_expected = true; - self.push_str("Expected["); - self.print_ty(&e.ok, true); + TypeDefKind::Result(r) => { + self.deps.needs_result = true; + self.push_str("Result["); + self.print_ty(&r.ok, true); self.push_str(", "); - self.print_ty(&e.err, true); + self.print_ty(&r.err, true); self.push_str("]"); } TypeDefKind::List(t) => self.print_list(t), diff --git a/crates/gen-host-wasmtime-rust/src/lib.rs b/crates/gen-host-wasmtime-rust/src/lib.rs index a5e6e2c09..dce290d2f 100644 --- a/crates/gen-host-wasmtime-rust/src/lib.rs +++ b/crates/gen-host-wasmtime-rust/src/lib.rs @@ -144,12 +144,12 @@ impl Wasmtime { } if let Type::Id(id) = &f.result { - if let TypeDefKind::Expected(e) = &iface.types[*id].kind { - if let Type::Id(err) = e.err { + if let TypeDefKind::Result(r) = &iface.types[*id].kind { + if let Type::Id(err) = r.err { if let Some(name) = &iface.types[err].name { self.needs_custom_error_to_types.insert(name.clone()); return FunctionRet::CustomToError { - ok: e.ok, + ok: r.ok, err: name.to_string(), }; } @@ -409,15 +409,15 @@ impl Generator for Wasmtime { self.print_typedef_option(iface, id, payload, docs); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, _name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { - self.print_typedef_expected(iface, id, expected, docs); + self.print_typedef_result(iface, id, result, docs); } fn type_enum(&mut self, _iface: &Interface, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) { @@ -1614,7 +1614,7 @@ impl Bindgen for FunctionBindgen<'_> { self.gen.needs_invalid_variant = true; } - Instruction::ExpectedLower { + Instruction::ResultLower { results: result_types, .. } => { @@ -1630,7 +1630,7 @@ impl Bindgen for FunctionBindgen<'_> { )); } - Instruction::ExpectedLift { .. } => { + Instruction::ResultLift { .. } => { let err = self.blocks.pop().unwrap(); let ok = self.blocks.pop().unwrap(); let operand = &operands[0]; @@ -1638,7 +1638,7 @@ impl Bindgen for FunctionBindgen<'_> { "match {operand} {{ 0 => Ok({ok}), 1 => Err({err}), - _ => return Err(invalid_variant(\"expected\")), + _ => return Err(invalid_variant(\"result\")), }}" )); self.gen.needs_invalid_variant = true; diff --git a/crates/gen-host-wasmtime-rust/tests/codegen.rs b/crates/gen-host-wasmtime-rust/tests/codegen.rs index 9cfdb5d9b..27e4b5192 100644 --- a/crates/gen-host-wasmtime-rust/tests/codegen.rs +++ b/crates/gen-host-wasmtime-rust/tests/codegen.rs @@ -42,12 +42,12 @@ mod custom_errors { wit_bindgen_host_wasmtime_rust::export!({ src["x"]: " foo: func() - bar: func() -> expected + bar: func() -> result enum errno { bad1, bad2, } - baz: func() -> expected + baz: func() -> result ", custom_error: true, }); diff --git a/crates/gen-markdown/src/lib.rs b/crates/gen-markdown/src/lib.rs index 48ed509ba..929140691 100644 --- a/crates/gen-markdown/src/lib.rs +++ b/crates/gen-markdown/src/lib.rs @@ -90,11 +90,11 @@ impl Markdown { self.print_ty(iface, t, false); self.src.push_str(">"); } - TypeDefKind::Expected(e) => { - self.src.push_str("expected<"); - self.print_ty(iface, &e.ok, false); + TypeDefKind::Result(r) => { + self.src.push_str("result<"); + self.print_ty(iface, &r.ok, false); self.src.push_str(", "); - self.print_ty(iface, &e.err, false); + self.print_ty(iface, &r.err, false); self.src.push_str(">"); } TypeDefKind::List(t) => { @@ -352,19 +352,19 @@ impl Generator for Markdown { self.print_type_info(id, docs); } - fn type_expected( + fn type_result( &mut self, iface: &Interface, id: TypeId, name: &str, - expected: &Expected, + result: &Result_, docs: &Docs, ) { self.print_type_header(name); - self.src.push_str("expected<"); - self.print_ty(iface, &expected.ok, false); + self.src.push_str("result<"); + self.print_ty(iface, &result.ok, false); self.src.push_str(", "); - self.print_ty(iface, &expected.err, false); + self.print_ty(iface, &result.err, false); self.src.push_str(">"); self.print_type_info(id, docs); } diff --git a/crates/gen-rust-lib/src/lib.rs b/crates/gen-rust-lib/src/lib.rs index 2830a64fb..e27228f97 100644 --- a/crates/gen-rust-lib/src/lib.rs +++ b/crates/gen-rust-lib/src/lib.rs @@ -230,7 +230,7 @@ pub trait RustGenerator { TypeDefKind::Variant(_) | TypeDefKind::Record(_) | TypeDefKind::Option(_) - | TypeDefKind::Expected(_) + | TypeDefKind::Result(_) | TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::List(_) @@ -255,11 +255,11 @@ pub trait RustGenerator { self.push_str(">"); } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { self.push_str("Result<"); - self.print_ty(iface, &e.ok, mode); + self.print_ty(iface, &r.ok, mode); self.push_str(","); - self.print_ty(iface, &e.err, mode); + self.print_ty(iface, &r.err, mode); self.push_str(">"); } @@ -418,7 +418,7 @@ pub trait RustGenerator { out.push_str("Optional"); self.write_name(iface, ty, out); } - TypeDefKind::Expected(_) => out.push_str("Result"), + TypeDefKind::Result(_) => out.push_str("Result"), TypeDefKind::Tuple(_) => out.push_str("Tuple"), TypeDefKind::List(ty) => { self.write_name(iface, ty, out); @@ -698,11 +698,11 @@ pub trait RustGenerator { } } - fn print_typedef_expected( + fn print_typedef_result( &mut self, iface: &Interface, id: TypeId, - expected: &Expected, + result: &Result_, docs: &Docs, ) { let info = self.info(id); @@ -713,9 +713,9 @@ pub trait RustGenerator { self.push_str(&format!("pub type {}", name)); self.print_generics(&info, lt, true); self.push_str("= Result<"); - self.print_ty(iface, &expected.ok, mode); + self.print_ty(iface, &result.ok, mode); self.push_str(","); - self.print_ty(iface, &expected.err, mode); + self.print_ty(iface, &result.err, mode); self.push_str(">;\n"); } } diff --git a/crates/test-helpers/src/lib.rs b/crates/test-helpers/src/lib.rs index c12d18bcd..9259bde30 100644 --- a/crates/test-helpers/src/lib.rs +++ b/crates/test-helpers/src/lib.rs @@ -183,9 +183,9 @@ pub fn codegen_rust_wasm_export(input: TokenStream) -> TokenStream { let ty = quote_ty(param, iface, ty); quote::quote! { Option<#ty> } } - TypeDefKind::Expected(e) => { - let ok = quote_ty(param, iface, &e.ok); - let err = quote_ty(param, iface, &e.err); + TypeDefKind::Result(r) => { + let ok = quote_ty(param, iface, &r.ok); + let err = quote_ty(param, iface, &r.err); quote::quote! { Result<#ok, #err> } } TypeDefKind::Future(_) => todo!("unknown future"), diff --git a/crates/wit-bindgen-demo/demo.wit b/crates/wit-bindgen-demo/demo.wit index 9381aa0f0..76ab7f4b7 100644 --- a/crates/wit-bindgen-demo/demo.wit +++ b/crates/wit-bindgen-demo/demo.wit @@ -14,7 +14,7 @@ enum lang { resource config { static new: func() -> config - render: func(lang: lang, wit: string, import: bool) -> expected + render: func(lang: lang, wit: string, import: bool) -> result set-rust-unchecked: func(unchecked: bool) set-wasmtime-tracing: func(unchecked: bool) diff --git a/crates/wit-component/src/decoding.rs b/crates/wit-component/src/decoding.rs index 4918c657c..025ed6ee2 100644 --- a/crates/wit-component/src/decoding.rs +++ b/crates/wit-component/src/decoding.rs @@ -304,7 +304,7 @@ impl<'a> InterfaceDecoder<'a> { } types::ComponentDefinedType::Option(ty) => self.decode_option(name, ty)?, types::ComponentDefinedType::Expected(ok, err) => { - self.decode_expected(name, ok, err)? + self.decode_result(name, ok, err)? } }, _ => unreachable!(), @@ -523,7 +523,7 @@ impl<'a> InterfaceDecoder<'a> { )) } - fn decode_expected( + fn decode_result( &mut self, name: Option, ok: &types::ComponentValType, @@ -533,7 +533,7 @@ impl<'a> InterfaceDecoder<'a> { let err = self.decode_type(err)?; Ok(Type::Id(self.alloc_type( name, - TypeDefKind::Expected(Expected { ok, err }), + TypeDefKind::Result(Result_ { ok, err }), ))) } diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 3f042c2b1..92a2235a6 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -12,7 +12,7 @@ use wasm_encoder::*; use wasmparser::{Validator, WasmFeatures}; use wit_parser::{ abi::{AbiVariant, WasmSignature, WasmType}, - Enum, Expected, Flags, Function, FunctionKind, Interface, Record, Tuple, Type, TypeDef, + Enum, Flags, Function, FunctionKind, Interface, Record, Result_, Tuple, Type, TypeDef, TypeDefKind, Union, Variant, }; @@ -167,19 +167,19 @@ impl PartialEq for TypeDefKey<'_> { interface: other.interface, ty: *t2, }), - (TypeDefKind::Expected(e1), TypeDefKind::Expected(e2)) => { + (TypeDefKind::Result(r1), TypeDefKind::Result(r2)) => { TypeKey { interface: self.interface, - ty: e1.ok, + ty: r1.ok, } == TypeKey { interface: other.interface, - ty: e2.ok, + ty: r2.ok, } && TypeKey { interface: self.interface, - ty: e1.err, + ty: r1.err, } == TypeKey { interface: other.interface, - ty: e2.err, + ty: r2.err, } } _ => false, @@ -262,16 +262,16 @@ impl Hash for TypeDefKey<'_> { } .hash(state); } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { state.write_u8(8); TypeKey { interface: self.interface, - ty: e.ok, + ty: r.ok, } .hash(state); TypeKey { interface: self.interface, - ty: e.err, + ty: r.err, } .hash(state); } @@ -560,8 +560,8 @@ impl<'a> TypeEncoder<'a> { TypeDefKind::Option(t) => { self.encode_option(interface, t, export_named_types)? } - TypeDefKind::Expected(e) => { - self.encode_expected(interface, e, export_named_types)? + TypeDefKind::Result(r) => { + self.encode_result(interface, r, export_named_types)? } TypeDefKind::Enum(e) => self.encode_enum(e)?, TypeDefKind::List(ty) => { @@ -714,14 +714,14 @@ impl<'a> TypeEncoder<'a> { Ok(ComponentValType::Type(index)) } - fn encode_expected( + fn encode_result( &mut self, interface: &'a Interface, - expected: &Expected, + result: &Result_, export_named_types: bool, ) -> Result { - let ok = self.encode_valtype(interface, &expected.ok, export_named_types)?; - let error = self.encode_valtype(interface, &expected.err, export_named_types)?; + let ok = self.encode_valtype(interface, &result.ok, export_named_types)?; + let error = self.encode_valtype(interface, &result.err, export_named_types)?; let index = self.types.len(); let encoder = self.types.defined_type(); encoder.expected(ok, error); @@ -823,8 +823,8 @@ impl RequiredOptions { TypeDefKind::Tuple(t) => Self::for_types(interface, t.types.iter()), TypeDefKind::Flags(_) => Self::None, TypeDefKind::Option(t) => Self::for_type(interface, t), - TypeDefKind::Expected(e) => { - Self::for_type(interface, &e.ok) | Self::for_type(interface, &e.err) + TypeDefKind::Result(r) => { + Self::for_type(interface, &r.ok) | Self::for_type(interface, &r.err) } TypeDefKind::Variant(v) => { Self::for_types(interface, v.cases.iter().map(|c| &c.ty)) diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs index ec98d1974..88c74387b 100644 --- a/crates/wit-component/src/printing.rs +++ b/crates/wit-component/src/printing.rs @@ -2,7 +2,7 @@ use anyhow::{bail, Result}; use indexmap::IndexSet; use std::fmt::Write; use wit_parser::{ - Enum, Expected, Flags, Interface, Record, Tuple, Type, TypeDefKind, TypeId, Union, Variant, + Enum, Flags, Interface, Record, Result_, Tuple, Type, TypeDefKind, TypeId, Union, Variant, }; /// A utility for printing WebAssembly interface definitions to a string. @@ -77,8 +77,8 @@ impl InterfacePrinter { TypeDefKind::Option(t) => { self.print_option_type(interface, t)?; } - TypeDefKind::Expected(t) => { - self.print_expected_type(interface, t)?; + TypeDefKind::Result(t) => { + self.print_result_type(interface, t)?; } TypeDefKind::Record(_) => { bail!("interface has an unnamed record type"); @@ -136,11 +136,11 @@ impl InterfacePrinter { Ok(()) } - fn print_expected_type(&mut self, interface: &Interface, expected: &Expected) -> Result<()> { - self.output.push_str("expected<"); - self.print_type_name(interface, &expected.ok)?; + fn print_result_type(&mut self, interface: &Interface, result: &Result_) -> Result<()> { + self.output.push_str("result<"); + self.print_type_name(interface, &result.ok)?; self.output.push_str(", "); - self.print_type_name(interface, &expected.err)?; + self.print_type_name(interface, &result.err)?; self.output.push('>'); Ok(()) } @@ -185,8 +185,8 @@ impl InterfacePrinter { TypeDefKind::Option(t) => { self.declare_option(interface, ty.name.as_deref(), t)? } - TypeDefKind::Expected(e) => { - self.declare_expected(interface, ty.name.as_deref(), e)? + TypeDefKind::Result(r) => { + self.declare_result(interface, ty.name.as_deref(), r)? } TypeDefKind::Enum(e) => self.declare_enum(ty.name.as_deref(), e)?, TypeDefKind::List(inner) => { @@ -336,18 +336,18 @@ impl InterfacePrinter { Ok(()) } - fn declare_expected( + fn declare_result( &mut self, interface: &Interface, name: Option<&str>, - expected: &Expected, + result: &Result_, ) -> Result<()> { - self.declare_type(interface, &expected.ok)?; - self.declare_type(interface, &expected.err)?; + self.declare_type(interface, &result.ok)?; + self.declare_type(interface, &result.err)?; if let Some(name) = name { write!(&mut self.output, "type {} = ", name)?; - self.print_expected_type(interface, expected)?; + self.print_result_type(interface, result)?; self.output.push_str("\n\n"); } Ok(()) diff --git a/crates/wit-component/tests/interfaces/variants/variants.wit b/crates/wit-component/tests/interfaces/variants/variants.wit index 4bace14a3..34eb5791b 100644 --- a/crates/wit-component/tests/interfaces/variants/variants.wit +++ b/crates/wit-component/tests/interfaces/variants/variants.wit @@ -77,21 +77,21 @@ option-result: func() -> tuple, option>, option, optio casts: func(a: casts1, b: casts2, c: casts3, d: casts4, e: casts5, f: casts6) -> tuple -expected-arg: func(a: expected, b: expected, c: expected, d: expected, tuple<>>, e: expected, f: expected>) +expected-arg: func(a: result, b: result, c: result, d: result, tuple<>>, e: result, f: result>) -expected-result: func() -> tuple, expected, expected, expected, tuple<>>, expected, expected>> +expected-result: func() -> tuple, result, result, result, tuple<>>, result, result>> -return-expected-sugar: func() -> expected +return-expected-sugar: func() -> result -return-expected-sugar2: func() -> expected +return-expected-sugar2: func() -> result -return-expected-sugar3: func() -> expected +return-expected-sugar3: func() -> result -return-expected-sugar4: func() -> expected, my-errno> +return-expected-sugar4: func() -> result, my-errno> return-option-sugar: func() -> option return-option-sugar2: func() -> option -expected-simple: func() -> expected +expected-simple: func() -> result diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs index 493bbadd5..460931fa7 100644 --- a/crates/wit-parser/src/abi.rs +++ b/crates/wit-parser/src/abi.rs @@ -1,6 +1,6 @@ use crate::sizealign::align_to; use crate::{ - Enum, Expected, Flags, FlagsRepr, Function, Int, Interface, Record, ResourceId, Tuple, Type, + Enum, Flags, FlagsRepr, Function, Int, Interface, Record, ResourceId, Result_, Tuple, Type, TypeDefKind, TypeId, Union, Variant, }; @@ -613,20 +613,20 @@ def_instruction! { ty: TypeId, } : [1] => [1], - /// Specialization of `VariantLower` for specifically `expected` + /// Specialization of `VariantLower` for specifically `result` /// types, otherwise behaves the same as `VariantLower` (e.g. two blocks /// for the two cases. - ExpectedLower { - expected: &'a Expected, + ResultLower { + result: &'a Result_ ty: TypeId, results: &'a [WasmType], } : [1] => [results.len()], - /// Specialization of `VariantLift` for specifically the `expected` type. Otherwise behaves the same as the `VariantLift` /// instruction with two blocks for the lift. - ExpectedLift { - expected: &'a Expected, + ResultLift { + result: &'a Result_, ty: TypeId, } : [1] => [1], @@ -912,9 +912,9 @@ impl Interface { self.push_wasm_variants(variant, [&Type::Unit, t], result); } - TypeDefKind::Expected(e) => { + TypeDefKind::Result(r) => { result.push(WasmType::I32); - self.push_wasm_variants(variant, [&e.ok, &e.err], result); + self.push_wasm_variants(variant, [&r.ok, &r.err], result); } TypeDefKind::Union(u) => { @@ -1387,10 +1387,10 @@ impl<'a, B: Bindgen> Generator<'a, B> { results: &results, }); } - TypeDefKind::Expected(e) => { - let results = self.lower_variant_arms(ty, [&e.ok, &e.err]); - self.emit(&ExpectedLower { - expected: e, + TypeDefKind::Result(r) => { + let results = self.lower_variant_arms(ty, [&r.ok, &r.err]); + self.emit(&ResultLower { + result: r, ty: id, results: &results, }); @@ -1597,12 +1597,9 @@ impl<'a, B: Bindgen> Generator<'a, B> { self.emit(&OptionLift { payload: t, ty: id }); } - TypeDefKind::Expected(e) => { - self.lift_variant_arms(ty, [&e.ok, &e.err]); - self.emit(&ExpectedLift { - expected: e, - ty: id, - }); + TypeDefKind::Result(r) => { + self.lift_variant_arms(ty, [&r.ok, &r.err]); + self.emit(&ResultLift { result: r, ty: id }); } TypeDefKind::Union(union) => { @@ -1756,10 +1753,10 @@ impl<'a, B: Bindgen> Generator<'a, B> { }); } - TypeDefKind::Expected(e) => { - self.write_variant_arms_to_memory(offset, addr, Int::U8, [&e.ok, &e.err]); - self.emit(&ExpectedLower { - expected: e, + TypeDefKind::Result(r) => { + self.write_variant_arms_to_memory(offset, addr, Int::U8, [&r.ok, &r.err]); + self.emit(&ResultLower { + result: r, ty: id, results: &[], }); @@ -1937,12 +1934,9 @@ impl<'a, B: Bindgen> Generator<'a, B> { self.emit(&OptionLift { payload: t, ty: id }); } - TypeDefKind::Expected(e) => { - self.read_variant_arms_from_memory(offset, addr, Int::U8, [&e.ok, &e.err]); - self.emit(&ExpectedLift { - expected: e, - ty: id, - }); + TypeDefKind::Result(r) => { + self.read_variant_arms_from_memory(offset, addr, Int::U8, [&r.ok, &r.err]); + self.emit(&ResultLift { result: r, ty: id }); } TypeDefKind::Enum(e) => { diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs index 185ca0adf..2f9a8b5a2 100644 --- a/crates/wit-parser/src/ast.rs +++ b/crates/wit-parser/src/ast.rs @@ -97,7 +97,7 @@ enum Type<'a> { Tuple(Vec>), Enum(Enum<'a>), Option(Box>), - Expected(Expected<'a>), + Result(Result_<'a>), Future(Box>), Stream(Stream<'a>), Union(Union<'a>), @@ -143,7 +143,7 @@ struct EnumCase<'a> { name: Id<'a>, } -struct Expected<'a> { +struct Result_<'a> { ok: Box>, err: Box>, } @@ -514,14 +514,14 @@ impl<'a> Type<'a> { Ok(Type::Option(Box::new(ty))) } - // expected - Some((_span, Token::Expected)) => { + // result + Some((_span, Token::Result_)) => { tokens.expect(Token::LessThan)?; let ok = Box::new(Type::parse(tokens)?); tokens.expect(Token::Comma)?; let err = Box::new(Type::parse(tokens)?); tokens.expect(Token::GreaterThan)?; - Ok(Type::Expected(Expected { ok, err })) + Ok(Type::Result(Result_ { ok, err })) } // future diff --git a/crates/wit-parser/src/ast/lex.rs b/crates/wit-parser/src/ast/lex.rs index 3db757870..4b9abef97 100644 --- a/crates/wit-parser/src/ast/lex.rs +++ b/crates/wit-parser/src/ast/lex.rs @@ -70,7 +70,7 @@ pub enum Token { Bool, String_, Option_, - Expected, + Result_, Future, Stream, List, @@ -260,7 +260,7 @@ impl<'a> Tokenizer<'a> { "bool" => Bool, "string" => String_, "option" => Option_, - "expected" => Expected, + "result" => Result_, "future" => Future, "stream" => Stream, "list" => List, @@ -524,7 +524,7 @@ impl Token { Bool => "keyword `bool`", String_ => "keyword `string`", Option_ => "keyword `option`", - Expected => "keyword `expected`", + Result_ => "keyword `result`", Future => "keyword `future`", Stream => "keyword `stream`", List => "keyword `list`", diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index bf701f2f0..daef51394 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -26,7 +26,7 @@ enum Key { Enum(Vec), List(Type), Option(Type), - Expected(Type, Type), + Result(Type, Type), Union(Vec), Future(Type), Stream(Type, Type), @@ -237,9 +237,9 @@ impl Resolver { }), TypeDefKind::List(t) => TypeDefKind::List(self.copy_type(dep_name, dep, *t)), TypeDefKind::Option(t) => TypeDefKind::Option(self.copy_type(dep_name, dep, *t)), - TypeDefKind::Expected(e) => TypeDefKind::Expected(Expected { - ok: self.copy_type(dep_name, dep, e.ok), - err: self.copy_type(dep_name, dep, e.err), + TypeDefKind::Result(r) => TypeDefKind::Result(Result_ { + ok: self.copy_type(dep_name, dep, r.ok), + err: self.copy_type(dep_name, dep, r.err), }), TypeDefKind::Union(u) => TypeDefKind::Union(Union { cases: u @@ -472,9 +472,9 @@ impl Resolver { TypeDefKind::Enum(Enum { cases }) } super::Type::Option(ty) => TypeDefKind::Option(self.resolve_type(ty)?), - super::Type::Expected(e) => TypeDefKind::Expected(Expected { - ok: self.resolve_type(&e.ok)?, - err: self.resolve_type(&e.err)?, + super::Type::Result(r) => TypeDefKind::Result(Result_ { + ok: self.resolve_type(&r.ok)?, + err: self.resolve_type(&r.err)?, }), super::Type::Union(e) => { if e.cases.is_empty() { @@ -538,7 +538,7 @@ impl Resolver { } TypeDefKind::List(ty) => Key::List(*ty), TypeDefKind::Option(t) => Key::Option(*t), - TypeDefKind::Expected(e) => Key::Expected(e.ok, e.err), + TypeDefKind::Result(r) => Key::Result(r.ok, r.err), TypeDefKind::Union(u) => Key::Union(u.cases.iter().map(|c| c.ty).collect()), TypeDefKind::Future(ty) => Key::Future(*ty), TypeDefKind::Stream(s) => Key::Stream(s.element, s.end), @@ -704,11 +704,11 @@ impl Resolver { self.validate_type_not_recursive(span, id, visiting, valid)? } } - TypeDefKind::Expected(e) => { - if let Type::Id(id) = e.ok { + TypeDefKind::Result(r) => { + if let Type::Id(id) = r.ok { self.validate_type_not_recursive(span, id, visiting, valid)? } - if let Type::Id(id) = e.err { + if let Type::Id(id) = r.err { self.validate_type_not_recursive(span, id, visiting, valid)? } } diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs index 5bdeb88ff..b03ccdb36 100644 --- a/crates/wit-parser/src/lib.rs +++ b/crates/wit-parser/src/lib.rs @@ -59,7 +59,7 @@ pub enum TypeDefKind { Variant(Variant), Enum(Enum), Option(Type), - Expected(Expected), + Result(Result_), Union(Union), List(Type), Future(Type), @@ -196,7 +196,7 @@ impl Enum { } #[derive(Debug, Clone, PartialEq)] -pub struct Expected { +pub struct Result_ { pub ok: Type, pub err: Type, } @@ -432,9 +432,9 @@ impl Interface { } } TypeDefKind::Option(ty) => self.topo_visit_ty(ty, list, visited), - TypeDefKind::Expected(e) => { - self.topo_visit_ty(&e.ok, list, visited); - self.topo_visit_ty(&e.err, list, visited); + TypeDefKind::Result(r) => { + self.topo_visit_ty(&r.ok, list, visited); + self.topo_visit_ty(&r.err, list, visited); } TypeDefKind::Union(u) => { for t in u.cases.iter() { @@ -479,7 +479,7 @@ impl Interface { | TypeDefKind::Variant(_) | TypeDefKind::Enum(_) | TypeDefKind::Option(_) - | TypeDefKind::Expected(_) + | TypeDefKind::Result(_) | TypeDefKind::Future(_) | TypeDefKind::Stream(_) | TypeDefKind::Union(_) => false, diff --git a/crates/wit-parser/src/sizealign.rs b/crates/wit-parser/src/sizealign.rs index be395792e..961bf90fa 100644 --- a/crates/wit-parser/src/sizealign.rs +++ b/crates/wit-parser/src/sizealign.rs @@ -28,7 +28,7 @@ impl SizeAlign { TypeDefKind::Variant(v) => self.variant(v.tag(), v.cases.iter().map(|c| &c.ty)), TypeDefKind::Enum(e) => self.variant(e.tag(), []), TypeDefKind::Option(t) => self.variant(Int::U8, [&Type::Unit, t]), - TypeDefKind::Expected(e) => self.variant(Int::U8, [&e.ok, &e.err]), + TypeDefKind::Result(r) => self.variant(Int::U8, [&r.ok, &r.err]), TypeDefKind::Union(u) => self.variant(u.tag(), u.cases.iter().map(|c| &c.ty)), // A future is represented as an index. TypeDefKind::Future(_) => (4, 4), diff --git a/crates/wit-parser/tests/all.rs b/crates/wit-parser/tests/all.rs index e9b72a7c8..f17cfebb5 100644 --- a/crates/wit-parser/tests/all.rs +++ b/crates/wit-parser/tests/all.rs @@ -208,7 +208,7 @@ fn to_json(i: &Interface) -> String { Variant { cases: Vec<(String, String)> }, Tuple { types: Vec }, Option(String), - Expected { ok: String, err: String }, + Result { ok: String, err: String }, Future(String), Stream { element: String, end: String }, List(String), @@ -301,9 +301,9 @@ fn to_json(i: &Interface) -> String { .collect(), }, TypeDefKind::Option(t) => Type::Option(translate_type(t)), - TypeDefKind::Expected(e) => Type::Expected { - ok: translate_type(&e.ok), - err: translate_type(&e.err), + TypeDefKind::Result(r) => Type::Result { + ok: translate_type(&r.ok), + err: translate_type(&r.err), }, TypeDefKind::Future(t) => Type::Future(translate_type(t)), TypeDefKind::Stream(s) => Type::Stream { diff --git a/crates/wit-parser/tests/ui/functions.wit b/crates/wit-parser/tests/ui/functions.wit index 44cbe832e..8ee64ba70 100644 --- a/crates/wit-parser/tests/ui/functions.wit +++ b/crates/wit-parser/tests/ui/functions.wit @@ -4,4 +4,4 @@ f3: func(a: u32,) f4: func() -> u32 f6: func() -> tuple f7: func(a: float32, b: float32) -> tuple -f8: func(a: option) -> expected +f8: func(a: option) -> result diff --git a/crates/wit-parser/tests/ui/functions.wit.result b/crates/wit-parser/tests/ui/functions.wit.result index c2c5e86e1..b4656d976 100644 --- a/crates/wit-parser/tests/ui/functions.wit.result +++ b/crates/wit-parser/tests/ui/functions.wit.result @@ -15,7 +15,7 @@ }, { "idx": 2, - "expected": { + "result": { "ok": "u32", "err": "float32" } diff --git a/crates/wit-parser/tests/ui/types.wit b/crates/wit-parser/tests/ui/types.wit index 014fafee7..5d2cafda9 100644 --- a/crates/wit-parser/tests/ui/types.wit +++ b/crates/wit-parser/tests/ui/types.wit @@ -14,10 +14,10 @@ type t11 = char type t12 = list type t13 = string type t14 = option -type t15 = expected -type t16 = expected -type t17 = expected -type t18 = expected +type t15 = result +type t16 = result +type t17 = result +type t18 = result type t19 = handle x record t20 {} record t21 { a: u32 } diff --git a/crates/wit-parser/tests/ui/types.wit.result b/crates/wit-parser/tests/ui/types.wit.result index 60a4f75aa..094418942 100644 --- a/crates/wit-parser/tests/ui/types.wit.result +++ b/crates/wit-parser/tests/ui/types.wit.result @@ -82,7 +82,7 @@ { "idx": 15, "name": "t15", - "expected": { + "result": { "ok": "u32", "err": "u32" } @@ -90,7 +90,7 @@ { "idx": 16, "name": "t16", - "expected": { + "result": { "ok": "unit", "err": "u32" } @@ -98,7 +98,7 @@ { "idx": 17, "name": "t17", - "expected": { + "result": { "ok": "u32", "err": "unit" } @@ -106,7 +106,7 @@ { "idx": 18, "name": "t18", - "expected": { + "result": { "ok": "unit", "err": "unit" } diff --git a/crates/wit-parser/tests/ui/wasi-clock.wit b/crates/wit-parser/tests/ui/wasi-clock.wit index 7f360b925..25535696a 100644 --- a/crates/wit-parser/tests/ui/wasi-clock.wit +++ b/crates/wit-parser/tests/ui/wasi-clock.wit @@ -8,8 +8,8 @@ use { clockid, timestamp, errno } from wasi // Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, // return `errno::inval`. // Note: This is similar to `clock-getres` in POSIX. -res-get: func(id: clockid) -> expected +res-get: func(id: clockid) -> result // Return the time value of a clock. // Note: This is similar to `clock-gettime` in POSIX. -time-get: func(id: clockid, precision: timestamp) -> expected +time-get: func(id: clockid, precision: timestamp) -> result diff --git a/crates/wit-parser/tests/ui/wasi-clock.wit.result b/crates/wit-parser/tests/ui/wasi-clock.wit.result index ee1e14ce6..8a91d9cf4 100644 --- a/crates/wit-parser/tests/ui/wasi-clock.wit.result +++ b/crates/wit-parser/tests/ui/wasi-clock.wit.result @@ -105,7 +105,7 @@ }, { "idx": 3, - "expected": { + "result": { "ok": "type-1", "err": "type-2" } diff --git a/crates/wit-parser/tests/ui/wasi-http.wit b/crates/wit-parser/tests/ui/wasi-http.wit index 67e006180..4ac72d31c 100644 --- a/crates/wit-parser/tests/ui/wasi-http.wit +++ b/crates/wit-parser/tests/ui/wasi-http.wit @@ -85,14 +85,13 @@ resource body { /// @param dest - destination buffer to write into /// @return result - a result containing the number of bytes written on success // TODO: check if `out-buffer` is the right way to express this - // NOTE: s/expected/result/ - read: func(dest: list) -> expected + read: func(dest: list) -> result /// Write to a body. /// @param source - source buffer to read from /// @return result - a result containing the number of bytes read on success // TODO: check if `in-buffer` is the right way to express this - write: func(source: list) -> expected + write: func(source: list) -> result } /* @@ -144,7 +143,7 @@ enum error { /// A function returning a Result, with the enum above as one of the options /// @return result - a `Result` containing either the desired number, or an `error` -maybe-number: func() -> expected +maybe-number: func() -> result /// A simple struct record timestamp { diff --git a/crates/wit-parser/tests/ui/wasi-http.wit.result b/crates/wit-parser/tests/ui/wasi-http.wit.result index 037e009ea..0ce263314 100644 --- a/crates/wit-parser/tests/ui/wasi-http.wit.result +++ b/crates/wit-parser/tests/ui/wasi-http.wit.result @@ -66,7 +66,7 @@ }, { "idx": 8, - "expected": { + "result": { "ok": "u64", "err": "type-4" } diff --git a/tests/codegen/small-anonymous.wit b/tests/codegen/small-anonymous.wit index 71f9cb4e4..3f30be440 100644 --- a/tests/codegen/small-anonymous.wit +++ b/tests/codegen/small-anonymous.wit @@ -3,4 +3,4 @@ enum error { failure, } -option-test: func() -> expected, error> +option-test: func() -> result, error> diff --git a/tests/codegen/variants.wit b/tests/codegen/variants.wit index c32c2ebf2..2bc9e904c 100644 --- a/tests/codegen/variants.wit +++ b/tests/codegen/variants.wit @@ -96,21 +96,21 @@ casts: func( casts6, > -expected-arg: func( - a: expected, - b: expected, - c: expected, - d: expected, tuple<>>, - e: expected, - f: expected>, +result-arg: func( + a: result, + b: result, + c: result, + d: result, tuple<>>, + e: result, + f: result>, ) -expected-result: func() -> tuple< - expected, - expected, - expected, - expected, tuple<>>, - expected, - expected>, +result-result: func() -> tuple< + result, + result, + result, + result, tuple<>>, + result, + result>, > enum my-errno { @@ -118,14 +118,14 @@ enum my-errno { bad2, } -return-expected-sugar: func() -> expected -return-expected-sugar2: func() -> expected -return-expected-sugar3: func() -> expected -return-expected-sugar4: func() -> expected, my-errno> +return-result-sugar: func() -> result +return-result-sugar2: func() -> result +return-result-sugar3: func() -> result +return-result-sugar4: func() -> result, my-errno> return-option-sugar: func() -> option return-option-sugar2: func() -> option -expected-simple: func() -> expected +result-simple: func() -> result record is-clone { v1: v1, diff --git a/tests/runtime/flavorful/exports.wit b/tests/runtime/flavorful/exports.wit index bc751b961..9804f6604 100644 --- a/tests/runtime/flavorful/exports.wit +++ b/tests/runtime/flavorful/exports.wit @@ -12,7 +12,7 @@ list-in-record3: func(a: list-in-record3) -> list-in-record3 list-in-record4: func(a: list-in-alias) -> list-in-alias type list-in-variant1-v1 = option -type list-in-variant1-v2 = expected +type list-in-variant1-v2 = result 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) @@ -23,7 +23,7 @@ type list-in-variant3 = option list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 enum my-errno { success, a, b } -errno-result: func() -> expected +errno-result: func() -> result type list-typedef = string type list-typedef2 = list diff --git a/tests/runtime/flavorful/host.py b/tests/runtime/flavorful/host.py index 6fa7afe2a..010e03840 100644 --- a/tests/runtime/flavorful/host.py +++ b/tests/runtime/flavorful/host.py @@ -33,7 +33,7 @@ def list_in_variant3(self, a: i.ListInVariant3) -> i.ListInVariant3: assert(a == 'input3') return 'output3' - def errno_result(self) -> i.Expected[None, i.MyErrno]: + def errno_result(self) -> i.Result[None, i.MyErrno]: return i.Err(i.MyErrno.B) def list_typedefs(self, a: i.ListTypedef, c: i.ListTypedef3) -> Tuple[i.ListTypedef2, i.ListTypedef3]: @@ -41,7 +41,7 @@ def list_typedefs(self, a: i.ListTypedef, c: i.ListTypedef3) -> Tuple[i.ListType assert(c == ['typedef2']) return (b'typedef3', ['typedef4']) - def list_of_variants(self, a: List[bool], b: List[i.Expected[None, None]], c: List[i.MyErrno]) -> Tuple[List[bool], List[i.Expected[None, None]], List[i.MyErrno]]: + def list_of_variants(self, a: List[bool], b: List[i.Result[None, None]], c: List[i.MyErrno]) -> Tuple[List[bool], List[i.Result[None, None]], List[i.MyErrno]]: assert(a == [True, False]) assert(b == [i.Ok(None), i.Err(None)]) assert(c == [i.MyErrno.SUCCESS, i.MyErrno.A]) diff --git a/tests/runtime/flavorful/imports.wit b/tests/runtime/flavorful/imports.wit index a3deecff5..d5838f840 100644 --- a/tests/runtime/flavorful/imports.wit +++ b/tests/runtime/flavorful/imports.wit @@ -10,7 +10,7 @@ list-in-record3: func(a: list-in-record3) -> list-in-record3 list-in-record4: func(a: list-in-alias) -> list-in-alias type list-in-variant1-v1 = option -type list-in-variant1-v2 = expected +type list-in-variant1-v2 = result 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) @@ -21,11 +21,11 @@ type list-in-variant3 = option list-in-variant3: func(a: list-in-variant3) -> list-in-variant3 enum my-errno { success, a, b } -errno-result: func() -> expected +errno-result: func() -> result type list-typedef = string type list-typedef2 = list type list-typedef3 = list list-typedefs: func(a: list-typedef, c: list-typedef3) -> tuple -list-of-variants: func(a: list, b: list>, c: list) -> tuple, list>, list> +list-of-variants: func(a: list, b: list>, c: list) -> tuple, list>, list> diff --git a/tests/runtime/flavorful/wasm.c b/tests/runtime/flavorful/wasm.c index 522c6ca3d..ba72be5e9 100644 --- a/tests/runtime/flavorful/wasm.c +++ b/tests/runtime/flavorful/wasm.c @@ -90,8 +90,8 @@ void exports_test_imports() { a.ptr = a_val; a.len = 2; - imports_list_expected_unit_unit_t b; - imports_expected_unit_unit_t b_val[2]; + imports_list_result_unit_unit_t b; + imports_result_unit_unit_t b_val[2]; b_val[0].is_err = false; b_val[1].is_err = true; b.ptr = b_val; @@ -105,7 +105,7 @@ void exports_test_imports() { c.len = 2; imports_list_bool_t d; - imports_list_expected_unit_unit_t e; + imports_list_result_unit_unit_t e; imports_list_my_errno_t f; imports_list_of_variants(&a, &b, &c, &d, &e, &f); @@ -122,7 +122,7 @@ void exports_test_imports() { assert(f.ptr[1] == IMPORTS_MY_ERRNO_B); imports_list_bool_free(&d); - imports_list_expected_unit_unit_free(&e); + imports_list_result_unit_unit_free(&e); imports_list_my_errno_free(&f); } } diff --git a/tests/runtime/handles/exports.wit b/tests/runtime/handles/exports.wit index 2a8602d0e..87f3e7a90 100644 --- a/tests/runtime/handles/exports.wit +++ b/tests/runtime/handles/exports.wit @@ -19,7 +19,7 @@ wasm-state2-param-tuple: func(a: wasm-state-param-tuple) type wasm-state-param-option = option wasm-state2-param-option: func(a: wasm-state-param-option) -type wasm-state-param-result = expected +type wasm-state-param-result = result wasm-state2-param-result: func(a: wasm-state-param-result) union wasm-state-param-variant { wasm-state2, u32 } @@ -37,7 +37,7 @@ wasm-state2-result-tuple: func() -> wasm-state-result-tuple type wasm-state-result-option = option wasm-state2-result-option: func() -> wasm-state-result-option -type wasm-state-result-result = expected +type wasm-state-result-result = result wasm-state2-result-result: func() -> wasm-state-result-result union wasm-state-result-variant { wasm-state2, u32 } diff --git a/tests/runtime/handles/imports.wit b/tests/runtime/handles/imports.wit index 1c5b600de..162de15b0 100644 --- a/tests/runtime/handles/imports.wit +++ b/tests/runtime/handles/imports.wit @@ -17,7 +17,7 @@ host-state2-param-tuple: func(a: host-state-param-tuple) type host-state-param-option = option host-state2-param-option: func(a: host-state-param-option) -type host-state-param-result = expected +type host-state-param-result = result host-state2-param-result: func(a: host-state-param-result) union host-state-param-variant { host-state2, u32 } @@ -35,7 +35,7 @@ host-state2-result-tuple: func() -> host-state-result-tuple type host-state-result-option = option host-state2-result-option: func() -> host-state-result-option -type host-state-result-result = expected +type host-state-result-result = result host-state2-result-result: func() -> host-state-result-result union host-state-result-variant { host-state2, u32 } diff --git a/tests/runtime/variants/exports.wit b/tests/runtime/variants/exports.wit index de0f94302..743be17d5 100644 --- a/tests/runtime/variants/exports.wit +++ b/tests/runtime/variants/exports.wit @@ -1,7 +1,7 @@ test-imports: func() roundtrip-option: func(a: option) -> option -roundtrip-result: func(a: expected) -> expected +roundtrip-result: func(a: result) -> result enum e1 { a, b } roundtrip-enum: func(a: e1) -> e1 @@ -26,5 +26,5 @@ variant-zeros: func(a: zeros) -> zeros type option-typedef = option type bool-typedef = bool -type result-typedef = expected +type result-typedef = result variant-typedefs: func(a: option-typedef, b: bool-typedef, c: result-typedef) diff --git a/tests/runtime/variants/host.py b/tests/runtime/variants/host.py index 2fe1e7a1f..a00989dc3 100644 --- a/tests/runtime/variants/host.py +++ b/tests/runtime/variants/host.py @@ -12,7 +12,7 @@ def roundtrip_option(self, a: Optional[float]) -> Optional[int]: return int(a) return None - def roundtrip_result(self, a: i.Expected[int, float]) -> i.Expected[float, int]: + def roundtrip_result(self, a: i.Result[int, float]) -> i.Result[float, int]: if isinstance(a, i.Ok): return i.Ok(float(a.value)) return i.Err(int(a.value)) @@ -32,7 +32,7 @@ def variant_zeros(self, a: i.Zeros) -> i.Zeros: def variant_typedefs(self, a: i.OptionTypedef, b: i.BoolTypedef, c: i.ResultTypedef) -> None: pass - def variant_enums(self, a: bool, b: i.Expected[None, None], c: i.MyErrno) -> Tuple[bool, i.Expected[None, None], i.MyErrno]: + def variant_enums(self, a: bool, b: i.Result[None, None], c: i.MyErrno) -> Tuple[bool, i.Result[None, None], i.MyErrno]: assert(a) assert(isinstance(b, i.Ok)) assert(c == i.MyErrno.SUCCESS) diff --git a/tests/runtime/variants/imports.wit b/tests/runtime/variants/imports.wit index 5223d4d7c..f0c442a23 100644 --- a/tests/runtime/variants/imports.wit +++ b/tests/runtime/variants/imports.wit @@ -1,5 +1,5 @@ roundtrip-option: func(a: option) -> option -roundtrip-result: func(a: expected) -> expected +roundtrip-result: func(a: result) -> result enum e1 { a, b } roundtrip-enum: func(a: e1) -> e1 @@ -24,8 +24,8 @@ variant-zeros: func(a: zeros) -> zeros type option-typedef = option type bool-typedef = bool -type result-typedef = expected +type result-typedef = result variant-typedefs: func(a: option-typedef, b: bool-typedef, c: result-typedef) enum my-errno { success, a, b } -variant-enums: func(a: bool, b: expected, c: my-errno) -> tuple, my-errno> +variant-enums: func(a: bool, b: result, c: my-errno) -> tuple, my-errno> diff --git a/tests/runtime/variants/wasm.c b/tests/runtime/variants/wasm.c index cf371e4b4..340201860 100644 --- a/tests/runtime/variants/wasm.c +++ b/tests/runtime/variants/wasm.c @@ -19,8 +19,8 @@ void exports_test_imports() { { - imports_expected_u32_float32_t a; - imports_expected_float64_u8_t b; + imports_result_u32_float32_t a; + imports_result_float64_u8_t b; a.is_err = false; a.val.ok = 2; @@ -153,7 +153,7 @@ void exports_test_imports() { { bool a; - imports_expected_unit_unit_t b; + imports_result_unit_unit_t b; imports_my_errno_t c; b.is_err = false; imports_variant_enums(true, &b, IMPORTS_MY_ERRNO_SUCCESS, &a, &b, &c); @@ -170,7 +170,7 @@ bool exports_roundtrip_option(exports_option_float32_t *a, uint8_t *ret0) { return a->is_some; } -void exports_roundtrip_result(exports_expected_u32_float32_t *a, exports_expected_float64_u8_t *ret0) { +void exports_roundtrip_result(exports_result_u32_float32_t *a, exports_result_float64_u8_t *ret0) { ret0->is_err = a->is_err; if (a->is_err) { ret0->val.err = a->val.err; From a0463827233dd45495085c8209b263fd4a012379 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 9 Sep 2022 12:57:48 -0700 Subject: [PATCH 3/5] Implement function and value type name mangling. This implements the name-mangling scheme in the current canonical ABI, with the modification proposed in WebAssembly/component-model#104, though that can be easily removed if the proposal is declined. --- crates/wit-parser/src/lib.rs | 1 + crates/wit-parser/src/mangle.rs | 538 ++++++++++++++++++++++++++++++++ 2 files changed, 539 insertions(+) create mode 100644 crates/wit-parser/src/mangle.rs diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs index b03ccdb36..48f991c10 100644 --- a/crates/wit-parser/src/lib.rs +++ b/crates/wit-parser/src/lib.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; pub mod abi; mod ast; +pub mod mangle; mod sizealign; pub use sizealign::*; diff --git a/crates/wit-parser/src/mangle.rs b/crates/wit-parser/src/mangle.rs new file mode 100644 index 000000000..b079e1b8c --- /dev/null +++ b/crates/wit-parser/src/mangle.rs @@ -0,0 +1,538 @@ +//! Canonical ABI name mangling. +//! +//! This file implements the name mangling scheme defined [here] +//! [here]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md#canonical-module-type + +use crate::{ + Case, EnumCase, Field, Flag, Function, Interface, ResourceId, Stream, Type, TypeDefKind, + UnionCase, +}; + +const CABI_VERSION: &str = "0.1"; + +enum PreSpace { + False, +} + +impl Interface { + pub fn mangle_funcname(&self, func: &Function) -> String { + self.mangle_funcname_with_name(&func.name, func) + } + + pub fn mangle_start_funcname(&self, func: &Function) -> String { + self.mangle_funcname_with_name(&format!("cabi_start{{cabi={}}}", CABI_VERSION), func) + } + + fn mangle_funcname_with_name(&self, name: &str, func: &Function) -> String { + format!( + "{}: func{} -> {}", + name, + self.mangle_funcvec(&func.params, PreSpace::False), + self.mangle_valtype(func.result) + ) + } + + fn mangle_funcvec(&self, es: &[(String, Type)], _pre_space: PreSpace) -> String { + format!( + "({})", + es.iter() + .map(|e| format!("{}: {}", e.0, self.mangle_valtype(e.1))) + .collect::>() + .join(", ") + ) + } + + fn mangle_valtype(&self, t: Type) -> String { + match t { + Type::Unit => "unit".to_owned(), + Type::Bool => "bool".to_owned(), + Type::S8 => "s8".to_owned(), + Type::U8 => "u8".to_owned(), + Type::S16 => "s16".to_owned(), + Type::U16 => "u16".to_owned(), + Type::S32 => "s32".to_owned(), + Type::U32 => "u32".to_owned(), + Type::S64 => "s64".to_owned(), + Type::U64 => "u64".to_owned(), + Type::Float32 => "float32".to_owned(), + Type::Float64 => "float64".to_owned(), + Type::Char => "char".to_owned(), + Type::String => "string".to_owned(), + Type::Handle(id) => self.mangle_handletype(id), + Type::Id(id) => self.mangle_valtypedef(&self.types[id].kind), + } + } + + fn mangle_valtypedef(&self, kind: &TypeDefKind) -> String { + match kind { + TypeDefKind::List(t) => format!("list<{}>", self.mangle_valtype(*t)), + TypeDefKind::Record(r) => self.mangle_recordtype(&r.fields), + TypeDefKind::Tuple(t) => self.mangle_tupletype(&t.types), + TypeDefKind::Flags(f) => self.mangle_flags(&f.flags), + TypeDefKind::Variant(v) => self.mangle_varianttype(&v.cases), + TypeDefKind::Enum(e) => self.mangle_enumtype(&e.cases), + TypeDefKind::Union(u) => self.mangle_uniontype(&u.cases), + TypeDefKind::Option(t) => self.mangle_optiontype(*t), + TypeDefKind::Result(r) => self.mangle_resulttype(r.ok, r.err), + TypeDefKind::Future(t) => self.mangle_futuretype(*t), + TypeDefKind::Stream(s) => self.mangle_streamtype(s), + TypeDefKind::Type(t) => self.mangle_valtype(*t), + } + } + + fn mangle_recordtype(&self, fields: &[Field]) -> String { + if fields.is_empty() { + "record {}".to_owned() + } else { + format!( + "record {{ {} }}", + fields + .iter() + .map(|f| format!("{}: {}", f.name, self.mangle_valtype(f.ty))) + .collect::>() + .join(", ") + ) + } + } + + fn mangle_tupletype(&self, ts: &[Type]) -> String { + format!( + "tuple<{}>", + ts.iter() + .map(|t| self.mangle_valtype(*t)) + .collect::>() + .join(", ") + ) + } + + fn mangle_flags(&self, labels: &[Flag]) -> String { + if labels.is_empty() { + "flags {}".to_owned() + } else { + format!( + "flags {{ {} }}", + labels + .iter() + .map(|f| f.name.clone()) + .collect::>() + .join(", ") + ) + } + } + + fn mangle_varianttype(&self, cases: &[Case]) -> String { + if cases.is_empty() { + "variant {}".to_owned() + } else { + format!( + "variant {{ {} }}", + cases + .iter() + .map(|c| format!("{}{}", c.name, format!("({})", self.mangle_valtype(c.ty)),)) + .collect::>() + .join(", ") + ) + } + } + + fn mangle_enumtype(&self, labels: &[EnumCase]) -> String { + if labels.is_empty() { + "enum {}".to_owned() + } else { + format!( + "enum {{ {} }}", + labels + .iter() + .map(|l| l.name.clone()) + .collect::>() + .join(", ") + ) + } + } + + fn mangle_uniontype(&self, cases: &[UnionCase]) -> String { + if cases.is_empty() { + "union {}".to_owned() + } else { + format!( + "union {{ {} }}", + cases + .iter() + .map(|case| self.mangle_valtype(case.ty)) + .collect::>() + .join(", ") + ) + } + } + + fn mangle_optiontype(&self, t: Type) -> String { + format!("option<{}>", self.mangle_valtype(t)) + } + + fn mangle_resulttype(&self, ok: Type, error: Type) -> String { + format!( + "result<{}, {}>", + self.mangle_valtype(ok), + self.mangle_valtype(error) + ) + } + + fn mangle_handletype(&self, id: ResourceId) -> String { + format!("handle<{}>", self.resources[id].name) + } + + fn mangle_futuretype(&self, ty: Type) -> String { + format!("future<{}>", self.mangle_valtype(ty)) + } + + fn mangle_streamtype(&self, stream: &Stream) -> String { + format!( + "stream<{}, {}>", + self.mangle_valtype(stream.element), + self.mangle_valtype(stream.end) + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + Docs, Enum, Flag, Flags, FunctionKind, Record, Resource, Result_, Tuple, Union, Variant, + }; + + #[test] + fn test_funcname() { + let interface = Interface::default(); + + assert_eq!( + interface.mangle_funcname( + "foo", + &Function { + docs: Docs::default(), + name: "bar".to_owned(), + kind: FunctionKind::Freestanding, + params: Vec::new(), + result: Type::Unit + } + ), + "foo: func() -> unit" + ); + assert_eq!( + interface.mangle_funcname( + "foo", + &Function { + docs: Docs::default(), + name: "bar".to_owned(), + kind: FunctionKind::Freestanding, + params: vec![("a".to_owned(), Type::S64)], + result: Type::S32 + } + ), + "foo: func(a: s64) -> s32" + ); + assert_eq!( + interface.mangle_funcname( + "foo", + &Function { + docs: Docs::default(), + name: "bar".to_owned(), + kind: FunctionKind::Freestanding, + params: vec![("a".to_owned(), Type::S64), ("b".to_owned(), Type::U64)], + result: Type::S32 + } + ), + "foo: func(a: s64, b: u64) -> s32" + ); + } + + #[test] + fn test_start_funcname() { + let interface = Interface::default(); + + assert_eq!( + interface.mangle_start_funcname(&Function { + docs: Docs::default(), + name: "foo".to_owned(), + kind: FunctionKind::Freestanding, + params: Vec::new(), + result: Type::Unit + }), + format!("cabi_start{{cabi={}}}: func() -> unit", CABI_VERSION) + ); + } + + #[test] + fn test_types() { + let iface = Interface::default(); + assert_eq!(iface.mangle_valtype(Type::Unit), "unit"); + assert_eq!(iface.mangle_valtype(Type::Bool), "bool"); + assert_eq!(iface.mangle_valtype(Type::S8), "s8"); + assert_eq!(iface.mangle_valtype(Type::U8), "u8"); + assert_eq!(iface.mangle_valtype(Type::S16), "s16"); + assert_eq!(iface.mangle_valtype(Type::U16), "u16"); + assert_eq!(iface.mangle_valtype(Type::S32), "s32"); + assert_eq!(iface.mangle_valtype(Type::U32), "u32"); + assert_eq!(iface.mangle_valtype(Type::S64), "s64"); + assert_eq!(iface.mangle_valtype(Type::U64), "u64"); + assert_eq!(iface.mangle_valtype(Type::Float32), "float32"); + assert_eq!(iface.mangle_valtype(Type::Float64), "float64"); + assert_eq!(iface.mangle_valtype(Type::Char), "char"); + assert_eq!(iface.mangle_valtype(Type::String), "string"); + } + + #[test] + fn test_listtype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::List(Type::U16)), + "list" + ); + } + + #[test] + fn test_recordtype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Record(Record { fields: Vec::new() })), + "record {}" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Record(Record { + fields: vec![Field { + name: "x".to_owned(), + docs: Docs::default(), + ty: Type::Float32 + }] + })), + "record { x: float32 }" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Record(Record { + fields: vec![ + Field { + name: "x".to_owned(), + docs: Docs::default(), + ty: Type::Float32 + }, + Field { + name: "y".to_owned(), + docs: Docs::default(), + ty: Type::Float64 + } + ] + })), + "record { x: float32, y: float64 }" + ); + } + + #[test] + fn test_tupletype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Tuple(Tuple { types: Vec::new() })), + "tuple<>" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Tuple(Tuple { + types: vec![Type::Float32] + })), + "tuple" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Tuple(Tuple { + types: vec![Type::Float32, Type::Float64] + })), + "tuple" + ); + } + + #[test] + fn test_flags() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Flags(Flags { flags: Vec::new() })), + "flags {}" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Flags(Flags { + flags: vec![Flag { + name: "red".to_owned(), + docs: Docs::default() + }] + })), + "flags { red }" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Flags(Flags { + flags: vec![ + Flag { + name: "red".to_owned(), + docs: Docs::default() + }, + Flag { + name: "green".to_owned(), + docs: Docs::default() + } + ] + })), + "flags { red, green }" + ); + } + + #[test] + fn test_varianttype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Variant(Variant { cases: Vec::new() })), + "variant {}" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Variant(Variant { + cases: vec![Case { + name: "x".to_owned(), + docs: Docs::default(), + ty: Type::Float32 + }] + })), + "variant { x(float32) }" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Variant(Variant { + cases: vec![ + Case { + name: "x".to_owned(), + docs: Docs::default(), + ty: Type::Float32 + }, + Case { + name: "y".to_owned(), + docs: Docs::default(), + ty: Type::Float64 + } + ] + })), + "variant { x(float32), y(float64) }" + ); + } + + #[test] + fn test_enumtype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Enum(Enum { cases: Vec::new() })), + "enum {}" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Enum(Enum { + cases: vec![EnumCase { + name: "x".to_owned(), + docs: Docs::default(), + }] + })), + "enum { x }" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Enum(Enum { + cases: vec![ + EnumCase { + name: "x".to_owned(), + docs: Docs::default(), + }, + EnumCase { + name: "y".to_owned(), + docs: Docs::default(), + } + ] + })), + "enum { x, y }" + ); + } + + #[test] + fn test_uniontype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Union(Union { cases: Vec::new() })), + "union {}" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Union(Union { + cases: vec![UnionCase { + docs: Docs::default(), + ty: Type::Float32 + }] + })), + "union { float32 }" + ); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Union(Union { + cases: vec![ + UnionCase { + docs: Docs::default(), + ty: Type::Float32 + }, + UnionCase { + docs: Docs::default(), + ty: Type::Float64 + } + ] + })), + "union { float32, float64 }" + ); + } + + #[test] + fn test_optiontype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Option(Type::S8)), + "option" + ); + } + + #[test] + fn test_resulttype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Result(Result_ { + ok: Type::S32, + err: Type::U32 + })), + "result" + ); + } + + #[test] + fn test_handletype() { + let mut iface = Interface::default(); + let id = iface.resources.alloc(Resource { + name: "thing".to_owned(), + docs: Docs::default(), + foreign_module: None, + supertype: None, + }); + assert_eq!(iface.mangle_valtype(Type::Handle(id)), "handle"); + } + + #[test] + fn test_futuretype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Future(Type::S8)), + "future" + ); + } + + #[test] + fn test_streamtype() { + let iface = Interface::default(); + assert_eq!( + iface.mangle_valtypedef(&TypeDefKind::Stream(Stream { + element: Type::S8, + end: Type::U8 + })), + "stream" + ); + } +} From c18971cb6305adddd00d3a24822a76d182120e43 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 12 Sep 2022 06:50:36 -0700 Subject: [PATCH 4/5] Use name mangling in the bindings generators. --- crates/gen-guest-c/src/lib.rs | 4 +- crates/gen-guest-rust/src/lib.rs | 13 ++++-- crates/gen-guest-spidermonkey-js/src/lib.rs | 19 +++++--- crates/gen-host-js/src/lib.rs | 7 +-- crates/gen-host-wasmtime-py/src/lib.rs | 19 +++++--- crates/gen-host-wasmtime-rust/src/lib.rs | 10 ++-- crates/wit-parser/src/abi.rs | 6 ++- crates/wit-parser/src/mangle.rs | 51 +++++++++------------ tests/runtime/invalid/wasm.rs | 16 +++---- 9 files changed, 79 insertions(+), 66 deletions(-) diff --git a/crates/gen-guest-c/src/lib.rs b/crates/gen-guest-c/src/lib.rs index 91adc28d9..8b407c8ae 100644 --- a/crates/gen-guest-c/src/lib.rs +++ b/crates/gen-guest-c/src/lib.rs @@ -987,7 +987,7 @@ impl Generator for C { self.src.c, "__attribute__((import_module(\"{}\"), import_name(\"{}\")))", iface.name, - func.name + iface.mangle_funcname(func) ); let import_name = self.names.tmp(&format!( "__wasm_import_{}_{}", @@ -1064,7 +1064,7 @@ impl Generator for C { uwriteln!( self.src.c, "__attribute__((export_name(\"{}\")))", - func.name + iface.mangle_funcname(func) ); let import_name = self.names.tmp(&format!( "__wasm_export_{}_{}", diff --git a/crates/gen-guest-rust/src/lib.rs b/crates/gen-guest-rust/src/lib.rs index 6e2ae13bc..3a3869941 100644 --- a/crates/gen-guest-rust/src/lib.rs +++ b/crates/gen-guest-rust/src/lib.rs @@ -533,11 +533,11 @@ impl Generator for RustWasm { Some(module) => { self.src.push_str(module); self.src.push_str("#"); - self.src.push_str(&func.name); + self.src.push_str(&iface.mangle_funcname(func)); } None => { self.src.push_str(&self.opts.symbol_namespace); - self.src.push_str(&func.name); + self.src.push_str(&iface.mangle_funcname(func)); } } self.src.push_str("\"]\n"); @@ -1433,8 +1433,13 @@ impl Bindgen for FunctionBindgen<'_> { Instruction::IterBasePointer => results.push("base".to_string()), - Instruction::CallWasm { iface, name, sig } => { - let func = self.declare_import(iface, name, &sig.params, &sig.results); + Instruction::CallWasm { + iface, + base_name: _, + mangled_name, + sig, + } => { + let func = self.declare_import(iface, mangled_name, &sig.params, &sig.results); // ... then call the function with all our operands if sig.results.len() > 0 { diff --git a/crates/gen-guest-spidermonkey-js/src/lib.rs b/crates/gen-guest-spidermonkey-js/src/lib.rs index bf51d5629..941db4e4c 100644 --- a/crates/gen-guest-spidermonkey-js/src/lib.rs +++ b/crates/gen-guest-spidermonkey-js/src/lib.rs @@ -1056,7 +1056,7 @@ impl Generator for SpiderMonkeyWasm<'_> { let import_fn_index = self.wit_import(self.imports.len()); self.imports.import( &iface.name, - Some(&func.name), + Some(&iface.mangle_funcname(func)), wasm_encoder::EntityType::Function(type_index), ); @@ -1065,7 +1065,7 @@ impl Generator for SpiderMonkeyWasm<'_> { .entry(iface.name.clone()) .or_default() .insert( - func.name.clone(), + iface.mangle_funcname(func), (import_fn_index, u32::try_from(func.params.len()).unwrap()), ); assert!(existing.is_none()); @@ -1088,8 +1088,10 @@ impl Generator for SpiderMonkeyWasm<'_> { let wasm_sig = iface.wasm_signature(AbiVariant::GuestExport, func); let type_index = self.intern_type(wasm_sig.clone()); let export_fn_index = self.wit_export(self.exports.len()); - self.exports - .export(&func.name, wasm_encoder::Export::Function(export_fn_index)); + self.exports.export( + &iface.mangle_funcname(func), + wasm_encoder::Export::Function(export_fn_index), + ); self.function_names .push((export_fn_index, format!("{}.{}", iface.name, func.name))); @@ -1979,7 +1981,12 @@ impl abi::Bindgen for Bindgen<'_, '_> { name: _, ty: _, } => todo!(), - abi::Instruction::CallWasm { iface, name, sig } => { + abi::Instruction::CallWasm { + iface, + base_name: _, + mangled_name, + sig, + } => { // Push the Wasm arguments. // // [] @@ -1994,7 +2001,7 @@ impl abi::Bindgen for Bindgen<'_, '_> { .import_fn_name_to_index .get(&iface.name) .unwrap() - .get(*name) + .get(&*mangled_name) .unwrap() .0; self.inst(Instruction::Call(func_index)); diff --git a/crates/gen-host-js/src/lib.rs b/crates/gen-host-js/src/lib.rs index 573b0a5d7..8fabb8946 100644 --- a/crates/gen-host-js/src/lib.rs +++ b/crates/gen-host-js/src/lib.rs @@ -663,7 +663,7 @@ impl Generator for Js { .entry(*resource) .or_insert(Vec::new()), }; - dst.push((func.name.to_string(), src)); + dst.push((iface.mangle_funcname(func), src)); } // As with `abi_variant` above, we're generating host-side bindings here @@ -2162,13 +2162,14 @@ impl Bindgen for FunctionBindgen<'_> { Instruction::CallWasm { iface: _, - name, + base_name: _, + mangled_name, sig, } => { self.bind_results(sig.results.len(), results); self.src.js(&self.src_object); self.src.js("._exports['"); - self.src.js(&name); + self.src.js(&mangled_name); self.src.js("']("); self.src.js(&operands.join(", ")); self.src.js(");\n"); diff --git a/crates/gen-host-wasmtime-py/src/lib.rs b/crates/gen-host-wasmtime-py/src/lib.rs index 80366f5c5..23b41575d 100644 --- a/crates/gen-host-wasmtime-py/src/lib.rs +++ b/crates/gen-host-wasmtime-py/src/lib.rs @@ -41,7 +41,8 @@ struct Imports { } struct Import { - name: String, + base_name: String, + mangled_name: String, src: Source, wasm_ty: String, pysig: String, @@ -443,7 +444,8 @@ impl Generator for WasmtimePy { ); wasm_ty.push_str("])"); let import = Import { - name: func.name.clone(), + base_name: func.name.clone(), + mangled_name: iface.mangle_funcname(func), src: func_body, wasm_ty, pysig, @@ -538,7 +540,9 @@ impl Generator for WasmtimePy { if let Some(name) = &needs_free { exports.fields.insert(name.clone(), "wasmtime.Func"); } - exports.fields.insert(func.name.clone(), "wasmtime.Func"); + exports + .fields + .insert(iface.mangle_funcname(func), "wasmtime.Func"); let dst = match &func.kind { FunctionKind::Freestanding => &mut exports.freestanding_funcs, @@ -701,8 +705,8 @@ impl Generator for WasmtimePy { self.src.push_str(&format!( "linker.define('{}', '{}', wasmtime.Func(store, ty, {}, access_caller = True))\n", iface.name, - func.name, - func.name.to_snake_case(), + func.mangled_name, + func.base_name.to_snake_case(), )); } @@ -1719,7 +1723,8 @@ impl Bindgen for FunctionBindgen<'_> { } Instruction::CallWasm { iface: _, - name, + base_name, + mangled_name: _, sig, } => { if sig.results.len() > 0 { @@ -1735,7 +1740,7 @@ impl Bindgen for FunctionBindgen<'_> { } builder.push_str(&self.src_object); builder.push_str("._"); - builder.push_str(&name.to_snake_case()); + builder.push_str(&base_name.to_snake_case()); builder.push_str("(caller"); if operands.len() > 0 { builder.push_str(", "); diff --git a/crates/gen-host-wasmtime-rust/src/lib.rs b/crates/gen-host-wasmtime-rust/src/lib.rs index dce290d2f..163b0cb11 100644 --- a/crates/gen-host-wasmtime-rust/src/lib.rs +++ b/crates/gen-host-wasmtime-rust/src/lib.rs @@ -595,7 +595,7 @@ impl Generator for Wasmtime { .entry(iface.name.to_string()) .or_insert(Vec::new()) .push(Import { - name: func.name.to_string(), + name: iface.mangle_funcname(func), closure, trait_signature, }); @@ -703,7 +703,8 @@ impl Generator for Wasmtime { format!("wasmtime::TypedFunc<{}>", cvt), format!( "instance.get_typed_func::<{}, _>(&mut store, \"{}\")?", - cvt, func.name, + cvt, + iface.mangle_funcname(func), ), ), ); @@ -1883,7 +1884,8 @@ impl Bindgen for FunctionBindgen<'_> { Instruction::CallWasm { iface: _, - name, + base_name, + mangled_name: _, sig, } => { if sig.results.len() > 0 { @@ -1898,7 +1900,7 @@ impl Bindgen for FunctionBindgen<'_> { self.push_str(") = "); } self.push_str("self."); - self.push_str(&to_rust_ident(name)); + self.push_str(&to_rust_ident(base_name)); self.push_str(".call("); self.push_str("&mut caller, ("); for operand in operands { diff --git a/crates/wit-parser/src/abi.rs b/crates/wit-parser/src/abi.rs index 460931fa7..b6f70dbe9 100644 --- a/crates/wit-parser/src/abi.rs +++ b/crates/wit-parser/src/abi.rs @@ -636,7 +636,8 @@ def_instruction! { /// provided inline as well as the types if necessary. CallWasm { iface: &'a Interface, - name: &'a str, + base_name: &'a str, + mangled_name: String, sig: &'a WasmSignature, } : [sig.params.len()] => [sig.results.len()], @@ -1080,7 +1081,8 @@ impl<'a, B: Bindgen> Generator<'a, B> { assert_eq!(self.stack.len(), sig.params.len()); self.emit(&Instruction::CallWasm { iface: self.iface, - name: &func.name, + base_name: &func.name, + mangled_name: self.iface.mangle_funcname(func), sig: &sig, }); diff --git a/crates/wit-parser/src/mangle.rs b/crates/wit-parser/src/mangle.rs index b079e1b8c..7b3b9275e 100644 --- a/crates/wit-parser/src/mangle.rs +++ b/crates/wit-parser/src/mangle.rs @@ -206,42 +206,33 @@ mod tests { let interface = Interface::default(); assert_eq!( - interface.mangle_funcname( - "foo", - &Function { - docs: Docs::default(), - name: "bar".to_owned(), - kind: FunctionKind::Freestanding, - params: Vec::new(), - result: Type::Unit - } - ), + interface.mangle_funcname(&Function { + docs: Docs::default(), + name: "foo".to_owned(), + kind: FunctionKind::Freestanding, + params: Vec::new(), + result: Type::Unit + }), "foo: func() -> unit" ); assert_eq!( - interface.mangle_funcname( - "foo", - &Function { - docs: Docs::default(), - name: "bar".to_owned(), - kind: FunctionKind::Freestanding, - params: vec![("a".to_owned(), Type::S64)], - result: Type::S32 - } - ), + interface.mangle_funcname(&Function { + docs: Docs::default(), + name: "foo".to_owned(), + kind: FunctionKind::Freestanding, + params: vec![("a".to_owned(), Type::S64)], + result: Type::S32 + }), "foo: func(a: s64) -> s32" ); assert_eq!( - interface.mangle_funcname( - "foo", - &Function { - docs: Docs::default(), - name: "bar".to_owned(), - kind: FunctionKind::Freestanding, - params: vec![("a".to_owned(), Type::S64), ("b".to_owned(), Type::U64)], - result: Type::S32 - } - ), + interface.mangle_funcname(&Function { + docs: Docs::default(), + name: "foo".to_owned(), + kind: FunctionKind::Freestanding, + params: vec![("a".to_owned(), Type::S64), ("b".to_owned(), Type::U64)], + result: Type::S32 + }), "foo: func(a: s64, b: u64) -> s32" ); } diff --git a/tests/runtime/invalid/wasm.rs b/tests/runtime/invalid/wasm.rs index 00c95cb80..2713da015 100644 --- a/tests/runtime/invalid/wasm.rs +++ b/tests/runtime/invalid/wasm.rs @@ -2,21 +2,21 @@ wit_bindgen_guest_rust::export!("../../tests/runtime/invalid/exports.wit"); #[link(wasm_import_module = "imports")] extern "C" { - #[link_name = "roundtrip-bool"] + #[link_name = "roundtrip-bool: func(a: bool) -> bool"] fn roundtrip_bool(a: i32) -> i32; - #[link_name = "roundtrip-u16"] + #[link_name = "roundtrip-u16: func(a: u16) -> u16"] fn roundtrip_u16(a: i32) -> i32; - #[link_name = "roundtrip-u8"] + #[link_name = "roundtrip-u8: func(a: u8) -> u8"] fn roundtrip_u8(a: i32) -> i32; - #[link_name = "roundtrip-s16"] + #[link_name = "roundtrip-s16: func(a: s16) -> s16"] fn roundtrip_s16(a: i32) -> i32; - #[link_name = "roundtrip-s8"] + #[link_name = "roundtrip-s8: func(a: s8) -> s8"] fn roundtrip_s8(a: i32) -> i32; - #[link_name = "roundtrip-char"] + #[link_name = "roundtrip-char: func(a: char) -> char"] fn roundtrip_char(a: i32) -> i32; - #[link_name = "roundtrip-enum"] + #[link_name = "roundtrip-enum: func(a: enum { a, b, c }) -> enum { a, b, c }"] fn roundtrip_enum(a: i32) -> i32; - #[link_name = "get-internal"] + #[link_name = "get-internal: func(a: handle) -> u32"] fn get_internal(a: i32) -> i32; } From ceaf2e0ddffdfdc4ccee6a98bf7223116618ba9b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 12 Sep 2022 08:03:04 -0700 Subject: [PATCH 5/5] Use the export base name rather than the mangled name for python identifiers. --- crates/gen-host-wasmtime-py/src/lib.rs | 58 +++++++++++++++++++------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/crates/gen-host-wasmtime-py/src/lib.rs b/crates/gen-host-wasmtime-py/src/lib.rs index 23b41575d..1f95bf0e2 100644 --- a/crates/gen-host-wasmtime-py/src/lib.rs +++ b/crates/gen-host-wasmtime-py/src/lib.rs @@ -52,7 +52,12 @@ struct Import { struct Exports { freestanding_funcs: Vec, resource_funcs: BTreeMap>, - fields: BTreeMap, + fields: BTreeMap, +} + +struct Export { + python_type: &'static str, + base_name: String, } #[derive(Default, Debug, Clone)] @@ -530,19 +535,39 @@ impl Generator for WasmtimePy { .entry(iface.name.to_string()) .or_insert_with(Exports::default); if needs_memory { - exports - .fields - .insert("memory".to_string(), "wasmtime.Memory"); + exports.fields.insert( + "memory".to_string(), + Export { + python_type: "wasmtime.Memory", + base_name: "memory".to_owned(), + }, + ); } if let Some(name) = &needs_realloc { - exports.fields.insert(name.clone(), "wasmtime.Func"); + exports.fields.insert( + name.clone(), + Export { + python_type: "wasmtime.Func", + base_name: name.clone(), + }, + ); } if let Some(name) = &needs_free { - exports.fields.insert(name.clone(), "wasmtime.Func"); + exports.fields.insert( + name.clone(), + Export { + python_type: "wasmtime.Func", + base_name: name.clone(), + }, + ); } - exports - .fields - .insert(iface.mangle_funcname(func), "wasmtime.Func"); + exports.fields.insert( + iface.mangle_funcname(func), + Export { + python_type: "wasmtime.Func", + base_name: func.name.clone(), + }, + ); let dst = match &func.kind { FunctionKind::Freestanding => &mut exports.freestanding_funcs, @@ -757,9 +782,12 @@ impl Generator for WasmtimePy { self.src.indent(); self.src.push_str("instance: wasmtime.Instance\n"); - for (name, ty) in exports.fields.iter() { - self.src - .push_str(&format!("_{}: {}\n", name.to_snake_case(), ty)); + for (_name, export) in exports.fields.iter() { + self.src.push_str(&format!( + "_{}: {}\n", + export.base_name.to_snake_case(), + export.python_type + )); } for (id, r) in iface.resources.iter() { self.src.push_str(&format!( @@ -808,7 +836,7 @@ impl Generator for WasmtimePy { .push_str("self.instance = linker.instantiate(store, module)\n"); self.src .push_str("exports = self.instance.exports(store)\n"); - for (name, ty) in exports.fields.iter() { + for (name, export) in exports.fields.iter() { self.src.push_str(&format!( " {snake} = exports['{name}'] @@ -816,8 +844,8 @@ impl Generator for WasmtimePy { self._{snake} = {snake} ", name = name, - snake = name.to_snake_case(), - ty = ty, + snake = export.base_name.to_snake_case(), + ty = export.python_type, )); } for (id, r) in iface.resources.iter() {