OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import 'dart:collection'; | 5 import 'dart:collection'; |
6 | 6 |
7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
8 | 8 |
9 import '../closure.dart'; | 9 import '../closure.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 super(backend.compiler); | 102 super(backend.compiler); |
103 | 103 |
104 DiagnosticReporter get reporter => compiler.reporter; | 104 DiagnosticReporter get reporter => compiler.reporter; |
105 | 105 |
106 HGraph build(CodegenWorkItem work) { | 106 HGraph build(CodegenWorkItem work) { |
107 return measure(() { | 107 return measure(() { |
108 Element element = work.element.implementation; | 108 Element element = work.element.implementation; |
109 return reporter.withCurrentElement(element, () { | 109 return reporter.withCurrentElement(element, () { |
110 SsaBuilder builder = new SsaBuilder( | 110 SsaBuilder builder = new SsaBuilder( |
111 work.element.implementation, | 111 work.element.implementation, |
112 work.resolutionTree, | 112 work.resolvedAst, |
113 work.compilationContext, | 113 work.compilationContext, |
114 work.registry, | 114 work.registry, |
115 backend, | 115 backend, |
116 emitter.nativeEmitter, | 116 emitter.nativeEmitter, |
117 sourceInformationFactory); | 117 sourceInformationFactory); |
118 HGraph graph = builder.build(); | 118 HGraph graph = builder.build(); |
119 | 119 |
120 // Default arguments are handled elsewhere, but we must ensure | 120 // Default arguments are handled elsewhere, but we must ensure |
121 // that the default values are computed during codegen. | 121 // that the default values are computed during codegen. |
122 if (!identical(element.kind, ElementKind.FIELD)) { | 122 if (!identical(element.kind, ElementKind.FIELD)) { |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 updateLocal(boxedVariable, oldValue); | 319 updateLocal(boxedVariable, oldValue); |
320 } | 320 } |
321 updateLocal(boxElement, newBox); | 321 updateLocal(boxElement, newBox); |
322 } | 322 } |
323 | 323 |
324 /** | 324 /** |
325 * Documentation wanted -- johnniwinther | 325 * Documentation wanted -- johnniwinther |
326 * | 326 * |
327 * Invariant: [function] must be an implementation element. | 327 * Invariant: [function] must be an implementation element. |
328 */ | 328 */ |
329 void startFunction(Element element, ast.Node node) { | 329 void startFunction(AstElement element, ast.Node node) { |
330 assert(invariant(element, element.isImplementation)); | 330 assert(invariant(element, element.isImplementation)); |
331 Compiler compiler = builder.compiler; | 331 Compiler compiler = builder.compiler; |
332 closureData = compiler.closureToClassMapper | 332 closureData = compiler.closureToClassMapper |
333 .computeClosureToClassMapping(element, node, builder.elements); | 333 .computeClosureToClassMapping(element.resolvedAst); |
334 | 334 |
335 if (element is FunctionElement) { | 335 if (element is FunctionElement) { |
336 FunctionElement functionElement = element; | 336 FunctionElement functionElement = element; |
337 FunctionSignature params = functionElement.functionSignature; | 337 FunctionSignature params = functionElement.functionSignature; |
338 ClosureScope scopeData = closureData.capturingScopes[node]; | 338 ClosureScope scopeData = closureData.capturingScopes[node]; |
339 params.orderedForEachParameter((ParameterElement parameterElement) { | 339 params.orderedForEachParameter((ParameterElement parameterElement) { |
340 if (element.isGenerativeConstructorBody) { | 340 if (element.isGenerativeConstructorBody) { |
341 if (scopeData != null && | 341 if (scopeData != null && |
342 scopeData.isCapturedVariable(parameterElement)) { | 342 scopeData.isCapturedVariable(parameterElement)) { |
343 // The parameter will be a field in the box passed as the | 343 // The parameter will be a field in the box passed as the |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
998 BaseImplementationOfCompoundsMixin, | 998 BaseImplementationOfCompoundsMixin, |
999 BaseImplementationOfSetIfNullsMixin, | 999 BaseImplementationOfSetIfNullsMixin, |
1000 BaseImplementationOfSuperIndexSetIfNullMixin, | 1000 BaseImplementationOfSuperIndexSetIfNullMixin, |
1001 SemanticSendResolvedMixin, | 1001 SemanticSendResolvedMixin, |
1002 NewBulkMixin, | 1002 NewBulkMixin, |
1003 ErrorBulkMixin | 1003 ErrorBulkMixin |
1004 implements SemanticSendVisitor { | 1004 implements SemanticSendVisitor { |
1005 /// The element for which this SSA builder is being used. | 1005 /// The element for which this SSA builder is being used. |
1006 final Element target; | 1006 final Element target; |
1007 | 1007 |
1008 /// Reference to resolved elements in [target]'s AST. | 1008 ResolvedAst resolvedAst; |
1009 TreeElements elements; | |
1010 | 1009 |
1011 /// Used to report information about inlining (which occurs while building the | 1010 /// Used to report information about inlining (which occurs while building the |
1012 /// SSA graph), when dump-info is enabled. | 1011 /// SSA graph), when dump-info is enabled. |
1013 final InfoReporter infoReporter; | 1012 final InfoReporter infoReporter; |
1014 | 1013 |
1015 /// If not null, the builder will store in [context] data that is used later | 1014 /// If not null, the builder will store in [context] data that is used later |
1016 /// during the optimization phases. | 1015 /// during the optimization phases. |
1017 final JavaScriptItemCompilationContext context; | 1016 final JavaScriptItemCompilationContext context; |
1018 | 1017 |
1019 /// Registry used to enqueue work during codegen, may be null to avoid | 1018 /// Registry used to enqueue work during codegen, may be null to avoid |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 /// Returns `true` if the current element is an `async` function. | 1112 /// Returns `true` if the current element is an `async` function. |
1114 bool get isBuildingAsyncFunction { | 1113 bool get isBuildingAsyncFunction { |
1115 Element element = sourceElement; | 1114 Element element = sourceElement; |
1116 return (element is FunctionElement && | 1115 return (element is FunctionElement && |
1117 element.asyncMarker == AsyncMarker.ASYNC); | 1116 element.asyncMarker == AsyncMarker.ASYNC); |
1118 } | 1117 } |
1119 | 1118 |
1120 // TODO(sigmund): make most args optional | 1119 // TODO(sigmund): make most args optional |
1121 SsaBuilder( | 1120 SsaBuilder( |
1122 this.target, | 1121 this.target, |
1123 this.elements, | 1122 this.resolvedAst, |
1124 this.context, | 1123 this.context, |
1125 this.registry, | 1124 this.registry, |
1126 JavaScriptBackend backend, | 1125 JavaScriptBackend backend, |
1127 this.nativeEmitter, | 1126 this.nativeEmitter, |
1128 SourceInformationStrategy sourceInformationFactory) | 1127 SourceInformationStrategy sourceInformationFactory) |
1129 : this.compiler = backend.compiler, | 1128 : this.compiler = backend.compiler, |
1130 this.infoReporter = backend.compiler.dumpInfoTask, | 1129 this.infoReporter = backend.compiler.dumpInfoTask, |
1131 this.backend = backend, | 1130 this.backend = backend, |
1132 this.constantSystem = backend.constantSystem, | 1131 this.constantSystem = backend.constantSystem, |
1133 this.rti = backend.rti { | 1132 this.rti = backend.rti { |
1134 assert(target.isImplementation); | 1133 assert(target.isImplementation); |
1135 graph.element = target; | 1134 graph.element = target; |
1136 localsHandler = new LocalsHandler(this, target, null); | 1135 localsHandler = new LocalsHandler(this, target, null); |
1137 sourceElementStack.add(target); | 1136 sourceElementStack.add(target); |
1138 sourceInformationBuilder = | 1137 sourceInformationBuilder = |
1139 sourceInformationFactory.createBuilderForContext(target); | 1138 sourceInformationFactory.createBuilderForContext(target); |
1140 graph.sourceInformation = | 1139 graph.sourceInformation = |
1141 sourceInformationBuilder.buildVariableDeclaration(); | 1140 sourceInformationBuilder.buildVariableDeclaration(); |
1142 } | 1141 } |
1143 | 1142 |
1144 BackendHelpers get helpers => backend.helpers; | 1143 BackendHelpers get helpers => backend.helpers; |
1145 | 1144 |
1146 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 1145 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
1147 | 1146 |
1148 DiagnosticReporter get reporter => compiler.reporter; | 1147 DiagnosticReporter get reporter => compiler.reporter; |
1149 | 1148 |
1150 CoreClasses get coreClasses => compiler.coreClasses; | 1149 CoreClasses get coreClasses => compiler.coreClasses; |
1151 | 1150 |
| 1151 /// Reference to resolved elements in [target]'s AST. |
| 1152 TreeElements get elements => resolvedAst.elements; |
| 1153 |
1152 @override | 1154 @override |
1153 SemanticSendVisitor get sendVisitor => this; | 1155 SemanticSendVisitor get sendVisitor => this; |
1154 | 1156 |
1155 @override | 1157 @override |
1156 void visitNode(ast.Node node) { | 1158 void visitNode(ast.Node node) { |
1157 internalError(node, "Unhandled node: $node"); | 1159 internalError(node, "Unhandled node: $node"); |
1158 } | 1160 } |
1159 | 1161 |
1160 @override | 1162 @override |
1161 void apply(ast.Node node, [_]) { | 1163 void apply(ast.Node node, [_]) { |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1827 * When inlining a function, [:return:] statements are not emitted as | 1829 * When inlining a function, [:return:] statements are not emitted as |
1828 * [HReturn] instructions. Instead, the value of a synthetic element is | 1830 * [HReturn] instructions. Instead, the value of a synthetic element is |
1829 * updated in the [localsHandler]. This function creates such an element and | 1831 * updated in the [localsHandler]. This function creates such an element and |
1830 * stores it in the [returnLocal] field. | 1832 * stores it in the [returnLocal] field. |
1831 */ | 1833 */ |
1832 void setupStateForInlining( | 1834 void setupStateForInlining( |
1833 FunctionElement function, List<HInstruction> compiledArguments, | 1835 FunctionElement function, List<HInstruction> compiledArguments, |
1834 {InterfaceType instanceType}) { | 1836 {InterfaceType instanceType}) { |
1835 localsHandler = new LocalsHandler(this, function, instanceType); | 1837 localsHandler = new LocalsHandler(this, function, instanceType); |
1836 localsHandler.closureData = compiler.closureToClassMapper | 1838 localsHandler.closureData = compiler.closureToClassMapper |
1837 .computeClosureToClassMapping(function, function.node, elements); | 1839 .computeClosureToClassMapping(function.resolvedAst); |
1838 returnLocal = new SyntheticLocal("result", function); | 1840 returnLocal = new SyntheticLocal("result", function); |
1839 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler)); | 1841 localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler)); |
1840 | 1842 |
1841 inTryStatement = false; // TODO(lry): why? Document. | 1843 inTryStatement = false; // TODO(lry): why? Document. |
1842 | 1844 |
1843 int argumentIndex = 0; | 1845 int argumentIndex = 0; |
1844 if (function.isInstanceMember) { | 1846 if (function.isInstanceMember) { |
1845 localsHandler.updateLocal(localsHandler.closureData.thisLocal, | 1847 localsHandler.updateLocal(localsHandler.closureData.thisLocal, |
1846 compiledArguments[argumentIndex++]); | 1848 compiledArguments[argumentIndex++]); |
1847 } | 1849 } |
1848 | 1850 |
1849 FunctionSignature signature = function.functionSignature; | 1851 FunctionSignature signature = function.functionSignature; |
1850 signature.orderedForEachParameter((ParameterElement parameter) { | 1852 signature.orderedForEachParameter((ParameterElement parameter) { |
1851 HInstruction argument = compiledArguments[argumentIndex++]; | 1853 HInstruction argument = compiledArguments[argumentIndex++]; |
1852 localsHandler.updateLocal(parameter, argument); | 1854 localsHandler.updateLocal(parameter, argument); |
1853 }); | 1855 }); |
1854 | 1856 |
1855 ClassElement enclosing = function.enclosingClass; | 1857 ClassElement enclosing = function.enclosingClass; |
1856 if ((function.isConstructor || function.isGenerativeConstructorBody) && | 1858 if ((function.isConstructor || function.isGenerativeConstructorBody) && |
1857 backend.classNeedsRti(enclosing)) { | 1859 backend.classNeedsRti(enclosing)) { |
1858 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | 1860 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { |
1859 HInstruction argument = compiledArguments[argumentIndex++]; | 1861 HInstruction argument = compiledArguments[argumentIndex++]; |
1860 localsHandler.updateLocal( | 1862 localsHandler.updateLocal( |
1861 localsHandler.getTypeVariableAsLocal(typeVariable), argument); | 1863 localsHandler.getTypeVariableAsLocal(typeVariable), argument); |
1862 }); | 1864 }); |
1863 } | 1865 } |
1864 assert(argumentIndex == compiledArguments.length); | 1866 assert(argumentIndex == compiledArguments.length); |
1865 | 1867 |
1866 elements = function.resolvedAst.elements; | 1868 resolvedAst = function.resolvedAst; |
1867 assert(elements != null); | 1869 assert(resolvedAst != null); |
1868 returnType = signature.type.returnType; | 1870 returnType = signature.type.returnType; |
1869 stack = <HInstruction>[]; | 1871 stack = <HInstruction>[]; |
1870 | 1872 |
1871 insertTraceCall(function); | 1873 insertTraceCall(function); |
1872 insertCoverageCall(function); | 1874 insertCoverageCall(function); |
1873 } | 1875 } |
1874 | 1876 |
1875 void restoreState(AstInliningState state) { | 1877 void restoreState(AstInliningState state) { |
1876 localsHandler = state.oldLocalsHandler; | 1878 localsHandler = state.oldLocalsHandler; |
1877 returnLocal = state.oldReturnLocal; | 1879 returnLocal = state.oldReturnLocal; |
1878 inTryStatement = state.inTryStatement; | 1880 inTryStatement = state.inTryStatement; |
1879 elements = state.oldElements; | 1881 resolvedAst = state.oldResolvedAst; |
1880 returnType = state.oldReturnType; | 1882 returnType = state.oldReturnType; |
1881 assert(stack.isEmpty); | 1883 assert(stack.isEmpty); |
1882 stack = state.oldStack; | 1884 stack = state.oldStack; |
1883 } | 1885 } |
1884 | 1886 |
1885 /** | 1887 /** |
1886 * Run this builder on the body of the [function] to be inlined. | 1888 * Run this builder on the body of the [function] to be inlined. |
1887 */ | 1889 */ |
1888 void visitInlinedFunction(FunctionElement function) { | 1890 void visitInlinedFunction(FunctionElement function) { |
1889 potentiallyCheckInlinedParameterTypes(function); | 1891 potentiallyCheckInlinedParameterTypes(function); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 localsHandler.updateLocal(parameter, argument); | 2002 localsHandler.updateLocal(parameter, argument); |
2001 // Don't forget to update the field, if the parameter is of the | 2003 // Don't forget to update the field, if the parameter is of the |
2002 // form [:this.x:]. | 2004 // form [:this.x:]. |
2003 if (parameter.isInitializingFormal) { | 2005 if (parameter.isInitializingFormal) { |
2004 InitializingFormalElement fieldParameterElement = parameter; | 2006 InitializingFormalElement fieldParameterElement = parameter; |
2005 fieldValues[fieldParameterElement.fieldElement] = argument; | 2007 fieldValues[fieldParameterElement.fieldElement] = argument; |
2006 } | 2008 } |
2007 }); | 2009 }); |
2008 | 2010 |
2009 // Build the initializers in the context of the new constructor. | 2011 // Build the initializers in the context of the new constructor. |
2010 TreeElements oldElements = elements; | 2012 ResolvedAst oldResolvedAst = resolvedAst; |
2011 ResolvedAst resolvedAst = callee.resolvedAst; | 2013 resolvedAst = callee.resolvedAst; |
2012 elements = resolvedAst.elements; | |
2013 ClosureClassMap oldClosureData = localsHandler.closureData; | 2014 ClosureClassMap oldClosureData = localsHandler.closureData; |
2014 ast.Node node = resolvedAst.node; | |
2015 ClosureClassMap newClosureData = compiler.closureToClassMapper | 2015 ClosureClassMap newClosureData = compiler.closureToClassMapper |
2016 .computeClosureToClassMapping(callee, node, elements); | 2016 .computeClosureToClassMapping(resolvedAst); |
2017 localsHandler.closureData = newClosureData; | 2017 localsHandler.closureData = newClosureData; |
2018 localsHandler.enterScope(node, callee); | 2018 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 2019 localsHandler.enterScope(resolvedAst.node, callee); |
| 2020 } |
2019 buildInitializers(callee, constructors, fieldValues); | 2021 buildInitializers(callee, constructors, fieldValues); |
2020 localsHandler.closureData = oldClosureData; | 2022 localsHandler.closureData = oldClosureData; |
2021 elements = oldElements; | 2023 resolvedAst = oldResolvedAst; |
2022 }); | 2024 }); |
2023 } | 2025 } |
2024 | 2026 |
| 2027 void buildInitializers( |
| 2028 ConstructorElement constructor, |
| 2029 List<FunctionElement> constructors, |
| 2030 Map<Element, HInstruction> fieldValues) { |
| 2031 assert(invariant( |
| 2032 constructor, resolvedAst.element == constructor.declaration, |
| 2033 message: "Expected ResolvedAst for $constructor, found $resolvedAst")); |
| 2034 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 2035 buildParsedInitializers(constructor, constructors, fieldValues); |
| 2036 } else { |
| 2037 buildSynthesizedConstructorInitializers( |
| 2038 constructor, constructors, fieldValues); |
| 2039 } |
| 2040 } |
| 2041 |
| 2042 void buildSynthesizedConstructorInitializers( |
| 2043 ConstructorElement constructor, |
| 2044 List<FunctionElement> constructors, |
| 2045 Map<Element, HInstruction> fieldValues) { |
| 2046 assert(invariant(constructor, constructor.isSynthesized)); |
| 2047 List<HInstruction> arguments = <HInstruction>[]; |
| 2048 HInstruction compileArgument(ParameterElement parameter) { |
| 2049 return localsHandler.readLocal(parameter); |
| 2050 } |
| 2051 |
| 2052 Element target = constructor.definingConstructor.implementation; |
| 2053 bool match = !target.isMalformed && |
| 2054 CallStructure.addForwardingElementArgumentsToList( |
| 2055 constructor, |
| 2056 arguments, |
| 2057 target, |
| 2058 compileArgument, |
| 2059 handleConstantForOptionalParameter); |
| 2060 if (!match) { |
| 2061 if (compiler.elementHasCompileTimeError(constructor)) { |
| 2062 return; |
| 2063 } |
| 2064 // If this fails, the selector we constructed for the call to a |
| 2065 // forwarding constructor in a mixin application did not match the |
| 2066 // constructor (which, for example, may happen when the libraries are |
| 2067 // not compatible for private names, see issue 20394). |
| 2068 reporter.internalError( |
| 2069 constructor, 'forwarding constructor call does not match'); |
| 2070 } |
| 2071 inlineSuperOrRedirect( |
| 2072 target, arguments, constructors, fieldValues, constructor); |
| 2073 } |
| 2074 |
2025 /** | 2075 /** |
2026 * Run through the initializers and inline all field initializers. Recursively | 2076 * Run through the initializers and inline all field initializers. Recursively |
2027 * inlines super initializers. | 2077 * inlines super initializers. |
2028 * | 2078 * |
2029 * The constructors of the inlined initializers is added to [constructors] | 2079 * The constructors of the inlined initializers is added to [constructors] |
2030 * with sub constructors having a lower index than super constructors. | 2080 * with sub constructors having a lower index than super constructors. |
2031 * | 2081 * |
2032 * Invariant: The [constructor] and elements in [constructors] must all be | 2082 * Invariant: The [constructor] and elements in [constructors] must all be |
2033 * implementation elements. | 2083 * implementation elements. |
2034 */ | 2084 */ |
2035 void buildInitializers( | 2085 void buildParsedInitializers( |
2036 ConstructorElement constructor, | 2086 ConstructorElement constructor, |
2037 List<FunctionElement> constructors, | 2087 List<FunctionElement> constructors, |
2038 Map<Element, HInstruction> fieldValues) { | 2088 Map<Element, HInstruction> fieldValues) { |
2039 assert(invariant(constructor, constructor.isImplementation)); | 2089 assert(invariant(constructor, constructor.isImplementation)); |
2040 if (constructor.isSynthesized) { | 2090 assert(invariant(constructor, !constructor.isSynthesized, |
2041 List<HInstruction> arguments = <HInstruction>[]; | 2091 message: "Unexpected synthesized constructor: $constructor")); |
2042 HInstruction compileArgument(ParameterElement parameter) { | |
2043 return localsHandler.readLocal(parameter); | |
2044 } | |
2045 | |
2046 Element target = constructor.definingConstructor.implementation; | |
2047 bool match = !target.isMalformed && | |
2048 CallStructure.addForwardingElementArgumentsToList( | |
2049 constructor, | |
2050 arguments, | |
2051 target, | |
2052 compileArgument, | |
2053 handleConstantForOptionalParameter); | |
2054 if (!match) { | |
2055 if (compiler.elementHasCompileTimeError(constructor)) { | |
2056 return; | |
2057 } | |
2058 // If this fails, the selector we constructed for the call to a | |
2059 // forwarding constructor in a mixin application did not match the | |
2060 // constructor (which, for example, may happen when the libraries are | |
2061 // not compatible for private names, see issue 20394). | |
2062 reporter.internalError( | |
2063 constructor, 'forwarding constructor call does not match'); | |
2064 } | |
2065 inlineSuperOrRedirect( | |
2066 target, arguments, constructors, fieldValues, constructor); | |
2067 return; | |
2068 } | |
2069 ast.FunctionExpression functionNode = constructor.node; | 2092 ast.FunctionExpression functionNode = constructor.node; |
2070 | 2093 |
2071 bool foundSuperOrRedirect = false; | 2094 bool foundSuperOrRedirect = false; |
2072 if (functionNode.initializers != null) { | 2095 if (functionNode.initializers != null) { |
2073 Link<ast.Node> initializers = functionNode.initializers.nodes; | 2096 Link<ast.Node> initializers = functionNode.initializers.nodes; |
2074 for (Link<ast.Node> link = initializers; | 2097 for (Link<ast.Node> link = initializers; |
2075 !link.isEmpty; | 2098 !link.isEmpty; |
2076 link = link.tail) { | 2099 link = link.tail) { |
2077 assert(link.head is ast.Send); | 2100 assert(link.head is ast.Send); |
2078 if (link.head is! ast.SendSet) { | 2101 if (link.head is! ast.SendSet) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 * | 2159 * |
2137 * Invariant: [classElement] must be an implementation element. | 2160 * Invariant: [classElement] must be an implementation element. |
2138 */ | 2161 */ |
2139 void buildFieldInitializers( | 2162 void buildFieldInitializers( |
2140 ClassElement classElement, Map<Element, HInstruction> fieldValues) { | 2163 ClassElement classElement, Map<Element, HInstruction> fieldValues) { |
2141 assert(invariant(classElement, classElement.isImplementation)); | 2164 assert(invariant(classElement, classElement.isImplementation)); |
2142 classElement.forEachInstanceField( | 2165 classElement.forEachInstanceField( |
2143 (ClassElement enclosingClass, VariableElement member) { | 2166 (ClassElement enclosingClass, VariableElement member) { |
2144 if (compiler.elementHasCompileTimeError(member)) return; | 2167 if (compiler.elementHasCompileTimeError(member)) return; |
2145 reporter.withCurrentElement(member, () { | 2168 reporter.withCurrentElement(member, () { |
2146 TreeElements definitions = member.treeElements; | |
2147 ast.Node node = member.node; | 2169 ast.Node node = member.node; |
2148 ast.Expression initializer = member.initializer; | 2170 ast.Expression initializer = member.initializer; |
2149 if (initializer == null) { | 2171 if (initializer == null) { |
2150 // Unassigned fields of native classes are not initialized to | 2172 // Unassigned fields of native classes are not initialized to |
2151 // prevent overwriting pre-initialized native properties. | 2173 // prevent overwriting pre-initialized native properties. |
2152 if (!backend.isNativeOrExtendsNative(classElement)) { | 2174 if (!backend.isNativeOrExtendsNative(classElement)) { |
2153 fieldValues[member] = graph.addConstantNull(compiler); | 2175 fieldValues[member] = graph.addConstantNull(compiler); |
2154 } | 2176 } |
2155 } else { | 2177 } else { |
2156 ast.Node right = initializer; | 2178 ast.Node right = initializer; |
2157 TreeElements savedElements = elements; | 2179 ResolvedAst savedResolvedAst = resolvedAst; |
2158 elements = definitions; | 2180 resolvedAst = member.resolvedAst; |
2159 // In case the field initializer uses closures, run the | 2181 // In case the field initializer uses closures, run the |
2160 // closure to class mapper. | 2182 // closure to class mapper. |
2161 compiler.closureToClassMapper | 2183 compiler.closureToClassMapper |
2162 .computeClosureToClassMapping(member, node, elements); | 2184 .computeClosureToClassMapping(resolvedAst); |
2163 inlinedFrom(member, () => right.accept(this)); | 2185 inlinedFrom(member, () => right.accept(this)); |
2164 elements = savedElements; | 2186 resolvedAst = savedResolvedAst; |
2165 fieldValues[member] = pop(); | 2187 fieldValues[member] = pop(); |
2166 } | 2188 } |
2167 }); | 2189 }); |
2168 }); | 2190 }); |
2169 } | 2191 } |
2170 | 2192 |
2171 /** | 2193 /** |
2172 * Build the factory function corresponding to the constructor | 2194 * Build the factory function corresponding to the constructor |
2173 * [functionElement]: | 2195 * [functionElement]: |
2174 * - Initialize fields with the values of the field initializers of the | 2196 * - Initialize fields with the values of the field initializers of the |
(...skipping 5694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7869 * This method is invoked before inlining the body of [function] into this | 7891 * This method is invoked before inlining the body of [function] into this |
7870 * [SsaBuilder]. | 7892 * [SsaBuilder]. |
7871 */ | 7893 */ |
7872 void enterInlinedMethod(FunctionElement function, ast.Node _, | 7894 void enterInlinedMethod(FunctionElement function, ast.Node _, |
7873 List<HInstruction> compiledArguments, | 7895 List<HInstruction> compiledArguments, |
7874 {InterfaceType instanceType}) { | 7896 {InterfaceType instanceType}) { |
7875 AstInliningState state = new AstInliningState( | 7897 AstInliningState state = new AstInliningState( |
7876 function, | 7898 function, |
7877 returnLocal, | 7899 returnLocal, |
7878 returnType, | 7900 returnType, |
7879 elements, | 7901 resolvedAst, |
7880 stack, | 7902 stack, |
7881 localsHandler, | 7903 localsHandler, |
7882 inTryStatement, | 7904 inTryStatement, |
7883 allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function)); | 7905 allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function)); |
7884 inliningStack.add(state); | 7906 inliningStack.add(state); |
7885 | 7907 |
7886 // Setting up the state of the (AST) builder is performed even when the | 7908 // Setting up the state of the (AST) builder is performed even when the |
7887 // inlined function is in IR, because the irInliner uses the [returnElement] | 7909 // inlined function is in IR, because the irInliner uses the [returnElement] |
7888 // of the AST builder. | 7910 // of the AST builder. |
7889 setupStateForInlining(function, compiledArguments, | 7911 setupStateForInlining(function, compiledArguments, |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8189 final FunctionElement function; | 8211 final FunctionElement function; |
8190 | 8212 |
8191 InliningState(this.function) { | 8213 InliningState(this.function) { |
8192 assert(function.isImplementation); | 8214 assert(function.isImplementation); |
8193 } | 8215 } |
8194 } | 8216 } |
8195 | 8217 |
8196 class AstInliningState extends InliningState { | 8218 class AstInliningState extends InliningState { |
8197 final Local oldReturnLocal; | 8219 final Local oldReturnLocal; |
8198 final DartType oldReturnType; | 8220 final DartType oldReturnType; |
8199 final TreeElements oldElements; | 8221 final ResolvedAst oldResolvedAst; |
8200 final List<HInstruction> oldStack; | 8222 final List<HInstruction> oldStack; |
8201 final LocalsHandler oldLocalsHandler; | 8223 final LocalsHandler oldLocalsHandler; |
8202 final bool inTryStatement; | 8224 final bool inTryStatement; |
8203 final bool allFunctionsCalledOnce; | 8225 final bool allFunctionsCalledOnce; |
8204 | 8226 |
8205 AstInliningState( | 8227 AstInliningState( |
8206 FunctionElement function, | 8228 FunctionElement function, |
8207 this.oldReturnLocal, | 8229 this.oldReturnLocal, |
8208 this.oldReturnType, | 8230 this.oldReturnType, |
8209 this.oldElements, | 8231 this.oldResolvedAst, |
8210 this.oldStack, | 8232 this.oldStack, |
8211 this.oldLocalsHandler, | 8233 this.oldLocalsHandler, |
8212 this.inTryStatement, | 8234 this.inTryStatement, |
8213 this.allFunctionsCalledOnce) | 8235 this.allFunctionsCalledOnce) |
8214 : super(function); | 8236 : super(function); |
8215 } | 8237 } |
8216 | 8238 |
8217 class SsaBranch { | 8239 class SsaBranch { |
8218 final SsaBranchBuilder branchBuilder; | 8240 final SsaBranchBuilder branchBuilder; |
8219 final HBasicBlock block; | 8241 final HBasicBlock block; |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8559 const _LoopTypeVisitor(); | 8581 const _LoopTypeVisitor(); |
8560 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 8582 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
8561 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 8583 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
8562 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 8584 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
8563 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 8585 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
8564 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8586 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
8565 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8587 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
8566 int visitSwitchStatement(ast.SwitchStatement node) => | 8588 int visitSwitchStatement(ast.SwitchStatement node) => |
8567 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 8589 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
8568 } | 8590 } |
OLD | NEW |