diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-09-19 15:50:30 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-19 15:50:30 -0700 |
commit | fe88b47749115009da0447e340cbdc86edf30984 (patch) | |
tree | 7dfd9aba7086c8aa6dff4877ac1ee3b9d78bc5ce /src/wasm/wasm-s-parser.cpp | |
parent | a53356ab155a7d8c2f334dc9a3c1432bacbc78fe (diff) | |
download | binaryen-fe88b47749115009da0447e340cbdc86edf30984.tar.gz binaryen-fe88b47749115009da0447e340cbdc86edf30984.tar.bz2 binaryen-fe88b47749115009da0447e340cbdc86edf30984.zip |
Unify imported and non-imported things (#1678)
Fixes #1649
This moves us to a single object for functions, which can be imported or nor, and likewise for globals (as a result, GetGlobals do not need to check if the global is imported or not, etc.). All imported things now inherit from Importable, which has the module and base of the import, and if they are set then it is an import.
For convenient iteration, there are a few helpers like
ModuleUtils::iterDefinedGlobals(wasm, [&](Global* global) {
.. use global ..
});
as often iteration only cares about imported or defined (non-imported) things.
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 166 |
1 files changed, 71 insertions, 95 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index e4c171b5c..7085666bb 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -23,6 +23,7 @@ #include "asm_v_wasm.h" #include "asmjs/shared-constants.h" #include "ir/branch-utils.h" +#include "ir/function-type-utils.h" #include "shared-constants.h" #include "wasm-binary.h" #include "wasm-builder.h" @@ -581,14 +582,15 @@ void SExpressionWasmBuilder::parseFunction(Element& s, bool preParseImport) { if (importModule.is()) { // this is an import, actually if (!preParseImport) throw ParseException("!preParseImport in func"); - std::unique_ptr<Import> im = make_unique<Import>(); + auto im = make_unique<Function>(); im->name = name; im->module = importModule; im->base = importBase; - im->kind = ExternalKind::Function; - im->functionType = wasm.getFunctionType(type)->name; - if (wasm.getImportOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); - wasm.addImport(im.release()); + im->type = type; + FunctionTypeUtils::fillFunction(im.get(), wasm.getFunctionType(type)); + functionTypes[name] = im->result; + if (wasm.getFunctionOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); + wasm.addFunction(im.release()); if (currFunction) throw ParseException("import module inside function dec"); currLocalTypes.clear(); nameMapper.clear(); @@ -821,7 +823,6 @@ Expression* SExpressionWasmBuilder::makeExpression(Element& s) { case 'c': { if (str[1] == 'a') { if (id == CALL) return makeCall(s); - if (id == CALL_IMPORT) return makeCallImport(s); if (id == CALL_INDIRECT) return makeCallIndirect(s); } else if (str[1] == 'u') return makeHost(s, HostOp::CurrentMemory); abort_on(str); @@ -1040,16 +1041,11 @@ Expression* SExpressionWasmBuilder::makeGetGlobal(Element& s) { auto ret = allocator.alloc<GetGlobal>(); ret->name = getGlobalName(*s[1]); auto* global = wasm.getGlobalOrNull(ret->name); - if (global) { - ret->type = global->type; - return ret; + if (!global) { + throw ParseException("bad get_global name", s.line, s.col); } - auto* import = wasm.getImportOrNull(ret->name); - if (import && import->kind == ExternalKind::Global) { - ret->type = import->globalType; - return ret; - } - throw ParseException("bad get_global name", s.line, s.col); + ret->type = global->type; + return ret; } Expression* SExpressionWasmBuilder::makeSetGlobal(Element& s) { @@ -1377,15 +1373,6 @@ Expression* SExpressionWasmBuilder::makeLoop(Element& s) { Expression* SExpressionWasmBuilder::makeCall(Element& s) { auto target = getFunctionName(*s[1]); - auto* import = wasm.getImportOrNull(target); - if (import && import->kind == ExternalKind::Function) { - auto ret = allocator.alloc<CallImport>(); - ret->target = target; - Import* import = wasm.getImport(ret->target); - ret->type = wasm.getFunctionType(import->functionType)->result; - parseCallOperands(s, 2, s.size(), ret); - return ret; - } auto ret = allocator.alloc<Call>(); ret->target = target; ret->type = functionTypes[ret->target]; @@ -1394,16 +1381,6 @@ Expression* SExpressionWasmBuilder::makeCall(Element& s) { return ret; } -Expression* SExpressionWasmBuilder::makeCallImport(Element& s) { - auto ret = allocator.alloc<CallImport>(); - ret->target = s[1]->str(); - Import* import = wasm.getImport(ret->target); - ret->type = wasm.getFunctionType(import->functionType)->result; - parseCallOperands(s, 2, s.size(), ret); - ret->finalize(); - return ret; -} - Expression* SExpressionWasmBuilder::makeCallIndirect(Element& s) { if (!wasm.table.exists) throw ParseException("no table"); auto ret = allocator.alloc<CallIndirect>(); @@ -1543,7 +1520,6 @@ Index SExpressionWasmBuilder::parseMemoryLimits(Element& s, Index i) { void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { if (wasm.memory.exists) throw ParseException("too many memories"); wasm.memory.exists = true; - wasm.memory.imported = preParseImport; wasm.memory.shared = false; Index i = 1; if (s[i]->dollared()) { @@ -1561,15 +1537,8 @@ void SExpressionWasmBuilder::parseMemory(Element& s, bool preParseImport) { wasm.addExport(ex.release()); i++; } else if (inner[0]->str() == IMPORT) { - importModule = inner[1]->str(); - importBase = inner[2]->str(); - auto im = make_unique<Import>(); - im->kind = ExternalKind::Memory; - im->module = importModule; - im->base = importBase; - im->name = importModule; - if (wasm.getImportOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); - wasm.addImport(im.release()); + wasm.memory.module = inner[1]->str(); + wasm.memory.base = inner[2]->str(); i++; } else if (inner[0]->str() == "shared") { wasm.memory.shared = true; @@ -1675,70 +1644,69 @@ void SExpressionWasmBuilder::parseExport(Element& s) { } void SExpressionWasmBuilder::parseImport(Element& s) { - std::unique_ptr<Import> im = make_unique<Import>(); size_t i = 1; bool newStyle = s.size() == 4 && s[3]->isList(); // (import "env" "STACKTOP" (global $stackTop i32)) + auto kind = ExternalKind::Invalid; if (newStyle) { if ((*s[3])[0]->str() == FUNC) { - im->kind = ExternalKind::Function; + kind = ExternalKind::Function; } else if ((*s[3])[0]->str() == MEMORY) { - im->kind = ExternalKind::Memory; + kind = ExternalKind::Memory; if (wasm.memory.exists) throw ParseException("more than one memory"); wasm.memory.exists = true; - wasm.memory.imported = true; } else if ((*s[3])[0]->str() == TABLE) { - im->kind = ExternalKind::Table; + kind = ExternalKind::Table; if (wasm.table.exists) throw ParseException("more than one table"); wasm.table.exists = true; - wasm.table.imported = true; } else if ((*s[3])[0]->str() == GLOBAL) { - im->kind = ExternalKind::Global; + kind = ExternalKind::Global; } else { newStyle = false; // either (param..) or (result..) } } Index newStyleInner = 1; + Name name; if (s.size() > 3 && s[3]->isStr()) { - im->name = s[i++]->str(); + name = s[i++]->str(); } else if (newStyle && newStyleInner < s[3]->size() && (*s[3])[newStyleInner]->dollared()) { - im->name = (*s[3])[newStyleInner++]->str(); - } - if (!im->name.is()) { - if (im->kind == ExternalKind::Function) { - im->name = Name("import$function$" + std::to_string(functionCounter++)); - functionNames.push_back(im->name); - } else if (im->kind == ExternalKind::Global) { - im->name = Name("import$global" + std::to_string(globalCounter++)); - globalNames.push_back(im->name); - } else if (im->kind == ExternalKind::Memory) { - im->name = Name("import$memory$" + std::to_string(0)); - } else if (im->kind == ExternalKind::Table) { - im->name = Name("import$table$" + std::to_string(0)); + name = (*s[3])[newStyleInner++]->str(); + } + if (!name.is()) { + if (kind == ExternalKind::Function) { + name = Name("import$function$" + std::to_string(functionCounter++)); + functionNames.push_back(name); + } else if (kind == ExternalKind::Global) { + name = Name("import$global" + std::to_string(globalCounter++)); + globalNames.push_back(name); + } else if (kind == ExternalKind::Memory) { + name = Name("import$memory$" + std::to_string(0)); + } else if (kind == ExternalKind::Table) { + name = Name("import$table$" + std::to_string(0)); } else { throw ParseException("invalid import"); } } if (!s[i]->quoted()) { if (s[i]->str() == MEMORY) { - im->kind = ExternalKind::Memory; + kind = ExternalKind::Memory; } else if (s[i]->str() == TABLE) { - im->kind = ExternalKind::Table; + kind = ExternalKind::Table; } else if (s[i]->str() == GLOBAL) { - im->kind = ExternalKind::Global; + kind = ExternalKind::Global; } else { throw ParseException("invalid ext import"); } i++; } else if (!newStyle) { - im->kind = ExternalKind::Function; + kind = ExternalKind::Function; } - im->module = s[i++]->str(); + auto module = s[i++]->str(); if (!s[i]->isStr()) throw ParseException("no name for import"); - im->base = s[i++]->str(); + auto base = s[i++]->str(); // parse internals Element& inner = newStyle ? *s[3] : s; Index j = newStyle ? newStyleInner : i; - if (im->kind == ExternalKind::Function) { + if (kind == ExternalKind::Function) { std::unique_ptr<FunctionType> type = make_unique<FunctionType>(); if (inner.size() > j) { Element& params = *inner[j]; @@ -1762,17 +1730,34 @@ void SExpressionWasmBuilder::parseImport(Element& s) { type->result = stringToType(result[1]->str()); } } - im->functionType = ensureFunctionType(getSig(type.get()), &wasm)->name; - } else if (im->kind == ExternalKind::Global) { + auto func = make_unique<Function>(); + func->name = name; + func->module = module; + func->base = base; + auto* functionType = ensureFunctionType(getSig(type.get()), &wasm); + func->type = functionType->name; + FunctionTypeUtils::fillFunction(func.get(), functionType); + functionTypes[name] = func->result; + wasm.addFunction(func.release()); + } else if (kind == ExternalKind::Global) { + Type type; if (inner[j]->isStr()) { - im->globalType = stringToType(inner[j]->str()); + type = stringToType(inner[j]->str()); } else { auto& inner2 = *inner[j]; if (inner2[0]->str() != MUT) throw ParseException("expected mut"); - im->globalType = stringToType(inner2[1]->str()); + type = stringToType(inner2[1]->str()); throw ParseException("cannot import a mutable global", s.line, s.col); } - } else if (im->kind == ExternalKind::Table) { + auto global = make_unique<Global>(); + global->name = name; + global->module = module; + global->base = base; + global->type = type; + wasm.addGlobal(global.release()); + } else if (kind == ExternalKind::Table) { + wasm.table.module = module; + wasm.table.base = base; if (j < inner.size() - 1) { wasm.table.initial = getCheckedAddress(inner[j++], "excessive table init size"); } @@ -1782,7 +1767,9 @@ void SExpressionWasmBuilder::parseImport(Element& s) { wasm.table.max = Table::kMaxSize; } // ends with the table element type - } else if (im->kind == ExternalKind::Memory) { + } else if (kind == ExternalKind::Memory) { + wasm.memory.module = module; + wasm.memory.base = base; if (inner[j]->isList()) { auto& limits = *inner[j]; if (!(limits[0]->isStr() && limits[0]->str() == "shared")) throw ParseException("bad memory limit declaration"); @@ -1792,8 +1779,6 @@ void SExpressionWasmBuilder::parseImport(Element& s) { parseMemoryLimits(inner, j); } } - if (wasm.getImportOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); - wasm.addImport(im.release()); } void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { @@ -1841,14 +1826,13 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { // this is an import, actually if (!preParseImport) throw ParseException("!preParseImport in global"); if (mutable_) throw ParseException("cannot import a mutable global", s.line, s.col); - std::unique_ptr<Import> im = make_unique<Import>(); + auto im = make_unique<Global>(); im->name = global->name; im->module = importModule; im->base = importBase; - im->kind = ExternalKind::Global; - im->globalType = type; - if (wasm.getImportOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); - wasm.addImport(im.release()); + im->type = type; + if (wasm.getGlobalOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); + wasm.addGlobal(im.release()); return; } if (preParseImport) throw ParseException("preParseImport in global"); @@ -1868,7 +1852,6 @@ void SExpressionWasmBuilder::parseGlobal(Element& s, bool preParseImport) { void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { if (wasm.table.exists) throw ParseException("more than one table"); wasm.table.exists = true; - wasm.table.imported = preParseImport; Index i = 1; if (i == s.size()) return; // empty table in old notation if (s[i]->dollared()) { @@ -1887,16 +1870,9 @@ void SExpressionWasmBuilder::parseTable(Element& s, bool preParseImport) { wasm.addExport(ex.release()); i++; } else if (inner[0]->str() == IMPORT) { - importModule = inner[1]->str(); - importBase = inner[2]->str(); if (!preParseImport) throw ParseException("!preParseImport in table"); - auto im = make_unique<Import>(); - im->kind = ExternalKind::Table; - im->module = importModule; - im->base = importBase; - im->name = importModule; - if (wasm.getImportOrNull(im->name)) throw ParseException("duplicate import", s.line, s.col); - wasm.addImport(im.release()); + wasm.table.module = inner[1]->str(); + wasm.table.base = inner[2]->str(); i++; } else { throw ParseException("invalid table"); |