| 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 = _referenceList(typeInformation); |
| 610 | 616 |
| 611 accept(Visitor visitor) => visitor.visitCreateInstance(this); | 617 accept(Visitor visitor) => visitor.visitCreateInstance(this); |
| 612 } | 618 } |
| 613 | 619 |
| 614 class Identical extends Primitive implements JsSpecificNode { | 620 class Identical extends Primitive implements JsSpecificNode { |
| 615 final Reference<Primitive> left; | 621 final Reference<Primitive> left; |
| 616 final Reference<Primitive> right; | 622 final Reference<Primitive> right; |
| 617 Identical(Primitive left, Primitive right) | 623 Identical(Primitive left, Primitive right) |
| 618 : left = new Reference<Primitive>(left), | 624 : left = new Reference<Primitive>(left), |
| 619 right = new Reference<Primitive>(right); | 625 right = new Reference<Primitive>(right); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 final TypeVariableType variable; | 897 final TypeVariableType variable; |
| 892 final Reference<Primitive> target; | 898 final Reference<Primitive> target; |
| 893 | 899 |
| 894 ReadTypeVariable(this.variable, Primitive target) | 900 ReadTypeVariable(this.variable, Primitive target) |
| 895 : this.target = new Reference<Primitive>(target); | 901 : this.target = new Reference<Primitive>(target); |
| 896 | 902 |
| 897 @override | 903 @override |
| 898 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); | 904 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); |
| 899 } | 905 } |
| 900 | 906 |
| 907 /// Representation of a closed type (that is, a type without type variables). |
| 908 /// |
| 909 /// The resulting value is constructed from [dartType] by replacing the type |
| 910 /// variables with consecutive values from [arguments], in the order generated |
| 911 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are |
| 912 /// treated as 'holes' in the term, which means that it must be ensured at |
| 913 /// construction, that duplicate occurences of a type variable in [dartType] |
| 914 /// are assigned the same value. |
| 915 class TypeExpression extends Primitive implements JsSpecificNode { |
| 916 final DartType dartType; |
| 917 final List<Reference<Primitive>> arguments; |
| 918 |
| 919 TypeExpression(this.dartType, |
| 920 [List<Primitive> arguments = const <Primitive>[]]) |
| 921 : this.arguments = _referenceList(arguments); |
| 922 |
| 923 @override |
| 924 accept(Visitor visitor) { |
| 925 return visitor.visitTypeExpression(this); |
| 926 } |
| 927 } |
| 928 |
| 901 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { | 929 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
| 902 return definitions.map((e) => new Reference<Primitive>(e)).toList(); | 930 return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
| 903 } | 931 } |
| 904 | 932 |
| 905 abstract class Visitor<T> { | 933 abstract class Visitor<T> { |
| 906 const Visitor(); | 934 const Visitor(); |
| 907 | 935 |
| 908 T visit(Node node); | 936 T visit(Node node); |
| 909 | 937 |
| 910 // Concrete classes. | 938 // Concrete classes. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 T visitSetField(SetField node); | 981 T visitSetField(SetField node); |
| 954 | 982 |
| 955 // Definitions. | 983 // Definitions. |
| 956 T visitIdentical(Identical node); | 984 T visitIdentical(Identical node); |
| 957 T visitInterceptor(Interceptor node); | 985 T visitInterceptor(Interceptor node); |
| 958 T visitCreateInstance(CreateInstance node); | 986 T visitCreateInstance(CreateInstance node); |
| 959 T visitGetField(GetField node); | 987 T visitGetField(GetField node); |
| 960 T visitCreateBox(CreateBox node); | 988 T visitCreateBox(CreateBox node); |
| 961 T visitReifyRuntimeType(ReifyRuntimeType node); | 989 T visitReifyRuntimeType(ReifyRuntimeType node); |
| 962 T visitReadTypeVariable(ReadTypeVariable node); | 990 T visitReadTypeVariable(ReadTypeVariable node); |
| 991 T visitTypeExpression(TypeExpression node); |
| 963 } | 992 } |
| 964 | 993 |
| 965 /// Recursively visits the entire CPS term, and calls abstract `process*` | 994 /// Recursively visits the entire CPS term, and calls abstract `process*` |
| 966 /// (i.e. `processLetPrim`) functions in pre-order. | 995 /// (i.e. `processLetPrim`) functions in pre-order. |
| 967 class RecursiveVisitor implements Visitor { | 996 class RecursiveVisitor implements Visitor { |
| 968 const RecursiveVisitor(); | 997 const RecursiveVisitor(); |
| 969 | 998 |
| 970 visit(Node node) => node.accept(this); | 999 visit(Node node) => node.accept(this); |
| 971 | 1000 |
| 972 processReference(Reference ref) {} | 1001 processReference(Reference ref) {} |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 processInterceptor(Interceptor node) {} | 1221 processInterceptor(Interceptor node) {} |
| 1193 visitInterceptor(Interceptor node) { | 1222 visitInterceptor(Interceptor node) { |
| 1194 processInterceptor(node); | 1223 processInterceptor(node); |
| 1195 processReference(node.input); | 1224 processReference(node.input); |
| 1196 } | 1225 } |
| 1197 | 1226 |
| 1198 processCreateInstance(CreateInstance node) {} | 1227 processCreateInstance(CreateInstance node) {} |
| 1199 visitCreateInstance(CreateInstance node) { | 1228 visitCreateInstance(CreateInstance node) { |
| 1200 processCreateInstance(node); | 1229 processCreateInstance(node); |
| 1201 node.arguments.forEach(processReference); | 1230 node.arguments.forEach(processReference); |
| 1231 node.typeInformation.forEach(processReference); |
| 1202 } | 1232 } |
| 1203 | 1233 |
| 1204 processSetField(SetField node) {} | 1234 processSetField(SetField node) {} |
| 1205 visitSetField(SetField node) { | 1235 visitSetField(SetField node) { |
| 1206 processSetField(node); | 1236 processSetField(node); |
| 1207 processReference(node.object); | 1237 processReference(node.object); |
| 1208 processReference(node.value); | 1238 processReference(node.value); |
| 1209 visit(node.body); | 1239 visit(node.body); |
| 1210 } | 1240 } |
| 1211 | 1241 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1224 visitReifyRuntimeType(ReifyRuntimeType node) { | 1254 visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1225 processReifyRuntimeType(node); | 1255 processReifyRuntimeType(node); |
| 1226 processReference(node.value); | 1256 processReference(node.value); |
| 1227 } | 1257 } |
| 1228 | 1258 |
| 1229 processReadTypeVariable(ReadTypeVariable node) {} | 1259 processReadTypeVariable(ReadTypeVariable node) {} |
| 1230 visitReadTypeVariable(ReadTypeVariable node) { | 1260 visitReadTypeVariable(ReadTypeVariable node) { |
| 1231 processReadTypeVariable(node); | 1261 processReadTypeVariable(node); |
| 1232 processReference(node.target); | 1262 processReference(node.target); |
| 1233 } | 1263 } |
| 1264 |
| 1265 processTypeExpression(TypeExpression node) {} |
| 1266 @override |
| 1267 visitTypeExpression(TypeExpression node) { |
| 1268 processTypeExpression(node); |
| 1269 node.arguments.forEach(processReference); |
| 1270 } |
| 1234 } | 1271 } |
| 1235 | 1272 |
| 1236 /// Keeps track of currently unused register indices. | 1273 /// Keeps track of currently unused register indices. |
| 1237 class RegisterArray { | 1274 class RegisterArray { |
| 1238 int nextIndex = 0; | 1275 int nextIndex = 0; |
| 1239 final List<int> freeStack = <int>[]; | 1276 final List<int> freeStack = <int>[]; |
| 1240 | 1277 |
| 1241 /// Returns an index that is currently unused. | 1278 /// Returns an index that is currently unused. |
| 1242 int makeIndex() { | 1279 int makeIndex() { |
| 1243 if (freeStack.isEmpty) { | 1280 if (freeStack.isEmpty) { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 | 1512 |
| 1476 void visitGetField(GetField node) { | 1513 void visitGetField(GetField node) { |
| 1477 visitReference(node.object); | 1514 visitReference(node.object); |
| 1478 } | 1515 } |
| 1479 | 1516 |
| 1480 void visitCreateBox(CreateBox node) { | 1517 void visitCreateBox(CreateBox node) { |
| 1481 } | 1518 } |
| 1482 | 1519 |
| 1483 void visitCreateInstance(CreateInstance node) { | 1520 void visitCreateInstance(CreateInstance node) { |
| 1484 node.arguments.forEach(visitReference); | 1521 node.arguments.forEach(visitReference); |
| 1522 node.typeInformation.forEach(visitReference); |
| 1485 } | 1523 } |
| 1486 | 1524 |
| 1487 void visitIdentical(Identical node) { | 1525 void visitIdentical(Identical node) { |
| 1488 visitReference(node.left); | 1526 visitReference(node.left); |
| 1489 visitReference(node.right); | 1527 visitReference(node.right); |
| 1490 } | 1528 } |
| 1491 | 1529 |
| 1492 void visitInterceptor(Interceptor node) { | 1530 void visitInterceptor(Interceptor node) { |
| 1493 visitReference(node.input); | 1531 visitReference(node.input); |
| 1494 } | 1532 } |
| 1495 | 1533 |
| 1496 void visitReifyRuntimeType(ReifyRuntimeType node) { | 1534 void visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1497 visitReference(node.value); | 1535 visitReference(node.value); |
| 1498 } | 1536 } |
| 1499 | 1537 |
| 1500 void visitReadTypeVariable(ReadTypeVariable node) { | 1538 void visitReadTypeVariable(ReadTypeVariable node) { |
| 1501 visitReference(node.target); | 1539 visitReference(node.target); |
| 1502 } | 1540 } |
| 1541 |
| 1542 @override |
| 1543 visitTypeExpression(TypeExpression node) { |
| 1544 node.arguments.forEach(visitReference); |
| 1545 } |
| 1503 } | 1546 } |
| OLD | NEW |