diff options
-rw-r--r-- | src/ir/module-utils.cpp | 5 | ||||
-rw-r--r-- | src/passes/Print.cpp | 3 | ||||
-rw-r--r-- | src/wasm-binary.h | 5 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 22 |
4 files changed, 23 insertions, 12 deletions
diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 1efbe490a..490955866 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -448,7 +448,10 @@ InsertOrderedMap<HeapType, HeapTypeInfo> collectHeapTypeInfo( for (auto type : func->vars) { info.note(type); } - if (!func->imported()) { + // Don't just use `func->imported()` here because we also might be + // printing an error message on a partially parsed module whose declared + // function bodies have not all been parsed yet. + if (func->body) { CodeScanner(wasm, info, inclusion).walk(func->body); } }); diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 46d519e9e..d49bc2974 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2980,6 +2980,9 @@ void PrintSExpression::visitDefinedGlobal(Global* curr) { void PrintSExpression::visitFunction(Function* curr) { if (curr->imported()) { visitImportedFunction(curr); + } else if (curr->body == nullptr) { + // We are in the middle of parsing the module and have not parsed this + // function's code yet. Skip it. } else { visitDefinedFunction(curr); } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index fe740d56a..5021b6a29 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1532,6 +1532,11 @@ public: // reconstructing the HeapTypes from the Signatures is expensive. std::vector<HeapType> functionTypes; + // Used to make sure the number of imported functions, signatures, and + // declared functions all match up. + Index numFuncImports = 0; + Index numFuncBodies = 0; + void readFunctionSignatures(); HeapType getTypeByIndex(Index index); HeapType getTypeByFunctionIndex(Index index); diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index d8a310103..d999141fd 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2578,6 +2578,7 @@ void WasmBinaryReader::readImports() { } } } + numFuncImports = wasm.functions.size(); } Name WasmBinaryReader::getNextLabel() { @@ -2595,9 +2596,12 @@ void WasmBinaryReader::readFunctionSignatures() { size_t num = getU32LEB(); for (size_t i = 0; i < num; i++) { auto index = getU32LEB(); - functionTypes.push_back(getTypeByIndex(index)); + HeapType type = getTypeByIndex(index); + functionTypes.push_back(type); // Check that the type is a signature. getSignatureByTypeIndex(index); + wasm.addFunction( + Builder(wasm).makeFunction(makeName("", i), type, {}, nullptr)); } } @@ -2633,12 +2637,11 @@ Signature WasmBinaryReader::getSignatureByFunctionIndex(Index index) { } void WasmBinaryReader::readFunctions() { - auto numImports = wasm.functions.size(); - size_t total = getU32LEB(); - if (total != functionTypes.size() - numImports) { + numFuncBodies = getU32LEB(); + if (numFuncBodies + numFuncImports != wasm.functions.size()) { throwError("invalid function section size, must equal types"); } - for (size_t i = 0; i < total; i++) { + for (size_t i = 0; i < numFuncBodies; i++) { auto sizePos = pos; size_t size = getU32LEB(); if (size == 0) { @@ -2646,9 +2649,7 @@ void WasmBinaryReader::readFunctions() { } endOfFunction = pos + size; - auto func = std::make_unique<Function>(); - func->name = makeName("", i); - func->type = getTypeByFunctionIndex(numImports + i); + auto& func = wasm.functions[numFuncImports + i]; currFunction = func.get(); if (DWARF) { @@ -2715,7 +2716,6 @@ void WasmBinaryReader::readFunctions() { std::swap(func->epilogLocation, debugLocation); currFunction = nullptr; debugLocation.clear(); - wasm.addFunction(std::move(func)); } } @@ -3192,8 +3192,8 @@ void WasmBinaryReader::validateBinary() { throwError("Number of segments does not agree with DataCount section"); } - if (functionTypes.size() != wasm.functions.size()) { - throwError("function section without code section"); + if (functionTypes.size() != numFuncImports + numFuncBodies) { + throwError("function and code sections have inconsistent lengths"); } } |