diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index a8033a8fca5..f48bbd7dd1c 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -4724,10 +4724,8 @@ class ModuleRunnerBase : public ExpressionRunner { if (funcValue.isNull()) { trap("null ref"); } - auto funcName = funcValue.getFunc(); - auto* func = self()->getModule()->getFunction(funcName); - return Literal(std::make_shared( - self()->makeFuncData(funcName, func->type), curr->type.getHeapType())); + return Literal( + std::make_shared(funcValue, curr->type.getHeapType())); } Flow visitContBind(ContBind* curr) { Literals arguments; diff --git a/test/lit/exec/cont_external_funcref.wast b/test/lit/exec/cont_external_funcref.wast new file mode 100644 index 00000000000..b94de188c1c --- /dev/null +++ b/test/lit/exec/cont_external_funcref.wast @@ -0,0 +1,22 @@ + +;; RUN: wasm-opt %s -all --fuzz-exec-before --fuzz-exec-second=%s.second -q -o /dev/null 2>&1 | filecheck %s + +;; Export a function reference from the first module to the second. The second +;; can create a continuation without erroring, even though it uses a funcref +;; from another module. + +(module + (type $func (func)) + + (global $global (ref $func) (ref.func $func)) + + (export "global$func" (global $global)) + + (func $func + ) +) + +;; CHECK: [fuzz-exec] running second module +;; CHECK-NEXT: [fuzz-exec] calling export +;; CHECK-NEXT: [fuzz-exec] note result: export => 42 + diff --git a/test/lit/exec/cont_external_funcref.wast.second b/test/lit/exec/cont_external_funcref.wast.second new file mode 100644 index 00000000000..b85fa113d1f --- /dev/null +++ b/test/lit/exec/cont_external_funcref.wast.second @@ -0,0 +1,15 @@ +(module + (type $func (func)) + (type $cont (cont $func)) + (import "primary" "global$func" (global $gimport (ref $func))) + + (func $export (export "export") (result i32) + (drop + (cont.new $cont + (global.get $gimport) + ) + ) + (i32.const 42) + ) +) +