diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs index 02f43fd349..f6fd5d3a28 100644 --- a/crates/wasmparser/src/validator/component.rs +++ b/crates/wasmparser/src/validator/component.rs @@ -2118,9 +2118,11 @@ impl ComponentState { } self.cabi_memory_at(memory, offset)?; - - self.core_funcs - .push(types.intern_func_type(FuncType::new([ValType::I32; 2], [ValType::I32]), offset)); + let memory64 = self.memory_at(memory, offset)?.memory64; + let ty = if memory64 { ValType::I64 } else { ValType::I32 }; + self.core_funcs.push( + types.intern_func_type(FuncType::new([ValType::I32, ty], [ValType::I32]), offset), + ); Ok(()) } @@ -2138,9 +2140,11 @@ impl ComponentState { } self.cabi_memory_at(memory, offset)?; - - self.core_funcs - .push(types.intern_func_type(FuncType::new([ValType::I32; 2], [ValType::I32]), offset)); + let memory64 = self.memory_at(memory, offset)?.memory64; + let ty = if memory64 { ValType::I64 } else { ValType::I32 }; + self.core_funcs.push( + types.intern_func_type(FuncType::new([ValType::I32, ty], [ValType::I32]), offset), + ); Ok(()) } diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index d7565b5600..67c491c6c2 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -633,16 +633,16 @@ impl ImportMap { return Ok(Import::WaitableSetNew); } - if let Some(info) = names.waitable_set_wait(name) { - let expected = FuncType::new([ValType::I32; 2], [ValType::I32]); + if let Some((info, result_ty)) = names.waitable_set_wait(name) { + let expected = FuncType::new([ValType::I32, result_ty], [ValType::I32]); validate_func_sig(name, &expected, ty)?; return Ok(Import::WaitableSetWait { cancellable: info.cancellable, }); } - if let Some(info) = names.waitable_set_poll(name) { - let expected = FuncType::new([ValType::I32; 2], [ValType::I32]); + if let Some((info, result_ty)) = names.waitable_set_poll(name) { + let expected = FuncType::new([ValType::I32, result_ty], [ValType::I32]); validate_func_sig(name, &expected, ty)?; return Ok(Import::WaitableSetPoll { cancellable: info.cancellable, @@ -1580,8 +1580,8 @@ trait NameMangling { fn backpressure_inc(&self, name: &str) -> bool; fn backpressure_dec(&self, name: &str) -> bool; fn waitable_set_new(&self, name: &str) -> bool; - fn waitable_set_wait(&self, name: &str) -> Option>; - fn waitable_set_poll(&self, name: &str) -> Option>; + fn waitable_set_wait(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)>; + fn waitable_set_poll(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)>; fn waitable_set_drop(&self, name: &str) -> bool; fn waitable_join(&self, name: &str) -> bool; fn thread_yield(&self, name: &str) -> Option>; @@ -1747,10 +1747,10 @@ impl NameMangling for Standard { fn waitable_set_new(&self, _name: &str) -> bool { false } - fn waitable_set_wait(&self, _name: &str) -> Option> { + fn waitable_set_wait(&self, _name: &str) -> Option<(MaybeCancellable<()>, ValType)> { None } - fn waitable_set_poll(&self, _name: &str) -> Option> { + fn waitable_set_poll(&self, _name: &str) -> Option<(MaybeCancellable<()>, ValType)> { None } fn waitable_set_drop(&self, _name: &str) -> bool { @@ -2142,6 +2142,23 @@ impl Legacy { None } } + + /// Matches a name with the given prefix and either no suffix (for backwards compat) or + /// "-i32" or "-i64". + /// Returns a `ValType` based on the suffix and defaults to `I32`. + fn match_with_optional_type_suffix(name: &str, match_prefix: &str) -> Option { + let tail = name.strip_prefix(match_prefix)?.strip_suffix(']')?; + if tail.is_empty() { + Some(ValType::I32) + } else { + match tail.strip_prefix('-')? { + "i32" => Some(ValType::I32), + "i64" => Some(ValType::I64), + // Other suffixes + _ => None, + } + } + } } impl NameMangling for Legacy { @@ -2196,11 +2213,23 @@ impl NameMangling for Legacy { fn waitable_set_new(&self, name: &str) -> bool { name == "[waitable-set-new]" } - fn waitable_set_wait(&self, name: &str) -> Option> { - self.match_with_cancellable_prefix(name, "[waitable-set-wait]") + fn waitable_set_wait(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)> { + let (cancellable, clean_name) = self.strip_cancellable_prefix(name); + let mb_cancellable = MaybeCancellable { + inner: (), + cancellable, + }; + let result_ty = Legacy::match_with_optional_type_suffix(clean_name, "[waitable-set-wait")?; + Some((mb_cancellable, result_ty)) } - fn waitable_set_poll(&self, name: &str) -> Option> { - self.match_with_cancellable_prefix(name, "[waitable-set-poll]") + fn waitable_set_poll(&self, name: &str) -> Option<(MaybeCancellable<()>, ValType)> { + let (cancellable, clean_name) = self.strip_cancellable_prefix(name); + let mb_cancellable = MaybeCancellable { + inner: (), + cancellable, + }; + let result_ty = Legacy::match_with_optional_type_suffix(clean_name, "[waitable-set-poll")?; + Some((mb_cancellable, result_ty)) } fn waitable_set_drop(&self, name: &str) -> bool { name == "[waitable-set-drop]" diff --git a/tests/cli/component-model/memory64/waitable-set.wast b/tests/cli/component-model/memory64/waitable-set.wast new file mode 100644 index 0000000000..00641d1e77 --- /dev/null +++ b/tests/cli/component-model/memory64/waitable-set.wast @@ -0,0 +1,78 @@ +;; RUN: wast --assert default --snapshot tests/snapshots % -f cm-async,cm64 + +;; waitable-set.wait + +(component + (core module $libc (memory (export "memory") i64 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i64) (result i32))) + ) + (core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait)))))) +) + +(assert_invalid + (component + (core module $libc (memory (export "memory") 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i64) (result i32))) + ) + (core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait)))))) + ) + "type mismatch for export `waitable-set.wait`" +) + +(assert_invalid + (component + (core module $libc (memory (export "memory") i64 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.wait" (func $waitable-set-wait (param i32 i32) (result i32))) + ) + (core func $waitable-set-wait (canon waitable-set.wait cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.wait" (func $waitable-set-wait)))))) + ) + "type mismatch for export `waitable-set.wait`" +) + + +;; waitable-set.poll + +(component + (core module $libc (memory (export "memory") i64 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i64) (result i32))) + ) + (core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll)))))) +) + +(assert_invalid + (component + (core module $libc (memory (export "memory") 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i64) (result i32))) + ) + (core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll)))))) + ) + "type mismatch for export `waitable-set.poll`" +) + +(assert_invalid + (component + (core module $libc (memory (export "memory") i64 1)) + (core instance $libc (instantiate $libc)) + (core module $m + (import "" "waitable-set.poll" (func $waitable-set-poll (param i32 i32) (result i32))) + ) + (core func $waitable-set-poll (canon waitable-set.poll cancellable (memory $libc "memory"))) + (core instance $i (instantiate $m (with "" (instance (export "waitable-set.poll" (func $waitable-set-poll)))))) + ) + "type mismatch for export `waitable-set.poll`" +) \ No newline at end of file diff --git a/tests/snapshots/cli/component-model/memory64/waitable-set.wast.json b/tests/snapshots/cli/component-model/memory64/waitable-set.wast.json new file mode 100644 index 0000000000..30e0a4c70b --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/waitable-set.wast.json @@ -0,0 +1,45 @@ +{ + "source_filename": "tests/cli/component-model/memory64/waitable-set.wast", + "commands": [ + { + "type": "module", + "line": 5, + "filename": "waitable-set.0.wasm", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 16, + "filename": "waitable-set.1.wasm", + "module_type": "binary", + "text": "type mismatch for export `waitable-set.wait`" + }, + { + "type": "assert_invalid", + "line": 29, + "filename": "waitable-set.2.wasm", + "module_type": "binary", + "text": "type mismatch for export `waitable-set.wait`" + }, + { + "type": "module", + "line": 44, + "filename": "waitable-set.3.wasm", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 55, + "filename": "waitable-set.4.wasm", + "module_type": "binary", + "text": "type mismatch for export `waitable-set.poll`" + }, + { + "type": "assert_invalid", + "line": 68, + "filename": "waitable-set.5.wasm", + "module_type": "binary", + "text": "type mismatch for export `waitable-set.poll`" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/cli/component-model/memory64/waitable-set.wast/0.print b/tests/snapshots/cli/component-model/memory64/waitable-set.wast/0.print new file mode 100644 index 0000000000..c32d30e5e7 --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/waitable-set.wast/0.print @@ -0,0 +1,20 @@ +(component + (core module $libc (;0;) + (memory (;0;) i64 1) + (export "memory" (memory 0)) + ) + (core instance $libc (;0;) (instantiate $libc)) + (core module $m (;1;) + (type (;0;) (func (param i32 i64) (result i32))) + (import "" "waitable-set.wait" (func $waitable-set-wait (;0;) (type 0))) + ) + (alias core export $libc "memory" (core memory (;0;))) + (core func $waitable-set-wait (;0;) (canon waitable-set.wait cancellable (memory 0))) + (core instance (;1;) + (export "waitable-set.wait" (func $waitable-set-wait)) + ) + (core instance $i (;2;) (instantiate $m + (with "" (instance 1)) + ) + ) +) diff --git a/tests/snapshots/cli/component-model/memory64/waitable-set.wast/3.print b/tests/snapshots/cli/component-model/memory64/waitable-set.wast/3.print new file mode 100644 index 0000000000..849528e4bb --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/waitable-set.wast/3.print @@ -0,0 +1,20 @@ +(component + (core module $libc (;0;) + (memory (;0;) i64 1) + (export "memory" (memory 0)) + ) + (core instance $libc (;0;) (instantiate $libc)) + (core module $m (;1;) + (type (;0;) (func (param i32 i64) (result i32))) + (import "" "waitable-set.poll" (func $waitable-set-poll (;0;) (type 0))) + ) + (alias core export $libc "memory" (core memory (;0;))) + (core func $waitable-set-poll (;0;) (canon waitable-set.poll cancellable (memory 0))) + (core instance (;1;) + (export "waitable-set.poll" (func $waitable-set-poll)) + ) + (core instance $i (;2;) (instantiate $m + (with "" (instance 1)) + ) + ) +)