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

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

Issue 1542003003: Revert "dart2js: Initial implementation of inlining." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years 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;
8 import '../constants/values.dart' as values; 7 import '../constants/values.dart' as values;
9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
10 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
11 import '../io/source_information.dart' show SourceInformation; 10 import '../io/source_information.dart' show SourceInformation;
12 import '../types/types.dart' show TypeMask; 11 import '../types/types.dart' show TypeMask;
13 import '../universe/selector.dart' show Selector; 12 import '../universe/selector.dart' show Selector;
14 13
15 import 'builtin_operator.dart'; 14 import 'builtin_operator.dart';
16 export 'builtin_operator.dart'; 15 export 'builtin_operator.dart';
17 16
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive); 196 EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive);
198 } 197 }
199 198
200 /// A named value. 199 /// A named value.
201 /// 200 ///
202 /// The identity of the [Primitive] object is the name of the value. 201 /// The identity of the [Primitive] object is the name of the value.
203 /// The subclass describes how to compute the value. 202 /// The subclass describes how to compute the value.
204 /// 203 ///
205 /// All primitives except [Parameter] must be bound by a [LetPrim]. 204 /// All primitives except [Parameter] must be bound by a [LetPrim].
206 abstract class Primitive extends Variable<Primitive> { 205 abstract class Primitive extends Variable<Primitive> {
207 Primitive() : super(null); 206 /// The [VariableElement] or [ParameterElement] from which the primitive
207 /// binding originated.
208 Entity hint;
209
210 /// Use the given element as a hint for naming this primitive.
211 ///
212 /// Has no effect if this primitive already has a non-null [element].
213 void useElementAsHint(Entity hint) {
214 if (this.hint == null) {
215 this.hint = hint;
216 }
217 }
208 218
209 /// True if this primitive has a value that can be used by other expressions. 219 /// True if this primitive has a value that can be used by other expressions.
210 bool get hasValue; 220 bool get hasValue;
211 221
212 /// True if the primitive can be removed, assuming it has no uses 222 /// True if the primitive can be removed, assuming it has no uses
213 /// (this getter does not check if there are any uses). 223 /// (this getter does not check if there are any uses).
214 /// 224 ///
215 /// False must be returned for primitives that may throw, diverge, or have 225 /// False must be returned for primitives that may throw, diverge, or have
216 /// observable side-effects. 226 /// observable side-effects.
217 bool get isSafeForElimination; 227 bool get isSafeForElimination;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 assert(this is! Parameter); 288 assert(this is! Parameter);
279 assert(newDefinition is! Parameter); 289 assert(newDefinition is! Parameter);
280 assert(newDefinition.parent == null); 290 assert(newDefinition.parent == null);
281 replaceUsesWith(newDefinition); 291 replaceUsesWith(newDefinition);
282 destroy(); 292 destroy();
283 LetPrim let = parent; 293 LetPrim let = parent;
284 let.primitive = newDefinition; 294 let.primitive = newDefinition;
285 newDefinition.parent = let; 295 newDefinition.parent = let;
286 newDefinition.useElementAsHint(hint); 296 newDefinition.useElementAsHint(hint);
287 } 297 }
288
289 /// Replaces this definition with a CPS fragment (a term with a hole in it),
290 /// given the value to replace the uses of the definition with.
291 ///
292 /// This can be thought of as substituting:
293 ///
294 /// let x = OLD in BODY
295 /// ==>
296 /// FRAGMENT[BODY{newPrimitive/x}]
297 void replaceWithFragment(CpsFragment fragment, Primitive newPrimitive) {
298 assert(this is! Parameter);
299 replaceUsesWith(newPrimitive);
300 destroy();
301 LetPrim let = parent;
302 fragment.insertBelow(let);
303 let.remove();
304 }
305 } 298 }
306 299
307 /// A primitive that is generally not safe for elimination, but may be marked 300 /// A primitive that is generally not safe for elimination, but may be marked
308 /// as safe by type propagation 301 /// as safe by type propagation
309 // 302 //
310 // TODO(asgerf): Store the flag in a bitmask in [Primitive] and get rid of this 303 // TODO(asgerf): Store the flag in a bitmask in [Primitive] and get rid of this
311 // class. 304 // class.
312 abstract class UnsafePrimitive extends Primitive { 305 abstract class UnsafePrimitive extends Primitive {
313 bool isSafeForElimination = false; 306 bool isSafeForElimination = false;
314 bool isSafeForReordering = false; 307 bool isSafeForReordering = false;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 457
465 accept(Visitor visitor) => visitor.visitLetMutable(this); 458 accept(Visitor visitor) => visitor.visitLetMutable(this);
466 459
467 void setParentPointers() { 460 void setParentPointers() {
468 variable.parent = this; 461 variable.parent = this;
469 value.parent = this; 462 value.parent = this;
470 if (body != null) body.parent = this; 463 if (body != null) body.parent = this;
471 } 464 }
472 } 465 }
473 466
474 enum CallingConvention {
475 /// JS receiver is the Dart receiver, there are no extra arguments.
476 ///
477 /// This includes cases (e.g., static functions, constructors) where there
478 /// is no receiver.
479 ///
480 /// For example: `foo.bar$1(x)`
481 Normal,
482
483 /// JS receiver is an interceptor, the first argument is the Dart receiver.
484 ///
485 /// For example: `getInterceptor(foo).bar$1(foo, x)`
486 Intercepted,
487
488 /// JS receiver is the Dart receiver, the first argument is a dummy value.
489 ///
490 /// For example: `foo.bar$1(0, x)`
491 DummyIntercepted,
492
493 /// JS receiver is the Dart receiver, there are no extra arguments.
494 ///
495 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)`
496 OneShotIntercepted,
497 }
498
499 /// Base class of function invocations.
500 ///
501 /// This class defines the common interface of function invocations.
502 abstract class InvocationPrimitive extends UnsafePrimitive {
503 Reference<Primitive> get receiver => null;
504 List<Reference<Primitive>> get arguments;
505 SourceInformation get sourceInformation;
506
507 Reference<Primitive> get dartReceiverReference => null;
508 CallingConvention get callingConvention => CallingConvention.Normal;
509 }
510
511 /// Invoke a static function. 467 /// Invoke a static function.
512 /// 468 ///
513 /// All optional arguments declared by [target] are passed in explicitly, and 469 /// All optional arguments declared by [target] are passed in explicitly, and
514 /// occur at the end of [arguments] list, in normalized order. 470 /// occur at the end of [arguments] list, in normalized order.
515 /// 471 ///
516 /// Discussion: 472 /// Discussion:
517 /// All information in the [selector] is technically redundant; it will likely 473 /// All information in the [selector] is technically redundant; it will likely
518 /// be removed. 474 /// be removed.
519 class InvokeStatic extends InvocationPrimitive { 475 class InvokeStatic extends UnsafePrimitive {
520 final FunctionElement target; 476 final FunctionElement target;
521 final Selector selector; 477 final Selector selector;
522 final List<Reference<Primitive>> arguments; 478 final List<Reference<Primitive>> arguments;
523 final SourceInformation sourceInformation; 479 final SourceInformation sourceInformation;
524 480
525 InvokeStatic(this.target, 481 InvokeStatic(this.target,
526 this.selector, 482 this.selector,
527 List<Primitive> args, 483 List<Primitive> args,
528 [this.sourceInformation]) 484 [this.sourceInformation])
529 : arguments = _referenceList(args); 485 : arguments = _referenceList(args);
530 486
531 InvokeStatic.byReference(this.target, 487 InvokeStatic.byReference(this.target,
532 this.selector, 488 this.selector,
533 this.arguments, 489 this.arguments,
534 [this.sourceInformation]); 490 [this.sourceInformation]);
535 491
536 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 492 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
537 493
538 bool get hasValue => true; 494 bool get hasValue => true;
539 495
540 void setParentPointers() { 496 void setParentPointers() {
541 _setParentsOnList(arguments, this); 497 _setParentsOnList(arguments, this);
542 } 498 }
543 } 499 }
544 500
501 enum CallingConvention {
502 /// JS receiver is the Dart receiver, there are no extra arguments.
503 ///
504 /// For example: `foo.bar$1(x)`
505 Normal,
506
507 /// JS receiver is an interceptor, the first argument is the Dart receiver.
508 ///
509 /// For example: `getInterceptor(foo).bar$1(foo, x)`
510 Intercepted,
511
512 /// JS receiver is the Dart receiver, the first argument is a dummy value.
513 ///
514 /// For example: `foo.bar$1(0, x)`
515 DummyIntercepted,
516
517 /// JS receiver is the Dart receiver, there are no extra arguments.
518 ///
519 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)`
520 OneShotIntercepted,
521 }
522
545 /// Invoke a method on an object. 523 /// Invoke a method on an object.
546 /// 524 ///
547 /// This includes getters, setters, operators, and index getter/setters. 525 /// This includes getters, setters, operators, and index getter/setters.
548 /// 526 ///
549 /// Tearing off a method is treated like a getter invocation (getters and 527 /// Tearing off a method is treated like a getter invocation (getters and
550 /// tear-offs cannot be distinguished at compile-time). 528 /// tear-offs cannot be distinguished at compile-time).
551 /// 529 ///
552 /// The [selector] records the names of named arguments. The value of named 530 /// The [selector] records the names of named arguments. The value of named
553 /// arguments occur at the end of the [arguments] list, in normalized order. 531 /// arguments occur at the end of the [arguments] list, in normalized order.
554 class InvokeMethod extends InvocationPrimitive { 532 class InvokeMethod extends UnsafePrimitive {
555 Reference<Primitive> receiver; 533 Reference<Primitive> receiver;
556 Selector selector; 534 Selector selector;
557 TypeMask mask; 535 TypeMask mask;
558 final List<Reference<Primitive>> arguments; 536 final List<Reference<Primitive>> arguments;
559 final SourceInformation sourceInformation; 537 final SourceInformation sourceInformation;
560 538
561 CallingConvention callingConvention = CallingConvention.Normal; 539 CallingConvention callingConvention = CallingConvention.Normal;
562 540
563 Reference<Primitive> get dartReceiverReference { 541 Reference<Primitive> get dartReceiverReference {
564 return callingConvention == CallingConvention.Intercepted 542 return callingConvention == CallingConvention.Intercepted
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 /// If it is known that [target] does not use its receiver argument, then 599 /// If it is known that [target] does not use its receiver argument, then
622 /// [receiver] may refer to a null constant primitive. This happens for direct 600 /// [receiver] may refer to a null constant primitive. This happens for direct
623 /// invocations to intercepted methods, where the effective receiver is instead 601 /// invocations to intercepted methods, where the effective receiver is instead
624 /// passed as a formal parameter. 602 /// passed as a formal parameter.
625 /// 603 ///
626 /// TODO(sra): Review. A direct call to a method that is mixed into a native 604 /// TODO(sra): Review. A direct call to a method that is mixed into a native
627 /// class will still require an explicit argument. 605 /// class will still require an explicit argument.
628 /// 606 ///
629 /// All optional arguments declared by [target] are passed in explicitly, and 607 /// All optional arguments declared by [target] are passed in explicitly, and
630 /// occur at the end of [arguments] list, in normalized order. 608 /// occur at the end of [arguments] list, in normalized order.
631 class InvokeMethodDirectly extends InvocationPrimitive { 609 class InvokeMethodDirectly extends UnsafePrimitive {
632 Reference<Primitive> receiver; 610 Reference<Primitive> receiver;
633 final FunctionElement target; 611 final FunctionElement target;
634 final Selector selector; 612 final Selector selector;
635 final List<Reference<Primitive>> arguments; 613 final List<Reference<Primitive>> arguments;
636 final SourceInformation sourceInformation; 614 final SourceInformation sourceInformation;
637 615
638 CallingConvention callingConvention = CallingConvention.Normal; 616 CallingConvention callingConvention = CallingConvention.Normal;
639 617
640 Reference<Primitive> get dartReceiverReference { 618 Reference<Primitive> get dartReceiverReference {
641 return callingConvention == CallingConvention.Intercepted 619 return callingConvention == CallingConvention.Intercepted
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 /// All optional arguments declared by [target] are passed in explicitly, and 657 /// All optional arguments declared by [target] are passed in explicitly, and
680 /// occur in the [arguments] list, in normalized order. 658 /// occur in the [arguments] list, in normalized order.
681 /// 659 ///
682 /// Last in the [arguments] list, after the mandatory and optional arguments, 660 /// Last in the [arguments] list, after the mandatory and optional arguments,
683 /// the internal representation of each type argument occurs, unless it could 661 /// the internal representation of each type argument occurs, unless it could
684 /// be determined at build-time that the constructed class has no need for its 662 /// be determined at build-time that the constructed class has no need for its
685 /// runtime type information. 663 /// runtime type information.
686 /// 664 ///
687 /// Note that [InvokeConstructor] does it itself allocate an object. 665 /// Note that [InvokeConstructor] does it itself allocate an object.
688 /// The invoked constructor will do that using [CreateInstance]. 666 /// The invoked constructor will do that using [CreateInstance].
689 class InvokeConstructor extends InvocationPrimitive { 667 class InvokeConstructor extends UnsafePrimitive {
690 final DartType dartType; 668 final DartType dartType;
691 final ConstructorElement target; 669 final ConstructorElement target;
692 final List<Reference<Primitive>> arguments; 670 final List<Reference<Primitive>> arguments;
693 final Selector selector; 671 final Selector selector;
694 final SourceInformation sourceInformation; 672 final SourceInformation sourceInformation;
695 673
696 /// If non-null, this is an allocation site-specific type that is potentially 674 /// If non-null, this is an allocation site-specific type that is potentially
697 /// better than the inferred return type of [target]. 675 /// better than the inferred return type of [target].
698 /// 676 ///
699 /// In particular, container type masks depend on the allocation site and 677 /// In particular, container type masks depend on the allocation site and
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 if (body != null) body.parent = this; 1681 if (body != null) body.parent = this;
1704 } 1682 }
1705 } 1683 }
1706 1684
1707 /// Common interface for [Primitive] and [MutableVariable]. 1685 /// Common interface for [Primitive] and [MutableVariable].
1708 abstract class Variable<T extends Variable<T>> extends Definition<T> { 1686 abstract class Variable<T extends Variable<T>> extends Definition<T> {
1709 /// Type of value held in the variable. 1687 /// Type of value held in the variable.
1710 /// 1688 ///
1711 /// Is `null` until initialized by type propagation. 1689 /// Is `null` until initialized by type propagation.
1712 TypeMask type; 1690 TypeMask type;
1713
1714 /// The [VariableElement] or [ParameterElement] from which the variable
1715 /// binding originated.
1716 Entity hint;
1717
1718 Variable(this.hint);
1719
1720 /// Use the given element as a hint for naming this primitive.
1721 ///
1722 /// Has no effect if this primitive already has a non-null [element].
1723 void useElementAsHint(Entity hint) {
1724 this.hint ??= hint;
1725 }
1726 } 1691 }
1727 1692
1728 /// Identifies a mutable variable. 1693 /// Identifies a mutable variable.
1729 class MutableVariable extends Variable<MutableVariable> { 1694 class MutableVariable extends Variable<MutableVariable> {
1730 MutableVariable(Entity hint) : super(hint); 1695 Entity hint;
1696
1697 MutableVariable(this.hint);
1731 1698
1732 accept(Visitor v) => v.visitMutableVariable(this); 1699 accept(Visitor v) => v.visitMutableVariable(this);
1733 1700
1734 void setParentPointers() {} 1701 void setParentPointers() {}
1735 } 1702 }
1736 1703
1737 /// A function definition, consisting of parameters and a body. 1704 /// A function definition, consisting of parameters and a body.
1738 /// 1705 ///
1739 /// There is an explicit parameter for the `this` argument, and a return 1706 /// There is an explicit parameter for the `this` argument, and a return
1740 /// continuation to invoke when returning from the function. 1707 /// continuation to invoke when returning from the function.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 1867
1901 // Concrete classes. 1868 // Concrete classes.
1902 T visitFunctionDefinition(FunctionDefinition node); 1869 T visitFunctionDefinition(FunctionDefinition node);
1903 1870
1904 // Expressions. 1871 // Expressions.
1905 T visitLetPrim(LetPrim node); 1872 T visitLetPrim(LetPrim node);
1906 T visitLetCont(LetCont node); 1873 T visitLetCont(LetCont node);
1907 T visitLetHandler(LetHandler node); 1874 T visitLetHandler(LetHandler node);
1908 T visitLetMutable(LetMutable node); 1875 T visitLetMutable(LetMutable node);
1909 T visitInvokeContinuation(InvokeContinuation node); 1876 T visitInvokeContinuation(InvokeContinuation node);
1910 T visitThrow(Throw node);
1911 T visitRethrow(Rethrow node);
1912 T visitBranch(Branch node);
1913 T visitUnreachable(Unreachable node);
1914
1915 // Definitions.
1916 T visitInvokeStatic(InvokeStatic node); 1877 T visitInvokeStatic(InvokeStatic node);
1917 T visitInvokeMethod(InvokeMethod node); 1878 T visitInvokeMethod(InvokeMethod node);
1918 T visitInvokeMethodDirectly(InvokeMethodDirectly node); 1879 T visitInvokeMethodDirectly(InvokeMethodDirectly node);
1919 T visitInvokeConstructor(InvokeConstructor node); 1880 T visitInvokeConstructor(InvokeConstructor node);
1881 T visitThrow(Throw node);
1882 T visitRethrow(Rethrow node);
1883 T visitBranch(Branch node);
1920 T visitTypeCast(TypeCast node); 1884 T visitTypeCast(TypeCast node);
1921 T visitSetMutable(SetMutable node); 1885 T visitSetMutable(SetMutable node);
1922 T visitSetStatic(SetStatic node); 1886 T visitSetStatic(SetStatic node);
1887 T visitGetLazyStatic(GetLazyStatic node);
1923 T visitSetField(SetField node); 1888 T visitSetField(SetField node);
1924 T visitGetLazyStatic(GetLazyStatic node); 1889 T visitUnreachable(Unreachable node);
1925 T visitAwait(Await node); 1890 T visitAwait(Await node);
1926 T visitYield(Yield node); 1891 T visitYield(Yield node);
1892
1893 // Definitions.
1927 T visitLiteralList(LiteralList node); 1894 T visitLiteralList(LiteralList node);
1928 T visitLiteralMap(LiteralMap node); 1895 T visitLiteralMap(LiteralMap node);
1929 T visitConstant(Constant node); 1896 T visitConstant(Constant node);
1930 T visitGetMutable(GetMutable node); 1897 T visitGetMutable(GetMutable node);
1931 T visitParameter(Parameter node); 1898 T visitParameter(Parameter node);
1932 T visitContinuation(Continuation node); 1899 T visitContinuation(Continuation node);
1933 T visitMutableVariable(MutableVariable node); 1900 T visitMutableVariable(MutableVariable node);
1934 T visitGetStatic(GetStatic node); 1901 T visitGetStatic(GetStatic node);
1935 T visitInterceptor(Interceptor node); 1902 T visitInterceptor(Interceptor node);
1936 T visitCreateInstance(CreateInstance node); 1903 T visitCreateInstance(CreateInstance node);
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 /// Visit a just-deleted subterm and unlink all [Reference]s in it. 2385 /// Visit a just-deleted subterm and unlink all [Reference]s in it.
2419 class RemovalVisitor extends TrampolineRecursiveVisitor { 2386 class RemovalVisitor extends TrampolineRecursiveVisitor {
2420 processReference(Reference reference) { 2387 processReference(Reference reference) {
2421 reference.unlink(); 2388 reference.unlink();
2422 } 2389 }
2423 2390
2424 static void remove(Node node) { 2391 static void remove(Node node) {
2425 (new RemovalVisitor()).visit(node); 2392 (new RemovalVisitor()).visit(node);
2426 } 2393 }
2427 } 2394 }
2428
2429 /// A visitor to copy instances of [Definition] or its subclasses, except for
2430 /// instances of [Continuation].
2431 ///
2432 /// The visitor maintains a map from original definitions to their copies.
2433 /// When the [copy] method is called for a non-Continuation definition,
2434 /// a copy is created, added to the map and returned as the result. Copying a
2435 /// definition assumes that the definitions of all references have already
2436 /// been copied by the same visitor.
2437 class DefinitionCopyingVisitor extends Visitor<Definition> {
2438 Map<Definition, Definition> _copies = <Definition, Definition>{};
2439
2440 /// Put a copy into the map.
2441 ///
2442 /// This method should be used instead of directly adding copies to the map.
2443 Definition putCopy(Definition original, Definition copy) {
2444 if (copy is Variable) {
2445 Variable originalVariable = original;
2446 copy.type = originalVariable.type;
2447 copy.hint = originalVariable.hint;
2448 }
2449 return _copies[original] = copy;
2450 }
2451
2452 /// Get the copy of a [Reference]'s definition from the map.
2453 Definition getCopy(Reference reference) => _copies[reference.definition];
2454
2455 /// Map a list of [Reference]s to the list of their definition's copies.
2456 List<Definition> getList(List<Reference> list) => list.map(getCopy).toList();
2457
2458 /// Copy a non-[Continuation] [Definition].
2459 Definition copy(Definition node) {
2460 assert (node is! Continuation);
2461 return putCopy(node, visit(node));
2462 }
2463
2464 Definition visit(Node node) => node.accept(this);
2465
2466 Definition visitFunctionDefinition(FunctionDefinition node) {}
2467 Definition visitLetPrim(LetPrim node) {}
2468 Definition visitLetCont(LetCont node) {}
2469 Definition visitLetHandler(LetHandler node) {}
2470 Definition visitLetMutable(LetMutable node) {}
2471 Definition visitInvokeContinuation(InvokeContinuation node) {}
2472 Definition visitThrow(Throw node) {}
2473 Definition visitRethrow(Rethrow node) {}
2474 Definition visitBranch(Branch node) {}
2475 Definition visitUnreachable(Unreachable node) {}
2476 Definition visitContinuation(Continuation node) {}
2477
2478 Definition visitInvokeStatic(InvokeStatic node) {
2479 return new InvokeStatic(node.target, node.selector, getList(node.arguments),
2480 node.sourceInformation);
2481 }
2482
2483 Definition visitInvokeMethod(InvokeMethod node) {
2484 return new InvokeMethod(getCopy(node.receiver), node.selector, node.mask,
2485 getList(node.arguments),
2486 node.sourceInformation);
2487 }
2488
2489 Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) {
2490 return new InvokeMethodDirectly(getCopy(node.receiver), node.target,
2491 node.selector,
2492 getList(node.arguments),
2493 node.sourceInformation);
2494 }
2495
2496 Definition visitInvokeConstructor(InvokeConstructor node) {
2497 return new InvokeConstructor(node.dartType, node.target, node.selector,
2498 getList(node.arguments),
2499 node.sourceInformation);
2500 }
2501
2502 Definition visitTypeCast(TypeCast node) {
2503 return new TypeCast(getCopy(node.value), node.dartType,
2504 getList(node.typeArguments));
2505 }
2506
2507 Definition visitSetMutable(SetMutable node) {
2508 return new SetMutable(getCopy(node.variable), getCopy(node.value));
2509 }
2510
2511 Definition visitSetStatic(SetStatic node) {
2512 return new SetStatic(node.element, getCopy(node.value),
2513 node.sourceInformation);
2514 }
2515
2516 Definition visitSetField(SetField node) {
2517 return new SetField(getCopy(node.object), node.field, getCopy(node.value));
2518 }
2519
2520 Definition visitGetLazyStatic(GetLazyStatic node) {
2521 return new GetLazyStatic(node.element, node.sourceInformation);
2522 }
2523
2524 Definition visitAwait(Await node) {
2525 return new Await(getCopy(node.input));
2526 }
2527
2528 Definition visitYield(Yield node) {
2529 return new Yield(getCopy(node.input), node.hasStar);
2530 }
2531
2532 Definition visitLiteralList(LiteralList node) {
2533 return new LiteralList(node.dartType, getList(node.values));
2534 }
2535
2536 Definition visitLiteralMap(LiteralMap node) {
2537 List<LiteralMapEntry> entries = node.entries.map((LiteralMapEntry entry) {
2538 return new LiteralMapEntry(getCopy(entry.key), getCopy(entry.value));
2539 }).toList();
2540 return new LiteralMap(node.dartType, entries);
2541 }
2542
2543 Definition visitConstant(Constant node) {
2544 return new Constant(node.value, sourceInformation: node.sourceInformation);
2545 }
2546
2547 Definition visitGetMutable(GetMutable node) {
2548 return new GetMutable(getCopy(node.variable));
2549 }
2550
2551 Definition visitParameter(Parameter node) {
2552 return new Parameter(node.hint);
2553 }
2554
2555 Definition visitMutableVariable(MutableVariable node) {
2556 return new MutableVariable(node.hint);
2557 }
2558
2559 Definition visitGetStatic(GetStatic node) {
2560 return new GetStatic(node.element, node.sourceInformation);
2561 }
2562
2563 Definition visitInterceptor(Interceptor node) {
2564 return new Interceptor(getCopy(node.input), node.sourceInformation)
2565 ..interceptedClasses.addAll(node.interceptedClasses);
2566 }
2567
2568 Definition visitCreateInstance(CreateInstance node) {
2569 return new CreateInstance(node.classElement, getList(node.arguments),
2570 getList(node.typeInformation),
2571 node.sourceInformation);
2572 }
2573
2574 Definition visitGetField(GetField node) {
2575 return new GetField(getCopy(node.object), node.field);
2576 }
2577
2578 Definition visitCreateBox(CreateBox node) {
2579 return new CreateBox();
2580 }
2581
2582 Definition visitReifyRuntimeType(ReifyRuntimeType node) {
2583 return new ReifyRuntimeType(getCopy(node.value), node.sourceInformation);
2584 }
2585
2586 Definition visitReadTypeVariable(ReadTypeVariable node) {
2587 return new ReadTypeVariable(node.variable, getCopy(node.target),
2588 node.sourceInformation);
2589 }
2590
2591 Definition visitTypeExpression(TypeExpression node) {
2592 return new TypeExpression(node.dartType, getList(node.arguments));
2593 }
2594
2595 Definition visitCreateInvocationMirror(CreateInvocationMirror node) {
2596 return new CreateInvocationMirror(node.selector, getList(node.arguments));
2597 }
2598
2599 Definition visitTypeTest(TypeTest node) {
2600 return new TypeTest(getCopy(node.value), node.dartType,
2601 getList(node.typeArguments));
2602 }
2603
2604 Definition visitTypeTestViaFlag(TypeTestViaFlag node) {
2605 return new TypeTestViaFlag(getCopy(node.interceptor), node.dartType);
2606 }
2607
2608 Definition visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
2609 return new ApplyBuiltinOperator(node.operator, getList(node.arguments),
2610 node.sourceInformation);
2611 }
2612
2613 Definition visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
2614 return new ApplyBuiltinMethod(node.method, getCopy(node.receiver),
2615 getList(node.arguments),
2616 node.sourceInformation,
2617 receiverIsNotNull: node.receiverIsNotNull);
2618 }
2619
2620 Definition visitGetLength(GetLength node) {
2621 return new GetLength(getCopy(node.object));
2622 }
2623
2624 Definition visitGetIndex(GetIndex node) {
2625 return new GetIndex(getCopy(node.object), getCopy(node.index));
2626 }
2627
2628 Definition visitSetIndex(SetIndex node) {
2629 return new SetIndex(getCopy(node.object), getCopy(node.index),
2630 getCopy(node.value));
2631 }
2632
2633 Definition visitRefinement(Refinement node) {
2634 return new Refinement(getCopy(node.value), node.refineType);
2635 }
2636
2637 Definition visitBoundsCheck(BoundsCheck node) {
2638 if (node.hasNoChecks) {
2639 return new BoundsCheck.noCheck(getCopy(node.object),
2640 node.sourceInformation);
2641 } else {
2642 return new BoundsCheck(getCopy(node.object), getCopy(node.index),
2643 getCopy(node.length),
2644 node.checks,
2645 node.sourceInformation);
2646 }
2647 }
2648
2649 Definition visitNullCheck(NullCheck node) {
2650 return new NullCheck(getCopy(node.value), node.sourceInformation);
2651 }
2652
2653 Definition visitForeignCode(ForeignCode node) {
2654 return new ForeignCode(node.codeTemplate, node.type,
2655 getList(node.arguments),
2656 node.nativeBehavior,
2657 dependency: node.dependency);
2658 }
2659 }
2660
2661 /// A trampolining visitor to copy [FunctionDefinition]s.
2662 class CopyingVisitor extends TrampolineRecursiveVisitor {
2663 // The visitor maintains a map from original continuations to their copies.
2664 Map<Continuation, Continuation> _copies = <Continuation, Continuation>{};
2665
2666 // The visitor uses an auxiliary visitor to copy definitions.
2667 DefinitionCopyingVisitor _definitions = new DefinitionCopyingVisitor();
2668
2669 // While copying a block, the state of the visitor is a 'linked list' of
2670 // the expressions in the block's body, with a pointer to the last element
2671 // of the list.
2672 Expression _first = null;
2673 Expression _current = null;
2674
2675 void plug(Expression body) {
2676 if (_first == null) {
2677 _first = body;
2678 } else {
2679 assert(_current != null);
2680 InteriorExpression interior = _current;
2681 interior.body = body;
2682 }
2683 _current = body;
2684 }
2685
2686 // Continuations are added to the visitor's stack to be visited after copying
2687 // the current block is finished. The stack action saves the current block,
2688 // copies the continuation's body, sets the body on the copy of the
2689 // continuation, and restores the current block.
2690 //
2691 // Note that continuations are added to the copy map before the stack action
2692 // to visit them is performed.
2693 void push(Continuation cont) {
2694 assert(!cont.isReturnContinuation);
2695 _stack.add(() {
2696 Expression savedFirst = _first;
2697 _first = _current = null;
2698 _processBlock(cont.body);
2699 _copies[cont].body = _first;
2700 _first = savedFirst;
2701 _current = null;
2702 });
2703 }
2704
2705 FunctionDefinition copy(FunctionDefinition node) {
2706 assert(_first == null && _current == null);
2707 _first = _current = null;
2708 // Definitions are copied where they are bound, before processing
2709 // expressions in the scope of their binding.
2710 Parameter thisParameter = node.thisParameter == null
2711 ? null
2712 : _definitions.copy(node.thisParameter);
2713 List<Parameter> parameters =
2714 node.parameters.map(_definitions.copy).toList();
2715 // Though the return continuation's parameter does not have any uses,
2716 // we still make a proper copy to ensure that hints, type, etc. are
2717 // copied.
2718 Parameter returnParameter =
2719 _definitions.copy(node.returnContinuation.parameters.first);
2720 Continuation returnContinuation = _copies[node.returnContinuation] =
2721 new Continuation([returnParameter]);
2722
2723 visit(node.body);
2724 FunctionDefinition copy = new FunctionDefinition(node.element,
2725 thisParameter,
2726 parameters,
2727 returnContinuation,
2728 _first);
2729 _first = _current = null;
2730 return copy;
2731 }
2732
2733 Node visit(Node node) => node.accept(this);
2734
2735 Expression traverseLetCont(LetCont node) {
2736 // Continuations are copied where they are bound, before processing
2737 // expressions in the scope of their binding.
2738 List<Continuation> continuations = node.continuations.map((Continuation c) {
2739 push(c);
2740 return _copies[c] =
2741 new Continuation(c.parameters.map(_definitions.copy).toList());
2742 }).toList();
2743 plug(new LetCont.many(continuations, null));
2744 return node.body;
2745 }
2746
2747 Expression traverseLetHandler(LetHandler node) {
2748 // Continuations are copied where they are bound, before processing
2749 // expressions in the scope of their binding.
2750 push(node.handler);
2751 Continuation handler = _copies[node.handler] =
2752 new Continuation(node.handler.parameters.map(_definitions.copy)
2753 .toList());
2754 plug(new LetHandler(handler, null));
2755 return node.body;
2756 }
2757
2758 Expression traverseLetPrim(LetPrim node) {
2759 plug(new LetPrim(_definitions.copy(node.primitive)));
2760 return node.body;
2761 }
2762
2763 Expression traverseLetMutable(LetMutable node) {
2764 plug(new LetMutable(_definitions.copy(node.variable),
2765 _definitions.getCopy(node.value)));
2766 return node.body;
2767 }
2768
2769 // Tail expressions do not have references, so we do not need to map them
2770 // to their copies.
2771 visitInvokeContinuation(InvokeContinuation node) {
2772 plug(new InvokeContinuation(_copies[node.continuation.definition],
2773 _definitions.getList(node.arguments),
2774 isRecursive: node.isRecursive,
2775 isEscapingTry: node.isEscapingTry,
2776 sourceInformation: node.sourceInformation));
2777 }
2778
2779 Node visitThrow(Throw node) {
2780 plug(new Throw(_definitions.getCopy(node.value)));
2781 }
2782
2783 Node visitRethrow(Rethrow node) {
2784 plug(new Rethrow());
2785 }
2786
2787 Node visitBranch(Branch node) {
2788 plug(new Branch.loose(_definitions.getCopy(node.condition),
2789 _copies[node.trueContinuation.definition],
2790 _copies[node.falseContinuation.definition])
2791 ..isStrictCheck = node.isStrictCheck);
2792 }
2793
2794 Node visitUnreachable(Unreachable node) {
2795 plug(new Unreachable());
2796 }
2797 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_fragment.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698