diff options
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"); |