@@ -3499,9 +3499,10 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
3499
3499
parent.functionStack .push_back (function->name );
3500
3500
locals.resize (function->getNumLocals ());
3501
3501
3502
- if (parent.resuming ) {
3503
- // Nothing more to do here: we are resuming execution, so there is old
3504
- // locals state that will be restored.
3502
+ if (parent.resuming && parent.currContinuation ->resumeExpr ) {
3503
+ // Nothing more to do here: we are resuming execution to some
3504
+ // suspended expression (resumeExpr), so there is old locals state that
3505
+ // will be restored.
3505
3506
return ;
3506
3507
}
3507
3508
@@ -4709,7 +4710,29 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4709
4710
Name func = funcFlow.getSingleValue ().getFunc ();
4710
4711
return Literal (std::make_shared<ContData>(func, curr->type .getHeapType ()));
4711
4712
}
4712
- Flow visitContBind (ContBind* curr) { return Flow (NONCONSTANT_FLOW); }
4713
+ Flow visitContBind (ContBind* curr) {
4714
+ Literals arguments;
4715
+ Flow flow = self ()->generateArguments (curr->operands , arguments);
4716
+ if (flow.breaking ()) {
4717
+ return flow;
4718
+ }
4719
+ Flow cont = self ()->visit (curr->cont );
4720
+ if (cont.breaking ()) {
4721
+ return cont;
4722
+ }
4723
+
4724
+ // Create a new continuation, copying the old but with the new type +
4725
+ // arguments.
4726
+ auto old = cont.getSingleValue ().getContData ();
4727
+ auto newData = *old;
4728
+ newData.type = curr->type .getHeapType ();
4729
+ newData.resumeArguments = arguments;
4730
+ // We handle only the simple case of applying all parameters, for now. TODO
4731
+ assert (old->resumeArguments .empty ());
4732
+ // The old one is done.
4733
+ old->executed = true ;
4734
+ return Literal (std::make_shared<ContData>(newData));
4735
+ }
4713
4736
Flow visitSuspend (Suspend* curr) {
4714
4737
// Process the arguments, whether or not we are resuming. If we are resuming
4715
4738
// then we don't need these values (we sent them as part of the suspension),
@@ -4771,15 +4794,15 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4771
4794
trap (" continuation already executed" );
4772
4795
}
4773
4796
contData->executed = true ;
4774
- contData->resumeArguments = arguments;
4797
+ if (contData->resumeArguments .empty ()) {
4798
+ // The continuation has no bound arguments. For now, we just handle the
4799
+ // simple case of binding all of them, so that means we can just use all
4800
+ // the immediate ones here. TODO
4801
+ contData->resumeArguments = arguments;
4802
+ }
4775
4803
Name func = contData->func ;
4776
4804
self ()->currContinuation = contData;
4777
- if (contData->resumeExpr ) {
4778
- // There is an expression to resume execution at, so this is not the first
4779
- // time we run this function. Mark us as resuming, until we reach that
4780
- // expression.
4781
- self ()->resuming = true ;
4782
- }
4805
+ self ()->resuming = true ;
4783
4806
#if WASM_INTERPRETER_DEBUG
4784
4807
std::cout << self ()->indent () << " resuming func " << func << ' \n ' ;
4785
4808
#endif
@@ -4897,6 +4920,19 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
4897
4920
hostLimit (" stack limit" );
4898
4921
}
4899
4922
4923
+ if (self ()->resuming ) {
4924
+ // The arguments are in the continuation data.
4925
+ arguments = self ()->currContinuation ->resumeArguments ;
4926
+
4927
+ if (!self ()->currContinuation ->resumeExpr ) {
4928
+ // This is the first time we resume, that is, there is no suspend which
4929
+ // is the resume expression that we need to execute up to. All we need
4930
+ // to do is just start calling this function (with the arguments we've
4931
+ // set), so resuming is done
4932
+ self ()->resuming = false ;
4933
+ }
4934
+ }
4935
+
4900
4936
Flow flow;
4901
4937
std::optional<Type> resultType;
4902
4938
0 commit comments