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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1743283002: dart2js cps: Use definitions by default, not references. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix doc comments and long lines Created 4 years, 9 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
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 library dart2js.ir_nodes; 4 library dart2js.ir_nodes;
5 5
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'cps_fragment.dart' show CpsFragment; 7 import 'cps_fragment.dart' show CpsFragment;
8 import 'cps_ir_nodes_sexpr.dart'; 8 import 'cps_ir_nodes_sexpr.dart';
9 import '../constants/values.dart' as values; 9 import '../constants/values.dart' as values;
10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 10 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 bool get isSafeForElimination; 260 bool get isSafeForElimination;
261 261
262 /// True if time-of-evaluation is irrelevant for the given primitive, 262 /// True if time-of-evaluation is irrelevant for the given primitive,
263 /// assuming its inputs are the same values. 263 /// assuming its inputs are the same values.
264 bool get isSafeForReordering; 264 bool get isSafeForReordering;
265 265
266 /// The source information associated with this primitive. 266 /// The source information associated with this primitive.
267 // TODO(johnniwinther): Require source information for all primitives. 267 // TODO(johnniwinther): Require source information for all primitives.
268 SourceInformation get sourceInformation => null; 268 SourceInformation get sourceInformation => null;
269 269
270 /// If this is a [Refinement], [BoundsCheck] or [ReceiverCheck] node, returns the 270 /// If this is a [Refinement], [BoundsCheck] or [ReceiverCheck] node, returns
271 /// value being refined, the indexable object being checked, or the value 271 /// the value being refined, the indexable object being checked, or the value
272 /// that was checked to be non-null, respectively. 272 /// that was checked to be non-null, respectively.
273 /// 273 ///
274 /// Those instructions all return the corresponding operand directly, and 274 /// Those instructions all return the corresponding operand directly, and
275 /// this getter can be used to get (closer to) where the value came from. 275 /// this getter can be used to get (closer to) where the value came from.
276 // 276 //
277 // TODO(asgerf): Also do this for [TypeCast]? 277 // TODO(asgerf): Also do this for [TypeCast]?
278 Primitive get effectiveDefinition => this; 278 Primitive get effectiveDefinition => this;
279 279
280 /// Like [effectiveDefinition] but only unfolds [Refinement] nodes. 280 /// Like [effectiveDefinition] but only unfolds [Refinement] nodes.
281 Primitive get unrefined => this; 281 Primitive get unrefined => this;
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 /// 489 ///
490 /// let mutable v = P in E 490 /// let mutable v = P in E
491 /// 491 ///
492 /// [MutableVariable]s can be seen as ref cells that are not first-class 492 /// [MutableVariable]s can be seen as ref cells that are not first-class
493 /// values. They are therefore not [Primitive]s and not bound by [LetPrim] 493 /// values. They are therefore not [Primitive]s and not bound by [LetPrim]
494 /// to prevent unrestricted use of references to them. During one-pass 494 /// to prevent unrestricted use of references to them. During one-pass
495 /// construction, a [LetMutable] with an empty body is use to represent the 495 /// construction, a [LetMutable] with an empty body is use to represent the
496 /// one-hole context 'let mutable v = P in []'. 496 /// one-hole context 'let mutable v = P in []'.
497 class LetMutable extends InteriorExpression { 497 class LetMutable extends InteriorExpression {
498 final MutableVariable variable; 498 final MutableVariable variable;
499 final Reference<Primitive> value; 499 final Reference<Primitive> valueRef;
sra1 2016/03/01 17:59:53 valueReference
500 Expression body; 500 Expression body;
501 501
502 Primitive get value => valueRef.definition;
503
502 LetMutable(this.variable, Primitive value) 504 LetMutable(this.variable, Primitive value)
503 : this.value = new Reference<Primitive>(value); 505 : this.valueRef = new Reference<Primitive>(value);
504 506
505 Expression plug(Expression expr) { 507 Expression plug(Expression expr) {
506 return body = expr; 508 return body = expr;
507 } 509 }
508 510
509 accept(BlockVisitor visitor) => visitor.visitLetMutable(this); 511 accept(BlockVisitor visitor) => visitor.visitLetMutable(this);
510 512
511 void setParentPointers() { 513 void setParentPointers() {
512 variable.parent = this; 514 variable.parent = this;
513 value.parent = this; 515 valueRef.parent = this;
514 if (body != null) body.parent = this; 516 if (body != null) body.parent = this;
515 } 517 }
516 } 518 }
517 519
518 enum CallingConvention { 520 enum CallingConvention {
519 /// JS receiver is the Dart receiver, there are no extra arguments. 521 /// JS receiver is the Dart receiver, there are no extra arguments.
520 /// 522 ///
521 /// This includes cases (e.g., static functions, constructors) where there 523 /// This includes cases (e.g., static functions, constructors) where there
522 /// is no receiver. 524 /// is no receiver.
523 /// 525 ///
(...skipping 13 matching lines...) Expand all
537 /// JS receiver is the Dart receiver, there are no extra arguments. 539 /// JS receiver is the Dart receiver, there are no extra arguments.
538 /// 540 ///
539 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)` 541 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)`
540 OneShotIntercepted, 542 OneShotIntercepted,
541 } 543 }
542 544
543 /// Base class of function invocations. 545 /// Base class of function invocations.
544 /// 546 ///
545 /// This class defines the common interface of function invocations. 547 /// This class defines the common interface of function invocations.
546 abstract class InvocationPrimitive extends UnsafePrimitive { 548 abstract class InvocationPrimitive extends UnsafePrimitive {
547 Reference<Primitive> get receiver => null; 549 Reference<Primitive> get receiverRef => null;
sra1 2016/03/01 17:59:53 receiverReference
548 List<Reference<Primitive>> get arguments; 550 Primitive get receiver => receiverRef?.definition;
549 SourceInformation get sourceInformation;
550 551
551 Reference<Primitive> get dartReceiverReference => null; 552 List<Reference<Primitive>> get argumentRefs;
sra1 2016/03/01 17:59:53 argumentReferences
552 Primitive get dartReceiver => dartReceiverReference.definition; 553 Primitive argument(int n) => argumentRefs[n].definition;
554 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
sra1 2016/03/01 17:59:53 I find it a surprising API choice that `arguments`
555
556 Reference<Primitive> get dartReceiverRef => null;
557 Primitive get dartReceiver => dartReceiverRef?.definition;
553 558
554 CallingConvention get callingConvention => CallingConvention.Normal; 559 CallingConvention get callingConvention => CallingConvention.Normal;
555 560
556 Reference<Primitive> dartArgumentReference(int n) { 561 Reference<Primitive> dartArgumentReference(int n) {
557 switch (callingConvention) { 562 switch (callingConvention) {
558 case CallingConvention.Normal: 563 case CallingConvention.Normal:
559 case CallingConvention.OneShotIntercepted: 564 case CallingConvention.OneShotIntercepted:
560 return arguments[n]; 565 return argumentRefs[n];
561 566
562 case CallingConvention.Intercepted: 567 case CallingConvention.Intercepted:
563 case CallingConvention.DummyIntercepted: 568 case CallingConvention.DummyIntercepted:
564 return arguments[n + 1]; 569 return argumentRefs[n + 1];
565 } 570 }
566 } 571 }
567 572
568 Primitive dartArgument(int n) => dartArgumentReference(n).definition; 573 Primitive dartArgument(int n) => dartArgumentReference(n).definition;
569 574
570 int get dartArgumentsLength => 575 int get dartArgumentsLength =>
571 arguments.length - 576 argumentRefs.length -
572 (callingConvention == CallingConvention.Intercepted || 577 (callingConvention == CallingConvention.Intercepted ||
573 callingConvention == CallingConvention.DummyIntercepted ? 1 : 0); 578 callingConvention == CallingConvention.DummyIntercepted ? 1 : 0);
579
580 SourceInformation get sourceInformation;
574 } 581 }
575 582
576 /// Invoke a static function. 583 /// Invoke a static function.
577 /// 584 ///
578 /// All optional arguments declared by [target] are passed in explicitly, and 585 /// All optional arguments declared by [target] are passed in explicitly, and
579 /// occur at the end of [arguments] list, in normalized order. 586 /// occur at the end of [arguments] list, in normalized order.
580 /// 587 ///
581 /// Discussion: 588 /// Discussion:
582 /// All information in the [selector] is technically redundant; it will likely 589 /// All information in the [selector] is technically redundant; it will likely
583 /// be removed. 590 /// be removed.
584 class InvokeStatic extends InvocationPrimitive { 591 class InvokeStatic extends InvocationPrimitive {
585 final FunctionElement target; 592 final FunctionElement target;
586 final Selector selector; 593 final Selector selector;
587 final List<Reference<Primitive>> arguments; 594 final List<Reference<Primitive>> argumentRefs;
588 final SourceInformation sourceInformation; 595 final SourceInformation sourceInformation;
589 596
590 InvokeStatic(this.target, 597 InvokeStatic(this.target,
591 this.selector, 598 this.selector,
592 List<Primitive> args, 599 List<Primitive> args,
593 [this.sourceInformation]) 600 [this.sourceInformation])
594 : arguments = _referenceList(args); 601 : argumentRefs = _referenceList(args);
595 602
596 InvokeStatic.byReference(this.target, 603 InvokeStatic.byReference(this.target,
597 this.selector, 604 this.selector,
598 this.arguments, 605 this.argumentRefs,
599 [this.sourceInformation]); 606 [this.sourceInformation]);
600 607
601 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 608 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
602 609
603 bool get hasValue => true; 610 bool get hasValue => true;
604 611
605 void setParentPointers() { 612 void setParentPointers() {
606 _setParentsOnList(arguments, this); 613 _setParentsOnList(argumentRefs, this);
607 } 614 }
608 } 615 }
609 616
610 /// Invoke a method on an object. 617 /// Invoke a method on an object.
611 /// 618 ///
612 /// This includes getters, setters, operators, and index getter/setters. 619 /// This includes getters, setters, operators, and index getter/setters.
613 /// 620 ///
614 /// Tearing off a method is treated like a getter invocation (getters and 621 /// Tearing off a method is treated like a getter invocation (getters and
615 /// tear-offs cannot be distinguished at compile-time). 622 /// tear-offs cannot be distinguished at compile-time).
616 /// 623 ///
617 /// The [selector] records the names of named arguments. The value of named 624 /// The [selector] records the names of named arguments. The value of named
618 /// arguments occur at the end of the [arguments] list, in normalized order. 625 /// arguments occur at the end of the [arguments] list, in normalized order.
619 class InvokeMethod extends InvocationPrimitive { 626 class InvokeMethod extends InvocationPrimitive {
620 Reference<Primitive> receiver; 627 Reference<Primitive> receiverRef;
621 Selector selector; 628 Selector selector;
622 TypeMask mask; 629 TypeMask mask;
623 final List<Reference<Primitive>> arguments; 630 final List<Reference<Primitive>> argumentRefs;
624 final SourceInformation sourceInformation; 631 final SourceInformation sourceInformation;
625 632
626 CallingConvention callingConvention = CallingConvention.Normal; 633 CallingConvention callingConvention = CallingConvention.Normal;
627 634
628 Reference<Primitive> get dartReceiverReference { 635 Reference<Primitive> get dartReceiverRef {
629 return callingConvention == CallingConvention.Intercepted 636 return callingConvention == CallingConvention.Intercepted
630 ? arguments[0] 637 ? argumentRefs[0]
631 : receiver; 638 : receiverRef;
632 } 639 }
633 640
634 /// If true, it is known that the receiver cannot be `null`. 641 /// If true, it is known that the receiver cannot be `null`.
635 bool receiverIsNotNull = false; 642 bool receiverIsNotNull = false;
636 643
637 InvokeMethod(Primitive receiver, 644 InvokeMethod(Primitive receiver,
638 this.selector, 645 this.selector,
639 this.mask, 646 this.mask,
640 List<Primitive> arguments, 647 List<Primitive> arguments,
641 {this.sourceInformation, 648 {this.sourceInformation,
642 this.callingConvention: CallingConvention.Normal}) 649 this.callingConvention: CallingConvention.Normal})
643 : this.receiver = new Reference<Primitive>(receiver), 650 : this.receiverRef = new Reference<Primitive>(receiver),
644 this.arguments = _referenceList(arguments); 651 this.argumentRefs = _referenceList(arguments);
645 652
646 accept(Visitor visitor) => visitor.visitInvokeMethod(this); 653 accept(Visitor visitor) => visitor.visitInvokeMethod(this);
647 654
648 bool get hasValue => true; 655 bool get hasValue => true;
649 656
650 void setParentPointers() { 657 void setParentPointers() {
651 receiver.parent = this; 658 receiverRef.parent = this;
652 _setParentsOnList(arguments, this); 659 _setParentsOnList(argumentRefs, this);
653 } 660 }
654 } 661 }
655 662
656 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. 663 /// Invoke [target] on [receiver], bypassing dispatch and override semantics.
657 /// 664 ///
658 /// That is, if [receiver] is an instance of a class that overrides [target] 665 /// That is, if [receiver] is an instance of a class that overrides [target]
659 /// with a different implementation, the overriding implementation is bypassed 666 /// with a different implementation, the overriding implementation is bypassed
660 /// and [target]'s implementation is invoked. 667 /// and [target]'s implementation is invoked.
661 /// 668 ///
662 /// As with [InvokeMethod], this can be used to invoke a method, operator, 669 /// As with [InvokeMethod], this can be used to invoke a method, operator,
663 /// getter, setter, or index getter/setter. 670 /// getter, setter, or index getter/setter.
664 /// 671 ///
665 /// If it is known that [target] does not use its receiver argument, then 672 /// If it is known that [target] does not use its receiver argument, then
666 /// [receiver] may refer to a null constant primitive. This happens for direct 673 /// [receiver] may refer to a null constant primitive. This happens for direct
667 /// invocations to intercepted methods, where the effective receiver is instead 674 /// invocations to intercepted methods, where the effective receiver is instead
668 /// passed as a formal parameter. 675 /// passed as a formal parameter.
669 /// 676 ///
670 /// TODO(sra): Review. A direct call to a method that is mixed into a native 677 /// TODO(sra): Review. A direct call to a method that is mixed into a native
671 /// class will still require an explicit argument. 678 /// class will still require an explicit argument.
672 /// 679 ///
673 /// All optional arguments declared by [target] are passed in explicitly, and 680 /// All optional arguments declared by [target] are passed in explicitly, and
674 /// occur at the end of [arguments] list, in normalized order. 681 /// occur at the end of [arguments] list, in normalized order.
675 class InvokeMethodDirectly extends InvocationPrimitive { 682 class InvokeMethodDirectly extends InvocationPrimitive {
676 Reference<Primitive> receiver; 683 Reference<Primitive> receiverRef;
677 final FunctionElement target; 684 final FunctionElement target;
678 final Selector selector; 685 final Selector selector;
679 final List<Reference<Primitive>> arguments; 686 final List<Reference<Primitive>> argumentRefs;
680 final SourceInformation sourceInformation; 687 final SourceInformation sourceInformation;
681 688
682 CallingConvention callingConvention; 689 CallingConvention callingConvention;
683 690
684 Reference<Primitive> get dartReceiverReference { 691 Reference<Primitive> get dartReceiverRef {
685 return callingConvention == CallingConvention.Intercepted 692 return callingConvention == CallingConvention.Intercepted
686 ? arguments[0] 693 ? argumentRefs[0]
687 : receiver; 694 : receiverRef;
688 } 695 }
689 696
690 InvokeMethodDirectly(Primitive receiver, 697 InvokeMethodDirectly(Primitive receiver,
691 this.target, 698 this.target,
692 this.selector, 699 this.selector,
693 List<Primitive> arguments, 700 List<Primitive> arguments,
694 this.sourceInformation, 701 this.sourceInformation,
695 {this.callingConvention: CallingConvention.Normal}) 702 {this.callingConvention: CallingConvention.Normal})
696 : this.receiver = new Reference<Primitive>(receiver), 703 : this.receiverRef = new Reference<Primitive>(receiver),
697 this.arguments = _referenceList(arguments); 704 this.argumentRefs = _referenceList(arguments);
698 705
699 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); 706 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this);
700 707
701 bool get hasValue => true; 708 bool get hasValue => true;
702 709
703 void setParentPointers() { 710 void setParentPointers() {
704 receiver.parent = this; 711 receiverRef.parent = this;
705 _setParentsOnList(arguments, this); 712 _setParentsOnList(argumentRefs, this);
706 } 713 }
707 714
708 bool get isConstructorBodyCall => target is ConstructorBodyElement; 715 bool get isConstructorBodyCall => target is ConstructorBodyElement;
709 bool get isTearOff => selector.isGetter && !target.isGetter; 716 bool get isTearOff => selector.isGetter && !target.isGetter;
710 } 717 }
711 718
712 /// Non-const call to a constructor. 719 /// Non-const call to a constructor.
713 /// 720 ///
714 /// The [target] may be a generative constructor (forwarding or normal) 721 /// The [target] may be a generative constructor (forwarding or normal)
715 /// or a non-redirecting factory. 722 /// or a non-redirecting factory.
716 /// 723 ///
717 /// All optional arguments declared by [target] are passed in explicitly, and 724 /// All optional arguments declared by [target] are passed in explicitly, and
718 /// occur in the [arguments] list, in normalized order. 725 /// occur in the [arguments] list, in normalized order.
719 /// 726 ///
720 /// Last in the [arguments] list, after the mandatory and optional arguments, 727 /// Last in the [arguments] list, after the mandatory and optional arguments,
721 /// the internal representation of each type argument occurs, unless it could 728 /// the internal representation of each type argument occurs, unless it could
722 /// be determined at build-time that the constructed class has no need for its 729 /// be determined at build-time that the constructed class has no need for its
723 /// runtime type information. 730 /// runtime type information.
724 /// 731 ///
725 /// Note that [InvokeConstructor] does it itself allocate an object. 732 /// Note that [InvokeConstructor] does it itself allocate an object.
726 /// The invoked constructor will do that using [CreateInstance]. 733 /// The invoked constructor will do that using [CreateInstance].
727 class InvokeConstructor extends InvocationPrimitive { 734 class InvokeConstructor extends InvocationPrimitive {
728 final DartType dartType; 735 final DartType dartType;
729 final ConstructorElement target; 736 final ConstructorElement target;
730 final List<Reference<Primitive>> arguments; 737 final List<Reference<Primitive>> argumentRefs;
731 final Selector selector; 738 final Selector selector;
732 final SourceInformation sourceInformation; 739 final SourceInformation sourceInformation;
733 740
734 /// If non-null, this is an allocation site-specific type that is potentially 741 /// If non-null, this is an allocation site-specific type that is potentially
735 /// better than the inferred return type of [target]. 742 /// better than the inferred return type of [target].
736 /// 743 ///
737 /// In particular, container type masks depend on the allocation site and 744 /// In particular, container type masks depend on the allocation site and
738 /// can therefore not be inferred solely based on the call target. 745 /// can therefore not be inferred solely based on the call target.
739 TypeMask allocationSiteType; 746 TypeMask allocationSiteType;
740 747
741 InvokeConstructor(this.dartType, 748 InvokeConstructor(this.dartType,
742 this.target, 749 this.target,
743 this.selector, 750 this.selector,
744 List<Primitive> args, 751 List<Primitive> args,
745 this.sourceInformation, 752 this.sourceInformation,
746 {this.allocationSiteType}) 753 {this.allocationSiteType})
747 : arguments = _referenceList(args); 754 : argumentRefs = _referenceList(args);
748 755
749 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); 756 accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
750 757
751 bool get hasValue => true; 758 bool get hasValue => true;
752 759
753 void setParentPointers() { 760 void setParentPointers() {
754 _setParentsOnList(arguments, this); 761 _setParentsOnList(argumentRefs, this);
755 } 762 }
756 } 763 }
757 764
758 /// An alias for [value] in a context where the value is known to satisfy 765 /// An alias for [value] in a context where the value is known to satisfy
759 /// [type]. 766 /// [type].
760 /// 767 ///
761 /// Refinement nodes are inserted before the type propagator pass and removed 768 /// Refinement nodes are inserted before the type propagator pass and removed
762 /// afterwards, so as not to complicate passes that don't reason about types, 769 /// afterwards, so as not to complicate passes that don't reason about types,
763 /// but need to reason about value references being identical (i.e. referring 770 /// but need to reason about value references being identical (i.e. referring
764 /// to the same primitive). 771 /// to the same primitive).
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 /// 815 ///
809 /// The [index] reference may be null if there are no checks to perform, 816 /// The [index] reference may be null if there are no checks to perform,
810 /// and the [length] reference may be null if there is no upper bound or 817 /// and the [length] reference may be null if there is no upper bound or
811 /// emptiness check. 818 /// emptiness check.
812 /// 819 ///
813 /// If a separate code motion guard for the index is required, e.g. because it 820 /// If a separate code motion guard for the index is required, e.g. because it
814 /// must be known to be non-negative in an operator that does not involve 821 /// must be known to be non-negative in an operator that does not involve
815 /// [object], a [Refinement] can be created for it with the non-negative integer 822 /// [object], a [Refinement] can be created for it with the non-negative integer
816 /// type. 823 /// type.
817 class BoundsCheck extends Primitive { 824 class BoundsCheck extends Primitive {
818 final Reference<Primitive> object; 825 final Reference<Primitive> objectRef;
819 Reference<Primitive> index; 826 Reference<Primitive> indexRef;
820 Reference<Primitive> length; 827 Reference<Primitive> lengthRef;
821 int checks; 828 int checks;
822 final SourceInformation sourceInformation; 829 final SourceInformation sourceInformation;
823 830
831 Primitive get object => objectRef.definition;
832 Primitive get index => indexRef?.definition;
833 Primitive get length => lengthRef?.definition;
834
824 /// If true, check that `index >= 0`. 835 /// If true, check that `index >= 0`.
825 bool get hasLowerBoundCheck => checks & LOWER_BOUND != 0; 836 bool get hasLowerBoundCheck => checks & LOWER_BOUND != 0;
826 837
827 /// If true, check that `index < object.length`. 838 /// If true, check that `index < object.length`.
828 bool get hasUpperBoundCheck => checks & UPPER_BOUND != 0; 839 bool get hasUpperBoundCheck => checks & UPPER_BOUND != 0;
829 840
830 /// If true, check that `object.length !== 0`. 841 /// If true, check that `object.length !== 0`.
831 /// 842 ///
832 /// Equivalent to a lower bound check with `object.length - 1` as the index, 843 /// Equivalent to a lower bound check with `object.length - 1` as the index,
833 /// but this check is faster. 844 /// but this check is faster.
(...skipping 13 matching lines...) Expand all
847 858
848 static const int UPPER_BOUND = 1 << 0; 859 static const int UPPER_BOUND = 1 << 0;
849 static const int LOWER_BOUND = 1 << 1; 860 static const int LOWER_BOUND = 1 << 1;
850 static const int EMPTINESS = 1 << 2; // See [hasEmptinessCheck]. 861 static const int EMPTINESS = 1 << 2; // See [hasEmptinessCheck].
851 static const int INTEGER = 1 << 3; // Check if index is an int. 862 static const int INTEGER = 1 << 3; // Check if index is an int.
852 static const int BOTH_BOUNDS = UPPER_BOUND | LOWER_BOUND; 863 static const int BOTH_BOUNDS = UPPER_BOUND | LOWER_BOUND;
853 static const int NONE = 0; 864 static const int NONE = 0;
854 865
855 BoundsCheck(Primitive object, Primitive index, Primitive length, 866 BoundsCheck(Primitive object, Primitive index, Primitive length,
856 [this.checks = BOTH_BOUNDS, this.sourceInformation]) 867 [this.checks = BOTH_BOUNDS, this.sourceInformation])
857 : this.object = new Reference<Primitive>(object), 868 : this.objectRef = new Reference<Primitive>(object),
858 this.index = new Reference<Primitive>(index), 869 this.indexRef = new Reference<Primitive>(index),
859 this.length = length == null ? null : new Reference<Primitive>(length); 870 this.lengthRef = _optionalReference(length);
860 871
861 BoundsCheck.noCheck(Primitive object, [this.sourceInformation]) 872 BoundsCheck.noCheck(Primitive object, [this.sourceInformation])
862 : this.object = new Reference<Primitive>(object), 873 : this.objectRef = new Reference<Primitive>(object),
863 this.checks = NONE; 874 this.checks = NONE;
864 875
865 accept(Visitor visitor) => visitor.visitBoundsCheck(this); 876 accept(Visitor visitor) => visitor.visitBoundsCheck(this);
866 877
867 void setParentPointers() { 878 void setParentPointers() {
868 object.parent = this; 879 objectRef.parent = this;
869 if (index != null) { 880 if (indexRef != null) {
870 index.parent = this; 881 indexRef.parent = this;
871 } 882 }
872 if (length != null) { 883 if (lengthRef != null) {
873 length.parent = this; 884 lengthRef.parent = this;
874 } 885 }
875 } 886 }
876 887
877 String get checkString { 888 String get checkString {
878 if (hasNoChecks) return 'no-check'; 889 if (hasNoChecks) return 'no-check';
879 return [hasUpperBoundCheck ? 'upper' : null, 890 return [hasUpperBoundCheck ? 'upper' : null,
880 hasLowerBoundCheck ? 'lower' : null, 891 hasLowerBoundCheck ? 'lower' : null,
881 hasEmptinessCheck ? 'emptiness' : null, 892 hasEmptinessCheck ? 'emptiness' : null,
882 hasIntegerCheck ? 'integer' : null, 893 hasIntegerCheck ? 'integer' : null,
883 'check'] 894 'check']
884 .where((x) => x != null).join('-'); 895 .where((x) => x != null).join('-');
885 } 896 }
886 897
887 bool get isSafeForElimination => checks == NONE; 898 bool get isSafeForElimination => checks == NONE;
888 bool get isSafeForReordering => false; 899 bool get isSafeForReordering => false;
889 bool get hasValue => true; // Can be referenced to restrict code motion. 900 bool get hasValue => true; // Can be referenced to restrict code motion.
890 901
891 Primitive get effectiveDefinition => object.definition.effectiveDefinition; 902 Primitive get effectiveDefinition => object.effectiveDefinition;
892 } 903 }
893 904
894 /// Throw a [NoSuchMethodError] if [value] cannot respond to [selector]. 905 /// Throw a [NoSuchMethodError] if [value] cannot respond to [selector].
895 /// 906 ///
896 /// Returns [value] so this can be used to restrict code motion. 907 /// Returns [value] so this can be used to restrict code motion.
897 /// 908 ///
898 /// The check can take one of three forms: 909 /// The check can take one of three forms:
899 /// 910 ///
900 /// value.toString; 911 /// value.toString;
901 /// value.selectorName; 912 /// value.selectorName;
902 /// value.selectorName(); (should only be used if check always fails) 913 /// value.selectorName(); (should only be used if check always fails)
903 /// 914 ///
904 /// The first two forms are used when it is known that only null fails the 915 /// The first two forms are used when it is known that only null fails the
905 /// check. Additionally, the check may be guarded by a [condition], allowing 916 /// check. Additionally, the check may be guarded by a [condition], allowing
906 /// for three more forms: 917 /// for three more forms:
907 /// 918 ///
908 /// if (condition) value.toString; (this form is valid but unused) 919 /// if (condition) value.toString; (this form is valid but unused)
909 /// if (condition) value.selectorName; 920 /// if (condition) value.selectorName;
910 /// if (condition) value.selectorName(); 921 /// if (condition) value.selectorName();
911 /// 922 ///
912 /// The condition must be true if and only if the check should fail. It should 923 /// The condition must be true if and only if the check should fail. It should
913 /// ideally be of a form understood by JS engines, e.g. a `typeof` test. 924 /// ideally be of a form understood by JS engines, e.g. a `typeof` test.
914 /// 925 ///
915 /// If [useSelector] is false, the first form instead becomes `value.toString;`. 926 /// If [useSelector] is false, the first form instead becomes `value.toString;`.
916 /// This form is faster when the value is non-null and the accessed property has 927 /// This form is faster when the value is non-null and the accessed property has
917 /// been removed by tree shaking. 928 /// been removed by tree shaking.
918 /// 929 ///
919 /// [selector] may not be one of the selectors implemented by the null object. 930 /// [selector] may not be one of the selectors implemented by the null object.
920 class ReceiverCheck extends Primitive { 931 class ReceiverCheck extends Primitive {
921 final Reference<Primitive> value; 932 final Reference<Primitive> valueRef;
922 final Selector selector; 933 final Selector selector;
923 final SourceInformation sourceInformation; 934 final SourceInformation sourceInformation;
924 final Reference<Primitive> condition; 935 final Reference<Primitive> conditionRef;
925 final int _flags; 936 final int _flags;
926 937
938 Primitive get value => valueRef.definition;
939 Primitive get condition => conditionRef?.definition;
940
927 static const int _USE_SELECTOR = 1 << 0; 941 static const int _USE_SELECTOR = 1 << 0;
928 static const int _NULL_CHECK = 1 << 1; 942 static const int _NULL_CHECK = 1 << 1;
929 943
930 /// True if the selector name should be used in the check; otherwise 944 /// True if the selector name should be used in the check; otherwise
931 /// `toString` will be used. 945 /// `toString` will be used.
932 bool get useSelector => _flags & _USE_SELECTOR != 0; 946 bool get useSelector => _flags & _USE_SELECTOR != 0;
933 947
934 /// True if null is the only possible input that cannot respond to [selector]. 948 /// True if null is the only possible input that cannot respond to [selector].
935 bool get isNullCheck => _flags & _NULL_CHECK != 0; 949 bool get isNullCheck => _flags & _NULL_CHECK != 0;
936 950
937 951
938 /// Constructor for creating checks in arbitrary configurations. 952 /// Constructor for creating checks in arbitrary configurations.
939 /// 953 ///
940 /// Consider using one of the named constructors instead. 954 /// Consider using one of the named constructors instead.
941 /// 955 ///
942 /// [useSelector] and [isNullCheck] are mandatory named arguments. 956 /// [useSelector] and [isNullCheck] are mandatory named arguments.
943 ReceiverCheck(Primitive value, this.selector, this.sourceInformation, 957 ReceiverCheck(Primitive value, this.selector, this.sourceInformation,
944 {Primitive condition, bool useSelector, bool isNullCheck}) 958 {Primitive condition, bool useSelector, bool isNullCheck})
945 : value = new Reference<Primitive>(value), 959 : valueRef = new Reference<Primitive>(value),
946 condition = _optionalReference(condition), 960 conditionRef = _optionalReference(condition),
947 _flags = (useSelector ? _USE_SELECTOR : 0) | 961 _flags = (useSelector ? _USE_SELECTOR : 0) |
948 (isNullCheck ? _NULL_CHECK : 0); 962 (isNullCheck ? _NULL_CHECK : 0);
949 963
950 /// Simplified constructor for building null checks. 964 /// Simplified constructor for building null checks.
951 /// 965 ///
952 /// Null must be the only possible input value that does not respond to 966 /// Null must be the only possible input value that does not respond to
953 /// [selector]. 967 /// [selector].
954 ReceiverCheck.nullCheck( 968 ReceiverCheck.nullCheck(
955 Primitive value, 969 Primitive value,
956 Selector selector, 970 Selector selector,
(...skipping 22 matching lines...) Expand all
979 useSelector: true, 993 useSelector: true,
980 isNullCheck: false); 994 isNullCheck: false);
981 995
982 bool get isSafeForElimination => false; 996 bool get isSafeForElimination => false;
983 bool get isSafeForReordering => false; 997 bool get isSafeForReordering => false;
984 bool get hasValue => true; 998 bool get hasValue => true;
985 999
986 accept(Visitor visitor) => visitor.visitReceiverCheck(this); 1000 accept(Visitor visitor) => visitor.visitReceiverCheck(this);
987 1001
988 void setParentPointers() { 1002 void setParentPointers() {
989 value.parent = this; 1003 valueRef.parent = this;
990 if (condition != null) { 1004 if (conditionRef != null) {
991 condition.parent = this; 1005 conditionRef.parent = this;
992 } 1006 }
993 } 1007 }
994 1008
995 Primitive get effectiveDefinition => value.definition.effectiveDefinition; 1009 Primitive get effectiveDefinition => value.effectiveDefinition;
996 1010
997 String get nullCheckString => isNullCheck ? 'null-check' : 'general-check'; 1011 String get nullCheckString => isNullCheck ? 'null-check' : 'general-check';
998 String get useSelectorString => useSelector ? 'use-selector' : 'no-selector'; 1012 String get useSelectorString => useSelector ? 'use-selector' : 'no-selector';
999 String get flagString => '$nullCheckString $useSelectorString'; 1013 String get flagString => '$nullCheckString $useSelectorString';
1000 } 1014 }
1001 1015
1002 /// An "is" type test. 1016 /// An "is" type test.
1003 /// 1017 ///
1004 /// Returns `true` if [value] is an instance of [dartType]. 1018 /// Returns `true` if [value] is an instance of [dartType].
1005 /// 1019 ///
1006 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might 1020 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might
1007 /// be a type variable containing one of these types). This design is chosen 1021 /// be a type variable containing one of these types). This design is chosen
1008 /// to simplify code generation for type tests. 1022 /// to simplify code generation for type tests.
1009 class TypeTest extends Primitive { 1023 class TypeTest extends Primitive {
1010 Reference<Primitive> value; 1024 Reference<Primitive> valueRef;
1011 final DartType dartType; 1025 final DartType dartType;
1012 1026
1013 /// If [dartType] is an [InterfaceType], this holds the internal 1027 /// If [dartType] is an [InterfaceType], this holds the internal
1014 /// representation of the type arguments to [dartType]. Since these may 1028 /// representation of the type arguments to [dartType]. Since these may
1015 /// reference type variables from the enclosing class, they are not constant. 1029 /// reference type variables from the enclosing class, they are not constant.
1016 /// 1030 ///
1017 /// If [dartType] is a [TypeVariableType], this is a singleton list with the 1031 /// If [dartType] is a [TypeVariableType], this is a singleton list with the
1018 /// internal representation of the type held in that type variable. 1032 /// internal representation of the type held in that type variable.
1019 /// 1033 ///
1020 /// If [dartType] is a [FunctionType], this is a singleton list with the 1034 /// If [dartType] is a [FunctionType], this is a singleton list with the
1021 /// internal representation of that type, 1035 /// internal representation of that type,
1022 /// 1036 ///
1023 /// Otherwise the list is empty. 1037 /// Otherwise the list is empty.
1024 final List<Reference<Primitive>> typeArguments; 1038 final List<Reference<Primitive>> typeArgumentRefs;
1039
1040 Primitive get value => valueRef.definition;
1041 Primitive typeArgument(int n) => typeArgumentRefs[n].definition;
1042 Iterable<Primitive> get typeArguments => _dereferenceList(typeArgumentRefs);
1025 1043
1026 TypeTest(Primitive value, 1044 TypeTest(Primitive value,
1027 this.dartType, 1045 this.dartType,
1028 List<Primitive> typeArguments) 1046 List<Primitive> typeArguments)
1029 : this.value = new Reference<Primitive>(value), 1047 : this.valueRef = new Reference<Primitive>(value),
1030 this.typeArguments = _referenceList(typeArguments); 1048 this.typeArgumentRefs = _referenceList(typeArguments);
1031 1049
1032 accept(Visitor visitor) => visitor.visitTypeTest(this); 1050 accept(Visitor visitor) => visitor.visitTypeTest(this);
1033 1051
1034 bool get hasValue => true; 1052 bool get hasValue => true;
1035 bool get isSafeForElimination => true; 1053 bool get isSafeForElimination => true;
1036 bool get isSafeForReordering => true; 1054 bool get isSafeForReordering => true;
1037 1055
1038 void setParentPointers() { 1056 void setParentPointers() {
1039 value.parent = this; 1057 valueRef.parent = this;
1040 _setParentsOnList(typeArguments, this); 1058 _setParentsOnList(typeArgumentRefs, this);
1041 } 1059 }
1042 } 1060 }
1043 1061
1044 /// An "is" type test for a raw type, performed by testing a flag property. 1062 /// An "is" type test for a raw type, performed by testing a flag property.
1045 /// 1063 ///
1046 /// Returns `true` if [interceptor] is for [dartType]. 1064 /// Returns `true` if [interceptor] is for [dartType].
1047 class TypeTestViaFlag extends Primitive { 1065 class TypeTestViaFlag extends Primitive {
1048 Reference<Primitive> interceptor; 1066 Reference<Primitive> interceptorRef;
1049 final DartType dartType; 1067 final DartType dartType;
1050 1068
1069 Primitive get interceptor => interceptorRef.definition;
1070
1051 TypeTestViaFlag(Primitive interceptor, this.dartType) 1071 TypeTestViaFlag(Primitive interceptor, this.dartType)
1052 : this.interceptor = new Reference<Primitive>(interceptor); 1072 : this.interceptorRef = new Reference<Primitive>(interceptor);
1053 1073
1054 accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this); 1074 accept(Visitor visitor) => visitor.visitTypeTestViaFlag(this);
1055 1075
1056 bool get hasValue => true; 1076 bool get hasValue => true;
1057 bool get isSafeForElimination => true; 1077 bool get isSafeForElimination => true;
1058 bool get isSafeForReordering => true; 1078 bool get isSafeForReordering => true;
1059 1079
1060 void setParentPointers() { 1080 void setParentPointers() {
1061 interceptor.parent = this; 1081 interceptorRef.parent = this;
1062 } 1082 }
1063 } 1083 }
1064 1084
1065 /// An "as" type cast. 1085 /// An "as" type cast.
1066 /// 1086 ///
1067 /// If [value] is `null` or is an instance of [type], [continuation] is invoked 1087 /// If [value] is `null` or is an instance of [type], [continuation] is invoked
1068 /// with [value] as argument. Otherwise, a [CastError] is thrown. 1088 /// with [value] as argument. Otherwise, a [CastError] is thrown.
1069 /// 1089 ///
1070 /// Discussion: 1090 /// Discussion:
1071 /// The parameter to [continuation] is redundant since it will always equal 1091 /// The parameter to [continuation] is redundant since it will always equal
1072 /// [value], which is typically in scope in the continuation. However, it might 1092 /// [value], which is typically in scope in the continuation. However, it might
1073 /// simplify type propagation, since a better type can be computed for the 1093 /// simplify type propagation, since a better type can be computed for the
1074 /// continuation parameter without needing flow-sensitive analysis. 1094 /// continuation parameter without needing flow-sensitive analysis.
1075 class TypeCast extends UnsafePrimitive { 1095 class TypeCast extends UnsafePrimitive {
1076 Reference<Primitive> value; 1096 Reference<Primitive> valueRef;
1077 final DartType dartType; 1097 final DartType dartType;
1078 1098
1079 /// See the corresponding field on [TypeTest]. 1099 /// See the corresponding field on [TypeTest].
1080 final List<Reference<Primitive>> typeArguments; 1100 final List<Reference<Primitive>> typeArgumentRefs;
1101
1102 Primitive get value => valueRef.definition;
1103 Primitive typeArgument(int n) => typeArgumentRefs[n].definition;
1104 Iterable<Primitive> get typeArguments => _dereferenceList(typeArgumentRefs);
1081 1105
1082 TypeCast(Primitive value, 1106 TypeCast(Primitive value,
1083 this.dartType, 1107 this.dartType,
1084 List<Primitive> typeArguments) 1108 List<Primitive> typeArguments)
1085 : this.value = new Reference<Primitive>(value), 1109 : this.valueRef = new Reference<Primitive>(value),
1086 this.typeArguments = _referenceList(typeArguments); 1110 this.typeArgumentRefs = _referenceList(typeArguments);
1087 1111
1088 accept(Visitor visitor) => visitor.visitTypeCast(this); 1112 accept(Visitor visitor) => visitor.visitTypeCast(this);
1089 1113
1090 bool get hasValue => true; 1114 bool get hasValue => true;
1091 1115
1092 void setParentPointers() { 1116 void setParentPointers() {
1093 value.parent = this; 1117 valueRef.parent = this;
1094 _setParentsOnList(typeArguments, this); 1118 _setParentsOnList(typeArgumentRefs, this);
1095 } 1119 }
1096 } 1120 }
1097 1121
1098 /// Apply a built-in operator. 1122 /// Apply a built-in operator.
1099 /// 1123 ///
1100 /// It must be known that the arguments have the proper types. 1124 /// It must be known that the arguments have the proper types.
1101 class ApplyBuiltinOperator extends Primitive { 1125 class ApplyBuiltinOperator extends Primitive {
1102 BuiltinOperator operator; 1126 BuiltinOperator operator;
1103 List<Reference<Primitive>> arguments; 1127 List<Reference<Primitive>> argumentRefs;
1104 final SourceInformation sourceInformation; 1128 final SourceInformation sourceInformation;
1105 1129
1130 Primitive argument(int n) => argumentRefs[n].definition;
1131 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1132
1106 ApplyBuiltinOperator(this.operator, 1133 ApplyBuiltinOperator(this.operator,
1107 List<Primitive> arguments, 1134 List<Primitive> arguments,
1108 this.sourceInformation) 1135 this.sourceInformation)
1109 : this.arguments = _referenceList(arguments); 1136 : this.argumentRefs = _referenceList(arguments);
1110 1137
1111 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this); 1138 accept(Visitor visitor) => visitor.visitApplyBuiltinOperator(this);
1112 1139
1113 bool get hasValue => true; 1140 bool get hasValue => true;
1114 bool get isSafeForElimination => true; 1141 bool get isSafeForElimination => true;
1115 bool get isSafeForReordering => true; 1142 bool get isSafeForReordering => true;
1116 1143
1117 void setParentPointers() { 1144 void setParentPointers() {
1118 _setParentsOnList(arguments, this); 1145 _setParentsOnList(argumentRefs, this);
1119 } 1146 }
1120 } 1147 }
1121 1148
1122 /// Apply a built-in method. 1149 /// Apply a built-in method.
1123 /// 1150 ///
1124 /// It must be known that the arguments have the proper types. 1151 /// It must be known that the arguments have the proper types.
1125 class ApplyBuiltinMethod extends Primitive { 1152 class ApplyBuiltinMethod extends Primitive {
1126 BuiltinMethod method; 1153 BuiltinMethod method;
1127 Reference<Primitive> receiver; 1154 Reference<Primitive> receiverRef;
1128 List<Reference<Primitive>> arguments; 1155 List<Reference<Primitive>> argumentRefs;
1129 final SourceInformation sourceInformation; 1156 final SourceInformation sourceInformation;
1130 1157
1158 Primitive get receiver => receiverRef.definition;
1159 Primitive argument(int n) => argumentRefs[n].definition;
1160 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1161
1131 bool receiverIsNotNull; 1162 bool receiverIsNotNull;
1132 1163
1133 ApplyBuiltinMethod(this.method, 1164 ApplyBuiltinMethod(this.method,
1134 Primitive receiver, 1165 Primitive receiver,
1135 List<Primitive> arguments, 1166 List<Primitive> arguments,
1136 this.sourceInformation, 1167 this.sourceInformation,
1137 {this.receiverIsNotNull: false}) 1168 {this.receiverIsNotNull: false})
1138 : this.receiver = new Reference<Primitive>(receiver), 1169 : this.receiverRef = new Reference<Primitive>(receiver),
1139 this.arguments = _referenceList(arguments); 1170 this.argumentRefs = _referenceList(arguments);
1140 1171
1141 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this); 1172 accept(Visitor visitor) => visitor.visitApplyBuiltinMethod(this);
1142 1173
1143 bool get hasValue => true; 1174 bool get hasValue => true;
1144 bool get isSafeForElimination => false; 1175 bool get isSafeForElimination => false;
1145 bool get isSafeForReordering => false; 1176 bool get isSafeForReordering => false;
1146 1177
1147 void setParentPointers() { 1178 void setParentPointers() {
1148 receiver.parent = this; 1179 receiverRef.parent = this;
1149 _setParentsOnList(arguments, this); 1180 _setParentsOnList(argumentRefs, this);
1150 } 1181 }
1151 1182
1152 int get effects => getEffectsOfBuiltinMethod(method); 1183 int get effects => getEffectsOfBuiltinMethod(method);
1153 } 1184 }
1154 1185
1155 /// Throw a value. 1186 /// Throw a value.
1156 /// 1187 ///
1157 /// Throw is an expression, i.e., it always occurs in tail position with 1188 /// Throw is an expression, i.e., it always occurs in tail position with
1158 /// respect to a body or expression. 1189 /// respect to a body or expression.
1159 class Throw extends TailExpression { 1190 class Throw extends TailExpression {
1160 Reference<Primitive> value; 1191 Reference<Primitive> valueRef;
1161 1192
1162 Throw(Primitive value) : value = new Reference<Primitive>(value); 1193 Primitive get value => valueRef.definition;
1194
1195 Throw(Primitive value) : valueRef = new Reference<Primitive>(value);
1163 1196
1164 accept(BlockVisitor visitor) => visitor.visitThrow(this); 1197 accept(BlockVisitor visitor) => visitor.visitThrow(this);
1165 1198
1166 void setParentPointers() { 1199 void setParentPointers() {
1167 value.parent = this; 1200 valueRef.parent = this;
1168 } 1201 }
1169 } 1202 }
1170 1203
1171 /// Rethrow 1204 /// Rethrow
1172 /// 1205 ///
1173 /// Rethrow can only occur inside a continuation bound by [LetHandler]. It 1206 /// Rethrow can only occur inside a continuation bound by [LetHandler]. It
1174 /// implicitly throws the exception parameter of the enclosing handler with 1207 /// implicitly throws the exception parameter of the enclosing handler with
1175 /// the same stack trace as the enclosing handler. 1208 /// the same stack trace as the enclosing handler.
1176 class Rethrow extends TailExpression { 1209 class Rethrow extends TailExpression {
1177 accept(BlockVisitor visitor) => visitor.visitRethrow(this); 1210 accept(BlockVisitor visitor) => visitor.visitRethrow(this);
(...skipping 10 matching lines...) Expand all
1188 } 1221 }
1189 1222
1190 /// Gets the value from a [MutableVariable]. 1223 /// Gets the value from a [MutableVariable].
1191 /// 1224 ///
1192 /// [MutableVariable]s can be seen as ref cells that are not first-class 1225 /// [MutableVariable]s can be seen as ref cells that are not first-class
1193 /// values. A [LetPrim] with a [GetMutable] can then be seen as: 1226 /// values. A [LetPrim] with a [GetMutable] can then be seen as:
1194 /// 1227 ///
1195 /// let prim p = ![variable] in [body] 1228 /// let prim p = ![variable] in [body]
1196 /// 1229 ///
1197 class GetMutable extends Primitive { 1230 class GetMutable extends Primitive {
1198 final Reference<MutableVariable> variable; 1231 final Reference<MutableVariable> variableRef;
1232
1233 MutableVariable get variable => variableRef.definition;
1199 1234
1200 GetMutable(MutableVariable variable) 1235 GetMutable(MutableVariable variable)
1201 : this.variable = new Reference<MutableVariable>(variable); 1236 : this.variableRef = new Reference<MutableVariable>(variable);
1202 1237
1203 accept(Visitor visitor) => visitor.visitGetMutable(this); 1238 accept(Visitor visitor) => visitor.visitGetMutable(this);
1204 1239
1205 bool get hasValue => true; 1240 bool get hasValue => true;
1206 bool get isSafeForElimination => true; 1241 bool get isSafeForElimination => true;
1207 bool get isSafeForReordering => false; 1242 bool get isSafeForReordering => false;
1208 1243
1209 void setParentPointers() { 1244 void setParentPointers() {
1210 variable.parent = this; 1245 variableRef.parent = this;
1211 } 1246 }
1212 } 1247 }
1213 1248
1214 /// Assign a [MutableVariable]. 1249 /// Assign a [MutableVariable].
1215 /// 1250 ///
1216 /// [MutableVariable]s can be seen as ref cells that are not first-class 1251 /// [MutableVariable]s can be seen as ref cells that are not first-class
1217 /// values. This can be seen as a dereferencing assignment: 1252 /// values. This can be seen as a dereferencing assignment:
1218 /// 1253 ///
1219 /// { [variable] := [value]; [body] } 1254 /// { [variable] := [value]; [body] }
1220 class SetMutable extends Primitive { 1255 class SetMutable extends Primitive {
1221 final Reference<MutableVariable> variable; 1256 final Reference<MutableVariable> variableRef;
1222 final Reference<Primitive> value; 1257 final Reference<Primitive> valueRef;
1258
1259 MutableVariable get variable => variableRef.definition;
1260 Primitive get value => valueRef.definition;
1223 1261
1224 SetMutable(MutableVariable variable, Primitive value) 1262 SetMutable(MutableVariable variable, Primitive value)
1225 : this.variable = new Reference<MutableVariable>(variable), 1263 : this.variableRef = new Reference<MutableVariable>(variable),
1226 this.value = new Reference<Primitive>(value); 1264 this.valueRef = new Reference<Primitive>(value);
1227 1265
1228 accept(Visitor visitor) => visitor.visitSetMutable(this); 1266 accept(Visitor visitor) => visitor.visitSetMutable(this);
1229 1267
1230 bool get hasValue => false; 1268 bool get hasValue => false;
1231 bool get isSafeForElimination => false; 1269 bool get isSafeForElimination => false;
1232 bool get isSafeForReordering => false; 1270 bool get isSafeForReordering => false;
1233 1271
1234 void setParentPointers() { 1272 void setParentPointers() {
1235 variable.parent = this; 1273 variableRef.parent = this;
1236 value.parent = this; 1274 valueRef.parent = this;
1237 } 1275 }
1238 } 1276 }
1239 1277
1240 /// Invoke a continuation in tail position. 1278 /// Invoke a continuation in tail position.
1241 class InvokeContinuation extends TailExpression { 1279 class InvokeContinuation extends TailExpression {
1242 Reference<Continuation> continuation; 1280 Reference<Continuation> continuationRef;
1243 List<Reference<Primitive>> arguments; 1281 List<Reference<Primitive>> argumentRefs;
1244 SourceInformation sourceInformation; 1282 SourceInformation sourceInformation;
1245 1283
1284 Continuation get continuation => continuationRef.definition;
1285 Primitive argument(int n) => argumentRefs[n].definition;
1286 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1287
1246 // An invocation of a continuation is recursive if it occurs in the body of 1288 // An invocation of a continuation is recursive if it occurs in the body of
1247 // the continuation itself. 1289 // the continuation itself.
1248 bool isRecursive; 1290 bool isRecursive;
1249 1291
1250 /// True if this invocation escapes from the body of a [LetHandler] 1292 /// True if this invocation escapes from the body of a [LetHandler]
1251 /// (i.e. a try block). Notably, such an invocation cannot be inlined. 1293 /// (i.e. a try block). Notably, such an invocation cannot be inlined.
1252 bool isEscapingTry; 1294 bool isEscapingTry;
1253 1295
1254 InvokeContinuation(Continuation cont, List<Primitive> args, 1296 InvokeContinuation(Continuation cont, List<Primitive> args,
1255 {this.isRecursive: false, 1297 {this.isRecursive: false,
1256 this.isEscapingTry: false, 1298 this.isEscapingTry: false,
1257 this.sourceInformation}) 1299 this.sourceInformation})
1258 : continuation = new Reference<Continuation>(cont), 1300 : continuationRef = new Reference<Continuation>(cont),
1259 arguments = _referenceList(args) { 1301 argumentRefs = _referenceList(args) {
1260 assert(cont.parameters == null || cont.parameters.length == args.length); 1302 assert(cont.parameters == null || cont.parameters.length == args.length);
1261 if (isRecursive) cont.isRecursive = true; 1303 if (isRecursive) cont.isRecursive = true;
1262 } 1304 }
1263 1305
1264 /// A continuation invocation whose target and arguments will be filled 1306 /// A continuation invocation whose target and arguments will be filled
1265 /// in later. 1307 /// in later.
1266 /// 1308 ///
1267 /// Used as a placeholder for a jump whose target is not yet created 1309 /// Used as a placeholder for a jump whose target is not yet created
1268 /// (e.g., in the translation of break and continue). 1310 /// (e.g., in the translation of break and continue).
1269 InvokeContinuation.uninitialized({this.isRecursive: false, 1311 InvokeContinuation.uninitialized({this.isRecursive: false,
1270 this.isEscapingTry: false}) 1312 this.isEscapingTry: false})
1271 : continuation = null, 1313 : continuationRef = null,
1272 arguments = null, 1314 argumentRefs = null,
1273 sourceInformation = null; 1315 sourceInformation = null;
1274 1316
1275 accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this); 1317 accept(BlockVisitor visitor) => visitor.visitInvokeContinuation(this);
1276 1318
1277 void setParentPointers() { 1319 void setParentPointers() {
1278 if (continuation != null) continuation.parent = this; 1320 if (continuationRef != null) continuationRef.parent = this;
1279 if (arguments != null) _setParentsOnList(arguments, this); 1321 if (argumentRefs != null) _setParentsOnList(argumentRefs, this);
1280 } 1322 }
1281 } 1323 }
1282 1324
1283 /// Choose between a pair of continuations based on a condition value. 1325 /// Choose between a pair of continuations based on a condition value.
1284 /// 1326 ///
1285 /// The two continuations must not declare any parameters. 1327 /// The two continuations must not declare any parameters.
1286 class Branch extends TailExpression { 1328 class Branch extends TailExpression {
1287 final Reference<Primitive> condition; 1329 final Reference<Primitive> conditionRef;
1288 final Reference<Continuation> trueContinuation; 1330 final Reference<Continuation> trueContinuationRef;
1289 final Reference<Continuation> falseContinuation; 1331 final Reference<Continuation> falseContinuationRef;
1332
1333 Primitive get condition => conditionRef.definition;
1334 Continuation get trueContinuation => trueContinuationRef.definition;
1335 Continuation get falseContinuation => falseContinuationRef.definition;
1290 1336
1291 /// If true, only the value `true` satisfies the condition. Otherwise, any 1337 /// If true, only the value `true` satisfies the condition. Otherwise, any
1292 /// truthy value satisfies the check. 1338 /// truthy value satisfies the check.
1293 /// 1339 ///
1294 /// Non-strict checks are preferable when the condition is known to be a 1340 /// Non-strict checks are preferable when the condition is known to be a
1295 /// boolean. 1341 /// boolean.
1296 bool isStrictCheck; 1342 bool isStrictCheck;
1297 1343
1298 Branch(Primitive condition, 1344 Branch(Primitive condition,
1299 Continuation trueCont, 1345 Continuation trueCont,
1300 Continuation falseCont, 1346 Continuation falseCont,
1301 {bool strict}) 1347 {bool strict})
1302 : this.condition = new Reference<Primitive>(condition), 1348 : this.conditionRef = new Reference<Primitive>(condition),
1303 trueContinuation = new Reference<Continuation>(trueCont), 1349 trueContinuationRef = new Reference<Continuation>(trueCont),
1304 falseContinuation = new Reference<Continuation>(falseCont), 1350 falseContinuationRef = new Reference<Continuation>(falseCont),
1305 isStrictCheck = strict { 1351 isStrictCheck = strict {
1306 assert(strict != null); 1352 assert(strict != null);
1307 } 1353 }
1308 1354
1309 Branch.strict(Primitive condition, 1355 Branch.strict(Primitive condition,
1310 Continuation trueCont, 1356 Continuation trueCont,
1311 Continuation falseCont) 1357 Continuation falseCont)
1312 : this(condition, trueCont, falseCont, strict: true); 1358 : this(condition, trueCont, falseCont, strict: true);
1313 1359
1314 Branch.loose(Primitive condition, 1360 Branch.loose(Primitive condition,
1315 Continuation trueCont, 1361 Continuation trueCont,
1316 Continuation falseCont) 1362 Continuation falseCont)
1317 : this(condition, trueCont, falseCont, strict: false); 1363 : this(condition, trueCont, falseCont, strict: false);
1318 1364
1319 accept(BlockVisitor visitor) => visitor.visitBranch(this); 1365 accept(BlockVisitor visitor) => visitor.visitBranch(this);
1320 1366
1321 void setParentPointers() { 1367 void setParentPointers() {
1322 condition.parent = this; 1368 conditionRef.parent = this;
1323 trueContinuation.parent = this; 1369 trueContinuationRef.parent = this;
1324 falseContinuation.parent = this; 1370 falseContinuationRef.parent = this;
1325 } 1371 }
1326 } 1372 }
1327 1373
1328 /// Directly assigns to a field on a given object. 1374 /// Directly assigns to a field on a given object.
1329 class SetField extends Primitive { 1375 class SetField extends Primitive {
1330 final Reference<Primitive> object; 1376 final Reference<Primitive> objectRef;
1331 FieldElement field; 1377 FieldElement field;
1332 final Reference<Primitive> value; 1378 final Reference<Primitive> valueRef;
1379
1380 Primitive get object => objectRef.definition;
1381 Primitive get value => valueRef.definition;
1333 1382
1334 SetField(Primitive object, this.field, Primitive value) 1383 SetField(Primitive object, this.field, Primitive value)
1335 : this.object = new Reference<Primitive>(object), 1384 : this.objectRef = new Reference<Primitive>(object),
1336 this.value = new Reference<Primitive>(value); 1385 this.valueRef = new Reference<Primitive>(value);
1337 1386
1338 accept(Visitor visitor) => visitor.visitSetField(this); 1387 accept(Visitor visitor) => visitor.visitSetField(this);
1339 1388
1340 bool get hasValue => false; 1389 bool get hasValue => false;
1341 bool get isSafeForElimination => false; 1390 bool get isSafeForElimination => false;
1342 bool get isSafeForReordering => false; 1391 bool get isSafeForReordering => false;
1343 1392
1344 void setParentPointers() { 1393 void setParentPointers() {
1345 object.parent = this; 1394 objectRef.parent = this;
1346 value.parent = this; 1395 valueRef.parent = this;
1347 } 1396 }
1348 1397
1349 int get effects => Effects.changesInstanceField; 1398 int get effects => Effects.changesInstanceField;
1350 } 1399 }
1351 1400
1352 /// Directly reads from a field on a given object. 1401 /// Directly reads from a field on a given object.
1353 /// 1402 ///
1354 /// The [object] must either be `null` or an object that has [field]. 1403 /// The [object] must either be `null` or an object that has [field].
1355 class GetField extends Primitive { 1404 class GetField extends Primitive {
1356 final Reference<Primitive> object; 1405 final Reference<Primitive> objectRef;
1357 FieldElement field; 1406 FieldElement field;
1358 1407
1359 /// True if the field never changes value. 1408 /// True if the field never changes value.
1360 final bool isFinal; 1409 final bool isFinal;
1361 1410
1362 /// True if the object is known not to be null. 1411 /// True if the object is known not to be null.
1363 // TODO(asgerf): This is a placeholder until we agree on how to track 1412 // TODO(asgerf): This is a placeholder until we agree on how to track
1364 // side effects. 1413 // side effects.
1365 bool objectIsNotNull = false; 1414 bool objectIsNotNull = false;
1366 1415
1416 Primitive get object => objectRef.definition;
1417
1367 GetField(Primitive object, this.field, {this.isFinal: false}) 1418 GetField(Primitive object, this.field, {this.isFinal: false})
1368 : this.object = new Reference<Primitive>(object); 1419 : this.objectRef = new Reference<Primitive>(object);
1369 1420
1370 accept(Visitor visitor) => visitor.visitGetField(this); 1421 accept(Visitor visitor) => visitor.visitGetField(this);
1371 1422
1372 bool get hasValue => true; 1423 bool get hasValue => true;
1373 bool get isSafeForElimination => objectIsNotNull; 1424 bool get isSafeForElimination => objectIsNotNull;
1374 bool get isSafeForReordering => false; 1425 bool get isSafeForReordering => false;
1375 1426
1376 toString() => 'GetField($field)'; 1427 toString() => 'GetField($field)';
1377 1428
1378 void setParentPointers() { 1429 void setParentPointers() {
1379 object.parent = this; 1430 objectRef.parent = this;
1380 } 1431 }
1381 1432
1382 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField; 1433 int get effects => isFinal ? 0 : Effects.dependsOnInstanceField;
1383 } 1434 }
1384 1435
1385 /// Get the length of a string or native list. 1436 /// Get the length of a string or native list.
1386 class GetLength extends Primitive { 1437 class GetLength extends Primitive {
1387 final Reference<Primitive> object; 1438 final Reference<Primitive> objectRef;
1388 1439
1389 /// True if the length of the given object can never change. 1440 /// True if the length of the given object can never change.
1390 bool isFinal; 1441 bool isFinal;
1391 1442
1392 /// True if the object is known not to be null. 1443 /// True if the object is known not to be null.
1393 bool objectIsNotNull = false; 1444 bool objectIsNotNull = false;
1394 1445
1446 Primitive get object => objectRef.definition;
1447
1395 GetLength(Primitive object, {this.isFinal: false}) 1448 GetLength(Primitive object, {this.isFinal: false})
1396 : this.object = new Reference<Primitive>(object); 1449 : this.objectRef = new Reference<Primitive>(object);
1397 1450
1398 bool get hasValue => true; 1451 bool get hasValue => true;
1399 bool get isSafeForElimination => objectIsNotNull; 1452 bool get isSafeForElimination => objectIsNotNull;
1400 bool get isSafeForReordering => false; 1453 bool get isSafeForReordering => false;
1401 1454
1402 accept(Visitor v) => v.visitGetLength(this); 1455 accept(Visitor v) => v.visitGetLength(this);
1403 1456
1404 void setParentPointers() { 1457 void setParentPointers() {
1405 object.parent = this; 1458 objectRef.parent = this;
1406 } 1459 }
1407 1460
1408 int get effects => isFinal ? 0 : Effects.dependsOnIndexableLength; 1461 int get effects => isFinal ? 0 : Effects.dependsOnIndexableLength;
1409 } 1462 }
1410 1463
1411 /// Read an entry from an indexable object. 1464 /// Read an entry from an indexable object.
1412 /// 1465 ///
1413 /// [object] must be null or an indexable object, and [index] must be 1466 /// [object] must be null or an indexable object, and [index] must be
1414 /// an integer where `0 <= index < object.length`. 1467 /// an integer where `0 <= index < object.length`.
1415 class GetIndex extends Primitive { 1468 class GetIndex extends Primitive {
1416 final Reference<Primitive> object; 1469 final Reference<Primitive> objectRef;
1417 final Reference<Primitive> index; 1470 final Reference<Primitive> indexRef;
1418 1471
1419 /// True if the object is known not to be null. 1472 /// True if the object is known not to be null.
1420 bool objectIsNotNull = false; 1473 bool objectIsNotNull = false;
1421 1474
1475 Primitive get object => objectRef.definition;
1476 Primitive get index => indexRef.definition;
1477
1422 GetIndex(Primitive object, Primitive index) 1478 GetIndex(Primitive object, Primitive index)
1423 : this.object = new Reference<Primitive>(object), 1479 : this.objectRef = new Reference<Primitive>(object),
1424 this.index = new Reference<Primitive>(index); 1480 this.indexRef = new Reference<Primitive>(index);
1425 1481
1426 bool get hasValue => true; 1482 bool get hasValue => true;
1427 bool get isSafeForElimination => objectIsNotNull; 1483 bool get isSafeForElimination => objectIsNotNull;
1428 bool get isSafeForReordering => false; 1484 bool get isSafeForReordering => false;
1429 1485
1430 accept(Visitor v) => v.visitGetIndex(this); 1486 accept(Visitor v) => v.visitGetIndex(this);
1431 1487
1432 void setParentPointers() { 1488 void setParentPointers() {
1433 object.parent = this; 1489 objectRef.parent = this;
1434 index.parent = this; 1490 indexRef.parent = this;
1435 } 1491 }
1436 1492
1437 int get effects => Effects.dependsOnIndexableContent; 1493 int get effects => Effects.dependsOnIndexableContent;
1438 } 1494 }
1439 1495
1440 /// Set an entry on a native list. 1496 /// Set an entry on a native list.
1441 /// 1497 ///
1442 /// [object] must be null or a native list, and [index] must be an integer 1498 /// [object] must be null or a native list, and [index] must be an integer
1443 /// within the bounds of the indexable object. 1499 /// within the bounds of the indexable object.
1444 /// 1500 ///
1445 /// [SetIndex] may not be used to alter the length of a JS array. 1501 /// [SetIndex] may not be used to alter the length of a JS array.
1446 /// 1502 ///
1447 /// The primitive itself has no value and may not be referenced. 1503 /// The primitive itself has no value and may not be referenced.
1448 class SetIndex extends Primitive { 1504 class SetIndex extends Primitive {
1449 final Reference<Primitive> object; 1505 final Reference<Primitive> objectRef;
1450 final Reference<Primitive> index; 1506 final Reference<Primitive> indexRef;
1451 final Reference<Primitive> value; 1507 final Reference<Primitive> valueRef;
1508
1509 Primitive get object => objectRef.definition;
1510 Primitive get index => indexRef.definition;
1511 Primitive get value => valueRef.definition;
1452 1512
1453 SetIndex(Primitive object, Primitive index, Primitive value) 1513 SetIndex(Primitive object, Primitive index, Primitive value)
1454 : this.object = new Reference<Primitive>(object), 1514 : this.objectRef = new Reference<Primitive>(object),
1455 this.index = new Reference<Primitive>(index), 1515 this.indexRef = new Reference<Primitive>(index),
1456 this.value = new Reference<Primitive>(value); 1516 this.valueRef = new Reference<Primitive>(value);
1457 1517
1458 bool get hasValue => false; 1518 bool get hasValue => false;
1459 bool get isSafeForElimination => false; 1519 bool get isSafeForElimination => false;
1460 bool get isSafeForReordering => false; 1520 bool get isSafeForReordering => false;
1461 1521
1462 accept(Visitor v) => v.visitSetIndex(this); 1522 accept(Visitor v) => v.visitSetIndex(this);
1463 1523
1464 void setParentPointers() { 1524 void setParentPointers() {
1465 object.parent = this; 1525 objectRef.parent = this;
1466 index.parent = this; 1526 indexRef.parent = this;
1467 value.parent = this; 1527 valueRef.parent = this;
1468 } 1528 }
1469 1529
1470 int get effects => Effects.changesIndexableContent; 1530 int get effects => Effects.changesIndexableContent;
1471 } 1531 }
1472 1532
1473 /// Reads the value of a static field or tears off a static method. 1533 /// Reads the value of a static field or tears off a static method.
1474 /// 1534 ///
1475 /// If [GetStatic] is used to load a lazily initialized static field, it must 1535 /// If [GetStatic] is used to load a lazily initialized static field, it must
1476 /// have been initialized beforehand, and a [witness] must be set to restrict 1536 /// have been initialized beforehand, and a [witness] must be set to restrict
1477 /// code motion. 1537 /// code motion.
1478 class GetStatic extends Primitive { 1538 class GetStatic extends Primitive {
1479 /// Can be [FieldElement] or [FunctionElement]. 1539 /// Can be [FieldElement] or [FunctionElement].
1480 final Element element; 1540 final Element element;
1481 final SourceInformation sourceInformation; 1541 final SourceInformation sourceInformation;
1482 1542
1483 /// True if the field never changes value. 1543 /// True if the field never changes value.
1484 final bool isFinal; 1544 final bool isFinal;
1485 1545
1486 /// If reading a lazily initialized field, [witness] must refer to a node 1546 /// If reading a lazily initialized field, [witness] must refer to a node
1487 /// that initializes the field or always occurs after the field initializer. 1547 /// that initializes the field or always occurs after the field initializer.
1488 /// 1548 ///
1489 /// The value of the witness is not used. 1549 /// The value of the witness is not used.
1490 Reference<Primitive> witness; 1550 Reference<Primitive> witnessRef;
1551
1552 Primitive get witness => witnessRef.definition;
1491 1553
1492 GetStatic(this.element, {this.isFinal: false, this.sourceInformation}); 1554 GetStatic(this.element, {this.isFinal: false, this.sourceInformation});
1493 1555
1494 /// Read a lazily initialized static field that is known to have been 1556 /// Read a lazily initialized static field that is known to have been
1495 /// initialized by [witness] or earlier. 1557 /// initialized by [witness] or earlier.
1496 GetStatic.witnessed(this.element, Primitive witness, {this.sourceInformation}) 1558 GetStatic.witnessed(this.element, Primitive witness, {this.sourceInformation})
1497 : witness = witness == null ? null : new Reference<Primitive>(witness), 1559 : witnessRef = _optionalReference(witness),
1498 isFinal = false; 1560 isFinal = false;
1499 1561
1500 accept(Visitor visitor) => visitor.visitGetStatic(this); 1562 accept(Visitor visitor) => visitor.visitGetStatic(this);
1501 1563
1502 bool get hasValue => true; 1564 bool get hasValue => true;
1503 bool get isSafeForElimination => true; 1565 bool get isSafeForElimination => true;
1504 bool get isSafeForReordering => isFinal; 1566 bool get isSafeForReordering => isFinal;
1505 1567
1506 void setParentPointers() { 1568 void setParentPointers() {
1507 if (witness != null) { 1569 if (witnessRef != null) {
1508 witness.parent = this; 1570 witnessRef.parent = this;
1509 } 1571 }
1510 } 1572 }
1511 1573
1512 int get effects => isFinal ? 0 : Effects.dependsOnStaticField; 1574 int get effects => isFinal ? 0 : Effects.dependsOnStaticField;
1513 } 1575 }
1514 1576
1515 /// Sets the value of a static field. 1577 /// Sets the value of a static field.
1516 class SetStatic extends Primitive { 1578 class SetStatic extends Primitive {
1517 final FieldElement element; 1579 final FieldElement element;
1518 final Reference<Primitive> value; 1580 final Reference<Primitive> valueRef;
1519 final SourceInformation sourceInformation; 1581 final SourceInformation sourceInformation;
1520 1582
1583 Primitive get value => valueRef.definition;
1584
1521 SetStatic(this.element, Primitive value, [this.sourceInformation]) 1585 SetStatic(this.element, Primitive value, [this.sourceInformation])
1522 : this.value = new Reference<Primitive>(value); 1586 : this.valueRef = new Reference<Primitive>(value);
1523 1587
1524 accept(Visitor visitor) => visitor.visitSetStatic(this); 1588 accept(Visitor visitor) => visitor.visitSetStatic(this);
1525 1589
1526 bool get hasValue => false; 1590 bool get hasValue => false;
1527 bool get isSafeForElimination => false; 1591 bool get isSafeForElimination => false;
1528 bool get isSafeForReordering => false; 1592 bool get isSafeForReordering => false;
1529 1593
1530 void setParentPointers() { 1594 void setParentPointers() {
1531 value.parent = this; 1595 valueRef.parent = this;
1532 } 1596 }
1533 1597
1534 int get effects => Effects.changesStaticField; 1598 int get effects => Effects.changesStaticField;
1535 } 1599 }
1536 1600
1537 /// Reads the value of a lazily initialized static field. 1601 /// Reads the value of a lazily initialized static field.
1538 /// 1602 ///
1539 /// If the field has not yet been initialized, its initializer is evaluated 1603 /// If the field has not yet been initialized, its initializer is evaluated
1540 /// and assigned to the field. 1604 /// and assigned to the field.
1541 class GetLazyStatic extends UnsafePrimitive { 1605 class GetLazyStatic extends UnsafePrimitive {
(...skipping 26 matching lines...) Expand all
1568 void setParentPointers() {} 1632 void setParentPointers() {}
1569 } 1633 }
1570 1634
1571 /// Creates an instance of a class and initializes its fields and runtime type 1635 /// Creates an instance of a class and initializes its fields and runtime type
1572 /// information. 1636 /// information.
1573 class CreateInstance extends Primitive { 1637 class CreateInstance extends Primitive {
1574 final ClassElement classElement; 1638 final ClassElement classElement;
1575 1639
1576 /// Initial values for the fields on the class. 1640 /// Initial values for the fields on the class.
1577 /// The order corresponds to the order of fields on the class. 1641 /// The order corresponds to the order of fields on the class.
1578 final List<Reference<Primitive>> arguments; 1642 final List<Reference<Primitive>> argumentRefs;
1579 1643
1580 /// The runtime type information structure which contains the type arguments. 1644 /// The runtime type information structure which contains the type arguments.
1581 /// 1645 ///
1582 /// May be `null` to indicate that no type information is needed because the 1646 /// May be `null` to indicate that no type information is needed because the
1583 /// compiler determined that the type information for instances of this class 1647 /// compiler determined that the type information for instances of this class
1584 /// is not needed at runtime. 1648 /// is not needed at runtime.
1585 final Reference<Primitive> typeInformation; 1649 final Reference<Primitive> typeInformationRef;
1586 1650
1587 final SourceInformation sourceInformation; 1651 final SourceInformation sourceInformation;
1588 1652
1653 Primitive argument(int n) => argumentRefs[n].definition;
1654 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1655 Primitive get typeInformation => typeInformationRef?.definition;
1656
1589 CreateInstance(this.classElement, List<Primitive> arguments, 1657 CreateInstance(this.classElement, List<Primitive> arguments,
1590 Primitive typeInformation, 1658 Primitive typeInformation,
1591 this.sourceInformation) 1659 this.sourceInformation)
1592 : this.arguments = _referenceList(arguments), 1660 : this.argumentRefs = _referenceList(arguments),
1593 this.typeInformation = typeInformation == null 1661 this.typeInformationRef = _optionalReference(typeInformation);
1594 ? null
1595 : new Reference<Primitive>(typeInformation);
1596 1662
1597 accept(Visitor visitor) => visitor.visitCreateInstance(this); 1663 accept(Visitor visitor) => visitor.visitCreateInstance(this);
1598 1664
1599 bool get hasValue => true; 1665 bool get hasValue => true;
1600 bool get isSafeForElimination => true; 1666 bool get isSafeForElimination => true;
1601 bool get isSafeForReordering => true; 1667 bool get isSafeForReordering => true;
1602 1668
1603 toString() => 'CreateInstance($classElement)'; 1669 toString() => 'CreateInstance($classElement)';
1604 1670
1605 void setParentPointers() { 1671 void setParentPointers() {
1606 _setParentsOnList(arguments, this); 1672 _setParentsOnList(argumentRefs, this);
1607 if (typeInformation != null) typeInformation.parent = this; 1673 if (typeInformationRef != null) typeInformationRef.parent = this;
1608 } 1674 }
1609 } 1675 }
1610 1676
1611 /// Obtains the interceptor for the given value. This is a method table 1677 /// Obtains the interceptor for the given value. This is a method table
1612 /// corresponding to the Dart class of the value. 1678 /// corresponding to the Dart class of the value.
1613 /// 1679 ///
1614 /// All values are either intercepted or self-intercepted. The interceptor for 1680 /// All values are either intercepted or self-intercepted. The interceptor for
1615 /// an "intercepted value" is one of the subclasses of Interceptor. 1681 /// an "intercepted value" is one of the subclasses of Interceptor.
1616 /// The interceptor for a "self-intercepted value" is the value itself. 1682 /// The interceptor for a "self-intercepted value" is the value itself.
1617 /// 1683 ///
1618 /// If the input is an intercepted value, and any of its superclasses is in 1684 /// If the input is an intercepted value, and any of its superclasses is in
1619 /// [interceptedClasses], the method table for the input is returned. 1685 /// [interceptedClasses], the method table for the input is returned.
1620 /// Otherwise, the input itself is returned. 1686 /// Otherwise, the input itself is returned.
1621 /// 1687 ///
1622 /// There are thus three significant cases: 1688 /// There are thus three significant cases:
1623 /// - the input is a self-interceptor 1689 /// - the input is a self-interceptor
1624 /// - the input is an intercepted value and is caught by [interceptedClasses] 1690 /// - the input is an intercepted value and is caught by [interceptedClasses]
1625 /// - the input is an intercepted value but is bypassed by [interceptedClasses] 1691 /// - the input is an intercepted value but is bypassed by [interceptedClasses]
1626 /// 1692 ///
1627 /// The [flags] field indicates which of the above cases may happen, with 1693 /// The [flags] field indicates which of the above cases may happen, with
1628 /// additional special cases for null (which can either by intercepted or 1694 /// additional special cases for null (which can either by intercepted or
1629 /// bypassed). 1695 /// bypassed).
1630 class Interceptor extends Primitive { 1696 class Interceptor extends Primitive {
1631 final Reference<Primitive> input; 1697 final Reference<Primitive> inputRef;
1632 final Set<ClassElement> interceptedClasses = new Set<ClassElement>(); 1698 final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
1633 final SourceInformation sourceInformation; 1699 final SourceInformation sourceInformation;
1634 1700
1701 Primitive get input => inputRef.definition;
1702
1635 Interceptor(Primitive input, this.sourceInformation) 1703 Interceptor(Primitive input, this.sourceInformation)
1636 : this.input = new Reference<Primitive>(input); 1704 : this.inputRef = new Reference<Primitive>(input);
1637 1705
1638 accept(Visitor visitor) => visitor.visitInterceptor(this); 1706 accept(Visitor visitor) => visitor.visitInterceptor(this);
1639 1707
1640 bool get hasValue => true; 1708 bool get hasValue => true;
1641 bool get isSafeForElimination => true; 1709 bool get isSafeForElimination => true;
1642 bool get isSafeForReordering => true; 1710 bool get isSafeForReordering => true;
1643 1711
1644 void setParentPointers() { 1712 void setParentPointers() {
1645 input.parent = this; 1713 inputRef.parent = this;
1646 } 1714 }
1647 } 1715 }
1648 1716
1649 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. 1717 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`.
1650 class CreateInvocationMirror extends Primitive { 1718 class CreateInvocationMirror extends Primitive {
1651 final Selector selector; 1719 final Selector selector;
1652 final List<Reference<Primitive>> arguments; 1720 final List<Reference<Primitive>> argumentRefs;
1721
1722 Primitive argument(int n) => argumentRefs[n].definition;
1723 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1653 1724
1654 CreateInvocationMirror(this.selector, List<Primitive> arguments) 1725 CreateInvocationMirror(this.selector, List<Primitive> arguments)
1655 : this.arguments = _referenceList(arguments); 1726 : this.argumentRefs = _referenceList(arguments);
1656 1727
1657 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); 1728 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this);
1658 1729
1659 bool get hasValue => true; 1730 bool get hasValue => true;
1660 bool get isSafeForElimination => true; 1731 bool get isSafeForElimination => true;
1661 bool get isSafeForReordering => true; 1732 bool get isSafeForReordering => true;
1662 1733
1663 void setParentPointers() { 1734 void setParentPointers() {
1664 _setParentsOnList(arguments, this); 1735 _setParentsOnList(argumentRefs, this);
1665 } 1736 }
1666 } 1737 }
1667 1738
1668 class ForeignCode extends UnsafePrimitive { 1739 class ForeignCode extends UnsafePrimitive {
1669 final js.Template codeTemplate; 1740 final js.Template codeTemplate;
1670 final TypeMask storedType; 1741 final TypeMask storedType;
1671 final List<Reference<Primitive>> arguments; 1742 final List<Reference<Primitive>> argumentRefs;
1672 final native.NativeBehavior nativeBehavior; 1743 final native.NativeBehavior nativeBehavior;
1673 final FunctionElement dependency; 1744 final FunctionElement dependency;
1674 1745
1746 Primitive argument(int n) => argumentRefs[n].definition;
1747 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1748
1675 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments, 1749 ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments,
1676 this.nativeBehavior, {this.dependency}) 1750 this.nativeBehavior, {this.dependency})
1677 : this.arguments = _referenceList(arguments) { 1751 : this.argumentRefs = _referenceList(arguments) {
1678 effects = Effects.from(nativeBehavior.sideEffects); 1752 effects = Effects.from(nativeBehavior.sideEffects);
1679 } 1753 }
1680 1754
1681 accept(Visitor visitor) => visitor.visitForeignCode(this); 1755 accept(Visitor visitor) => visitor.visitForeignCode(this);
1682 1756
1683 bool get hasValue => true; 1757 bool get hasValue => true;
1684 1758
1685 void setParentPointers() { 1759 void setParentPointers() {
1686 _setParentsOnList(arguments, this); 1760 _setParentsOnList(argumentRefs, this);
1687 } 1761 }
1688 1762
1689 bool isNullGuardOnNullFirstArgument() { 1763 bool isNullGuardOnNullFirstArgument() {
1690 if (arguments.length < 1) return false; 1764 if (argumentRefs.length < 1) return false;
1691 // TODO(sra): Fix NativeThrowBehavior to distinguish MAY from 1765 // TODO(sra): Fix NativeThrowBehavior to distinguish MAY from
1692 // throws-nsm-on-null-followed-by-MAY and remove 1766 // throws-nsm-on-null-followed-by-MAY and remove
1693 // [isNullGuardForFirstArgument]. 1767 // [isNullGuardForFirstArgument].
1694 if (nativeBehavior.throwBehavior.isNullNSMGuard) return true; 1768 if (nativeBehavior.throwBehavior.isNullNSMGuard) return true;
1695 return js.isNullGuardOnFirstArgument(codeTemplate); 1769 return js.isNullGuardOnFirstArgument(codeTemplate);
1696 } 1770 }
1697 } 1771 }
1698 1772
1699 class Constant extends Primitive { 1773 class Constant extends Primitive {
1700 final values.ConstantValue value; 1774 final values.ConstantValue value;
1701 final SourceInformation sourceInformation; 1775 final SourceInformation sourceInformation;
1702 1776
1703 Constant(this.value, {this.sourceInformation}) { 1777 Constant(this.value, {this.sourceInformation}) {
1704 assert(value != null); 1778 assert(value != null);
1705 } 1779 }
1706 1780
1707 accept(Visitor visitor) => visitor.visitConstant(this); 1781 accept(Visitor visitor) => visitor.visitConstant(this);
1708 1782
1709 bool get hasValue => true; 1783 bool get hasValue => true;
1710 bool get isSafeForElimination => true; 1784 bool get isSafeForElimination => true;
1711 bool get isSafeForReordering => true; 1785 bool get isSafeForReordering => true;
1712 1786
1713 void setParentPointers() {} 1787 void setParentPointers() {}
1714 } 1788 }
1715 1789
1716 class LiteralList extends Primitive { 1790 class LiteralList extends Primitive {
1717 /// The List type being created; this is not the type argument. 1791 /// The List type being created; this is not the type argument.
1718 final InterfaceType dartType; 1792 final InterfaceType dartType;
1719 final List<Reference<Primitive>> values; 1793 final List<Reference<Primitive>> valueRefs;
1720 1794
1721 /// If non-null, this is an allocation site-specific type for the list 1795 /// If non-null, this is an allocation site-specific type for the list
1722 /// created here. 1796 /// created here.
1723 TypeMask allocationSiteType; 1797 TypeMask allocationSiteType;
1724 1798
1799 Primitive value(int n) => valueRefs[n].definition;
1800 Iterable<Primitive> get values => _dereferenceList(valueRefs);
1801
1725 LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType}) 1802 LiteralList(this.dartType, List<Primitive> values, {this.allocationSiteType})
1726 : this.values = _referenceList(values); 1803 : this.valueRefs = _referenceList(values);
1727 1804
1728 accept(Visitor visitor) => visitor.visitLiteralList(this); 1805 accept(Visitor visitor) => visitor.visitLiteralList(this);
1729 1806
1730 bool get hasValue => true; 1807 bool get hasValue => true;
1731 bool get isSafeForElimination => true; 1808 bool get isSafeForElimination => true;
1732 bool get isSafeForReordering => true; 1809 bool get isSafeForReordering => true;
1733 1810
1734 void setParentPointers() { 1811 void setParentPointers() {
1735 _setParentsOnList(values, this); 1812 _setParentsOnList(valueRefs, this);
1736 } 1813 }
1737 } 1814 }
1738 1815
1739 class Parameter extends Primitive { 1816 class Parameter extends Primitive {
1740 Parameter(Entity hint) { 1817 Parameter(Entity hint) {
1741 super.hint = hint; 1818 super.hint = hint;
1742 } 1819 }
1743 1820
1744 accept(Visitor visitor) => visitor.visitParameter(this); 1821 accept(Visitor visitor) => visitor.visitParameter(this);
1745 1822
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 returnContinuation.parent = this; 1927 returnContinuation.parent = this;
1851 if (body != null) body.parent = this; 1928 if (body != null) body.parent = this;
1852 } 1929 }
1853 } 1930 }
1854 1931
1855 /// Converts the internal representation of a type to a Dart object of type 1932 /// Converts the internal representation of a type to a Dart object of type
1856 /// [Type]. 1933 /// [Type].
1857 class ReifyRuntimeType extends Primitive { 1934 class ReifyRuntimeType extends Primitive {
1858 /// Reference to the internal representation of a type (as produced, for 1935 /// Reference to the internal representation of a type (as produced, for
1859 /// example, by [ReadTypeVariable]). 1936 /// example, by [ReadTypeVariable]).
1860 final Reference<Primitive> value; 1937 final Reference<Primitive> valueRef;
1861 1938
1862 final SourceInformation sourceInformation; 1939 final SourceInformation sourceInformation;
1863 1940
1941 Primitive get value => valueRef.definition;
1942
1864 ReifyRuntimeType(Primitive value, this.sourceInformation) 1943 ReifyRuntimeType(Primitive value, this.sourceInformation)
1865 : this.value = new Reference<Primitive>(value); 1944 : this.valueRef = new Reference<Primitive>(value);
1866 1945
1867 @override 1946 @override
1868 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); 1947 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
1869 1948
1870 bool get hasValue => true; 1949 bool get hasValue => true;
1871 bool get isSafeForElimination => true; 1950 bool get isSafeForElimination => true;
1872 bool get isSafeForReordering => true; 1951 bool get isSafeForReordering => true;
1873 1952
1874 void setParentPointers() { 1953 void setParentPointers() {
1875 value.parent = this; 1954 valueRef.parent = this;
1876 } 1955 }
1877 } 1956 }
1878 1957
1879 /// Read the value the type variable [variable] from the target object. 1958 /// Read the value the type variable [variable] from the target object.
1880 /// 1959 ///
1881 /// The resulting value is an internal representation (and not neccessarily a 1960 /// The resulting value is an internal representation (and not neccessarily a
1882 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be 1961 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be
1883 /// used as a Dart value. 1962 /// used as a Dart value.
1884 class ReadTypeVariable extends Primitive { 1963 class ReadTypeVariable extends Primitive {
1885 final TypeVariableType variable; 1964 final TypeVariableType variable;
1886 final Reference<Primitive> target; 1965 final Reference<Primitive> targetRef;
1887 final SourceInformation sourceInformation; 1966 final SourceInformation sourceInformation;
1888 1967
1968 Primitive get target => targetRef.definition;
1969
1889 ReadTypeVariable(this.variable, Primitive target, this.sourceInformation) 1970 ReadTypeVariable(this.variable, Primitive target, this.sourceInformation)
1890 : this.target = new Reference<Primitive>(target); 1971 : this.targetRef = new Reference<Primitive>(target);
1891 1972
1892 @override 1973 @override
1893 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); 1974 accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
1894 1975
1895 bool get hasValue => true; 1976 bool get hasValue => true;
1896 bool get isSafeForElimination => true; 1977 bool get isSafeForElimination => true;
1897 bool get isSafeForReordering => true; 1978 bool get isSafeForReordering => true;
1898 1979
1899 void setParentPointers() { 1980 void setParentPointers() {
1900 target.parent = this; 1981 targetRef.parent = this;
1901 } 1982 }
1902 } 1983 }
1903 1984
1904 enum TypeExpressionKind { 1985 enum TypeExpressionKind {
1905 COMPLETE, 1986 COMPLETE,
1906 INSTANCE 1987 INSTANCE
1907 } 1988 }
1908 1989
1909 /// Constructs a representation of a closed or ground-term type (that is, a type 1990 /// Constructs a representation of a closed or ground-term type (that is, a type
1910 /// without type variables). 1991 /// without type variables).
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 /// TypeExpression(COMPLETE, // E3 = List<T> 2033 /// TypeExpression(COMPLETE, // E3 = List<T>
1953 /// dartType: List<E2>, 2034 /// dartType: List<E2>,
1954 /// ReadTypeVariable(this, T)))) // E2 = T 2035 /// ReadTypeVariable(this, T)))) // E2 = T
1955 // 2036 //
1956 // TODO(sra): The INSTANCE form requires the actual instance for full 2037 // TODO(sra): The INSTANCE form requires the actual instance for full
1957 // interpretation. I want to move to a representation where the INSTANCE form is 2038 // interpretation. I want to move to a representation where the INSTANCE form is
1958 // also a complete form (possibly the same). 2039 // also a complete form (possibly the same).
1959 class TypeExpression extends Primitive { 2040 class TypeExpression extends Primitive {
1960 final TypeExpressionKind kind; 2041 final TypeExpressionKind kind;
1961 final DartType dartType; 2042 final DartType dartType;
1962 final List<Reference<Primitive>> arguments; 2043 final List<Reference<Primitive>> argumentRefs;
2044
2045 Primitive argument(int n) => argumentRefs[n].definition;
2046 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
1963 2047
1964 TypeExpression(this.kind, 2048 TypeExpression(this.kind,
1965 this.dartType, 2049 this.dartType,
1966 List<Primitive> arguments) 2050 List<Primitive> arguments)
1967 : this.arguments = _referenceList(arguments) { 2051 : this.argumentRefs = _referenceList(arguments) {
1968 assert(kind == TypeExpressionKind.INSTANCE 2052 assert(kind == TypeExpressionKind.INSTANCE
1969 ? dartType == (dartType.element as ClassElement).thisType 2053 ? dartType == (dartType.element as ClassElement).thisType
1970 : true); 2054 : true);
1971 } 2055 }
1972 2056
1973 @override 2057 @override
1974 accept(Visitor visitor) { 2058 accept(Visitor visitor) {
1975 return visitor.visitTypeExpression(this); 2059 return visitor.visitTypeExpression(this);
1976 } 2060 }
1977 2061
1978 bool get hasValue => true; 2062 bool get hasValue => true;
1979 bool get isSafeForElimination => true; 2063 bool get isSafeForElimination => true;
1980 bool get isSafeForReordering => true; 2064 bool get isSafeForReordering => true;
1981 2065
1982 void setParentPointers() { 2066 void setParentPointers() {
1983 _setParentsOnList(arguments, this); 2067 _setParentsOnList(argumentRefs, this);
1984 } 2068 }
1985 2069
1986 String get kindAsString { 2070 String get kindAsString {
1987 switch (kind) { 2071 switch (kind) {
1988 case TypeExpressionKind.COMPLETE: return 'COMPLETE'; 2072 case TypeExpressionKind.COMPLETE: return 'COMPLETE';
1989 case TypeExpressionKind.INSTANCE: return 'INSTANCE'; 2073 case TypeExpressionKind.INSTANCE: return 'INSTANCE';
1990 } 2074 }
1991 } 2075 }
1992 } 2076 }
1993 2077
1994 class Await extends UnsafePrimitive { 2078 class Await extends UnsafePrimitive {
1995 final Reference<Primitive> input; 2079 final Reference<Primitive> inputRef;
2080
2081 Primitive get input => inputRef.definition;
1996 2082
1997 Await(Primitive input) 2083 Await(Primitive input)
1998 : this.input = new Reference<Primitive>(input); 2084 : this.inputRef = new Reference<Primitive>(input);
1999 2085
2000 @override 2086 @override
2001 accept(Visitor visitor) { 2087 accept(Visitor visitor) {
2002 return visitor.visitAwait(this); 2088 return visitor.visitAwait(this);
2003 } 2089 }
2004 2090
2005 bool get hasValue => true; 2091 bool get hasValue => true;
2006 2092
2007 void setParentPointers() { 2093 void setParentPointers() {
2008 input.parent = this; 2094 inputRef.parent = this;
2009 } 2095 }
2010 } 2096 }
2011 2097
2012 class Yield extends UnsafePrimitive { 2098 class Yield extends UnsafePrimitive {
2013 final Reference<Primitive> input; 2099 final Reference<Primitive> inputRef;
2014 final bool hasStar; 2100 final bool hasStar;
2015 2101
2102 Primitive get input => inputRef.definition;
2103
2016 Yield(Primitive input, this.hasStar) 2104 Yield(Primitive input, this.hasStar)
2017 : this.input = new Reference<Primitive>(input); 2105 : this.inputRef = new Reference<Primitive>(input);
2018 2106
2019 @override 2107 @override
2020 accept(Visitor visitor) { 2108 accept(Visitor visitor) {
2021 return visitor.visitYield(this); 2109 return visitor.visitYield(this);
2022 } 2110 }
2023 2111
2024 bool get hasValue => true; 2112 bool get hasValue => true;
2025 2113
2026 void setParentPointers() { 2114 void setParentPointers() {
2027 input.parent = this; 2115 inputRef.parent = this;
2028 } 2116 }
2029 } 2117 }
2030 2118
2031 Reference<Primitive> _reference(Primitive definition) { 2119 Reference<Primitive> _reference(Primitive definition) {
2032 return new Reference<Primitive>(definition); 2120 return new Reference<Primitive>(definition);
2033 } 2121 }
2034 2122
2035 Reference<Primitive> _optionalReference(Primitive definition) { 2123 Reference<Primitive> _optionalReference(Primitive definition) {
2036 return definition == null 2124 return definition == null
2037 ? null 2125 ? null
2038 : new Reference<Primitive>(definition); 2126 : new Reference<Primitive>(definition);
2039 } 2127 }
2040 2128
2041 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { 2129 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
2042 return definitions.map((e) => new Reference<Primitive>(e)).toList(); 2130 return definitions.map((e) => new Reference<Primitive>(e)).toList();
2043 } 2131 }
2044 2132
2133 Iterable<Primitive> _dereferenceList(List<Reference<Primitive>> references) {
2134 return references.map((ref) => ref.definition);
2135 }
2136
2045 void _setParentsOnNodes(List<Node> nodes, Node parent) { 2137 void _setParentsOnNodes(List<Node> nodes, Node parent) {
2046 for (Node node in nodes) { 2138 for (Node node in nodes) {
2047 node.parent = parent; 2139 node.parent = parent;
2048 } 2140 }
2049 } 2141 }
2050 2142
2051 void _setParentsOnList(List<Reference> nodes, Node parent) { 2143 void _setParentsOnList(List<Reference> nodes, Node parent) {
2052 for (Reference node in nodes) { 2144 for (Reference node in nodes) {
2053 node.parent = parent; 2145 node.parent = parent;
2054 } 2146 }
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 visitLetHandler(LetHandler node) { 2336 visitLetHandler(LetHandler node) {
2245 processLetHandler(node); 2337 processLetHandler(node);
2246 visit(node.handler); 2338 visit(node.handler);
2247 visit(node.body); 2339 visit(node.body);
2248 } 2340 }
2249 2341
2250 processLetMutable(LetMutable node) {} 2342 processLetMutable(LetMutable node) {}
2251 visitLetMutable(LetMutable node) { 2343 visitLetMutable(LetMutable node) {
2252 processLetMutable(node); 2344 processLetMutable(node);
2253 visit(node.variable); 2345 visit(node.variable);
2254 processReference(node.value); 2346 processReference(node.valueRef);
2255 visit(node.body); 2347 visit(node.body);
2256 } 2348 }
2257 2349
2258 processInvokeStatic(InvokeStatic node) {} 2350 processInvokeStatic(InvokeStatic node) {}
2259 visitInvokeStatic(InvokeStatic node) { 2351 visitInvokeStatic(InvokeStatic node) {
2260 processInvokeStatic(node); 2352 processInvokeStatic(node);
2261 node.arguments.forEach(processReference); 2353 node.argumentRefs.forEach(processReference);
2262 } 2354 }
2263 2355
2264 processInvokeContinuation(InvokeContinuation node) {} 2356 processInvokeContinuation(InvokeContinuation node) {}
2265 visitInvokeContinuation(InvokeContinuation node) { 2357 visitInvokeContinuation(InvokeContinuation node) {
2266 processInvokeContinuation(node); 2358 processInvokeContinuation(node);
2267 processReference(node.continuation); 2359 processReference(node.continuationRef);
2268 node.arguments.forEach(processReference); 2360 node.argumentRefs.forEach(processReference);
2269 } 2361 }
2270 2362
2271 processInvokeMethod(InvokeMethod node) {} 2363 processInvokeMethod(InvokeMethod node) {}
2272 visitInvokeMethod(InvokeMethod node) { 2364 visitInvokeMethod(InvokeMethod node) {
2273 processInvokeMethod(node); 2365 processInvokeMethod(node);
2274 processReference(node.receiver); 2366 processReference(node.receiverRef);
2275 node.arguments.forEach(processReference); 2367 node.argumentRefs.forEach(processReference);
2276 } 2368 }
2277 2369
2278 processInvokeMethodDirectly(InvokeMethodDirectly node) {} 2370 processInvokeMethodDirectly(InvokeMethodDirectly node) {}
2279 visitInvokeMethodDirectly(InvokeMethodDirectly node) { 2371 visitInvokeMethodDirectly(InvokeMethodDirectly node) {
2280 processInvokeMethodDirectly(node); 2372 processInvokeMethodDirectly(node);
2281 processReference(node.receiver); 2373 processReference(node.receiverRef);
2282 node.arguments.forEach(processReference); 2374 node.argumentRefs.forEach(processReference);
2283 } 2375 }
2284 2376
2285 processInvokeConstructor(InvokeConstructor node) {} 2377 processInvokeConstructor(InvokeConstructor node) {}
2286 visitInvokeConstructor(InvokeConstructor node) { 2378 visitInvokeConstructor(InvokeConstructor node) {
2287 processInvokeConstructor(node); 2379 processInvokeConstructor(node);
2288 node.arguments.forEach(processReference); 2380 node.argumentRefs.forEach(processReference);
2289 } 2381 }
2290 2382
2291 processThrow(Throw node) {} 2383 processThrow(Throw node) {}
2292 visitThrow(Throw node) { 2384 visitThrow(Throw node) {
2293 processThrow(node); 2385 processThrow(node);
2294 processReference(node.value); 2386 processReference(node.valueRef);
2295 } 2387 }
2296 2388
2297 processRethrow(Rethrow node) {} 2389 processRethrow(Rethrow node) {}
2298 visitRethrow(Rethrow node) { 2390 visitRethrow(Rethrow node) {
2299 processRethrow(node); 2391 processRethrow(node);
2300 } 2392 }
2301 2393
2302 processBranch(Branch node) {} 2394 processBranch(Branch node) {}
2303 visitBranch(Branch node) { 2395 visitBranch(Branch node) {
2304 processBranch(node); 2396 processBranch(node);
2305 processReference(node.trueContinuation); 2397 processReference(node.trueContinuationRef);
2306 processReference(node.falseContinuation); 2398 processReference(node.falseContinuationRef);
2307 processReference(node.condition); 2399 processReference(node.conditionRef);
2308 } 2400 }
2309 2401
2310 processTypeCast(TypeCast node) {} 2402 processTypeCast(TypeCast node) {}
2311 visitTypeCast(TypeCast node) { 2403 visitTypeCast(TypeCast node) {
2312 processTypeCast(node); 2404 processTypeCast(node);
2313 processReference(node.value); 2405 processReference(node.valueRef);
2314 node.typeArguments.forEach(processReference); 2406 node.typeArgumentRefs.forEach(processReference);
2315 } 2407 }
2316 2408
2317 processTypeTest(TypeTest node) {} 2409 processTypeTest(TypeTest node) {}
2318 visitTypeTest(TypeTest node) { 2410 visitTypeTest(TypeTest node) {
2319 processTypeTest(node); 2411 processTypeTest(node);
2320 processReference(node.value); 2412 processReference(node.valueRef);
2321 node.typeArguments.forEach(processReference); 2413 node.typeArgumentRefs.forEach(processReference);
2322 } 2414 }
2323 2415
2324 processTypeTestViaFlag(TypeTestViaFlag node) {} 2416 processTypeTestViaFlag(TypeTestViaFlag node) {}
2325 visitTypeTestViaFlag(TypeTestViaFlag node) { 2417 visitTypeTestViaFlag(TypeTestViaFlag node) {
2326 processTypeTestViaFlag(node); 2418 processTypeTestViaFlag(node);
2327 processReference(node.interceptor); 2419 processReference(node.interceptorRef);
2328 } 2420 }
2329 2421
2330 processSetMutable(SetMutable node) {} 2422 processSetMutable(SetMutable node) {}
2331 visitSetMutable(SetMutable node) { 2423 visitSetMutable(SetMutable node) {
2332 processSetMutable(node); 2424 processSetMutable(node);
2333 processReference(node.variable); 2425 processReference(node.variableRef);
2334 processReference(node.value); 2426 processReference(node.valueRef);
2335 } 2427 }
2336 2428
2337 processGetLazyStatic(GetLazyStatic node) {} 2429 processGetLazyStatic(GetLazyStatic node) {}
2338 visitGetLazyStatic(GetLazyStatic node) { 2430 visitGetLazyStatic(GetLazyStatic node) {
2339 processGetLazyStatic(node); 2431 processGetLazyStatic(node);
2340 } 2432 }
2341 2433
2342 processLiteralList(LiteralList node) {} 2434 processLiteralList(LiteralList node) {}
2343 visitLiteralList(LiteralList node) { 2435 visitLiteralList(LiteralList node) {
2344 processLiteralList(node); 2436 processLiteralList(node);
2345 node.values.forEach(processReference); 2437 node.valueRefs.forEach(processReference);
2346 } 2438 }
2347 2439
2348 processConstant(Constant node) {} 2440 processConstant(Constant node) {}
2349 visitConstant(Constant node) { 2441 visitConstant(Constant node) {
2350 processConstant(node); 2442 processConstant(node);
2351 } 2443 }
2352 2444
2353 processMutableVariable(node) {} 2445 processMutableVariable(node) {}
2354 visitMutableVariable(MutableVariable node) { 2446 visitMutableVariable(MutableVariable node) {
2355 processMutableVariable(node); 2447 processMutableVariable(node);
2356 } 2448 }
2357 2449
2358 processGetMutable(GetMutable node) {} 2450 processGetMutable(GetMutable node) {}
2359 visitGetMutable(GetMutable node) { 2451 visitGetMutable(GetMutable node) {
2360 processGetMutable(node); 2452 processGetMutable(node);
2361 processReference(node.variable); 2453 processReference(node.variableRef);
2362 } 2454 }
2363 2455
2364 processParameter(Parameter node) {} 2456 processParameter(Parameter node) {}
2365 visitParameter(Parameter node) { 2457 visitParameter(Parameter node) {
2366 processParameter(node); 2458 processParameter(node);
2367 } 2459 }
2368 2460
2369 processInterceptor(Interceptor node) {} 2461 processInterceptor(Interceptor node) {}
2370 visitInterceptor(Interceptor node) { 2462 visitInterceptor(Interceptor node) {
2371 processInterceptor(node); 2463 processInterceptor(node);
2372 processReference(node.input); 2464 processReference(node.inputRef);
2373 } 2465 }
2374 2466
2375 processCreateInstance(CreateInstance node) {} 2467 processCreateInstance(CreateInstance node) {}
2376 visitCreateInstance(CreateInstance node) { 2468 visitCreateInstance(CreateInstance node) {
2377 processCreateInstance(node); 2469 processCreateInstance(node);
2378 node.arguments.forEach(processReference); 2470 node.argumentRefs.forEach(processReference);
2379 if (node.typeInformation != null) processReference(node.typeInformation); 2471 if (node.typeInformationRef != null) {
2472 processReference(node.typeInformationRef);
2473 }
2380 } 2474 }
2381 2475
2382 processSetField(SetField node) {} 2476 processSetField(SetField node) {}
2383 visitSetField(SetField node) { 2477 visitSetField(SetField node) {
2384 processSetField(node); 2478 processSetField(node);
2385 processReference(node.object); 2479 processReference(node.objectRef);
2386 processReference(node.value); 2480 processReference(node.valueRef);
2387 } 2481 }
2388 2482
2389 processGetField(GetField node) {} 2483 processGetField(GetField node) {}
2390 visitGetField(GetField node) { 2484 visitGetField(GetField node) {
2391 processGetField(node); 2485 processGetField(node);
2392 processReference(node.object); 2486 processReference(node.objectRef);
2393 } 2487 }
2394 2488
2395 processGetStatic(GetStatic node) {} 2489 processGetStatic(GetStatic node) {}
2396 visitGetStatic(GetStatic node) { 2490 visitGetStatic(GetStatic node) {
2397 processGetStatic(node); 2491 processGetStatic(node);
2398 if (node.witness != null) { 2492 if (node.witnessRef != null) {
2399 processReference(node.witness); 2493 processReference(node.witnessRef);
2400 } 2494 }
2401 } 2495 }
2402 2496
2403 processSetStatic(SetStatic node) {} 2497 processSetStatic(SetStatic node) {}
2404 visitSetStatic(SetStatic node) { 2498 visitSetStatic(SetStatic node) {
2405 processSetStatic(node); 2499 processSetStatic(node);
2406 processReference(node.value); 2500 processReference(node.valueRef);
2407 } 2501 }
2408 2502
2409 processCreateBox(CreateBox node) {} 2503 processCreateBox(CreateBox node) {}
2410 visitCreateBox(CreateBox node) { 2504 visitCreateBox(CreateBox node) {
2411 processCreateBox(node); 2505 processCreateBox(node);
2412 } 2506 }
2413 2507
2414 processReifyRuntimeType(ReifyRuntimeType node) {} 2508 processReifyRuntimeType(ReifyRuntimeType node) {}
2415 visitReifyRuntimeType(ReifyRuntimeType node) { 2509 visitReifyRuntimeType(ReifyRuntimeType node) {
2416 processReifyRuntimeType(node); 2510 processReifyRuntimeType(node);
2417 processReference(node.value); 2511 processReference(node.valueRef);
2418 } 2512 }
2419 2513
2420 processReadTypeVariable(ReadTypeVariable node) {} 2514 processReadTypeVariable(ReadTypeVariable node) {}
2421 visitReadTypeVariable(ReadTypeVariable node) { 2515 visitReadTypeVariable(ReadTypeVariable node) {
2422 processReadTypeVariable(node); 2516 processReadTypeVariable(node);
2423 processReference(node.target); 2517 processReference(node.targetRef);
2424 } 2518 }
2425 2519
2426 processTypeExpression(TypeExpression node) {} 2520 processTypeExpression(TypeExpression node) {}
2427 visitTypeExpression(TypeExpression node) { 2521 visitTypeExpression(TypeExpression node) {
2428 processTypeExpression(node); 2522 processTypeExpression(node);
2429 node.arguments.forEach(processReference); 2523 node.argumentRefs.forEach(processReference);
2430 } 2524 }
2431 2525
2432 processCreateInvocationMirror(CreateInvocationMirror node) {} 2526 processCreateInvocationMirror(CreateInvocationMirror node) {}
2433 visitCreateInvocationMirror(CreateInvocationMirror node) { 2527 visitCreateInvocationMirror(CreateInvocationMirror node) {
2434 processCreateInvocationMirror(node); 2528 processCreateInvocationMirror(node);
2435 node.arguments.forEach(processReference); 2529 node.argumentRefs.forEach(processReference);
2436 } 2530 }
2437 2531
2438 processApplyBuiltinOperator(ApplyBuiltinOperator node) {} 2532 processApplyBuiltinOperator(ApplyBuiltinOperator node) {}
2439 visitApplyBuiltinOperator(ApplyBuiltinOperator node) { 2533 visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
2440 processApplyBuiltinOperator(node); 2534 processApplyBuiltinOperator(node);
2441 node.arguments.forEach(processReference); 2535 node.argumentRefs.forEach(processReference);
2442 } 2536 }
2443 2537
2444 processApplyBuiltinMethod(ApplyBuiltinMethod node) {} 2538 processApplyBuiltinMethod(ApplyBuiltinMethod node) {}
2445 visitApplyBuiltinMethod(ApplyBuiltinMethod node) { 2539 visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
2446 processApplyBuiltinMethod(node); 2540 processApplyBuiltinMethod(node);
2447 processReference(node.receiver); 2541 processReference(node.receiverRef);
2448 node.arguments.forEach(processReference); 2542 node.argumentRefs.forEach(processReference);
2449 } 2543 }
2450 2544
2451 processForeignCode(ForeignCode node) {} 2545 processForeignCode(ForeignCode node) {}
2452 visitForeignCode(ForeignCode node) { 2546 visitForeignCode(ForeignCode node) {
2453 processForeignCode(node); 2547 processForeignCode(node);
2454 node.arguments.forEach(processReference); 2548 node.argumentRefs.forEach(processReference);
2455 } 2549 }
2456 2550
2457 processUnreachable(Unreachable node) {} 2551 processUnreachable(Unreachable node) {}
2458 visitUnreachable(Unreachable node) { 2552 visitUnreachable(Unreachable node) {
2459 processUnreachable(node); 2553 processUnreachable(node);
2460 } 2554 }
2461 2555
2462 processAwait(Await node) {} 2556 processAwait(Await node) {}
2463 visitAwait(Await node) { 2557 visitAwait(Await node) {
2464 processAwait(node); 2558 processAwait(node);
2465 processReference(node.input); 2559 processReference(node.inputRef);
2466 } 2560 }
2467 2561
2468 processYield(Yield node) {} 2562 processYield(Yield node) {}
2469 visitYield(Yield node) { 2563 visitYield(Yield node) {
2470 processYield(node); 2564 processYield(node);
2471 processReference(node.input); 2565 processReference(node.inputRef);
2472 } 2566 }
2473 2567
2474 processGetLength(GetLength node) {} 2568 processGetLength(GetLength node) {}
2475 visitGetLength(GetLength node) { 2569 visitGetLength(GetLength node) {
2476 processGetLength(node); 2570 processGetLength(node);
2477 processReference(node.object); 2571 processReference(node.objectRef);
2478 } 2572 }
2479 2573
2480 processGetIndex(GetIndex node) {} 2574 processGetIndex(GetIndex node) {}
2481 visitGetIndex(GetIndex node) { 2575 visitGetIndex(GetIndex node) {
2482 processGetIndex(node); 2576 processGetIndex(node);
2483 processReference(node.object); 2577 processReference(node.objectRef);
2484 processReference(node.index); 2578 processReference(node.indexRef);
2485 } 2579 }
2486 2580
2487 processSetIndex(SetIndex node) {} 2581 processSetIndex(SetIndex node) {}
2488 visitSetIndex(SetIndex node) { 2582 visitSetIndex(SetIndex node) {
2489 processSetIndex(node); 2583 processSetIndex(node);
2490 processReference(node.object); 2584 processReference(node.objectRef);
2491 processReference(node.index); 2585 processReference(node.indexRef);
2492 processReference(node.value); 2586 processReference(node.valueRef);
2493 } 2587 }
2494 2588
2495 processRefinement(Refinement node) {} 2589 processRefinement(Refinement node) {}
2496 visitRefinement(Refinement node) { 2590 visitRefinement(Refinement node) {
2497 processRefinement(node); 2591 processRefinement(node);
2498 processReference(node.value); 2592 processReference(node.value);
2499 } 2593 }
2500 2594
2501 processBoundsCheck(BoundsCheck node) {} 2595 processBoundsCheck(BoundsCheck node) {}
2502 visitBoundsCheck(BoundsCheck node) { 2596 visitBoundsCheck(BoundsCheck node) {
2503 processBoundsCheck(node); 2597 processBoundsCheck(node);
2504 processReference(node.object); 2598 processReference(node.objectRef);
2505 if (node.index != null) { 2599 if (node.indexRef != null) {
2506 processReference(node.index); 2600 processReference(node.indexRef);
2507 } 2601 }
2508 if (node.length != null) { 2602 if (node.lengthRef != null) {
2509 processReference(node.length); 2603 processReference(node.lengthRef);
2510 } 2604 }
2511 } 2605 }
2512 2606
2513 processNullCheck(ReceiverCheck node) {} 2607 processNullCheck(ReceiverCheck node) {}
2514 visitReceiverCheck(ReceiverCheck node) { 2608 visitReceiverCheck(ReceiverCheck node) {
2515 processNullCheck(node); 2609 processNullCheck(node);
2516 processReference(node.value); 2610 processReference(node.valueRef);
2517 if (node.condition != null) { 2611 if (node.conditionRef != null) {
2518 processReference(node.condition); 2612 processReference(node.conditionRef);
2519 } 2613 }
2520 } 2614 }
2521 } 2615 }
2522 2616
2523 typedef void StackAction(); 2617 typedef void StackAction();
2524 2618
2525 /// Calls `process*` for all nodes in a tree. 2619 /// Calls `process*` for all nodes in a tree.
2526 /// For simple usage, only override the `process*` methods. 2620 /// For simple usage, only override the `process*` methods.
2527 /// 2621 ///
2528 /// To avoid deep recursion, this class uses an "action stack" containing 2622 /// To avoid deep recursion, this class uses an "action stack" containing
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2604 2698
2605 Expression traverseLetPrim(LetPrim node) { 2699 Expression traverseLetPrim(LetPrim node) {
2606 processLetPrim(node); 2700 processLetPrim(node);
2607 visit(node.primitive); 2701 visit(node.primitive);
2608 return node.body; 2702 return node.body;
2609 } 2703 }
2610 2704
2611 Expression traverseLetMutable(LetMutable node) { 2705 Expression traverseLetMutable(LetMutable node) {
2612 processLetMutable(node); 2706 processLetMutable(node);
2613 visit(node.variable); 2707 visit(node.variable);
2614 processReference(node.value); 2708 processReference(node.valueRef);
2615 return node.body; 2709 return node.body;
2616 } 2710 }
2617 2711
2618 void _trampoline(Expression node, {int initialHeight}) { 2712 void _trampoline(Expression node, {int initialHeight}) {
2619 initialHeight = initialHeight ?? _stack.length; 2713 initialHeight = initialHeight ?? _stack.length;
2620 _processBlock(node); 2714 _processBlock(node);
2621 while (_stack.length > initialHeight) { 2715 while (_stack.length > initialHeight) {
2622 StackAction callback = _stack.removeLast(); 2716 StackAction callback = _stack.removeLast();
2623 callback(); 2717 callback();
2624 } 2718 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 visitLetHandler(LetHandler node) {} 2793 visitLetHandler(LetHandler node) {}
2700 visitLetMutable(LetMutable node) {} 2794 visitLetMutable(LetMutable node) {}
2701 visitInvokeContinuation(InvokeContinuation node) {} 2795 visitInvokeContinuation(InvokeContinuation node) {}
2702 visitThrow(Throw node) {} 2796 visitThrow(Throw node) {}
2703 visitRethrow(Rethrow node) {} 2797 visitRethrow(Rethrow node) {}
2704 visitBranch(Branch node) {} 2798 visitBranch(Branch node) {}
2705 visitUnreachable(Unreachable node) {} 2799 visitUnreachable(Unreachable node) {}
2706 visitContinuation(Continuation node) {} 2800 visitContinuation(Continuation node) {}
2707 2801
2708 Definition visitInvokeStatic(InvokeStatic node) { 2802 Definition visitInvokeStatic(InvokeStatic node) {
2709 return new InvokeStatic(node.target, node.selector, getList(node.arguments), 2803 return new InvokeStatic(node.target, node.selector,
2710 node.sourceInformation); 2804 getList(node.argumentRefs), node.sourceInformation);
2711 } 2805 }
2712 2806
2713 Definition visitInvokeMethod(InvokeMethod node) { 2807 Definition visitInvokeMethod(InvokeMethod node) {
2714 return new InvokeMethod(getCopy(node.receiver), node.selector, node.mask, 2808 return new InvokeMethod(getCopy(node.receiverRef), node.selector, node.mask,
2715 getList(node.arguments), 2809 getList(node.argumentRefs),
2716 sourceInformation: node.sourceInformation, 2810 sourceInformation: node.sourceInformation,
2717 callingConvention: node.callingConvention); 2811 callingConvention: node.callingConvention);
2718 } 2812 }
2719 2813
2720 Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) { 2814 Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) {
2721 return new InvokeMethodDirectly(getCopy(node.receiver), node.target, 2815 return new InvokeMethodDirectly(getCopy(node.receiverRef), node.target,
2722 node.selector, 2816 node.selector,
2723 getList(node.arguments), 2817 getList(node.argumentRefs),
2724 node.sourceInformation, 2818 node.sourceInformation,
2725 callingConvention: node.callingConvention); 2819 callingConvention: node.callingConvention);
2726 } 2820 }
2727 2821
2728 Definition visitInvokeConstructor(InvokeConstructor node) { 2822 Definition visitInvokeConstructor(InvokeConstructor node) {
2729 return new InvokeConstructor(node.dartType, node.target, node.selector, 2823 return new InvokeConstructor(node.dartType, node.target, node.selector,
2730 getList(node.arguments), 2824 getList(node.argumentRefs),
2731 node.sourceInformation) 2825 node.sourceInformation)
2732 ..allocationSiteType = node.allocationSiteType; 2826 ..allocationSiteType = node.allocationSiteType;
2733 } 2827 }
2734 2828
2735 Definition visitTypeCast(TypeCast node) { 2829 Definition visitTypeCast(TypeCast node) {
2736 return new TypeCast(getCopy(node.value), node.dartType, 2830 return new TypeCast(getCopy(node.valueRef), node.dartType,
2737 getList(node.typeArguments)); 2831 getList(node.typeArgumentRefs));
2738 } 2832 }
2739 2833
2740 Definition visitSetMutable(SetMutable node) { 2834 Definition visitSetMutable(SetMutable node) {
2741 return new SetMutable(getCopy(node.variable), getCopy(node.value)); 2835 return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef));
2742 } 2836 }
2743 2837
2744 Definition visitSetStatic(SetStatic node) { 2838 Definition visitSetStatic(SetStatic node) {
2745 return new SetStatic(node.element, getCopy(node.value), 2839 return new SetStatic(node.element, getCopy(node.valueRef),
2746 node.sourceInformation); 2840 node.sourceInformation);
2747 } 2841 }
2748 2842
2749 Definition visitSetField(SetField node) { 2843 Definition visitSetField(SetField node) {
2750 return new SetField(getCopy(node.object), node.field, getCopy(node.value)); 2844 return new SetField(getCopy(node.objectRef), node.field,
2845 getCopy(node.valueRef));
2751 } 2846 }
2752 2847
2753 Definition visitGetLazyStatic(GetLazyStatic node) { 2848 Definition visitGetLazyStatic(GetLazyStatic node) {
2754 return new GetLazyStatic(node.element, 2849 return new GetLazyStatic(node.element,
2755 isFinal: node.isFinal, 2850 isFinal: node.isFinal,
2756 sourceInformation: node.sourceInformation); 2851 sourceInformation: node.sourceInformation);
2757 } 2852 }
2758 2853
2759 Definition visitAwait(Await node) { 2854 Definition visitAwait(Await node) {
2760 return new Await(getCopy(node.input)); 2855 return new Await(getCopy(node.inputRef));
2761 } 2856 }
2762 2857
2763 Definition visitYield(Yield node) { 2858 Definition visitYield(Yield node) {
2764 return new Yield(getCopy(node.input), node.hasStar); 2859 return new Yield(getCopy(node.inputRef), node.hasStar);
2765 } 2860 }
2766 2861
2767 Definition visitLiteralList(LiteralList node) { 2862 Definition visitLiteralList(LiteralList node) {
2768 return new LiteralList(node.dartType, getList(node.values)) 2863 return new LiteralList(node.dartType, getList(node.valueRefs))
2769 ..allocationSiteType = node.allocationSiteType; 2864 ..allocationSiteType = node.allocationSiteType;
2770 } 2865 }
2771 2866
2772 Definition visitConstant(Constant node) { 2867 Definition visitConstant(Constant node) {
2773 return new Constant(node.value, sourceInformation: node.sourceInformation); 2868 return new Constant(node.value, sourceInformation: node.sourceInformation);
2774 } 2869 }
2775 2870
2776 Definition visitGetMutable(GetMutable node) { 2871 Definition visitGetMutable(GetMutable node) {
2777 return new GetMutable(getCopy(node.variable)); 2872 return new GetMutable(getCopy(node.variableRef));
2778 } 2873 }
2779 2874
2780 Definition visitParameter(Parameter node) { 2875 Definition visitParameter(Parameter node) {
2781 return new Parameter(node.hint); 2876 return new Parameter(node.hint);
2782 } 2877 }
2783 2878
2784 Definition visitMutableVariable(MutableVariable node) { 2879 Definition visitMutableVariable(MutableVariable node) {
2785 return new MutableVariable(node.hint); 2880 return new MutableVariable(node.hint);
2786 } 2881 }
2787 2882
2788 Definition visitGetStatic(GetStatic node) { 2883 Definition visitGetStatic(GetStatic node) {
2789 if (node.witness != null) { 2884 if (node.witnessRef != null) {
2790 return new GetStatic.witnessed(node.element, 2885 return new GetStatic.witnessed(node.element,
2791 getCopy(node.witness), 2886 getCopy(node.witnessRef),
2792 sourceInformation: node.sourceInformation); 2887 sourceInformation: node.sourceInformation);
2793 } else { 2888 } else {
2794 return new GetStatic(node.element, 2889 return new GetStatic(node.element,
2795 isFinal: node.isFinal, 2890 isFinal: node.isFinal,
2796 sourceInformation: node.sourceInformation); 2891 sourceInformation: node.sourceInformation);
2797 } 2892 }
2798 } 2893 }
2799 2894
2800 Definition visitInterceptor(Interceptor node) { 2895 Definition visitInterceptor(Interceptor node) {
2801 return new Interceptor(getCopy(node.input), node.sourceInformation) 2896 return new Interceptor(getCopy(node.inputRef), node.sourceInformation)
2802 ..interceptedClasses.addAll(node.interceptedClasses); 2897 ..interceptedClasses.addAll(node.interceptedClasses);
2803 } 2898 }
2804 2899
2805 Definition visitCreateInstance(CreateInstance node) { 2900 Definition visitCreateInstance(CreateInstance node) {
2806 return new CreateInstance( 2901 return new CreateInstance(
2807 node.classElement, 2902 node.classElement,
2808 getList(node.arguments), 2903 getList(node.argumentRefs),
2809 node.typeInformation == null ? null : getCopy(node.typeInformation), 2904 getCopyOrNull(node.typeInformationRef),
2810 node.sourceInformation); 2905 node.sourceInformation);
2811 } 2906 }
2812 2907
2813 Definition visitGetField(GetField node) { 2908 Definition visitGetField(GetField node) {
2814 return new GetField(getCopy(node.object), node.field, 2909 return new GetField(getCopy(node.objectRef), node.field,
2815 isFinal: node.isFinal); 2910 isFinal: node.isFinal);
2816 } 2911 }
2817 2912
2818 Definition visitCreateBox(CreateBox node) { 2913 Definition visitCreateBox(CreateBox node) {
2819 return new CreateBox(); 2914 return new CreateBox();
2820 } 2915 }
2821 2916
2822 Definition visitReifyRuntimeType(ReifyRuntimeType node) { 2917 Definition visitReifyRuntimeType(ReifyRuntimeType node) {
2823 return new ReifyRuntimeType(getCopy(node.value), node.sourceInformation); 2918 return new ReifyRuntimeType(getCopy(node.valueRef), node.sourceInformation);
2824 } 2919 }
2825 2920
2826 Definition visitReadTypeVariable(ReadTypeVariable node) { 2921 Definition visitReadTypeVariable(ReadTypeVariable node) {
2827 return new ReadTypeVariable(node.variable, getCopy(node.target), 2922 return new ReadTypeVariable(node.variable, getCopy(node.targetRef),
2828 node.sourceInformation); 2923 node.sourceInformation);
2829 } 2924 }
2830 2925
2831 Definition visitTypeExpression(TypeExpression node) { 2926 Definition visitTypeExpression(TypeExpression node) {
2832 return new TypeExpression( 2927 return new TypeExpression(
2833 node.kind, node.dartType, getList(node.arguments)); 2928 node.kind, node.dartType, getList(node.argumentRefs));
2834 } 2929 }
2835 2930
2836 Definition visitCreateInvocationMirror(CreateInvocationMirror node) { 2931 Definition visitCreateInvocationMirror(CreateInvocationMirror node) {
2837 return new CreateInvocationMirror(node.selector, getList(node.arguments)); 2932 return new CreateInvocationMirror(node.selector,
2933 getList(node.argumentRefs));
2838 } 2934 }
2839 2935
2840 Definition visitTypeTest(TypeTest node) { 2936 Definition visitTypeTest(TypeTest node) {
2841 return new TypeTest(getCopy(node.value), node.dartType, 2937 return new TypeTest(getCopy(node.valueRef), node.dartType,
2842 getList(node.typeArguments)); 2938 getList(node.typeArgumentRefs));
2843 } 2939 }
2844 2940
2845 Definition visitTypeTestViaFlag(TypeTestViaFlag node) { 2941 Definition visitTypeTestViaFlag(TypeTestViaFlag node) {
2846 return new TypeTestViaFlag(getCopy(node.interceptor), node.dartType); 2942 return new TypeTestViaFlag(getCopy(node.interceptorRef), node.dartType);
2847 } 2943 }
2848 2944
2849 Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) { 2945 Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
2850 return new ApplyBuiltinOperator(node.operator, getList(node.arguments), 2946 return new ApplyBuiltinOperator(node.operator, getList(node.argumentRefs),
2851 node.sourceInformation); 2947 node.sourceInformation);
2852 } 2948 }
2853 2949
2854 Definition visitApplyBuiltinMethod(ApplyBuiltinMethod node) { 2950 Definition visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
2855 return new ApplyBuiltinMethod(node.method, getCopy(node.receiver), 2951 return new ApplyBuiltinMethod(node.method, getCopy(node.receiverRef),
2856 getList(node.arguments), 2952 getList(node.argumentRefs),
2857 node.sourceInformation, 2953 node.sourceInformation,
2858 receiverIsNotNull: node.receiverIsNotNull); 2954 receiverIsNotNull: node.receiverIsNotNull);
2859 } 2955 }
2860 2956
2861 Definition visitGetLength(GetLength node) { 2957 Definition visitGetLength(GetLength node) {
2862 return new GetLength(getCopy(node.object), isFinal: node.isFinal); 2958 return new GetLength(getCopy(node.objectRef), isFinal: node.isFinal);
2863 } 2959 }
2864 2960
2865 Definition visitGetIndex(GetIndex node) { 2961 Definition visitGetIndex(GetIndex node) {
2866 return new GetIndex(getCopy(node.object), getCopy(node.index)); 2962 return new GetIndex(getCopy(node.objectRef), getCopy(node.indexRef));
2867 } 2963 }
2868 2964
2869 Definition visitSetIndex(SetIndex node) { 2965 Definition visitSetIndex(SetIndex node) {
2870 return new SetIndex(getCopy(node.object), getCopy(node.index), 2966 return new SetIndex(getCopy(node.objectRef), getCopy(node.indexRef),
2871 getCopy(node.value)); 2967 getCopy(node.valueRef));
2872 } 2968 }
2873 2969
2874 Definition visitRefinement(Refinement node) { 2970 Definition visitRefinement(Refinement node) {
2875 return new Refinement(getCopy(node.value), node.refineType); 2971 return new Refinement(getCopy(node.value), node.refineType);
2876 } 2972 }
2877 2973
2878 Definition visitBoundsCheck(BoundsCheck node) { 2974 Definition visitBoundsCheck(BoundsCheck node) {
2879 if (node.hasNoChecks) { 2975 if (node.hasNoChecks) {
2880 return new BoundsCheck.noCheck(getCopy(node.object), 2976 return new BoundsCheck.noCheck(getCopy(node.objectRef),
2881 node.sourceInformation); 2977 node.sourceInformation);
2882 } else { 2978 } else {
2883 return new BoundsCheck(getCopy(node.object), getCopy(node.index), 2979 return new BoundsCheck(getCopy(node.objectRef), getCopy(node.indexRef),
2884 getCopyOrNull(node.length), 2980 getCopyOrNull(node.lengthRef),
2885 node.checks, 2981 node.checks,
2886 node.sourceInformation); 2982 node.sourceInformation);
2887 } 2983 }
2888 } 2984 }
2889 2985
2890 Definition visitReceiverCheck(ReceiverCheck node) { 2986 Definition visitReceiverCheck(ReceiverCheck node) {
2891 return new ReceiverCheck(getCopy(node.value), 2987 return new ReceiverCheck(getCopy(node.valueRef),
2892 node.selector, 2988 node.selector,
2893 node.sourceInformation, 2989 node.sourceInformation,
2894 condition: getCopyOrNull(node.condition), 2990 condition: getCopyOrNull(node.conditionRef),
2895 useSelector: node.useSelector, 2991 useSelector: node.useSelector,
2896 isNullCheck: node.isNullCheck); 2992 isNullCheck: node.isNullCheck);
2897 } 2993 }
2898 2994
2899 Definition visitForeignCode(ForeignCode node) { 2995 Definition visitForeignCode(ForeignCode node) {
2900 return new ForeignCode(node.codeTemplate, node.storedType, 2996 return new ForeignCode(node.codeTemplate, node.storedType,
2901 getList(node.arguments), 2997 getList(node.argumentRefs),
2902 node.nativeBehavior, 2998 node.nativeBehavior,
2903 dependency: node.dependency); 2999 dependency: node.dependency);
2904 } 3000 }
2905 } 3001 }
2906 3002
2907 /// A trampolining visitor to copy [FunctionDefinition]s. 3003 /// A trampolining visitor to copy [FunctionDefinition]s.
2908 class CopyingVisitor extends TrampolineRecursiveVisitor { 3004 class CopyingVisitor extends TrampolineRecursiveVisitor {
2909 // The visitor maintains a map from original continuations to their copies. 3005 // The visitor maintains a map from original continuations to their copies.
2910 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{}; 3006 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{};
2911 3007
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 return node.body; 3100 return node.body;
3005 } 3101 }
3006 3102
3007 Expression traverseLetPrim(LetPrim node) { 3103 Expression traverseLetPrim(LetPrim node) {
3008 plug(new LetPrim(_definitions.copy(node.primitive))); 3104 plug(new LetPrim(_definitions.copy(node.primitive)));
3009 return node.body; 3105 return node.body;
3010 } 3106 }
3011 3107
3012 Expression traverseLetMutable(LetMutable node) { 3108 Expression traverseLetMutable(LetMutable node) {
3013 plug(new LetMutable(_definitions.copy(node.variable), 3109 plug(new LetMutable(_definitions.copy(node.variable),
3014 _definitions.getCopy(node.value))); 3110 _definitions.getCopy(node.valueRef)));
3015 return node.body; 3111 return node.body;
3016 } 3112 }
3017 3113
3018 // Tail expressions do not have references, so we do not need to map them 3114 // Tail expressions do not have references, so we do not need to map them
3019 // to their copies. 3115 // to their copies.
3020 visitInvokeContinuation(InvokeContinuation node) { 3116 visitInvokeContinuation(InvokeContinuation node) {
3021 plug(new InvokeContinuation(_copies[node.continuation.definition], 3117 plug(new InvokeContinuation(_copies[node.continuation],
3022 _definitions.getList(node.arguments), 3118 _definitions.getList(node.argumentRefs),
3023 isRecursive: node.isRecursive, 3119 isRecursive: node.isRecursive,
3024 isEscapingTry: node.isEscapingTry, 3120 isEscapingTry: node.isEscapingTry,
3025 sourceInformation: node.sourceInformation)); 3121 sourceInformation: node.sourceInformation));
3026 } 3122 }
3027 3123
3028 visitThrow(Throw node) { 3124 visitThrow(Throw node) {
3029 plug(new Throw(_definitions.getCopy(node.value))); 3125 plug(new Throw(_definitions.getCopy(node.valueRef)));
3030 } 3126 }
3031 3127
3032 visitRethrow(Rethrow node) { 3128 visitRethrow(Rethrow node) {
3033 plug(new Rethrow()); 3129 plug(new Rethrow());
3034 } 3130 }
3035 3131
3036 visitBranch(Branch node) { 3132 visitBranch(Branch node) {
3037 plug(new Branch.loose(_definitions.getCopy(node.condition), 3133 plug(new Branch.loose(_definitions.getCopy(node.conditionRef),
3038 _copies[node.trueContinuation.definition], 3134 _copies[node.trueContinuation],
3039 _copies[node.falseContinuation.definition]) 3135 _copies[node.falseContinuation])
3040 ..isStrictCheck = node.isStrictCheck); 3136 ..isStrictCheck = node.isStrictCheck);
3041 } 3137 }
3042 3138
3043 visitUnreachable(Unreachable node) { 3139 visitUnreachable(Unreachable node) {
3044 plug(new Unreachable()); 3140 plug(new Unreachable());
3045 } 3141 }
3046 } 3142 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698