From 9f83b3cfc1dc63226f7186df8e861f2ab445d764 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Dec 2025 10:27:04 -0800 Subject: [PATCH 1/3] fix --- src/wasm-interpreter.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 2b98c12af31..f6fc5586a94 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -4861,9 +4861,17 @@ class ModuleRunnerBase : public ExpressionRunner { // There was a return call, so we need to call the next function before // returning to the caller. The flow carries the function arguments and a // function reference. - name = flow.values.back().getFunc(); + auto nextData = flow.values.back().getFuncData(); + name = nextData->name; flow.values.pop_back(); arguments = flow.values; + + if (nextData->self != this) { + // This function is in another module. Call from there. + auto other = (decltype(this))nextData->self; + flow = other->callFunction(name, arguments); + break; + } } if (flow.breaking() && flow.breakTo == NONCONSTANT_FLOW) { From 20e10d828da53e99777f7c913b511bb22a1b4f68 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Dec 2025 10:40:29 -0800 Subject: [PATCH 2/3] test --- test/lit/exec/second_retcall.wast | 23 +++++++++++++++++++++++ test/lit/exec/second_retcall.wast.second | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/lit/exec/second_retcall.wast create mode 100644 test/lit/exec/second_retcall.wast.second diff --git a/test/lit/exec/second_retcall.wast b/test/lit/exec/second_retcall.wast new file mode 100644 index 00000000000..842d2e446b7 --- /dev/null +++ b/test/lit/exec/second_retcall.wast @@ -0,0 +1,23 @@ + +;; RUN: wasm-opt %s -all --fuzz-exec-before --fuzz-exec-second=%s.second -q -o /dev/null 2>&1 | filecheck %s + +(module + (import "fuzzing-support" "log-i32" (func $log-i32 (param i32))) + + (global $global funcref (ref.func $func)) + + (export "global" (global $global)) + + (func $func + (call $log-i32 + (i32.const 42) + ) + ) +) + +;; Export a funcref through a global, and return_call it from the other module. +;; It must be called ok, print 42, and not error. + +;; CHECK: [fuzz-exec] calling caller +;; CHECK-NEXT: [LoggingExternalInterface logging 42] + diff --git a/test/lit/exec/second_retcall.wast.second b/test/lit/exec/second_retcall.wast.second new file mode 100644 index 00000000000..77a5e5f27fc --- /dev/null +++ b/test/lit/exec/second_retcall.wast.second @@ -0,0 +1,19 @@ +(module + (type $func (func)) + + (import "primary" "global" (global $gimport funcref)) + + (table $table 10 funcref) + + (func $caller (export "caller") + ;; Do an indirec call from the table, writing the imported funcref first. + (table.set $table + (i32.const 1) + (global.get $gimport) + ) + (return_call_indirect (type $func) + (i32.const 1) + ) + ) +) + From c9d6bf4722de9c76ff25e473b29c6197fd19f3a4 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 2 Dec 2025 10:41:04 -0800 Subject: [PATCH 3/3] typo --- test/lit/exec/second_retcall.wast.second | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lit/exec/second_retcall.wast.second b/test/lit/exec/second_retcall.wast.second index 77a5e5f27fc..6a7184c4241 100644 --- a/test/lit/exec/second_retcall.wast.second +++ b/test/lit/exec/second_retcall.wast.second @@ -6,7 +6,7 @@ (table $table 10 funcref) (func $caller (export "caller") - ;; Do an indirec call from the table, writing the imported funcref first. + ;; Do an indirect call from the table, writing the imported funcref first. (table.set $table (i32.const 1) (global.get $gimport)