Repository: bytecodealliance/wasm-tools (rust)

Issue:
components: Realloc option required when not necessary
This component:

```wasm
(component
  (type $big (func
    (param u32) (param u32) (param u32) (param u32) (param u32)
    (param u32) (param u32) (param u32) (param u32) (param u32)
    (param u32) (param u32) (param u32) (param u32) (param u32)
    (param u32) (param u32) (param u32) (param u32) (param u32)
  ))

  (component $c
    (import "big" (func $big (type $big)))

    (core module $libc (memory (export "memory") 1))
    (core instance $libc (instantiate $libc))
    (core func $big (canon lower (func $big) (memory $libc "memory")))
  )
)
```

validates with:

```
$ cargo run -q validate foo.wat --features component-model
Error: canonical option `realloc` is required (at offset 0x8f)
```

In this case, though,`realloc` isn't needed for the outgoing parameters since they're placed onto the stack by the caller.

cc @peterhuene 

Pull request description:
wasmparser: fix validation for realloc option. 
The fix for #684 was a little too broad, applying the requirement that the
realloc option be present when the maximum number of flat parameters is
exceeded to both lifts and lowers.

In fact, this is only true of lifting a function and not for lowering a
function because the adapter just reads the parameters out of the caller's
linear memory and doesn't need to allocate.

Fixes #693.

Patch:
diff --git a/crates/wasm-smith/src/core/notrap.rs b/crates/wasm-smith/src/core/notrap.rs
index b9917ee9..3557f297 100755
--- a/crates/wasm-smith/src/core/notrap.rs
+++ b/crates/wasm-smith/src/core/notrap.rs
@@ -1,5 +1,5 @@
 use crate::core::*;
-use wasm_encoder::{BlockType, ConstExpr, Instruction, ValType};
+use wasm_encoder::{BlockType, Instruction, ValType};
 
 const WASM_PAGE_SIZE: u64 = 65_536;
 
@@ -578,7 +578,6 @@ impl Module {
                             *offset = Offset::Const32(n as i32);
                         }
                         Offset::Global(_) => *offset = Offset::Const32(0),
-                        _ => unreachable!("Unexpected instruction: {:?}", offset),
                     }
                 }
             }
diff --git a/crates/wasmparser/src/validator/types.rs b/crates/wasmparser/src/validator/types.rs
index 312b1261..bc4f4796 100644
--- a/crates/wasmparser/src/validator/types.rs
+++ b/crates/wasmparser/src/validator/types.rs
@@ -752,7 +752,11 @@ impl ComponentFuncType {
                 info.params.clear();
                 assert!(info.params.push(ValType::I32));
                 info.requires_memory = true;
-                info.requires_realloc = true;
+
+                // We need realloc as well when lifting a function
+                if !import {
+                    info.requires_realloc = true;
+                }
                 break;
             }
         }


Test patch:
diff --git a/tests/local/component-model/func.wast b/tests/local/component-model/func.wast
index 63359c2f..a1924e7f 100644
--- a/tests/local/component-model/func.wast
+++ b/tests/local/component-model/func.wast
@@ -39,6 +39,22 @@
   )
 )
 
+(component
+  (type $big (func
+    (param u32) (param u32) (param u32) (param u32) (param u32)
+    (param u32) (param u32) (param u32) (param u32) (param u32)
+    (param u32) (param u32) (param u32) (param u32) (param u32)
+    (param u32) (param u32) (param u32) (param u32) (param u32)
+  ))
+
+  (component $c
+    (import "big" (func $big (type $big)))
+    (core module $libc (memory (export "memory") 1))
+    (core instance $libc (instantiate $libc))
+    (core func $big (canon lower (func $big) (memory $libc "memory")))
+  )
+)
+
 (assert_invalid
   (component
     (core module $m