Commit 7a2b7597 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[wasm] Fix initialization of block merge types

The merge values of a block have to be initialized to their
static types, even if the actual values on the stack have
subtypes of the loop's static type.

Drive-by cleanup: drop some unneeded manual {TestModuleBuilder}
instantiations from existing tests. The test fixture provides
one anyway.

Bug: chromium:1234453
Change-Id: I39c7eae4b6a6d5124f29be92da5ee92ff7e20e57
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3068948Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76087}
parent d36cc695
......@@ -3582,27 +3582,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
InitMerge(&c->end_merge, imm.out_arity(), [pc, &imm](uint32_t i) {
return Value{pc, imm.out_type(i)};
});
InitMerge(&c->start_merge, imm.in_arity(),
#ifdef DEBUG
[this, pc, &imm, args](uint32_t i) {
#else
[pc, &imm, args](uint32_t i) {
#endif
// The merge needs to be instantiated with Values of the correct
// type even in the presence of bottom values (i.e. in
// unreachable code). Since bottom Values will never be used for
// code generation, we can safely instantiate new ones in that
// case.
DCHECK_IMPLIES(current_code_reachable_and_ok_,
args[i].type != kWasmBottom);
// Warning: Do not use a ternary operator here, as gcc bugs out
// (as of version 10.2.1).
if (args[i].type != kWasmBottom) {
return args[i];
} else {
return Value{pc, imm.in_type(i)};
}
});
InitMerge(&c->start_merge, imm.in_arity(), [&imm, args](uint32_t i) {
// The merge needs to be instantiated with Values of the correct
// type, even if the actual Value is bottom/unreachable or has
// a subtype of the static type.
// So we copy-construct a new Value, and update its type.
Value value = args[i];
value.type = imm.in_type(i);
return value;
});
}
// In reachable code, check if there are at least {count} values on the stack.
......
......@@ -2673,12 +2673,10 @@ TEST_F(FunctionBodyDecoderTest, BrTableSubtyping) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
byte supertype1 = builder.AddStruct({F(kWasmI8, true), F(kWasmI16, false)});
byte supertype2 = builder.AddStruct({F(kWasmI8, true)});
byte subtype = builder.AddStruct(
{F(kWasmI8, true), F(kWasmI16, false), F(kWasmI32, true)});
module = builder.module();
ExpectValidates(
sigs.v_v(),
{WASM_BLOCK_R(
......@@ -3762,8 +3760,6 @@ TEST_F(FunctionBodyDecoderTest, RefAsNonNull) {
WASM_FEATURE_SCOPE(simd);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
byte array_type_index = builder.AddArray(kWasmI32, true);
uint32_t heap_types[] = {
......@@ -3804,8 +3800,6 @@ TEST_F(FunctionBodyDecoderTest, RefNull) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
byte array_type_index = builder.AddArray(kWasmI32, true);
uint32_t type_reprs[] = {
......@@ -3834,8 +3828,6 @@ TEST_F(FunctionBodyDecoderTest, RefIsNull) {
sigs.i_i(), {WASM_REF_IS_NULL(WASM_LOCAL_GET(0))}, kAppendEnd,
"ref.is_null[0] expected reference type, found local.get of type i32");
TestModuleBuilder builder;
module = builder.module();
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
byte array_type_index = builder.AddArray(kWasmI32, true);
uint32_t heap_types[] = {
......@@ -3910,8 +3902,6 @@ TEST_F(FunctionBodyDecoderTest, GCStruct) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
byte array_type_index = builder.AddArray(kWasmI32, true);
byte immutable_struct_type_index = builder.AddStruct({F(kWasmI32, false)});
......@@ -4045,8 +4035,6 @@ TEST_F(FunctionBodyDecoderTest, GCArray) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte array_type_index = builder.AddArray(kWasmFuncRef, true);
byte struct_type_index = builder.AddStruct({F(kWasmI32, false)});
......@@ -4185,8 +4173,6 @@ TEST_F(FunctionBodyDecoderTest, PackedFields) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte array_type_index = builder.AddArray(kWasmI8, true);
byte struct_type_index = builder.AddStruct({F(kWasmI16, true)});
byte field_index = 0;
......@@ -4281,8 +4267,6 @@ TEST_F(FunctionBodyDecoderTest, RttCanon) {
WASM_FEATURE_SCOPE(gc);
WASM_FEATURE_SCOPE(eh);
TestModuleBuilder builder;
module = builder.module();
uint8_t array_type_index = builder.AddArray(kWasmI32, true);
uint8_t struct_type_index = builder.AddStruct({F(kWasmI64, true)});
......@@ -4305,8 +4289,6 @@ TEST_F(FunctionBodyDecoderTest, RttSub) {
WASM_FEATURE_SCOPE(gc);
WASM_FEATURE_SCOPE(gc_experiments);
TestModuleBuilder builder;
module = builder.module();
uint8_t array_type_index = builder.AddArray(kWasmI8, true);
uint8_t super_struct_type_index = builder.AddStruct({F(kWasmI16, true)});
uint8_t sub_struct_type_index =
......@@ -4396,8 +4378,6 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
HeapType::Representation array_heap =
static_cast<HeapType::Representation>(builder.AddArray(kWasmI8, true));
HeapType::Representation super_struct_heap =
......@@ -4492,9 +4472,6 @@ TEST_F(FunctionBodyDecoderTest, BrOnCastOrCastFail) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte super_struct = builder.AddStruct({F(kWasmI16, true)});
byte sub_struct = builder.AddStruct({F(kWasmI16, true), F(kWasmI32, false)});
......@@ -4563,9 +4540,6 @@ TEST_F(FunctionBodyDecoderTest, BrOnAbstractType) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
ValueType kNonNullableFunc = ValueType::Ref(HeapType::kFunc, kNonNullable);
ExpectValidates(
......@@ -4623,8 +4597,6 @@ TEST_F(FunctionBodyDecoderTest, LocalTeeTyping) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
TestModuleBuilder builder;
module = builder.module();
byte array_type = builder.AddArray(kWasmI8, true);
ValueType types[] = {ValueType::Ref(array_type, kNonNullable)};
......@@ -4639,6 +4611,26 @@ TEST_F(FunctionBodyDecoderTest, LocalTeeTyping) {
kAppendEnd, "expected (ref 0), got (ref null 0)");
}
TEST_F(FunctionBodyDecoderTest, MergeNullableTypes) {
WASM_FEATURE_SCOPE(reftypes);
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(gc);
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
ValueType struct_type = optref(struct_type_index);
FunctionSig loop_sig(0, 1, &struct_type);
byte loop_sig_index = builder.AddSignature(&loop_sig);
// Verifies that when a loop consuming a nullable type is entered with a
// statically known non-null value on the stack, its {start_merge_} can
// consume null values later.
// Regression test for crbug.com/1234453.
ExpectValidates(sigs.v_v(),
{WASM_GC_OP(kExprRttCanon), struct_type_index,
WASM_GC_OP(kExprStructNewDefault), struct_type_index,
WASM_LOOP_X(loop_sig_index, kExprDrop, kExprRefNull,
struct_type_index, kExprBr, 0)});
}
// This tests that num_locals_ in decoder remains consistent, even if we fail
// mid-DecodeLocals().
TEST_F(FunctionBodyDecoderTest, Regress_1154439) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment