diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-05-04 17:50:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-04 17:50:29 -0700 |
commit | 996cbd861c0cae4c942cc57b1915af5ea7b4d5f5 (patch) | |
tree | e0318d1a61c31a8498b8a68e3e175758800deb5b /src/wasm/wasm-binary.cpp | |
parent | ef4011c665f225f895861ce555c9347eb505c89f (diff) | |
download | binaryen-996cbd861c0cae4c942cc57b1915af5ea7b4d5f5.tar.gz binaryen-996cbd861c0cae4c942cc57b1915af5ea7b4d5f5.tar.bz2 binaryen-996cbd861c0cae4c942cc57b1915af5ea7b4d5f5.zip |
Parse the prototype nominal binary format (#4644)
In f124a11ca3 we removed support for the prototype nominal binary format
entirely, but that means that we can no longer parse older binary modules that
used that format. Fix this regression by restoring the ability to parse the
prototype binary format.
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 9dcdbb73d..60a4bad77 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1985,6 +1985,7 @@ void WasmBinaryBuilder::readTypes() { builder.createRecGroup(i, groupSize); form = getS32LEB(); } + std::optional<uint32_t> superIndex; if (form == BinaryConsts::EncodedType::Sub) { uint32_t supers = getU32LEB(); if (supers > 0) { @@ -1992,24 +1993,54 @@ void WasmBinaryBuilder::readTypes() { throwError("Invalid type definition with " + std::to_string(supers) + " supertypes"); } - uint32_t superIndex = getU32LEB(); - if (superIndex > builder.size()) { - throwError("Out of bounds supertype index " + - std::to_string(superIndex)); - } - builder[i].subTypeOf(builder[superIndex]); + superIndex = getU32LEB(); } form = getS32LEB(); } - if (form == BinaryConsts::EncodedType::Func) { + if (form == BinaryConsts::EncodedType::Func || + form == BinaryConsts::EncodedType::FuncSubtype) { builder[i] = readSignatureDef(); - } else if (form == BinaryConsts::EncodedType::Struct) { + } else if (form == BinaryConsts::EncodedType::Struct || + form == BinaryConsts::EncodedType::StructSubtype) { builder[i] = readStructDef(); - } else if (form == BinaryConsts::EncodedType::Array) { + } else if (form == BinaryConsts::EncodedType::Array || + form == BinaryConsts::EncodedType::ArraySubtype) { builder[i] = Array(readFieldDef()); } else { throwError("Bad type form " + std::to_string(form)); } + if (form == BinaryConsts::EncodedType::FuncSubtype || + form == BinaryConsts::EncodedType::StructSubtype || + form == BinaryConsts::EncodedType::ArraySubtype) { + int64_t super = getS64LEB(); // TODO: Actually s33 + if (super >= 0) { + superIndex = (uint32_t)super; + } else { + // Validate but otherwise ignore trivial supertypes. + HeapType basicSuper; + if (!getBasicHeapType(super, basicSuper)) { + throwError("Unrecognized supertype " + std::to_string(super)); + } + if (form == BinaryConsts::EncodedType::FuncSubtype) { + if (basicSuper != HeapType::func) { + throwError( + "The only allowed trivial supertype for functions is func"); + } + } else { + if (basicSuper != HeapType::data) { + throwError("The only allowed trivial supertype for structs and " + "arrays is data"); + } + } + } + } + if (superIndex) { + if (*superIndex > builder.size()) { + throwError("Out of bounds supertype index " + + std::to_string(*superIndex)); + } + builder[i].subTypeOf(builder[*superIndex]); + } } auto result = builder.build(); |