| 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 import '../../cps_ir/optimizers.dart' show ParentVisitor; | 5 import '../../cps_ir/optimizers.dart' show ParentVisitor; |
| 6 import '../../constants/values.dart'; | 6 import '../../constants/values.dart'; |
| 7 import '../../elements/elements.dart'; | 7 import '../../elements/elements.dart'; |
| 8 import '../../io/source_information.dart'; | 8 import '../../io/source_information.dart'; |
| 9 import '../../js_backend/codegen/glue.dart'; | 9 import '../../js_backend/codegen/glue.dart'; |
| 10 import '../../universe/universe.dart' show Selector; | 10 import '../../universe/universe.dart' show Selector; |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 // getInterceptor again, so the receiver must be the interceptor (likely | 286 // getInterceptor again, so the receiver must be the interceptor (likely |
| 287 // `this`), not `null`. | 287 // `this`), not `null`. |
| 288 node.receiver = new Reference<Primitive>(nullPrim); | 288 node.receiver = new Reference<Primitive>(nullPrim); |
| 289 } | 289 } |
| 290 } | 290 } |
| 291 | 291 |
| 292 processBranch(Branch node) { | 292 processBranch(Branch node) { |
| 293 // TODO(karlklose): implement the checked mode part of boolean conversion. | 293 // TODO(karlklose): implement the checked mode part of boolean conversion. |
| 294 InteriorNode parent = node.parent; | 294 InteriorNode parent = node.parent; |
| 295 IsTrue condition = node.condition; | 295 IsTrue condition = node.condition; |
| 296 |
| 297 // Do not rewrite conditions that are foreign code. |
| 298 // It is redundant, and causes infinite recursion (if not optimized) |
| 299 // in the implementation of identical, which itself contains a condition. |
| 300 Primitive value = condition.value.definition; |
| 301 if (value is Parameter && value.parent is Continuation) { |
| 302 Continuation cont = value.parent; |
| 303 if (cont.hasExactlyOneUse && cont.firstRef.parent is ForeignCode) { |
| 304 ForeignCode foreign = cont.firstRef.parent; |
| 305 if (foreign.type.containsOnlyBool(_glue.classWorld)) { |
| 306 return; |
| 307 } |
| 308 } |
| 309 } |
| 310 |
| 296 Primitive t = trueConstant; | 311 Primitive t = trueConstant; |
| 297 Primitive i = new ApplyBuiltinOperator( | 312 Primitive i = new ApplyBuiltinOperator( |
| 298 BuiltinOperator.Identical, | 313 BuiltinOperator.Identical, |
| 299 <Primitive>[condition.value.definition, t], | 314 <Primitive>[condition.value.definition, t], |
| 300 condition.value.definition.sourceInformation); | 315 condition.value.definition.sourceInformation); |
| 301 LetPrim newNode = new LetPrim(t, | 316 LetPrim newNode = new LetPrim(t, |
| 302 new LetPrim(i, | 317 new LetPrim(i, |
| 303 new Branch(new IsTrue(i), | 318 new Branch(new IsTrue(i), |
| 304 node.trueContinuation.definition, | 319 node.trueContinuation.definition, |
| 305 node.falseContinuation.definition))); | 320 node.falseContinuation.definition))); |
| 306 condition.value.unlink(); | 321 condition.value.unlink(); |
| 307 node.trueContinuation.unlink(); | 322 node.trueContinuation.unlink(); |
| 308 node.falseContinuation.unlink(); | 323 node.falseContinuation.unlink(); |
| 309 parent.body = newNode; | 324 parent.body = newNode; |
| 310 } | 325 } |
| 311 | 326 |
| 312 processInterceptor(Interceptor node) { | 327 processInterceptor(Interceptor node) { |
| 313 _glue.registerSpecializedGetInterceptor(node.interceptedClasses); | 328 _glue.registerSpecializedGetInterceptor(node.interceptedClasses); |
| 314 } | 329 } |
| 315 } | 330 } |
| OLD | NEW |