@@ -4664,6 +4664,30 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
46644664
46654665 // We may have to call multiple functions in the event of return calls.
46664666 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+
46674691 Function* function = wasm.getFunction (name);
46684692 assert (function);
46694693
@@ -4684,7 +4708,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
46844708 // Restore the local state (see below for the ordering, we push/pop).
46854709 for (Index i = 0 ; i < scope.locals .size (); i++) {
46864710 auto l = scope.locals .size () - 1 - i;
4687- scope.locals [l] = self ()->popResumeEntry (" function" );
4711+ scope.locals [l] = self ()->popResumeEntry (" function-local " );
46884712#ifndef NDEBUG
46894713 // Must have restored valid data. The type must match the local's
46904714 // type, except for the case of a non-nullable local that has not yet
@@ -4718,8 +4742,15 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
47184742 if (flow.suspendTag ) {
47194743 // Save the local state.
47204744 for (auto & local : scope.locals ) {
4721- self ()->pushResumeEntry (local, " function" );
4745+ self ()->pushResumeEntry (local, " function-local " );
47224746 }
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" );
47234754 }
47244755
47254756 if (flow.breakTo != RETURN_CALL_FLOW) {
0 commit comments