diff options
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(); |