summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-09-19 17:07:51 -0700
committerGitHub <noreply@github.com>2024-09-19 17:07:51 -0700
commit2711d4fe4b4514ea146e8810959a8f170c932591 (patch)
tree76f352d5ba9ea963527214f02c87293b9bb3b171
parentb285448a3f8f06123b5b6048efa4ff3d2a13e0a7 (diff)
downloadbinaryen-2711d4fe4b4514ea146e8810959a8f170c932591.tar.gz
binaryen-2711d4fe4b4514ea146e8810959a8f170c932591.tar.bz2
binaryen-2711d4fe4b4514ea146e8810959a8f170c932591.zip
[NFC] Eagerly create Functions in binary parser (#6957)
In preparation for using IRBuilder in the binary parser, eagerly create Functions when parsing the function section so that they are already created once we parse the code section. IRBuilder will require the functions to exist when parsing calls so it can figure out what type each call should have, even when there is a call to a function whose body has not been parsed yet.
-rw-r--r--src/ir/module-utils.cpp5
-rw-r--r--src/passes/Print.cpp3
-rw-r--r--src/wasm-binary.h5
-rw-r--r--src/wasm/wasm-binary.cpp22
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");
}
}