summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-02-24 22:29:45 +0000
committerGitHub <noreply@github.com>2021-02-24 14:29:45 -0800
commit4311e46cc7ae7dd998698e5d15371b605c663bc0 (patch)
tree9de793569862a547f791062f25ad3e5d4b68440f /src
parent6656dfaf9c52b1dda3426b6d7e2a1db3ec3617e5 (diff)
downloadbinaryen-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')
-rw-r--r--src/wasm-type.h11
-rw-r--r--src/wasm/wasm-s-parser.cpp45
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());