diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-s-parser.h | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index abe0c4700..5acae1e6b 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -372,12 +372,22 @@ private: } } + bool isImport(Element& curr) { + for (Index i = 0; i < curr.size(); i++) { + auto& x = *curr[i]; + if (x.isList() && x.size() > 0 && x[0]->isStr() && x[0]->str() == IMPORT) return true; + } + return false; + } + void preParseImports(Element& curr) { IString id = curr[0]->str(); if (id == IMPORT) parseImport(curr); + if (id == FUNC && isImport(curr)) parseFunction(curr, true /* preParseImport */); } void parseModuleElement(Element& curr) { + if (isImport(curr)) return; // already done IString id = curr[0]->str(); if (id == START) return parseStart(curr); if (id == FUNC) return parseFunction(curr); @@ -454,7 +464,7 @@ private: return i; } - void parseFunction(Element& s) { + void parseFunction(Element& s, bool preParseImport = false) { size_t i = 1; Name name, exportName; i = parseFunctionNames(s, name, exportName); @@ -481,6 +491,7 @@ private: WasmType result = none; Name type; Block* autoBlock = nullptr; // we may need to add a block for the very top level + Name importModule, importBase; auto makeFunction = [&]() { currFunction = std::unique_ptr<Function>(Builder(wasm).makeFunction( name, @@ -530,7 +541,7 @@ private: } else if (id == TYPE) { Name name = curr[1]->str(); type = name; - if (!wasm.checkFunctionType(name)) throw ParseException("unknown function"); + if (!wasm.checkFunctionType(name)) throw ParseException("unknown function type"); FunctionType* type = wasm.getFunctionType(name); result = type->result; for (size_t j = 0; j < type->params.size(); j++) { @@ -539,6 +550,9 @@ private: typeParams.emplace_back(name, currType); currLocalTypes[name] = currType; } + } else if (id == IMPORT) { + importModule = curr[1]->str(); + importBase = curr[2]->str(); } else { // body if (typeParams.size() > 0 && params.size() == 0) { @@ -554,6 +568,26 @@ private: } } } + if (importModule.is()) { + // this is an import, actually + assert(preParseImport); + std::unique_ptr<Import> im = make_unique<Import>(); + im->name = name; + if (!im->name.is()) { + im->name = Name::fromInt(importCounter); + } + importCounter++; + im->module = importModule; + im->base = importBase; + im->kind = Import::Function; + im->functionType = wasm.getFunctionType(type); + wasm.addImport(im.release()); + assert(!currFunction); + currLocalTypes.clear(); + labelStack.clear(); + return; + } + assert(!preParseImport); if (brokeToAutoBlock) { ensureAutoBlock(); autoBlock->name = FAKE_RETURN; @@ -1520,10 +1554,11 @@ private: newStyle = false; // either (param..) or (result..) } } + Index newStyleInner = 1; if (s.size() > 3 && s[3]->isStr()) { im->name = s[i++]->str(); - } else if (newStyle) { - im->name = (*s[3])[1]->str(); + } else if (newStyle && (*s[3])[newStyleInner]->isStr()) { + im->name = (*s[3])[newStyleInner++]->str(); } else { im->name = Name::fromInt(importCounter); } @@ -1547,7 +1582,7 @@ private: im->base = s[i++]->str(); // parse internals Element& inner = newStyle ? *s[3] : s; - Index j = newStyle ? 2 : i; + Index j = newStyle ? newStyleInner : i; if (im->kind == Import::Function) { std::unique_ptr<FunctionType> type = make_unique<FunctionType>(); if (inner.size() > j) { |