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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
5 | 5 |
6 import '../constants/expressions.dart'; | 6 import '../constants/expressions.dart'; |
7 import '../constants/values.dart' as values show ConstantValue; | 7 import '../constants/values.dart' as values show ConstantValue; |
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
11 import '../universe/universe.dart' show Selector, SelectorKind; | 11 import '../universe/universe.dart' show Selector, SelectorKind; |
12 | 12 |
| 13 import 'builtin_operator.dart'; |
| 14 export 'builtin_operator.dart'; |
| 15 |
13 abstract class Node { | 16 abstract class Node { |
14 /// A pointer to the parent node. Is null until set by optimization passes. | 17 /// A pointer to the parent node. Is null until set by optimization passes. |
15 Node parent; | 18 Node parent; |
16 | 19 |
17 accept(Visitor visitor); | 20 accept(Visitor visitor); |
18 } | 21 } |
19 | 22 |
20 /// Expressions can be evaluated, and may diverge, throw, and/or have | 23 /// Expressions can be evaluated, and may diverge, throw, and/or have |
21 /// side-effects. | 24 /// side-effects. |
22 /// | 25 /// |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 } | 115 } |
113 } | 116 } |
114 | 117 |
115 /// Evaluates a primitive and binds it to variable: `let val x = V in E`. | 118 /// Evaluates a primitive and binds it to variable: `let val x = V in E`. |
116 /// | 119 /// |
117 /// The bound value is in scope in the body. | 120 /// The bound value is in scope in the body. |
118 /// | 121 /// |
119 /// During one-pass construction a LetPrim with an empty body is used to | 122 /// During one-pass construction a LetPrim with an empty body is used to |
120 /// represent the one-hole context `let val x = V in []`. | 123 /// represent the one-hole context `let val x = V in []`. |
121 class LetPrim extends Expression implements InteriorNode { | 124 class LetPrim extends Expression implements InteriorNode { |
122 final Primitive primitive; | 125 Primitive primitive; |
123 Expression body; | 126 Expression body; |
124 | 127 |
125 LetPrim(this.primitive, [this.body = null]); | 128 LetPrim(this.primitive, [this.body = null]); |
126 | 129 |
127 Expression plug(Expression expr) { | 130 Expression plug(Expression expr) { |
128 assert(body == null); | 131 assert(body == null); |
129 return body = expr; | 132 return body = expr; |
130 } | 133 } |
131 | 134 |
132 accept(Visitor visitor) => visitor.visitLetPrim(this); | 135 accept(Visitor visitor) => visitor.visitLetPrim(this); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 final List<Reference<Primitive>> arguments; | 433 final List<Reference<Primitive>> arguments; |
431 final Reference<Continuation> continuation; | 434 final Reference<Continuation> continuation; |
432 | 435 |
433 ConcatenateStrings(List<Primitive> args, Continuation cont) | 436 ConcatenateStrings(List<Primitive> args, Continuation cont) |
434 : arguments = _referenceList(args), | 437 : arguments = _referenceList(args), |
435 continuation = new Reference<Continuation>(cont); | 438 continuation = new Reference<Continuation>(cont); |
436 | 439 |
437 accept(Visitor visitor) => visitor.visitConcatenateStrings(this); | 440 accept(Visitor visitor) => visitor.visitConcatenateStrings(this); |
438 } | 441 } |
439 | 442 |
| 443 /// Apply a built-in operator. |
| 444 /// |
| 445 /// It must be known that the arguments have the proper types. |
| 446 class ApplyBuiltinOperator extends Primitive { |
| 447 BuiltinOperator operator; |
| 448 List<Reference<Primitive>> arguments; |
| 449 |
| 450 ApplyBuiltinOperator(this.operator, List<Primitive> arguments) |
| 451 : this.arguments = _referenceList(arguments); |
| 452 |
| 453 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this); |
| 454 } |
| 455 |
440 /// Throw a value. | 456 /// Throw a value. |
441 /// | 457 /// |
442 /// Throw is an expression, i.e., it always occurs in tail position with | 458 /// Throw is an expression, i.e., it always occurs in tail position with |
443 /// respect to a body or expression. | 459 /// respect to a body or expression. |
444 class Throw extends Expression { | 460 class Throw extends Expression { |
445 Reference<Primitive> value; | 461 Reference<Primitive> value; |
446 | 462 |
447 Throw(Primitive value) : value = new Reference<Primitive>(value); | 463 Throw(Primitive value) : value = new Reference<Primitive>(value); |
448 | 464 |
449 accept(Visitor visitor) => visitor.visitThrow(this); | 465 accept(Visitor visitor) => visitor.visitThrow(this); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 bool isRecursive; | 545 bool isRecursive; |
530 | 546 |
531 InvokeContinuation(Continuation cont, List<Primitive> args, | 547 InvokeContinuation(Continuation cont, List<Primitive> args, |
532 {this.isRecursive: false}) | 548 {this.isRecursive: false}) |
533 : continuation = new Reference<Continuation>(cont), | 549 : continuation = new Reference<Continuation>(cont), |
534 arguments = _referenceList(args) { | 550 arguments = _referenceList(args) { |
535 assert(cont.parameters == null || cont.parameters.length == args.length); | 551 assert(cont.parameters == null || cont.parameters.length == args.length); |
536 if (isRecursive) cont.isRecursive = true; | 552 if (isRecursive) cont.isRecursive = true; |
537 } | 553 } |
538 | 554 |
539 /// Build a one-argument InvokeContinuation using existing reference objects. | |
540 /// | |
541 /// This is useful for converting call continuations to local continuations. | |
542 InvokeContinuation.fromCall(this.continuation, | |
543 Reference<Primitive> argument) | |
544 : arguments = <Reference<Primitive>>[argument], | |
545 isRecursive = false; | |
546 | |
547 /// A continuation invocation whose target and arguments will be filled | 555 /// A continuation invocation whose target and arguments will be filled |
548 /// in later. | 556 /// in later. |
549 /// | 557 /// |
550 /// Used as a placeholder for a jump whose target is not yet created | 558 /// Used as a placeholder for a jump whose target is not yet created |
551 /// (e.g., in the translation of break and continue). | 559 /// (e.g., in the translation of break and continue). |
552 InvokeContinuation.uninitialized({this.isRecursive: false}) | 560 InvokeContinuation.uninitialized({this.isRecursive: false}) |
553 : continuation = null, | 561 : continuation = null, |
554 arguments = null; | 562 arguments = null; |
555 | 563 |
556 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); | 564 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 T visitIdentical(Identical node); | 953 T visitIdentical(Identical node); |
946 T visitInterceptor(Interceptor node); | 954 T visitInterceptor(Interceptor node); |
947 T visitCreateInstance(CreateInstance node); | 955 T visitCreateInstance(CreateInstance node); |
948 T visitGetField(GetField node); | 956 T visitGetField(GetField node); |
949 T visitCreateBox(CreateBox node); | 957 T visitCreateBox(CreateBox node); |
950 T visitReifyRuntimeType(ReifyRuntimeType node); | 958 T visitReifyRuntimeType(ReifyRuntimeType node); |
951 T visitReadTypeVariable(ReadTypeVariable node); | 959 T visitReadTypeVariable(ReadTypeVariable node); |
952 T visitTypeExpression(TypeExpression node); | 960 T visitTypeExpression(TypeExpression node); |
953 T visitCreateInvocationMirror(CreateInvocationMirror node); | 961 T visitCreateInvocationMirror(CreateInvocationMirror node); |
954 T visitTypeTest(TypeTest node); | 962 T visitTypeTest(TypeTest node); |
| 963 T visitApplyBuiltinOperator(ApplyBuiltinOperator node); |
955 | 964 |
956 // Conditions. | 965 // Conditions. |
957 T visitIsTrue(IsTrue node); | 966 T visitIsTrue(IsTrue node); |
958 } | 967 } |
959 | 968 |
960 /// Recursively visits the entire CPS term, and calls abstract `process*` | 969 /// Recursively visits the entire CPS term, and calls abstract `process*` |
961 /// (i.e. `processLetPrim`) functions in pre-order. | 970 /// (i.e. `processLetPrim`) functions in pre-order. |
962 class RecursiveVisitor implements Visitor { | 971 class RecursiveVisitor implements Visitor { |
963 const RecursiveVisitor(); | 972 const RecursiveVisitor(); |
964 | 973 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 processNonTailThrow(node); | 1236 processNonTailThrow(node); |
1228 processReference(node.value); | 1237 processReference(node.value); |
1229 } | 1238 } |
1230 | 1239 |
1231 processCreateInvocationMirror(CreateInvocationMirror node) {} | 1240 processCreateInvocationMirror(CreateInvocationMirror node) {} |
1232 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1241 visitCreateInvocationMirror(CreateInvocationMirror node) { |
1233 processCreateInvocationMirror(node); | 1242 processCreateInvocationMirror(node); |
1234 node.arguments.forEach(processReference); | 1243 node.arguments.forEach(processReference); |
1235 } | 1244 } |
1236 | 1245 |
| 1246 processApplyBuiltinOperator(ApplyBuiltinOperator node) {} |
| 1247 visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
| 1248 processApplyBuiltinOperator(node); |
| 1249 node.arguments.forEach(processReference); |
| 1250 } |
| 1251 |
1237 processUnreachable(Unreachable node) {} | 1252 processUnreachable(Unreachable node) {} |
1238 visitUnreachable(Unreachable node) { | 1253 visitUnreachable(Unreachable node) { |
1239 processUnreachable(node); | 1254 processUnreachable(node); |
1240 } | 1255 } |
1241 } | 1256 } |
1242 | 1257 |
1243 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 1258 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
1244 class RemovalVisitor extends RecursiveVisitor { | 1259 class RemovalVisitor extends RecursiveVisitor { |
1245 const RemovalVisitor(); | 1260 const RemovalVisitor(); |
1246 | 1261 |
1247 processReference(Reference reference) { | 1262 processReference(Reference reference) { |
1248 reference.unlink(); | 1263 reference.unlink(); |
1249 } | 1264 } |
1250 | 1265 |
1251 static void remove(Node node) { | 1266 static void remove(Node node) { |
1252 (const RemovalVisitor()).visit(node); | 1267 (const RemovalVisitor()).visit(node); |
1253 } | 1268 } |
1254 } | 1269 } |
OLD | NEW |