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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' show PrimitiveConstantValue; | 8 import '../constants/values.dart' show PrimitiveConstantValue; |
| 9 import '../dart_backend/dart_backend.dart' show DartBackend; | 9 import '../dart_backend/dart_backend.dart' show DartBackend; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 439 | 439 |
| 440 /// Create a static invocation of [element] with arguments structure defined | 440 /// Create a static invocation of [element] with arguments structure defined |
| 441 /// by [selector] and argument values defined by [arguments]. | 441 /// by [selector] and argument values defined by [arguments]. |
| 442 ir.Primitive buildStaticInvocation(Element element, | 442 ir.Primitive buildStaticInvocation(Element element, |
| 443 Selector selector, | 443 Selector selector, |
| 444 List<ir.Definition> arguments) { | 444 List<ir.Definition> arguments) { |
| 445 return continueWithExpression( | 445 return continueWithExpression( |
| 446 (k) => new ir.InvokeStatic(element, selector, k, arguments)); | 446 (k) => new ir.InvokeStatic(element, selector, k, arguments)); |
| 447 } | 447 } |
| 448 | 448 |
| 449 /// Creates an if-then-else statement with the provided [condition] where the | |
| 450 /// then and else branches are created throught the [buildThenPart] and | |
|
sigurdm
2014/10/20 09:12:03
throught -> by
Johnni Winther
2014/10/20 10:18:53
Acknowledged.
| |
| 451 /// [buildElsePart] functions, respectively. | |
| 452 /// | |
| 453 /// An if-then statement is created if [buildElsePart] is a no-op. | |
| 454 void buildIf(ir.Primitive condition, | |
|
sigurdm
2014/10/20 09:12:03
Maybe this should be generalized, so it can also h
Johnni Winther
2014/10/20 10:18:53
Will look into this.
| |
| 455 void buildThenPart(IrBuilder builder), | |
| 456 void buildElsePart(IrBuilder builder)) { | |
| 457 assert(isOpen); | |
| 458 | |
| 459 // The then and else parts are delimited. | |
| 460 IrBuilder thenBuilder = new IrBuilder.delimited(this); | |
| 461 IrBuilder elseBuilder = new IrBuilder.delimited(this); | |
| 462 buildThenPart(thenBuilder); | |
| 463 buildElsePart(elseBuilder); | |
| 464 | |
| 465 // Build the term | |
| 466 // (Result =) let cont then() = [[thenPart]] in | |
| 467 // let cont else() = [[elsePart]] in | |
| 468 // if condition (then, else) | |
| 469 ir.Continuation thenContinuation = new ir.Continuation([]); | |
| 470 ir.Continuation elseContinuation = new ir.Continuation([]); | |
| 471 ir.Expression letElse = | |
| 472 new ir.LetCont(elseContinuation, | |
| 473 new ir.Branch(new ir.IsTrue(condition), | |
| 474 thenContinuation, | |
| 475 elseContinuation)); | |
| 476 ir.Expression letThen = new ir.LetCont(thenContinuation, letElse); | |
| 477 ir.Expression result = letThen; | |
| 478 | |
| 479 ir.Continuation joinContinuation; // Null if there is no join. | |
| 480 if (thenBuilder.isOpen && elseBuilder.isOpen) { | |
| 481 // There is a join-point continuation. Build the term | |
| 482 // 'let cont join(x, ...) = [] in Result' and plug invocations of the | |
| 483 // join-point continuation into the then and else continuations. | |
| 484 JumpCollector jumps = new JumpCollector(null); | |
| 485 jumps.addJump(thenBuilder); | |
| 486 jumps.addJump(elseBuilder); | |
| 487 joinContinuation = createJoin(environment.length, jumps); | |
| 488 result = new ir.LetCont(joinContinuation, result); | |
| 489 } | |
| 490 | |
| 491 // The then or else term root could be null, but not both. If there is | |
| 492 // a join then an InvokeContinuation was just added to both of them. If | |
| 493 // there is no join, then at least one of them is closed and thus has a | |
| 494 // non-null root by the definition of the predicate isClosed. In the | |
| 495 // case that one of them is null, it must be the only one that is open | |
| 496 // and thus contains the new hole in the context. This case is handled | |
| 497 // after the branch is plugged into the current hole. | |
| 498 thenContinuation.body = thenBuilder._root; | |
| 499 elseContinuation.body = elseBuilder._root; | |
| 500 | |
| 501 add(result); | |
| 502 if (joinContinuation == null) { | |
| 503 // At least one subexpression is closed. | |
| 504 if (thenBuilder.isOpen) { | |
| 505 _current = | |
| 506 (thenBuilder._root == null) ? letThen : thenBuilder._current; | |
| 507 environment = thenBuilder.environment; | |
| 508 } else if (elseBuilder.isOpen) { | |
| 509 _current = | |
| 510 (elseBuilder._root == null) ? letElse : elseBuilder._current; | |
| 511 environment = elseBuilder.environment; | |
| 512 } else { | |
| 513 _current = null; | |
| 514 } | |
| 515 } | |
| 516 } | |
| 517 | |
| 449 /// Create a return statement `return value;` or `return;` if [value] is | 518 /// Create a return statement `return value;` or `return;` if [value] is |
| 450 /// null. | 519 /// null. |
| 451 void buildReturn([ir.Primitive value]) { | 520 void buildReturn([ir.Primitive value]) { |
| 452 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] | 521 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] |
| 453 // where (C', x) = Build(e, C) | 522 // where (C', x) = Build(e, C) |
| 454 // | 523 // |
| 455 // Return without a subexpression is translated as if it were return null. | 524 // Return without a subexpression is translated as if it were return null. |
| 456 assert(isOpen); | 525 assert(isOpen); |
| 457 if (value == null) { | 526 if (value == null) { |
| 458 value = buildNullLiteral(); | 527 value = buildNullLiteral(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 index = 0; | 774 index = 0; |
| 706 for (int i = 0; i < environment.length; ++i) { | 775 for (int i = 0; i < environment.length; ++i) { |
| 707 if (common[i] == null) { | 776 if (common[i] == null) { |
| 708 environment.index2value[i] = parameters[index++]; | 777 environment.index2value[i] = parameters[index++]; |
| 709 } | 778 } |
| 710 } | 779 } |
| 711 | 780 |
| 712 return join; | 781 return join; |
| 713 } | 782 } |
| 714 } | 783 } |
| OLD | NEW |