From babd8b66e4615119e2e94c377eecf92375b11021 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 26 Jun 2026 10:46:17 -0500 Subject: [PATCH] Fix 'canon lower' validation rule inconsistency --- design/mvp/CanonicalABI.md | 2 +- test/validation/abi.wast | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/validation/abi.wast diff --git a/design/mvp/CanonicalABI.md b/design/mvp/CanonicalABI.md index 9a268606..e9132ab3 100644 --- a/design/mvp/CanonicalABI.md +++ b/design/mvp/CanonicalABI.md @@ -3795,7 +3795,7 @@ validation is performed where `$callee` has type `$ft`: * requires options [based on `lower(param)`](#canonopt-validation) for all parameters in `ft` * requires options [based on `lift(result)`](#canonopt-validation) if `ft` has a result * if `len(flatten_types(ft.param_types())) > max_flat_params`, `memory` is required -* if `len(flatten_types(ft.result_type())) > max_flat_results`, `realloc` is required +* if `len(flatten_types(ft.result_type())) > max_flat_results`, `memory` is required * 🔀 if `async` is specified, `memory` must be present When instantiating a component instance, the runtime calls `Store.lower` (defined diff --git a/test/validation/abi.wast b/test/validation/abi.wast new file mode 100644 index 00000000..5f1f6483 --- /dev/null +++ b/test/validation/abi.wast @@ -0,0 +1,31 @@ +(assert_invalid + (component + (import "foo" (func $foo (result (tuple u64 u64 u64 u64 u64 u64 u64 u64)))) + (canon lower (func $foo) (core func $foo')) + ) + "canonical option `memory` is required" +) +(assert_invalid + (component + (import "foo" (func $foo (result (tuple u64 u64 u64 u64 u64 u64 u64 u64)))) + (core module $M + (func (export "realloc") (param i32 i32 i32 i32) (result i32) unreachable) + ) + (core instance $i (instantiate $M)) + (canon lower (func $foo) (realloc (func $i "realloc")) (core func $foo')) + ) + "canonical option `realloc` requires `memory` to also be specified" +) +(component + (component + (import "foo" (func $foo (result (tuple u64 u64 u64 u64 u64 u64 u64 u64)))) + (core module $M + (memory (export "mem") 1) + (func (export "realloc") (param i32 i32 i32 i32) (result i32) unreachable) + ) + (core instance $i (instantiate $M)) + (canon lower (func $foo) (memory $i "mem") (core func $foo1)) + ;; realloc superfluous but allowed: + (canon lower (func $foo) (memory $i "mem") (realloc (func $i "realloc")) (core func $foo2)) + ) +)