summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2021-06-09 22:54:56 -0400
committerGitHub <noreply@github.com>2021-06-10 02:54:56 +0000
commit83ae39af1f8ffe67856b16f7ee13de066169b48f (patch)
tree91ed056401b27f90516c00395ea3c8858b516a3f /src/wasm/wasm-binary.cpp
parentd8877922143219eada93568074f2a262de62d04f (diff)
downloadbinaryen-83ae39af1f8ffe67856b16f7ee13de066169b48f.tar.gz
binaryen-83ae39af1f8ffe67856b16f7ee13de066169b48f.tar.bz2
binaryen-83ae39af1f8ffe67856b16f7ee13de066169b48f.zip
Store signatures as HeapTypes when parsing binaries (#3929)
When parsing func.ref instructions, we need to get the HeapType corresponding to the referenced function's signature. Since constructing HeapTypes from Signatures can be expensive under equirecursive typing, keep track of the original function signature HeapTypes directly during parsing rather than storing them as Signatures.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp53
1 files changed, 32 insertions, 21 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 35bc468b1..84834352b 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1987,6 +1987,7 @@ void WasmBinaryBuilder::readImports() {
case ExternalKind::Function: {
Name name(std::string("fimport$") + std::to_string(functionCounter++));
auto index = getU32LEB();
+ functionTypes.push_back(getTypeByIndex(index));
auto curr =
builder.makeFunction(name, getSignatureByTypeIndex(index), {});
curr->module = module;
@@ -2084,28 +2085,37 @@ void WasmBinaryBuilder::readFunctionSignatures() {
for (size_t i = 0; i < num; i++) {
BYN_TRACE("read one\n");
auto index = getU32LEB();
- functionSignatures.push_back(getSignatureByTypeIndex(index));
+ functionTypes.push_back(getTypeByIndex(index));
+ // Check that the type is a signature.
+ getSignatureByTypeIndex(index);
}
}
-Signature WasmBinaryBuilder::getSignatureByFunctionIndex(Index index) {
- Signature sig;
- if (index < functionImports.size()) {
- return functionImports[index]->sig;
+HeapType WasmBinaryBuilder::getTypeByIndex(Index index) {
+ if (index >= types.size()) {
+ throwError("invalid type index " + std::to_string(index) + " / " +
+ std::to_string(types.size()));
}
- Index adjustedIndex = index - functionImports.size();
- if (adjustedIndex >= functionSignatures.size()) {
+ return types[index];
+}
+
+HeapType WasmBinaryBuilder::getTypeByFunctionIndex(Index index) {
+ if (index >= functionTypes.size()) {
throwError("invalid function index");
}
- return functionSignatures[adjustedIndex];
+ return functionTypes[index];
}
Signature WasmBinaryBuilder::getSignatureByTypeIndex(Index index) {
- if (index >= types.size()) {
- throwError("invalid type index " + std::to_string(index) + " / " +
- std::to_string(types.size()));
+ auto heapType = getTypeByIndex(index);
+ if (!heapType.isSignature()) {
+ throwError("invalid signature type " + heapType.toString());
}
- auto heapType = types[index];
+ return heapType.getSignature();
+}
+
+Signature WasmBinaryBuilder::getSignatureByFunctionIndex(Index index) {
+ auto heapType = getTypeByFunctionIndex(index);
if (!heapType.isSignature()) {
throwError("invalid signature type " + heapType.toString());
}
@@ -2115,7 +2125,7 @@ Signature WasmBinaryBuilder::getSignatureByTypeIndex(Index index) {
void WasmBinaryBuilder::readFunctions() {
BYN_TRACE("== readFunctions\n");
size_t total = getU32LEB();
- if (total != functionSignatures.size()) {
+ if (total != functionTypes.size() - functionImports.size()) {
throwError("invalid function section size, must equal types");
}
for (size_t i = 0; i < total; i++) {
@@ -2129,7 +2139,7 @@ void WasmBinaryBuilder::readFunctions() {
auto* func = new Function;
func->name = Name::fromInt(i);
- func->sig = functionSignatures[i];
+ func->sig = getSignatureByFunctionIndex(functionImports.size() + i);
currFunction = func;
if (DWARF) {
@@ -2860,7 +2870,7 @@ void WasmBinaryBuilder::readElementSegments() {
} else {
for (Index j = 0; j < size; j++) {
Index index = getU32LEB();
- auto sig = getSignatureByFunctionIndex(index);
+ auto sig = getTypeByFunctionIndex(index);
// Use a placeholder name for now
auto* refFunc = Builder(wasm).makeRefFunc(Name::fromInt(index), sig);
functionRefs[index].push_back(refFunc);
@@ -6043,14 +6053,15 @@ void WasmBinaryBuilder::visitRefIs(RefIs* curr, uint8_t code) {
void WasmBinaryBuilder::visitRefFunc(RefFunc* curr) {
BYN_TRACE("zz node: RefFunc\n");
Index index = getU32LEB();
- if (index >= functionImports.size() + functionSignatures.size()) {
- throwError("ref.func: invalid call index");
- }
- functionRefs[index].push_back(curr); // we don't know function names yet
+ // We don't know function names yet, so record this use to be updated later.
+ // Note that we do not need to check that 'index' is in bounds, as that will
+ // be verified in the next line. (Also, note that functionRefs[index] may
+ // write to an odd place in the functionRefs map if index is invalid, but that
+ // is harmless.)
+ functionRefs[index].push_back(curr);
// To support typed function refs, we give the reference not just a general
// funcref, but a specific subtype with the actual signature.
- curr->finalize(
- Type(HeapType(getSignatureByFunctionIndex(index)), NonNullable));
+ curr->finalize(Type(getTypeByFunctionIndex(index), NonNullable));
}
void WasmBinaryBuilder::visitRefEq(RefEq* curr) {