Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1011403003: cps-ir: Set runtime type information for new objects that require it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update comment. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // IrNodes are kept in a separate library to have precise control over their 5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system. 6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 7 library dart2js.ir_nodes;
8 8
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../constants/values.dart' as values show ConstantValue; 10 import '../constants/values.dart' as values show ConstantValue;
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 bool get isFactory => target.isFactoryConstructor; 375 bool get isFactory => target.isFactoryConstructor;
376 376
377 InvokeConstructor(this.type, 377 InvokeConstructor(this.type,
378 this.target, 378 this.target,
379 this.selector, 379 this.selector,
380 Continuation cont, 380 Continuation cont,
381 List<Primitive> args) 381 List<Primitive> args)
382 : continuation = new Reference<Continuation>(cont), 382 : continuation = new Reference<Continuation>(cont),
383 arguments = _referenceList(args) { 383 arguments = _referenceList(args) {
384 assert(dart2js.invariant(target, 384 assert(dart2js.invariant(target,
385 target.isErroneous || target.isConstructor,
386 message: "Constructor invocation target is not a constructor: "
387 "$target."));
388 assert(dart2js.invariant(target,
389 target.isErroneous || 385 target.isErroneous ||
390 type.isDynamic || 386 type.isDynamic ||
391 type.element == target.enclosingClass.declaration, 387 type.element == target.enclosingClass.declaration,
392 message: "Constructor invocation type ${type} does not match enclosing " 388 message: "Constructor invocation target is not a constructor: "
393 "class of target ${target}.")); 389 "$target."));
394 } 390 }
395 391
396 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); 392 accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
397 } 393 }
398 394
399 /// "as" casts and "is" checks. 395 /// "as" casts and "is" checks.
400 // We might want to turn "is"-checks into a [Primitive] as it can never diverge. 396 // We might want to turn "is"-checks into a [Primitive] as it can never diverge.
401 // But then we need to special-case for is-checks with an erroneous .type as 397 // But then we need to special-case for is-checks with an erroneous .type as
402 // these will throw. 398 // these will throw.
403 class TypeOperator extends Expression { 399 class TypeOperator extends Expression {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 : this.object = new Reference<Primitive>(object); 586 : this.object = new Reference<Primitive>(object);
591 587
592 accept(Visitor visitor) => visitor.visitGetField(this); 588 accept(Visitor visitor) => visitor.visitGetField(this);
593 } 589 }
594 590
595 /// Creates an object for holding boxed variables captured by a closure. 591 /// Creates an object for holding boxed variables captured by a closure.
596 class CreateBox extends Primitive implements JsSpecificNode { 592 class CreateBox extends Primitive implements JsSpecificNode {
597 accept(Visitor visitor) => visitor.visitCreateBox(this); 593 accept(Visitor visitor) => visitor.visitCreateBox(this);
598 } 594 }
599 595
600 /// Creates an instance of a class and initializes its fields. 596 /// Creates an instance of a class and initializes its fields and runtime type
597 /// information.
601 class CreateInstance extends Primitive implements JsSpecificNode { 598 class CreateInstance extends Primitive implements JsSpecificNode {
602 final ClassElement classElement; 599 final ClassElement classElement;
603 600
604 /// Initial values for the fields on the class. 601 /// Initial values for the fields on the class.
605 /// The order corresponds to the order of fields on the class. 602 /// The order corresponds to the order of fields on the class.
606 final List<Reference<Primitive>> arguments; 603 final List<Reference<Primitive>> arguments;
607 604
608 CreateInstance(this.classElement, List<Primitive> arguments) 605 /// The runtime type information structure which contains the type arguments.
609 : this.arguments = _referenceList(arguments); 606 ///
607 /// May be `null` to indicate that no type information is needed because the
608 /// compiler determined that the type information for instances of this class
609 /// is not needed at runtime.
610 final List<Reference<Primitive>> typeInformation;
asgerf 2015/03/24 12:37:22 Is there ever a need to distinguish the empty list
karlklose 2015/03/26 09:50:07 Currently not. Changed.
611
612 CreateInstance(this.classElement, List<Primitive> arguments,
613 [List<Primitive> typeInformation])
614 : this.arguments = _referenceList(arguments),
615 this.typeInformation =
616 typeInformation == null ? null : _referenceList(typeInformation);
617
618 bool get hasTypeInformation => typeInformation != null;
610 619
611 accept(Visitor visitor) => visitor.visitCreateInstance(this); 620 accept(Visitor visitor) => visitor.visitCreateInstance(this);
612 } 621 }
613 622
614 class Identical extends Primitive implements JsSpecificNode { 623 class Identical extends Primitive implements JsSpecificNode {
615 final Reference<Primitive> left; 624 final Reference<Primitive> left;
616 final Reference<Primitive> right; 625 final Reference<Primitive> right;
617 Identical(Primitive left, Primitive right) 626 Identical(Primitive left, Primitive right)
618 : left = new Reference<Primitive>(left), 627 : left = new Reference<Primitive>(left),
619 right = new Reference<Primitive>(right); 628 right = new Reference<Primitive>(right);
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 final TypeVariableType variable; 900 final TypeVariableType variable;
892 final Reference<Primitive> target; 901 final Reference<Primitive> target;
893 902
894 ReadTypeVariable(this.variable, Primitive target) 903 ReadTypeVariable(this.variable, Primitive target)
895 : this.target = new Reference<Primitive>(target); 904 : this.target = new Reference<Primitive>(target);
896 905
897 @override 906 @override
898 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); 907 accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
899 } 908 }
900 909
910 /// Representation of a closed type (that is, a type without type variables).
911 ///
912 /// The resulting value is constructed from [dartType] by replacing the type
913 /// variables with consecutive values from [arguments], in the order generated
914 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are
915 /// treated as 'holes' in the term, which means that it must be ensured at
916 /// construction, that duplicate occurences of a type variable in [dartType]
917 /// are assigned the same value.
918 class TypeExpression extends Primitive implements JsSpecificNode {
919 final DartType dartType;
920 final List<Reference<Primitive>> arguments;
921
922 TypeExpression(this.dartType,
923 [List<Primitive> arguments = const <Primitive>[]])
924 : this.arguments = _referenceList(arguments);
925
926 @override
927 accept(Visitor visitor) {
928 return visitor.visitTypeExpression(this);
929 }
930 }
931
901 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { 932 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
902 return definitions.map((e) => new Reference<Primitive>(e)).toList(); 933 return definitions.map((e) => new Reference<Primitive>(e)).toList();
903 } 934 }
904 935
905 abstract class Visitor<T> { 936 abstract class Visitor<T> {
906 const Visitor(); 937 const Visitor();
907 938
908 T visit(Node node); 939 T visit(Node node);
909 940
910 // Concrete classes. 941 // Concrete classes.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 T visitSetField(SetField node); 984 T visitSetField(SetField node);
954 985
955 // Definitions. 986 // Definitions.
956 T visitIdentical(Identical node); 987 T visitIdentical(Identical node);
957 T visitInterceptor(Interceptor node); 988 T visitInterceptor(Interceptor node);
958 T visitCreateInstance(CreateInstance node); 989 T visitCreateInstance(CreateInstance node);
959 T visitGetField(GetField node); 990 T visitGetField(GetField node);
960 T visitCreateBox(CreateBox node); 991 T visitCreateBox(CreateBox node);
961 T visitReifyRuntimeType(ReifyRuntimeType node); 992 T visitReifyRuntimeType(ReifyRuntimeType node);
962 T visitReadTypeVariable(ReadTypeVariable node); 993 T visitReadTypeVariable(ReadTypeVariable node);
994 T visitTypeExpression(TypeExpression node);
963 } 995 }
964 996
965 /// Recursively visits the entire CPS term, and calls abstract `process*` 997 /// Recursively visits the entire CPS term, and calls abstract `process*`
966 /// (i.e. `processLetPrim`) functions in pre-order. 998 /// (i.e. `processLetPrim`) functions in pre-order.
967 class RecursiveVisitor implements Visitor { 999 class RecursiveVisitor implements Visitor {
968 const RecursiveVisitor(); 1000 const RecursiveVisitor();
969 1001
970 visit(Node node) => node.accept(this); 1002 visit(Node node) => node.accept(this);
971 1003
972 processReference(Reference ref) {} 1004 processReference(Reference ref) {}
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 processInterceptor(Interceptor node) {} 1224 processInterceptor(Interceptor node) {}
1193 visitInterceptor(Interceptor node) { 1225 visitInterceptor(Interceptor node) {
1194 processInterceptor(node); 1226 processInterceptor(node);
1195 processReference(node.input); 1227 processReference(node.input);
1196 } 1228 }
1197 1229
1198 processCreateInstance(CreateInstance node) {} 1230 processCreateInstance(CreateInstance node) {}
1199 visitCreateInstance(CreateInstance node) { 1231 visitCreateInstance(CreateInstance node) {
1200 processCreateInstance(node); 1232 processCreateInstance(node);
1201 node.arguments.forEach(processReference); 1233 node.arguments.forEach(processReference);
1234 if (node.hasTypeInformation) {
1235 node.typeInformation.forEach(processReference);
1236 }
1202 } 1237 }
1203 1238
1204 processSetField(SetField node) {} 1239 processSetField(SetField node) {}
1205 visitSetField(SetField node) { 1240 visitSetField(SetField node) {
1206 processSetField(node); 1241 processSetField(node);
1207 processReference(node.object); 1242 processReference(node.object);
1208 processReference(node.value); 1243 processReference(node.value);
1209 visit(node.body); 1244 visit(node.body);
1210 } 1245 }
1211 1246
(...skipping 12 matching lines...) Expand all
1224 visitReifyRuntimeType(ReifyRuntimeType node) { 1259 visitReifyRuntimeType(ReifyRuntimeType node) {
1225 processReifyRuntimeType(node); 1260 processReifyRuntimeType(node);
1226 processReference(node.value); 1261 processReference(node.value);
1227 } 1262 }
1228 1263
1229 processReadTypeVariable(ReadTypeVariable node) {} 1264 processReadTypeVariable(ReadTypeVariable node) {}
1230 visitReadTypeVariable(ReadTypeVariable node) { 1265 visitReadTypeVariable(ReadTypeVariable node) {
1231 processReadTypeVariable(node); 1266 processReadTypeVariable(node);
1232 processReference(node.target); 1267 processReference(node.target);
1233 } 1268 }
1269
1270 processTypeExpression(TypeExpression node) {}
1271 @override
1272 visitTypeExpression(TypeExpression node) {
1273 processTypeExpression(node);
1274 node.arguments.forEach(processReference);
1275 }
1234 } 1276 }
1235 1277
1236 /// Keeps track of currently unused register indices. 1278 /// Keeps track of currently unused register indices.
1237 class RegisterArray { 1279 class RegisterArray {
1238 int nextIndex = 0; 1280 int nextIndex = 0;
1239 final List<int> freeStack = <int>[]; 1281 final List<int> freeStack = <int>[];
1240 1282
1241 /// Returns an index that is currently unused. 1283 /// Returns an index that is currently unused.
1242 int makeIndex() { 1284 int makeIndex() {
1243 if (freeStack.isEmpty) { 1285 if (freeStack.isEmpty) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 1517
1476 void visitGetField(GetField node) { 1518 void visitGetField(GetField node) {
1477 visitReference(node.object); 1519 visitReference(node.object);
1478 } 1520 }
1479 1521
1480 void visitCreateBox(CreateBox node) { 1522 void visitCreateBox(CreateBox node) {
1481 } 1523 }
1482 1524
1483 void visitCreateInstance(CreateInstance node) { 1525 void visitCreateInstance(CreateInstance node) {
1484 node.arguments.forEach(visitReference); 1526 node.arguments.forEach(visitReference);
1527 if (node.hasTypeInformation) {
1528 node.typeInformation.forEach(visitReference);
1529 }
1485 } 1530 }
1486 1531
1487 void visitIdentical(Identical node) { 1532 void visitIdentical(Identical node) {
1488 visitReference(node.left); 1533 visitReference(node.left);
1489 visitReference(node.right); 1534 visitReference(node.right);
1490 } 1535 }
1491 1536
1492 void visitInterceptor(Interceptor node) { 1537 void visitInterceptor(Interceptor node) {
1493 visitReference(node.input); 1538 visitReference(node.input);
1494 } 1539 }
1495 1540
1496 void visitReifyRuntimeType(ReifyRuntimeType node) { 1541 void visitReifyRuntimeType(ReifyRuntimeType node) {
1497 visitReference(node.value); 1542 visitReference(node.value);
1498 } 1543 }
1499 1544
1500 void visitReadTypeVariable(ReadTypeVariable node) { 1545 void visitReadTypeVariable(ReadTypeVariable node) {
1501 visitReference(node.target); 1546 visitReference(node.target);
1502 } 1547 }
1548
1549 @override
1550 visitTypeExpression(TypeExpression node) {
1551 node.arguments.forEach(visitReference);
1552 }
1503 } 1553 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698