[vm/nnbd] Fix supertype check in GenerateSubtype1TestCacheLookup
Before calling Subtype1TestCache stub, there was a quick check if supertype's class id matches tested class id. Null extends Object, so supertype of Null matches Object. However, in NNBD strong mode Null is not assignable to Object. Fixes https://github.com/dart-lang/sdk/issues/41272 Change-Id: Icc3efaf90992b5083cbe086af81db7504724b855 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142085 Reviewed-by: Régis Crelier <regis@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
0e8ee2b668
commit
6e53ac6e4c
@@ -428,13 +428,17 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
|
||||
__ LoadClassId(R2, TypeTestABI::kInstanceReg);
|
||||
__ LoadClassById(R1, R2);
|
||||
// R1: instance class.
|
||||
// Check immediate superclass equality.
|
||||
__ ldr(R2, compiler::FieldAddress(
|
||||
R1, compiler::target::Class::super_type_offset()));
|
||||
__ ldr(R2, compiler::FieldAddress(
|
||||
R2, compiler::target::Type::type_class_id_offset()));
|
||||
__ CompareImmediate(R2, Smi::RawValue(type_class.id()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
// Check immediate superclass equality. If type_class is Object, then testing
|
||||
// supertype may yield a wrong result for Null in NNBD strong mode (because
|
||||
// Null also extends Object).
|
||||
if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
|
||||
__ ldr(R2, compiler::FieldAddress(
|
||||
R1, compiler::target::Class::super_type_offset()));
|
||||
__ ldr(R2, compiler::FieldAddress(
|
||||
R2, compiler::target::Type::type_class_id_offset()));
|
||||
__ CompareImmediate(R2, Smi::RawValue(type_class.id()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
}
|
||||
|
||||
const Register kInstantiatorTypeArgumentsReg = kNoRegister;
|
||||
const Register kFunctionTypeArgumentsReg = kNoRegister;
|
||||
|
||||
@@ -414,11 +414,15 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
|
||||
__ LoadClassId(TMP, TypeTestABI::kInstanceReg);
|
||||
__ LoadClassById(R1, TMP);
|
||||
// R1: instance class.
|
||||
// Check immediate superclass equality.
|
||||
__ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
|
||||
__ LoadFieldFromOffset(R2, R2, Type::type_class_id_offset());
|
||||
__ CompareImmediate(R2, Smi::RawValue(type_class.id()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
// Check immediate superclass equality. If type_class is Object, then testing
|
||||
// supertype may yield a wrong result for Null in NNBD strong mode (because
|
||||
// Null also extends Object).
|
||||
if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
|
||||
__ LoadFieldFromOffset(R2, R1, Class::super_type_offset());
|
||||
__ LoadFieldFromOffset(R2, R2, Type::type_class_id_offset());
|
||||
__ CompareImmediate(R2, Smi::RawValue(type_class.id()));
|
||||
__ b(is_instance_lbl, EQ);
|
||||
}
|
||||
|
||||
const Register kInstantiatorTypeArgumentsReg = kNoRegister;
|
||||
const Register kFunctionTypeArgumentsReg = kNoRegister;
|
||||
|
||||
@@ -401,11 +401,15 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
|
||||
__ LoadClassId(EDI, TypeTestABI::kInstanceReg);
|
||||
__ LoadClassById(ECX, EDI);
|
||||
// ECX: instance class.
|
||||
// Check immediate superclass equality.
|
||||
__ movl(EDI, compiler::FieldAddress(ECX, Class::super_type_offset()));
|
||||
__ movl(EDI, compiler::FieldAddress(EDI, Type::type_class_id_offset()));
|
||||
__ cmpl(EDI, compiler::Immediate(Smi::RawValue(type_class.id())));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
// Check immediate superclass equality. If type_class is Object, then testing
|
||||
// supertype may yield a wrong result for Null in NNBD strong mode (because
|
||||
// Null also extends Object).
|
||||
if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
|
||||
__ movl(EDI, compiler::FieldAddress(ECX, Class::super_type_offset()));
|
||||
__ movl(EDI, compiler::FieldAddress(EDI, Type::type_class_id_offset()));
|
||||
__ cmpl(EDI, compiler::Immediate(Smi::RawValue(type_class.id())));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
}
|
||||
|
||||
const Register kInstantiatorTypeArgumentsReg = kNoRegister;
|
||||
const Register kFunctionTypeArgumentsReg = kNoRegister;
|
||||
|
||||
@@ -433,11 +433,16 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
|
||||
__ LoadClassId(TMP, TypeTestABI::kInstanceReg);
|
||||
__ LoadClassById(R10, TMP);
|
||||
// R10: instance class.
|
||||
// Check immediate superclass equality.
|
||||
__ movq(R13, compiler::FieldAddress(R10, Class::super_type_offset()));
|
||||
__ movq(R13, compiler::FieldAddress(R13, Type::type_class_id_offset()));
|
||||
__ CompareImmediate(R13, compiler::Immediate(Smi::RawValue(type_class.id())));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
// Check immediate superclass equality. If type_class is Object, then testing
|
||||
// supertype may yield a wrong result for Null in NNBD strong mode (because
|
||||
// Null also extends Object).
|
||||
if (!type_class.IsObjectClass() || !Isolate::Current()->null_safety()) {
|
||||
__ movq(R13, compiler::FieldAddress(R10, Class::super_type_offset()));
|
||||
__ movq(R13, compiler::FieldAddress(R13, Type::type_class_id_offset()));
|
||||
__ CompareImmediate(R13,
|
||||
compiler::Immediate(Smi::RawValue(type_class.id())));
|
||||
__ j(EQUAL, is_instance_lbl);
|
||||
}
|
||||
|
||||
const Register kInstantiatorTypeArgumentsReg = kNoRegister;
|
||||
const Register kFunctionTypeArgumentsReg = kNoRegister;
|
||||
|
||||
@@ -17827,7 +17827,8 @@ bool Instance::RuntimeTypeIsSubtypeOf(
|
||||
}
|
||||
const Class& cls = Class::Handle(zone, clazz());
|
||||
if (cls.IsClosureClass()) {
|
||||
if (other.IsDartFunctionType() || other.IsDartClosureType()) {
|
||||
if (other.IsDartFunctionType() || other.IsDartClosureType() ||
|
||||
other.IsObjectType()) {
|
||||
return true;
|
||||
}
|
||||
AbstractType& instantiated_other = AbstractType::Handle(zone, other.raw());
|
||||
|
||||
Reference in New Issue
Block a user