summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-s-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r--src/wasm/wasm-s-parser.cpp166
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");