summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm/wasm-binary.cpp20
1 files changed, 14 insertions, 6 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 3bb33529b..466771803 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -472,6 +472,10 @@ void WasmBinaryWriter::writeFunctions() {
std::cerr << "Some VMs may not accept this binary because it has a large "
<< "number of parameters in function " << func->name << ".\n";
}
+ if (func->getNumLocals() > WebLimitations::MaxFunctionLocals) {
+ std::cerr << "Some VMs may not accept this binary because it has a large "
+ << "number of locals in function " << func->name << ".\n";
+ }
});
finishSection(sectionStart);
}
@@ -2722,16 +2726,20 @@ void WasmBinaryReader::readFunctions() {
void WasmBinaryReader::readVars() {
uint32_t totalVars = 0;
size_t numLocalTypes = getU32LEB();
+ // Use a SmallVector as in the common (MVP) case there are only 4 possible
+ // types.
+ SmallVector<std::pair<uint32_t, Type>, 4> decodedVars;
+ decodedVars.reserve(numLocalTypes);
for (size_t t = 0; t < numLocalTypes; t++) {
auto num = getU32LEB();
- // The core spec allows up to 2^32 locals, but to avoid allocation failures,
- // we additionally impose a much smaller limit, matching the JS embedding.
- if (std::ckd_add(&totalVars, totalVars, num) ||
- totalVars > WebLimitations::MaxFunctionLocals) {
- throwError("too many locals");
+ if (std::ckd_add(&totalVars, totalVars, num)) {
+ throwError("unaddressable number of locals");
}
auto type = getConcreteType();
-
+ decodedVars.emplace_back(num, type);
+ }
+ currFunction->vars.reserve(totalVars);
+ for (auto [num, type] : decodedVars) {
while (num > 0) {
currFunction->vars.push_back(type);
num--;