diff options
-rw-r--r-- | src/asm2wasm.h | 35 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 2 | ||||
-rw-r--r-- | src/wasm-js.cpp | 2 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 34 | ||||
-rw-r--r-- | src/wasm.h | 60 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.wast | 2 | ||||
-rw-r--r-- | test/emcc_hello_world.wast | 2 |
7 files changed, 93 insertions, 44 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index e9b0ce2c6..a2d68369f 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -174,7 +174,7 @@ private: str += getSigFromType(operand->type); } IString sig(str.c_str(), false); - if (wasm.functionTypes.find(sig) == wasm.functionTypes.end()) { + if (wasm.functionTypesMap.find(sig) == wasm.functionTypesMap.end()) { // add new type auto type = allocator.alloc<FunctionType>(); type->name = sig; @@ -182,10 +182,9 @@ private: for (auto operand : operands) { type->params.push_back(operand->type); } - wasm.functionTypes[sig] = type; - assert(wasm.functionTypes.find(sig) != wasm.functionTypes.end()); + wasm.addFunctionType(type); } - return wasm.functionTypes[sig]; + return wasm.functionTypesMap[sig]; } public: @@ -367,19 +366,19 @@ void Asm2WasmBuilder::processAsm(Ref ast) { assert(module[0] == NAME); moduleName = module[1]->getIString(); } - Import import; - import.name = name; - import.module = moduleName; - import.base = imported[2]->getIString(); + auto import = allocator.alloc<Import>(); + import->name = name; + import->module = moduleName; + import->base = imported[2]->getIString(); // special-case some asm builtins - if (import.module == GLOBAL && (import.base == NAN_ || import.base == INFINITY_)) { + if (import->module == GLOBAL && (import->base == NAN_ || import->base == INFINITY_)) { type = WasmType::f64; } if (type != WasmType::none) { // wasm has no imported constants, so allocate a global, and we need to write the value into that - allocateGlobal(name, type, true, import.module, import.base); + allocateGlobal(name, type, true, import->module, import->base); } else { - wasm.imports.emplace(name, import); + wasm.addImport(import); } }; @@ -481,9 +480,9 @@ void Asm2WasmBuilder::processAsm(Ref ast) { IString key = pair[0]->getIString(); Ref value = pair[1]; assert(value[0] == NAME); - Export export_; - export_.name = key; - export_.value = value[1]->getIString(); + auto export_ = allocator.alloc<Export>(); + export_->name = key; + export_->value = value[1]->getIString(); wasm.exports.push_back(export_); } } @@ -493,9 +492,9 @@ void Asm2WasmBuilder::processAsm(Ref ast) { std::vector<IString> toErase; - for (auto& pair : wasm.imports) { + for (auto& pair : wasm.importsMap) { IString name = pair.first; - Import& import = pair.second; + Import& import = *pair.second; if (importedFunctionTypes.find(name) != importedFunctionTypes.end()) { import.type = importedFunctionTypes[name]; } else { @@ -505,7 +504,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { } for (auto curr : toErase) { - wasm.imports.erase(curr); + wasm.removeImport(curr); } } @@ -799,7 +798,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { return ret; } Call* ret; - if (wasm.imports.find(name) != wasm.imports.end()) { + if (wasm.importsMap.find(name) != wasm.importsMap.end()) { #ifndef __EMSCRIPTEN__ // no imports yet in reference interpreter, fake it AsmType asmType = detectAsmType(astStackHelper.getParent(), &asmData); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 0de04712a..c2faa1df4 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -232,7 +232,7 @@ public: LiteralList arguments; Flow flow = generateArguments(curr->operands, arguments); if (flow.breaking()) return flow; - return instance.externalInterface->callImport(&instance.wasm.imports[curr->target], arguments); + return instance.externalInterface->callImport(instance.wasm.importsMap[curr->target], arguments); } Flow visitCallIndirect(CallIndirect *curr) override { NOTE_ENTER("CallIndirect"); diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index f26d1c4c1..44c5cb099 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -75,7 +75,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { Module['tempArguments'] = Array.prototype.slice.call(arguments); return Module['_call_from_js']($0); }; - }, curr.name.str); + }, curr->name.str); } if (debug) std::cerr << "creating instance...\n"; diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 6beadcf8b..28f30a579 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -757,8 +757,8 @@ private: Expression* makeCallIndirect(Element& s) { auto ret = allocator.alloc<CallIndirect>(); IString type = s[1]->str(); - assert(wasm.functionTypes.find(type) != wasm.functionTypes.end()); - ret->type = wasm.functionTypes[type]; + assert(wasm.functionTypesMap.find(type) != wasm.functionTypesMap.end()); + ret->type = wasm.functionTypesMap[type]; ret->target = parseExpression(s[2]); parseCallOperands(s, 3, ret); return ret; @@ -799,27 +799,27 @@ private: } void parseExport(Element& s) { - Export ex; - ex.name = s[1]->str(); - ex.value = s[2]->str(); - wasm.exports.push_back(ex); + auto ex = allocator.alloc<Export>(); + ex->name = s[1]->str(); + ex->value = s[2]->str(); + wasm.addExport(ex); } void parseImport(Element& s) { - Import im; - im.name = s[1]->str(); - im.module = s[2]->str(); - im.base = s[3]->str(); + auto im = allocator.alloc<Import>(); + im->name = s[1]->str(); + im->module = s[2]->str(); + im->base = s[3]->str(); Element& params = *s[4]; if (params[0]->str() == PARAM) { for (size_t i = 1; i < params.size(); i++) { - im.type.params.push_back(stringToWasmType(params[i]->str())); + im->type.params.push_back(stringToWasmType(params[i]->str())); } } else { onError(); } assert(s.size() == 5); - wasm.imports[im.name] = im; + wasm.addImport(im); } void parseTable(Element& s) { @@ -830,8 +830,12 @@ private: void parseType(Element& s) { auto type = allocator.alloc<FunctionType>(); - type->name = s[1]->str(); - Element& func = *s[2]; + size_t i = 1; + if (s[i]->isStr()) { + type->name = s[i]->str(); + i++; + } + Element& func = *s[i]; assert(func.isList()); for (size_t i = 1; i < func.size(); i++) { Element& curr = *func[i]; @@ -843,7 +847,7 @@ private: type->result = stringToWasmType(curr[1]->str()); } } - wasm.functionTypes[type->name] = type; + wasm.addFunctionType(type); } }; diff --git a/src/wasm.h b/src/wasm.h index 0ffca478b..9cd2a1457 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -846,15 +846,61 @@ public: class Module { public: // wasm contents - std::map<Name, FunctionType*> functionTypes; - std::map<Name, Import> imports; - std::vector<Export> exports; + std::vector<FunctionType*> functionTypes; + std::vector<Import*> imports; + std::vector<Export*> exports; Table table; std::vector<Function*> functions; + + // utility maps + std::map<Name, FunctionType*> functionTypesMap; + std::map<Name, Import*> importsMap; + std::map<Name, Export*> exportsMap; + std::map<Name, Function*> functionsMap; + Memory memory; Module() {} + void addFunctionType(FunctionType* curr) { + if (!curr->name) { + curr->name = cashew::IString(std::to_string(functionTypes.size()).c_str(), false); + } + functionTypes.push_back(curr); + functionTypesMap[curr->name] = curr; + } + void addImport(Import* curr) { + if (!curr->name) { + curr->name = cashew::IString(std::to_string(imports.size()).c_str(), false); + } + imports.push_back(curr); + importsMap[curr->name] = curr; + } + void addExport(Export* curr) { + if (!curr->name) { + curr->name = cashew::IString(std::to_string(exports.size()).c_str(), false); + } + exports.push_back(curr); + exportsMap[curr->name] = curr; + } + void addFunction(Function* curr) { + if (!curr->name) { + curr->name = cashew::IString(std::to_string(functions.size()).c_str(), false); + } + functions.push_back(curr); + functionsMap[curr->name] = curr; + } + + void removeImport(Name name) { + for (size_t i = 0; i < imports.size(); i++) { + if (imports[i]->name == name) { + imports.erase(imports.begin() + i); + break; + } + } + importsMap.erase(name); + } + friend std::ostream& operator<<(std::ostream &o, Module module) { unsigned indent = 0; printOpening(o, "module", true); @@ -868,17 +914,17 @@ public: o << ")\n"; for (auto& curr : module.functionTypes) { doIndent(o, indent); - curr.second->print(o, indent, true); + curr->print(o, indent, true); o << '\n'; } for (auto& curr : module.imports) { doIndent(o, indent); - curr.second.print(o, indent); + curr->print(o, indent); o << '\n'; } for (auto& curr : module.exports) { doIndent(o, indent); - curr.print(o, indent); + curr->print(o, indent); o << '\n'; } if (module.table.names.size() > 0) { @@ -897,7 +943,7 @@ public: bool validate() { for (auto& exp : exports) { - Name name = exp.name; + Name name = exp->name; bool found = false; for (auto& func : functions) { if (func->name == name) { diff --git a/test/emcc_O2_hello_world.wast b/test/emcc_O2_hello_world.wast index 9aae649a1..8392dabea 100644 --- a/test/emcc_O2_hello_world.wast +++ b/test/emcc_O2_hello_world.wast @@ -1,7 +1,7 @@ (module (memory 16777216 16777216) - (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) (export "_free" $_free) (export "_main" $_main) diff --git a/test/emcc_hello_world.wast b/test/emcc_hello_world.wast index 6ed6b3d65..80fb3908b 100644 --- a/test/emcc_hello_world.wast +++ b/test/emcc_hello_world.wast @@ -1,7 +1,7 @@ (module (memory 16777216 16777216) - (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) (export "_i64Subtract" $_i64Subtract) (export "_free" $_free) |