summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2022-05-04 17:50:29 -0700
committerGitHub <noreply@github.com>2022-05-04 17:50:29 -0700
commit996cbd861c0cae4c942cc57b1915af5ea7b4d5f5 (patch)
treee0318d1a61c31a8498b8a68e3e175758800deb5b /src/wasm/wasm-binary.cpp
parentef4011c665f225f895861ce555c9347eb505c89f (diff)
downloadbinaryen-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.cpp49
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();