@@ -103,6 +103,14 @@ abstract class HVisitor<R> {
103103 R visitTypeInfoReadRaw (HTypeInfoReadRaw node);
104104 R visitTypeInfoReadVariable (HTypeInfoReadVariable node);
105105 R visitTypeInfoExpression (HTypeInfoExpression node);
106+
107+ // Instructions for 'dart:_rti'.
108+ R visitIsTest (HIsTest node);
109+ R visitAsCheck (HAsCheck node);
110+ R visitSubtypeCheck (HSubtypeCheck node);
111+ R visitLoadType (HLoadType node);
112+ R visitTypeEval (HTypeEval node);
113+ R visitTypeBind (HTypeBind node);
106114}
107115
108116abstract class HGraphVisitor {
@@ -584,8 +592,22 @@ class HBaseVisitor extends HGraphVisitor implements HVisitor {
584592 @override
585593 visitTypeInfoReadVariable (HTypeInfoReadVariable node) =>
586594 visitInstruction (node);
595+
587596 @override
588597 visitTypeInfoExpression (HTypeInfoExpression node) => visitInstruction (node);
598+
599+ @override
600+ visitIsTest (HIsTest node) => visitInstruction (node);
601+ @override
602+ visitAsCheck (HAsCheck node) => visitCheck (node);
603+ @override
604+ visitSubtypeCheck (HSubtypeCheck node) => visitCheck (node);
605+ @override
606+ visitLoadType (HLoadType node) => visitInstruction (node);
607+ @override
608+ visitTypeEval (HTypeEval node) => visitInstruction (node);
609+ @override
610+ visitTypeBind (HTypeBind node) => visitInstruction (node);
589611}
590612
591613class SubGraph {
@@ -1064,6 +1086,13 @@ abstract class HInstruction implements Spannable {
10641086 static const int BOOL_CONVERSION_TYPECODE = 45 ;
10651087 static const int PRIMITIVE_CHECK_TYPECODE = 46 ;
10661088
1089+ static const int IS_TEST_TYPECODE = 47 ;
1090+ static const int AS_CHECK_TYPECODE = 48 ;
1091+ static const int SUBTYPE_CHECK_TYPECODE = 49 ;
1092+ static const int LOAD_TYPE_TYPECODE = 50 ;
1093+ static const int TYPE_EVAL_TYPECODE = 51 ;
1094+ static const int TYPE_BIND_TYPECODE = 52 ;
1095+
10671096 HInstruction (this .inputs, this .instructionType)
10681097 : id = idCounter++ ,
10691098 usedBy = < HInstruction > [] {
@@ -1384,6 +1413,9 @@ abstract class HInstruction implements Spannable {
13841413 bool hasSameLoopHeaderAs (HInstruction other) {
13851414 return block.enclosingLoopHeader == other.block.enclosingLoopHeader;
13861415 }
1416+
1417+ @override
1418+ String toString () => '${this .runtimeType }()' ;
13871419}
13881420
13891421/// The set of uses of [source] that are dominated by [dominator] .
@@ -3342,6 +3374,7 @@ class HIndexAssign extends HInstruction {
33423374 receiver.isNull (domain).isPotentiallyTrue;
33433375}
33443376
3377+ /// Is-test using legacy constructor based typ representation.
33453378class HIs extends HInstruction {
33463379 /// A check against a raw type: 'o is int', 'o is A'.
33473380 static const int RAW_CHECK = 0 ;
@@ -3476,7 +3509,7 @@ class HIsViaInterceptor extends HLateInstruction {
34763509///
34773510/// HLateValue is useful for naming values that would otherwise be generated at
34783511/// use site, for example, if 'this' is used many times, replacing uses of
3479- /// 'this' with HLateValhe (HThis) will have the effect of copying 'this' to a
3512+ /// 'this' with HLateValue (HThis) will have the effect of copying 'this' to a
34803513/// temporary will reduce the size of minified code.
34813514class HLateValue extends HLateInstruction {
34823515 HLateValue (HInstruction target) : super ([target], target.instructionType);
@@ -3489,6 +3522,7 @@ class HLateValue extends HLateInstruction {
34893522 toString () => 'HLateValue($target )' ;
34903523}
34913524
3525+ /// Type check or cast using legacy constructor-based type representation.
34923526class HTypeConversion extends HCheck {
34933527 // Values for [kind].
34943528 static const int TYPE_CHECK = 0 ;
@@ -4299,3 +4333,179 @@ class HTypeInfoExpression extends HInstruction {
42994333 }
43004334 }
43014335}
4336+
4337+ // -----------------------------------------------------------------------------
4338+
4339+ /// Is-test using Rti form of type expression.
4340+ ///
4341+ /// This instruction can be used for any type. Tests for simple types are
4342+ /// lowered to other instructions, so this instruction remains for types that
4343+ /// depend on type variables and complex types.
4344+ class HIsTest extends HInstruction {
4345+ HIsTest (HInstruction checked, HInstruction rti, AbstractValue type)
4346+ : super ([rti, checked], type) {
4347+ setUseGvn ();
4348+ }
4349+
4350+ // The type input is first to facilitate the `type.is(value)` codegen pattern.
4351+ HInstruction get typeInput => inputs[0 ];
4352+ HInstruction get checkedInput => inputs[1 ];
4353+
4354+ @override
4355+ accept (HVisitor visitor) => visitor.visitIsTest (this );
4356+
4357+ @override
4358+ int typeCode () => HInstruction .IS_TEST_TYPECODE ;
4359+
4360+ @override
4361+ bool typeEquals (HInstruction other) => other is HIsTest ;
4362+
4363+ @override
4364+ bool dataEquals (HIsTest other) => true ;
4365+
4366+ @override
4367+ String toString () => 'HIsTest()' ;
4368+ }
4369+
4370+ /// Type cast or type check using Rti form of type expression.
4371+ class HAsCheck extends HCheck {
4372+ final bool isTypeError;
4373+
4374+ HAsCheck (HInstruction checked, HInstruction rti, this .isTypeError,
4375+ AbstractValue type)
4376+ : super ([rti, checked], type) {}
4377+
4378+ // The type input is first to facilitate the `type.as(value)` codegen pattern.
4379+ HInstruction get typeInput => inputs[0 ];
4380+ @override
4381+ HInstruction get checkedInput => inputs[1 ];
4382+
4383+ @override
4384+ accept (HVisitor visitor) => visitor.visitAsCheck (this );
4385+
4386+ @override
4387+ int typeCode () => HInstruction .AS_CHECK_TYPECODE ;
4388+
4389+ @override
4390+ bool typeEquals (HInstruction other) => other is HAsCheck ;
4391+
4392+ @override
4393+ bool dataEquals (HAsCheck other) {
4394+ return isTypeError == other.isTypeError;
4395+ }
4396+
4397+ @override
4398+ String toString () {
4399+ String error = isTypeError ? 'TypeError' : 'CastError' ;
4400+ return 'HAsCheck($error )' ;
4401+ }
4402+ }
4403+
4404+ /// Subtype check comparing two Rti types.
4405+ class HSubtypeCheck extends HCheck {
4406+ HSubtypeCheck (
4407+ HInstruction subtype, HInstruction supertype, AbstractValue type)
4408+ : super ([subtype, supertype], type) {
4409+ setUseGvn ();
4410+ }
4411+
4412+ HInstruction get typeInput => inputs[1 ];
4413+
4414+ @override
4415+ accept (HVisitor visitor) => visitor.visitSubtypeCheck (this );
4416+
4417+ @override
4418+ int typeCode () => HInstruction .SUBTYPE_CHECK_TYPECODE ;
4419+
4420+ @override
4421+ bool typeEquals (HInstruction other) => other is HSubtypeCheck ;
4422+
4423+ @override
4424+ bool dataEquals (HSubtypeCheck other) => true ;
4425+
4426+ @override
4427+ String toString () => 'HSubtypeCheck()' ;
4428+ }
4429+
4430+ /// Common superclass for instructions that generate Rti values.
4431+ abstract class HRtiInstruction extends HInstruction {
4432+ HRtiInstruction (List <HInstruction > inputs, AbstractValue type)
4433+ : super (inputs, type);
4434+ }
4435+
4436+ /// Evaluates an Rti type recipe in the global environment.
4437+ class HLoadType extends HRtiInstruction {
4438+ DartType typeExpression; // TODO(sra): Allow a type environment expression.
4439+
4440+ HLoadType (this .typeExpression, AbstractValue type) : super ([], type) {
4441+ setUseGvn ();
4442+ }
4443+
4444+ @override
4445+ accept (HVisitor visitor) => visitor.visitLoadType (this );
4446+
4447+ @override
4448+ int typeCode () => HInstruction .LOAD_TYPE_TYPECODE ;
4449+
4450+ @override
4451+ bool typeEquals (HInstruction other) => other is HLoadType ;
4452+
4453+ @override
4454+ bool dataEquals (HLoadType other) {
4455+ return typeExpression == other.typeExpression;
4456+ }
4457+
4458+ @override
4459+ String toString () => 'HLoadType($typeExpression )' ;
4460+ }
4461+
4462+ /// Evaluates an Rti type recipe in an Rti environment.
4463+ class HTypeEval extends HRtiInstruction {
4464+ DartType typeExpression; // TODO(sra); Allow a type environment expression.
4465+
4466+ HTypeEval (HInstruction environment, this .typeExpression, AbstractValue type)
4467+ : super ([environment], type) {
4468+ setUseGvn ();
4469+ }
4470+
4471+ @override
4472+ accept (HVisitor visitor) => visitor.visitTypeEval (this );
4473+
4474+ @override
4475+ int typeCode () => HInstruction .TYPE_EVAL_TYPECODE ;
4476+
4477+ @override
4478+ bool typeEquals (HInstruction other) => other is HTypeEval ;
4479+
4480+ @override
4481+ bool dataEquals (HTypeEval other) {
4482+ return typeExpression == other.typeExpression;
4483+ }
4484+
4485+ @override
4486+ String toString () => 'HTypeEval($typeExpression )' ;
4487+ }
4488+
4489+ /// Extends an Rti type environment with generic function types.
4490+ class HTypeBind extends HRtiInstruction {
4491+ HTypeBind (
4492+ HInstruction environment, HInstruction typeArguments, AbstractValue type)
4493+ : super ([environment, typeArguments], type) {
4494+ setUseGvn ();
4495+ }
4496+
4497+ @override
4498+ accept (HVisitor visitor) => visitor.visitTypeBind (this );
4499+
4500+ @override
4501+ int typeCode () => HInstruction .TYPE_BIND_TYPECODE ;
4502+
4503+ @override
4504+ bool typeEquals (HInstruction other) => other is HTypeBind ;
4505+
4506+ @override
4507+ bool dataEquals (HTypeBind other) => true ;
4508+
4509+ @override
4510+ String toString () => 'HTypeBind()' ;
4511+ }
0 commit comments