| 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 |