Merge branch 'main' into binary-parser-refactor-name-fixup
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 5021b6a..c394c40 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1547,36 +1547,24 @@
Name getNextLabel();
- // We read functions and globals before we know their names, so we need to
- // backpatch the names later
+ // We read functions, globals, etc. before we know their final names, so we
+ // need to backpatch the names later. Map the original names to their indices
+ // so we can find the final names based on index.
+ std::unordered_map<Name, Index> functionIndices;
+ std::unordered_map<Name, Index> tableIndices;
+ std::unordered_map<Name, Index> memoryIndices;
+ std::unordered_map<Name, Index> globalIndices;
+ std::unordered_map<Name, Index> tagIndices;
+ std::unordered_map<Name, Index> dataIndices;
+ std::unordered_map<Name, Index> elemIndices;
- // at index i we have all refs to the function i
- std::map<Index, std::vector<Name*>> functionRefs;
Function* currFunction = nullptr;
// before we see a function (like global init expressions), there is no end of
// function to check
Index endOfFunction = -1;
- // at index i we have all references to the table i
- std::map<Index, std::vector<Name*>> tableRefs;
-
std::map<Index, Name> elemTables;
- // at index i we have all references to the memory i
- std::map<Index, std::vector<wasm::Name*>> memoryRefs;
-
- // at index i we have all refs to the global i
- std::map<Index, std::vector<Name*>> globalRefs;
-
- // at index i we have all refs to the tag i
- std::map<Index, std::vector<Name*>> tagRefs;
-
- // at index i we have all refs to the data segment i
- std::map<Index, std::vector<Name*>> dataRefs;
-
- // at index i we have all refs to the element segment i
- std::map<Index, std::vector<Name*>> elemRefs;
-
// Throws a parsing error if we are not in a function context
void requireFunctionContext(const char* error);
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index cb9ea37..a513955 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -23,6 +23,7 @@
#include "ir/names.h"
#include "ir/table-utils.h"
#include "ir/type-updating.h"
+#include "pass.h"
#include "support/bits.h"
#include "support/debug.h"
#include "support/stdckdint.h"
@@ -2222,6 +2223,7 @@
memory->shared,
memory->indexType,
Memory::kUnlimitedSize);
+ memoryIndices[memory->name] = wasm.memories.size();
wasm.addMemory(std::move(memory));
}
}
@@ -2487,11 +2489,6 @@
void WasmBinaryReader::readImports() {
size_t num = getU32LEB();
Builder builder(wasm);
- size_t tableCounter = 0;
- size_t memoryCounter = 0;
- size_t functionCounter = 0;
- size_t globalCounter = 0;
- size_t tagCounter = 0;
for (size_t i = 0; i < num; i++) {
auto module = getInlineString();
auto base = getInlineString();
@@ -2501,7 +2498,7 @@
// could occur later due to the names section.
switch (kind) {
case ExternalKind::Function: {
- Name name = makeName("fimport$", functionCounter++);
+ Name name = makeName("fimport$", wasm.functions.size());
auto index = getU32LEB();
functionTypes.push_back(getTypeByIndex(index));
auto type = getTypeByIndex(index);
@@ -2513,11 +2510,13 @@
auto curr = builder.makeFunction(name, type, {});
curr->module = module;
curr->base = base;
+ functionIndices[name] = wasm.functions.size();
wasm.addFunction(std::move(curr));
break;
}
case ExternalKind::Table: {
- auto table = builder.makeTable(makeName("timport$", tableCounter++));
+ Name name = makeName("timport$", wasm.tables.size());
+ auto table = builder.makeTable(name);
table->module = module;
table->base = base;
table->type = getType();
@@ -2531,12 +2530,13 @@
if (is_shared) {
throwError("Tables may not be shared");
}
-
+ tableIndices[name] = wasm.tables.size();
wasm.addTable(std::move(table));
break;
}
case ExternalKind::Memory: {
- auto memory = builder.makeMemory(makeName("mimport$", memoryCounter++));
+ Name name = makeName("mimport$", wasm.memories.size());
+ auto memory = builder.makeMemory(name);
memory->module = module;
memory->base = base;
getResizableLimits(memory->initial,
@@ -2544,32 +2544,36 @@
memory->shared,
memory->indexType,
Memory::kUnlimitedSize);
+ memoryIndices[name] = wasm.memories.size();
wasm.addMemory(std::move(memory));
break;
}
case ExternalKind::Global: {
+ Name name = makeName("gimport$", wasm.globals.size());
auto type = getConcreteType();
auto mutable_ = getU32LEB();
if (mutable_ & ~1) {
throwError("Global mutability must be 0 or 1");
}
auto curr =
- builder.makeGlobal(makeName("gimport$", globalCounter++),
+ builder.makeGlobal(name,
type,
nullptr,
mutable_ ? Builder::Mutable : Builder::Immutable);
curr->module = module;
curr->base = base;
+ globalIndices[name] = wasm.globals.size();
wasm.addGlobal(std::move(curr));
break;
}
case ExternalKind::Tag: {
- Name name = makeName("eimport$", tagCounter++);
+ Name name = makeName("eimport$", wasm.tags.size());
getInt8(); // Reserved 'attribute' field
auto index = getU32LEB();
auto curr = builder.makeTag(name, getSignatureByTypeIndex(index));
curr->module = module;
curr->base = base;
+ tagIndices[name] = wasm.tags.size();
wasm.addTag(std::move(curr));
break;
}
@@ -2600,8 +2604,9 @@
functionTypes.push_back(type);
// Check that the type is a signature.
getSignatureByTypeIndex(index);
- wasm.addFunction(
- Builder(wasm).makeFunction(makeName("", i), type, {}, nullptr));
+ auto name = makeName("", i);
+ functionIndices[name] = wasm.functions.size();
+ wasm.addFunction(Builder(wasm).makeFunction(name, type, {}, nullptr));
}
}
@@ -3001,11 +3006,13 @@
throwError("Global mutability must be 0 or 1");
}
auto* init = readExpression();
- wasm.addGlobal(
+ auto global =
Builder::makeGlobal(makeName("global$", i),
type,
init,
- mutable_ ? Builder::Mutable : Builder::Immutable));
+ mutable_ ? Builder::Mutable : Builder::Immutable);
+ globalIndices[global->name] = wasm.globals.size();
+ wasm.addGlobal(std::move(global));
}
}
@@ -3198,7 +3205,112 @@
}
void WasmBinaryReader::processNames() {
- // now that we have names, apply things
+ // Now that we have final names for module elements, update the names used in
+ // expressions and anywhere else.
+ struct NameUpdater
+ : WalkerPass<
+ PostWalker<NameUpdater, UnifiedExpressionVisitor<NameUpdater>>> {
+ WasmBinaryReader& parent;
+ NameUpdater(WasmBinaryReader& parent) : parent(parent) {}
+ bool isFunctionParallel() override { return true; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<NameUpdater>(parent);
+ }
+
+ void visitExpression(Expression* curr) {
+ auto& wasm = *getModule();
+
+#define DELEGATE_ID curr->_id
+#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();
+#define DELEGATE_GET_FIELD(id, field) cast->field
+#define DELEGATE_FIELD_TYPE(id, field)
+#define DELEGATE_FIELD_HEAPTYPE(id, field)
+#define DELEGATE_FIELD_CHILD(id, field)
+#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
+#define DELEGATE_FIELD_INT(id, field)
+#define DELEGATE_FIELD_LITERAL(id, field)
+#define DELEGATE_FIELD_NAME(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
+#define DELEGATE_FIELD_ADDRESS(id, field)
+
+#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \
+ switch (kind) { \
+ case ModuleItemKind::Function: \
+ if (auto it = parent.functionIndices.find(cast->field); \
+ it != parent.functionIndices.end()) { \
+ cast->field = wasm.functions[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::Table: \
+ if (auto it = parent.tableIndices.find(cast->field); \
+ it != parent.tableIndices.end()) { \
+ cast->field = wasm.tables[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::Memory: \
+ if (auto it = parent.memoryIndices.find(cast->field); \
+ it != parent.memoryIndices.end()) { \
+ cast->field = wasm.memories[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::Global: \
+ if (auto it = parent.globalIndices.find(cast->field); \
+ it != parent.globalIndices.end()) { \
+ cast->field = wasm.globals[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::Tag: \
+ if (auto it = parent.tagIndices.find(cast->field); \
+ it != parent.tagIndices.end()) { \
+ cast->field = wasm.tags[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::DataSegment: \
+ if (auto it = parent.dataIndices.find(cast->field); \
+ it != parent.dataIndices.end()) { \
+ cast->field = wasm.dataSegments[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::ElementSegment: \
+ if (auto it = parent.elemIndices.find(cast->field); \
+ it != parent.elemIndices.end()) { \
+ cast->field = wasm.elementSegments[it->second]->name; \
+ } \
+ break; \
+ case ModuleItemKind::Invalid: \
+ WASM_UNREACHABLE("unexpected kind"); \
+ }
+#include "wasm-delegations-fields.def"
+ }
+ };
+
+ if (debugInfo) {
+ // Perform the replacement. Mark the runner nested to avoid unnecessary
+ // validation.
+ PassRunner runner(&wasm);
+ runner.setIsNested(true);
+ runner.add(std::make_unique<NameUpdater>(*this));
+ runner.run();
+ NameUpdater(*this).runOnModuleCode(&runner, &wasm);
+
+ for (auto& seg : wasm.elementSegments) {
+ if (seg->table) {
+ if (auto it = tableIndices.find(seg->table); it != tableIndices.end()) {
+ seg->table = wasm.tables[it->second]->name;
+ }
+ }
+ }
+
+ for (auto& seg : wasm.dataSegments) {
+ if (seg->memory) {
+ if (auto it = memoryIndices.find(seg->memory);
+ it != memoryIndices.end()) {
+ seg->memory = wasm.memories[it->second]->name;
+ }
+ }
+ }
+ }
if (startIndex != static_cast<Index>(-1)) {
wasm.start = getFunctionName(startIndex);
@@ -3229,44 +3341,7 @@
wasm.addExport(std::move(curr));
}
- for (auto& [index, refs] : functionRefs) {
- for (auto* ref : refs) {
- *ref = getFunctionName(index);
- }
- }
- for (auto& [index, refs] : tableRefs) {
- for (auto* ref : refs) {
- *ref = getTableName(index);
- }
- }
- for (auto& [index, refs] : memoryRefs) {
- for (auto ref : refs) {
- *ref = getMemoryName(index);
- }
- }
- for (auto& [index, refs] : globalRefs) {
- for (auto* ref : refs) {
- *ref = getGlobalName(index);
- }
- }
- for (auto& [index, refs] : tagRefs) {
- for (auto* ref : refs) {
- *ref = getTagName(index);
- }
- }
- for (auto& [index, refs] : dataRefs) {
- for (auto* ref : refs) {
- *ref = getDataName(index);
- }
- }
- for (auto& [index, refs] : elemRefs) {
- for (auto* ref : refs) {
- *ref = getElemName(index);
- }
- }
-
// Everything now has its proper name.
-
wasm.updateMaps();
}
@@ -3278,6 +3353,7 @@
for (size_t i = 0; i < dataCount; ++i) {
auto curr = Builder::makeDataSegment();
curr->setName(Name::fromInt(i), false);
+ dataIndices[curr->name] = wasm.dataSegments.size();
wasm.addDataSegment(std::move(curr));
}
}
@@ -3293,6 +3369,7 @@
for (size_t i = 0; i < num; ++i) {
auto curr = Builder::makeDataSegment();
curr->setName(Name::fromInt(i), false);
+ dataIndices[curr->name] = wasm.dataSegments.size();
wasm.addDataSegment(std::move(curr));
}
}
@@ -3313,7 +3390,7 @@
if (flags & BinaryConsts::HasIndex) {
memIdx = getU32LEB();
}
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->offset = readExpression();
}
auto size = getU32LEB();
@@ -3340,6 +3417,7 @@
if (is_shared) {
throwError("Tables may not be shared");
}
+ tableIndices[table->name] = wasm.tables.size();
wasm.addTable(std::move(table));
}
}
@@ -3410,13 +3488,12 @@
for (Index j = 0; j < size; j++) {
Index index = getU32LEB();
auto sig = getTypeByFunctionIndex(index);
- // Use a placeholder name for now
- auto* refFunc = Builder(wasm).makeRefFunc(Name::fromInt(index), sig);
- functionRefs[index].push_back(&refFunc->func);
+ auto* refFunc = Builder(wasm).makeRefFunc(getFunctionName(index), sig);
segmentData.push_back(refFunc);
}
}
+ elemIndices[segment->name] = wasm.elementSegments.size();
wasm.addElementSegment(std::move(segment));
}
}
@@ -3426,8 +3503,10 @@
for (size_t i = 0; i < numTags; i++) {
getInt8(); // Reserved 'attribute' field
auto typeIndex = getU32LEB();
- wasm.addTag(Builder::makeTag(makeName("tag$", i),
- getSignatureByTypeIndex(typeIndex)));
+ auto tag =
+ Builder::makeTag(makeName("tag$", i), getSignatureByTypeIndex(typeIndex));
+ tagIndices[tag->name] = wasm.tags.size();
+ wasm.addTag(std::move(tag));
}
}
@@ -4554,21 +4633,20 @@
void WasmBinaryReader::visitCall(Call* curr) {
auto index = getU32LEB();
auto sig = getSignatureByFunctionIndex(index);
+ curr->target = getFunctionName(index);
auto num = sig.params.size();
curr->operands.resize(num);
for (size_t i = 0; i < num; i++) {
curr->operands[num - i - 1] = popNonVoidExpression();
}
curr->type = sig.results;
- // We don't know function names yet.
- functionRefs[index].push_back(&curr->target);
curr->finalize();
}
void WasmBinaryReader::visitCallIndirect(CallIndirect* curr) {
auto index = getU32LEB();
curr->heapType = getTypeByIndex(index);
- Index tableIdx = getU32LEB();
+ curr->table = getTableName(getU32LEB());
// TODO: Handle error cases where `heapType` is not a signature?
auto num = curr->heapType.getSignature().params.size();
curr->operands.resize(num);
@@ -4576,8 +4654,6 @@
for (size_t i = 0; i < num; i++) {
curr->operands[num - i - 1] = popNonVoidExpression();
}
- // Defer setting the table name for later, when we know it.
- tableRefs[tableIdx].push_back(&curr->table);
curr->finalize();
}
@@ -4614,7 +4690,6 @@
auto* global = wasm.globals[index].get();
curr->name = global->name;
curr->type = global->type;
- globalRefs[index].push_back(&curr->name); // we don't know the final name yet
}
void WasmBinaryReader::visitGlobalSet(GlobalSet* curr) {
@@ -4624,7 +4699,6 @@
}
curr->name = wasm.globals[index]->name;
curr->value = popNonVoidExpression();
- globalRefs[index].push_back(&curr->name); // we don't know the final name yet
curr->finalize();
}
@@ -4799,7 +4873,7 @@
curr->isAtomic = prefix == BinaryConsts::AtomicPrefix;
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->ptr = popNonVoidExpression();
curr->finalize();
out = curr;
@@ -4917,7 +4991,7 @@
curr->isAtomic = prefix == BinaryConsts::AtomicPrefix;
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
curr->finalize();
@@ -4977,7 +5051,7 @@
Address readAlign;
Index memIdx = readMemoryAccess(readAlign, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
if (readAlign != curr->bytes) {
throwError("Align of AtomicRMW must match size");
}
@@ -5028,7 +5102,7 @@
Address readAlign;
Index memIdx = readMemoryAccess(readAlign, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
if (readAlign != curr->bytes) {
throwError("Align of AtomicCpxchg must match size");
}
@@ -5063,7 +5137,7 @@
curr->ptr = popNonVoidExpression();
Address readAlign;
Index memIdx = readMemoryAccess(readAlign, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
if (readAlign != curr->expectedType.getByteSize()) {
throwError("Align of AtomicWait must match size");
}
@@ -5083,7 +5157,7 @@
curr->ptr = popNonVoidExpression();
Address readAlign;
Index memIdx = readMemoryAccess(readAlign, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
if (readAlign != curr->type.getByteSize()) {
throwError("Align of AtomicNotify must match size");
}
@@ -5409,10 +5483,8 @@
curr->size = popNonVoidExpression();
curr->offset = popNonVoidExpression();
curr->dest = popNonVoidExpression();
- Index segIdx = getU32LEB();
- dataRefs[segIdx].push_back(&curr->segment);
- Index memIdx = getU32LEB();
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->segment = getDataName(getU32LEB());
+ curr->memory = getMemoryName(getU32LEB());
curr->finalize();
out = curr;
return true;
@@ -5423,8 +5495,7 @@
return false;
}
auto* curr = allocator.alloc<DataDrop>();
- Index segIdx = getU32LEB();
- dataRefs[segIdx].push_back(&curr->segment);
+ curr->segment = getDataName(getU32LEB());
curr->finalize();
out = curr;
return true;
@@ -5438,11 +5509,9 @@
curr->size = popNonVoidExpression();
curr->source = popNonVoidExpression();
curr->dest = popNonVoidExpression();
- Index destIdx = getU32LEB();
- Index sourceIdx = getU32LEB();
+ curr->destMemory = getMemoryName(getU32LEB());
+ curr->sourceMemory = getMemoryName(getU32LEB());
curr->finalize();
- memoryRefs[destIdx].push_back(&curr->destMemory);
- memoryRefs[sourceIdx].push_back(&curr->sourceMemory);
out = curr;
return true;
}
@@ -5455,9 +5524,8 @@
curr->size = popNonVoidExpression();
curr->value = popNonVoidExpression();
curr->dest = popNonVoidExpression();
- Index memIdx = getU32LEB();
+ curr->memory = getMemoryName(getU32LEB());
curr->finalize();
- memoryRefs[memIdx].push_back(&curr->memory);
out = curr;
return true;
}
@@ -5466,17 +5534,13 @@
if (code != BinaryConsts::TableSize) {
return false;
}
- Index tableIdx = getU32LEB();
- if (tableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
auto* curr = allocator.alloc<TableSize>();
+ Index tableIdx = getU32LEB();
+ curr->table = getTableName(tableIdx);
if (getTable(tableIdx)->is64()) {
curr->type = Type::i64;
}
curr->finalize();
- // Defer setting the table name for later, when we know it.
- tableRefs[tableIdx].push_back(&curr->table);
out = curr;
return true;
}
@@ -5485,19 +5549,15 @@
if (code != BinaryConsts::TableGrow) {
return false;
}
- Index tableIdx = getU32LEB();
- if (tableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
auto* curr = allocator.alloc<TableGrow>();
+ Index tableIdx = getU32LEB();
+ curr->table = getTableName(tableIdx);
curr->delta = popNonVoidExpression();
curr->value = popNonVoidExpression();
if (getTable(tableIdx)->is64()) {
curr->type = Type::i64;
}
curr->finalize();
- // Defer setting the table name for later, when we know it.
- tableRefs[tableIdx].push_back(&curr->table);
out = curr;
return true;
}
@@ -5506,16 +5566,11 @@
if (code != BinaryConsts::TableFill) {
return false;
}
- Index tableIdx = getU32LEB();
- if (tableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
+ auto table = getTableName(getU32LEB());
auto* size = popNonVoidExpression();
auto* value = popNonVoidExpression();
auto* dest = popNonVoidExpression();
- auto* ret = Builder(wasm).makeTableFill(Name(), dest, value, size);
- tableRefs[tableIdx].push_back(&ret->table);
- out = ret;
+ out = Builder(wasm).makeTableFill(table, dest, value, size);
return true;
}
@@ -5523,21 +5578,12 @@
if (code != BinaryConsts::TableCopy) {
return false;
}
- Index destTableIdx = getU32LEB();
- if (destTableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
- Index sourceTableIdx = getU32LEB();
- if (sourceTableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
+ auto destTable = getTableName(getU32LEB());
+ auto srcTable = getTableName(getU32LEB());
auto* size = popNonVoidExpression();
auto* source = popNonVoidExpression();
auto* dest = popNonVoidExpression();
- auto* ret = Builder(wasm).makeTableCopy(dest, source, size, Name(), Name());
- tableRefs[destTableIdx].push_back(&ret->destTable);
- tableRefs[sourceTableIdx].push_back(&ret->sourceTable);
- out = ret;
+ out = Builder(wasm).makeTableCopy(dest, source, size, destTable, srcTable);
return true;
}
@@ -5549,10 +5595,8 @@
curr->size = popNonVoidExpression();
curr->offset = popNonVoidExpression();
curr->dest = popNonVoidExpression();
- Index segIdx = getU32LEB();
- elemRefs[segIdx].push_back(&curr->segment);
- Index memIdx = getU32LEB();
- tableRefs[memIdx].push_back(&curr->table);
+ curr->segment = getElemName(getU32LEB());
+ curr->table = getTableName(getU32LEB());
curr->finalize();
out = curr;
return true;
@@ -6550,7 +6594,7 @@
curr->bytes = 16;
curr->valueType = Type::v128;
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->isAtomic = false;
curr->value = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
@@ -6808,7 +6852,7 @@
curr->type = Type::v128;
curr->bytes = 16;
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->isAtomic = false;
curr->ptr = popNonVoidExpression();
curr->finalize();
@@ -6869,7 +6913,7 @@
return false;
}
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->ptr = popNonVoidExpression();
curr->finalize();
out = curr;
@@ -6919,7 +6963,7 @@
auto* curr = allocator.alloc<SIMDLoadStoreLane>();
curr->op = op;
Index memIdx = readMemoryAccess(curr->align, curr->offset);
- memoryRefs[memIdx].push_back(&curr->memory);
+ curr->memory = getMemoryName(memIdx);
curr->index = getLaneIndex(lanes);
curr->vec = popNonVoidExpression();
curr->ptr = popNonVoidExpression();
@@ -6962,20 +7006,21 @@
void WasmBinaryReader::visitMemorySize(MemorySize* curr) {
Index index = getU32LEB();
+ curr->memory = getMemoryName(index);
if (getMemory(index)->is64()) {
curr->type = Type::i64;
}
curr->finalize();
- memoryRefs[index].push_back(&curr->memory);
}
void WasmBinaryReader::visitMemoryGrow(MemoryGrow* curr) {
- curr->delta = popNonVoidExpression();
Index index = getU32LEB();
+ curr->memory = getMemoryName(index);
if (getMemory(index)->is64()) {
curr->type = Type::i64;
}
- memoryRefs[index].push_back(&curr->memory);
+ curr->delta = popNonVoidExpression();
+ curr->finalize();
}
void WasmBinaryReader::visitNop(Nop* curr) {}
@@ -6998,14 +7043,9 @@
void WasmBinaryReader::visitRefFunc(RefFunc* curr) {
Index index = getU32LEB();
- // 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->func);
// To support typed function refs, we give the reference not just a general
// funcref, but a specific subtype with the actual signature.
+ curr->func = getFunctionName(index);
curr->finalize(Type(getTypeByFunctionIndex(index), NonNullable));
}
@@ -7017,26 +7057,18 @@
void WasmBinaryReader::visitTableGet(TableGet* curr) {
Index tableIdx = getU32LEB();
- if (tableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
+ curr->table = getTableName(tableIdx);
curr->index = popNonVoidExpression();
curr->type = wasm.tables[tableIdx]->type;
curr->finalize();
- // Defer setting the table name for later, when we know it.
- tableRefs[tableIdx].push_back(&curr->table);
}
void WasmBinaryReader::visitTableSet(TableSet* curr) {
Index tableIdx = getU32LEB();
- if (tableIdx >= wasm.tables.size()) {
- throwError("bad table index");
- }
+ curr->table = getTableName(tableIdx);
curr->value = popNonVoidExpression();
curr->index = popNonVoidExpression();
curr->finalize();
- // Defer setting the table name for later, when we know it.
- tableRefs[tableIdx].push_back(&curr->table);
}
void WasmBinaryReader::visitTryOrTryInBlock(Expression*& out) {
@@ -7073,11 +7105,6 @@
}
};
- // We cannot immediately update tagRefs in the loop below, as catchTags is
- // being grown, an so references would get invalidated. Store the indexes
- // here, then do that later.
- std::vector<Index> tagIndexes;
-
while (lastSeparator == BinaryConsts::Catch_Legacy ||
lastSeparator == BinaryConsts::CatchAll_Legacy) {
if (lastSeparator == BinaryConsts::Catch_Legacy) {
@@ -7085,7 +7112,6 @@
if (index >= wasm.tags.size()) {
throwError("bad tag index");
}
- tagIndexes.push_back(index);
auto* tag = wasm.tags[index].get();
curr->catchTags.push_back(tag->name);
readCatchBody(tag->sig.params);
@@ -7098,11 +7124,6 @@
}
breakStack.pop_back();
- for (Index i = 0; i < tagIndexes.size(); i++) {
- // We don't know the final name yet.
- tagRefs[tagIndexes[i]].push_back(&curr->catchTags[i]);
- }
-
if (lastSeparator == BinaryConsts::Delegate) {
curr->delegateTarget = getExceptionTargetName(getU32LEB());
}
@@ -7197,10 +7218,6 @@
// within each try-body, and let branches target those inner blocks instead.
curr->type = getType();
auto numCatches = getU32LEB();
- // We cannot immediately update tagRefs in the loop below, as catchTags is
- // being grown, an so references would get invalidated. Store the indexes
- // here, then do that later.
- std::vector<Index> tagIndexes;
for (size_t i = 0; i < numCatches; i++) {
uint8_t code = getInt8();
@@ -7209,11 +7226,9 @@
if (index >= wasm.tags.size()) {
throwError("bad tag index");
}
- tagIndexes.push_back(index);
auto* tag = wasm.tags[index].get();
curr->catchTags.push_back(tag->name);
} else {
- tagIndexes.push_back(-1); // unused
curr->catchTags.push_back(Name());
}
curr->catchDests.push_back(getBreakTarget(getU32LEB()).name);
@@ -7221,13 +7236,6 @@
code == BinaryConsts::CatchAllRef);
}
- for (Index i = 0; i < tagIndexes.size(); i++) {
- if (curr->catchTags[i]) {
- // We don't know the final name yet.
- tagRefs[tagIndexes[i]].push_back(&curr->catchTags[i]);
- }
- }
-
// catch_*** clauses should refer to block labels without entering the try
// scope. So we do this after reading catch clauses.
startControlFlow(curr);
@@ -7242,7 +7250,6 @@
}
auto* tag = wasm.tags[index].get();
curr->tag = tag->name;
- tagRefs[index].push_back(&curr->tag); // we don't know the final name yet
size_t num = tag->sig.params.size();
curr->operands.resize(num);
for (size_t i = 0; i < num; i++) {
@@ -7490,18 +7497,13 @@
throwError("Expected array heaptype");
}
auto segIdx = getU32LEB();
+ auto segment = isData ? getDataName(segIdx) : getElemName(segIdx);
auto* size = popNonVoidExpression();
auto* offset = popNonVoidExpression();
if (isData) {
- auto* curr =
- Builder(wasm).makeArrayNewData(heapType, Name(), offset, size);
- dataRefs[segIdx].push_back(&curr->segment);
- out = curr;
+ out = Builder(wasm).makeArrayNewData(heapType, segment, offset, size);
} else {
- auto* curr =
- Builder(wasm).makeArrayNewElem(heapType, Name(), offset, size);
- elemRefs[segIdx].push_back(&curr->segment);
- out = curr;
+ out = Builder(wasm).makeArrayNewElem(heapType, segment, offset, size);
}
return true;
}
@@ -7632,21 +7634,16 @@
throwError("Expected array heaptype");
}
Index segIdx = getU32LEB();
+ auto segment = isData ? getDataName(segIdx) : getElemName(segIdx);
auto* size = popNonVoidExpression();
auto* offset = popNonVoidExpression();
auto* index = popNonVoidExpression();
auto* ref = popNonVoidExpression();
validateHeapTypeUsingChild(ref, heapType);
if (isData) {
- auto* curr =
- Builder(wasm).makeArrayInitData(Name(), ref, index, offset, size);
- dataRefs[segIdx].push_back(&curr->segment);
- out = curr;
+ out = Builder(wasm).makeArrayInitData(segment, ref, index, offset, size);
} else {
- auto* curr =
- Builder(wasm).makeArrayInitElem(Name(), ref, index, offset, size);
- elemRefs[segIdx].push_back(&curr->segment);
- out = curr;
+ out = Builder(wasm).makeArrayInitElem(segment, ref, index, offset, size);
}
return true;
}
@@ -7855,25 +7852,12 @@
}
auto numHandlers = getU32LEB();
-
- // We *must* bring the handlerTags vector to an appropriate size to ensure
- // that we do not invalidate the pointers we add to tagRefs. They need to stay
- // valid until processNames ran.
curr->handlerTags.resize(numHandlers);
curr->handlerBlocks.resize(numHandlers);
for (size_t i = 0; i < numHandlers; i++) {
- auto tagIndex = getU32LEB();
- auto tag = getTagName(tagIndex);
-
- auto handlerIndex = getU32LEB();
- auto handler = getBreakTarget(handlerIndex).name;
-
- curr->handlerTags[i] = tag;
- curr->handlerBlocks[i] = handler;
-
- // We don't know the final name yet
- tagRefs[tagIndex].push_back(&curr->handlerTags[i]);
+ curr->handlerTags[i] = getTagName(getU32LEB());
+ curr->handlerBlocks[i] = getBreakTarget(getU32LEB()).name;
}
curr->cont = popNonVoidExpression();
@@ -7889,14 +7873,9 @@
}
void WasmBinaryReader::visitSuspend(Suspend* curr) {
-
auto tagIndex = getU32LEB();
- if (tagIndex >= wasm.tags.size()) {
- throwError("bad tag index");
- }
+ curr->tag = getTagName(tagIndex);
auto* tag = wasm.tags[tagIndex].get();
- curr->tag = tag->name;
- tagRefs[tagIndex].push_back(&curr->tag);
auto numArgs = tag->sig.params.size();
curr->operands.resize(numArgs);