Chromium Code Reviews| 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 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 (selector.kind == SelectorKind.SETTER && arguments.length == 1) || | 353 (selector.kind == SelectorKind.SETTER && arguments.length == 1) || |
| 354 (selector.kind == SelectorKind.INDEX && arguments.length == 1) || | 354 (selector.kind == SelectorKind.INDEX && arguments.length == 1) || |
| 355 (selector.kind == SelectorKind.INDEX && arguments.length == 2)); | 355 (selector.kind == SelectorKind.INDEX && arguments.length == 2)); |
| 356 } | 356 } |
| 357 | 357 |
| 358 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); | 358 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); |
| 359 } | 359 } |
| 360 | 360 |
| 361 /// Non-const call to a constructor. The [target] may be a generative | 361 /// Non-const call to a constructor. The [target] may be a generative |
| 362 /// constructor, factory, or redirecting factory. | 362 /// constructor, factory, or redirecting factory. |
| 363 class InvokeConstructor extends Expression implements Invoke { | 363 class InvokeConstructor extends Expression implements Invoke { |
|
karlklose
2015/03/18 08:44:51
Alternatively, we could split this into two backen
asgerf
2015/03/18 10:18:06
Following my comment in codegen, I think construct
| |
| 364 /// [type] encodes the instantiated type for the [DartBackend]; it must be | |
| 365 /// `null` in the [JavaScriptBackend]. | |
| 364 final DartType type; | 366 final DartType type; |
| 365 final FunctionElement target; | 367 final FunctionElement target; |
| 366 final Reference<Continuation> continuation; | 368 final Reference<Continuation> continuation; |
| 367 final List<Reference<Primitive>> arguments; | 369 final List<Reference<Primitive>> arguments; |
| 370 /// The type arguments are used in the [JavaScriptBackend]. | |
| 371 final List<Reference<Primitive>> typeArguments; | |
| 368 final Selector selector; | 372 final Selector selector; |
| 369 | 373 |
| 370 /// The class being instantiated. This is the same as `target.enclosingClass` | 374 /// The class being instantiated. This is the same as `target.enclosingClass` |
| 371 /// and `type.element`. | 375 /// and `type.element`. |
| 372 ClassElement get targetClass => target.enclosingElement; | 376 ClassElement get targetClass => target.enclosingElement; |
| 373 | 377 |
| 374 /// True if this is an invocation of a factory constructor. | 378 /// True if this is an invocation of a factory constructor. |
| 375 bool get isFactory => target.isFactoryConstructor; | 379 bool get isFactory => target.isFactoryConstructor; |
| 376 | 380 |
| 377 InvokeConstructor(this.type, | 381 InvokeConstructor.byType(this.type, |
| 378 this.target, | 382 this.target, |
| 379 this.selector, | 383 this.selector, |
| 380 Continuation cont, | 384 Continuation cont, |
| 381 List<Primitive> args) | 385 List<Primitive> args) |
| 382 : continuation = new Reference<Continuation>(cont), | 386 : continuation = new Reference<Continuation>(cont), |
| 383 arguments = _referenceList(args) { | 387 arguments = _referenceList(args), |
| 388 typeArguments = const <Reference<Primitive>>[] { | |
| 389 assert(dart2js.invariant(target, | |
| 390 target.isErroneous || | |
| 391 type.isDynamic || | |
| 392 type.element == target.enclosingClass.declaration, | |
| 393 message: "Constructor invocation target is not a constructor: " | |
| 394 "$target.")); | |
| 395 } | |
| 396 | |
| 397 InvokeConstructor.withTypeArguments(this.target, | |
| 398 this.selector, | |
| 399 Continuation cont, | |
| 400 List<Primitive> args, | |
| 401 List<Primitive> typeArguments) | |
| 402 : type = null, | |
| 403 continuation = new Reference<Continuation>(cont), | |
| 404 arguments = _referenceList(args), | |
| 405 typeArguments = _referenceList(typeArguments) { | |
| 384 assert(dart2js.invariant(target, | 406 assert(dart2js.invariant(target, |
| 385 target.isErroneous || target.isConstructor, | 407 target.isErroneous || target.isConstructor, |
| 386 message: "Constructor invocation target is not a constructor: " | 408 message: "Constructor invocation target is not a constructor: " |
| 387 "$target.")); | 409 "$target.")); |
| 388 assert(dart2js.invariant(target, | |
| 389 target.isErroneous || | |
| 390 type.isDynamic || | |
| 391 type.element == target.enclosingClass.declaration, | |
| 392 message: "Constructor invocation type ${type} does not match enclosing " | |
| 393 "class of target ${target}.")); | |
| 394 } | 410 } |
| 395 | 411 |
| 396 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); | 412 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| 397 } | 413 } |
| 398 | 414 |
| 399 /// "as" casts and "is" checks. | 415 /// "as" casts and "is" checks. |
| 400 // We might want to turn "is"-checks into a [Primitive] as it can never diverge. | 416 // 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 | 417 // But then we need to special-case for is-checks with an erroneous .type as |
| 402 // these will throw. | 418 // these will throw. |
| 403 class TypeOperator extends Expression { | 419 class TypeOperator extends Expression { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 class ReadTypeVariable extends Primitive implements JsSpecificNode { | 906 class ReadTypeVariable extends Primitive implements JsSpecificNode { |
| 891 final TypeVariableType variable; | 907 final TypeVariableType variable; |
| 892 final Reference<Primitive> target; | 908 final Reference<Primitive> target; |
| 893 | 909 |
| 894 ReadTypeVariable(this.variable, Primitive target) | 910 ReadTypeVariable(this.variable, Primitive target) |
| 895 : this.target = new Reference<Primitive>(target); | 911 : this.target = new Reference<Primitive>(target); |
| 896 | 912 |
| 897 @override | 913 @override |
| 898 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); | 914 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); |
| 899 } | 915 } |
| 900 | 916 |
|
asgerf
2015/03/18 10:18:06
It's not clear to me what dartType should be.
If
| |
| 917 /// Denotes the internal representation of [dartType], where all type variables | |
| 918 /// are replaced by the values in [arguments]. | |
| 919 class TypeExpression extends Primitive implements JsSpecificNode { | |
| 920 final DartType dartType; | |
| 921 final List<Reference<Primitive>> arguments; | |
| 922 | |
| 923 TypeExpression(this.dartType, | |
| 924 [List<Primitive> arguments = const <Primitive>[]]) | |
| 925 : this.arguments = _referenceList(arguments); | |
| 926 | |
| 927 @override | |
| 928 accept(Visitor visitor) { | |
| 929 return visitor.visitTypeExpression(this); | |
| 930 } | |
| 931 } | |
| 932 | |
| 901 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { | 933 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
| 902 return definitions.map((e) => new Reference<Primitive>(e)).toList(); | 934 return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
| 903 } | 935 } |
| 904 | 936 |
| 905 abstract class Visitor<T> { | 937 abstract class Visitor<T> { |
| 906 const Visitor(); | 938 const Visitor(); |
| 907 | 939 |
| 908 T visit(Node node); | 940 T visit(Node node); |
| 909 | 941 |
| 910 // Concrete classes. | 942 // Concrete classes. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 954 T visitSetField(SetField node); | 986 T visitSetField(SetField node); |
| 955 | 987 |
| 956 // Definitions. | 988 // Definitions. |
| 957 T visitIdentical(Identical node); | 989 T visitIdentical(Identical node); |
| 958 T visitInterceptor(Interceptor node); | 990 T visitInterceptor(Interceptor node); |
| 959 T visitCreateInstance(CreateInstance node); | 991 T visitCreateInstance(CreateInstance node); |
| 960 T visitGetField(GetField node); | 992 T visitGetField(GetField node); |
| 961 T visitCreateBox(CreateBox node); | 993 T visitCreateBox(CreateBox node); |
| 962 T visitReifyRuntimeType(ReifyRuntimeType node); | 994 T visitReifyRuntimeType(ReifyRuntimeType node); |
| 963 T visitReadTypeVariable(ReadTypeVariable node); | 995 T visitReadTypeVariable(ReadTypeVariable node); |
| 996 T visitTypeExpression(TypeExpression node); | |
| 964 } | 997 } |
| 965 | 998 |
| 966 /// Recursively visits the entire CPS term, and calls abstract `process*` | 999 /// Recursively visits the entire CPS term, and calls abstract `process*` |
| 967 /// (i.e. `processLetPrim`) functions in pre-order. | 1000 /// (i.e. `processLetPrim`) functions in pre-order. |
| 968 class RecursiveVisitor implements Visitor { | 1001 class RecursiveVisitor implements Visitor { |
| 969 const RecursiveVisitor(); | 1002 const RecursiveVisitor(); |
| 970 | 1003 |
| 971 visit(Node node) => node.accept(this); | 1004 visit(Node node) => node.accept(this); |
| 972 | 1005 |
| 973 processReference(Reference ref) {} | 1006 processReference(Reference ref) {} |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1075 processReference(node.receiver); | 1108 processReference(node.receiver); |
| 1076 processReference(node.continuation); | 1109 processReference(node.continuation); |
| 1077 node.arguments.forEach(processReference); | 1110 node.arguments.forEach(processReference); |
| 1078 } | 1111 } |
| 1079 | 1112 |
| 1080 processInvokeConstructor(InvokeConstructor node) {} | 1113 processInvokeConstructor(InvokeConstructor node) {} |
| 1081 visitInvokeConstructor(InvokeConstructor node) { | 1114 visitInvokeConstructor(InvokeConstructor node) { |
| 1082 processInvokeConstructor(node); | 1115 processInvokeConstructor(node); |
| 1083 processReference(node.continuation); | 1116 processReference(node.continuation); |
| 1084 node.arguments.forEach(processReference); | 1117 node.arguments.forEach(processReference); |
| 1118 node.typeArguments.forEach(processReference); | |
| 1085 } | 1119 } |
| 1086 | 1120 |
| 1087 processConcatenateStrings(ConcatenateStrings node) {} | 1121 processConcatenateStrings(ConcatenateStrings node) {} |
| 1088 visitConcatenateStrings(ConcatenateStrings node) { | 1122 visitConcatenateStrings(ConcatenateStrings node) { |
| 1089 processConcatenateStrings(node); | 1123 processConcatenateStrings(node); |
| 1090 processReference(node.continuation); | 1124 processReference(node.continuation); |
| 1091 node.arguments.forEach(processReference); | 1125 node.arguments.forEach(processReference); |
| 1092 } | 1126 } |
| 1093 | 1127 |
| 1094 processBranch(Branch node) {} | 1128 processBranch(Branch node) {} |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 visitReifyRuntimeType(ReifyRuntimeType node) { | 1260 visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1227 processReifyRuntimeType(node); | 1261 processReifyRuntimeType(node); |
| 1228 processReference(node.value); | 1262 processReference(node.value); |
| 1229 } | 1263 } |
| 1230 | 1264 |
| 1231 processReadTypeVariable(ReadTypeVariable node) {} | 1265 processReadTypeVariable(ReadTypeVariable node) {} |
| 1232 visitReadTypeVariable(ReadTypeVariable node) { | 1266 visitReadTypeVariable(ReadTypeVariable node) { |
| 1233 processReadTypeVariable(node); | 1267 processReadTypeVariable(node); |
| 1234 processReference(node.target); | 1268 processReference(node.target); |
| 1235 } | 1269 } |
| 1270 | |
| 1271 processTypeExpression(TypeExpression node) {} | |
| 1272 @override | |
| 1273 visitTypeExpression(TypeExpression node) { | |
| 1274 processTypeExpression(node); | |
| 1275 node.arguments.forEach(processReference); | |
| 1276 } | |
| 1236 } | 1277 } |
| 1237 | 1278 |
| 1238 /// Keeps track of currently unused register indices. | 1279 /// Keeps track of currently unused register indices. |
| 1239 class RegisterArray { | 1280 class RegisterArray { |
| 1240 int nextIndex = 0; | 1281 int nextIndex = 0; |
| 1241 final List<int> freeStack = <int>[]; | 1282 final List<int> freeStack = <int>[]; |
| 1242 | 1283 |
| 1243 /// Returns an index that is currently unused. | 1284 /// Returns an index that is currently unused. |
| 1244 int makeIndex() { | 1285 int makeIndex() { |
| 1245 if (freeStack.isEmpty) { | 1286 if (freeStack.isEmpty) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1386 node.arguments.forEach(visitReference); | 1427 node.arguments.forEach(visitReference); |
| 1387 } | 1428 } |
| 1388 | 1429 |
| 1389 void visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 1430 void visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
| 1390 visitReference(node.receiver); | 1431 visitReference(node.receiver); |
| 1391 node.arguments.forEach(visitReference); | 1432 node.arguments.forEach(visitReference); |
| 1392 } | 1433 } |
| 1393 | 1434 |
| 1394 void visitInvokeConstructor(InvokeConstructor node) { | 1435 void visitInvokeConstructor(InvokeConstructor node) { |
| 1395 node.arguments.forEach(visitReference); | 1436 node.arguments.forEach(visitReference); |
| 1437 node.typeArguments.forEach(visitReference); | |
| 1396 } | 1438 } |
| 1397 | 1439 |
| 1398 void visitConcatenateStrings(ConcatenateStrings node) { | 1440 void visitConcatenateStrings(ConcatenateStrings node) { |
| 1399 node.arguments.forEach(visitReference); | 1441 node.arguments.forEach(visitReference); |
| 1400 } | 1442 } |
| 1401 | 1443 |
| 1402 void visitBranch(Branch node) { | 1444 void visitBranch(Branch node) { |
| 1403 visit(node.condition); | 1445 visit(node.condition); |
| 1404 } | 1446 } |
| 1405 | 1447 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1498 visitReference(node.input); | 1540 visitReference(node.input); |
| 1499 } | 1541 } |
| 1500 | 1542 |
| 1501 void visitReifyRuntimeType(ReifyRuntimeType node) { | 1543 void visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1502 visitReference(node.value); | 1544 visitReference(node.value); |
| 1503 } | 1545 } |
| 1504 | 1546 |
| 1505 void visitReadTypeVariable(ReadTypeVariable node) { | 1547 void visitReadTypeVariable(ReadTypeVariable node) { |
| 1506 visitReference(node.target); | 1548 visitReference(node.target); |
| 1507 } | 1549 } |
| 1550 | |
| 1551 @override | |
| 1552 visitTypeExpression(TypeExpression node) { | |
| 1553 node.arguments.forEach(visitReference); | |
| 1554 } | |
| 1508 } | 1555 } |
| OLD | NEW |