diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 8 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 8 | ||||
-rw-r--r-- | src/passes/Print.cpp | 15 | ||||
-rw-r--r-- | src/wasm-binary.h | 39 | ||||
-rw-r--r-- | src/wasm-linker.cpp | 7 | ||||
-rw-r--r-- | src/wasm-linker.h | 1 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 28 | ||||
-rw-r--r-- | src/wasm-validator.h | 14 | ||||
-rw-r--r-- | src/wasm.h | 9 |
9 files changed, 96 insertions, 33 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 4d2ddb0cd..c88563109 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -710,6 +710,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { auto* export_ = new Export; export_->name = key; export_->value = value; + export_->kind = Export::Function; wasm.addExport(export_); exported[key] = export_; } @@ -813,10 +814,15 @@ void Asm2WasmBuilder::processAsm(Ref ast) { )); auto export_ = new Export; export_->name = export_->value = GROW_WASM_MEMORY; + export_->kind = Export::Function; wasm.addExport(export_); } - wasm.memory.exportName = MEMORY; + auto memoryExport = make_unique<Export>(); + memoryExport->name = MEMORY; + memoryExport->value = Name::fromInt(0); + memoryExport->kind = Export::Memory; + wasm.addExport(memoryExport.release()); #if 0 // enable asm2wasm i64 optimizations when browsers have consistent i64 support in wasm if (udivmoddi4.is() && getTempRet0.is()) { diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 8703237d5..e333f64d8 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -805,7 +805,13 @@ void BinaryenSetMemory(BinaryenModuleRef module, BinaryenIndex initial, Binaryen auto* wasm = (Module*)module; wasm->memory.initial = initial; wasm->memory.max = maximum; - if (exportName) wasm->memory.exportName = exportName; + if (exportName) { + auto memoryExport = make_unique<Export>(); + memoryExport->name = exportName; + memoryExport->value = Name::fromInt(0); + memoryExport->kind = Export::Memory; + wasm->addExport(memoryExport.release()); + } for (BinaryenIndex i = 0; i < numSegments; i++) { wasm->memory.segments.emplace_back((Expression*)segmentOffsets[i], segments[i], segmentSizes[i]); } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 02e9b9065..0152f917c 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -543,7 +543,14 @@ struct PrintSExpression : public Visitor<PrintSExpression> { void visitExport(Export *curr) { printOpening(o, "export "); printText(o, curr->name.str) << ' '; - printName(curr->value) << ')'; + switch (curr->kind) { + case Export::Function: printName(curr->value); break; + case Export::Table: o << "table"; break; + case Export::Memory: o << "memory"; break; + case Export::Global: o << "global "; printName(curr->value); break; + default: WASM_UNREACHABLE(); + } + o << ')'; } void visitGlobal(Global *curr) { printOpening(o, "global "); @@ -636,12 +643,6 @@ struct PrintSExpression : public Visitor<PrintSExpression> { } o << "\")\n"; } - if (curr->memory.exportName.is()) { - doIndent(o, indent); - printOpening(o, "export "); - printText(o, curr->memory.exportName.str) << " memory)"; - o << maybeNewLine; - } if (curr->start.is()) { doIndent(o, indent); printOpening(o, "start") << ' ' << curr->start << ')'; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index fa4b78c9d..e250e26ff 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -531,8 +531,7 @@ public: if (debug) std::cerr << "== writeMemory" << std::endl; auto start = startSection(BinaryConsts::Section::Memory); o << U32LEB(wasm->memory.initial) - << U32LEB(wasm->memory.max) - << int8_t(wasm->memory.exportName.is()); // export memory + << U32LEB(wasm->memory.max); finishSection(start); } @@ -692,7 +691,14 @@ public: o << U32LEB(wasm->exports.size()); for (auto& curr : wasm->exports) { if (debug) std::cerr << "write one" << std::endl; - o << U32LEB(getFunctionIndex(curr->value)); + o << U32LEB(curr->kind); + switch (curr->kind) { + case Export::Function: o << U32LEB(getFunctionIndex(curr->value)); break; + case Export::Table: o << U32LEB(0); break; + case Export::Memory: o << U32LEB(0); break; + case Export::Global: o << U32LEB(getGlobalIndex(curr->value)); break; + default: WASM_UNREACHABLE(); + } writeInlineString(curr->name.str); } finishSection(start); @@ -741,6 +747,19 @@ public: return mappedFunctions[name]; } + std::map<Name, uint32_t> mappedGlobals; // name of the Global => index + uint32_t getGlobalIndex(Name name) { + if (!mappedGlobals.size()) { + // Create name => index mapping. + for (size_t i = 0; i < wasm->globals.size(); i++) { + assert(mappedGlobals.count(wasm->globals[i]->name) == 0); + mappedGlobals[wasm->globals[i]->name] = i; + } + } + assert(mappedGlobals.count(name)); + return mappedGlobals[name]; + } + void writeFunctionTable() { if (wasm->table.segments.size() == 0) return; if (debug) std::cerr << "== writeFunctionTable" << std::endl; @@ -1437,10 +1456,6 @@ public: if (debug) std::cerr << "== readMemory" << std::endl; wasm.memory.initial = getU32LEB(); wasm.memory.max = getU32LEB(); - auto exportMemory = getInt8(); - if (exportMemory) { - wasm.memory.exportName = Name("memory"); - } } void readSignatures() { @@ -1578,8 +1593,8 @@ public: for (size_t i = 0; i < num; i++) { if (debug) std::cerr << "read one" << std::endl; auto curr = new Export; + curr->kind = (Export::Kind)getU32LEB(); auto index = getU32LEB(); - assert(index < functionTypes.size()); curr->name = getInlineString(); exportIndexes[curr] = index; } @@ -1644,7 +1659,13 @@ public: for (auto& iter : exportIndexes) { Export* curr = iter.first; - curr->value = wasm.functions[iter.second]->name; + switch (curr->kind) { + case Export::Function: curr->value = wasm.functions[iter.second]->name; break; + case Export::Table: curr->value = Name::fromInt(0); break; + case Export::Memory: curr->value = Name::fromInt(0); break; + case Export::Global: curr->value = wasm.globals[iter.second]->name; break; + default: WASM_UNREACHABLE(); + } wasm.addExport(curr); } diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index b1160e94a..9e968598a 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -106,7 +106,12 @@ void Linker::layout() { } if (userMaxMemory) out.wasm.memory.max = userMaxMemory / Memory::kPageSize; - out.wasm.memory.exportName = MEMORY; + + auto memoryExport = make_unique<Export>(); + memoryExport->name = MEMORY; + memoryExport->value = Name::fromInt(0); + memoryExport->kind = Export::Memory; + out.wasm.addExport(memoryExport.release()); // XXX For now, export all functions marked .globl. for (Name name : out.globls) exportFunction(name, false); diff --git a/src/wasm-linker.h b/src/wasm-linker.h index a6f5d319a..21d336273 100644 --- a/src/wasm-linker.h +++ b/src/wasm-linker.h @@ -310,6 +310,7 @@ class Linker { if (out.wasm.checkExport(name)) return; // Already exported auto exp = new Export; exp->name = exp->value = name; + exp->kind = Export::Function; out.wasm.addExport(exp); } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 429dde417..b6270217b 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -443,6 +443,7 @@ private: auto ex = make_unique<Export>(); ex->name = exportName; ex->value = name; + ex->kind = Export::Function; wasm.addExport(ex.release()); } functionCounter++; @@ -1405,15 +1406,28 @@ private: } void parseExport(Element& s) { + std::unique_ptr<Export> ex = make_unique<Export>(); if (!s[2]->dollared() && !std::isdigit(s[2]->str()[0])) { - assert(s[2]->str() == MEMORY); - if (!hasMemory) throw ParseException("memory exported but no memory"); - wasm.memory.exportName = s[1]->str(); - return; + ex->name = s[1]->str(); + if (s[2]->str() == MEMORY) { + if (!hasMemory) throw ParseException("memory exported but no memory"); + ex->value = Name::fromInt(0); + ex->kind = Export::Memory; + } else if (s[2]->str() == TABLE) { + ex->value = Name::fromInt(0); + ex->kind = Export::Table; + } else if (s[2]->str() == GLOBAL) { + ex->value = s[3]->str(); + ex->kind = Export::Table; + } else { + WASM_UNREACHABLE(); + } + } else { + // function + ex->name = s[1]->str(); + ex->value = s[2]->str(); + ex->kind = Export::Function; } - std::unique_ptr<Export> ex = make_unique<Export>(); - ex->name = s[1]->str(); - ex->value = s[2]->str(); wasm.addExport(ex.release()); } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index ffdd2a2b7..77bf6d3e9 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -367,14 +367,16 @@ public: std::set<Name> exportNames; for (auto& exp : curr->exports) { Name name = exp->value; - bool found = false; - for (auto& func : curr->functions) { - if (func->name == name) { - found = true; - break; + if (exp->kind == Export::Function) { + bool found = false; + for (auto& func : curr->functions) { + if (func->name == name) { + found = true; + break; + } } + shouldBeTrue(found, name, "module exports must be found"); } - shouldBeTrue(found, name, "module exports must be found"); Name exportName = exp->name; shouldBeFalse(exportNames.count(exportName) > 0, exportName, "module exports must be unique"); exportNames.insert(exportName); diff --git a/src/wasm.h b/src/wasm.h index 43c8b192b..f93fb3a80 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1438,8 +1438,16 @@ public: class Export { public: + enum Kind { + Function = 0, + Table = 1, + Memory = 2, + Global = 3, + }; + Name name; // exported name Name value; // internal name + Kind kind; }; class Table { @@ -1484,7 +1492,6 @@ public: Address initial, max; // sizes are in pages std::vector<Segment> segments; - Name exportName; Memory() : initial(0), max(kMaxSize) {} }; |