diff options
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index df01a18d8..169470181 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -782,7 +782,12 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { builder.getTempTupleType(results)); }; - auto parseField = [&](Element* elem) { + // Maps type indexes to a mapping of field index => name. We store the data + // here while parsing as types have not been created yet. + std::unordered_map<size_t, std::unordered_map<Index, Name>> fieldNames; + + // Parses a field, and notes the name if one is found. + auto parseField = [&](Element* elem, Name& name) { Mutability mutable_ = Immutable; // elem is a list, containing either // TYPE @@ -790,7 +795,6 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { // (field TYPE) // or // (field $name TYPE) - Name name; if (elementStartsWith(elem, FIELD)) { if (elem->size() == 3) { name = (*elem)[1]->str(); @@ -803,28 +807,29 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { elem = (*elem)[1]; } if (elem->isStr()) { - // elem is a simple string name like "i32". It can be a normal wasm type, - // or one of the special types only available in fields. + // elem is a simple string name like "i32". It can be a normal wasm + // type, or one of the special types only available in fields. if (*elem == I8) { - return Field(Field::i8, mutable_, name); + return Field(Field::i8, mutable_); } else if (*elem == I16) { - return Field(Field::i16, mutable_, name); + return Field(Field::i16, mutable_); } } // Otherwise it's an arbitrary type. - return Field(parseValType(*elem), mutable_, name); + return Field(parseValType(*elem), mutable_); }; - auto parseStructDef = [&](Element& elem) { + auto parseStructDef = [&](Element& elem, size_t typeIndex) { FieldList fields; - for (auto it = ++elem.begin(); it != elem.end(); ++it) { - fields.emplace_back(parseField(*it)); + for (Index i = 1; i < elem.size(); i++) { + fields.emplace_back(parseField(elem[i], fieldNames[typeIndex][i - 1])); } return Struct(fields); }; auto parseArrayDef = [&](Element& elem) { - return Array(parseField(elem[1])); + Name unused; + return Array(parseField(elem[1], unused)); }; size_t index = 0; @@ -834,7 +839,8 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { if (kind == FUNC) { builder.setHeapType(index++, parseSignatureDef(def)); } else if (kind == STRUCT) { - builder.setHeapType(index++, parseStructDef(def)); + builder.setHeapType(index, parseStructDef(def, index)); + index++; } else if (kind == ARRAY) { builder.setHeapType(index++, parseArrayDef(def)); } else { @@ -846,14 +852,19 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) { for (auto& pair : typeIndices) { auto name = pair.first; - auto type = types[pair.second]; + auto index = pair.second; + auto type = types[index]; // A type may appear in the type section more than once, but we canonicalize // types internally, so there will be a single name chosen for that type. Do // so determistically. if (wasm.typeNames.count(type) && wasm.typeNames[type].name.str < name) { continue; } - wasm.typeNames[type].name = name; + auto& currTypeNames = wasm.typeNames[type]; + currTypeNames.name = name; + if (type.isStruct()) { + currTypeNames.fieldNames = fieldNames[index]; + } } } @@ -2410,12 +2421,14 @@ Index SExpressionWasmBuilder::getStructIndex(const HeapType& type, Element& s) { auto name = s.str(); auto struct_ = type.getStruct(); auto& fields = struct_.fields; + const auto& fieldNames = wasm.typeNames[type].fieldNames; for (Index i = 0; i < fields.size(); i++) { - if (fields[i].name == name) { + auto it = fieldNames.find(i); + if (it != fieldNames.end() && it->second == name) { return i; } } - throw ParseException("bad struct name", s.line, s.col); + throw ParseException("bad struct field name", s.line, s.col); } // this is a numeric index return atoi(s.c_str()); |