diff options
-rw-r--r-- | src/passes/Print.cpp | 15 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 16 | ||||
-rw-r--r-- | test/heap-types.wast | 8 | ||||
-rw-r--r-- | test/heap-types.wast.from-wast | 13 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary | 3 | ||||
-rw-r--r-- | test/heap-types.wast.fromBinary.noDebugInfo | 3 |
6 files changed, 58 insertions, 0 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 67deac35c..b7b7e1320 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1840,7 +1840,18 @@ struct PrintExpressionContents o << "with_rtt "; printHeapTypeName(o, curr->rtt->type.getHeapType()); } + void printUnreachableReplacement() { + // If we cannot print a valid unreachable instruction (say, a struct.get, + // where if the ref is unreachable, we don't know what heap type to print), + // then print the children in a block, which is good enough as this + // instruction is never reached anyhow. + printMedium(o, "block "); + } void visitStructGet(StructGet* curr) { + if (curr->ref->type == Type::unreachable) { + printUnreachableReplacement(); + return; + } const auto& field = curr->ref->type.getHeapType().getStruct().fields[curr->index]; if (field.type == Type::i32 && field.packedType != Field::not_packed) { @@ -1857,6 +1868,10 @@ struct PrintExpressionContents o << curr->index; } void visitStructSet(StructSet* curr) { + if (curr->ref->type == Type::unreachable) { + printUnreachableReplacement(); + return; + } printMedium(o, "struct.set "); printHeapTypeName(o, curr->ref->type.getHeapType()); o << ' '; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 6a1b72476..a9a69b244 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2296,6 +2296,14 @@ void FunctionValidator::visitStructGet(StructGet* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.get requires gc to be enabled"); + if (curr->ref->type == Type::unreachable) { + return; + } + if (!shouldBeTrue(curr->ref->type.isStruct(), + curr->ref, + "struct.get ref must be a struct")) { + return; + } const auto& fields = curr->ref->type.getHeapType().getStruct().fields; shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field"); auto field = fields[curr->index]; @@ -2315,6 +2323,14 @@ void FunctionValidator::visitStructSet(StructSet* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.set requires gc to be enabled"); + if (curr->ref->type == Type::unreachable) { + return; + } + if (!shouldBeTrue(curr->ref->type.isStruct(), + curr->ref, + "struct.set ref must be a struct")) { + return; + } if (curr->ref->type != Type::unreachable) { const auto& fields = curr->ref->type.getHeapType().getStruct().fields; shouldBeTrue(curr->index < fields.size(), curr, "bad struct.get field"); diff --git a/test/heap-types.wast b/test/heap-types.wast index 7558e1676..87d751691 100644 --- a/test/heap-types.wast +++ b/test/heap-types.wast @@ -226,4 +226,12 @@ ) ) ) + (func $unreachables + (drop + (struct.get $struct.A 0 (unreachable)) + ) + (drop + (struct.set $struct.A 0 (unreachable) (unreachable)) + ) + ) ) diff --git a/test/heap-types.wast.from-wast b/test/heap-types.wast.from-wast index a93bd0d90..458842a7b 100644 --- a/test/heap-types.wast.from-wast +++ b/test/heap-types.wast.from-wast @@ -282,4 +282,17 @@ ) ) ) + (func $unreachables + (drop + (block + (unreachable) + ) + ) + (drop + (block + (unreachable) + (unreachable) + ) + ) + ) ) diff --git a/test/heap-types.wast.fromBinary b/test/heap-types.wast.fromBinary index d8ddb48ed..5e48da116 100644 --- a/test/heap-types.wast.fromBinary +++ b/test/heap-types.wast.fromBinary @@ -281,5 +281,8 @@ ) ) ) + (func $unreachables + (unreachable) + ) ) diff --git a/test/heap-types.wast.fromBinary.noDebugInfo b/test/heap-types.wast.fromBinary.noDebugInfo index 63f7e132e..d49d5fa1e 100644 --- a/test/heap-types.wast.fromBinary.noDebugInfo +++ b/test/heap-types.wast.fromBinary.noDebugInfo @@ -281,5 +281,8 @@ ) ) ) + (func $8 + (unreachable) + ) ) |