diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-type.h | 11 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 45 |
2 files changed, 33 insertions, 23 deletions
diff --git a/src/wasm-type.h b/src/wasm-type.h index 1b7ec5081..3dcd53d0e 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -405,12 +405,11 @@ struct Field { i16, } packedType; // applicable iff type=i32 Mutability mutable_; - Name name; - Field(Type type, Mutability mutable_, Name name = Name()) - : type(type), packedType(not_packed), mutable_(mutable_), name(name) {} - Field(PackedType packedType, Mutability mutable_, Name name = Name()) - : type(Type::i32), packedType(packedType), mutable_(mutable_), name(name) {} + Field(Type type, Mutability mutable_) + : type(type), packedType(not_packed), mutable_(mutable_) {} + Field(PackedType packedType, Mutability mutable_) + : type(Type::i32), packedType(packedType), mutable_(mutable_) {} constexpr bool isPacked() const { if (packedType != not_packed) { @@ -421,8 +420,6 @@ struct Field { } bool operator==(const Field& other) const { - // Note that the name is not checked here - it is pure metadata for printing - // purposes only. return type == other.type && packedType == other.packedType && mutable_ == other.mutable_; } 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()); |