diff --git a/src/compiler/wasm-gc-lowering.cc b/src/compiler/wasm-gc-lowering.cc index 9d9caae767..a4e5f65619 100644 --- a/src/compiler/wasm-gc-lowering.cc +++ b/src/compiler/wasm-gc-lowering.cc @@ -95,8 +95,12 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) { gasm_.InitializeEffectControl(effect_input, control_input); auto end_label = gasm_.MakeLabel(MachineRepresentation::kWord32); + bool is_cast_from_any = config.from.is_reference_to(wasm::HeapType::kAny); - if (object_can_be_null) { + // Skip the null check if casting from any and if null results in check + // failure. In that case the instance type check will identify null as not + // being a wasm object and return 0 (failure). + if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) { const int kResult = config.to.is_nullable() ? 1 : 0; gasm_.GotoIf(gasm_.TaggedEqual(object, Null()), &end_label, BranchHint::kFalse, gasm_.Int32Constant(kResult)); @@ -114,7 +118,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) { gasm_.Int32Constant(1)); // Check if map instance type identifies a wasm object. - if (config.from.is_reference_to(wasm::HeapType::kAny)) { + if (is_cast_from_any) { Node* is_wasm_obj = gasm_.IsDataRefMap(map); gasm_.GotoIfNot(is_wasm_obj, &end_label, BranchHint::kTrue, gasm_.Int32Constant(0)); @@ -166,8 +170,12 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) { gasm_.InitializeEffectControl(effect_input, control_input); auto end_label = gasm_.MakeLabel(); + bool is_cast_from_any = config.from.is_reference_to(wasm::HeapType::kAny); - if (object_can_be_null) { + // Skip the null check if casting from any and if null results in check + // failure. In that case the instance type check will identify null as not + // being a wasm object and trap. + if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) { Node* is_null = gasm_.TaggedEqual(object, Null()); if (config.to.is_nullable()) { gasm_.GotoIf(is_null, &end_label, BranchHint::kFalse); @@ -187,7 +195,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) { gasm_.GotoIf(gasm_.TaggedEqual(map, rtt), &end_label, BranchHint::kTrue); // Check if map instance type identifies a wasm object. - if (config.from.is_reference_to(wasm::HeapType::kAny)) { + if (is_cast_from_any) { Node* is_wasm_obj = gasm_.IsDataRefMap(map); gasm_.TrapUnless(is_wasm_obj, TrapId::kTrapIllegalCast); } diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 9502a0af32..485837efa2 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -5848,8 +5848,12 @@ class LiftoffCompiler { NullSucceeds null_succeeds, const FreezeCacheState& frozen) { Label match; + bool is_cast_from_any = obj_type.is_reference_to(HeapType::kAny); - if (obj_type.is_nullable()) { + // Skip the null check if casting from any and not {null_succeeds}. + // In that case the instance type check will identify null as not being a + // wasm object and fail. + if (obj_type.is_nullable() && (!is_cast_from_any || null_succeeds)) { __ emit_cond_jump(kEqual, null_succeeds ? &match : no_match, obj_type.kind(), obj_reg, scratch_null, frozen); } @@ -5876,7 +5880,7 @@ class LiftoffCompiler { // rtt. __ emit_cond_jump(kEqual, &match, rtt_type.kind(), tmp1, rtt_reg, frozen); - if (obj_type.is_reference_to(HeapType::kAny)) { + if (is_cast_from_any) { // Check for map being a map for a wasm object (struct, array, func). __ Load(LiftoffRegister(scratch2), tmp1, no_reg, wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset),