Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder.dart

Issue 1927963002: Support compilation of Hello World (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fixes Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 compiler.options.trustTypeAnnotations; 1175 compiler.options.trustTypeAnnotations;
1176 1176
1177 /// Build the graph for [target]. 1177 /// Build the graph for [target].
1178 HGraph build() { 1178 HGraph build() {
1179 assert(invariant(target, target.isImplementation)); 1179 assert(invariant(target, target.isImplementation));
1180 HInstruction.idCounter = 0; 1180 HInstruction.idCounter = 0;
1181 // TODO(sigmund): remove `result` and return graph directly, need to ensure 1181 // TODO(sigmund): remove `result` and return graph directly, need to ensure
1182 // that it can never be null (see result in buildFactory for instance). 1182 // that it can never be null (see result in buildFactory for instance).
1183 var result; 1183 var result;
1184 if (target.isGenerativeConstructor) { 1184 if (target.isGenerativeConstructor) {
1185 result = buildFactory(target); 1185 result = buildFactory(resolvedAst);
1186 } else if (target.isGenerativeConstructorBody || 1186 } else if (target.isGenerativeConstructorBody ||
1187 target.isFactoryConstructor || 1187 target.isFactoryConstructor ||
1188 target.isFunction || 1188 target.isFunction ||
1189 target.isGetter || 1189 target.isGetter ||
1190 target.isSetter) { 1190 target.isSetter) {
1191 result = buildMethod(target); 1191 result = buildMethod(target);
1192 } else if (target.isField) { 1192 } else if (target.isField) {
1193 if (target.isInstanceMember) { 1193 if (target.isInstanceMember) {
1194 assert(compiler.options.enableTypeAssertions); 1194 assert(compiler.options.enableTypeAssertions);
1195 result = buildCheckedSetter(target); 1195 result = buildCheckedSetter(target);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 currentNode); 1532 currentNode);
1533 } 1533 }
1534 List<HInstruction> compiledArguments = completeSendArgumentsList( 1534 List<HInstruction> compiledArguments = completeSendArgumentsList(
1535 function, selector, providedArguments, currentNode); 1535 function, selector, providedArguments, currentNode);
1536 enterInlinedMethod(function, functionResolvedAst, compiledArguments, 1536 enterInlinedMethod(function, functionResolvedAst, compiledArguments,
1537 instanceType: instanceType); 1537 instanceType: instanceType);
1538 inlinedFrom(function, () { 1538 inlinedFrom(function, () {
1539 if (!isReachable) { 1539 if (!isReachable) {
1540 emitReturn(graph.addConstantNull(compiler), null); 1540 emitReturn(graph.addConstantNull(compiler), null);
1541 } else { 1541 } else {
1542 doInline(function); 1542 doInline(functionResolvedAst);
1543 } 1543 }
1544 }); 1544 });
1545 leaveInlinedMethod(); 1545 leaveInlinedMethod();
1546 } 1546 }
1547 1547
1548 if (meetsHardConstraints() && heuristicSayGoodToGo()) { 1548 if (meetsHardConstraints() && heuristicSayGoodToGo()) {
1549 doInlining(); 1549 doInlining();
1550 infoReporter?.reportInlined(element, 1550 infoReporter?.reportInlined(element,
1551 inliningStack.isEmpty ? target : inliningStack.last.function); 1551 inliningStack.isEmpty ? target : inliningStack.last.function);
1552 return true; 1552 return true;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator))); 1766 sourceInformationBuilder.buildReturn(sendSet.assignmentOperator)));
1767 return closeFunction(); 1767 return closeFunction();
1768 } 1768 }
1769 1769
1770 /** 1770 /**
1771 * Returns the constructor body associated with the given constructor or 1771 * Returns the constructor body associated with the given constructor or
1772 * creates a new constructor body, if none can be found. 1772 * creates a new constructor body, if none can be found.
1773 * 1773 *
1774 * Returns [:null:] if the constructor does not have a body. 1774 * Returns [:null:] if the constructor does not have a body.
1775 */ 1775 */
1776 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { 1776 ConstructorBodyElement getConstructorBody(
1777 ResolvedAst constructorResolvedAst) {
1778 ConstructorElement constructor =
1779 constructorResolvedAst.element.implementation;
1777 assert(constructor.isGenerativeConstructor); 1780 assert(constructor.isGenerativeConstructor);
1778 assert(invariant(constructor, constructor.isImplementation)); 1781 if (constructorResolvedAst.kind != ResolvedAstKind.PARSED) return null;
1779 if (constructor.isSynthesized) return null; 1782
1780 ast.FunctionExpression node = constructor.node; 1783 ast.FunctionExpression node = constructorResolvedAst.node;
1781 // If we know the body doesn't have any code, we don't generate it. 1784 // If we know the body doesn't have any code, we don't generate it.
1782 if (!node.hasBody) return null; 1785 if (!node.hasBody) return null;
1783 if (node.hasEmptyBody) return null; 1786 if (node.hasEmptyBody) return null;
1784 ClassElement classElement = constructor.enclosingClass; 1787 ClassElement classElement = constructor.enclosingClass;
1785 ConstructorBodyElement bodyElement; 1788 ConstructorBodyElement bodyElement;
1786 classElement.forEachBackendMember((Element backendMember) { 1789 classElement.forEachBackendMember((Element backendMember) {
1787 if (backendMember.isGenerativeConstructorBody) { 1790 if (backendMember.isGenerativeConstructorBody) {
1788 ConstructorBodyElement body = backendMember; 1791 ConstructorBodyElement body = backendMember;
1789 if (body.constructor == constructor) { 1792 if (body.constructor == constructor) {
1790 // TODO(kasperl): Find a way of stopping the iteration 1793 // TODO(kasperl): Find a way of stopping the iteration
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 inTryStatement = state.inTryStatement; 1884 inTryStatement = state.inTryStatement;
1882 resolvedAst = state.oldResolvedAst; 1885 resolvedAst = state.oldResolvedAst;
1883 returnType = state.oldReturnType; 1886 returnType = state.oldReturnType;
1884 assert(stack.isEmpty); 1887 assert(stack.isEmpty);
1885 stack = state.oldStack; 1888 stack = state.oldStack;
1886 } 1889 }
1887 1890
1888 /** 1891 /**
1889 * Run this builder on the body of the [function] to be inlined. 1892 * Run this builder on the body of the [function] to be inlined.
1890 */ 1893 */
1891 void visitInlinedFunction(FunctionElement function) { 1894 void visitInlinedFunction(ResolvedAst resolvedAst) {
1892 potentiallyCheckInlinedParameterTypes(function); 1895 potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation);
1893 1896
1894 if (function.isGenerativeConstructor) { 1897 if (resolvedAst.element.isGenerativeConstructor) {
1895 buildFactory(function); 1898 buildFactory(resolvedAst);
1896 } else { 1899 } else {
1897 ast.FunctionExpression functionNode = function.node; 1900 ast.FunctionExpression functionNode = resolvedAst.node;
1898 functionNode.body.accept(this); 1901 functionNode.body.accept(this);
1899 } 1902 }
1900 } 1903 }
1901 1904
1902 addInlinedInstantiation(DartType type) { 1905 addInlinedInstantiation(DartType type) {
1903 if (type != null) { 1906 if (type != null) {
1904 currentInlinedInstantiations.add(type); 1907 currentInlinedInstantiations.add(type);
1905 } 1908 }
1906 } 1909 }
1907 1910
(...skipping 26 matching lines...) Expand all
1934 potentiallyCheckOrTrustType(argument, parameter.type); 1937 potentiallyCheckOrTrustType(argument, parameter.type);
1935 }); 1938 });
1936 } 1939 }
1937 1940
1938 /** 1941 /**
1939 * Documentation wanted -- johnniwinther 1942 * Documentation wanted -- johnniwinther
1940 * 1943 *
1941 * Invariant: [constructors] must contain only implementation elements. 1944 * Invariant: [constructors] must contain only implementation elements.
1942 */ 1945 */
1943 void inlineSuperOrRedirect( 1946 void inlineSuperOrRedirect(
1944 ConstructorElement callee, 1947 ResolvedAst constructorRecolvedAst,
1945 List<HInstruction> compiledArguments, 1948 List<HInstruction> compiledArguments,
1946 List<FunctionElement> constructors, 1949 List<ResolvedAst> constructorResolvedAsts,
1947 Map<Element, HInstruction> fieldValues, 1950 Map<Element, HInstruction> fieldValues,
1948 FunctionElement caller) { 1951 FunctionElement caller) {
1949 callee = callee.implementation; 1952 ConstructorElement callee = constructorRecolvedAst.element.implementation;
1950 reporter.withCurrentElement(callee, () { 1953 reporter.withCurrentElement(callee, () {
1951 constructors.add(callee); 1954 constructorResolvedAsts.add(constructorRecolvedAst);
1952 ClassElement enclosingClass = callee.enclosingClass; 1955 ClassElement enclosingClass = callee.enclosingClass;
1953 if (backend.classNeedsRti(enclosingClass)) { 1956 if (backend.classNeedsRti(enclosingClass)) {
1954 // If [enclosingClass] needs RTI, we have to give a value to its 1957 // If [enclosingClass] needs RTI, we have to give a value to its
1955 // type parameters. 1958 // type parameters.
1956 ClassElement currentClass = caller.enclosingClass; 1959 ClassElement currentClass = caller.enclosingClass;
1957 // For a super constructor call, the type is the supertype of 1960 // For a super constructor call, the type is the supertype of
1958 // [currentClass]. For a redirecting constructor, the type is 1961 // [currentClass]. For a redirecting constructor, the type is
1959 // the current type. [InterfaceType.asInstanceOf] takes care 1962 // the current type. [InterfaceType.asInstanceOf] takes care
1960 // of both. 1963 // of both.
1961 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass); 1964 InterfaceType type = currentClass.thisType.asInstanceOf(enclosingClass);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 // Build the initializers in the context of the new constructor. 2015 // Build the initializers in the context of the new constructor.
2013 ResolvedAst oldResolvedAst = resolvedAst; 2016 ResolvedAst oldResolvedAst = resolvedAst;
2014 resolvedAst = backend.frontend.getResolvedAst(callee); 2017 resolvedAst = backend.frontend.getResolvedAst(callee);
2015 ClosureClassMap oldClosureData = localsHandler.closureData; 2018 ClosureClassMap oldClosureData = localsHandler.closureData;
2016 ClosureClassMap newClosureData = compiler.closureToClassMapper 2019 ClosureClassMap newClosureData = compiler.closureToClassMapper
2017 .computeClosureToClassMapping(resolvedAst); 2020 .computeClosureToClassMapping(resolvedAst);
2018 localsHandler.closureData = newClosureData; 2021 localsHandler.closureData = newClosureData;
2019 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 2022 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
2020 localsHandler.enterScope(resolvedAst.node, callee); 2023 localsHandler.enterScope(resolvedAst.node, callee);
2021 } 2024 }
2022 buildInitializers(callee, constructors, fieldValues); 2025 buildInitializers(callee, constructorResolvedAsts, fieldValues);
2023 localsHandler.closureData = oldClosureData; 2026 localsHandler.closureData = oldClosureData;
2024 resolvedAst = oldResolvedAst; 2027 resolvedAst = oldResolvedAst;
2025 }); 2028 });
2026 } 2029 }
2027 2030
2028 void buildInitializers( 2031 void buildInitializers(
2029 ConstructorElement constructor, 2032 ConstructorElement constructor,
2030 List<FunctionElement> constructors, 2033 List<ResolvedAst> constructorResolvedAsts,
2031 Map<Element, HInstruction> fieldValues) { 2034 Map<Element, HInstruction> fieldValues) {
2032 assert(invariant( 2035 assert(invariant(
2033 constructor, resolvedAst.element == constructor.declaration, 2036 constructor, resolvedAst.element == constructor.declaration,
2034 message: "Expected ResolvedAst for $constructor, found $resolvedAst")); 2037 message: "Expected ResolvedAst for $constructor, found $resolvedAst"));
2035 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 2038 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
2036 buildParsedInitializers(constructor, constructors, fieldValues); 2039 buildParsedInitializers(
2040 constructor, constructorResolvedAsts, fieldValues);
2037 } else { 2041 } else {
2038 buildSynthesizedConstructorInitializers( 2042 buildSynthesizedConstructorInitializers(
2039 constructor, constructors, fieldValues); 2043 constructor, constructorResolvedAsts, fieldValues);
2040 } 2044 }
2041 } 2045 }
2042 2046
2043 void buildSynthesizedConstructorInitializers( 2047 void buildSynthesizedConstructorInitializers(
2044 ConstructorElement constructor, 2048 ConstructorElement constructor,
2045 List<FunctionElement> constructors, 2049 List<ResolvedAst> constructorResolvedAsts,
2046 Map<Element, HInstruction> fieldValues) { 2050 Map<Element, HInstruction> fieldValues) {
2047 assert(invariant(constructor, constructor.isSynthesized)); 2051 assert(invariant(constructor, constructor.isSynthesized,
2052 message: "Unexpected unsynthesized constructor: $constructor"));
2048 List<HInstruction> arguments = <HInstruction>[]; 2053 List<HInstruction> arguments = <HInstruction>[];
2049 HInstruction compileArgument(ParameterElement parameter) { 2054 HInstruction compileArgument(ParameterElement parameter) {
2050 return localsHandler.readLocal(parameter); 2055 return localsHandler.readLocal(parameter);
2051 } 2056 }
2052 2057
2053 Element target = constructor.definingConstructor.implementation; 2058 Element target = constructor.definingConstructor.implementation;
2054 bool match = !target.isMalformed && 2059 bool match = !target.isMalformed &&
2055 CallStructure.addForwardingElementArgumentsToList( 2060 CallStructure.addForwardingElementArgumentsToList(
2056 constructor, 2061 constructor,
2057 arguments, 2062 arguments,
2058 target, 2063 target,
2059 compileArgument, 2064 compileArgument,
2060 handleConstantForOptionalParameter); 2065 handleConstantForOptionalParameter);
2061 if (!match) { 2066 if (!match) {
2062 if (compiler.elementHasCompileTimeError(constructor)) { 2067 if (compiler.elementHasCompileTimeError(constructor)) {
2063 return; 2068 return;
2064 } 2069 }
2065 // If this fails, the selector we constructed for the call to a 2070 // If this fails, the selector we constructed for the call to a
2066 // forwarding constructor in a mixin application did not match the 2071 // forwarding constructor in a mixin application did not match the
2067 // constructor (which, for example, may happen when the libraries are 2072 // constructor (which, for example, may happen when the libraries are
2068 // not compatible for private names, see issue 20394). 2073 // not compatible for private names, see issue 20394).
2069 reporter.internalError( 2074 reporter.internalError(
2070 constructor, 'forwarding constructor call does not match'); 2075 constructor, 'forwarding constructor call does not match');
2071 } 2076 }
2072 inlineSuperOrRedirect( 2077 inlineSuperOrRedirect(backend.frontend.getResolvedAst(target), arguments,
2073 target, arguments, constructors, fieldValues, constructor); 2078 constructorResolvedAsts, fieldValues, constructor);
2074 } 2079 }
2075 2080
2076 /** 2081 /**
2077 * Run through the initializers and inline all field initializers. Recursively 2082 * Run through the initializers and inline all field initializers. Recursively
2078 * inlines super initializers. 2083 * inlines super initializers.
2079 * 2084 *
2080 * The constructors of the inlined initializers is added to [constructors] 2085 * The constructors of the inlined initializers is added to [constructors]
2081 * with sub constructors having a lower index than super constructors. 2086 * with sub constructors having a lower index than super constructors.
2082 * 2087 *
2083 * Invariant: The [constructor] and elements in [constructors] must all be 2088 * Invariant: The [constructor] and elements in [constructors] must all be
2084 * implementation elements. 2089 * implementation elements.
2085 */ 2090 */
2086 void buildParsedInitializers( 2091 void buildParsedInitializers(
2087 ConstructorElement constructor, 2092 ConstructorElement constructor,
2088 List<FunctionElement> constructors, 2093 List<ResolvedAst> constructorResolvedAsts,
2089 Map<Element, HInstruction> fieldValues) { 2094 Map<Element, HInstruction> fieldValues) {
2095 assert(
2096 invariant(constructor, resolvedAst.element == constructor.declaration));
2090 assert(invariant(constructor, constructor.isImplementation)); 2097 assert(invariant(constructor, constructor.isImplementation));
2091 assert(invariant(constructor, !constructor.isSynthesized, 2098 assert(invariant(constructor, !constructor.isSynthesized,
2092 message: "Unexpected synthesized constructor: $constructor")); 2099 message: "Unexpected synthesized constructor: $constructor"));
2093 ast.FunctionExpression functionNode = constructor.node; 2100 ast.FunctionExpression functionNode = resolvedAst.node;
2094 2101
2095 bool foundSuperOrRedirect = false; 2102 bool foundSuperOrRedirect = false;
2096 if (functionNode.initializers != null) { 2103 if (functionNode.initializers != null) {
2097 Link<ast.Node> initializers = functionNode.initializers.nodes; 2104 Link<ast.Node> initializers = functionNode.initializers.nodes;
2098 for (Link<ast.Node> link = initializers; 2105 for (Link<ast.Node> link = initializers;
2099 !link.isEmpty; 2106 !link.isEmpty;
2100 link = link.tail) { 2107 link = link.tail) {
2101 assert(link.head is ast.Send); 2108 assert(link.head is ast.Send);
2102 if (link.head is! ast.SendSet) { 2109 if (link.head is! ast.SendSet) {
2103 // A super initializer or constructor redirection. 2110 // A super initializer or constructor redirection.
2104 foundSuperOrRedirect = true; 2111 foundSuperOrRedirect = true;
2105 ast.Send call = link.head; 2112 ast.Send call = link.head;
2106 assert(ast.Initializers.isSuperConstructorCall(call) || 2113 assert(ast.Initializers.isSuperConstructorCall(call) ||
2107 ast.Initializers.isConstructorRedirect(call)); 2114 ast.Initializers.isConstructorRedirect(call));
2108 FunctionElement target = elements[call].implementation; 2115 FunctionElement target = elements[call].implementation;
2109 CallStructure callStructure = 2116 CallStructure callStructure =
2110 elements.getSelector(call).callStructure; 2117 elements.getSelector(call).callStructure;
2111 Link<ast.Node> arguments = call.arguments; 2118 Link<ast.Node> arguments = call.arguments;
2112 List<HInstruction> compiledArguments; 2119 List<HInstruction> compiledArguments;
2113 inlinedFrom(constructor, () { 2120 inlinedFrom(constructor, () {
2114 compiledArguments = 2121 compiledArguments =
2115 makeStaticArgumentList(callStructure, arguments, target); 2122 makeStaticArgumentList(callStructure, arguments, target);
2116 }); 2123 });
2117 inlineSuperOrRedirect(target, compiledArguments, constructors, 2124 inlineSuperOrRedirect(
2118 fieldValues, constructor); 2125 backend.frontend.getResolvedAst(target.declaration),
2126 compiledArguments,
2127 constructorResolvedAsts,
2128 fieldValues,
2129 constructor);
2119 } else { 2130 } else {
2120 // A field initializer. 2131 // A field initializer.
2121 ast.SendSet init = link.head; 2132 ast.SendSet init = link.head;
2122 Link<ast.Node> arguments = init.arguments; 2133 Link<ast.Node> arguments = init.arguments;
2123 assert(!arguments.isEmpty && arguments.tail.isEmpty); 2134 assert(!arguments.isEmpty && arguments.tail.isEmpty);
2124 inlinedFrom(constructor, () { 2135 inlinedFrom(constructor, () {
2125 visit(arguments.head); 2136 visit(arguments.head);
2126 }); 2137 });
2127 fieldValues[elements[init]] = pop(); 2138 fieldValues[elements[init]] = pop();
2128 } 2139 }
(...skipping 13 matching lines...) Expand all
2142 if (target == null) { 2153 if (target == null) {
2143 reporter.internalError( 2154 reporter.internalError(
2144 superClass, "No default constructor available."); 2155 superClass, "No default constructor available.");
2145 } 2156 }
2146 List<HInstruction> arguments = CallStructure.NO_ARGS.makeArgumentsList( 2157 List<HInstruction> arguments = CallStructure.NO_ARGS.makeArgumentsList(
2147 const Link<ast.Node>(), 2158 const Link<ast.Node>(),
2148 target.implementation, 2159 target.implementation,
2149 null, 2160 null,
2150 handleConstantForOptionalParameter); 2161 handleConstantForOptionalParameter);
2151 inlineSuperOrRedirect( 2162 inlineSuperOrRedirect(
2152 target, arguments, constructors, fieldValues, constructor); 2163 backend.frontend.getResolvedAst(target.declaration),
2164 arguments,
2165 constructorResolvedAsts,
2166 fieldValues,
2167 constructor);
2153 } 2168 }
2154 } 2169 }
2155 } 2170 }
2156 2171
2157 /** 2172 /**
2158 * Run through the fields of [cls] and add their potential 2173 * Run through the fields of [cls] and add their potential
2159 * initializers. 2174 * initializers.
2160 * 2175 *
2161 * Invariant: [classElement] must be an implementation element. 2176 * Invariant: [classElement] must be an implementation element.
2162 */ 2177 */
2163 void buildFieldInitializers( 2178 void buildFieldInitializers(
2164 ClassElement classElement, Map<Element, HInstruction> fieldValues) { 2179 ClassElement classElement, Map<Element, HInstruction> fieldValues) {
2165 assert(invariant(classElement, classElement.isImplementation)); 2180 assert(invariant(classElement, classElement.isImplementation));
2166 classElement.forEachInstanceField( 2181 classElement.forEachInstanceField(
2167 (ClassElement enclosingClass, VariableElement member) { 2182 (ClassElement enclosingClass, FieldElement member) {
2168 if (compiler.elementHasCompileTimeError(member)) return; 2183 if (compiler.elementHasCompileTimeError(member)) return;
2169 reporter.withCurrentElement(member, () { 2184 reporter.withCurrentElement(member, () {
2170 ast.Node node = member.node; 2185 ResolvedAst fieldResolvedAst = backend.frontend.getResolvedAst(member);
2171 ast.Expression initializer = member.initializer; 2186 ast.Node node = fieldResolvedAst.node;
2187 ast.Expression initializer = fieldResolvedAst.body;
2172 if (initializer == null) { 2188 if (initializer == null) {
2173 // Unassigned fields of native classes are not initialized to 2189 // Unassigned fields of native classes are not initialized to
2174 // prevent overwriting pre-initialized native properties. 2190 // prevent overwriting pre-initialized native properties.
2175 if (!backend.isNativeOrExtendsNative(classElement)) { 2191 if (!backend.isNativeOrExtendsNative(classElement)) {
2176 fieldValues[member] = graph.addConstantNull(compiler); 2192 fieldValues[member] = graph.addConstantNull(compiler);
2177 } 2193 }
2178 } else { 2194 } else {
2179 ast.Node right = initializer; 2195 ast.Node right = initializer;
2180 ResolvedAst savedResolvedAst = resolvedAst; 2196 ResolvedAst savedResolvedAst = resolvedAst;
2181 resolvedAst = backend.frontend.getResolvedAst(member); 2197 resolvedAst = fieldResolvedAst;
2182 // In case the field initializer uses closures, run the 2198 // In case the field initializer uses closures, run the
2183 // closure to class mapper. 2199 // closure to class mapper.
2184 compiler.closureToClassMapper 2200 compiler.closureToClassMapper
2185 .computeClosureToClassMapping(resolvedAst); 2201 .computeClosureToClassMapping(resolvedAst);
2186 inlinedFrom(member, () => right.accept(this)); 2202 inlinedFrom(member, () => right.accept(this));
2187 resolvedAst = savedResolvedAst; 2203 resolvedAst = savedResolvedAst;
2188 fieldValues[member] = pop(); 2204 fieldValues[member] = pop();
2189 } 2205 }
2190 }); 2206 });
2191 }); 2207 });
2192 } 2208 }
2193 2209
2194 /** 2210 /**
2195 * Build the factory function corresponding to the constructor 2211 * Build the factory function corresponding to the constructor
2196 * [functionElement]: 2212 * [functionElement]:
2197 * - Initialize fields with the values of the field initializers of the 2213 * - Initialize fields with the values of the field initializers of the
2198 * current constructor and super constructors or constructors redirected 2214 * current constructor and super constructors or constructors redirected
2199 * to, starting from the current constructor. 2215 * to, starting from the current constructor.
2200 * - Call the constructor bodies, starting from the constructor(s) in the 2216 * - Call the constructor bodies, starting from the constructor(s) in the
2201 * super class(es). 2217 * super class(es).
2202 */ 2218 */
2203 HGraph buildFactory(ConstructorElement functionElement) { 2219 HGraph buildFactory(ResolvedAst resolvedAst) {
2220 ConstructorElement functionElement = resolvedAst.element;
2204 functionElement = functionElement.implementation; 2221 functionElement = functionElement.implementation;
2205 ClassElement classElement = functionElement.enclosingClass.implementation; 2222 ClassElement classElement = functionElement.enclosingClass.implementation;
2206 bool isNativeUpgradeFactory = 2223 bool isNativeUpgradeFactory =
2207 backend.isNativeOrExtendsNative(classElement) && 2224 backend.isNativeOrExtendsNative(classElement) &&
2208 !backend.isJsInterop(classElement); 2225 !backend.isJsInterop(classElement);
2209 ast.FunctionExpression function = functionElement.node; 2226 ast.FunctionExpression function;
2227 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
2228 function = resolvedAst.node;
2229 }
2230
2210 // Note that constructors (like any other static function) do not need 2231 // Note that constructors (like any other static function) do not need
2211 // to deal with optional arguments. It is the callers job to provide all 2232 // to deal with optional arguments. It is the callers job to provide all
2212 // arguments as if they were positional. 2233 // arguments as if they were positional.
2213 2234
2214 if (inliningStack.isEmpty) { 2235 if (inliningStack.isEmpty) {
2215 // The initializer list could contain closures. 2236 // The initializer list could contain closures.
2216 openFunction(functionElement, function); 2237 openFunction(functionElement, function);
2217 } 2238 }
2218 2239
2219 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>(); 2240 Map<Element, HInstruction> fieldValues = new Map<Element, HInstruction>();
(...skipping 12 matching lines...) Expand all
2232 // If the [element] is a field-parameter then 2253 // If the [element] is a field-parameter then
2233 // initialize the field element with its value. 2254 // initialize the field element with its value.
2234 InitializingFormalElement fieldParameter = parameter; 2255 InitializingFormalElement fieldParameter = parameter;
2235 HInstruction parameterValue = localsHandler.readLocal(fieldParameter); 2256 HInstruction parameterValue = localsHandler.readLocal(fieldParameter);
2236 fieldValues[fieldParameter.fieldElement] = parameterValue; 2257 fieldValues[fieldParameter.fieldElement] = parameterValue;
2237 } 2258 }
2238 }); 2259 });
2239 2260
2240 // Analyze the constructor and all referenced constructors and collect 2261 // Analyze the constructor and all referenced constructors and collect
2241 // initializers and constructor bodies. 2262 // initializers and constructor bodies.
2242 List<FunctionElement> constructors = <FunctionElement>[functionElement]; 2263 List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst];
2243 buildInitializers(functionElement, constructors, fieldValues); 2264 buildInitializers(functionElement, constructorResolvedAsts, fieldValues);
2244 2265
2245 // Call the JavaScript constructor with the fields as argument. 2266 // Call the JavaScript constructor with the fields as argument.
2246 List<HInstruction> constructorArguments = <HInstruction>[]; 2267 List<HInstruction> constructorArguments = <HInstruction>[];
2247 List<Element> fields = <Element>[]; 2268 List<Element> fields = <Element>[];
2248 2269
2249 classElement.forEachInstanceField( 2270 classElement.forEachInstanceField(
2250 (ClassElement enclosingClass, VariableElement member) { 2271 (ClassElement enclosingClass, VariableElement member) {
2251 HInstruction value = fieldValues[member]; 2272 HInstruction value = fieldValues[member];
2252 if (value == null) { 2273 if (value == null) {
2253 // Uninitialized native fields are pre-initialized by the native 2274 // Uninitialized native fields are pre-initialized by the native
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 if (source != null && allIndexed && remainingTypeVariables == 0) { 2383 if (source != null && allIndexed && remainingTypeVariables == 0) {
2363 copyRuntimeTypeInfo(source, newObject); 2384 copyRuntimeTypeInfo(source, newObject);
2364 } else { 2385 } else {
2365 newObject = 2386 newObject =
2366 callSetRuntimeTypeInfo(classElement, typeArguments, newObject); 2387 callSetRuntimeTypeInfo(classElement, typeArguments, newObject);
2367 } 2388 }
2368 } 2389 }
2369 2390
2370 // Generate calls to the constructor bodies. 2391 // Generate calls to the constructor bodies.
2371 HInstruction interceptor = null; 2392 HInstruction interceptor = null;
2372 for (int index = constructors.length - 1; index >= 0; index--) { 2393 for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
2373 FunctionElement constructor = constructors[index]; 2394 ResolvedAst constructorResolvedAst = constructorResolvedAsts[index];
2374 assert(invariant(functionElement, constructor.isImplementation)); 2395 ConstructorBodyElement body = getConstructorBody(constructorResolvedAst);
2375 ConstructorBodyElement body = getConstructorBody(constructor);
2376 if (body == null) continue; 2396 if (body == null) continue;
2377 2397
2378 List bodyCallInputs = <HInstruction>[]; 2398 List bodyCallInputs = <HInstruction>[];
2379 if (isNativeUpgradeFactory) { 2399 if (isNativeUpgradeFactory) {
2380 if (interceptor == null) { 2400 if (interceptor == null) {
2381 ConstantValue constant = 2401 ConstantValue constant =
2382 new InterceptorConstantValue(classElement.thisType); 2402 new InterceptorConstantValue(classElement.thisType);
2383 interceptor = graph.addConstant(constant, compiler); 2403 interceptor = graph.addConstant(constant, compiler);
2384 } 2404 }
2385 bodyCallInputs.add(interceptor); 2405 bodyCallInputs.add(interceptor);
2386 } 2406 }
2387 bodyCallInputs.add(newObject); 2407 bodyCallInputs.add(newObject);
2388 ResolvedAst resolvedAst = backend.frontend.getResolvedAst(constructor); 2408 ast.Node node = constructorResolvedAst.node;
2389 ast.Node node = resolvedAst.node;
2390 ClosureClassMap parameterClosureData = 2409 ClosureClassMap parameterClosureData =
2391 compiler.closureToClassMapper.getMappingForNestedFunction(node); 2410 compiler.closureToClassMapper.getMappingForNestedFunction(node);
2392 2411
2393 FunctionSignature functionSignature = body.functionSignature; 2412 FunctionSignature functionSignature = body.functionSignature;
2394 // Provide the parameters to the generative constructor body. 2413 // Provide the parameters to the generative constructor body.
2395 functionSignature.orderedForEachParameter((ParameterElement parameter) { 2414 functionSignature.orderedForEachParameter((ParameterElement parameter) {
2396 // If [parameter] is boxed, it will be a field in the box passed as the 2415 // If [parameter] is boxed, it will be a field in the box passed as the
2397 // last parameter. So no need to directly pass it. 2416 // last parameter. So no need to directly pass it.
2398 if (!localsHandler.isBoxed(parameter)) { 2417 if (!localsHandler.isBoxed(parameter)) {
2399 bodyCallInputs.add(localsHandler.readLocal(parameter)); 2418 bodyCallInputs.add(localsHandler.readLocal(parameter));
2400 } 2419 }
2401 }); 2420 });
2402 2421
2403 // If there are locals that escape (ie mutated in closures), we 2422 // If there are locals that escape (ie mutated in closures), we
2404 // pass the box to the constructor. 2423 // pass the box to the constructor.
2405 // The box must be passed before any type variable. 2424 // The box must be passed before any type variable.
2406 ClosureScope scopeData = parameterClosureData.capturingScopes[node]; 2425 ClosureScope scopeData = parameterClosureData.capturingScopes[node];
2407 if (scopeData != null) { 2426 if (scopeData != null) {
2408 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement)); 2427 bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
2409 } 2428 }
2410 2429
2411 // Type variables arguments must come after the box (if there is one). 2430 // Type variables arguments must come after the box (if there is one).
2431 ConstructorElement constructor =
2432 constructorResolvedAst.element.implementation;
2412 ClassElement currentClass = constructor.enclosingClass; 2433 ClassElement currentClass = constructor.enclosingClass;
2413 if (backend.classNeedsRti(currentClass)) { 2434 if (backend.classNeedsRti(currentClass)) {
2414 // If [currentClass] needs RTI, we add the type variables as 2435 // If [currentClass] needs RTI, we add the type variables as
2415 // parameters of the generative constructor body. 2436 // parameters of the generative constructor body.
2416 currentClass.typeVariables.forEach((TypeVariableType argument) { 2437 currentClass.typeVariables.forEach((TypeVariableType argument) {
2417 // TODO(johnniwinther): Substitute [argument] with 2438 // TODO(johnniwinther): Substitute [argument] with
2418 // `localsHandler.substInContext(argument)`. 2439 // `localsHandler.substInContext(argument)`.
2419 bodyCallInputs.add(localsHandler 2440 bodyCallInputs.add(localsHandler
2420 .readLocal(localsHandler.getTypeVariableAsLocal(argument))); 2441 .readLocal(localsHandler.getTypeVariableAsLocal(argument)));
2421 }); 2442 });
(...skipping 5484 matching lines...) Expand 10 before | Expand all | Expand 10 after
7906 instanceType: instanceType); 7927 instanceType: instanceType);
7907 } 7928 }
7908 7929
7909 void leaveInlinedMethod() { 7930 void leaveInlinedMethod() {
7910 HInstruction result = localsHandler.readLocal(returnLocal); 7931 HInstruction result = localsHandler.readLocal(returnLocal);
7911 AstInliningState state = inliningStack.removeLast(); 7932 AstInliningState state = inliningStack.removeLast();
7912 restoreState(state); 7933 restoreState(state);
7913 stack.add(result); 7934 stack.add(result);
7914 } 7935 }
7915 7936
7916 void doInline(FunctionElement function) { 7937 void doInline(ResolvedAst resolvedAst) {
7917 visitInlinedFunction(function); 7938 visitInlinedFunction(resolvedAst);
7918 } 7939 }
7919 7940
7920 void emitReturn(HInstruction value, ast.Node node) { 7941 void emitReturn(HInstruction value, ast.Node node) {
7921 if (inliningStack.isEmpty) { 7942 if (inliningStack.isEmpty) {
7922 closeAndGotoExit( 7943 closeAndGotoExit(
7923 new HReturn(value, sourceInformationBuilder.buildReturn(node))); 7944 new HReturn(value, sourceInformationBuilder.buildReturn(node)));
7924 } else { 7945 } else {
7925 localsHandler.updateLocal(returnLocal, value); 7946 localsHandler.updateLocal(returnLocal, value);
7926 } 7947 }
7927 } 7948 }
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
8575 const _LoopTypeVisitor(); 8596 const _LoopTypeVisitor();
8576 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; 8597 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
8577 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; 8598 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
8578 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; 8599 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
8579 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; 8600 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
8580 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8601 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8581 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; 8602 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
8582 int visitSwitchStatement(ast.SwitchStatement node) => 8603 int visitSwitchStatement(ast.SwitchStatement node) =>
8583 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; 8604 HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
8584 } 8605 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/serialization/modelz.dart ('k') | tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698