| 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 | 4 |
| 5 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' show PrimitiveConstantValue; | 8 import '../constants/values.dart' show PrimitiveConstantValue; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../dart2jslib.dart'; | 10 import '../dart2jslib.dart'; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 /// Remove an [ir.MutableVariable] for a local. | 252 /// Remove an [ir.MutableVariable] for a local. |
| 253 /// | 253 /// |
| 254 /// Subsequent access to the local will be direct rather than through the | 254 /// Subsequent access to the local will be direct rather than through the |
| 255 /// mutable variable. This is used for variables that do not spend their | 255 /// mutable variable. This is used for variables that do not spend their |
| 256 /// entire lifetime as mutable variables (e.g., variables that are boxed | 256 /// entire lifetime as mutable variables (e.g., variables that are boxed |
| 257 /// in mutable variables for a try block). | 257 /// in mutable variables for a try block). |
| 258 void removeMutableVariable(Local local); | 258 void removeMutableVariable(Local local); |
| 259 | 259 |
| 260 void declareLocalVariable(LocalVariableElement element, | 260 void declareLocalVariable(LocalVariableElement element, |
| 261 {ir.Primitive initialValue}); | 261 {ir.Primitive initialValue}); |
| 262 ir.Primitive buildLocalGet(LocalElement element); | |
| 263 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); | |
| 264 | 262 |
| 265 /// Called when entering a nested function with free variables. | 263 /// Called when entering a nested function with free variables. |
| 266 /// | 264 /// |
| 267 /// The free variables must subsequently be accessible using [buildLocalGet] | 265 /// The free variables must subsequently be accessible using [buildLocalGet] |
| 268 /// and [buildLocalSet]. | 266 /// and [buildLocalSet]. |
| 269 void _enterClosureEnvironment(ClosureEnvironment env); | 267 void _enterClosureEnvironment(ClosureEnvironment env); |
| 270 | 268 |
| 271 /// Called when entering a function body or loop body. | 269 /// Called when entering a function body or loop body. |
| 272 /// | 270 /// |
| 273 /// This is not called for for-loops, which instead use the methods | 271 /// This is not called for for-loops, which instead use the methods |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 ir.Continuation k = new ir.Continuation([v]); | 446 ir.Continuation k = new ir.Continuation([v]); |
| 449 ir.Expression expression = build(k); | 447 ir.Expression expression = build(k); |
| 450 add(new ir.LetCont(k, expression)); | 448 add(new ir.LetCont(k, expression)); |
| 451 return v; | 449 return v; |
| 452 } | 450 } |
| 453 | 451 |
| 454 ir.Primitive _buildInvokeStatic(Element element, | 452 ir.Primitive _buildInvokeStatic(Element element, |
| 455 Selector selector, | 453 Selector selector, |
| 456 List<ir.Primitive> arguments, | 454 List<ir.Primitive> arguments, |
| 457 SourceInformation sourceInformation) { | 455 SourceInformation sourceInformation) { |
| 456 assert(!element.isLocal); |
| 457 assert(!element.isInstanceMember); |
| 458 assert(isOpen); | 458 assert(isOpen); |
| 459 return _continueWithExpression( | 459 return _continueWithExpression( |
| 460 (k) => new ir.InvokeStatic(element, selector, k, arguments, | 460 (k) => new ir.InvokeStatic(element, selector, k, arguments, |
| 461 sourceInformation)); | 461 sourceInformation)); |
| 462 } | 462 } |
| 463 | 463 |
| 464 ir.Primitive _buildInvokeSuper(Element target, | 464 ir.Primitive _buildInvokeSuper(Element target, |
| 465 Selector selector, | 465 Selector selector, |
| 466 List<ir.Primitive> arguments) { | 466 List<ir.Primitive> arguments) { |
| 467 assert(target.isInstanceMember); |
| 467 assert(isOpen); | 468 assert(isOpen); |
| 468 return _continueWithExpression( | 469 return _continueWithExpression( |
| 469 (k) => new ir.InvokeMethodDirectly( | 470 (k) => new ir.InvokeMethodDirectly( |
| 470 buildThis(), target, selector, k, arguments)); | 471 buildThis(), target, selector, k, arguments)); |
| 471 } | 472 } |
| 472 | 473 |
| 473 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, | 474 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, |
| 474 Selector selector, | 475 Selector selector, |
| 475 List<ir.Primitive> arguments) { | 476 List<ir.Primitive> arguments) { |
| 476 assert(isOpen); | 477 assert(isOpen); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 state.localConstants, defaults); | 691 state.localConstants, defaults); |
| 691 } | 692 } |
| 692 | 693 |
| 693 /// Create a super invocation where the method name and the argument structure | 694 /// Create a super invocation where the method name and the argument structure |
| 694 /// are defined by [selector] and the argument values are defined by | 695 /// are defined by [selector] and the argument values are defined by |
| 695 /// [arguments]. | 696 /// [arguments]. |
| 696 ir.Primitive buildSuperInvocation(Element target, | 697 ir.Primitive buildSuperInvocation(Element target, |
| 697 Selector selector, | 698 Selector selector, |
| 698 List<ir.Primitive> arguments); | 699 List<ir.Primitive> arguments); |
| 699 | 700 |
| 700 /// Create a setter invocation on the super class where the setter name and | 701 /// Create a getter invocation of the [target] on the super class. |
| 701 /// argument are defined by [selector] and [value], respectively. | 702 ir.Primitive buildSuperGet(Element target) { |
| 702 void buildSuperSet(Element target, Selector selector, ir.Primitive value) { | 703 Selector selector = new Selector.getter(target.name, target.library); |
| 704 return buildSuperInvocation(target, selector, const <ir.Primitive>[]); |
| 705 } |
| 706 |
| 707 /// Create a setter invocation of the [target] on the super class of with |
| 708 /// [value]. |
| 709 ir.Primitive buildSuperSet(Element target, ir.Primitive value) { |
| 710 Selector selector = new Selector.setter(target.name, target.library); |
| 703 buildSuperInvocation(target, selector, [value]); | 711 buildSuperInvocation(target, selector, [value]); |
| 712 return value; |
| 704 } | 713 } |
| 705 | 714 |
| 706 /// Create an index set invocation on the super class with the provided | 715 /// Create an index set invocation on the super class with the provided |
| 707 /// [index] and [value]. | 716 /// [index] and [value]. |
| 708 ir.Primitive buildSuperIndexSet(Element target, | 717 ir.Primitive buildSuperIndexSet(Element target, |
| 709 ir.Primitive index, | 718 ir.Primitive index, |
| 710 ir.Primitive value) { | 719 ir.Primitive value) { |
| 711 _buildInvokeSuper(target, new Selector.indexSet(), | 720 _buildInvokeSuper(target, new Selector.indexSet(), |
| 712 <ir.Primitive>[index, value]); | 721 <ir.Primitive>[index, value]); |
| 713 return value; | 722 return value; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 742 /// Create a dynamic index set invocation on [receiver] with the provided | 751 /// Create a dynamic index set invocation on [receiver] with the provided |
| 743 /// [index] and [value]. | 752 /// [index] and [value]. |
| 744 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver, | 753 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver, |
| 745 ir.Primitive index, | 754 ir.Primitive index, |
| 746 ir.Primitive value) { | 755 ir.Primitive value) { |
| 747 _buildInvokeDynamic( | 756 _buildInvokeDynamic( |
| 748 receiver, new Selector.indexSet(), <ir.Primitive>[index, value]); | 757 receiver, new Selector.indexSet(), <ir.Primitive>[index, value]); |
| 749 return value; | 758 return value; |
| 750 } | 759 } |
| 751 | 760 |
| 761 /// Create a read access of [local]. |
| 762 ir.Primitive buildLocalGet(LocalElement element); |
| 763 |
| 764 /// Create a write access to [local] with the provided [value]. |
| 765 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); |
| 766 |
| 767 /// Create an invocation of the local [element] where argument structure is |
| 768 /// defined by [selector] and the argument values are defined by [arguments]. |
| 769 ir.Primitive buildLocalInvocation(LocalElement element, |
| 770 Selector selector, |
| 771 List<ir.Primitive> arguments) { |
| 772 return buildCallInvocation(buildLocalGet(element), selector, arguments); |
| 773 } |
| 774 |
| 752 /// Create a static invocation of [element] where argument structure is | 775 /// Create a static invocation of [element] where argument structure is |
| 753 /// defined by [selector] and the argument values are defined by [arguments]. | 776 /// defined by [selector] and the argument values are defined by [arguments]. |
| 754 ir.Primitive buildStaticInvocation(Element element, | 777 ir.Primitive buildStaticInvocation(Element element, |
| 755 Selector selector, | 778 Selector selector, |
| 756 List<ir.Primitive> arguments, | 779 List<ir.Primitive> arguments, |
| 757 {SourceInformation sourceInformation}) { | 780 {SourceInformation sourceInformation}) { |
| 758 return _buildInvokeStatic(element, selector, arguments, sourceInformation); | 781 return _buildInvokeStatic(element, selector, arguments, sourceInformation); |
| 759 } | 782 } |
| 760 | 783 |
| 761 /// Create a static getter invocation of [element] where the getter name is | 784 /// Create a static getter invocation of [element] where the getter name is |
| 762 /// defined by [selector]. | 785 /// defined by [selector]. |
| 763 ir.Primitive buildStaticGet(Element element, | 786 ir.Primitive buildStaticGet(Element element, |
| 764 Selector selector, | |
| 765 {SourceInformation sourceInformation}) { | 787 {SourceInformation sourceInformation}) { |
| 766 assert(selector.isGetter); | 788 Selector selector = new Selector.getter(element.name, element.library); |
| 767 // TODO(karlklose,sigurdm): build different nodes for getters. | 789 // TODO(karlklose,sigurdm): build different nodes for getters. |
| 768 return _buildInvokeStatic( | 790 return _buildInvokeStatic( |
| 769 element, selector, const <ir.Primitive>[], sourceInformation); | 791 element, selector, const <ir.Primitive>[], sourceInformation); |
| 770 } | 792 } |
| 771 | 793 |
| 772 /// Create a static setter invocation of [element] where the setter name and | 794 /// Create a static setter invocation of [element] where the setter name and |
| 773 /// argument are defined by [selector] and [value], respectively. | 795 /// argument are defined by [selector] and [value], respectively. |
| 774 ir.Primitive buildStaticSet(Element element, | 796 ir.Primitive buildStaticSet(Element element, |
| 775 Selector selector, | |
| 776 ir.Primitive value, | 797 ir.Primitive value, |
| 777 {SourceInformation sourceInformation}) { | 798 {SourceInformation sourceInformation}) { |
| 778 assert(selector.isSetter); | 799 Selector selector = new Selector.setter(element.name, element.library); |
| 779 // TODO(karlklose,sigurdm): build different nodes for setters. | 800 // TODO(karlklose,sigurdm): build different nodes for setters. |
| 780 _buildInvokeStatic( | 801 _buildInvokeStatic( |
| 781 element, selector, <ir.Primitive>[value], sourceInformation); | 802 element, selector, <ir.Primitive>[value], sourceInformation); |
| 782 return value; | 803 return value; |
| 783 } | 804 } |
| 784 | 805 |
| 785 /// Create a constructor invocation of [element] on [type] where the | 806 /// Create a constructor invocation of [element] on [type] where the |
| 786 /// constructor name and argument structure are defined by [selector] and the | 807 /// constructor name and argument structure are defined by [selector] and the |
| 787 /// argument values are defined by [arguments]. | 808 /// argument values are defined by [arguments]. |
| 788 ir.Primitive buildConstructorInvocation(FunctionElement element, | 809 ir.Primitive buildConstructorInvocation(FunctionElement element, |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 } | 1164 } |
| 1144 | 1165 |
| 1145 ir.Parameter currentValue = new ir.Parameter(null); | 1166 ir.Parameter currentValue = new ir.Parameter(null); |
| 1146 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); | 1167 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); |
| 1147 bodyBuilder.add(new ir.LetCont(currentInvoked, | 1168 bodyBuilder.add(new ir.LetCont(currentInvoked, |
| 1148 new ir.InvokeMethod(iterator, new Selector.getter("current", null), | 1169 new ir.InvokeMethod(iterator, new Selector.getter("current", null), |
| 1149 currentInvoked, emptyArguments))); | 1170 currentInvoked, emptyArguments))); |
| 1150 if (Elements.isLocal(variableElement)) { | 1171 if (Elements.isLocal(variableElement)) { |
| 1151 bodyBuilder.buildLocalSet(variableElement, currentValue); | 1172 bodyBuilder.buildLocalSet(variableElement, currentValue); |
| 1152 } else if (Elements.isStaticOrTopLevel(variableElement)) { | 1173 } else if (Elements.isStaticOrTopLevel(variableElement)) { |
| 1153 bodyBuilder.buildStaticSet( | 1174 bodyBuilder.buildStaticSet(variableElement, currentValue); |
| 1154 variableElement, variableSelector, currentValue); | |
| 1155 } else { | 1175 } else { |
| 1156 ir.Primitive receiver = bodyBuilder.buildThis(); | 1176 ir.Primitive receiver = bodyBuilder.buildThis(); |
| 1157 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); | 1177 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); |
| 1158 } | 1178 } |
| 1159 | 1179 |
| 1160 buildBody(bodyBuilder); | 1180 buildBody(bodyBuilder); |
| 1161 assert(state.breakCollectors.last == breakCollector); | 1181 assert(state.breakCollectors.last == breakCollector); |
| 1162 assert(state.continueCollectors.last == continueCollector); | 1182 assert(state.continueCollectors.last == continueCollector); |
| 1163 state.breakCollectors.removeLast(); | 1183 state.breakCollectors.removeLast(); |
| 1164 state.continueCollectors.removeLast(); | 1184 state.continueCollectors.removeLast(); |
| (...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 // TODO(johnniwinther): Support passing of [DartType] for the exception. | 2440 // TODO(johnniwinther): Support passing of [DartType] for the exception. |
| 2421 class CatchClauseInfo { | 2441 class CatchClauseInfo { |
| 2422 final LocalVariableElement exceptionVariable; | 2442 final LocalVariableElement exceptionVariable; |
| 2423 final LocalVariableElement stackTraceVariable; | 2443 final LocalVariableElement stackTraceVariable; |
| 2424 final SubbuildFunction buildCatchBlock; | 2444 final SubbuildFunction buildCatchBlock; |
| 2425 | 2445 |
| 2426 CatchClauseInfo({this.exceptionVariable, | 2446 CatchClauseInfo({this.exceptionVariable, |
| 2427 this.stackTraceVariable, | 2447 this.stackTraceVariable, |
| 2428 this.buildCatchBlock}); | 2448 this.buildCatchBlock}); |
| 2429 } | 2449 } |
| OLD | NEW |