summaryrefslogtreecommitdiff
path: root/src/wasm2js.h
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-09-19 15:50:30 -0700
committerGitHub <noreply@github.com>2018-09-19 15:50:30 -0700
commitfe88b47749115009da0447e340cbdc86edf30984 (patch)
tree7dfd9aba7086c8aa6dff4877ac1ee3b9d78bc5ce /src/wasm2js.h
parenta53356ab155a7d8c2f334dc9a3c1432bacbc78fe (diff)
downloadbinaryen-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/wasm2js.h')
-rw-r--r--src/wasm2js.h70
1 files changed, 28 insertions, 42 deletions
diff --git a/src/wasm2js.h b/src/wasm2js.h
index a0519effd..080315490 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -34,6 +34,8 @@
#include "emscripten-optimizer/optimizer.h"
#include "mixed_arena.h"
#include "asm_v_wasm.h"
+#include "ir/import-utils.h"
+#include "ir/module-utils.h"
#include "ir/names.h"
#include "ir/utils.h"
#include "passes/passes.h"
@@ -272,7 +274,7 @@ private:
void addEsmImports(Ref ast, Module* wasm);
void addEsmExportsAndInstantiate(Ref ast, Module* wasm, Name funcName);
void addBasics(Ref ast);
- void addImport(Ref ast, Import* import);
+ void addFunctionImport(Ref ast, Function* import);
void addTables(Ref ast, Module* wasm);
void addExports(Ref ast, Module* wasm);
void addGlobal(Ref ast, Global* global);
@@ -341,9 +343,12 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
asmFunc[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeString(USE_ASM)));
// create heaps, etc
addBasics(asmFunc[3]);
- for (auto& import : wasm->imports) {
- addImport(asmFunc[3], import.get());
- }
+ ModuleUtils::iterImportedFunctions(*wasm, [&](Function* import) {
+ addFunctionImport(asmFunc[3], import);
+ });
+ ModuleUtils::iterImportedGlobals(*wasm, [&](Global* import) {
+ addGlobal(asmFunc[3], import);
+ });
// figure out the table size
tableSize = std::accumulate(wasm->table.segments.begin(),
wasm->table.segments.end(),
@@ -368,16 +373,16 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
fromName(WASM_FETCH_HIGH_BITS, NameScope::Top);
// globals
bool generateFetchHighBits = false;
- for (auto& global : wasm->globals) {
- addGlobal(asmFunc[3], global.get());
+ ModuleUtils::iterDefinedGlobals(*wasm, [&](Global* global) {
+ addGlobal(asmFunc[3], global);
if (flags.allowAsserts && global->name == INT64_TO_32_HIGH_BITS) {
generateFetchHighBits = true;
}
- }
+ });
// functions
- for (auto& func : wasm->functions) {
- asmFunc[3]->push_back(processFunction(wasm, func.get()));
- }
+ ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
+ asmFunc[3]->push_back(processFunction(wasm, func));
+ });
if (generateFetchHighBits) {
Builder builder(allocator);
std::vector<Type> params;
@@ -402,19 +407,15 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
return ret;
}
-void Wasm2JSBuilder::addEsmImports(Ref ast, Module *wasm) {
+void Wasm2JSBuilder::addEsmImports(Ref ast, Module* wasm) {
std::unordered_map<Name, Name> nameMap;
- for (auto& import : wasm->imports) {
- // Only function imports are supported for now, but eventually imported
- // memories can probably be supported at least.
- switch (import->kind) {
- case ExternalKind::Function: break;
- default:
- Fatal() << "non-function imports aren't supported yet\n";
- abort();
- }
-
+ ImportInfo imports(*wasm);
+ if (imports.getNumImportedGlobals() > 0) {
+ Fatal() << "non-function imports aren't supported yet\n";
+ abort();
+ }
+ ModuleUtils::iterImportedFunctions(*wasm, [&](Function* import) {
// Right now codegen requires a flat namespace going into the module,
// meaning we don't importing the same name from multiple namespaces yet.
if (nameMap.count(import->base) && nameMap[import->base] != import->module) {
@@ -434,7 +435,7 @@ void Wasm2JSBuilder::addEsmImports(Ref ast, Module *wasm) {
std::string os = out.str();
IString name(os.c_str(), false);
flattenAppend(ast, ValueBuilder::makeName(name));
- }
+ });
}
static std::string base64Encode(std::vector<char> &data) {
@@ -553,13 +554,10 @@ void Wasm2JSBuilder::addEsmExportsAndInstantiate(Ref ast, Module *wasm, Name fun
<< "}, {";
construct << "abort:function() { throw new Error('abort'); }";
- for (auto& import : wasm->imports) {
- switch (import->kind) {
- case ExternalKind::Function: break;
- default: continue;
- }
+
+ ModuleUtils::iterImportedFunctions(*wasm, [&](Function* import) {
construct << "," << import->base.str;
- }
+ });
construct << "},mem" << funcName.str << ")";
std::string sconstruct = construct.str();
IString name(sconstruct.c_str(), false);
@@ -678,7 +676,7 @@ void Wasm2JSBuilder::addBasics(Ref ast) {
);
}
-void Wasm2JSBuilder::addImport(Ref ast, Import* import) {
+void Wasm2JSBuilder::addFunctionImport(Ref ast, Function* import) {
Ref theVar = ValueBuilder::makeVar();
ast->push_back(theVar);
Ref module = ValueBuilder::makeName(ENV); // TODO: handle nested module imports
@@ -940,14 +938,6 @@ void Wasm2JSBuilder::scanFunctionBody(Expression* curr) {
}
}
}
- void visitCallImport(CallImport* curr) {
- for (auto item : curr->operands) {
- if (parent->isStatement(item)) {
- parent->setStatement(curr);
- break;
- }
- }
- }
void visitCallIndirect(CallIndirect* curr) {
// TODO: this is a pessimization that probably wants to get tweaked in
// the future. If none of the arguments have any side effects then we
@@ -1255,10 +1245,6 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, Function* func, IString resul
return visitGenericCall(curr, curr->target, curr->operands);
}
- Ref visitCallImport(CallImport* curr) {
- return visitGenericCall(curr, curr->target, curr->operands);
- }
-
Ref visitCallIndirect(CallIndirect* curr) {
// TODO: the codegen here is a pessimization of what the ideal codegen
// looks like. Eventually if necessary this should be tightened up in the
@@ -2197,7 +2183,7 @@ Ref Wasm2JSBuilder::makeAssertReturnNanFunc(SExpressionWasmBuilder& sexpBuilder,
Name testFuncName,
Name asmModule) {
Expression* actual = sexpBuilder.parseExpression(e[1]);
- Expression* body = wasmBuilder.makeCallImport("isNaN", {actual}, i32);
+ Expression* body = wasmBuilder.makeCall("isNaN", {actual}, i32);
std::unique_ptr<Function> testFunc(
wasmBuilder.makeFunction(
testFuncName,