summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-s-parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-s-parser.cpp')
-rw-r--r--src/wasm/wasm-s-parser.cpp45
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());