summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h35
-rw-r--r--src/wasm-interpreter.h2
-rw-r--r--src/wasm-js.cpp2
-rw-r--r--src/wasm-s-parser.h34
-rw-r--r--src/wasm.h60
-rw-r--r--test/emcc_O2_hello_world.wast2
-rw-r--r--test/emcc_hello_world.wast2
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)