summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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());