summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h4
-rw-r--r--src/wasm/wasm-binary.cpp49
2 files changed, 44 insertions, 9 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 62c2f7af2..12deeacab 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -382,6 +382,10 @@ enum EncodedType {
Struct = -0x21, // 0x5f
Array = -0x22, // 0x5e
Sub = -0x30, // 0x50
+ // prototype nominal forms we still parse
+ FuncSubtype = -0x23, // 0x5d
+ StructSubtype = -0x24, // 0x5c
+ ArraySubtype = -0x25, // 0x5b
// isorecursive recursion groups
Rec = -0x31, // 0x4f
// block_type
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();