| OLD | NEW |
| 1 library dart2js.unsugar_cps; | 1 library dart2js.unsugar_cps; |
| 2 | 2 |
| 3 import '../../cps_ir/cps_ir_nodes.dart'; | 3 import '../../cps_ir/cps_ir_nodes.dart'; |
| 4 | 4 |
| 5 // TODO(karlklose): share the [ParentVisitor]. | 5 // TODO(karlklose): share the [ParentVisitor]. |
| 6 import '../../cps_ir/optimizers.dart'; | 6 import '../../cps_ir/optimizers.dart'; |
| 7 import '../../constants/expressions.dart'; | 7 import '../../constants/expressions.dart'; |
| 8 import '../../constants/values.dart'; | 8 import '../../constants/values.dart'; |
| 9 import '../../elements/elements.dart' show ClassElement; | |
| 10 import '../../js_backend/codegen/glue.dart'; | |
| 11 | 9 |
| 12 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts | 10 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts |
| 13 /// special nodes that respect JavaScript behavior. | 11 /// special nodes that respect JavaScript behavior. |
| 14 /// | 12 /// |
| 15 /// Performs the following rewrites: | 13 /// Performs the following rewrites: |
| 16 /// - rewrite [IsTrue] in a [Branch] to do boolean conversion. | 14 /// - rewrite [IsTrue] in a [Branch] to do boolean conversion. |
| 17 class UnsugarVisitor extends RecursiveVisitor { | 15 class UnsugarVisitor extends RecursiveVisitor { |
| 18 Glue _glue; | 16 const UnsugarVisitor(); |
| 19 | |
| 20 UnsugarVisitor(this._glue); | |
| 21 | 17 |
| 22 void rewrite(FunctionDefinition function) { | 18 void rewrite(FunctionDefinition function) { |
| 23 // Set all parent pointers. | 19 // Set all parent pointers. |
| 24 new ParentVisitor().visit(function); | 20 new ParentVisitor().visit(function); |
| 25 visit(function); | 21 visit(function); |
| 26 } | 22 } |
| 27 | 23 |
| 28 @override | 24 @override |
| 29 visit(Node node) { | 25 visit(Node node) { |
| 30 Node result = node.accept(this); | 26 Node result = node.accept(this); |
| 31 return result != null ? result : node; | 27 return result != null ? result : node; |
| 32 } | 28 } |
| 33 | 29 |
| 34 Constant get trueConstant { | 30 Constant get trueConstant { |
| 35 return new Constant( | 31 return new Constant( |
| 36 new PrimitiveConstantExpression( | 32 new PrimitiveConstantExpression( |
| 37 new TrueConstantValue())); | 33 new TrueConstantValue())); |
| 38 } | 34 } |
| 39 | 35 |
| 40 processInvokeMethod(InvokeMethod node) { | |
| 41 if (!_glue.isInterceptedSelector(node.selector)) return; | |
| 42 Set<ClassElement> interceptedClasses = | |
| 43 _glue.getInterceptedClassesOn(node.selector); | |
| 44 _glue.registerSpecializedGetInterceptor(interceptedClasses); | |
| 45 InteriorNode parent = node.parent; | |
| 46 Primitive receiver = node.receiver.definition; | |
| 47 Primitive intercepted = new Interceptor(receiver, interceptedClasses); | |
| 48 List<Reference<Primitive>> arguments = | |
| 49 new List<Reference<Primitive>>.generate(node.arguments.length + 1, | |
| 50 (int index) { | |
| 51 return index == 0 ? new Reference<Primitive>(receiver) | |
| 52 : node.arguments[index - 1]; | |
| 53 }); | |
| 54 LetPrim newNode = new LetPrim(intercepted, | |
| 55 new InvokeMethod.internal(new Reference<Primitive>(intercepted), | |
| 56 node.selector, | |
| 57 new Reference<Continuation>(node.continuation.definition), | |
| 58 arguments)); | |
| 59 node.continuation.unlink(); | |
| 60 node.receiver.unlink(); | |
| 61 parent.body = newNode; | |
| 62 } | |
| 63 | |
| 64 processBranch(Branch node) { | 36 processBranch(Branch node) { |
| 65 // TODO(karlklose): implement the checked mode part of boolean conversion. | 37 // TODO(karlklose): implement the checked mode part of boolean conversion. |
| 66 InteriorNode parent = node.parent; | 38 InteriorNode parent = node.parent; |
| 67 IsTrue condition = node.condition; | 39 IsTrue condition = node.condition; |
| 68 Primitive t = trueConstant; | 40 Primitive t = trueConstant; |
| 69 Primitive i = new Identical(condition.value.definition, t); | 41 Primitive i = new Identical(condition.value.definition, t); |
| 70 LetPrim newNode = new LetPrim(t, | 42 LetPrim newNode = new LetPrim(t, |
| 71 new LetPrim(i, | 43 new LetPrim(i, |
| 72 new Branch(new IsTrue(i), | 44 new Branch(new IsTrue(i), |
| 73 node.trueContinuation.definition, | 45 node.trueContinuation.definition, |
| 74 node.falseContinuation.definition))); | 46 node.falseContinuation.definition))); |
| 75 condition.value.unlink(); | 47 condition.value.unlink(); |
| 76 node.trueContinuation.unlink(); | 48 node.trueContinuation.unlink(); |
| 77 node.falseContinuation.unlink(); | 49 node.falseContinuation.unlink(); |
| 78 parent.body = newNode; | 50 parent.body = newNode; |
| 79 } | 51 } |
| 80 } | 52 } |
| OLD | NEW |