@@ -4664,6 +4664,30 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4664
4664
4665
4665
// We may have to call multiple functions in the event of return calls.
4666
4666
while (true ) {
4667
+ if (self ()->isResuming ()) {
4668
+ // See which function to call. Re-winding the stack, we are calling the
4669
+ // function that the parent called, but the target that was called may
4670
+ // have return-called. In that case, the original target function should
4671
+ // not be called, as it was returned from, and we noted the proper
4672
+ // target during that return.
4673
+ auto entry = self ()->popResumeEntry (" function-target" );
4674
+ assert (entry.size () == 1 );
4675
+ auto func = entry[0 ];
4676
+ auto data = func.getFuncData ();
4677
+ // We must be in the right module to do the call using that name.
4678
+ if (data->self != self ()) {
4679
+ // Restore the entry to the resume stack, as the other module's
4680
+ // callFunction() will read it. Then call into the other module. This
4681
+ // sets this up as if we called into the proper module in the first
4682
+ // place.
4683
+ self ()->pushResumeEntry (entry, " function-target" );
4684
+ return data->doCall (arguments);
4685
+ }
4686
+
4687
+ // We are in the right place, and can just call the given function.
4688
+ name = data->name ;
4689
+ }
4690
+
4667
4691
Function* function = wasm.getFunction (name);
4668
4692
assert (function);
4669
4693
@@ -4684,7 +4708,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4684
4708
// Restore the local state (see below for the ordering, we push/pop).
4685
4709
for (Index i = 0 ; i < scope.locals .size (); i++) {
4686
4710
auto l = scope.locals .size () - 1 - i;
4687
- scope.locals [l] = self ()->popResumeEntry (" function" );
4711
+ scope.locals [l] = self ()->popResumeEntry (" function-local " );
4688
4712
#ifndef NDEBUG
4689
4713
// Must have restored valid data. The type must match the local's
4690
4714
// type, except for the case of a non-nullable local that has not yet
@@ -4718,8 +4742,15 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4718
4742
if (flow.suspendTag ) {
4719
4743
// Save the local state.
4720
4744
for (auto & local : scope.locals ) {
4721
- self ()->pushResumeEntry (local, " function" );
4745
+ self ()->pushResumeEntry (local, " function-local " );
4722
4746
}
4747
+
4748
+ // Save the function we called (in the case of a return call, this is
4749
+ // not the original function that was called, and the original has been
4750
+ // returned from already; we should call the last return_called
4751
+ // function).
4752
+ auto target = self ()->makeFuncData (name, function->type );
4753
+ self ()->pushResumeEntry ({target}, " function-target" );
4723
4754
}
4724
4755
4725
4756
if (flow.breakTo != RETURN_CALL_FLOW) {
0 commit comments