diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 651 |
1 files changed, 325 insertions, 326 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7e1daf0b1..57a01bb1c 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1780,10 +1780,16 @@ void WasmBinaryReader::read() { } } + // Skip ahead and read the name section so we know what names to use when we + // construct module elements. + if (debugInfo) { + findAndReadNames(); + } + readHeader(); readSourceMapHeader(); - // read sections until the end + // Read sections until the end while (more()) { uint8_t sectionCode = getInt8(); uint32_t payloadLen = getU32LEB(); @@ -1793,7 +1799,7 @@ void WasmBinaryReader::read() { auto oldPos = pos; - // note the section in the list of seen sections, as almost no sections can + // Note the section in the list of seen sections, as almost no sections can // appear more than once, and verify those that shouldn't do not. if (sectionCode != BinaryConsts::Section::Custom && !seenSections.insert(sectionCode).second) { @@ -1870,8 +1876,26 @@ void WasmBinaryReader::read() { } } + // Set local names for imported and declared functions. + for (auto& [index, locals] : localNames) { + if (index >= wasm.functions.size()) { + std::cerr << "warning: function index out of bounds in name section: " + "locals at index " + << index << '\n'; + continue; + } + for (auto& [local, name] : locals) { + if (local >= wasm.functions[index]->getNumLocals()) { + std::cerr << "warning: local index out of bounds in name section: " + << name << " at index " << local << " in function " << index + << '\n'; + continue; + } + wasm.functions[index]->setLocalName(local, name); + } + } + validateBinary(); - processNames(); } void WasmBinaryReader::readCustomSection(size_t payloadLen) { @@ -1883,11 +1907,8 @@ void WasmBinaryReader::readCustomSection(size_t payloadLen) { } payloadLen -= read; if (sectionName.equals(BinaryConsts::CustomSections::Name)) { - if (debugInfo) { - readNames(payloadLen); - } else { - pos += payloadLen; - } + // We already read the name section before anything else. + pos += payloadLen; } else if (sectionName.equals(BinaryConsts::CustomSections::TargetFeatures)) { readFeatures(payloadLen); } else if (sectionName.equals(BinaryConsts::CustomSections::Dylink)) { @@ -2233,16 +2254,47 @@ void WasmBinaryReader::readHeader() { } } -void WasmBinaryReader::readStart() { startIndex = getU32LEB(); } +void WasmBinaryReader::readStart() { + startIndex = getU32LEB(); + wasm.start = getFunctionName(startIndex); +} static Name makeName(std::string prefix, size_t counter) { return Name(prefix + std::to_string(counter)); } +// Look up a name from the names section or use a validated version of the +// provided name. Return the name and whether it is explicit in the input. +static std::pair<Name, bool> +getOrMakeName(const std::unordered_map<Index, Name>& nameMap, + Index i, + Name name, + std::unordered_set<Name>& usedNames) { + if (auto it = nameMap.find(i); it != nameMap.end()) { + return {it->second, true}; + } else { + auto valid = Names::getValidNameGivenExisting(name, usedNames); + usedNames.insert(valid); + return {valid, false}; + } +} + void WasmBinaryReader::readMemories() { auto num = getU32LEB(); + auto numImports = wasm.memories.size(); + std::unordered_set<Name> usedNames; + for (auto& [index, name] : memoryNames) { + if (index >= num + numImports) { + std::cerr << "warning: memory index out of bounds in name section: " + << name << " at index " << index << '\n'; + } + usedNames.insert(name); + } for (size_t i = 0; i < num; i++) { - auto memory = Builder::makeMemory(makeName("", i)); + auto [name, isExplicit] = + getOrMakeName(memoryNames, numImports + i, makeName("", i), usedNames); + auto memory = Builder::makeMemory(name); + memory->hasExplicitName = isExplicit; getResizableLimits(memory->initial, memory->max, memory->shared, @@ -2423,6 +2475,39 @@ void WasmBinaryReader::readTypes() { for (Index i = 0; i < types.size(); ++i) { wasm.typeIndices.insert({types[i], i}); } + + // Assign names from the names section. + for (auto& [index, name] : typeNames) { + if (index >= types.size()) { + std::cerr << "warning: type index out of bounds in name section: " << name + << " at index " << index << '\n'; + continue; + } + wasm.typeNames[types[index]].name = name; + } + for (auto& [index, fields] : fieldNames) { + if (index >= types.size()) { + std::cerr + << "warning: type index out of bounds in name section: fields at index " + << index << '\n'; + continue; + } + if (!types[index].isStruct()) { + std::cerr << "warning: field names applied to non-struct type at index " + << index << '\n'; + continue; + } + auto& names = wasm.typeNames[types[index]].fieldNames; + for (auto& [field, name] : fields) { + if (field >= types[index].getStruct().fields.size()) { + std::cerr << "warning: field index out of bounds in name section: " + << name << " at index " << field << " in type " << index + << '\n'; + continue; + } + names[field] = name; + } + } } Name WasmBinaryReader::getFunctionName(Index index) { @@ -2513,11 +2598,8 @@ void WasmBinaryReader::getResizableLimits(Address& initial, 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; + std::unordered_set<Name> usedFunctionNames, usedTableNames, usedMemoryNames, + usedGlobalNames, usedTagNames; for (size_t i = 0; i < num; i++) { auto module = getInlineString(); auto base = getInlineString(); @@ -2527,7 +2609,11 @@ void WasmBinaryReader::readImports() { // could occur later due to the names section. switch (kind) { case ExternalKind::Function: { - Name name = makeName("fimport$", functionCounter++); + auto [name, isExplicit] = + getOrMakeName(functionNames, + wasm.functions.size(), + makeName("fimport$", wasm.functions.size()), + usedFunctionNames); auto index = getU32LEB(); functionTypes.push_back(getTypeByIndex(index)); auto type = getTypeByIndex(index); @@ -2537,13 +2623,20 @@ void WasmBinaryReader::readImports() { "'s type must be a signature. Given: " + type.toString()); } auto curr = builder.makeFunction(name, type, {}); + curr->hasExplicitName = isExplicit; curr->module = module; curr->base = base; wasm.addFunction(std::move(curr)); break; } case ExternalKind::Table: { - auto table = builder.makeTable(makeName("timport$", tableCounter++)); + auto [name, isExplicit] = + getOrMakeName(tableNames, + wasm.tables.size(), + makeName("timport$", wasm.tables.size()), + usedTableNames); + auto table = builder.makeTable(name); + table->hasExplicitName = isExplicit; table->module = module; table->base = base; table->type = getType(); @@ -2562,7 +2655,13 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Memory: { - auto memory = builder.makeMemory(makeName("mimport$", memoryCounter++)); + auto [name, isExplicit] = + getOrMakeName(memoryNames, + wasm.memories.size(), + makeName("mimport$", wasm.memories.size()), + usedMemoryNames); + auto memory = builder.makeMemory(name); + memory->hasExplicitName = isExplicit; memory->module = module; memory->base = base; getResizableLimits(memory->initial, @@ -2574,26 +2673,37 @@ void WasmBinaryReader::readImports() { break; } case ExternalKind::Global: { + auto [name, isExplicit] = + getOrMakeName(globalNames, + wasm.globals.size(), + makeName("gimport$", wasm.globals.size()), + usedGlobalNames); 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->hasExplicitName = isExplicit; curr->module = module; curr->base = base; wasm.addGlobal(std::move(curr)); break; } case ExternalKind::Tag: { - Name name = makeName("eimport$", tagCounter++); + auto [name, isExplicit] = + getOrMakeName(tagNames, + wasm.tags.size(), + makeName("eimport$", wasm.tags.size()), + usedTagNames); getInt8(); // Reserved 'attribute' field auto index = getU32LEB(); auto curr = builder.makeTag(name, getSignatureByTypeIndex(index)); + curr->hasExplicitName = isExplicit; curr->module = module; curr->base = base; wasm.addTag(std::move(curr)); @@ -2620,14 +2730,26 @@ void WasmBinaryReader::requireFunctionContext(const char* error) { void WasmBinaryReader::readFunctionSignatures() { size_t num = getU32LEB(); + auto numImports = wasm.functions.size(); + std::unordered_set<Name> usedNames; + for (auto& [index, name] : functionNames) { + if (index >= num + numImports) { + std::cerr << "warning: function index out of bounds in name section: " + << name << " at index " << index << '\n'; + } + usedNames.insert(name); + } for (size_t i = 0; i < num; i++) { + auto [name, isExplicit] = + getOrMakeName(functionNames, numImports + i, makeName("", i), usedNames); auto index = getU32LEB(); 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)); + auto func = Builder(wasm).makeFunction(name, type, {}, nullptr); + func->hasExplicitName = isExplicit; + wasm.addFunction(std::move(func)); } } @@ -2779,9 +2901,28 @@ void WasmBinaryReader::readExports() { throwError("duplicate export name"); } curr->kind = (ExternalKind)getU32LEB(); + auto* ex = wasm.addExport(std::move(curr)); auto index = getU32LEB(); - exportIndices[curr.get()] = index; - exportOrder.push_back(std::move(curr)); + switch (ex->kind) { + case ExternalKind::Function: + ex->value = getFunctionName(index); + continue; + case ExternalKind::Table: + ex->value = getTableName(index); + continue; + case ExternalKind::Memory: + ex->value = getMemoryName(index); + continue; + case ExternalKind::Global: + ex->value = getGlobalName(index); + continue; + case ExternalKind::Tag: + ex->value = getTagName(index); + continue; + case ExternalKind::Invalid: + break; + } + throwError("invalid export kind"); } } @@ -3052,18 +3193,28 @@ void WasmBinaryReader::readStrings() { void WasmBinaryReader::readGlobals() { size_t num = getU32LEB(); + auto numImports = wasm.globals.size(); + std::unordered_set<Name> usedNames; + for (auto& [index, name] : globalNames) { + if (index >= num + numImports) { + std::cerr << "warning: global index out of bounds in name section: " + << name << " at index " << index << '\n'; + } + usedNames.insert(name); + } for (size_t i = 0; i < num; i++) { + auto [name, isExplicit] = getOrMakeName( + globalNames, numImports + i, makeName("global$", i), usedNames); auto type = getConcreteType(); auto mutable_ = getU32LEB(); if (mutable_ & ~1) { throwError("Global mutability must be 0 or 1"); } auto* init = readExpression(); - wasm.addGlobal( - Builder::makeGlobal(makeName("global$", i), - type, - init, - mutable_ ? Builder::Mutable : Builder::Immutable)); + auto global = Builder::makeGlobal( + name, type, init, mutable_ ? Builder::Mutable : Builder::Immutable); + global->hasExplicitName = isExplicit; + wasm.addGlobal(std::move(global)); } } @@ -3255,77 +3406,22 @@ void WasmBinaryReader::validateBinary() { } } -void WasmBinaryReader::processNames() { - // now that we have names, apply things - - if (startIndex != static_cast<Index>(-1)) { - wasm.start = getFunctionName(startIndex); - } - - for (auto& curr : exportOrder) { - auto index = exportIndices[curr.get()]; - switch (curr->kind) { - case ExternalKind::Function: { - curr->value = getFunctionName(index); - break; - } - case ExternalKind::Table: - curr->value = getTableName(index); - break; - case ExternalKind::Memory: - curr->value = getMemoryName(index); - break; - case ExternalKind::Global: - curr->value = getGlobalName(index); - break; - case ExternalKind::Tag: - curr->value = getTagName(index); - break; - default: - throwError("bad export kind"); - } - 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); +void WasmBinaryReader::createDataSegments(Index count) { + std::unordered_set<Name> usedNames; + for (auto& [index, name] : dataNames) { + if (index >= count) { + std::cerr << "warning: data index out of bounds in name section: " << name + << " at index " << index << '\n'; } + usedNames.insert(name); } - for (auto& [index, refs] : elemRefs) { - for (auto* ref : refs) { - *ref = getElemName(index); - } + for (size_t i = 0; i < count; ++i) { + auto [name, isExplicit] = + getOrMakeName(dataNames, i, makeName("", i), usedNames); + auto curr = Builder::makeDataSegment(name); + curr->hasExplicitName = isExplicit; + wasm.addDataSegment(std::move(curr)); } - - // Everything now has its proper name. - - wasm.updateMaps(); } void WasmBinaryReader::readDataSegmentCount() { @@ -3333,11 +3429,7 @@ void WasmBinaryReader::readDataSegmentCount() { dataCount = getU32LEB(); // Eagerly create the data segments so they are available during parsing of // the code section. - for (size_t i = 0; i < dataCount; ++i) { - auto curr = Builder::makeDataSegment(); - curr->setName(Name::fromInt(i), false); - wasm.addDataSegment(std::move(curr)); - } + createDataSegments(dataCount); } void WasmBinaryReader::readDataSegments() { @@ -3348,11 +3440,7 @@ void WasmBinaryReader::readDataSegments() { } } else { // We haven't already created the data segments, so create them now. - for (size_t i = 0; i < num; ++i) { - auto curr = Builder::makeDataSegment(); - curr->setName(Name::fromInt(i), false); - wasm.addDataSegment(std::move(curr)); - } + createDataSegments(num); } assert(wasm.dataSegments.size() == num); for (size_t i = 0; i < num; i++) { @@ -3371,7 +3459,7 @@ void WasmBinaryReader::readDataSegments() { if (flags & BinaryConsts::HasIndex) { memIdx = getU32LEB(); } - memoryRefs[memIdx].push_back(&curr->memory); + curr->memory = getMemoryName(memIdx); curr->offset = readExpression(); } auto size = getU32LEB(); @@ -3381,14 +3469,25 @@ void WasmBinaryReader::readDataSegments() { } void WasmBinaryReader::readTableDeclarations() { - auto numTables = getU32LEB(); - - for (size_t i = 0; i < numTables; i++) { + auto num = getU32LEB(); + auto numImports = wasm.tables.size(); + std::unordered_set<Name> usedNames; + for (auto& [index, name] : tableNames) { + if (index >= num + numImports) { + std::cerr << "warning: table index out of bounds in name section: " + << name << " at index " << index << '\n'; + } + usedNames.insert(name); + } + for (size_t i = 0; i < num; i++) { + auto [name, isExplicit] = + getOrMakeName(tableNames, numImports + i, makeName("", i), usedNames); auto elemType = getType(); if (!elemType.isRef()) { throwError("Table type must be a reference type"); } - auto table = Builder::makeTable(makeName("", i), elemType); + auto table = Builder::makeTable(name, elemType); + table->hasExplicitName = isExplicit; bool is_shared; getResizableLimits(table->initial, table->max, @@ -3403,11 +3502,21 @@ void WasmBinaryReader::readTableDeclarations() { } void WasmBinaryReader::readElementSegments() { - auto numSegments = getU32LEB(); - if (numSegments >= Table::kMaxSize) { + auto num = getU32LEB(); + if (num >= Table::kMaxSize) { throwError("Too many segments"); } - for (size_t i = 0; i < numSegments; i++) { + std::unordered_set<Name> usedNames; + for (auto& [index, name] : elemNames) { + if (index >= num) { + std::cerr << "warning: elem index out of bounds in name section: " << name + << " at index " << index << '\n'; + } + usedNames.insert(name); + } + for (size_t i = 0; i < num; i++) { + auto [name, isExplicit] = + getOrMakeName(elemNames, i, makeName("", i), usedNames); auto flags = getU32LEB(); bool isPassive = (flags & BinaryConsts::IsPassive) != 0; bool hasTableIdx = !isPassive && ((flags & BinaryConsts::HasIndex) != 0); @@ -3431,7 +3540,7 @@ void WasmBinaryReader::readElementSegments() { } auto segment = std::make_unique<ElementSegment>(); - segment->setName(Name::fromInt(i), false); + segment->setName(name, isExplicit); if (!isPassive) { Index tableIdx = 0; @@ -3468,9 +3577,7 @@ void WasmBinaryReader::readElementSegments() { 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); } } @@ -3480,12 +3587,24 @@ void WasmBinaryReader::readElementSegments() { } void WasmBinaryReader::readTags() { - size_t numTags = getU32LEB(); - for (size_t i = 0; i < numTags; i++) { + size_t num = getU32LEB(); + auto numImports = wasm.tags.size(); + std::unordered_set<Name> usedNames; + for (auto& [index, name] : tagNames) { + if (index >= num + numImports) { + std::cerr << "warning: tag index out of bounds in name section: " << name + << " at index " << index << '\n'; + } + usedNames.insert(name); + } + for (size_t i = 0; i < num; i++) { getInt8(); // Reserved 'attribute' field + auto [name, isExplicit] = + getOrMakeName(tagNames, numImports + i, makeName("tag$", i), usedNames); auto typeIndex = getU32LEB(); - wasm.addTag(Builder::makeTag(makeName("tag$", i), - getSignatureByTypeIndex(typeIndex))); + auto tag = Builder::makeTag(name, getSignatureByTypeIndex(typeIndex)); + tag->hasExplicitName = isExplicit; + wasm.addTag(std::move(tag)); } } @@ -3531,19 +3650,6 @@ namespace { // Performs necessary processing of names from the name section before using // them. Specifically it escapes and deduplicates them. -// -// Deduplication is not trivial, since we can't only consider things in the name -// section itself. The issue is that we have already given everything a -// temporary name. Consider if we gave these two temp names: -// -// $foo$0 -// $foo$1 -// -// and imagine that the first appears in the name section, where it is given the -// the name $foo$1, and the second does not appear in the name section. In that -// case, we'd rename the second to the same name as the first. If we left things -// there that would be invalid, so we need to pick another temp name for the -// second item to resolve that. class NameProcessor { public: // Returns a unique, escaped name. Notes that name for the items to follow to @@ -3552,20 +3658,6 @@ public: return deduplicate(WasmBinaryReader::escape(name)); } - // After processing the names section entries, which set explicit names, we - // also handle the remaining items here, which handles the corner case - // described above. - // - // TODO: This handles vectors of Named objects; we should also do this for - // local names and type names etc. - template<typename T> void deduplicateUnexplicitlyNamed(std::vector<T>& vec) { - for (auto& x : vec) { - if (!x->hasExplicitName) { - x->name = deduplicate(x->name); - } - } - } - private: std::unordered_set<Name> usedNames; @@ -3578,8 +3670,33 @@ private: } // anonymous namespace -void WasmBinaryReader::readNames(size_t payloadLen) { - auto sectionPos = pos; +void WasmBinaryReader::findAndReadNames() { + // Find the names section. Skip the magic and version. + assert(pos == 0); + getInt32(); + getInt32(); + Index payloadLen, sectionPos; + bool found = false; + while (more()) { + uint8_t sectionCode = getInt8(); + payloadLen = getU32LEB(); + sectionPos = pos; + if (sectionCode == BinaryConsts::Section::Custom) { + auto sectionName = getInlineString(); + if (sectionName.equals(BinaryConsts::CustomSections::Name)) { + found = true; + break; + } + } + pos = sectionPos + payloadLen; + } + if (!found) { + // No names section to read. + pos = 0; + return; + } + + // Read the names. uint32_t lastType = 0; while (pos < sectionPos + payloadLen) { auto nameType = getU32LEB(); @@ -3600,51 +3717,19 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < wasm.functions.size()) { - wasm.functions[index]->setExplicitName(name); - } else { - std::cerr << "warning: function index out of bounds in name section, " - "function subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + functionNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.functions); } else if (nameType == Subsection::NameLocal) { auto numFuncs = getU32LEB(); for (size_t i = 0; i < numFuncs; i++) { auto funcIndex = getU32LEB(); - Function* func = nullptr; - if (funcIndex < wasm.functions.size()) { - func = wasm.functions[funcIndex].get(); - } else { - std::cerr - << "warning: function index out of bounds in name section, local " - "subsection: " - << std::to_string(funcIndex) << std::endl; - } auto numLocals = getU32LEB(); NameProcessor processor; for (size_t j = 0; j < numLocals; j++) { auto localIndex = getU32LEB(); - auto rawLocalName = getInlineString(); - if (!func) { - continue; // read and discard in case of prior error - } - auto localName = processor.process(rawLocalName); - if (localName.size() == 0) { - std::cerr << "warning: empty local name at index " - << std::to_string(localIndex) << " in function " - << std::string(func->name.str) << std::endl; - } else if (localIndex < func->getNumLocals()) { - func->localNames[localIndex] = localName; - } else { - std::cerr << "warning: local index out of bounds in name " - "section, local subsection: " - << std::string(rawLocalName.str) << " at index " - << std::to_string(localIndex) << " in function " - << std::string(func->name.str) << std::endl; - } + auto rawName = getInlineString(); + auto name = processor.process(rawName); + localNames[funcIndex][localIndex] = name; } } } else if (nameType == Subsection::NameType) { @@ -3654,14 +3739,7 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < types.size()) { - wasm.typeNames[types[index]].name = name; - } else { - std::cerr << "warning: type index out of bounds in name section, " - "type subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + typeNames[index] = name; } } else if (nameType == Subsection::NameTable) { auto num = getU32LEB(); @@ -3670,23 +3748,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - - if (index < wasm.tables.size()) { - auto* table = wasm.tables[index].get(); - for (auto& segment : wasm.elementSegments) { - if (segment->table == table->name) { - segment->table = name; - } - } - table->setExplicitName(name); - } else { - std::cerr << "warning: table index out of bounds in name section, " - "table subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + tableNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.tables); } else if (nameType == Subsection::NameElem) { auto num = getU32LEB(); NameProcessor processor; @@ -3694,17 +3757,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - - if (index < wasm.elementSegments.size()) { - wasm.elementSegments[index]->setExplicitName(name); - } else { - std::cerr << "warning: elem index out of bounds in name section, " - "elem subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + elemNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.elementSegments); } else if (nameType == Subsection::NameMemory) { auto num = getU32LEB(); NameProcessor processor; @@ -3712,16 +3766,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < wasm.memories.size()) { - wasm.memories[index]->setExplicitName(name); - } else { - std::cerr << "warning: memory index out of bounds in name section, " - "memory subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + memoryNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.memories); } else if (nameType == Subsection::NameData) { auto num = getU32LEB(); NameProcessor processor; @@ -3729,16 +3775,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < wasm.dataSegments.size()) { - wasm.dataSegments[index]->setExplicitName(name); - } else { - std::cerr << "warning: data index out of bounds in name section, " - "data subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + dataNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.dataSegments); } else if (nameType == Subsection::NameGlobal) { auto num = getU32LEB(); NameProcessor processor; @@ -3746,16 +3784,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < wasm.globals.size()) { - wasm.globals[index]->setExplicitName(name); - } else { - std::cerr << "warning: global index out of bounds in name section, " - "global subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + globalNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.globals); } else if (nameType == Subsection::NameField) { auto numTypes = getU32LEB(); for (size_t i = 0; i < numTypes; i++) { @@ -3771,9 +3801,7 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto fieldIndex = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (validType) { - wasm.typeNames[types[typeIndex]].fieldNames[fieldIndex] = name; - } + fieldNames[typeIndex][fieldIndex] = name; } } } else if (nameType == Subsection::NameTag) { @@ -3783,16 +3811,8 @@ void WasmBinaryReader::readNames(size_t payloadLen) { auto index = getU32LEB(); auto rawName = getInlineString(); auto name = processor.process(rawName); - if (index < wasm.tags.size()) { - wasm.tags[index]->setExplicitName(name); - } else { - std::cerr << "warning: tag index out of bounds in name section, " - "tag subsection: " - << std::string(rawName.str) << " at index " - << std::to_string(index) << std::endl; - } + tagNames[index] = name; } - processor.deduplicateUnexplicitlyNamed(wasm.tags); } else { std::cerr << "warning: unknown name subsection with id " << std::to_string(nameType) << " at " << pos << std::endl; @@ -3805,6 +3825,9 @@ void WasmBinaryReader::readNames(size_t payloadLen) { if (pos != sectionPos + payloadLen) { throwError("bad names section position change"); } + + // Reset the position; we were just reading ahead. + pos = 0; } void WasmBinaryReader::readFeatures(size_t payloadLen) { @@ -4614,8 +4637,7 @@ void WasmBinaryReader::visitCall(Call* curr) { curr->operands[num - i - 1] = popNonVoidExpression(); } curr->type = sig.results; - // We don't know function names yet. - functionRefs[index].push_back(&curr->target); + curr->target = getFunctionName(index); curr->finalize(); } @@ -4630,8 +4652,7 @@ void WasmBinaryReader::visitCallIndirect(CallIndirect* curr) { 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->table = getTableName(tableIdx); curr->finalize(); } @@ -4668,7 +4689,6 @@ void WasmBinaryReader::visitGlobalGet(GlobalGet* curr) { 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) { @@ -4678,7 +4698,6 @@ void WasmBinaryReader::visitGlobalSet(GlobalSet* curr) { } 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(); } @@ -4853,7 +4872,7 @@ bool WasmBinaryReader::maybeVisitLoad( 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; @@ -4971,7 +4990,7 @@ bool WasmBinaryReader::maybeVisitStore( 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(); @@ -5031,7 +5050,7 @@ bool WasmBinaryReader::maybeVisitAtomicRMW(Expression*& out, uint8_t code) { 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"); } @@ -5082,7 +5101,7 @@ bool WasmBinaryReader::maybeVisitAtomicCmpxchg(Expression*& out, uint8_t code) { 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"); } @@ -5117,7 +5136,7 @@ bool WasmBinaryReader::maybeVisitAtomicWait(Expression*& out, uint8_t code) { 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"); } @@ -5137,7 +5156,7 @@ bool WasmBinaryReader::maybeVisitAtomicNotify(Expression*& out, uint8_t code) { 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"); } @@ -5464,9 +5483,9 @@ bool WasmBinaryReader::maybeVisitMemoryInit(Expression*& out, uint32_t code) { curr->offset = popNonVoidExpression(); curr->dest = popNonVoidExpression(); Index segIdx = getU32LEB(); - dataRefs[segIdx].push_back(&curr->segment); + curr->segment = getDataName(segIdx); Index memIdx = getU32LEB(); - memoryRefs[memIdx].push_back(&curr->memory); + curr->memory = getMemoryName(memIdx); curr->finalize(); out = curr; return true; @@ -5478,7 +5497,7 @@ bool WasmBinaryReader::maybeVisitDataDrop(Expression*& out, uint32_t code) { } auto* curr = allocator.alloc<DataDrop>(); Index segIdx = getU32LEB(); - dataRefs[segIdx].push_back(&curr->segment); + curr->segment = getDataName(segIdx); curr->finalize(); out = curr; return true; @@ -5495,8 +5514,8 @@ bool WasmBinaryReader::maybeVisitMemoryCopy(Expression*& out, uint32_t code) { Index destIdx = getU32LEB(); Index sourceIdx = getU32LEB(); curr->finalize(); - memoryRefs[destIdx].push_back(&curr->destMemory); - memoryRefs[sourceIdx].push_back(&curr->sourceMemory); + curr->destMemory = getMemoryName(destIdx); + curr->sourceMemory = getMemoryName(sourceIdx); out = curr; return true; } @@ -5511,7 +5530,7 @@ bool WasmBinaryReader::maybeVisitMemoryFill(Expression*& out, uint32_t code) { curr->dest = popNonVoidExpression(); Index memIdx = getU32LEB(); curr->finalize(); - memoryRefs[memIdx].push_back(&curr->memory); + curr->memory = getMemoryName(memIdx); out = curr; return true; } @@ -5528,9 +5547,8 @@ bool WasmBinaryReader::maybeVisitTableSize(Expression*& out, uint32_t code) { if (getTable(tableIdx)->is64()) { curr->type = Type::i64; } + curr->table = getTableName(tableIdx); curr->finalize(); - // Defer setting the table name for later, when we know it. - tableRefs[tableIdx].push_back(&curr->table); out = curr; return true; } @@ -5549,9 +5567,8 @@ bool WasmBinaryReader::maybeVisitTableGrow(Expression*& out, uint32_t code) { if (getTable(tableIdx)->is64()) { curr->type = Type::i64; } + curr->table = getTableName(tableIdx); curr->finalize(); - // Defer setting the table name for later, when we know it. - tableRefs[tableIdx].push_back(&curr->table); out = curr; return true; } @@ -5568,7 +5585,7 @@ bool WasmBinaryReader::maybeVisitTableFill(Expression*& out, uint32_t code) { auto* value = popNonVoidExpression(); auto* dest = popNonVoidExpression(); auto* ret = Builder(wasm).makeTableFill(Name(), dest, value, size); - tableRefs[tableIdx].push_back(&ret->table); + ret->table = getTableName(tableIdx); out = ret; return true; } @@ -5589,8 +5606,8 @@ bool WasmBinaryReader::maybeVisitTableCopy(Expression*& out, uint32_t code) { 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); + ret->destTable = getTableName(destTableIdx); + ret->sourceTable = getTableName(sourceTableIdx); out = ret; return true; } @@ -5604,9 +5621,9 @@ bool WasmBinaryReader::maybeVisitTableInit(Expression*& out, uint32_t code) { 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(segIdx); + Index tableIdx = getU32LEB(); + curr->table = getTableName(tableIdx); curr->finalize(); out = curr; return true; @@ -6620,7 +6637,7 @@ bool WasmBinaryReader::maybeVisitSIMDStore(Expression*& out, uint32_t code) { 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(); @@ -6878,7 +6895,7 @@ bool WasmBinaryReader::maybeVisitSIMDLoad(Expression*& out, uint32_t code) { 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(); @@ -6939,7 +6956,7 @@ bool WasmBinaryReader::maybeVisitSIMDLoad(Expression*& out, uint32_t code) { 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; @@ -6989,7 +7006,7 @@ bool WasmBinaryReader::maybeVisitSIMDLoadStoreLane(Expression*& out, 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(); @@ -7035,8 +7052,8 @@ void WasmBinaryReader::visitMemorySize(MemorySize* curr) { if (getMemory(index)->is64()) { curr->type = Type::i64; } + curr->memory = getMemoryName(index); curr->finalize(); - memoryRefs[index].push_back(&curr->memory); } void WasmBinaryReader::visitMemoryGrow(MemoryGrow* curr) { @@ -7045,7 +7062,7 @@ void WasmBinaryReader::visitMemoryGrow(MemoryGrow* curr) { if (getMemory(index)->is64()) { curr->type = Type::i64; } - memoryRefs[index].push_back(&curr->memory); + curr->memory = getMemoryName(index); } void WasmBinaryReader::visitNop(Nop* curr) {} @@ -7068,12 +7085,7 @@ void WasmBinaryReader::visitRefIsNull(RefIsNull* curr) { 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); + curr->func = getFunctionName(index); // 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(getTypeByFunctionIndex(index), NonNullable)); @@ -7092,9 +7104,8 @@ void WasmBinaryReader::visitTableGet(TableGet* curr) { } curr->index = popNonVoidExpression(); curr->type = wasm.tables[tableIdx]->type; + curr->table = getTableName(tableIdx); curr->finalize(); - // Defer setting the table name for later, when we know it. - tableRefs[tableIdx].push_back(&curr->table); } void WasmBinaryReader::visitTableSet(TableSet* curr) { @@ -7104,9 +7115,8 @@ void WasmBinaryReader::visitTableSet(TableSet* curr) { } curr->value = popNonVoidExpression(); curr->index = popNonVoidExpression(); + curr->table = getTableName(tableIdx); curr->finalize(); - // Defer setting the table name for later, when we know it. - tableRefs[tableIdx].push_back(&curr->table); } void WasmBinaryReader::visitTryOrTryInBlock(Expression*& out) { @@ -7169,8 +7179,7 @@ void WasmBinaryReader::visitTryOrTryInBlock(Expression*& out) { 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]); + curr->catchTags[i] = getTagName(tagIndexes[i]); } if (lastSeparator == BinaryConsts::Delegate) { @@ -7293,8 +7302,7 @@ void WasmBinaryReader::visitTryTable(TryTable* curr) { 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]); + curr->catchTags[i] = getTagName(tagIndexes[i]); } } @@ -7312,7 +7320,6 @@ void WasmBinaryReader::visitThrow(Throw* curr) { } 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++) { @@ -7563,14 +7570,12 @@ bool WasmBinaryReader::maybeVisitArrayNewElem(Expression*& out, uint32_t code) { auto* size = popNonVoidExpression(); auto* offset = popNonVoidExpression(); if (isData) { - auto* curr = - Builder(wasm).makeArrayNewData(heapType, Name(), offset, size); - dataRefs[segIdx].push_back(&curr->segment); + auto* curr = Builder(wasm).makeArrayNewData( + heapType, getDataName(segIdx), offset, size); out = curr; } else { - auto* curr = - Builder(wasm).makeArrayNewElem(heapType, Name(), offset, size); - elemRefs[segIdx].push_back(&curr->segment); + auto* curr = Builder(wasm).makeArrayNewElem( + heapType, getElemName(segIdx), offset, size); out = curr; } return true; @@ -7708,14 +7713,12 @@ bool WasmBinaryReader::maybeVisitArrayInit(Expression*& out, uint32_t code) { auto* ref = popNonVoidExpression(); validateHeapTypeUsingChild(ref, heapType); if (isData) { - auto* curr = - Builder(wasm).makeArrayInitData(Name(), ref, index, offset, size); - dataRefs[segIdx].push_back(&curr->segment); + auto* curr = Builder(wasm).makeArrayInitData( + getDataName(segIdx), ref, index, offset, size); out = curr; } else { - auto* curr = - Builder(wasm).makeArrayInitElem(Name(), ref, index, offset, size); - elemRefs[segIdx].push_back(&curr->segment); + auto* curr = Builder(wasm).makeArrayInitElem( + getElemName(segIdx), ref, index, offset, size); out = curr; } return true; @@ -7941,9 +7944,6 @@ void WasmBinaryReader::visitResume(Resume* curr) { curr->handlerTags[i] = tag; curr->handlerBlocks[i] = handler; - - // We don't know the final name yet - tagRefs[tagIndex].push_back(&curr->handlerTags[i]); } curr->cont = popNonVoidExpression(); @@ -7966,7 +7966,6 @@ void WasmBinaryReader::visitSuspend(Suspend* curr) { } 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); |