@@ -798,8 +798,14 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
798798 // If |possibleDefiningGlobal| is provided, it is the name of a global that we
799799 // are in the init expression of, and which can be reused as defining global,
800800 // if the other conditions are suitable.
801+ //
802+ // Returns nullptr if we cannot serialize.
801803 Expression* getSerialization (Literal value,
802804 Name possibleDefiningGlobal = Name()) {
805+ if (value.isContinuation ()) {
806+ return nullptr ;
807+ }
808+
803809 Builder builder (*wasm);
804810
805811 // If this is externalized then we want to inspect the inner data, handle
@@ -861,12 +867,19 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
861867 }
862868
863869 for (auto & value : values) {
864- args.push_back (getSerialization (value));
870+ auto * serialized = getSerialization (value);
871+ if (!serialized) {
872+ return nullptr ;
873+ }
874+ args.push_back (serialized);
865875 }
866876
867877 Expression* desc = nullptr ;
868878 if (data->desc .getGCData ()) {
869879 desc = getSerialization (data->desc );
880+ if (!desc) {
881+ return nullptr ;
882+ }
870883 }
871884
872885 Expression* init;
@@ -913,7 +926,11 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
913926 assert (possibleDefiningGlobal.isNull ());
914927 std::vector<Expression*> children;
915928 for (const auto & value : values) {
916- children.push_back (getSerialization (value));
929+ auto * serialized = getSerialization (value);
930+ if (!serialized) {
931+ return nullptr ;
932+ }
933+ children.push_back (serialized);
917934 }
918935 return Builder (*wasm).makeTupleMake (children);
919936 }
@@ -1132,7 +1149,17 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance,
11321149 // state in case we fail to eval the new function.
11331150 localExprs.clear ();
11341151 for (auto & param : params) {
1135- localExprs.push_back (interface.getSerialization (param));
1152+ auto * serialized = interface.getSerialization (param);
1153+ if (!serialized) {
1154+ break ;
1155+ }
1156+ localExprs.push_back (serialized);
1157+ }
1158+ if (localExprs.size () < params.size ()) {
1159+ if (!quiet) {
1160+ std::cout << " ...stopping due to non-serializable param\n " ;
1161+ }
1162+ break ;
11361163 }
11371164 interface.applyToModule ();
11381165 goto start_eval;
@@ -1152,7 +1179,17 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance,
11521179 // serialization sets from scratch each time here, for all locals.
11531180 localExprs.clear ();
11541181 for (Index i = 0 ; i < func->getNumLocals (); i++) {
1155- localExprs.push_back (interface.getSerialization (scope.locals [i]));
1182+ auto * serialized = interface.getSerialization (scope.locals [i]);
1183+ if (!serialized) {
1184+ break ;
1185+ }
1186+ localExprs.push_back (serialized);
1187+ }
1188+ if (localExprs.size () < func->getNumLocals ()) {
1189+ if (!quiet) {
1190+ std::cout << " ...stopping due to non-serializable local\n " ;
1191+ }
1192+ break ;
11561193 }
11571194 interface.applyToModule ();
11581195 successes++;
@@ -1341,12 +1378,20 @@ void evalCtors(Module& wasm,
13411378 ? *exp->getInternalName ()
13421379 : Name ());
13431380 auto copyName = Names::getValidFunctionName (wasm, func->name );
1344- auto * copyFunc = ModuleUtils::copyFunction (func, wasm, copyName);
1381+ auto copyFunc =
1382+ ModuleUtils::copyFunctionWithoutAdd (func, wasm, copyName);
13451383 if (func->getResults () == Type::none) {
13461384 copyFunc->body = Builder (wasm).makeNop ();
13471385 } else {
13481386 copyFunc->body = interface.getSerialization (*outcome);
1387+ if (!copyFunc->body ) {
1388+ if (!quiet) {
1389+ std::cout << " ...stopping due to non-serializable body\n " ;
1390+ }
1391+ return ;
1392+ }
13491393 }
1394+ wasm.addFunction (std::move (copyFunc));
13501395 *wasm.getExport (exp->name )->getInternalName () = copyName;
13511396 }
13521397 }
0 commit comments