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.cpp39
1 files changed, 34 insertions, 5 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index d9b7e1a84..639f4b848 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -236,6 +236,19 @@ void WasmBinaryWriter::writeTypes() {
lastGroup = currGroup;
}
}
+
+ // As a temporary measure, detect which types have subtypes and always use
+ // `sub` or `sub final` for these types. The standard says that types without
+ // `sub` or `sub final` are final, but we currently treat them as non-final.
+ // To avoid unsafe ambiguity, only use the short form for types that it would
+ // be safe to treat as final, i.e. types without subtypes.
+ std::vector<bool> hasSubtypes(indexedTypes.types.size());
+ for (auto type : indexedTypes.types) {
+ if (auto super = type.getSuperType()) {
+ hasSubtypes[indexedTypes.indices[*super]] = true;
+ }
+ }
+
BYN_TRACE("== writeTypes\n");
auto start = startSection(BinaryConsts::Section::Type);
o << U32LEB(numGroups);
@@ -251,10 +264,21 @@ void WasmBinaryWriter::writeTypes() {
lastGroup = currGroup;
// Emit the type definition.
BYN_TRACE("write " << type << std::endl);
- if (auto super = type.getSuperType()) {
- // Subtype constructor and vector of 1 supertype.
- o << S32LEB(BinaryConsts::EncodedType::Sub) << U32LEB(1);
- writeHeapType(*super);
+ auto super = type.getSuperType();
+ // TODO: Use the binary shorthand for final types once we parse MVP
+ // signatures as final.
+ if (type.isFinal() || super || hasSubtypes[i]) {
+ if (type.isFinal()) {
+ o << S32LEB(BinaryConsts::EncodedType::SubFinal);
+ } else {
+ o << S32LEB(BinaryConsts::EncodedType::Sub);
+ }
+ if (super) {
+ o << U32LEB(1);
+ writeHeapType(*super);
+ } else {
+ o << U32LEB(0);
+ }
}
if (type.isSignature()) {
o << S32LEB(BinaryConsts::EncodedType::Func);
@@ -2210,7 +2234,12 @@ void WasmBinaryReader::readTypes() {
form = getS32LEB();
}
std::optional<uint32_t> superIndex;
- if (form == BinaryConsts::EncodedType::Sub) {
+ if (form == BinaryConsts::EncodedType::Sub ||
+ form == BinaryConsts::EncodedType::SubFinal) {
+ if (form == BinaryConsts::EncodedType::SubFinal) {
+ // TODO: Interpret type definitions without any `sub` as final as well.
+ builder[i].setFinal();
+ }
uint32_t supers = getU32LEB();
if (supers > 0) {
if (supers != 1) {