summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index db253fa6e..a4df4ed16 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -219,8 +219,11 @@ void WasmBinaryWriter::writeTypes() {
for (Index i = 0; i < types.size(); ++i) {
auto type = types[i];
BYN_TRACE("write " << type << std::endl);
+ HeapType super;
+ bool hasSuper = type.getSuperType(super);
if (type.isSignature()) {
- o << S32LEB(BinaryConsts::EncodedType::Func);
+ o << S32LEB(hasSuper ? BinaryConsts::EncodedType::FuncExtending
+ : BinaryConsts::EncodedType::Func);
auto sig = type.getSignature();
for (auto& sigType : {sig.params, sig.results}) {
o << U32LEB(sigType.size());
@@ -229,18 +232,23 @@ void WasmBinaryWriter::writeTypes() {
}
}
} else if (type.isStruct()) {
- o << S32LEB(BinaryConsts::EncodedType::Struct);
+ o << S32LEB(hasSuper ? BinaryConsts::EncodedType::StructExtending
+ : BinaryConsts::EncodedType::Struct);
auto fields = type.getStruct().fields;
o << U32LEB(fields.size());
for (const auto& field : fields) {
writeField(field);
}
} else if (type.isArray()) {
- o << S32LEB(BinaryConsts::EncodedType::Array);
+ o << S32LEB(hasSuper ? BinaryConsts::EncodedType::ArrayExtending
+ : BinaryConsts::EncodedType::Array);
writeField(type.getArray().element);
} else {
WASM_UNREACHABLE("TODO GC type writing");
}
+ if (hasSuper) {
+ o << U32LEB(getTypeIndex(super));
+ }
}
finishSection(start);
}
@@ -1901,15 +1909,27 @@ void WasmBinaryBuilder::readTypes() {
for (size_t i = 0; i < numTypes; i++) {
BYN_TRACE("read one\n");
auto form = getS32LEB();
- if (form == BinaryConsts::EncodedType::Func) {
+ if (form == BinaryConsts::EncodedType::Func ||
+ form == BinaryConsts::EncodedType::FuncExtending) {
builder[i] = readSignatureDef();
- } else if (form == BinaryConsts::EncodedType::Struct) {
+ } else if (form == BinaryConsts::EncodedType::Struct ||
+ form == BinaryConsts::EncodedType::StructExtending) {
builder[i] = readStructDef();
- } else if (form == BinaryConsts::EncodedType::Array) {
+ } else if (form == BinaryConsts::EncodedType::Array ||
+ form == BinaryConsts::EncodedType::ArrayExtending) {
builder[i] = Array(readFieldDef());
} else {
throwError("bad type form " + std::to_string(form));
}
+ if (form == BinaryConsts::EncodedType::FuncExtending ||
+ form == BinaryConsts::EncodedType::StructExtending ||
+ form == BinaryConsts::EncodedType::ArrayExtending) {
+ auto superIndex = getU32LEB();
+ if (superIndex >= numTypes) {
+ throwError("bad supertype index " + std::to_string(superIndex));
+ }
+ builder[i].subTypeOf(builder[superIndex]);
+ }
}
types = builder.build();