summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-07-21 16:07:30 -0700
committerGitHub <noreply@github.com>2016-07-21 16:07:30 -0700
commitfdbba5eb702a945c0a72ae5c4ab00c5579730f4a (patch)
tree5d402051ae1781328fb8fe0725cf9c4286c0ff5c /src
parent12abb63203788cba23f5c65a971a2af922e05bfc (diff)
downloadbinaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.tar.gz
binaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.tar.bz2
binaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.zip
support wasm globals (#650)
Diffstat (limited to 'src')
-rw-r--r--src/ast_utils.h26
-rw-r--r--src/passes/Precompute.cpp6
-rw-r--r--src/passes/Print.cpp27
-rw-r--r--src/wasm-builder.h13
-rw-r--r--src/wasm-interpreter.h42
-rw-r--r--src/wasm-s-parser.h59
-rw-r--r--src/wasm-traversal.h21
-rw-r--r--src/wasm-validator.h5
-rw-r--r--src/wasm.h66
9 files changed, 256 insertions, 9 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h
index 77bfaf1f3..3e45d0e33 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -160,6 +160,8 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer
void visitSetLocal(SetLocal *curr) {
localsWritten.insert(curr->index);
}
+ void visitGetGlobal(GetGlobal *curr) { readsMemory = true; } // TODO: global-specific
+ void visitSetGlobal(SetGlobal *curr) { writesMemory = true; } // stuff?
void visitLoad(Load *curr) { readsMemory = true; }
void visitStore(Store *curr) { writesMemory = true; }
void visitReturn(Return *curr) { branches = true; }
@@ -277,6 +279,12 @@ struct ExpressionManipulator {
Expression* visitSetLocal(SetLocal *curr) {
return builder.makeSetLocal(curr->index, copy(curr->value));
}
+ Expression* visitGetGlobal(GetGlobal *curr) {
+ return builder.makeGetGlobal(curr->index, curr->type);
+ }
+ Expression* visitSetGlobal(SetGlobal *curr) {
+ return builder.makeSetGlobal(curr->index, copy(curr->value));
+ }
Expression* visitLoad(Load *curr) {
return builder.makeLoad(curr->bytes, curr->signed_, curr->offset, curr->align, copy(curr->ptr), curr->type);
}
@@ -476,6 +484,15 @@ struct ExpressionAnalyzer {
PUSH(SetLocal, value);
break;
}
+ case Expression::Id::GetGlobalId: {
+ CHECK(GetGlobal, index);
+ break;
+ }
+ case Expression::Id::SetGlobalId: {
+ CHECK(SetGlobal, index);
+ PUSH(SetGlobal, value);
+ break;
+ }
case Expression::Id::LoadId: {
CHECK(Load, bytes);
CHECK(Load, signed_);
@@ -678,6 +695,15 @@ struct ExpressionAnalyzer {
PUSH(SetLocal, value);
break;
}
+ case Expression::Id::GetGlobalId: {
+ HASH(GetGlobal, index);
+ break;
+ }
+ case Expression::Id::SetGlobalId: {
+ HASH(SetGlobal, index);
+ PUSH(SetGlobal, value);
+ break;
+ }
case Expression::Id::LoadId: {
HASH(Load, bytes);
HASH(Load, signed_);
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 4f0a0e22d..a341ba938 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -63,6 +63,12 @@ public:
Flow visitSetLocal(SetLocal *curr) {
return Flow(NONSTANDALONE);
}
+ Flow visitGetGlobal(GetGlobal *curr) {
+ return Flow(NONSTANDALONE);
+ }
+ Flow visitSetGlobal(SetGlobal *curr) {
+ return Flow(NONSTANDALONE);
+ }
Flow visitLoad(Load *curr) {
return Flow(NONSTANDALONE);
}
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 5fe7f93ac..e967d1850 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -35,6 +35,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
bool fullAST = false; // whether to not elide nodes in output when possible
// (like implicit blocks)
+ Module* currModule = nullptr;
Function* currFunction = nullptr;
PrintSExpression(std::ostream& o) : o(o) {
@@ -78,6 +79,10 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
return name;
}
+ Name printableGlobal(Index index) {
+ return currModule->getGlobal(index)->name;
+ }
+
std::ostream& printName(Name name) {
// we need to quote names if they have tricky chars
if (strpbrk(name.str, "()")) {
@@ -239,6 +244,15 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
printFullLine(curr->value);
decIndent();
}
+ void visitGetGlobal(GetGlobal *curr) {
+ printOpening(o, "get_global ") << printableGlobal(curr->index) << ')';
+ }
+ void visitSetGlobal(SetGlobal *curr) {
+ printOpening(o, "set_global ") << printableGlobal(curr->index);
+ incIndent();
+ printFullLine(curr->value);
+ decIndent();
+ }
void visitLoad(Load *curr) {
o << '(';
prepareColor(o) << printWasmType(curr->type) << ".load";
@@ -519,6 +533,12 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
printText(o, curr->name.str) << ' ';
printName(curr->value) << ')';
}
+ void visitGlobal(Global *curr) {
+ printOpening(o, "global ");
+ printName(curr->name) << ' ' << printWasmType(curr->type);
+ printFullLine(curr->init);
+ o << ')';
+ }
void visitFunction(Function *curr) {
currFunction = curr;
printOpening(o, "func ", true);
@@ -563,6 +583,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
o << ')';
}
void visitModule(Module *curr) {
+ currModule = curr;
printOpening(o, "module", true);
incIndent();
doIndent(o, indent);
@@ -621,6 +642,11 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
visitExport(child.get());
o << maybeNewLine;
}
+ for (auto& child : curr->globals) {
+ doIndent(o, indent);
+ visitGlobal(child.get());
+ o << maybeNewLine;
+ }
if (curr->table.names.size() > 0) {
doIndent(o, indent);
visitTable(&curr->table);
@@ -633,6 +659,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
decIndent();
o << maybeNewLine;
+ currModule = nullptr;
}
};
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index e73b707b9..22e1f9a00 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -145,6 +145,19 @@ public:
ret->type = value->type;
return ret;
}
+ GetGlobal* makeGetGlobal(Index index, WasmType type) {
+ auto* ret = allocator.alloc<GetGlobal>();
+ ret->index = index;
+ ret->type = type;
+ return ret;
+ }
+ SetGlobal* makeSetGlobal(Index index, Expression* value) {
+ auto* ret = allocator.alloc<SetGlobal>();
+ ret->index = index;
+ ret->value = value;
+ ret->type = value->type;
+ return ret;
+ }
Load* makeLoad(unsigned bytes, bool signed_, uint32_t offset, unsigned align, Expression *ptr, WasmType type) {
auto* ret = allocator.alloc<Load>();
ret->bytes = bytes; ret->signed_ = signed_; ret->offset = offset; ret->align = align; ret->ptr = ptr;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index a8b4b5614..adaee0b6f 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -491,6 +491,22 @@ public:
}
};
+// Execute an expression in global init
+class GlobalInitRunner : public ExpressionRunner<GlobalInitRunner> {
+public:
+ Flow visitLoop(Loop* curr) { WASM_UNREACHABLE(); }
+ Flow visitCall(Call* curr) { WASM_UNREACHABLE(); }
+ Flow visitCallImport(CallImport* curr) { WASM_UNREACHABLE(); }
+ Flow visitCallIndirect(CallIndirect* curr) { WASM_UNREACHABLE(); }
+ Flow visitGetLocal(GetLocal *curr) { WASM_UNREACHABLE(); }
+ Flow visitSetLocal(SetLocal *curr) { WASM_UNREACHABLE(); }
+ Flow visitGetGlobal(GetGlobal *curr) { WASM_UNREACHABLE(); }
+ Flow visitSetGlobal(SetGlobal *curr) { WASM_UNREACHABLE(); }
+ Flow visitLoad(Load *curr) { WASM_UNREACHABLE(); }
+ Flow visitStore(Store *curr) { WASM_UNREACHABLE(); }
+ Flow visitHost(Host *curr) { WASM_UNREACHABLE(); }
+};
+
//
// An instance of a WebAssembly module, which can execute it via AST interpretation.
//
@@ -519,8 +535,14 @@ public:
Module& wasm;
+ // Values of globals
+ std::vector<Literal> globals;
+
ModuleInstance(Module& wasm, ExternalInterface* externalInterface) : wasm(wasm), externalInterface(externalInterface) {
memorySize = wasm.memory.initial;
+ for (Index i = 0; i < wasm.globals.size(); i++) {
+ globals.push_back(GlobalInitRunner().visit(wasm.globals[i]->init).value);
+ }
externalInterface->init(wasm);
if (wasm.start.is()) {
LiteralList arguments;
@@ -676,6 +698,26 @@ private:
scope.locals[index] = flow.value;
return flow;
}
+
+ Flow visitGetGlobal(GetGlobal *curr) {
+ NOTE_ENTER("GetGlobal");
+ auto index = curr->index;
+ NOTE_EVAL1(index);
+ NOTE_EVAL1(instance.globals[index]);
+ return instance.globals[index];
+ }
+ Flow visitSetGlobal(SetGlobal *curr) {
+ NOTE_ENTER("SetGlobal");
+ auto index = curr->index;
+ Flow flow = visit(curr->value);
+ if (flow.breaking()) return flow;
+ NOTE_EVAL1(index);
+ NOTE_EVAL1(flow.value);
+ assert(flow.value.type == curr->type);
+ instance.globals[index] = flow.value;
+ return flow;
+ }
+
Flow visitLoad(Load *curr) {
NOTE_ENTER("Load");
Flow flow = visit(curr->ptr);
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index c6b3809f1..b93494c76 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -264,11 +264,12 @@ class SExpressionWasmBuilder {
std::vector<Name> functionNames;
int functionCounter;
int importCounter;
+ int globalCounter;
std::map<Name, WasmType> functionTypes; // we need to know function return types before we parse their contents
public:
// Assumes control of and modifies the input.
- SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0) {
+ SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0), globalCounter(0) {
assert(module[0]->str() == MODULE);
if (module.size() > 1 && module[1]->isStr()) {
// these s-expressions contain a binary module, actually
@@ -340,6 +341,7 @@ private:
if (id == MEMORY) return parseMemory(curr);
if (id == EXPORT) return parseExport(curr);
if (id == IMPORT) return; // already done
+ if (id == GLOBAL) return parseGlobal(curr);
if (id == TABLE) return parseTable(curr);
if (id == TYPE) return; // already done
std::cerr << "bad module element " << id.str << '\n';
@@ -703,7 +705,10 @@ public:
abort_on(str);
}
case 'g': {
- if (str[1] == 'e') return makeGetLocal(s);
+ if (str[1] == 'e') {
+ if (str[4] == 'l') return makeGetLocal(s);
+ if (str[4] == 'g') return makeGetGlobal(s);
+ }
if (str[1] == 'r') return makeHost(s, HostOp::GrowMemory);
abort_on(str);
}
@@ -728,7 +733,10 @@ public:
abort_on(str);
}
case 's': {
- if (str[1] == 'e' && str[2] == 't') return makeSetLocal(s);
+ if (str[1] == 'e' && str[2] == 't') {
+ if (str[4] == 'l') return makeSetLocal(s);
+ if (str[4] == 'g') return makeSetGlobal(s);
+ }
if (str[1] == 'e' && str[2] == 'l') return makeSelect(s);
abort_on(str);
}
@@ -844,6 +852,7 @@ private:
}
Index getLocalIndex(Element& s) {
+ if (!currFunction) throw ParseException("local access in non-function scope", s.line, s.col);
if (s.dollared()) {
auto ret = s.str();
if (currFunction->localIndices.count(ret) == 0) throw ParseException("bad local name", s.line, s.col);
@@ -870,6 +879,35 @@ private:
return ret;
}
+ Index getGlobalIndex(Element& s) {
+ if (s.dollared()) {
+ auto name = s.str();
+ for (Index i = 0; i < wasm.globals.size(); i++) {
+ if (wasm.globals[i]->name == name) return i;
+ }
+ throw ParseException("bad global name", s.line, s.col);
+ }
+ // this is a numeric index
+ Index ret = atoi(s.c_str());
+ if (!wasm.checkGlobal(ret)) throw ParseException("bad global index", s.line, s.col);
+ return ret;
+ }
+
+ Expression* makeGetGlobal(Element& s) {
+ auto ret = allocator.alloc<GetGlobal>();
+ ret->index = getGlobalIndex(*s[1]);
+ ret->type = wasm.getGlobal(ret->index)->type;
+ return ret;
+ }
+
+ Expression* makeSetGlobal(Element& s) {
+ auto ret = allocator.alloc<SetGlobal>();
+ ret->index = getGlobalIndex(*s[1]);
+ ret->value = parseExpression(s[2]);
+ ret->type = wasm.getGlobal(ret->index)->type;
+ return ret;
+ }
+
Expression* makeBlock(Element& s) {
// special-case Block, because Block nesting (in their first element) can be incredibly deep
auto curr = allocator.alloc<Block>();
@@ -1315,6 +1353,21 @@ private:
wasm.addImport(im.release());
}
+ void parseGlobal(Element& s) {
+ std::unique_ptr<Global> global = make_unique<Global>();
+ size_t i = 1;
+ if (s.size() == 4) {
+ global->name = s[i++]->str();
+ } else {
+ global->name = Name::fromInt(globalCounter);
+ }
+ globalCounter++;
+ global->type = stringToWasmType(s[i++]->str());
+ global->init = parseExpression(s[i++]);
+ assert(i == s.size());
+ wasm.addGlobal(global.release());
+ }
+
void parseTable(Element& s) {
for (size_t i = 1; i < s.size(); i++) {
wasm.table.names.push_back(getFunctionName(*s[i]));
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h
index cf023d3fa..b50ca0fb2 100644
--- a/src/wasm-traversal.h
+++ b/src/wasm-traversal.h
@@ -45,6 +45,8 @@ struct Visitor {
ReturnType visitCallIndirect(CallIndirect *curr) {}
ReturnType visitGetLocal(GetLocal *curr) {}
ReturnType visitSetLocal(SetLocal *curr) {}
+ ReturnType visitGetGlobal(GetGlobal *curr) {}
+ ReturnType visitSetGlobal(SetGlobal *curr) {}
ReturnType visitLoad(Load *curr) {}
ReturnType visitStore(Store *curr) {}
ReturnType visitConst(Const *curr) {}
@@ -59,6 +61,7 @@ struct Visitor {
ReturnType visitFunctionType(FunctionType *curr) {}
ReturnType visitImport(Import *curr) {}
ReturnType visitExport(Export *curr) {}
+ ReturnType visitGlobal(Global *curr) {}
ReturnType visitFunction(Function *curr) {}
ReturnType visitTable(Table *curr) {}
ReturnType visitMemory(Memory *curr) {}
@@ -82,6 +85,8 @@ struct Visitor {
case Expression::Id::CallIndirectId: DELEGATE(CallIndirect);
case Expression::Id::GetLocalId: DELEGATE(GetLocal);
case Expression::Id::SetLocalId: DELEGATE(SetLocal);
+ case Expression::Id::GetGlobalId: DELEGATE(GetGlobal);
+ case Expression::Id::SetGlobalId: DELEGATE(SetGlobal);
case Expression::Id::LoadId: DELEGATE(Load);
case Expression::Id::StoreId: DELEGATE(Store);
case Expression::Id::ConstId: DELEGATE(Const);
@@ -119,6 +124,8 @@ struct UnifiedExpressionVisitor : public Visitor<SubType> {
ReturnType visitCallIndirect(CallIndirect *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
ReturnType visitGetLocal(GetLocal *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
ReturnType visitSetLocal(SetLocal *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
+ ReturnType visitGetGlobal(GetGlobal *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
+ ReturnType visitSetGlobal(SetGlobal *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
ReturnType visitLoad(Load *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
ReturnType visitStore(Store *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
ReturnType visitConst(Const *curr) { return static_cast<SubType*>(this)->visitExpression(curr); }
@@ -192,6 +199,9 @@ struct Walker : public VisitorType {
for (auto& curr : module->exports) {
self->visitExport(curr.get());
}
+ for (auto& curr : module->globals) {
+ self->visitGlobal(curr.get());
+ }
for (auto& curr : module->functions) {
self->walkFunction(curr.get());
}
@@ -254,6 +264,8 @@ struct Walker : public VisitorType {
static void doVisitCallIndirect(SubType* self, Expression** currp) { self->visitCallIndirect((*currp)->cast<CallIndirect>()); }
static void doVisitGetLocal(SubType* self, Expression** currp) { self->visitGetLocal((*currp)->cast<GetLocal>()); }
static void doVisitSetLocal(SubType* self, Expression** currp) { self->visitSetLocal((*currp)->cast<SetLocal>()); }
+ static void doVisitGetGlobal(SubType* self, Expression** currp) { self->visitGetGlobal((*currp)->cast<GetGlobal>()); }
+ static void doVisitSetGlobal(SubType* self, Expression** currp) { self->visitSetGlobal((*currp)->cast<SetGlobal>()); }
static void doVisitLoad(SubType* self, Expression** currp) { self->visitLoad((*currp)->cast<Load>()); }
static void doVisitStore(SubType* self, Expression** currp) { self->visitStore((*currp)->cast<Store>()); }
static void doVisitConst(SubType* self, Expression** currp) { self->visitConst((*currp)->cast<Const>()); }
@@ -357,6 +369,15 @@ struct PostWalker : public Walker<SubType, VisitorType> {
self->pushTask(SubType::scan, &curr->cast<SetLocal>()->value);
break;
}
+ case Expression::Id::GetGlobalId: {
+ self->pushTask(SubType::doVisitGetGlobal, currp);
+ break;
+ }
+ case Expression::Id::SetGlobalId: {
+ self->pushTask(SubType::doVisitSetGlobal, currp);
+ self->pushTask(SubType::scan, &curr->cast<SetGlobal>()->value);
+ break;
+ }
case Expression::Id::LoadId: {
self->pushTask(SubType::doVisitLoad, currp);
self->pushTask(SubType::scan, &curr->cast<Load>()->ptr);
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
index 066ab57da..90930d8f4 100644
--- a/src/wasm-validator.h
+++ b/src/wasm-validator.h
@@ -260,6 +260,11 @@ public:
}
}
+ void visitGlobal(Global* curr) {
+ shouldBeTrue(curr->init->is<Const>(), curr->name, "global init must be valid");
+ shouldBeEqual(curr->type, curr->init->type, curr, "global init must have correct type");
+ }
+
void visitFunction(Function *curr) {
// if function has no result, it is ignored
// if body is unreachable, it might be e.g. a return
diff --git a/src/wasm.h b/src/wasm.h
index 2d007be65..f3eee7375 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -869,6 +869,8 @@ public:
CallIndirectId,
GetLocalId,
SetLocalId,
+ GetGlobalId,
+ SetGlobalId,
LoadId,
StoreId,
ConstId,
@@ -919,6 +921,8 @@ inline const char *getExpressionName(Expression *curr) {
case Expression::Id::CallIndirectId: return "call_indirect";
case Expression::Id::GetLocalId: return "get_local";
case Expression::Id::SetLocalId: return "set_local";
+ case Expression::Id::GetGlobalId: return "get_global";
+ case Expression::Id::SetGlobalId: return "set_global";
case Expression::Id::LoadId: return "load";
case Expression::Id::StoreId: return "store";
case Expression::Id::ConstId: return "const";
@@ -1105,6 +1109,27 @@ public:
}
};
+class GetGlobal : public SpecificExpression<Expression::GetGlobalId> {
+public:
+ GetGlobal() {}
+ GetGlobal(MixedArena& allocator) {}
+
+ Index index;
+};
+
+class SetGlobal : public SpecificExpression<Expression::SetGlobalId> {
+public:
+ SetGlobal() {}
+ SetGlobal(MixedArena& allocator) {}
+
+ Index index;
+ Expression *value;
+
+ void finalize() {
+ type = value->type;
+ }
+};
+
class Load : public SpecificExpression<Expression::LoadId> {
public:
Load() {}
@@ -1431,6 +1456,13 @@ public:
Memory() : initial(0), max(kMaxSize) {}
};
+class Global {
+public:
+ Name name;
+ WasmType type;
+ Expression* init;
+};
+
class Module {
public:
// wasm contents (generally you shouldn't access these from outside, except maybe for iterating; use add*() and the get() functions)
@@ -1438,6 +1470,7 @@ public:
std::vector<std::unique_ptr<Import>> imports;
std::vector<std::unique_ptr<Export>> exports;
std::vector<std::unique_ptr<Function>> functions;
+ std::vector<std::unique_ptr<Global>> globals;
Table table;
Memory memory;
@@ -1451,24 +1484,34 @@ private:
std::map<Name, Import*> importsMap;
std::map<Name, Export*> exportsMap;
std::map<Name, Function*> functionsMap;
+ std::map<Name, Global*> globalsMap;
public:
- Module() : functionTypeIndex(0), importIndex(0), exportIndex(0), functionIndex(0) {}
+ Module() : functionTypeIndex(0), importIndex(0), exportIndex(0), functionIndex(0), globalIndex(0) {}
- FunctionType* getFunctionType(size_t i) { assert(i < functionTypes.size()); return functionTypes[i].get(); }
- Import* getImport(size_t i) { assert(i < imports.size()); return imports[i].get(); }
- Export* getExport(size_t i) { assert(i < exports.size()); return exports[i].get(); }
- Function* getFunction(size_t i) { assert(i < functions.size()); return functions[i].get(); }
+ FunctionType* getFunctionType(Index i) { assert(i < functionTypes.size()); return functionTypes[i].get(); }
+ Import* getImport(Index i) { assert(i < imports.size()); return imports[i].get(); }
+ Export* getExport(Index i) { assert(i < exports.size()); return exports[i].get(); }
+ Function* getFunction(Index i) { assert(i < functions.size()); return functions[i].get(); }
+ Global* getGlobal(Index i) { assert(i < globals.size()); return globals[i].get(); }
FunctionType* getFunctionType(Name name) { assert(functionTypesMap[name]); return functionTypesMap[name]; }
Import* getImport(Name name) { assert(importsMap[name]); return importsMap[name]; }
Export* getExport(Name name) { assert(exportsMap[name]); return exportsMap[name]; }
Function* getFunction(Name name) { assert(functionsMap[name]); return functionsMap[name]; }
+ Global* getGlobal(Name name) { assert(globalsMap[name]); return globalsMap[name]; }
FunctionType* checkFunctionType(Name name) { if (functionTypesMap.find(name) == functionTypesMap.end()) return nullptr; return functionTypesMap[name]; }
Import* checkImport(Name name) { if (importsMap.find(name) == importsMap.end()) return nullptr; return importsMap[name]; }
Export* checkExport(Name name) { if (exportsMap.find(name) == exportsMap.end()) return nullptr; return exportsMap[name]; }
Function* checkFunction(Name name) { if (functionsMap.find(name) == functionsMap.end()) return nullptr; return functionsMap[name]; }
+ Global* checkGlobal(Name name) { if (globalsMap.find(name) == globalsMap.end()) return nullptr; return globalsMap[name]; }
+
+ FunctionType* checkFunctionType(Index i) { if (i >= functionTypes.size()) return nullptr; return functionTypes[i].get(); }
+ Import* checkImport(Index i) { if (i >= imports.size()) return nullptr; return imports[i].get(); }
+ Export* checkExport(Index i) { if (i >= exports.size()) return nullptr; return exports[i].get(); }
+ Function* checkFunction(Index i) { if (i >= functions.size()) return nullptr; return functions[i].get(); }
+ Global* checkGlobal(Index i) { if (i >= globals.size()) return nullptr; return globals[i].get(); }
void addFunctionType(FunctionType* curr) {
Name numericName = Name::fromInt(functionTypeIndex); // TODO: remove all these, assert on names already existing, do numeric stuff in wasm-s-parser etc.
@@ -1510,6 +1553,17 @@ public:
functionsMap[numericName] = curr;
functionIndex++;
}
+ void addGlobal(Global* curr) {
+ Name numericName = Name::fromInt(globalIndex);
+ if (curr->name.isNull()) {
+ curr->name = numericName;
+ }
+ globals.push_back(std::unique_ptr<Global>(curr));
+ globalsMap[curr->name] = curr;
+ globalsMap[numericName] = curr;
+ globalIndex++;
+ }
+
void addStart(const Name &s) {
start = s;
}
@@ -1533,7 +1587,7 @@ public:
}
private:
- size_t functionTypeIndex, importIndex, exportIndex, functionIndex;
+ size_t functionTypeIndex, importIndex, exportIndex, functionIndex, globalIndex;
};
} // namespace wasm