Skip to content

Commit 73c3a05

Browse files
authored
Fix cross-module return_calls in the interpreter (#8083)
If the return-called method is from another module, we need to call from that runner instance.
1 parent 3f922c3 commit 73c3a05

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/wasm-interpreter.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4861,9 +4861,17 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
48614861
// There was a return call, so we need to call the next function before
48624862
// returning to the caller. The flow carries the function arguments and a
48634863
// function reference.
4864-
name = flow.values.back().getFunc();
4864+
auto nextData = flow.values.back().getFuncData();
4865+
name = nextData->name;
48654866
flow.values.pop_back();
48664867
arguments = flow.values;
4868+
4869+
if (nextData->self != this) {
4870+
// This function is in another module. Call from there.
4871+
auto other = (decltype(this))nextData->self;
4872+
flow = other->callFunction(name, arguments);
4873+
break;
4874+
}
48674875
}
48684876

48694877
if (flow.breaking() && flow.breakTo == NONCONSTANT_FLOW) {

test/lit/exec/second_retcall.wast

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
;; RUN: wasm-opt %s -all --fuzz-exec-before --fuzz-exec-second=%s.second -q -o /dev/null 2>&1 | filecheck %s
3+
4+
(module
5+
(import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
6+
7+
(global $global funcref (ref.func $func))
8+
9+
(export "global" (global $global))
10+
11+
(func $func
12+
(call $log-i32
13+
(i32.const 42)
14+
)
15+
)
16+
)
17+
18+
;; Export a funcref through a global, and return_call it from the other module.
19+
;; It must be called ok, print 42, and not error.
20+
21+
;; CHECK: [fuzz-exec] calling caller
22+
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
23+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(module
2+
(type $func (func))
3+
4+
(import "primary" "global" (global $gimport funcref))
5+
6+
(table $table 10 funcref)
7+
8+
(func $caller (export "caller")
9+
;; Do an indirect call from the table, writing the imported funcref first.
10+
(table.set $table
11+
(i32.const 1)
12+
(global.get $gimport)
13+
)
14+
(return_call_indirect (type $func)
15+
(i32.const 1)
16+
)
17+
)
18+
)
19+

0 commit comments

Comments
 (0)