summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-binary.h4
-rw-r--r--src/wasm/wasm-binary.cpp48
-rw-r--r--src/wasm/wasm-s-parser.cpp7
-rw-r--r--test/heap-types.wast.fromBinary10
4 files changed, 62 insertions, 7 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 3f76a4421..9f298662b 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -430,7 +430,9 @@ enum Subsection {
NameMemory = 6,
NameGlobal = 7,
NameElem = 8,
- NameData = 9
+ NameData = 9,
+ // see: https://github.com/WebAssembly/gc/issues/193
+ NameField = 10
};
} // namespace UserSections
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index c0d7ab36e..c7096b154 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -795,6 +795,34 @@ void WasmBinaryWriter::writeNames() {
// TODO: label, type, and element names
// see: https://github.com/WebAssembly/extended-name-section
+ // GC field names
+ if (wasm->features.hasGC()) {
+ std::vector<HeapType> relevantTypes;
+ for (auto& type : types) {
+ if (type.isStruct() && wasm->typeNames.count(type) &&
+ !wasm->typeNames.at(type).fieldNames.empty()) {
+ relevantTypes.push_back(type);
+ }
+ }
+ if (!relevantTypes.empty()) {
+ auto substart =
+ startSubsection(BinaryConsts::UserSections::Subsection::NameField);
+ o << U32LEB(relevantTypes.size());
+ for (Index i = 0; i < relevantTypes.size(); i++) {
+ auto type = relevantTypes[i];
+ o << U32LEB(typeIndices[type]);
+ std::unordered_map<Index, Name>& fieldNames =
+ wasm->typeNames.at(type).fieldNames;
+ o << U32LEB(fieldNames.size());
+ for (auto& kv : fieldNames) {
+ o << U32LEB(kv.first);
+ writeEscapedName(kv.second.str);
+ }
+ }
+ finishSubsection(substart);
+ }
+ }
+
finishSection(start);
}
@@ -2908,6 +2936,26 @@ void WasmBinaryBuilder::readNames(size_t payloadLen) {
<< std::to_string(index) << std::endl;
}
}
+ } else if (nameType == BinaryConsts::UserSections::Subsection::NameField) {
+ auto numTypes = getU32LEB();
+ for (size_t i = 0; i < numTypes; i++) {
+ auto typeIndex = getU32LEB();
+ bool validType =
+ typeIndex < types.size() && types[typeIndex].isStruct();
+ if (!validType) {
+ std::cerr << "warning: invalid field index in name field section\n";
+ }
+ auto numFields = getU32LEB();
+ NameProcessor processor;
+ for (size_t i = 0; i < numFields; i++) {
+ auto fieldIndex = getU32LEB();
+ auto rawName = getInlineString();
+ auto name = processor.process(rawName);
+ if (validType) {
+ wasm.typeNames[types[typeIndex]].fieldNames[fieldIndex] = name;
+ }
+ }
+ }
} else {
std::cerr << "warning: unknown name subsection with id "
<< std::to_string(nameType) << " at " << pos << std::endl;
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 15b9cd5cb..1271ff603 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -826,7 +826,12 @@ void SExpressionWasmBuilder::preParseHeapTypes(Element& module) {
auto parseStructDef = [&](Element& elem, size_t typeIndex) {
FieldList fields;
for (Index i = 1; i < elem.size(); i++) {
- fields.emplace_back(parseField(elem[i], fieldNames[typeIndex][i - 1]));
+ Name name;
+ fields.emplace_back(parseField(elem[i], name));
+ if (name.is()) {
+ // Only add the name to the map if it exists.
+ fieldNames[typeIndex][i - 1] = name;
+ }
}
return Struct(fields);
};
diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary
index 75dcae823..2fe6adbe1 100644
--- a/test/heap-types.wast.fromBinary
+++ b/test/heap-types.wast.fromBinary
@@ -1,11 +1,11 @@
(module
- (type $struct.A (struct (field i32) (field f32) (field f64)))
+ (type $struct.A (struct (field i32) (field f32) (field $named f64)))
(type $struct.B (struct (field i8) (field (mut i16)) (field (ref null $struct.A)) (field (mut (ref null $struct.A)))))
(type $matrix (array (ref null $vector)))
(type $vector (array (mut f64)))
(type $anyref_=>_none (func (param anyref)))
(type $parent (struct ))
- (type $struct.C (struct (field (mut f32))))
+ (type $struct.C (struct (field $named-mut (mut f32))))
(type $none_=>_none (func))
(type $rtt_1_$parent_=>_none (func (param (rtt 1 $parent))))
(type $rtt_$parent_=>_none (func (param (rtt $parent))))
@@ -42,12 +42,12 @@
)
)
(drop
- (struct.get $struct.A 2
+ (struct.get $struct.A $named
(local.get $x)
)
)
(drop
- (struct.get $struct.A 2
+ (struct.get $struct.A $named
(local.get $x)
)
)
@@ -88,7 +88,7 @@
(i32.const 1)
)
)
- (struct.set $struct.C 0
+ (struct.set $struct.C $named-mut
(ref.null $struct.C)
(f32.const 100)
)