summaryrefslogtreecommitdiff
path: root/src/ir/module-utils.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/ir/module-utils.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/ir/module-utils.h')
-rw-r--r--src/ir/module-utils.h102
1 files changed, 84 insertions, 18 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 4205514e5..1d0512401 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -25,30 +25,45 @@ namespace wasm {
namespace ModuleUtils {
// Computes the indexes in a wasm binary, i.e., with function imports
-// and function implementations sharing a single index space, etc.
+// and function implementations sharing a single index space, etc.,
+// and with the imports first (the Module's functions and globals
+// arrays are not assumed to be in a particular order, so we can't
+// just use them directly).
struct BinaryIndexes {
std::unordered_map<Name, Index> functionIndexes;
std::unordered_map<Name, Index> globalIndexes;
BinaryIndexes(Module& wasm) {
- for (Index i = 0; i < wasm.imports.size(); i++) {
- auto& import = wasm.imports[i];
- if (import->kind == ExternalKind::Function) {
- auto index = functionIndexes.size();
- functionIndexes[import->name] = index;
- } else if (import->kind == ExternalKind::Global) {
- auto index = globalIndexes.size();
- globalIndexes[import->name] = index;
+ auto addGlobal = [&](Global* curr) {
+ auto index = globalIndexes.size();
+ globalIndexes[curr->name] = index;
+ };
+ for (auto& curr : wasm.globals) {
+ if (curr->imported()) {
+ addGlobal(curr.get());
+ }
+ }
+ for (auto& curr : wasm.globals) {
+ if (!curr->imported()) {
+ addGlobal(curr.get());
}
}
- for (Index i = 0; i < wasm.functions.size(); i++) {
+ assert(globalIndexes.size() == wasm.globals.size());
+ auto addFunction = [&](Function* curr) {
auto index = functionIndexes.size();
- functionIndexes[wasm.functions[i]->name] = index;
+ functionIndexes[curr->name] = index;
+ };
+ for (auto& curr : wasm.functions) {
+ if (curr->imported()) {
+ addFunction(curr.get());
+ }
}
- for (Index i = 0; i < wasm.globals.size(); i++) {
- auto index = globalIndexes.size();
- globalIndexes[wasm.globals[i]->name] = index;
+ for (auto& curr : wasm.functions) {
+ if (!curr->imported()) {
+ addFunction(curr.get());
+ }
}
+ assert(functionIndexes.size() == wasm.functions.size());
}
};
@@ -63,21 +78,34 @@ inline Function* copyFunction(Function* func, Module& out) {
ret->localIndices = func->localIndices;
ret->debugLocations = func->debugLocations;
ret->body = ExpressionManipulator::copy(func->body, out);
+ ret->module = func->module;
+ ret->base = func->base;
// TODO: copy Stack IR
assert(!func->stackIR);
out.addFunction(ret);
return ret;
}
+inline Global* copyGlobal(Global* global, Module& out) {
+ auto* ret = new Global();
+ ret->name = global->name;
+ ret->type = global->type;
+ ret->mutable_ = global->mutable_;
+ if (global->imported()) {
+ ret->init = nullptr;
+ } else {
+ ret->init = ExpressionManipulator::copy(global->init, out);
+ }
+ out.addGlobal(ret);
+ return ret;
+}
+
inline void copyModule(Module& in, Module& out) {
// we use names throughout, not raw points, so simple copying is fine
// for everything *but* expressions
for (auto& curr : in.functionTypes) {
out.addFunctionType(new FunctionType(*curr));
}
- for (auto& curr : in.imports) {
- out.addImport(new Import(*curr));
- }
for (auto& curr : in.exports) {
out.addExport(new Export(*curr));
}
@@ -85,7 +113,7 @@ inline void copyModule(Module& in, Module& out) {
copyFunction(curr.get(), out);
}
for (auto& curr : in.globals) {
- out.addGlobal(new Global(*curr));
+ copyGlobal(curr.get(), out);
}
out.table = in.table;
for (auto& segment : out.table.segments) {
@@ -100,6 +128,44 @@ inline void copyModule(Module& in, Module& out) {
out.debugInfoFileNames = in.debugInfoFileNames;
}
+// Convenient iteration over imported/non-imported functions/globals
+
+template<typename T>
+inline void iterImportedGlobals(Module& wasm, T visitor) {
+ for (auto& import : wasm.globals) {
+ if (import->imported()) {
+ visitor(import.get());
+ }
+ }
+}
+
+template<typename T>
+inline void iterDefinedGlobals(Module& wasm, T visitor) {
+ for (auto& import : wasm.globals) {
+ if (!import->imported()) {
+ visitor(import.get());
+ }
+ }
+}
+
+template<typename T>
+inline void iterImportedFunctions(Module& wasm, T visitor) {
+ for (auto& import : wasm.functions) {
+ if (import->imported()) {
+ visitor(import.get());
+ }
+ }
+}
+
+template<typename T>
+inline void iterDefinedFunctions(Module& wasm, T visitor) {
+ for (auto& import : wasm.functions) {
+ if (!import->imported()) {
+ visitor(import.get());
+ }
+ }
+}
+
} // namespace ModuleUtils
} // namespace wasm