| 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 '../constants/expressions.dart'; | |
| 7 import '../constants/values.dart' as values show ConstantValue; | 6 import '../constants/values.dart' as values show ConstantValue; |
| 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 7 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 9 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 10 import '../io/source_information.dart' show SourceInformation; | 9 import '../io/source_information.dart' show SourceInformation; |
| 11 import '../types/types.dart' show TypeMask; | 10 import '../types/types.dart' show TypeMask; |
| 12 import '../universe/universe.dart' show Selector, SelectorKind; | 11 import '../universe/universe.dart' show Selector; |
| 13 | 12 |
| 14 import 'builtin_operator.dart'; | 13 import 'builtin_operator.dart'; |
| 15 export 'builtin_operator.dart'; | 14 export 'builtin_operator.dart'; |
| 16 | 15 |
| 17 // These imports are only used for the JavaScript specific nodes. If we want to | 16 // These imports are only used for the JavaScript specific nodes. If we want to |
| 18 // support more than one native backend, we should probably create better | 17 // support more than one native backend, we should probably create better |
| 19 // abstractions for native code and its type and effect system. | 18 // abstractions for native code and its type and effect system. |
| 20 import '../js/js.dart' as js show Template; | 19 import '../js/js.dart' as js show Template; |
| 21 import '../native/native.dart' as native show NativeBehavior; | 20 import '../native/native.dart' as native show NativeBehavior; |
| 22 import '../types/types.dart' as types show TypeMask; | |
| 23 | 21 |
| 24 abstract class Node { | 22 abstract class Node { |
| 25 /// A pointer to the parent node. Is null until set by optimization passes. | 23 /// A pointer to the parent node. Is null until set by optimization passes. |
| 26 Node parent; | 24 Node parent; |
| 27 | 25 |
| 28 accept(Visitor visitor); | 26 accept(Visitor visitor); |
| 29 } | 27 } |
| 30 | 28 |
| 31 /// Expressions can be evaluated, and may diverge, throw, and/or have | 29 /// Expressions can be evaluated, and may diverge, throw, and/or have |
| 32 /// side-effects. | 30 /// side-effects. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 /// During one-pass construction a LetCont whose first continuation has an empty | 160 /// During one-pass construction a LetCont whose first continuation has an empty |
| 163 /// body is used to represent the one-hole context | 161 /// body is used to represent the one-hole context |
| 164 /// `let cont ... k(v) = [] ... in E`. | 162 /// `let cont ... k(v) = [] ... in E`. |
| 165 class LetCont extends Expression implements InteriorNode { | 163 class LetCont extends Expression implements InteriorNode { |
| 166 List<Continuation> continuations; | 164 List<Continuation> continuations; |
| 167 Expression body; | 165 Expression body; |
| 168 | 166 |
| 169 LetCont(Continuation continuation, this.body) | 167 LetCont(Continuation continuation, this.body) |
| 170 : continuations = <Continuation>[continuation]; | 168 : continuations = <Continuation>[continuation]; |
| 171 | 169 |
| 170 LetCont.two(Continuation first, Continuation second, this.body) |
| 171 : continuations = <Continuation>[first, second]; |
| 172 |
| 172 LetCont.many(this.continuations, this.body); | 173 LetCont.many(this.continuations, this.body); |
| 173 | 174 |
| 174 Expression plug(Expression expr) { | 175 Expression plug(Expression expr) { |
| 175 assert(continuations != null && | 176 assert(continuations != null && |
| 176 continuations.isNotEmpty && | 177 continuations.isNotEmpty && |
| 177 continuations.first.body == null); | 178 continuations.first.body == null); |
| 178 return continuations.first.body = expr; | 179 return continuations.first.body = expr; |
| 179 } | 180 } |
| 180 | 181 |
| 181 accept(Visitor visitor) => visitor.visitLetCont(this); | 182 accept(Visitor visitor) => visitor.visitLetCont(this); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 final FunctionElement target; | 255 final FunctionElement target; |
| 255 final Selector selector; | 256 final Selector selector; |
| 256 final List<Reference<Primitive>> arguments; | 257 final List<Reference<Primitive>> arguments; |
| 257 final Reference<Continuation> continuation; | 258 final Reference<Continuation> continuation; |
| 258 final SourceInformation sourceInformation; | 259 final SourceInformation sourceInformation; |
| 259 | 260 |
| 260 InvokeStatic(this.target, | 261 InvokeStatic(this.target, |
| 261 this.selector, | 262 this.selector, |
| 262 List<Primitive> args, | 263 List<Primitive> args, |
| 263 Continuation cont, | 264 Continuation cont, |
| 264 this.sourceInformation) | 265 [this.sourceInformation]) |
| 265 : arguments = _referenceList(args), | 266 : arguments = _referenceList(args), |
| 266 continuation = new Reference<Continuation>(cont); | 267 continuation = new Reference<Continuation>(cont); |
| 267 | 268 |
| 268 accept(Visitor visitor) => visitor.visitInvokeStatic(this); | 269 accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
| 269 } | 270 } |
| 270 | 271 |
| 271 /// Invoke a method on an object. | 272 /// Invoke a method on an object. |
| 272 /// | 273 /// |
| 273 /// This includes getters, setters, operators, and index getter/setters. | 274 /// This includes getters, setters, operators, and index getter/setters. |
| 274 /// | 275 /// |
| 275 /// Tearing off a method is treated like a getter invocation (getters and | 276 /// Tearing off a method is treated like a getter invocation (getters and |
| 276 /// tear-offs cannot be distinguished at compile-time). | 277 /// tear-offs cannot be distinguished at compile-time). |
| 277 /// | 278 /// |
| 278 /// The [selector] records the names of named arguments. The value of named | 279 /// The [selector] records the names of named arguments. The value of named |
| 279 /// arguments occur at the end of the [arguments] list, in normalized order. | 280 /// arguments occur at the end of the [arguments] list, in normalized order. |
| 280 /// | |
| 281 /// Discussion: | |
| 282 /// If the [selector] is a [TypedSelector], the type information contained | |
| 283 /// there is used by optimization passes. This is likely to change. | |
| 284 class InvokeMethod extends Expression implements Invoke { | 281 class InvokeMethod extends Expression implements Invoke { |
| 285 Reference<Primitive> receiver; | 282 Reference<Primitive> receiver; |
| 286 Selector selector; | 283 Selector selector; |
| 287 TypeMask mask; | 284 TypeMask mask; |
| 288 final List<Reference<Primitive>> arguments; | 285 final List<Reference<Primitive>> arguments; |
| 289 final Reference<Continuation> continuation; | 286 final Reference<Continuation> continuation; |
| 290 final SourceInformation sourceInformation; | 287 final SourceInformation sourceInformation; |
| 291 | 288 |
| 292 /// If true, it is known that the receiver cannot be `null`. | 289 /// If true, it is known that the receiver cannot be `null`. |
| 293 bool receiverIsNotNull = false; | 290 bool receiverIsNotNull = false; |
| 294 | 291 |
| 295 InvokeMethod(Primitive receiver, | 292 InvokeMethod(Primitive receiver, |
| 296 this.selector, | 293 this.selector, |
| 297 this.mask, | 294 this.mask, |
| 298 List<Primitive> arguments, | 295 List<Primitive> arguments, |
| 299 Continuation continuation, | 296 Continuation continuation, |
| 300 {this.sourceInformation}) | 297 [this.sourceInformation]) |
| 301 : this.receiver = new Reference<Primitive>(receiver), | 298 : this.receiver = new Reference<Primitive>(receiver), |
| 302 this.arguments = _referenceList(arguments), | 299 this.arguments = _referenceList(arguments), |
| 303 this.continuation = new Reference<Continuation>(continuation); | 300 this.continuation = new Reference<Continuation>(continuation); |
| 304 | 301 |
| 305 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 302 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 306 } | 303 } |
| 307 | 304 |
| 308 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. | 305 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. |
| 309 /// | 306 /// |
| 310 /// That is, if [receiver] is an instance of a class that overrides [target] | 307 /// That is, if [receiver] is an instance of a class that overrides [target] |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 @override | 625 @override |
| 629 bool get isSafeForElimination => objectIsNotNull; | 626 bool get isSafeForElimination => objectIsNotNull; |
| 630 } | 627 } |
| 631 | 628 |
| 632 /// Reads the value of a static field or tears off a static method. | 629 /// Reads the value of a static field or tears off a static method. |
| 633 class GetStatic extends Primitive { | 630 class GetStatic extends Primitive { |
| 634 /// Can be [FieldElement] or [FunctionElement]. | 631 /// Can be [FieldElement] or [FunctionElement]. |
| 635 final Element element; | 632 final Element element; |
| 636 final SourceInformation sourceInformation; | 633 final SourceInformation sourceInformation; |
| 637 | 634 |
| 638 GetStatic(this.element, this.sourceInformation); | 635 GetStatic(this.element, [this.sourceInformation]); |
| 639 | 636 |
| 640 accept(Visitor visitor) => visitor.visitGetStatic(this); | 637 accept(Visitor visitor) => visitor.visitGetStatic(this); |
| 641 } | 638 } |
| 642 | 639 |
| 643 /// Sets the value of a static field. | 640 /// Sets the value of a static field. |
| 644 class SetStatic extends Expression implements InteriorNode { | 641 class SetStatic extends Expression implements InteriorNode { |
| 645 final FieldElement element; | 642 final FieldElement element; |
| 646 final Reference<Primitive> value; | 643 final Reference<Primitive> value; |
| 647 Expression body; | 644 Expression body; |
| 648 final SourceInformation sourceInformation; | 645 final SourceInformation sourceInformation; |
| 649 | 646 |
| 650 SetStatic(this.element, Primitive value, this.sourceInformation) | 647 SetStatic(this.element, Primitive value, [this.sourceInformation]) |
| 651 : this.value = new Reference<Primitive>(value); | 648 : this.value = new Reference<Primitive>(value); |
| 652 | 649 |
| 653 Expression plug(Expression expr) { | 650 Expression plug(Expression expr) { |
| 654 assert(body == null); | 651 assert(body == null); |
| 655 return body = expr; | 652 return body = expr; |
| 656 } | 653 } |
| 657 | 654 |
| 658 accept(Visitor visitor) => visitor.visitSetStatic(this); | 655 accept(Visitor visitor) => visitor.visitSetStatic(this); |
| 659 } | 656 } |
| 660 | 657 |
| 661 /// Reads the value of a lazily initialized static field. | 658 /// Reads the value of a lazily initialized static field. |
| 662 /// | 659 /// |
| 663 /// If the field has not yet been initialized, its initializer is evaluated | 660 /// If the field has not yet been initialized, its initializer is evaluated |
| 664 /// and assigned to the field. | 661 /// and assigned to the field. |
| 665 /// | 662 /// |
| 666 /// [continuation] is then invoked with the value of the field as argument. | 663 /// [continuation] is then invoked with the value of the field as argument. |
| 667 class GetLazyStatic extends Expression { | 664 class GetLazyStatic extends Expression { |
| 668 final FieldElement element; | 665 final FieldElement element; |
| 669 final Reference<Continuation> continuation; | 666 final Reference<Continuation> continuation; |
| 670 final SourceInformation sourceInformation; | 667 final SourceInformation sourceInformation; |
| 671 | 668 |
| 672 GetLazyStatic(this.element, | 669 GetLazyStatic(this.element, |
| 673 Continuation continuation, | 670 Continuation continuation, |
| 674 this.sourceInformation) | 671 [this.sourceInformation]) |
| 675 : continuation = new Reference<Continuation>(continuation); | 672 : continuation = new Reference<Continuation>(continuation); |
| 676 | 673 |
| 677 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); | 674 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); |
| 678 } | 675 } |
| 679 | 676 |
| 680 /// Creates an object for holding boxed variables captured by a closure. | 677 /// Creates an object for holding boxed variables captured by a closure. |
| 681 class CreateBox extends Primitive { | 678 class CreateBox extends Primitive { |
| 682 accept(Visitor visitor) => visitor.visitCreateBox(this); | 679 accept(Visitor visitor) => visitor.visitCreateBox(this); |
| 683 } | 680 } |
| 684 | 681 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 final List<Reference<Primitive>> arguments; | 717 final List<Reference<Primitive>> arguments; |
| 721 | 718 |
| 722 CreateInvocationMirror(this.selector, List<Primitive> arguments) | 719 CreateInvocationMirror(this.selector, List<Primitive> arguments) |
| 723 : this.arguments = _referenceList(arguments); | 720 : this.arguments = _referenceList(arguments); |
| 724 | 721 |
| 725 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); | 722 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); |
| 726 } | 723 } |
| 727 | 724 |
| 728 class ForeignCode extends Expression { | 725 class ForeignCode extends Expression { |
| 729 final js.Template codeTemplate; | 726 final js.Template codeTemplate; |
| 730 final types.TypeMask type; | 727 final TypeMask type; |
| 731 final List<Reference<Primitive>> arguments; | 728 final List<Reference<Primitive>> arguments; |
| 732 final native.NativeBehavior nativeBehavior; | 729 final native.NativeBehavior nativeBehavior; |
| 733 final FunctionElement dependency; | 730 final FunctionElement dependency; |
| 734 | 731 |
| 735 /// The continuation, if the foreign code is not a JavaScript 'throw', | 732 /// The continuation, if the foreign code is not a JavaScript 'throw', |
| 736 /// otherwise null. | 733 /// otherwise null. |
| 737 final Reference<Continuation> continuation; | 734 final Reference<Continuation> continuation; |
| 738 | 735 |
| 739 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments, | 736 ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments, |
| 740 this.nativeBehavior, {Continuation continuation, this.dependency}) | 737 this.nativeBehavior, {Continuation continuation, this.dependency}) |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1270 const RemovalVisitor(); | 1267 const RemovalVisitor(); |
| 1271 | 1268 |
| 1272 processReference(Reference reference) { | 1269 processReference(Reference reference) { |
| 1273 reference.unlink(); | 1270 reference.unlink(); |
| 1274 } | 1271 } |
| 1275 | 1272 |
| 1276 static void remove(Node node) { | 1273 static void remove(Node node) { |
| 1277 (const RemovalVisitor()).visit(node); | 1274 (const RemovalVisitor()).visit(node); |
| 1278 } | 1275 } |
| 1279 } | 1276 } |
| OLD | NEW |