@@ -798,8 +798,14 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
798
798
// If |possibleDefiningGlobal| is provided, it is the name of a global that we
799
799
// are in the init expression of, and which can be reused as defining global,
800
800
// if the other conditions are suitable.
801
+ //
802
+ // Returns nullptr if we cannot serialize.
801
803
Expression* getSerialization (Literal value,
802
804
Name possibleDefiningGlobal = Name()) {
805
+ if (value.isContinuation ()) {
806
+ return nullptr ;
807
+ }
808
+
803
809
Builder builder (*wasm);
804
810
805
811
// If this is externalized then we want to inspect the inner data, handle
@@ -861,12 +867,19 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
861
867
}
862
868
863
869
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);
865
875
}
866
876
867
877
Expression* desc = nullptr ;
868
878
if (data->desc .getGCData ()) {
869
879
desc = getSerialization (data->desc );
880
+ if (!desc) {
881
+ return nullptr ;
882
+ }
870
883
}
871
884
872
885
Expression* init;
@@ -913,7 +926,11 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
913
926
assert (possibleDefiningGlobal.isNull ());
914
927
std::vector<Expression*> children;
915
928
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);
917
934
}
918
935
return Builder (*wasm).makeTupleMake (children);
919
936
}
@@ -1132,7 +1149,17 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance,
1132
1149
// state in case we fail to eval the new function.
1133
1150
localExprs.clear ();
1134
1151
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 ;
1136
1163
}
1137
1164
interface.applyToModule ();
1138
1165
goto start_eval;
@@ -1152,7 +1179,17 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance,
1152
1179
// serialization sets from scratch each time here, for all locals.
1153
1180
localExprs.clear ();
1154
1181
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 ;
1156
1193
}
1157
1194
interface.applyToModule ();
1158
1195
successes++;
@@ -1341,12 +1378,20 @@ void evalCtors(Module& wasm,
1341
1378
? *exp->getInternalName ()
1342
1379
: Name ());
1343
1380
auto copyName = Names::getValidFunctionName (wasm, func->name );
1344
- auto * copyFunc = ModuleUtils::copyFunction (func, wasm, copyName);
1381
+ auto copyFunc =
1382
+ ModuleUtils::copyFunctionWithoutAdd (func, wasm, copyName);
1345
1383
if (func->getResults () == Type::none) {
1346
1384
copyFunc->body = Builder (wasm).makeNop ();
1347
1385
} else {
1348
1386
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
+ }
1349
1393
}
1394
+ wasm.addFunction (std::move (copyFunc));
1350
1395
*wasm.getExport (exp->name )->getInternalName () = copyName;
1351
1396
}
1352
1397
}
0 commit comments