diff options
-rw-r--r-- | src/wasm-binary.h | 4 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 48 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 7 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary | 10 |
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) ) |