summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h8
-rw-r--r--src/binaryen-c.cpp8
-rw-r--r--src/passes/Print.cpp15
-rw-r--r--src/wasm-binary.h39
-rw-r--r--src/wasm-linker.cpp7
-rw-r--r--src/wasm-linker.h1
-rw-r--r--src/wasm-s-parser.h28
-rw-r--r--src/wasm-validator.h14
-rw-r--r--src/wasm.h9
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) {}
};