diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index c723dfe32..521edab39 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -83,6 +83,16 @@ void WasmBinaryWriter::finishSection(int32_t start) { o.writeAt(start, U32LEB(size)); } +int32_t WasmBinaryWriter::startSubsection(BinaryConsts::UserSections::Subsection code) { + o << U32LEB(code); + return writeU32LEBPlaceholder(); // section size to be filled in later +} + +void WasmBinaryWriter::finishSubsection(int32_t start) { + int32_t size = o.size() - start - 5; // section size does not include the 5 bytes of the size field itself + o.writeAt(start, U32LEB(size)); +} + void WasmBinaryWriter::writeStart() { if (!wasm->start.is()) return; if (debug) std::cerr << "== writeStart" << std::endl; @@ -389,21 +399,24 @@ void WasmBinaryWriter::writeNames() { if (debug) std::cerr << "== writeNames" << std::endl; auto start = startSection(BinaryConsts::Section::User); writeInlineString(BinaryConsts::UserSections::Name); + auto substart = startSubsection(BinaryConsts::UserSections::Subsection::NameFunction); o << U32LEB(mappedFunctions.size()); Index emitted = 0; for (auto& import : wasm->imports) { if (import->kind == ExternalKind::Function) { + o << U32LEB(emitted); writeInlineString(import->name.str); - o << U32LEB(0); // TODO: locals emitted++; } } for (auto& curr : wasm->functions) { + o << U32LEB(emitted); writeInlineString(curr->name.str); - o << U32LEB(0); // TODO: locals emitted++; } assert(emitted == mappedFunctions.size()); + finishSubsection(substart); + /* TODO: locals */ finishSection(start); } @@ -969,7 +982,7 @@ void WasmBinaryBuilder::readUserSection(size_t payloadLen) { auto oldPos = pos; Name sectionName = getInlineString(); if (sectionName.equals(BinaryConsts::UserSections::Name)) { - readNames(); + readNames(payloadLen - (pos - oldPos)); } else { // an unfamiliar custom section wasm.userSections.resize(wasm.userSections.size() + 1); @@ -1510,25 +1523,36 @@ void WasmBinaryBuilder::readTableElements() { } } -void WasmBinaryBuilder::readNames() { +void WasmBinaryBuilder::readNames(size_t payloadLen) { if (debug) std::cerr << "== readNames" << std::endl; - auto num = getU32LEB(); - if (num == 0) return; - for (auto& import : wasm.imports) { - if (import->kind == ExternalKind::Function) { - getInlineString(); // TODO: use this - auto numLocals = getU32LEB(); - WASM_UNUSED(numLocals); - assert(numLocals == 0); // TODO - if (--num == 0) return; + auto sectionPos = pos; + while (pos < sectionPos + payloadLen) { + auto nameType = getU32LEB(); + auto subsectionSize = getU32LEB(); + auto subsectionPos = pos; + if (nameType != BinaryConsts::UserSections::Subsection::NameFunction) { + // TODO: locals + std::cerr << "unknown name subsection at " << pos << std::endl; + pos = subsectionPos + subsectionSize; + continue; } + auto num = getU32LEB(); + uint32_t importedFunctions = 0; + for (auto& import : wasm.imports) { + if (import->kind != ExternalKind::Function) continue; + importedFunctions++; + } + for (size_t i = 0; i < num; i++) { + auto index = getU32LEB(); + if (index < importedFunctions) { + getInlineString(); // TODO: use this + } else if (index - importedFunctions < functions.size()) { + functions[index - importedFunctions]->name = getInlineString(); + } + } + assert(pos == subsectionPos + subsectionSize); } - for (size_t i = 0; i < num; i++) { - functions[i]->name = getInlineString(); - auto numLocals = getU32LEB(); - WASM_UNUSED(numLocals); - assert(numLocals == 0); // TODO - } + assert(pos == sectionPos + payloadLen); } BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { |