Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1104)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart

Issue 661923003: Support binary expressions in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 Iterable<JumpCollector> collectors) { 488 Iterable<JumpCollector> collectors) {
489 assert(isOpen); 489 assert(isOpen);
490 for (JumpCollector collector in collectors) { 490 for (JumpCollector collector in collectors) {
491 if (target == collector.target) { 491 if (target == collector.target) {
492 collector.addJump(this); 492 collector.addJump(this);
493 return true; 493 return true;
494 } 494 }
495 } 495 }
496 return false; 496 return false;
497 } 497 }
498
Johnni Winther 2014/10/17 11:37:40 These are moved/adapted from IrBuilderVisitor.
499 /// Create a negation of [condition].
500 ir.Primitive buildNegation(ir.Primitive condition) {
501 // ! e is translated as e ? false : true
502
503 // Add a continuation parameter for the result of the expression.
504 ir.Parameter resultParameter = new ir.Parameter(null);
505
506 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]);
507 ir.Continuation thenContinuation = new ir.Continuation([]);
508 ir.Continuation elseContinuation = new ir.Continuation([]);
509
510 ir.Constant trueConstant =
511 makePrimConst(state.constantSystem.createBool(true));
512 ir.Constant falseConstant =
513 makePrimConst(state.constantSystem.createBool(false));
514
515 thenContinuation.body = new ir.LetPrim(falseConstant)
516 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
517 elseContinuation.body = new ir.LetPrim(trueConstant)
518 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
519
520 add(new ir.LetCont(joinContinuation,
521 new ir.LetCont(thenContinuation,
522 new ir.LetCont(elseContinuation,
523 new ir.Branch(new ir.IsTrue(condition),
524 thenContinuation,
525 elseContinuation)))));
526 return resultParameter;
527 }
528
529 /// Create a lazy and/or expression. [leftValue] is the value of the left
530 /// operand and [buildRightValue] is called to process the value of the right
531 /// operand in the context of its own [IrBuilder].
532 ir.Primitive buildLogicalOperator(
533 ir.Primitive leftValue,
534 ir.Primitive buildRightValue(IrBuilder builder),
535 {bool isLazyOr: false}) {
536 // e0 && e1 is translated as if e0 ? (e1 == true) : false.
537 // e0 || e1 is translated as if e0 ? true : (e1 == true).
538 // The translation must convert both e0 and e1 to booleans and handle
539 // local variable assignments in e1.
540
541 IrBuilder rightBuilder = new IrBuilder.delimited(this);
542 ir.Primitive rightValue = buildRightValue(rightBuilder);
543 // A dummy empty target for the branch on the left subexpression branch.
544 // This enables using the same infrastructure for join-point continuations
545 // as in visitIf and visitConditional. It will hold a definition of the
546 // appropriate constant and an invocation of the join-point continuation.
547 IrBuilder emptyBuilder = new IrBuilder.delimited(this);
548 // Dummy empty targets for right true and right false. They hold
549 // definitions of the appropriate constant and an invocation of the
550 // join-point continuation.
551 IrBuilder rightTrueBuilder = new IrBuilder.delimited(rightBuilder);
552 IrBuilder rightFalseBuilder = new IrBuilder.delimited(rightBuilder);
553
554 // If we don't evaluate the right subexpression, the value of the whole
555 // expression is this constant.
556 ir.Constant leftBool = emptyBuilder.makePrimConst(
557 emptyBuilder.state.constantSystem.createBool(isLazyOr));
558 // If we do evaluate the right subexpression, the value of the expression
559 // is a true or false constant.
560 ir.Constant rightTrue = rightTrueBuilder.makePrimConst(
561 rightTrueBuilder.state.constantSystem.createBool(true));
562 ir.Constant rightFalse = rightFalseBuilder.makePrimConst(
563 rightFalseBuilder.state.constantSystem.createBool(false));
564 emptyBuilder.add(new ir.LetPrim(leftBool));
565 rightTrueBuilder.add(new ir.LetPrim(rightTrue));
566 rightFalseBuilder.add(new ir.LetPrim(rightFalse));
567
568 // Treat the result values as named values in the environment, so they
569 // will be treated as arguments to the join-point continuation.
570 assert(environment.length == emptyBuilder.environment.length);
571 assert(environment.length == rightTrueBuilder.environment.length);
572 assert(environment.length == rightFalseBuilder.environment.length);
573 emptyBuilder.environment.extend(null, leftBool);
574 rightTrueBuilder.environment.extend(null, rightTrue);
575 rightFalseBuilder.environment.extend(null, rightFalse);
576
577 // Wire up two continuations for the left subexpression, two continuations
578 // for the right subexpression, and a three-way join continuation.
579 JumpCollector jumps = new JumpCollector(null);
580 jumps.addJump(emptyBuilder);
581 jumps.addJump(rightTrueBuilder);
582 jumps.addJump(rightFalseBuilder);
583 ir.Continuation joinContinuation =
584 createJoin(environment.length + 1, jumps);
585 ir.Continuation leftTrueContinuation = new ir.Continuation([]);
586 ir.Continuation leftFalseContinuation = new ir.Continuation([]);
587 ir.Continuation rightTrueContinuation = new ir.Continuation([]);
588 ir.Continuation rightFalseContinuation = new ir.Continuation([]);
589 rightTrueContinuation.body = rightTrueBuilder._root;
590 rightFalseContinuation.body = rightFalseBuilder._root;
591 // The right subexpression has two continuations.
592 rightBuilder.add(
593 new ir.LetCont(rightTrueContinuation,
594 new ir.LetCont(rightFalseContinuation,
595 new ir.Branch(new ir.IsTrue(rightValue),
596 rightTrueContinuation,
597 rightFalseContinuation))));
598 // Depending on the operator, the left subexpression's continuations are
599 // either the right subexpression or an invocation of the join-point
600 // continuation.
601 if (isLazyOr) {
602 leftTrueContinuation.body = emptyBuilder._root;
603 leftFalseContinuation.body = rightBuilder._root;
604 } else {
605 leftTrueContinuation.body = rightBuilder._root;
606 leftFalseContinuation.body = emptyBuilder._root;
607 }
608
609 add(new ir.LetCont(joinContinuation,
610 new ir.LetCont(leftTrueContinuation,
611 new ir.LetCont(leftFalseContinuation,
612 new ir.Branch(new ir.IsTrue(leftValue),
613 leftTrueContinuation,
614 leftFalseContinuation)))));
615 // There is always a join parameter for the result value, because it
616 // is different on at least two paths.
617 return joinContinuation.parameters.last;
618 }
619
620 /// Create a non-recursive join-point continuation.
621 ///
622 /// Given the environment length at the join point and a list of
623 /// jumps that should reach the join point, create a join-point
624 /// continuation. The join-point continuation has a parameter for each
625 /// variable that has different values reaching on different paths.
626 ///
627 /// The jumps are uninitialized [ir.InvokeContinuation] expressions.
628 /// They are filled in with the target continuation and appropriate
629 /// arguments.
630 ///
631 /// As a side effect, the environment of this builder is updated to include
632 /// the join-point continuation parameters.
633 ir.Continuation createJoin(int environmentLength, JumpCollector jumps) {
634 assert(jumps.length >= 2);
635
636 // Compute which values are identical on all paths reaching the join.
637 // Handle the common case of a pair of contexts efficiently.
638 Environment first = jumps.environments[0];
639 Environment second = jumps.environments[1];
640 assert(environmentLength <= first.length);
641 assert(environmentLength <= second.length);
642 assert(first.sameDomain(environmentLength, second));
643 // A running count of the join-point parameters.
644 int parameterCount = 0;
645 // The null elements of common correspond to required parameters of the
646 // join-point continuation.
647 List<ir.Primitive> common =
648 new List<ir.Primitive>.generate(environmentLength,
649 (i) {
650 ir.Primitive candidate = first[i];
651 if (second[i] == candidate) {
652 return candidate;
653 } else {
654 ++parameterCount;
655 return null;
656 }
657 });
658 // If there is already a parameter for each variable, the other
659 // environments do not need to be considered.
660 if (parameterCount < environmentLength) {
661 for (int i = 0; i < environmentLength; ++i) {
662 ir.Primitive candidate = common[i];
663 if (candidate == null) continue;
664 for (Environment current in jumps.environments.skip(2)) {
665 assert(environmentLength <= current.length);
666 assert(first.sameDomain(environmentLength, current));
667 if (candidate != current[i]) {
668 common[i] = null;
669 ++parameterCount;
670 break;
671 }
672 }
673 if (parameterCount >= environmentLength) break;
674 }
675 }
676
677 // Create the join point continuation.
678 List<ir.Parameter> parameters = <ir.Parameter>[];
679 parameters.length = parameterCount;
680 int index = 0;
681 for (int i = 0; i < environmentLength; ++i) {
682 if (common[i] == null) {
683 parameters[index++] = new ir.Parameter(first.index2variable[i]);
684 }
685 }
686 assert(index == parameterCount);
687 ir.Continuation join = new ir.Continuation(parameters);
688
689 // Fill in all the continuation invocations.
690 for (int i = 0; i < jumps.length; ++i) {
691 Environment currentEnvironment = jumps.environments[i];
692 ir.InvokeContinuation invoke = jumps.invocations[i];
693 // Sharing this.environment with one of the invocations will not do
694 // the right thing (this.environment has already been mutated).
695 List<ir.Reference> arguments = <ir.Reference>[];
696 arguments.length = parameterCount;
697 int index = 0;
698 for (int i = 0; i < environmentLength; ++i) {
699 if (common[i] == null) {
700 arguments[index++] = new ir.Reference(currentEnvironment[i]);
701 }
702 }
703 invoke.continuation = new ir.Reference(join);
704 invoke.arguments = arguments;
705 }
706
707 // Mutate this.environment to be the environment at the join point. Do
708 // this after adding the continuation invocations, because this.environment
709 // might be collected by the jump collector and so the old environment
710 // values are needed for the continuation invocation.
711 //
712 // Iterate to environment.length because environmentLength includes values
713 // outside the environment which are 'phantom' variables used for the
714 // values of expressions like &&, ||, and ?:.
715 index = 0;
716 for (int i = 0; i < environment.length; ++i) {
717 if (common[i] == null) {
718 environment.index2value[i] = parameters[index++];
719 }
720 }
721
722 return join;
723 }
498 } 724 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/test/end2end_test.dart ('k') | sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698