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.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();