| 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'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../io/source_file.dart'; | 12 import '../io/source_file.dart'; |
| 13 import '../tree/tree.dart' as ast; | 13 import '../tree/tree.dart' as ast; |
| 14 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; | 14 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; |
| 15 import '../universe/universe.dart' show SelectorKind; | 15 import '../universe/universe.dart' show SelectorKind; |
| 16 import 'cps_ir_nodes.dart' as ir; | 16 import 'cps_ir_nodes.dart' as ir; |
| 17 import '../elements/modelx.dart' show SynthesizedConstructorElementX; | 17 import '../elements/modelx.dart' show SynthesizedConstructorElementX, |
| 18 ConstructorBodyElementX, FunctionSignatureX; |
| 18 import '../closure.dart'; | 19 import '../closure.dart'; |
| 19 import '../closure.dart' as closurelib; | 20 import '../closure.dart' as closurelib; |
| 20 import '../js_backend/js_backend.dart' show JavaScriptBackend; | 21 import '../js_backend/js_backend.dart' show JavaScriptBackend; |
| 21 | 22 |
| 22 part 'cps_ir_builder_visitor.dart'; | 23 part 'cps_ir_builder_visitor.dart'; |
| 23 | 24 |
| 24 /// A mapping from variable elements to their compile-time values. | 25 /// A mapping from variable elements to their compile-time values. |
| 25 /// | 26 /// |
| 26 /// Map elements denoted by parameters and local variables to the | 27 /// Map elements denoted by parameters and local variables to the |
| 27 /// [ir.Primitive] that is their value. Parameters and locals are | 28 /// [ir.Primitive] that is their value. Parameters and locals are |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 | 203 |
| 203 /// A factory for building the cps IR. | 204 /// A factory for building the cps IR. |
| 204 /// | 205 /// |
| 205 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured | 206 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured |
| 206 /// variables in different ways. | 207 /// variables in different ways. |
| 207 abstract class IrBuilder { | 208 abstract class IrBuilder { |
| 208 IrBuilder _makeInstance(); | 209 IrBuilder _makeInstance(); |
| 209 | 210 |
| 210 void declareLocalVariable(LocalVariableElement element, | 211 void declareLocalVariable(LocalVariableElement element, |
| 211 {ir.Primitive initialValue}); | 212 {ir.Primitive initialValue}); |
| 212 void declareLocalFunction(LocalFunctionElement element, Object function); | |
| 213 ir.Primitive buildFunctionExpression(Object function); | |
| 214 ir.Primitive buildLocalGet(LocalElement element); | 213 ir.Primitive buildLocalGet(LocalElement element); |
| 215 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); | 214 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); |
| 216 | 215 |
| 217 /// Called when entering a nested function with free variables. | 216 /// Called when entering a nested function with free variables. |
| 218 /// | 217 /// |
| 219 /// The free variables must subsequently be accessible using [buildLocalGet] | 218 /// The free variables must subsequently be accessible using [buildLocalGet] |
| 220 /// and [buildLocalSet]. | 219 /// and [buildLocalSet]. |
| 221 void _enterClosureEnvironment(ClosureEnvironment env); | 220 void _enterClosureEnvironment(ClosureEnvironment env); |
| 222 | 221 |
| 223 /// Called when entering a function body or loop body. | 222 /// Called when entering a function body or loop body. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 ..environment = new Environment.empty(); | 339 ..environment = new Environment.empty(); |
| 341 } | 340 } |
| 342 | 341 |
| 343 bool get isOpen => _root == null || _current != null; | 342 bool get isOpen => _root == null || _current != null; |
| 344 | 343 |
| 345 | 344 |
| 346 void buildFieldInitializerHeader({ClosureScope closureScope}) { | 345 void buildFieldInitializerHeader({ClosureScope closureScope}) { |
| 347 _enterScope(closureScope); | 346 _enterScope(closureScope); |
| 348 } | 347 } |
| 349 | 348 |
| 350 void buildFunctionHeader(Iterable<ParameterElement> parameters, | 349 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters, |
| 351 {ClosureScope closureScope, | 350 {ClosureScope closureScope, |
| 352 ClosureEnvironment closureEnvironment}) { | 351 ClosureEnvironment env}) { |
| 353 _enterClosureEnvironment(closureEnvironment); | 352 _enterClosureEnvironment(env); |
| 354 _enterScope(closureScope); | 353 _enterScope(closureScope); |
| 355 parameters.forEach(_createFunctionParameter); | 354 parameters.forEach(_createFunctionParameter); |
| 355 return _parameters; |
| 356 } | 356 } |
| 357 | 357 |
| 358 /// Creates a parameter for [local] and adds it to the current environment. | 358 /// Creates a parameter for [local] and adds it to the current environment. |
| 359 ir.Parameter createLocalParameter(Local local) { | 359 ir.Parameter createLocalParameter(Local local) { |
| 360 ir.Parameter parameter = new ir.Parameter(local); | 360 ir.Parameter parameter = new ir.Parameter(local); |
| 361 _parameters.add(parameter); | 361 _parameters.add(parameter); |
| 362 environment.extend(local, parameter); | 362 environment.extend(local, parameter); |
| 363 return parameter; | 363 return parameter; |
| 364 } | 364 } |
| 365 | 365 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 393 } | 393 } |
| 394 | 394 |
| 395 ir.Primitive _buildInvokeStatic(Element element, | 395 ir.Primitive _buildInvokeStatic(Element element, |
| 396 Selector selector, | 396 Selector selector, |
| 397 List<ir.Primitive> arguments) { | 397 List<ir.Primitive> arguments) { |
| 398 assert(isOpen); | 398 assert(isOpen); |
| 399 return _continueWithExpression( | 399 return _continueWithExpression( |
| 400 (k) => new ir.InvokeStatic(element, selector, k, arguments)); | 400 (k) => new ir.InvokeStatic(element, selector, k, arguments)); |
| 401 } | 401 } |
| 402 | 402 |
| 403 ir.Primitive _buildInvokeDirectly(Element target, | 403 ir.Primitive _buildInvokeSuper(Element target, |
| 404 Selector selector, | 404 Selector selector, |
| 405 List<ir.Primitive> arguments) { | 405 List<ir.Primitive> arguments) { |
| 406 assert(isOpen); | 406 assert(isOpen); |
| 407 return _continueWithExpression( | 407 return _continueWithExpression( |
| 408 (k) => new ir.InvokeMethodDirectly( | 408 (k) => new ir.InvokeMethodDirectly( |
| 409 buildThis(), target, selector, k, arguments)); | 409 buildThis(), target, selector, k, arguments)); |
| 410 } | 410 } |
| 411 | 411 |
| 412 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, | 412 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, |
| 413 Selector selector, | 413 Selector selector, |
| 414 List<ir.Primitive> arguments) { | 414 List<ir.Primitive> arguments) { |
| 415 assert(isOpen); | 415 assert(isOpen); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 /// argument are defined by [selector] and [value], respectively. | 642 /// argument are defined by [selector] and [value], respectively. |
| 643 void buildSuperSet(Element target, Selector selector, ir.Primitive value) { | 643 void buildSuperSet(Element target, Selector selector, ir.Primitive value) { |
| 644 buildSuperInvocation(target, selector, [value]); | 644 buildSuperInvocation(target, selector, [value]); |
| 645 } | 645 } |
| 646 | 646 |
| 647 /// Create an index set invocation on the super class with the provided | 647 /// Create an index set invocation on the super class with the provided |
| 648 /// [index] and [value]. | 648 /// [index] and [value]. |
| 649 ir.Primitive buildSuperIndexSet(Element target, | 649 ir.Primitive buildSuperIndexSet(Element target, |
| 650 ir.Primitive index, | 650 ir.Primitive index, |
| 651 ir.Primitive value) { | 651 ir.Primitive value) { |
| 652 _buildInvokeDirectly(target, new Selector.indexSet(), | 652 _buildInvokeSuper(target, new Selector.indexSet(), |
| 653 <ir.Primitive>[index, value]); | 653 <ir.Primitive>[index, value]); |
| 654 return value; | 654 return value; |
| 655 } | 655 } |
| 656 | 656 |
| 657 /// Create a dynamic invocation on [receiver] where the method name and | 657 /// Create a dynamic invocation on [receiver] where the method name and |
| 658 /// argument structure are defined by [selector] and the argument values are | 658 /// argument structure are defined by [selector] and the argument values are |
| 659 /// defined by [arguments]. | 659 /// defined by [arguments]. |
| 660 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, | 660 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, |
| 661 Selector selector, | 661 Selector selector, |
| 662 List<ir.Primitive> arguments) { | 662 List<ir.Primitive> arguments) { |
| (...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1721 | 1721 |
| 1722 ir.Primitive buildThis() { | 1722 ir.Primitive buildThis() { |
| 1723 ir.Primitive thisPrim = new ir.This(); | 1723 ir.Primitive thisPrim = new ir.This(); |
| 1724 add(new ir.LetPrim(thisPrim)); | 1724 add(new ir.LetPrim(thisPrim)); |
| 1725 return thisPrim; | 1725 return thisPrim; |
| 1726 } | 1726 } |
| 1727 | 1727 |
| 1728 ir.Primitive buildSuperInvocation(Element target, | 1728 ir.Primitive buildSuperInvocation(Element target, |
| 1729 Selector selector, | 1729 Selector selector, |
| 1730 List<ir.Primitive> arguments) { | 1730 List<ir.Primitive> arguments) { |
| 1731 return _buildInvokeDirectly(target, selector, arguments); | 1731 return _buildInvokeSuper(target, selector, arguments); |
| 1732 } | 1732 } |
| 1733 | 1733 |
| 1734 } | 1734 } |
| 1735 | 1735 |
| 1736 /// State shared between JsIrBuilders within the same function. | 1736 /// State shared between JsIrBuilders within the same function. |
| 1737 /// | 1737 /// |
| 1738 /// Note that this is not shared between builders of nested functions. | 1738 /// Note that this is not shared between builders of nested functions. |
| 1739 class JsIrBuilderSharedState { | 1739 class JsIrBuilderSharedState { |
| 1740 /// Maps boxed locals to their location. These locals are not part of | 1740 /// Maps boxed locals to their location. These locals are not part of |
| 1741 /// the environment. | 1741 /// the environment. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1843 ClosureClassElement classElement) { | 1843 ClosureClassElement classElement) { |
| 1844 ir.Primitive closure = buildFunctionExpression(classElement); | 1844 ir.Primitive closure = buildFunctionExpression(classElement); |
| 1845 declareLocalVariable(functionElement, initialValue: closure); | 1845 declareLocalVariable(functionElement, initialValue: closure); |
| 1846 } | 1846 } |
| 1847 | 1847 |
| 1848 ir.Primitive buildFunctionExpression(ClosureClassElement classElement) { | 1848 ir.Primitive buildFunctionExpression(ClosureClassElement classElement) { |
| 1849 List<ir.Primitive> arguments = <ir.Primitive>[]; | 1849 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 1850 for (ClosureFieldElement field in classElement.closureFields) { | 1850 for (ClosureFieldElement field in classElement.closureFields) { |
| 1851 arguments.add(environment.lookup(field.local)); | 1851 arguments.add(environment.lookup(field.local)); |
| 1852 } | 1852 } |
| 1853 ir.Primitive closure = new ir.CreateClosureClass(classElement, arguments); | 1853 ir.Primitive closure = new ir.CreateInstance(classElement, arguments); |
| 1854 add(new ir.LetPrim(closure)); | 1854 add(new ir.LetPrim(closure)); |
| 1855 return closure; | 1855 return closure; |
| 1856 } | 1856 } |
| 1857 | 1857 |
| 1858 /// Create a read access of [local]. | 1858 /// Create a read access of [local]. |
| 1859 ir.Primitive buildLocalGet(LocalElement local) { | 1859 ir.Primitive buildLocalGet(LocalElement local) { |
| 1860 assert(isOpen); | 1860 assert(isOpen); |
| 1861 ClosureLocation location = jsState.boxedVariables[local]; | 1861 ClosureLocation location = jsState.boxedVariables[local]; |
| 1862 if (location != null) { | 1862 if (location != null) { |
| 1863 ir.Primitive result = new ir.GetField(environment.lookup(location.box), | 1863 ir.Primitive result = new ir.GetField(environment.lookup(location.box), |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 if (selector.isGetter) { | 1946 if (selector.isGetter) { |
| 1947 ir.Primitive get = new ir.GetField(buildThis(), target); | 1947 ir.Primitive get = new ir.GetField(buildThis(), target); |
| 1948 add(new ir.LetPrim(get)); | 1948 add(new ir.LetPrim(get)); |
| 1949 return get; | 1949 return get; |
| 1950 } else { | 1950 } else { |
| 1951 assert(selector.isSetter); | 1951 assert(selector.isSetter); |
| 1952 add(new ir.SetField(buildThis(), target, arguments.single)); | 1952 add(new ir.SetField(buildThis(), target, arguments.single)); |
| 1953 return arguments.single; | 1953 return arguments.single; |
| 1954 } | 1954 } |
| 1955 } else { | 1955 } else { |
| 1956 return _buildInvokeDirectly(target, selector, arguments); | 1956 return _buildInvokeSuper(target, selector, arguments); |
| 1957 } |
| 1958 } |
| 1959 |
| 1960 ir.Primitive buildInvokeDirectly(FunctionElement target, |
| 1961 ir.Primitive receiver, |
| 1962 List<ir.Primitive> arguments) { |
| 1963 assert(isOpen); |
| 1964 Selector selector = |
| 1965 new Selector.call(target.name, target.library, arguments.length); |
| 1966 return _continueWithExpression( |
| 1967 (k) => new ir.InvokeMethodDirectly( |
| 1968 receiver, target, selector, k, arguments)); |
| 1969 } |
| 1970 |
| 1971 /// Loads parameters to a constructor body into the environment. |
| 1972 /// |
| 1973 /// The header for a constructor body differs from other functions in that |
| 1974 /// some parameters are already boxed, and the box is passed as an argument |
| 1975 /// instead of being created in the header. |
| 1976 void buildConstructorBodyHeader(Iterable<Local> parameters, |
| 1977 ClosureScope closureScope) { |
| 1978 for (Local param in parameters) { |
| 1979 ir.Parameter parameter = createLocalParameter(param); |
| 1980 state.functionParameters.add(parameter); |
| 1981 } |
| 1982 if (closureScope != null) { |
| 1983 jsState.boxedVariables.addAll(closureScope.capturedVariables); |
| 1957 } | 1984 } |
| 1958 } | 1985 } |
| 1959 } | 1986 } |
| 1960 | 1987 |
| 1961 | 1988 |
| 1962 /// Location of a variable relative to a given closure. | 1989 /// Location of a variable relative to a given closure. |
| 1963 class ClosureLocation { | 1990 class ClosureLocation { |
| 1964 /// If not `null`, this location is [box].[field]. | 1991 /// If not `null`, this location is [box].[field]. |
| 1965 /// The location of [box] can be obtained separately from an | 1992 /// The location of [box] can be obtained separately from an |
| 1966 /// enclosing [ClosureEnvironment] or [ClosureScope]. | 1993 /// enclosing [ClosureEnvironment] or [ClosureScope]. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2038 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2012 } | 2039 } |
| 2013 | 2040 |
| 2014 /// Information about which variables are captured in a closure. | 2041 /// Information about which variables are captured in a closure. |
| 2015 /// | 2042 /// |
| 2016 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and | 2043 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and |
| 2017 /// [ClosureEnvironment]. | 2044 /// [ClosureEnvironment]. |
| 2018 abstract class ClosureVariableInfo { | 2045 abstract class ClosureVariableInfo { |
| 2019 Iterable<Local> get capturedVariables; | 2046 Iterable<Local> get capturedVariables; |
| 2020 } | 2047 } |
| OLD | NEW |