diff options
author | Alon Zakai <azakai@google.com> | 2021-02-24 22:29:45 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-24 14:29:45 -0800 |
commit | 4311e46cc7ae7dd998698e5d15371b605c663bc0 (patch) | |
tree | 9de793569862a547f791062f25ad3e5d4b68440f | |
parent | 6656dfaf9c52b1dda3426b6d7e2a1db3ec3617e5 (diff) | |
download | binaryen-4311e46cc7ae7dd998698e5d15371b605c663bc0.tar.gz binaryen-4311e46cc7ae7dd998698e5d15371b605c663bc0.tar.bz2 binaryen-4311e46cc7ae7dd998698e5d15371b605c663bc0.zip |
[Wasm GC] Move struct field names to their proper place (#3600)
#3591 adds type and field names to the Module object, and used that
for the type but not the fields. This uses it for the fields as well, and removes
the "name" field from the Field objects itself, completing the refactoring.
After this, binary format support can be added as a proper replacement for
#3589
-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()); |