| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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; |
| 611 |
| 612 CreateInstance(this.classElement, List<Primitive> arguments, |
| 613 [List<Primitive> typeInformation]) |
| 614 : this.arguments = _referenceList(arguments), |
| 615 this.typeInformation = typeInformation == null |
| 616 ? <Reference<Primitive>>[] : _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 Loading... |
| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 T visitSetField(SetField node); | 985 T visitSetField(SetField node); |
| 955 | 986 |
| 956 // Definitions. | 987 // Definitions. |
| 957 T visitIdentical(Identical node); | 988 T visitIdentical(Identical node); |
| 958 T visitInterceptor(Interceptor node); | 989 T visitInterceptor(Interceptor node); |
| 959 T visitCreateInstance(CreateInstance node); | 990 T visitCreateInstance(CreateInstance node); |
| 960 T visitGetField(GetField node); | 991 T visitGetField(GetField node); |
| 961 T visitCreateBox(CreateBox node); | 992 T visitCreateBox(CreateBox node); |
| 962 T visitReifyRuntimeType(ReifyRuntimeType node); | 993 T visitReifyRuntimeType(ReifyRuntimeType node); |
| 963 T visitReadTypeVariable(ReadTypeVariable node); | 994 T visitReadTypeVariable(ReadTypeVariable node); |
| 995 T visitTypeExpression(TypeExpression node); |
| 964 } | 996 } |
| 965 | 997 |
| 966 /// Recursively visits the entire CPS term, and calls abstract `process*` | 998 /// Recursively visits the entire CPS term, and calls abstract `process*` |
| 967 /// (i.e. `processLetPrim`) functions in pre-order. | 999 /// (i.e. `processLetPrim`) functions in pre-order. |
| 968 class RecursiveVisitor implements Visitor { | 1000 class RecursiveVisitor implements Visitor { |
| 969 const RecursiveVisitor(); | 1001 const RecursiveVisitor(); |
| 970 | 1002 |
| 971 visit(Node node) => node.accept(this); | 1003 visit(Node node) => node.accept(this); |
| 972 | 1004 |
| 973 processReference(Reference ref) {} | 1005 processReference(Reference ref) {} |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 processInterceptor(Interceptor node) {} | 1226 processInterceptor(Interceptor node) {} |
| 1195 visitInterceptor(Interceptor node) { | 1227 visitInterceptor(Interceptor node) { |
| 1196 processInterceptor(node); | 1228 processInterceptor(node); |
| 1197 processReference(node.input); | 1229 processReference(node.input); |
| 1198 } | 1230 } |
| 1199 | 1231 |
| 1200 processCreateInstance(CreateInstance node) {} | 1232 processCreateInstance(CreateInstance node) {} |
| 1201 visitCreateInstance(CreateInstance node) { | 1233 visitCreateInstance(CreateInstance node) { |
| 1202 processCreateInstance(node); | 1234 processCreateInstance(node); |
| 1203 node.arguments.forEach(processReference); | 1235 node.arguments.forEach(processReference); |
| 1236 if (node.hasTypeInformation) { |
| 1237 node.typeInformation.forEach(processReference); |
| 1238 } |
| 1204 } | 1239 } |
| 1205 | 1240 |
| 1206 processSetField(SetField node) {} | 1241 processSetField(SetField node) {} |
| 1207 visitSetField(SetField node) { | 1242 visitSetField(SetField node) { |
| 1208 processSetField(node); | 1243 processSetField(node); |
| 1209 processReference(node.object); | 1244 processReference(node.object); |
| 1210 processReference(node.value); | 1245 processReference(node.value); |
| 1211 visit(node.body); | 1246 visit(node.body); |
| 1212 } | 1247 } |
| 1213 | 1248 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1226 visitReifyRuntimeType(ReifyRuntimeType node) { | 1261 visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1227 processReifyRuntimeType(node); | 1262 processReifyRuntimeType(node); |
| 1228 processReference(node.value); | 1263 processReference(node.value); |
| 1229 } | 1264 } |
| 1230 | 1265 |
| 1231 processReadTypeVariable(ReadTypeVariable node) {} | 1266 processReadTypeVariable(ReadTypeVariable node) {} |
| 1232 visitReadTypeVariable(ReadTypeVariable node) { | 1267 visitReadTypeVariable(ReadTypeVariable node) { |
| 1233 processReadTypeVariable(node); | 1268 processReadTypeVariable(node); |
| 1234 processReference(node.target); | 1269 processReference(node.target); |
| 1235 } | 1270 } |
| 1271 |
| 1272 processTypeExpression(TypeExpression node) {} |
| 1273 @override |
| 1274 visitTypeExpression(TypeExpression node) { |
| 1275 processTypeExpression(node); |
| 1276 node.arguments.forEach(processReference); |
| 1277 } |
| 1236 } | 1278 } |
| 1237 | 1279 |
| 1238 /// Keeps track of currently unused register indices. | 1280 /// Keeps track of currently unused register indices. |
| 1239 class RegisterArray { | 1281 class RegisterArray { |
| 1240 int nextIndex = 0; | 1282 int nextIndex = 0; |
| 1241 final List<int> freeStack = <int>[]; | 1283 final List<int> freeStack = <int>[]; |
| 1242 | 1284 |
| 1243 /// Returns an index that is currently unused. | 1285 /// Returns an index that is currently unused. |
| 1244 int makeIndex() { | 1286 int makeIndex() { |
| 1245 if (freeStack.isEmpty) { | 1287 if (freeStack.isEmpty) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1480 | 1522 |
| 1481 void visitGetField(GetField node) { | 1523 void visitGetField(GetField node) { |
| 1482 visitReference(node.object); | 1524 visitReference(node.object); |
| 1483 } | 1525 } |
| 1484 | 1526 |
| 1485 void visitCreateBox(CreateBox node) { | 1527 void visitCreateBox(CreateBox node) { |
| 1486 } | 1528 } |
| 1487 | 1529 |
| 1488 void visitCreateInstance(CreateInstance node) { | 1530 void visitCreateInstance(CreateInstance node) { |
| 1489 node.arguments.forEach(visitReference); | 1531 node.arguments.forEach(visitReference); |
| 1532 if (node.hasTypeInformation) { |
| 1533 node.typeInformation.forEach(visitReference); |
| 1534 } |
| 1490 } | 1535 } |
| 1491 | 1536 |
| 1492 void visitIdentical(Identical node) { | 1537 void visitIdentical(Identical node) { |
| 1493 visitReference(node.left); | 1538 visitReference(node.left); |
| 1494 visitReference(node.right); | 1539 visitReference(node.right); |
| 1495 } | 1540 } |
| 1496 | 1541 |
| 1497 void visitInterceptor(Interceptor node) { | 1542 void visitInterceptor(Interceptor node) { |
| 1498 visitReference(node.input); | 1543 visitReference(node.input); |
| 1499 } | 1544 } |
| 1500 | 1545 |
| 1501 void visitReifyRuntimeType(ReifyRuntimeType node) { | 1546 void visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1502 visitReference(node.value); | 1547 visitReference(node.value); |
| 1503 } | 1548 } |
| 1504 | 1549 |
| 1505 void visitReadTypeVariable(ReadTypeVariable node) { | 1550 void visitReadTypeVariable(ReadTypeVariable node) { |
| 1506 visitReference(node.target); | 1551 visitReference(node.target); |
| 1507 } | 1552 } |
| 1553 |
| 1554 @override |
| 1555 visitTypeExpression(TypeExpression node) { |
| 1556 node.arguments.forEach(visitReference); |
| 1557 } |
| 1508 } | 1558 } |
| OLD | NEW |