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 /src/wasm/wasm-s-parser.cpp | |
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
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()); |