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