OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 /// 'currentNode': node, | 58 /// 'currentNode': node, |
59 /// 'caller': someContinuation | 59 /// 'caller': someContinuation |
60 /// }); | 60 /// }); |
61 /// throw 'Node was not in environment'; | 61 /// throw 'Node was not in environment'; |
62 /// } | 62 /// } |
63 /// | 63 /// |
64 /// If two strings map to the same node, it will be given both annotations. | 64 /// If two strings map to the same node, it will be given both annotations. |
65 /// | 65 /// |
66 /// Avoid using nodes as keys if there is a chance that two keys are the | 66 /// Avoid using nodes as keys if there is a chance that two keys are the |
67 /// same node. | 67 /// same node. |
68 String debugString([Map annotations]) { | 68 String debugString([Map annotations = const {}]) { |
69 return new SExpressionStringifier() | 69 return new SExpressionStringifier() |
70 .withAnnotations(annotations) | 70 .withAnnotations(annotations) |
| 71 .withTypes() |
71 .visit(this); | 72 .visit(this); |
72 } | 73 } |
73 | 74 |
74 /// Prints the result of [debugString]. | 75 /// Prints the result of [debugString]. |
75 void debugPrint([Map annotations]) { | 76 void debugPrint([Map annotations = const {}]) { |
76 print(debugString(annotations)); | 77 print(debugString(annotations)); |
77 } | 78 } |
78 } | 79 } |
79 | 80 |
80 /// Expressions can be evaluated, and may diverge, throw, and/or have | 81 /// Expressions can be evaluated, and may diverge, throw, and/or have |
81 /// side-effects. | 82 /// side-effects. |
82 /// | 83 /// |
83 /// Evaluation continues by stepping into a sub-expression, invoking a | 84 /// Evaluation continues by stepping into a sub-expression, invoking a |
84 /// continuation, or throwing an exception. | 85 /// continuation, or throwing an exception. |
85 /// | 86 /// |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 410 |
410 void setParentPointers() {} | 411 void setParentPointers() {} |
411 } | 412 } |
412 | 413 |
413 /// A function definition, consisting of parameters and a body. | 414 /// A function definition, consisting of parameters and a body. |
414 /// | 415 /// |
415 /// There is an explicit parameter for the `this` argument, and a return | 416 /// There is an explicit parameter for the `this` argument, and a return |
416 /// continuation to invoke when returning from the function. | 417 /// continuation to invoke when returning from the function. |
417 class FunctionDefinition extends InteriorNode { | 418 class FunctionDefinition extends InteriorNode { |
418 final ExecutableElement element; | 419 final ExecutableElement element; |
419 final Parameter thisParameter; | 420 Parameter interceptorParameter; |
| 421 final Parameter receiverParameter; |
420 final List<Parameter> parameters; | 422 final List<Parameter> parameters; |
421 final Continuation returnContinuation; | 423 final Continuation returnContinuation; |
422 Expression body; | 424 Expression body; |
423 | 425 |
424 FunctionDefinition(this.element, this.thisParameter, this.parameters, | 426 FunctionDefinition(this.element, this.receiverParameter, this.parameters, |
425 this.returnContinuation, this.body); | 427 this.returnContinuation, this.body, {this.interceptorParameter}); |
426 | 428 |
427 accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this); | 429 accept(BlockVisitor visitor) => visitor.visitFunctionDefinition(this); |
428 | 430 |
429 void setParentPointers() { | 431 void setParentPointers() { |
430 if (thisParameter != null) thisParameter.parent = this; | 432 if (interceptorParameter != null) interceptorParameter.parent = this; |
| 433 if (receiverParameter != null) receiverParameter.parent = this; |
431 _setParentsOnNodes(parameters, this); | 434 _setParentsOnNodes(parameters, this); |
432 returnContinuation.parent = this; | 435 returnContinuation.parent = this; |
433 if (body != null) body.parent = this; | 436 if (body != null) body.parent = this; |
434 } | 437 } |
435 } | 438 } |
436 | 439 |
437 // ---------------------------------------------------------------------------- | 440 // ---------------------------------------------------------------------------- |
438 // PRIMITIVES | 441 // PRIMITIVES |
439 // ---------------------------------------------------------------------------- | 442 // ---------------------------------------------------------------------------- |
440 | 443 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 /// JS receiver is the Dart receiver, there are no extra arguments. | 487 /// JS receiver is the Dart receiver, there are no extra arguments. |
485 /// | 488 /// |
486 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)` | 489 /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)` |
487 OneShotIntercepted, | 490 OneShotIntercepted, |
488 } | 491 } |
489 | 492 |
490 /// Base class of function invocations. | 493 /// Base class of function invocations. |
491 /// | 494 /// |
492 /// This class defines the common interface of function invocations. | 495 /// This class defines the common interface of function invocations. |
493 abstract class InvocationPrimitive extends UnsafePrimitive { | 496 abstract class InvocationPrimitive extends UnsafePrimitive { |
| 497 Reference<Primitive> get interceptorRef => null; |
| 498 Primitive get interceptor => interceptorRef?.definition; |
| 499 |
494 Reference<Primitive> get receiverRef => null; | 500 Reference<Primitive> get receiverRef => null; |
495 Primitive get receiver => receiverRef?.definition; | 501 Primitive get receiver => receiverRef?.definition; |
496 | 502 |
497 List<Reference<Primitive>> get argumentRefs; | 503 List<Reference<Primitive>> get argumentRefs; |
498 Primitive argument(int n) => argumentRefs[n].definition; | 504 Primitive argument(int n) => argumentRefs[n].definition; |
499 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); | 505 Iterable<Primitive> get arguments => _dereferenceList(argumentRefs); |
500 | 506 |
501 Reference<Primitive> get dartReceiverRef => null; | |
502 Primitive get dartReceiver => dartReceiverRef?.definition; | |
503 | |
504 CallingConvention get callingConvention => CallingConvention.Normal; | 507 CallingConvention get callingConvention => CallingConvention.Normal; |
505 | 508 |
506 Reference<Primitive> dartArgumentReference(int n) { | |
507 switch (callingConvention) { | |
508 case CallingConvention.Normal: | |
509 case CallingConvention.OneShotIntercepted: | |
510 return argumentRefs[n]; | |
511 | |
512 case CallingConvention.Intercepted: | |
513 case CallingConvention.DummyIntercepted: | |
514 return argumentRefs[n + 1]; | |
515 } | |
516 } | |
517 | |
518 Primitive dartArgument(int n) => dartArgumentReference(n).definition; | |
519 | |
520 int get dartArgumentsLength => | |
521 argumentRefs.length - | |
522 (callingConvention == CallingConvention.Intercepted || | |
523 callingConvention == CallingConvention.DummyIntercepted ? 1 : 0); | |
524 | |
525 SourceInformation get sourceInformation; | 509 SourceInformation get sourceInformation; |
526 } | 510 } |
527 | 511 |
528 /// Invoke a static function. | 512 /// Invoke a static function. |
529 /// | 513 /// |
530 /// All optional arguments declared by [target] are passed in explicitly, and | 514 /// All optional arguments declared by [target] are passed in explicitly, and |
531 /// occur at the end of [arguments] list, in normalized order. | 515 /// occur at the end of [arguments] list, in normalized order. |
532 /// | 516 /// |
533 /// Discussion: | 517 /// Discussion: |
534 /// All information in the [selector] is technically redundant; it will likely | 518 /// All information in the [selector] is technically redundant; it will likely |
(...skipping 23 matching lines...) Expand all Loading... |
558 /// Invoke a method on an object. | 542 /// Invoke a method on an object. |
559 /// | 543 /// |
560 /// This includes getters, setters, operators, and index getter/setters. | 544 /// This includes getters, setters, operators, and index getter/setters. |
561 /// | 545 /// |
562 /// Tearing off a method is treated like a getter invocation (getters and | 546 /// Tearing off a method is treated like a getter invocation (getters and |
563 /// tear-offs cannot be distinguished at compile-time). | 547 /// tear-offs cannot be distinguished at compile-time). |
564 /// | 548 /// |
565 /// The [selector] records the names of named arguments. The value of named | 549 /// The [selector] records the names of named arguments. The value of named |
566 /// arguments occur at the end of the [arguments] list, in normalized order. | 550 /// arguments occur at the end of the [arguments] list, in normalized order. |
567 class InvokeMethod extends InvocationPrimitive { | 551 class InvokeMethod extends InvocationPrimitive { |
| 552 Reference<Primitive> interceptorRef; |
568 Reference<Primitive> receiverRef; | 553 Reference<Primitive> receiverRef; |
569 Selector selector; | 554 Selector selector; |
570 TypeMask mask; | 555 TypeMask mask; |
571 final List<Reference<Primitive>> argumentRefs; | 556 final List<Reference<Primitive>> argumentRefs; |
572 final SourceInformation sourceInformation; | 557 final SourceInformation sourceInformation; |
| 558 CallingConvention _callingConvention; |
573 | 559 |
574 CallingConvention callingConvention = CallingConvention.Normal; | 560 CallingConvention get callingConvention => _callingConvention; |
575 | |
576 Reference<Primitive> get dartReceiverRef { | |
577 return callingConvention == CallingConvention.Intercepted | |
578 ? argumentRefs[0] | |
579 : receiverRef; | |
580 } | |
581 | 561 |
582 InvokeMethod( | 562 InvokeMethod( |
583 Primitive receiver, this.selector, this.mask, List<Primitive> arguments, | 563 Primitive receiver, this.selector, this.mask, List<Primitive> arguments, |
584 {this.sourceInformation, | 564 {this.sourceInformation, |
585 this.callingConvention: CallingConvention.Normal}) | 565 CallingConvention callingConvention, |
| 566 Primitive interceptor}) |
586 : this.receiverRef = new Reference<Primitive>(receiver), | 567 : this.receiverRef = new Reference<Primitive>(receiver), |
587 this.argumentRefs = _referenceList(arguments); | 568 this.argumentRefs = _referenceList(arguments), |
| 569 this.interceptorRef = _optionalReference(interceptor), |
| 570 this._callingConvention = callingConvention ?? |
| 571 (interceptor != null |
| 572 ? CallingConvention.Intercepted |
| 573 : CallingConvention.Normal); |
588 | 574 |
589 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 575 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
590 | 576 |
591 bool get hasValue => true; | 577 bool get hasValue => true; |
592 | 578 |
593 void setParentPointers() { | 579 void setParentPointers() { |
| 580 interceptorRef?.parent = this; |
594 receiverRef.parent = this; | 581 receiverRef.parent = this; |
595 _setParentsOnList(argumentRefs, this); | 582 _setParentsOnList(argumentRefs, this); |
596 } | 583 } |
| 584 |
| 585 void makeIntercepted(Primitive interceptor) { |
| 586 interceptorRef?.unlink(); |
| 587 interceptorRef = new Reference<Primitive>(interceptor)..parent = this; |
| 588 _callingConvention = CallingConvention.Intercepted; |
| 589 } |
| 590 |
| 591 void makeOneShotIntercepted() { |
| 592 interceptorRef?.unlink(); |
| 593 interceptorRef = null; |
| 594 _callingConvention = CallingConvention.OneShotIntercepted; |
| 595 } |
| 596 |
| 597 void makeDummyIntercepted() { |
| 598 interceptorRef?.unlink(); |
| 599 interceptorRef = null; |
| 600 _callingConvention = CallingConvention.DummyIntercepted; |
| 601 } |
597 } | 602 } |
598 | 603 |
599 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. | 604 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. |
600 /// | 605 /// |
601 /// That is, if [receiver] is an instance of a class that overrides [target] | 606 /// That is, if [receiver] is an instance of a class that overrides [target] |
602 /// with a different implementation, the overriding implementation is bypassed | 607 /// with a different implementation, the overriding implementation is bypassed |
603 /// and [target]'s implementation is invoked. | 608 /// and [target]'s implementation is invoked. |
604 /// | 609 /// |
605 /// As with [InvokeMethod], this can be used to invoke a method, operator, | 610 /// As with [InvokeMethod], this can be used to invoke a method, operator, |
606 /// getter, setter, or index getter/setter. | 611 /// getter, setter, or index getter/setter. |
607 /// | 612 /// |
608 /// If it is known that [target] does not use its receiver argument, then | 613 /// If it is known that [target] does not use its receiver argument, then |
609 /// [receiver] may refer to a null constant primitive. This happens for direct | 614 /// [receiver] may refer to a null constant primitive. This happens for direct |
610 /// invocations to intercepted methods, where the effective receiver is instead | 615 /// invocations to intercepted methods, where the effective receiver is instead |
611 /// passed as a formal parameter. | 616 /// passed as a formal parameter. |
612 /// | 617 /// |
613 /// TODO(sra): Review. A direct call to a method that is mixed into a native | 618 /// TODO(sra): Review. A direct call to a method that is mixed into a native |
614 /// class will still require an explicit argument. | 619 /// class will still require an explicit argument. |
615 /// | 620 /// |
616 /// All optional arguments declared by [target] are passed in explicitly, and | 621 /// All optional arguments declared by [target] are passed in explicitly, and |
617 /// occur at the end of [arguments] list, in normalized order. | 622 /// occur at the end of [arguments] list, in normalized order. |
618 class InvokeMethodDirectly extends InvocationPrimitive { | 623 class InvokeMethodDirectly extends InvocationPrimitive { |
| 624 Reference<Primitive> interceptorRef; |
619 Reference<Primitive> receiverRef; | 625 Reference<Primitive> receiverRef; |
620 final FunctionElement target; | 626 final FunctionElement target; |
621 final Selector selector; | 627 final Selector selector; |
622 final List<Reference<Primitive>> argumentRefs; | 628 final List<Reference<Primitive>> argumentRefs; |
623 final SourceInformation sourceInformation; | 629 final SourceInformation sourceInformation; |
624 | 630 |
625 CallingConvention callingConvention; | |
626 | |
627 Reference<Primitive> get dartReceiverRef { | |
628 return callingConvention == CallingConvention.Intercepted | |
629 ? argumentRefs[0] | |
630 : receiverRef; | |
631 } | |
632 | |
633 InvokeMethodDirectly(Primitive receiver, this.target, this.selector, | 631 InvokeMethodDirectly(Primitive receiver, this.target, this.selector, |
634 List<Primitive> arguments, this.sourceInformation, | 632 List<Primitive> arguments, this.sourceInformation, |
635 {this.callingConvention: CallingConvention.Normal}) | 633 {Primitive interceptor}) |
636 : this.receiverRef = new Reference<Primitive>(receiver), | 634 : this.receiverRef = new Reference<Primitive>(receiver), |
637 this.argumentRefs = _referenceList(arguments); | 635 this.argumentRefs = _referenceList(arguments), |
| 636 this.interceptorRef = _optionalReference(interceptor); |
638 | 637 |
639 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); | 638 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); |
640 | 639 |
641 bool get hasValue => true; | 640 bool get hasValue => true; |
642 | 641 |
643 void setParentPointers() { | 642 void setParentPointers() { |
| 643 interceptorRef?.parent = this; |
644 receiverRef.parent = this; | 644 receiverRef.parent = this; |
645 _setParentsOnList(argumentRefs, this); | 645 _setParentsOnList(argumentRefs, this); |
646 } | 646 } |
647 | 647 |
648 bool get isConstructorBodyCall => target is ConstructorBodyElement; | 648 bool get isConstructorBodyCall => target is ConstructorBodyElement; |
649 bool get isTearOff => selector.isGetter && !target.isGetter; | 649 bool get isTearOff => selector.isGetter && !target.isGetter; |
| 650 |
| 651 void makeIntercepted(Primitive interceptor) { |
| 652 interceptorRef?.unlink(); |
| 653 interceptorRef = new Reference<Primitive>(interceptor)..parent = this; |
| 654 } |
650 } | 655 } |
651 | 656 |
652 /// Non-const call to a constructor. | 657 /// Non-const call to a constructor. |
653 /// | 658 /// |
654 /// The [target] may be a generative constructor (forwarding or normal) | 659 /// The [target] may be a generative constructor (forwarding or normal) |
655 /// or a non-redirecting factory. | 660 /// or a non-redirecting factory. |
656 /// | 661 /// |
657 /// All optional arguments declared by [target] are passed in explicitly, and | 662 /// All optional arguments declared by [target] are passed in explicitly, and |
658 /// occur in the [arguments] list, in normalized order. | 663 /// occur in the [arguments] list, in normalized order. |
659 /// | 664 /// |
(...skipping 1606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 class DeepRecursiveVisitor implements Visitor { | 2271 class DeepRecursiveVisitor implements Visitor { |
2267 const DeepRecursiveVisitor(); | 2272 const DeepRecursiveVisitor(); |
2268 | 2273 |
2269 visit(Node node) => node.accept(this); | 2274 visit(Node node) => node.accept(this); |
2270 | 2275 |
2271 processReference(Reference ref) {} | 2276 processReference(Reference ref) {} |
2272 | 2277 |
2273 processFunctionDefinition(FunctionDefinition node) {} | 2278 processFunctionDefinition(FunctionDefinition node) {} |
2274 visitFunctionDefinition(FunctionDefinition node) { | 2279 visitFunctionDefinition(FunctionDefinition node) { |
2275 processFunctionDefinition(node); | 2280 processFunctionDefinition(node); |
2276 if (node.thisParameter != null) visit(node.thisParameter); | 2281 if (node.interceptorParameter != null) visit(node.interceptorParameter); |
| 2282 if (node.receiverParameter != null) visit(node.receiverParameter); |
2277 node.parameters.forEach(visit); | 2283 node.parameters.forEach(visit); |
2278 visit(node.body); | 2284 visit(node.body); |
2279 } | 2285 } |
2280 | 2286 |
2281 processContinuation(Continuation node) {} | 2287 processContinuation(Continuation node) {} |
2282 visitContinuation(Continuation node) { | 2288 visitContinuation(Continuation node) { |
2283 processContinuation(node); | 2289 processContinuation(node); |
2284 node.parameters.forEach(visit); | 2290 node.parameters.forEach(visit); |
2285 if (node.body != null) visit(node.body); | 2291 if (node.body != null) visit(node.body); |
2286 } | 2292 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 processInvokeContinuation(InvokeContinuation node) {} | 2330 processInvokeContinuation(InvokeContinuation node) {} |
2325 visitInvokeContinuation(InvokeContinuation node) { | 2331 visitInvokeContinuation(InvokeContinuation node) { |
2326 processInvokeContinuation(node); | 2332 processInvokeContinuation(node); |
2327 processReference(node.continuationRef); | 2333 processReference(node.continuationRef); |
2328 node.argumentRefs.forEach(processReference); | 2334 node.argumentRefs.forEach(processReference); |
2329 } | 2335 } |
2330 | 2336 |
2331 processInvokeMethod(InvokeMethod node) {} | 2337 processInvokeMethod(InvokeMethod node) {} |
2332 visitInvokeMethod(InvokeMethod node) { | 2338 visitInvokeMethod(InvokeMethod node) { |
2333 processInvokeMethod(node); | 2339 processInvokeMethod(node); |
| 2340 if (node.interceptorRef != null) { |
| 2341 processReference(node.interceptorRef); |
| 2342 } |
2334 processReference(node.receiverRef); | 2343 processReference(node.receiverRef); |
2335 node.argumentRefs.forEach(processReference); | 2344 node.argumentRefs.forEach(processReference); |
2336 } | 2345 } |
2337 | 2346 |
2338 processInvokeMethodDirectly(InvokeMethodDirectly node) {} | 2347 processInvokeMethodDirectly(InvokeMethodDirectly node) {} |
2339 visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 2348 visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
2340 processInvokeMethodDirectly(node); | 2349 processInvokeMethodDirectly(node); |
| 2350 if (node.interceptorRef != null) { |
| 2351 processReference(node.interceptorRef); |
| 2352 } |
2341 processReference(node.receiverRef); | 2353 processReference(node.receiverRef); |
2342 node.argumentRefs.forEach(processReference); | 2354 node.argumentRefs.forEach(processReference); |
2343 } | 2355 } |
2344 | 2356 |
2345 processInvokeConstructor(InvokeConstructor node) {} | 2357 processInvokeConstructor(InvokeConstructor node) {} |
2346 visitInvokeConstructor(InvokeConstructor node) { | 2358 visitInvokeConstructor(InvokeConstructor node) { |
2347 processInvokeConstructor(node); | 2359 processInvokeConstructor(node); |
2348 node.argumentRefs.forEach(processReference); | 2360 node.argumentRefs.forEach(processReference); |
2349 } | 2361 } |
2350 | 2362 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 if (cont.isReturnContinuation) { | 2631 if (cont.isReturnContinuation) { |
2620 traverseContinuation(cont); | 2632 traverseContinuation(cont); |
2621 } else { | 2633 } else { |
2622 _processBlock(traverseContinuation(cont)); | 2634 _processBlock(traverseContinuation(cont)); |
2623 } | 2635 } |
2624 }); | 2636 }); |
2625 } | 2637 } |
2626 | 2638 |
2627 visitFunctionDefinition(FunctionDefinition node) { | 2639 visitFunctionDefinition(FunctionDefinition node) { |
2628 processFunctionDefinition(node); | 2640 processFunctionDefinition(node); |
2629 if (node.thisParameter != null) visit(node.thisParameter); | 2641 if (node.interceptorParameter != null) visit(node.interceptorParameter); |
| 2642 if (node.receiverParameter != null) visit(node.receiverParameter); |
2630 node.parameters.forEach(visit); | 2643 node.parameters.forEach(visit); |
2631 visit(node.body); | 2644 visit(node.body); |
2632 } | 2645 } |
2633 | 2646 |
2634 visitContinuation(Continuation cont) { | 2647 visitContinuation(Continuation cont) { |
2635 if (cont.isReturnContinuation) { | 2648 if (cont.isReturnContinuation) { |
2636 traverseContinuation(cont); | 2649 traverseContinuation(cont); |
2637 } else { | 2650 } else { |
2638 int initialHeight = _stack.length; | 2651 int initialHeight = _stack.length; |
2639 Expression body = traverseContinuation(cont); | 2652 Expression body = traverseContinuation(cont); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 | 2781 |
2769 Definition visitInvokeStatic(InvokeStatic node) { | 2782 Definition visitInvokeStatic(InvokeStatic node) { |
2770 return new InvokeStatic(node.target, node.selector, | 2783 return new InvokeStatic(node.target, node.selector, |
2771 getList(node.argumentRefs), node.sourceInformation); | 2784 getList(node.argumentRefs), node.sourceInformation); |
2772 } | 2785 } |
2773 | 2786 |
2774 Definition visitInvokeMethod(InvokeMethod node) { | 2787 Definition visitInvokeMethod(InvokeMethod node) { |
2775 return new InvokeMethod(getCopy(node.receiverRef), node.selector, node.mask, | 2788 return new InvokeMethod(getCopy(node.receiverRef), node.selector, node.mask, |
2776 getList(node.argumentRefs), | 2789 getList(node.argumentRefs), |
2777 sourceInformation: node.sourceInformation, | 2790 sourceInformation: node.sourceInformation, |
2778 callingConvention: node.callingConvention); | 2791 callingConvention: node.callingConvention, |
| 2792 interceptor: getCopyOrNull(node.interceptorRef)); |
2779 } | 2793 } |
2780 | 2794 |
2781 Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 2795 Definition visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
2782 return new InvokeMethodDirectly(getCopy(node.receiverRef), node.target, | 2796 return new InvokeMethodDirectly(getCopy(node.receiverRef), node.target, |
2783 node.selector, getList(node.argumentRefs), node.sourceInformation, | 2797 node.selector, getList(node.argumentRefs), node.sourceInformation, |
2784 callingConvention: node.callingConvention); | 2798 interceptor: getCopyOrNull(node.interceptorRef)); |
2785 } | 2799 } |
2786 | 2800 |
2787 Definition visitInvokeConstructor(InvokeConstructor node) { | 2801 Definition visitInvokeConstructor(InvokeConstructor node) { |
2788 return new InvokeConstructor( | 2802 return new InvokeConstructor( |
2789 node.dartType, | 2803 node.dartType, |
2790 node.target, | 2804 node.target, |
2791 node.selector, | 2805 node.selector, |
2792 getList(node.argumentRefs), | 2806 getList(node.argumentRefs), |
2793 node.sourceInformation)..allocationSiteType = node.allocationSiteType; | 2807 node.sourceInformation)..allocationSiteType = node.allocationSiteType; |
2794 } | 2808 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 _first = savedFirst; | 3014 _first = savedFirst; |
3001 _current = null; | 3015 _current = null; |
3002 }); | 3016 }); |
3003 } | 3017 } |
3004 | 3018 |
3005 FunctionDefinition copy(FunctionDefinition node) { | 3019 FunctionDefinition copy(FunctionDefinition node) { |
3006 assert(_first == null && _current == null); | 3020 assert(_first == null && _current == null); |
3007 _first = _current = null; | 3021 _first = _current = null; |
3008 // Definitions are copied where they are bound, before processing | 3022 // Definitions are copied where they are bound, before processing |
3009 // expressions in the scope of their binding. | 3023 // expressions in the scope of their binding. |
3010 Parameter thisParameter = node.thisParameter == null | 3024 Parameter thisParameter = node.receiverParameter == null |
3011 ? null | 3025 ? null |
3012 : _definitions.copy(node.thisParameter); | 3026 : _definitions.copy(node.receiverParameter); |
| 3027 Parameter interceptorParameter = node.interceptorParameter == null |
| 3028 ? null |
| 3029 : _definitions.copy(node.interceptorParameter); |
3013 List<Parameter> parameters = | 3030 List<Parameter> parameters = |
3014 node.parameters.map(_definitions.copy).toList(); | 3031 node.parameters.map(_definitions.copy).toList(); |
3015 // Though the return continuation's parameter does not have any uses, | 3032 // Though the return continuation's parameter does not have any uses, |
3016 // we still make a proper copy to ensure that hints, type, etc. are | 3033 // we still make a proper copy to ensure that hints, type, etc. are |
3017 // copied. | 3034 // copied. |
3018 Parameter returnParameter = | 3035 Parameter returnParameter = |
3019 _definitions.copy(node.returnContinuation.parameters.first); | 3036 _definitions.copy(node.returnContinuation.parameters.first); |
3020 Continuation returnContinuation = | 3037 Continuation returnContinuation = |
3021 _copies[node.returnContinuation] = new Continuation([returnParameter]); | 3038 _copies[node.returnContinuation] = new Continuation([returnParameter]); |
3022 | 3039 |
3023 visit(node.body); | 3040 visit(node.body); |
3024 FunctionDefinition copy = new FunctionDefinition( | 3041 FunctionDefinition copy = new FunctionDefinition( |
3025 node.element, thisParameter, parameters, returnContinuation, _first); | 3042 node.element, thisParameter, parameters, returnContinuation, _first, |
| 3043 interceptorParameter: interceptorParameter); |
3026 _first = _current = null; | 3044 _first = _current = null; |
3027 return copy; | 3045 return copy; |
3028 } | 3046 } |
3029 | 3047 |
3030 Node visit(Node node) => node.accept(this); | 3048 Node visit(Node node) => node.accept(this); |
3031 | 3049 |
3032 Expression traverseLetCont(LetCont node) { | 3050 Expression traverseLetCont(LetCont node) { |
3033 // Continuations are copied where they are bound, before processing | 3051 // Continuations are copied where they are bound, before processing |
3034 // expressions in the scope of their binding. | 3052 // expressions in the scope of their binding. |
3035 List<Continuation> continuations = node.continuations.map((Continuation c) { | 3053 List<Continuation> continuations = node.continuations.map((Continuation c) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3084 plug(new Branch.loose( | 3102 plug(new Branch.loose( |
3085 _definitions.getCopy(node.conditionRef), | 3103 _definitions.getCopy(node.conditionRef), |
3086 _copies[node.trueContinuation], | 3104 _copies[node.trueContinuation], |
3087 _copies[node.falseContinuation])..isStrictCheck = node.isStrictCheck); | 3105 _copies[node.falseContinuation])..isStrictCheck = node.isStrictCheck); |
3088 } | 3106 } |
3089 | 3107 |
3090 visitUnreachable(Unreachable node) { | 3108 visitUnreachable(Unreachable node) { |
3091 plug(new Unreachable()); | 3109 plug(new Unreachable()); |
3092 } | 3110 } |
3093 } | 3111 } |
OLD | NEW |