summaryrefslogtreecommitdiff
path: root/src/wasm-s-parser.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r--src/wasm-s-parser.h52
1 files changed, 39 insertions, 13 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index f9a43e69b..a914b6598 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -275,6 +275,8 @@ class SExpressionWasmBuilder {
Module& wasm;
MixedArena& allocator;
std::vector<Name> functionNames;
+ std::vector<Name> functionTypeNames;
+ std::vector<Name> globalNames;
int functionCounter;
int globalCounter;
std::map<Name, WasmType> functionTypes; // we need to know function return types before we parse their contents
@@ -346,8 +348,8 @@ private:
if (curr.size() > 2) throw ParseException("invalid result arity", curr.line, curr.col);
functionTypes[name] = stringToWasmType(curr[1]->str());
} else if (id == TYPE) {
- Name typeName = curr[1]->str();
- if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function", curr.line, curr.col);
+ Name typeName = getFunctionTypeName(*curr[1]);
+ if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function type", curr.line, curr.col);
type = wasm.getFunctionType(typeName);
functionTypes[name] = type->result;
} else if (id == PARAM && curr.size() > 1) {
@@ -377,6 +379,8 @@ private:
}
}
if (need) {
+ functionType->name = Name::fromInt(wasm.functionTypes.size());
+ functionTypeNames.push_back(functionType->name);
wasm.addFunctionType(functionType.release());
}
}
@@ -441,11 +445,22 @@ private:
} else {
// index
size_t offset = atoi(s.str().c_str());
- if (offset >= functionNames.size()) throw ParseException("unknown function");
+ if (offset >= functionNames.size()) throw ParseException("unknown function in getFunctionName");
return functionNames[offset];
}
}
+ Name getFunctionTypeName(Element& s) {
+ if (s.dollared()) {
+ return s.str();
+ } else {
+ // index
+ size_t offset = atoi(s.str().c_str());
+ if (offset >= functionTypeNames.size()) throw ParseException("unknown function type in getFunctionTypeName");
+ return functionTypeNames[offset];
+ }
+ }
+
void parseStart(Element& s) {
wasm.addStart(getFunctionName(*s[1]));
}
@@ -484,9 +499,18 @@ private:
size_t i = 1;
Name name, exportName;
i = parseFunctionNames(s, name, exportName);
- if (!name.is()) {
- // unnamed, use an index
- name = Name::fromInt(functionCounter);
+ if (!preParseImport) {
+ if (!name.is()) {
+ // unnamed, use an index
+ name = Name::fromInt(functionCounter);
+ }
+ functionCounter++;
+ } else {
+ // just preparsing, functionCounter was incremented by preParseFunctionType
+ if (!name.is()) {
+ // unnamed, use an index
+ name = functionNames[functionCounter - 1];
+ }
}
if (exportName.is()) {
auto ex = make_unique<Export>();
@@ -496,7 +520,6 @@ private:
if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col);
wasm.addExport(ex.release());
}
- functionCounter++;
Expression* body = nullptr;
localIndex = 0;
otherIndex = 0;
@@ -555,7 +578,7 @@ private:
if (curr.size() > 2) throw ParseException("invalid result arity", curr.line, curr.col);
result = stringToWasmType(curr[1]->str());
} else if (id == TYPE) {
- Name name = curr[1]->str();
+ Name name = getFunctionTypeName(*curr[1]);
type = name;
if (!wasm.checkFunctionType(name)) throw ParseException("unknown function type");
FunctionType* type = wasm.getFunctionType(name);
@@ -601,9 +624,6 @@ private:
assert(preParseImport);
std::unique_ptr<Import> im = make_unique<Import>();
im->name = name;
- if (!im->name.is()) {
- im->name = name;
- }
im->module = importModule;
im->base = importBase;
im->kind = Import::Function;
@@ -629,7 +649,6 @@ private:
if (currFunction->result != result) throw ParseException("bad func declaration", s.line, s.col);
currFunction->body = body;
currFunction->type = type;
-
wasm.addFunction(currFunction.release());
currLocalTypes.clear();
labelStack.clear();
@@ -1293,7 +1312,7 @@ private:
}
Expression* makeCall(Element& s) {
- auto target = s[1]->str();
+ auto target = getFunctionName(*s[1]);
auto* import = wasm.checkImport(target);
if (import && import->kind == Import::Function) {
auto ret = allocator.alloc<CallImport>();
@@ -1604,8 +1623,10 @@ private:
if (!im->name.is()) {
if (im->kind == Import::Function) {
im->name = Name::fromInt(functionCounter++);
+ functionNames.push_back(im->name);
} else if (im->kind == Import::Global) {
im->name = Name::fromInt(globalCounter++);
+ globalNames.push_back(im->name);
} else if (im->kind == Import::Memory) {
im->name = Name::fromInt(0);
} else if (im->kind == Import::Table) {
@@ -1700,6 +1721,7 @@ private:
global->name = Name::fromInt(globalCounter);
}
globalCounter++;
+ globalNames.push_back(global->name);
bool mutable_ = false;
WasmType type = none;
bool exported = false;
@@ -1861,6 +1883,10 @@ private:
type->result = stringToWasmType(curr[1]->str());
}
}
+ if (!type->name.is()) {
+ type->name = Name::fromInt(wasm.functionTypes.size());
+ }
+ functionTypeNames.push_back(type->name);
wasm.addFunctionType(type.release());
}
};