Skip to content

Commit 63860fb

Browse files
authored
[Stack Switching] wasm-ctor-eval: Do not try to serialize continuations (#7877)
They cannot be serialized. This requires us to be able to "give up" when any serialization fails, adding various code paths for that.
1 parent e4d3666 commit 63860fb

File tree

2 files changed

+388
-5
lines changed

2 files changed

+388
-5
lines changed

src/tools/wasm-ctor-eval.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)