From 386f011e386c9eaf1e92c025fa1fad2187793b4e Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Thu, 23 Apr 2026 13:09:05 +0000 Subject: [PATCH 1/4] realloc --- .../src/readers/component/canonicals.rs | 3 +- crates/wasmparser/src/validator/component.rs | 13 +++-- .../cli/component-model/memory64/realloc.wast | 50 +++++++++++++++++++ .../memory64/realloc.wast.json | 39 +++++++++++++++ .../memory64/realloc.wast/0.print | 22 ++++++++ .../memory64/realloc.wast/13.print | 26 ++++++++++ .../memory64/realloc.wast/2.print | 26 ++++++++++ .../memory64/realloc.wast/3.print | 26 ++++++++++ 8 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 tests/cli/component-model/memory64/realloc.wast create mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast.json create mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/0.print create mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/13.print create mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/2.print create mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/3.print diff --git a/crates/wasmparser/src/readers/component/canonicals.rs b/crates/wasmparser/src/readers/component/canonicals.rs index 26df1257cd..76ac7b86bc 100644 --- a/crates/wasmparser/src/readers/component/canonicals.rs +++ b/crates/wasmparser/src/readers/component/canonicals.rs @@ -18,7 +18,8 @@ pub enum CanonicalOption { /// The realloc function to use if the lifting or lowering of a function requires memory /// allocation. /// - /// The value is an index to a core function of type `(func (param i32 i32 i32 i32) (result i32))`. + /// The value is an index to a core function of type `(func (param $T $T $T $T) (result $T))` where + /// `$T` is the index type of the memory, i.e., either `i32` or `i64`. Realloc(u32), /// The post-return function to use if the lifting of a function requires /// cleanup after the function returns. diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs index f323315630..95efea2f2c 100644 --- a/crates/wasmparser/src/validator/component.rs +++ b/crates/wasmparser/src/validator/component.rs @@ -2635,11 +2635,18 @@ impl ComponentState { CanonicalOption::Realloc(idx) => { realloc = match realloc { None => { + let memory_idx = memory.ok_or(BinaryReaderError::new( + "canonical option `realloc` requires the `memory` option", + offset, + ))?; + let addr_type = match self.memory_at(memory_idx, offset)?.memory64 { + true => ValType::I64, + false => ValType::I32, + }; let ty_id = self.core_function_at(*idx, offset)?; let func_ty = types[ty_id].unwrap_func(); - if func_ty.params() - != [ValType::I32, ValType::I32, ValType::I32, ValType::I32] - || func_ty.results() != [ValType::I32] + if func_ty.params() != [addr_type, addr_type, addr_type, addr_type] + || func_ty.results() != [addr_type] { return Err(BinaryReaderError::new( "canonical option `realloc` uses a core function with an incorrect signature", diff --git a/tests/cli/component-model/memory64/realloc.wast b/tests/cli/component-model/memory64/realloc.wast new file mode 100644 index 0000000000..12fc13d71c --- /dev/null +++ b/tests/cli/component-model/memory64/realloc.wast @@ -0,0 +1,50 @@ +;; RUN: wast --assert default --snapshot tests/snapshots -f cm64 % + +(component + (core module $m + (memory (export "m") i64 1) + (func (export "f") (result i32) unreachable) + (func (export "realloc") (param i64 i64 i64 i64) (result i64) unreachable) + ) + (core instance $i (instantiate $m)) + (func (result string) + (canon lift (core func $i "f") + (memory $i "m") + (realloc (func $i "realloc")) + ) + ) +) + +(assert_invalid + (component + (core module $m + (memory (export "m") i64 1) + (func (export "f") (param i32 i32)) + (func (export "realloc") (param i32 i32 i32 i32) (result i32) unreachable) + ) + (core instance $i (instantiate $m)) + (func (param "p1" (list u8)) + (canon lift (core func $i "f") + (memory $i "m") + (realloc (func $i "realloc")) + ) + ) + ) + "canonical option `realloc` uses a core function with an incorrect signature") + +(assert_invalid + (component + (core module $m + (memory (export "m") i32 1) + (func (export "f") (param i32 i32)) + (func (export "realloc") (param i64 i64 i64 i64) (result i64) unreachable) + ) + (core instance $i (instantiate $m)) + (func (param "p1" (list u8)) + (canon lift (core func $i "f") + (memory $i "m") + (realloc (func $i "realloc")) + ) + ) + ) + "canonical option `realloc` uses a core function with an incorrect signature") \ No newline at end of file diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast.json b/tests/snapshots/cli/component-model/memory64/realloc.wast.json new file mode 100644 index 0000000000..62a1e15fba --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast.json @@ -0,0 +1,39 @@ +{ + "source_filename": "tests/cli/component-model/memory64/realloc.wast", + "commands": [ + { + "type": "module", + "line": 3, + "filename": "realloc.0.wasm", + "module_type": "binary" + }, + { + "type": "assert_invalid", + "line": 19, + "filename": "realloc.1.wasm", + "module_type": "binary", + "text": "canonical option `realloc` uses a core function with an incorrect signature" + }, + { + "type": "assert_invalid", + "line": 36, + "filename": "realloc.2.wasm", + "module_type": "binary", + "text": "canonical option `realloc` uses a core function with an incorrect signature" + }, + { + "type": "assert_invalid", + "line": 53, + "filename": "realloc.3.wasm", + "module_type": "binary", + "text": "lowered parameter types `[]` do not match parameter types `[I32]`" + }, + { + "type": "assert_invalid", + "line": 61, + "filename": "realloc.4.wasm", + "module_type": "binary", + "text": "lowered result types `[]` do not match result types `[I32]`" + } + ] +} \ No newline at end of file diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/0.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/0.print new file mode 100644 index 0000000000..6b1f904c64 --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast/0.print @@ -0,0 +1,22 @@ +(component + (core module $m (;0;) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i64 i64 i64 i64) (result i64))) + (memory (;0;) i64 1) + (export "m" (memory 0)) + (export "f" (func 0)) + (export "realloc" (func 1)) + (func (;0;) (type 0) (result i32) + unreachable + ) + (func (;1;) (type 1) (param i64 i64 i64 i64) (result i64) + unreachable + ) + ) + (core instance $i (;0;) (instantiate $m)) + (type (;0;) (func (result string))) + (alias core export $i "f" (core func (;0;))) + (alias core export $i "m" (core memory (;0;))) + (alias core export $i "realloc" (core func (;1;))) + (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1))) +) diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print new file mode 100644 index 0000000000..33ae157f20 --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print @@ -0,0 +1,26 @@ +(component + (core module $m (;0;) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32 i32 i32) (result i32))) + (type (;2;) (func (param i32))) + (memory (;0;) 1) + (export "m" (memory 0)) + (export "f" (func 0)) + (export "r" (func 1)) + (export "p" (func 2)) + (func (;0;) (type 0) (result i32) + unreachable + ) + (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) + unreachable + ) + (func (;2;) (type 2) (param i32)) + ) + (core instance $i (;0;) (instantiate $m)) + (type (;0;) (func (result string))) + (alias core export $i "f" (core func (;0;))) + (alias core export $i "m" (core memory (;0;))) + (alias core export $i "r" (core func (;1;))) + (alias core export $i "p" (core func (;2;))) + (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) +) diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print new file mode 100644 index 0000000000..33ae157f20 --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print @@ -0,0 +1,26 @@ +(component + (core module $m (;0;) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32 i32 i32) (result i32))) + (type (;2;) (func (param i32))) + (memory (;0;) 1) + (export "m" (memory 0)) + (export "f" (func 0)) + (export "r" (func 1)) + (export "p" (func 2)) + (func (;0;) (type 0) (result i32) + unreachable + ) + (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) + unreachable + ) + (func (;2;) (type 2) (param i32)) + ) + (core instance $i (;0;) (instantiate $m)) + (type (;0;) (func (result string))) + (alias core export $i "f" (core func (;0;))) + (alias core export $i "m" (core memory (;0;))) + (alias core export $i "r" (core func (;1;))) + (alias core export $i "p" (core func (;2;))) + (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) +) diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print new file mode 100644 index 0000000000..33ae157f20 --- /dev/null +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print @@ -0,0 +1,26 @@ +(component + (core module $m (;0;) + (type (;0;) (func (result i32))) + (type (;1;) (func (param i32 i32 i32 i32) (result i32))) + (type (;2;) (func (param i32))) + (memory (;0;) 1) + (export "m" (memory 0)) + (export "f" (func 0)) + (export "r" (func 1)) + (export "p" (func 2)) + (func (;0;) (type 0) (result i32) + unreachable + ) + (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) + unreachable + ) + (func (;2;) (type 2) (param i32)) + ) + (core instance $i (;0;) (instantiate $m)) + (type (;0;) (func (result string))) + (alias core export $i "f" (core func (;0;))) + (alias core export $i "m" (core memory (;0;))) + (alias core export $i "r" (core func (;1;))) + (alias core export $i "p" (core func (;2;))) + (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) +) From 421ab314d45c1ef81165276524f0ad1da0042675 Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Thu, 23 Apr 2026 13:23:18 +0000 Subject: [PATCH 2/4] fix task.return --- .../component-model/async/task-builtins.wast | 3 +- .../async/task-builtins.wast.json | 68 +++++++++---------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/tests/cli/component-model/async/task-builtins.wast b/tests/cli/component-model/async/task-builtins.wast index 7cc328897e..060ee7a78d 100644 --- a/tests/cli/component-model/async/task-builtins.wast +++ b/tests/cli/component-model/async/task-builtins.wast @@ -79,10 +79,11 @@ (assert_invalid (component (core module $m + (memory (export "m") i32 1) (func (export "r") (param i32 i32 i32 i32) (result i32) unreachable) ) (core instance $m (instantiate $m)) - (core func $task-return (canon task.return (result u32) (realloc (func $m "r")))) + (core func $task-return (canon task.return (result u32) (memory $m "m") (realloc (func $m "r")))) ) "cannot specify `realloc` option on `task.return`") diff --git a/tests/snapshots/cli/component-model/async/task-builtins.wast.json b/tests/snapshots/cli/component-model/async/task-builtins.wast.json index 195e931af7..8d9b3d4e17 100644 --- a/tests/snapshots/cli/component-model/async/task-builtins.wast.json +++ b/tests/snapshots/cli/component-model/async/task-builtins.wast.json @@ -70,223 +70,223 @@ }, { "type": "module", - "line": 89, + "line": 90, "filename": "task-builtins.10.wasm", "module_type": "binary" }, { "type": "module", - "line": 101, + "line": 102, "filename": "task-builtins.11.wasm", "module_type": "binary" }, { "type": "module", - "line": 110, + "line": 111, "filename": "task-builtins.12.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 118, + "line": 119, "filename": "task-builtins.13.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.new` of module instantiation argument ``" }, { "type": "module", - "line": 127, + "line": 128, "filename": "task-builtins.14.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 139, + "line": 140, "filename": "task-builtins.15.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.wait` of module instantiation argument ``" }, { "type": "module", - "line": 151, + "line": 152, "filename": "task-builtins.16.wasm", "module_type": "binary" }, { "type": "module", - "line": 162, + "line": 163, "filename": "task-builtins.17.wasm", "module_type": "binary" }, { "type": "module", - "line": 171, + "line": 172, "filename": "task-builtins.18.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 183, + "line": 184, "filename": "task-builtins.19.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.poll` of module instantiation argument ``" }, { "type": "module", - "line": 196, + "line": 197, "filename": "task-builtins.20.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 204, + "line": 205, "filename": "task-builtins.21.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.drop` of module instantiation argument ``" }, { "type": "module", - "line": 213, + "line": 214, "filename": "task-builtins.22.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 221, + "line": 222, "filename": "task-builtins.23.wasm", "module_type": "binary", "text": "type mismatch for export `waitable.join` of module instantiation argument ``" }, { "type": "module", - "line": 230, + "line": 231, "filename": "task-builtins.24.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 240, + "line": 241, "filename": "task-builtins.25.wasm", "module_type": "binary", "text": "type mismatch for export `subtask.drop` of module instantiation argument ``" }, { "type": "module", - "line": 251, + "line": 252, "filename": "task-builtins.26.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 261, + "line": 262, "filename": "task-builtins.27.wasm", "module_type": "binary", "text": "type mismatch for export `subtask.cancel` of module instantiation argument ``" }, { "type": "module", - "line": 272, + "line": 273, "filename": "task-builtins.28.wasm", "module_type": "binary" }, { "type": "module", - "line": 289, + "line": 290, "filename": "task-builtins.29.wasm", "module_type": "binary" }, { "type": "module", - "line": 297, + "line": 298, "filename": "task-builtins.30.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 307, + "line": 308, "filename": "task-builtins.31.wasm", "module_type": "binary", "text": "type mismatch for export `thread.yield` of module instantiation argument ``" }, { "type": "assert_invalid", - "line": 318, + "line": 319, "filename": "task-builtins.32.wasm", "module_type": "binary", "text": "found: (func (result i32))" }, { "type": "assert_invalid", - "line": 325, + "line": 326, "filename": "task-builtins.33.wasm", "module_type": "binary", "text": "found: (func (param i32))" }, { "type": "assert_invalid", - "line": 332, + "line": 333, "filename": "task-builtins.34.wasm", "module_type": "binary", "text": "immediate must be zero: 1" }, { "type": "assert_invalid", - "line": 336, + "line": 337, "filename": "task-builtins.35.wasm", "module_type": "binary", "text": "immediate must be zero: 1" }, { "type": "assert_invalid", - "line": 340, + "line": 341, "filename": "task-builtins.36.wasm", "module_type": "binary", "text": "immediate must be zero: 100" }, { "type": "assert_invalid", - "line": 344, + "line": 345, "filename": "task-builtins.37.wasm", "module_type": "binary", "text": "immediate must be zero: 100" }, { "type": "assert_malformed", - "line": 348, + "line": 349, "filename": "task-builtins.38.wat", "module_type": "text", "text": "expected keyword `i32`" }, { "type": "assert_malformed", - "line": 352, + "line": 353, "filename": "task-builtins.39.wat", "module_type": "text", "text": "expected keyword `i32`" }, { "type": "assert_malformed", - "line": 357, + "line": 358, "filename": "task-builtins.40.wasm", "module_type": "binary", "text": "invalid leading byte (0x7e) for context.get" }, { "type": "assert_malformed", - "line": 364, + "line": 365, "filename": "task-builtins.41.wasm", "module_type": "binary", "text": "invalid leading byte (0x7e) for context.set" }, { "type": "module", - "line": 373, + "line": 374, "filename": "task-builtins.42.wasm", "module_type": "binary" }, { "type": "module", - "line": 433, + "line": 434, "filename": "task-builtins.43.wasm", "module_type": "binary" } From 9c2069836138d8ce66bf9680495e3e3d7a645ede Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Thu, 23 Apr 2026 13:30:24 +0000 Subject: [PATCH 3/4] files --- .../memory64/realloc.wast.json | 14 ---------- .../memory64/realloc.wast/13.print | 26 ------------------- .../memory64/realloc.wast/2.print | 26 ------------------- .../memory64/realloc.wast/3.print | 26 ------------------- 4 files changed, 92 deletions(-) delete mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/13.print delete mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/2.print delete mode 100644 tests/snapshots/cli/component-model/memory64/realloc.wast/3.print diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast.json b/tests/snapshots/cli/component-model/memory64/realloc.wast.json index 62a1e15fba..fe0b7dd7d9 100644 --- a/tests/snapshots/cli/component-model/memory64/realloc.wast.json +++ b/tests/snapshots/cli/component-model/memory64/realloc.wast.json @@ -20,20 +20,6 @@ "filename": "realloc.2.wasm", "module_type": "binary", "text": "canonical option `realloc` uses a core function with an incorrect signature" - }, - { - "type": "assert_invalid", - "line": 53, - "filename": "realloc.3.wasm", - "module_type": "binary", - "text": "lowered parameter types `[]` do not match parameter types `[I32]`" - }, - { - "type": "assert_invalid", - "line": 61, - "filename": "realloc.4.wasm", - "module_type": "binary", - "text": "lowered result types `[]` do not match result types `[I32]`" } ] } \ No newline at end of file diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print deleted file mode 100644 index 33ae157f20..0000000000 --- a/tests/snapshots/cli/component-model/memory64/realloc.wast/13.print +++ /dev/null @@ -1,26 +0,0 @@ -(component - (core module $m (;0;) - (type (;0;) (func (result i32))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (type (;2;) (func (param i32))) - (memory (;0;) 1) - (export "m" (memory 0)) - (export "f" (func 0)) - (export "r" (func 1)) - (export "p" (func 2)) - (func (;0;) (type 0) (result i32) - unreachable - ) - (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) - unreachable - ) - (func (;2;) (type 2) (param i32)) - ) - (core instance $i (;0;) (instantiate $m)) - (type (;0;) (func (result string))) - (alias core export $i "f" (core func (;0;))) - (alias core export $i "m" (core memory (;0;))) - (alias core export $i "r" (core func (;1;))) - (alias core export $i "p" (core func (;2;))) - (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) -) diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print deleted file mode 100644 index 33ae157f20..0000000000 --- a/tests/snapshots/cli/component-model/memory64/realloc.wast/2.print +++ /dev/null @@ -1,26 +0,0 @@ -(component - (core module $m (;0;) - (type (;0;) (func (result i32))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (type (;2;) (func (param i32))) - (memory (;0;) 1) - (export "m" (memory 0)) - (export "f" (func 0)) - (export "r" (func 1)) - (export "p" (func 2)) - (func (;0;) (type 0) (result i32) - unreachable - ) - (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) - unreachable - ) - (func (;2;) (type 2) (param i32)) - ) - (core instance $i (;0;) (instantiate $m)) - (type (;0;) (func (result string))) - (alias core export $i "f" (core func (;0;))) - (alias core export $i "m" (core memory (;0;))) - (alias core export $i "r" (core func (;1;))) - (alias core export $i "p" (core func (;2;))) - (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) -) diff --git a/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print b/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print deleted file mode 100644 index 33ae157f20..0000000000 --- a/tests/snapshots/cli/component-model/memory64/realloc.wast/3.print +++ /dev/null @@ -1,26 +0,0 @@ -(component - (core module $m (;0;) - (type (;0;) (func (result i32))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (type (;2;) (func (param i32))) - (memory (;0;) 1) - (export "m" (memory 0)) - (export "f" (func 0)) - (export "r" (func 1)) - (export "p" (func 2)) - (func (;0;) (type 0) (result i32) - unreachable - ) - (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) - unreachable - ) - (func (;2;) (type 2) (param i32)) - ) - (core instance $i (;0;) (instantiate $m)) - (type (;0;) (func (result string))) - (alias core export $i "f" (core func (;0;))) - (alias core export $i "m" (core memory (;0;))) - (alias core export $i "r" (core func (;1;))) - (alias core export $i "p" (core func (;2;))) - (func (;0;) (type 0) (canon lift (core func 0) (memory 0) (realloc 1) (post-return 2))) -) From 168015381943d7fffb0301ba3925c58b11fdf6ee Mon Sep 17 00:00:00 2001 From: Michael Weigelt Date: Fri, 24 Apr 2026 09:25:43 +0000 Subject: [PATCH 4/4] address comments --- crates/wasmparser/src/validator/component.rs | 42 +++++++----- .../component-model/async/task-builtins.wast | 3 +- .../async/task-builtins.wast.json | 68 +++++++++---------- 3 files changed, 59 insertions(+), 54 deletions(-) diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs index 95efea2f2c..83b1749a48 100644 --- a/crates/wasmparser/src/validator/component.rs +++ b/crates/wasmparser/src/validator/component.rs @@ -2635,24 +2635,7 @@ impl ComponentState { CanonicalOption::Realloc(idx) => { realloc = match realloc { None => { - let memory_idx = memory.ok_or(BinaryReaderError::new( - "canonical option `realloc` requires the `memory` option", - offset, - ))?; - let addr_type = match self.memory_at(memory_idx, offset)?.memory64 { - true => ValType::I64, - false => ValType::I32, - }; - let ty_id = self.core_function_at(*idx, offset)?; - let func_ty = types[ty_id].unwrap_func(); - if func_ty.params() != [addr_type, addr_type, addr_type, addr_type] - || func_ty.results() != [addr_type] - { - return Err(BinaryReaderError::new( - "canonical option `realloc` uses a core function with an incorrect signature", - offset, - )); - } + // Validation deferred because it may depend on the memory option. Some(*idx) } Some(_) => { @@ -2778,6 +2761,29 @@ impl ComponentState { bail!(offset, "cannot specify `core-type` without `gc`") } + // Validate `realloc` + if let Some(realloc_idx) = realloc { + let addr_type = match memory { + // If a memory was specified, `realloc` must match its address type. + Some(memory_idx) => match self.memory_at(memory_idx, offset)?.memory64 { + true => ValType::I64, + false => ValType::I32, + }, + // Backwards compatibility: Assume `i32` memory if none was specified. + None => ValType::I32, + }; + let ty_id = self.core_function_at(realloc_idx, offset)?; + let func_ty = types[ty_id].unwrap_func(); + if func_ty.params() != [addr_type, addr_type, addr_type, addr_type] + || func_ty.results() != [addr_type] + { + return Err(BinaryReaderError::new( + "canonical option `realloc` uses a core function with an incorrect signature", + offset, + )); + } + } + Ok(CanonicalOptions { string_encoding, memory, diff --git a/tests/cli/component-model/async/task-builtins.wast b/tests/cli/component-model/async/task-builtins.wast index 060ee7a78d..7cc328897e 100644 --- a/tests/cli/component-model/async/task-builtins.wast +++ b/tests/cli/component-model/async/task-builtins.wast @@ -79,11 +79,10 @@ (assert_invalid (component (core module $m - (memory (export "m") i32 1) (func (export "r") (param i32 i32 i32 i32) (result i32) unreachable) ) (core instance $m (instantiate $m)) - (core func $task-return (canon task.return (result u32) (memory $m "m") (realloc (func $m "r")))) + (core func $task-return (canon task.return (result u32) (realloc (func $m "r")))) ) "cannot specify `realloc` option on `task.return`") diff --git a/tests/snapshots/cli/component-model/async/task-builtins.wast.json b/tests/snapshots/cli/component-model/async/task-builtins.wast.json index 8d9b3d4e17..195e931af7 100644 --- a/tests/snapshots/cli/component-model/async/task-builtins.wast.json +++ b/tests/snapshots/cli/component-model/async/task-builtins.wast.json @@ -70,223 +70,223 @@ }, { "type": "module", - "line": 90, + "line": 89, "filename": "task-builtins.10.wasm", "module_type": "binary" }, { "type": "module", - "line": 102, + "line": 101, "filename": "task-builtins.11.wasm", "module_type": "binary" }, { "type": "module", - "line": 111, + "line": 110, "filename": "task-builtins.12.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 119, + "line": 118, "filename": "task-builtins.13.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.new` of module instantiation argument ``" }, { "type": "module", - "line": 128, + "line": 127, "filename": "task-builtins.14.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 140, + "line": 139, "filename": "task-builtins.15.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.wait` of module instantiation argument ``" }, { "type": "module", - "line": 152, + "line": 151, "filename": "task-builtins.16.wasm", "module_type": "binary" }, { "type": "module", - "line": 163, + "line": 162, "filename": "task-builtins.17.wasm", "module_type": "binary" }, { "type": "module", - "line": 172, + "line": 171, "filename": "task-builtins.18.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 184, + "line": 183, "filename": "task-builtins.19.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.poll` of module instantiation argument ``" }, { "type": "module", - "line": 197, + "line": 196, "filename": "task-builtins.20.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 205, + "line": 204, "filename": "task-builtins.21.wasm", "module_type": "binary", "text": "type mismatch for export `waitable-set.drop` of module instantiation argument ``" }, { "type": "module", - "line": 214, + "line": 213, "filename": "task-builtins.22.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 222, + "line": 221, "filename": "task-builtins.23.wasm", "module_type": "binary", "text": "type mismatch for export `waitable.join` of module instantiation argument ``" }, { "type": "module", - "line": 231, + "line": 230, "filename": "task-builtins.24.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 241, + "line": 240, "filename": "task-builtins.25.wasm", "module_type": "binary", "text": "type mismatch for export `subtask.drop` of module instantiation argument ``" }, { "type": "module", - "line": 252, + "line": 251, "filename": "task-builtins.26.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 262, + "line": 261, "filename": "task-builtins.27.wasm", "module_type": "binary", "text": "type mismatch for export `subtask.cancel` of module instantiation argument ``" }, { "type": "module", - "line": 273, + "line": 272, "filename": "task-builtins.28.wasm", "module_type": "binary" }, { "type": "module", - "line": 290, + "line": 289, "filename": "task-builtins.29.wasm", "module_type": "binary" }, { "type": "module", - "line": 298, + "line": 297, "filename": "task-builtins.30.wasm", "module_type": "binary" }, { "type": "assert_invalid", - "line": 308, + "line": 307, "filename": "task-builtins.31.wasm", "module_type": "binary", "text": "type mismatch for export `thread.yield` of module instantiation argument ``" }, { "type": "assert_invalid", - "line": 319, + "line": 318, "filename": "task-builtins.32.wasm", "module_type": "binary", "text": "found: (func (result i32))" }, { "type": "assert_invalid", - "line": 326, + "line": 325, "filename": "task-builtins.33.wasm", "module_type": "binary", "text": "found: (func (param i32))" }, { "type": "assert_invalid", - "line": 333, + "line": 332, "filename": "task-builtins.34.wasm", "module_type": "binary", "text": "immediate must be zero: 1" }, { "type": "assert_invalid", - "line": 337, + "line": 336, "filename": "task-builtins.35.wasm", "module_type": "binary", "text": "immediate must be zero: 1" }, { "type": "assert_invalid", - "line": 341, + "line": 340, "filename": "task-builtins.36.wasm", "module_type": "binary", "text": "immediate must be zero: 100" }, { "type": "assert_invalid", - "line": 345, + "line": 344, "filename": "task-builtins.37.wasm", "module_type": "binary", "text": "immediate must be zero: 100" }, { "type": "assert_malformed", - "line": 349, + "line": 348, "filename": "task-builtins.38.wat", "module_type": "text", "text": "expected keyword `i32`" }, { "type": "assert_malformed", - "line": 353, + "line": 352, "filename": "task-builtins.39.wat", "module_type": "text", "text": "expected keyword `i32`" }, { "type": "assert_malformed", - "line": 358, + "line": 357, "filename": "task-builtins.40.wasm", "module_type": "binary", "text": "invalid leading byte (0x7e) for context.get" }, { "type": "assert_malformed", - "line": 365, + "line": 364, "filename": "task-builtins.41.wasm", "module_type": "binary", "text": "invalid leading byte (0x7e) for context.set" }, { "type": "module", - "line": 374, + "line": 373, "filename": "task-builtins.42.wasm", "module_type": "binary" }, { "type": "module", - "line": 434, + "line": 433, "filename": "task-builtins.43.wasm", "module_type": "binary" }