summaryrefslogtreecommitdiff
path: root/src/wasm-s-parser.h
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/wasm-s-parser.h
parent12abb63203788cba23f5c65a971a2af922e05bfc (diff)
downloadbinaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.tar.gz
binaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.tar.bz2
binaryen-fdbba5eb702a945c0a72ae5c4ab00c5579730f4a.zip
support wasm globals (#650)
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r--src/wasm-s-parser.h59
1 files changed, 56 insertions, 3 deletions
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]));