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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 | 134 |
135 /// Registry used to enqueue work during codegen, may be null to avoid | 135 /// Registry used to enqueue work during codegen, may be null to avoid |
136 /// enqueing any work. | 136 /// enqueing any work. |
137 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be | 137 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be |
138 // able to return the impact as a result after building and avoid enqueing | 138 // able to return the impact as a result after building and avoid enqueing |
139 // things here. Later the codegen task can decide whether to enqueue | 139 // things here. Later the codegen task can decide whether to enqueue |
140 // something. In the past this didn't matter as much because the SSA graph was | 140 // something. In the past this didn't matter as much because the SSA graph was |
141 // used only for codegen, but currently we want to experiment using it for | 141 // used only for codegen, but currently we want to experiment using it for |
142 // code-analysis too. | 142 // code-analysis too. |
143 final CodegenRegistry registry; | 143 final CodegenRegistry registry; |
144 | |
145 /// All results from the global type-inference analysis. | |
144 final GlobalTypeInferenceResults inferenceResults; | 146 final GlobalTypeInferenceResults inferenceResults; |
147 | |
148 /// Results from the global type-inference analysis corresponding to the | |
149 /// current element being visited. | |
150 /// | |
151 /// Invariant: this property is updated together with [resolvedAst]. | |
152 GlobalTypeInferenceElementResult elementInferenceResults; | |
153 | |
145 final JavaScriptBackend backend; | 154 final JavaScriptBackend backend; |
146 final ConstantSystem constantSystem; | 155 final ConstantSystem constantSystem; |
147 final RuntimeTypes rti; | 156 final RuntimeTypes rti; |
148 | 157 |
149 SourceInformationBuilder sourceInformationBuilder; | 158 SourceInformationBuilder sourceInformationBuilder; |
150 | 159 |
151 bool inLazyInitializerExpression = false; | 160 bool inLazyInitializerExpression = false; |
152 | 161 |
153 // TODO(sigmund): make all comments /// instead of /* */ | 162 // TODO(sigmund): make all comments /// instead of /* */ |
154 /* This field is used by the native handler. */ | 163 /* This field is used by the native handler. */ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 JavaScriptBackend backend, | 195 JavaScriptBackend backend, |
187 this.nativeEmitter, | 196 this.nativeEmitter, |
188 SourceInformationStrategy sourceInformationFactory) | 197 SourceInformationStrategy sourceInformationFactory) |
189 : this.infoReporter = backend.compiler.dumpInfoTask, | 198 : this.infoReporter = backend.compiler.dumpInfoTask, |
190 this.backend = backend, | 199 this.backend = backend, |
191 this.constantSystem = backend.constantSystem, | 200 this.constantSystem = backend.constantSystem, |
192 this.rti = backend.rti, | 201 this.rti = backend.rti, |
193 this.inferenceResults = backend.compiler.globalInference.results { | 202 this.inferenceResults = backend.compiler.globalInference.results { |
194 assert(target.isImplementation); | 203 assert(target.isImplementation); |
195 compiler = backend.compiler; | 204 compiler = backend.compiler; |
205 elementInferenceResults = inferenceResults.resultOf(target); | |
206 assert(elementInferenceResults != null); | |
196 graph.element = target; | 207 graph.element = target; |
197 sourceElementStack.add(target); | 208 sourceElementStack.add(target); |
198 sourceInformationBuilder = | 209 sourceInformationBuilder = |
199 sourceInformationFactory.createBuilderForContext(resolvedAst); | 210 sourceInformationFactory.createBuilderForContext(resolvedAst); |
200 graph.sourceInformation = | 211 graph.sourceInformation = |
201 sourceInformationBuilder.buildVariableDeclaration(); | 212 sourceInformationBuilder.buildVariableDeclaration(); |
202 localsHandler = new LocalsHandler(this, target, null, compiler); | 213 localsHandler = new LocalsHandler(this, target, null, compiler); |
203 loopHandler = new SsaLoopHandler(this); | 214 loopHandler = new SsaLoopHandler(this); |
204 } | 215 } |
205 | 216 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 // Generative constructors of native classes should not be called directly | 440 // Generative constructors of native classes should not be called directly |
430 // and have an extra argument that causes problems with inlining. | 441 // and have an extra argument that causes problems with inlining. |
431 if (element.isGenerativeConstructor && | 442 if (element.isGenerativeConstructor && |
432 backend.isNativeOrExtendsNative(element.enclosingClass)) { | 443 backend.isNativeOrExtendsNative(element.enclosingClass)) { |
433 return false; | 444 return false; |
434 } | 445 } |
435 | 446 |
436 // A generative constructor body is not seen by global analysis, | 447 // A generative constructor body is not seen by global analysis, |
437 // so we should not query for its type. | 448 // so we should not query for its type. |
438 if (!element.isGenerativeConstructorBody) { | 449 if (!element.isGenerativeConstructorBody) { |
439 if (inferenceResults.throwsAlways(element)) { | 450 if (inferenceResults.resultOf(element).throwsAlways) { |
440 isReachable = false; | 451 isReachable = false; |
441 return false; | 452 return false; |
442 } | 453 } |
443 } | 454 } |
444 | 455 |
445 return true; | 456 return true; |
446 } | 457 } |
447 | 458 |
448 bool doesNotContainCode() { | 459 bool doesNotContainCode() { |
449 // A function with size 1 does not contain any code. | 460 // A function with size 1 does not contain any code. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 return true; | 572 return true; |
562 } | 573 } |
563 | 574 |
564 return false; | 575 return false; |
565 } | 576 } |
566 | 577 |
567 bool get allInlinedFunctionsCalledOnce { | 578 bool get allInlinedFunctionsCalledOnce { |
568 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; | 579 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; |
569 } | 580 } |
570 | 581 |
571 bool isFunctionCalledOnce(Element element) { | 582 bool isFunctionCalledOnce(element) { |
572 if (element is ConstructorBodyElement) { | 583 // ConstructorBodyElements are not in the type inference graph. |
573 // ConstructorBodyElements are not in the type inference graph. | 584 if (element is ConstructorBodyElement) return false; |
574 return false; | 585 return inferenceResults.resultOf(element).isCalledOnce; |
575 } | |
576 return inferenceResults.isCalledOnce(element); | |
577 } | 586 } |
578 | 587 |
579 bool isCalledOnce(Element element) { | 588 bool isCalledOnce(Element element) { |
580 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); | 589 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); |
581 } | 590 } |
582 | 591 |
583 inlinedFrom(ResolvedAst resolvedAst, f()) { | 592 inlinedFrom(ResolvedAst resolvedAst, f()) { |
584 Element element = resolvedAst.element; | 593 Element element = resolvedAst.element; |
585 assert(element is FunctionElement || element is VariableElement); | 594 assert(element is FunctionElement || element is VariableElement); |
586 return reporter.withCurrentElement(element.implementation, () { | 595 return reporter.withCurrentElement(element.implementation, () { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
752 // variable. So find the specific initialized variable we are referring to. | 761 // variable. So find the specific initialized variable we are referring to. |
753 ast.Node sourceInfoNode = initializer; | 762 ast.Node sourceInfoNode = initializer; |
754 for (var definition in node.definitions) { | 763 for (var definition in node.definitions) { |
755 if (definition is ast.SendSet && | 764 if (definition is ast.SendSet && |
756 definition.selector.asIdentifier().source == variable.name) { | 765 definition.selector.asIdentifier().source == variable.name) { |
757 sourceInfoNode = definition.assignmentOperator; | 766 sourceInfoNode = definition.assignmentOperator; |
758 break; | 767 break; |
759 } | 768 } |
760 } | 769 } |
761 | 770 |
762 closeAndGotoExit(new HReturn(value, sourceInformationBuilder.buildReturn( | 771 closeAndGotoExit(new HReturn( |
763 sourceInfoNode))); | 772 value, sourceInformationBuilder.buildReturn(sourceInfoNode))); |
764 return closeFunction(); | 773 return closeFunction(); |
765 } | 774 } |
766 | 775 |
767 /** | 776 /** |
768 * Returns the constructor body associated with the given constructor or | 777 * Returns the constructor body associated with the given constructor or |
769 * creates a new constructor body, if none can be found. | 778 * creates a new constructor body, if none can be found. |
770 * | 779 * |
771 * Returns [:null:] if the constructor does not have a body. | 780 * Returns [:null:] if the constructor does not have a body. |
772 */ | 781 */ |
773 ConstructorBodyElement getConstructorBody( | 782 ConstructorBodyElement getConstructorBody( |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 | 870 |
862 insertTraceCall(function); | 871 insertTraceCall(function); |
863 insertCoverageCall(function); | 872 insertCoverageCall(function); |
864 } | 873 } |
865 | 874 |
866 void restoreState(AstInliningState state) { | 875 void restoreState(AstInliningState state) { |
867 localsHandler = state.oldLocalsHandler; | 876 localsHandler = state.oldLocalsHandler; |
868 returnLocal = state.oldReturnLocal; | 877 returnLocal = state.oldReturnLocal; |
869 inTryStatement = state.inTryStatement; | 878 inTryStatement = state.inTryStatement; |
870 resolvedAst = state.oldResolvedAst; | 879 resolvedAst = state.oldResolvedAst; |
880 elementInferenceResults = state.oldElementInferenceResults; | |
871 returnType = state.oldReturnType; | 881 returnType = state.oldReturnType; |
872 assert(stack.isEmpty); | 882 assert(stack.isEmpty); |
873 stack = state.oldStack; | 883 stack = state.oldStack; |
874 } | 884 } |
875 | 885 |
876 /** | 886 /** |
877 * Run this builder on the body of the [function] to be inlined. | 887 * Run this builder on the body of the [function] to be inlined. |
878 */ | 888 */ |
879 void visitInlinedFunction(ResolvedAst resolvedAst) { | 889 void visitInlinedFunction(ResolvedAst resolvedAst) { |
880 potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation); | 890 potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
993 // form [:this.x:]. | 1003 // form [:this.x:]. |
994 if (parameter.isInitializingFormal) { | 1004 if (parameter.isInitializingFormal) { |
995 InitializingFormalElement fieldParameterElement = parameter; | 1005 InitializingFormalElement fieldParameterElement = parameter; |
996 fieldValues[fieldParameterElement.fieldElement] = argument; | 1006 fieldValues[fieldParameterElement.fieldElement] = argument; |
997 } | 1007 } |
998 }); | 1008 }); |
999 | 1009 |
1000 // Build the initializers in the context of the new constructor. | 1010 // Build the initializers in the context of the new constructor. |
1001 ResolvedAst oldResolvedAst = resolvedAst; | 1011 ResolvedAst oldResolvedAst = resolvedAst; |
1002 resolvedAst = callee.resolvedAst; | 1012 resolvedAst = callee.resolvedAst; |
1013 final oldElementInferenceResults = elementInferenceResults; | |
1014 elementInferenceResults = inferenceResults.resultOf(callee); | |
1003 ClosureClassMap oldClosureData = localsHandler.closureData; | 1015 ClosureClassMap oldClosureData = localsHandler.closureData; |
1004 ClosureClassMap newClosureData = | 1016 ClosureClassMap newClosureData = |
1005 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 1017 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); |
1006 localsHandler.closureData = newClosureData; | 1018 localsHandler.closureData = newClosureData; |
1007 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 1019 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
1008 localsHandler.enterScope(resolvedAst.node, callee); | 1020 localsHandler.enterScope(resolvedAst.node, callee); |
1009 } | 1021 } |
1010 buildInitializers(callee, constructorResolvedAsts, fieldValues); | 1022 buildInitializers(callee, constructorResolvedAsts, fieldValues); |
1011 localsHandler.closureData = oldClosureData; | 1023 localsHandler.closureData = oldClosureData; |
1012 resolvedAst = oldResolvedAst; | 1024 resolvedAst = oldResolvedAst; |
1025 elementInferenceResults = oldElementInferenceResults; | |
1013 }); | 1026 }); |
1014 } | 1027 } |
1015 | 1028 |
1016 void buildInitializers( | 1029 void buildInitializers( |
1017 ConstructorElement constructor, | 1030 ConstructorElement constructor, |
1018 List<ResolvedAst> constructorResolvedAsts, | 1031 List<ResolvedAst> constructorResolvedAsts, |
1019 Map<Element, HInstruction> fieldValues) { | 1032 Map<Element, HInstruction> fieldValues) { |
1020 assert(invariant( | 1033 assert(invariant( |
1021 constructor, resolvedAst.element == constructor.declaration, | 1034 constructor, resolvedAst.element == constructor.declaration, |
1022 message: "Expected ResolvedAst for $constructor, found $resolvedAst")); | 1035 message: "Expected ResolvedAst for $constructor, found $resolvedAst")); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 if (initializer == null) { | 1178 if (initializer == null) { |
1166 // Unassigned fields of native classes are not initialized to | 1179 // Unassigned fields of native classes are not initialized to |
1167 // prevent overwriting pre-initialized native properties. | 1180 // prevent overwriting pre-initialized native properties. |
1168 if (!backend.isNativeOrExtendsNative(classElement)) { | 1181 if (!backend.isNativeOrExtendsNative(classElement)) { |
1169 fieldValues[member] = graph.addConstantNull(compiler); | 1182 fieldValues[member] = graph.addConstantNull(compiler); |
1170 } | 1183 } |
1171 } else { | 1184 } else { |
1172 ast.Node right = initializer; | 1185 ast.Node right = initializer; |
1173 ResolvedAst savedResolvedAst = resolvedAst; | 1186 ResolvedAst savedResolvedAst = resolvedAst; |
1174 resolvedAst = fieldResolvedAst; | 1187 resolvedAst = fieldResolvedAst; |
1188 final oldElementInferenceResults = elementInferenceResults; | |
1189 elementInferenceResults = inferenceResults.resultOf(member); | |
1175 // In case the field initializer uses closures, run the | 1190 // In case the field initializer uses closures, run the |
1176 // closure to class mapper. | 1191 // closure to class mapper. |
1177 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 1192 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); |
1178 inlinedFrom(fieldResolvedAst, () => right.accept(this)); | 1193 inlinedFrom(fieldResolvedAst, () => right.accept(this)); |
1179 resolvedAst = savedResolvedAst; | 1194 resolvedAst = savedResolvedAst; |
1195 elementInferenceResults = oldElementInferenceResults; | |
1180 fieldValues[member] = pop(); | 1196 fieldValues[member] = pop(); |
1181 } | 1197 } |
1182 }); | 1198 }); |
1183 }); | 1199 }); |
1184 } | 1200 } |
1185 | 1201 |
1186 /** | 1202 /** |
1187 * Build the factory function corresponding to the constructor | 1203 * Build the factory function corresponding to the constructor |
1188 * [functionElement]: | 1204 * [functionElement]: |
1189 * - Initialize fields with the values of the field initializers of the | 1205 * - Initialize fields with the values of the field initializers of the |
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2062 UnaryOperation operation = constantSystem.lookupUnary(operator); | 2078 UnaryOperation operation = constantSystem.lookupUnary(operator); |
2063 HConstant constant = operand; | 2079 HConstant constant = operand; |
2064 ConstantValue folded = operation.fold(constant.constant); | 2080 ConstantValue folded = operation.fold(constant.constant); |
2065 if (folded != null) { | 2081 if (folded != null) { |
2066 stack.add(graph.addConstant(folded, compiler)); | 2082 stack.add(graph.addConstant(folded, compiler)); |
2067 return; | 2083 return; |
2068 } | 2084 } |
2069 } | 2085 } |
2070 | 2086 |
2071 pushInvokeDynamic(node, elements.getSelector(node), | 2087 pushInvokeDynamic(node, elements.getSelector(node), |
2072 inferenceResults.typeOfSend(node, elements), [operand], | 2088 elementInferenceResults.typeOfSend(node), [operand], |
2073 sourceInformation: sourceInformationBuilder.buildGeneric(node)); | 2089 sourceInformation: sourceInformationBuilder.buildGeneric(node)); |
2074 } | 2090 } |
2075 | 2091 |
2076 @override | 2092 @override |
2077 void visitBinary(ast.Send node, ast.Node left, BinaryOperator operator, | 2093 void visitBinary(ast.Send node, ast.Node left, BinaryOperator operator, |
2078 ast.Node right, _) { | 2094 ast.Node right, _) { |
2079 handleBinary(node, left, right); | 2095 handleBinary(node, left, right); |
2080 } | 2096 } |
2081 | 2097 |
2082 @override | 2098 @override |
(...skipping 10 matching lines...) Expand all Loading... | |
2093 void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) { | 2109 void visitNotEquals(ast.Send node, ast.Node left, ast.Node right, _) { |
2094 handleBinary(node, left, right); | 2110 handleBinary(node, left, right); |
2095 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector); | 2111 pushWithPosition(new HNot(popBoolified(), backend.boolType), node.selector); |
2096 } | 2112 } |
2097 | 2113 |
2098 void handleBinary(ast.Send node, ast.Node left, ast.Node right) { | 2114 void handleBinary(ast.Send node, ast.Node left, ast.Node right) { |
2099 visitBinarySend( | 2115 visitBinarySend( |
2100 visitAndPop(left), | 2116 visitAndPop(left), |
2101 visitAndPop(right), | 2117 visitAndPop(right), |
2102 elements.getSelector(node), | 2118 elements.getSelector(node), |
2103 inferenceResults.typeOfSend(node, elements), | 2119 elementInferenceResults.typeOfSend(node), |
2104 node, | 2120 node, |
2105 sourceInformation: | 2121 sourceInformation: |
2106 sourceInformationBuilder.buildGeneric(node.selector)); | 2122 sourceInformationBuilder.buildGeneric(node.selector)); |
2107 } | 2123 } |
2108 | 2124 |
2109 /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and | 2125 /// TODO(johnniwinther): Merge [visitBinarySend] with [handleBinary] and |
2110 /// remove use of [location] for source information. | 2126 /// remove use of [location] for source information. |
2111 void visitBinarySend(HInstruction left, HInstruction right, Selector selector, | 2127 void visitBinarySend(HInstruction left, HInstruction right, Selector selector, |
2112 TypeMask mask, ast.Send send, | 2128 TypeMask mask, ast.Send send, |
2113 {SourceInformation sourceInformation}) { | 2129 {SourceInformation sourceInformation}) { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2256 } else { | 2272 } else { |
2257 pushInvokeStatic(node, getter, <HInstruction>[], | 2273 pushInvokeStatic(node, getter, <HInstruction>[], |
2258 sourceInformation: sourceInformation); | 2274 sourceInformation: sourceInformation); |
2259 } | 2275 } |
2260 } | 2276 } |
2261 | 2277 |
2262 /// Generate a dynamic getter invocation. | 2278 /// Generate a dynamic getter invocation. |
2263 void generateDynamicGet(ast.Send node) { | 2279 void generateDynamicGet(ast.Send node) { |
2264 HInstruction receiver = generateInstanceSendReceiver(node); | 2280 HInstruction receiver = generateInstanceSendReceiver(node); |
2265 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), | 2281 generateInstanceGetterWithCompiledReceiver(node, elements.getSelector(node), |
2266 inferenceResults.typeOfSend(node, elements), receiver); | 2282 elementInferenceResults.typeOfSend(node), receiver); |
2267 } | 2283 } |
2268 | 2284 |
2269 /// Generate a closurization of the static or top level [function]. | 2285 /// Generate a closurization of the static or top level [function]. |
2270 void generateStaticFunctionGet(ast.Send node, MethodElement function) { | 2286 void generateStaticFunctionGet(ast.Send node, MethodElement function) { |
2271 // TODO(5346): Try to avoid the need for calling [declaration] before | 2287 // TODO(5346): Try to avoid the need for calling [declaration] before |
2272 // creating an [HStatic]. | 2288 // creating an [HStatic]. |
2273 SourceInformation sourceInformation = | 2289 SourceInformation sourceInformation = |
2274 sourceInformationBuilder.buildGet(node); | 2290 sourceInformationBuilder.buildGet(node); |
2275 push(new HStatic(function.declaration, backend.nonNullType) | 2291 push(new HStatic(function.declaration, backend.nonNullType) |
2276 ..sourceInformation = sourceInformation); | 2292 ..sourceInformation = sourceInformation); |
(...skipping 28 matching lines...) Expand all Loading... | |
2305 brancher.handleConditional( | 2321 brancher.handleConditional( |
2306 () { | 2322 () { |
2307 expression = visitAndPop(receiver); | 2323 expression = visitAndPop(receiver); |
2308 pushCheckNull(expression); | 2324 pushCheckNull(expression); |
2309 }, | 2325 }, |
2310 () => stack.add(expression), | 2326 () => stack.add(expression), |
2311 () { | 2327 () { |
2312 generateInstanceGetterWithCompiledReceiver( | 2328 generateInstanceGetterWithCompiledReceiver( |
2313 node, | 2329 node, |
2314 elements.getSelector(node), | 2330 elements.getSelector(node), |
2315 inferenceResults.typeOfSend(node, elements), | 2331 elementInferenceResults.typeOfSend(node), |
2316 expression); | 2332 expression); |
2317 }); | 2333 }); |
2318 } | 2334 } |
2319 | 2335 |
2320 @override | 2336 @override |
2321 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) { | 2337 void visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) { |
2322 handleLocalGet(node, variable); | 2338 handleLocalGet(node, variable); |
2323 } | 2339 } |
2324 | 2340 |
2325 @override | 2341 @override |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2370 void generateInstanceSetterWithCompiledReceiver( | 2386 void generateInstanceSetterWithCompiledReceiver( |
2371 ast.Send send, HInstruction receiver, HInstruction value, | 2387 ast.Send send, HInstruction receiver, HInstruction value, |
2372 {Selector selector, TypeMask mask, ast.Node location}) { | 2388 {Selector selector, TypeMask mask, ast.Node location}) { |
2373 assert(invariant(send == null ? location : send, | 2389 assert(invariant(send == null ? location : send, |
2374 send == null || Elements.isInstanceSend(send, elements), | 2390 send == null || Elements.isInstanceSend(send, elements), |
2375 message: "Unexpected instance setter" | 2391 message: "Unexpected instance setter" |
2376 "${send != null ? " element: ${elements[send]}" : ""}")); | 2392 "${send != null ? " element: ${elements[send]}" : ""}")); |
2377 if (selector == null) { | 2393 if (selector == null) { |
2378 assert(send != null); | 2394 assert(send != null); |
2379 selector = elements.getSelector(send); | 2395 selector = elements.getSelector(send); |
2380 mask ??= inferenceResults.typeOfSend(send, elements); | 2396 mask ??= elementInferenceResults.typeOfSend(send); |
2381 } | 2397 } |
2382 if (location == null) { | 2398 if (location == null) { |
2383 assert(send != null); | 2399 assert(send != null); |
2384 location = send; | 2400 location = send; |
2385 } | 2401 } |
2386 assert(selector.isSetter); | 2402 assert(selector.isSetter); |
2387 pushInvokeDynamic(location, selector, mask, [receiver, value], | 2403 pushInvokeDynamic(location, selector, mask, [receiver, value], |
2388 sourceInformation: sourceInformationBuilder.buildAssignment(location)); | 2404 sourceInformation: sourceInformationBuilder.buildAssignment(location)); |
2389 pop(); | 2405 pop(); |
2390 stack.add(value); | 2406 stack.add(value); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2641 } | 2657 } |
2642 | 2658 |
2643 /// Generate a dynamic method, getter or setter invocation. | 2659 /// Generate a dynamic method, getter or setter invocation. |
2644 void generateDynamicSend(ast.Send node) { | 2660 void generateDynamicSend(ast.Send node) { |
2645 HInstruction receiver = generateInstanceSendReceiver(node); | 2661 HInstruction receiver = generateInstanceSendReceiver(node); |
2646 _generateDynamicSend(node, receiver); | 2662 _generateDynamicSend(node, receiver); |
2647 } | 2663 } |
2648 | 2664 |
2649 void _generateDynamicSend(ast.Send node, HInstruction receiver) { | 2665 void _generateDynamicSend(ast.Send node, HInstruction receiver) { |
2650 Selector selector = elements.getSelector(node); | 2666 Selector selector = elements.getSelector(node); |
2651 TypeMask mask = inferenceResults.typeOfSend(node, elements); | 2667 TypeMask mask = elementInferenceResults.typeOfSend(node); |
2652 SourceInformation sourceInformation = | 2668 SourceInformation sourceInformation = |
2653 sourceInformationBuilder.buildCall(node, node.selector); | 2669 sourceInformationBuilder.buildCall(node, node.selector); |
2654 | 2670 |
2655 List<HInstruction> inputs = <HInstruction>[]; | 2671 List<HInstruction> inputs = <HInstruction>[]; |
2656 inputs.add(receiver); | 2672 inputs.add(receiver); |
2657 addDynamicSendArgumentsToList(node, inputs); | 2673 addDynamicSendArgumentsToList(node, inputs); |
2658 | 2674 |
2659 pushInvokeDynamic(node, selector, mask, inputs, | 2675 pushInvokeDynamic(node, selector, mask, inputs, |
2660 sourceInformation: sourceInformation); | 2676 sourceInformation: sourceInformation); |
2661 if (selector.isSetter || selector.isIndexSet) { | 2677 if (selector.isSetter || selector.isIndexSet) { |
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4420 rhs = graph.addConstantInt(1, compiler); | 4436 rhs = graph.addConstantInt(1, compiler); |
4421 } else { | 4437 } else { |
4422 visit(arguments.head); | 4438 visit(arguments.head); |
4423 assert(arguments.tail.isEmpty); | 4439 assert(arguments.tail.isEmpty); |
4424 rhs = pop(); | 4440 rhs = pop(); |
4425 } | 4441 } |
4426 visitBinarySend( | 4442 visitBinarySend( |
4427 receiver, | 4443 receiver, |
4428 rhs, | 4444 rhs, |
4429 elements.getOperatorSelectorInComplexSendSet(node), | 4445 elements.getOperatorSelectorInComplexSendSet(node), |
4430 inferenceResults.typeOfOperator(node, elements), | 4446 elementInferenceResults.typeOfOperator(node), |
4431 node, | 4447 node, |
4432 sourceInformation: | 4448 sourceInformation: |
4433 sourceInformationBuilder.buildGeneric(node.assignmentOperator)); | 4449 sourceInformationBuilder.buildGeneric(node.assignmentOperator)); |
4434 } | 4450 } |
4435 | 4451 |
4436 void handleSuperSendSet(ast.SendSet node) { | 4452 void handleSuperSendSet(ast.SendSet node) { |
4437 Element element = elements[node]; | 4453 Element element = elements[node]; |
4438 List<HInstruction> setterInputs = <HInstruction>[]; | 4454 List<HInstruction> setterInputs = <HInstruction>[]; |
4439 void generateSuperSendSet() { | 4455 void generateSuperSendSet() { |
4440 Selector setterSelector = elements.getSelector(node); | 4456 Selector setterSelector = elements.getSelector(node); |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4783 HInstruction receiver = pop(); | 4799 HInstruction receiver = pop(); |
4784 Link<ast.Node> arguments = node.arguments; | 4800 Link<ast.Node> arguments = node.arguments; |
4785 HInstruction index; | 4801 HInstruction index; |
4786 if (node.isIndex) { | 4802 if (node.isIndex) { |
4787 visit(arguments.head); | 4803 visit(arguments.head); |
4788 arguments = arguments.tail; | 4804 arguments = arguments.tail; |
4789 index = pop(); | 4805 index = pop(); |
4790 } | 4806 } |
4791 | 4807 |
4792 pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node), | 4808 pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node), |
4793 inferenceResults.typeOfGetter(node, elements), [receiver, index]); | 4809 elementInferenceResults.typeOfGetter(node), [receiver, index]); |
4794 HInstruction getterInstruction = pop(); | 4810 HInstruction getterInstruction = pop(); |
4795 if (node.isIfNullAssignment) { | 4811 if (node.isIfNullAssignment) { |
4796 // Compile x[i] ??= e as: | 4812 // Compile x[i] ??= e as: |
4797 // t1 = x[i] | 4813 // t1 = x[i] |
4798 // if (t1 == null) | 4814 // if (t1 == null) |
4799 // t1 = x[i] = e; | 4815 // t1 = x[i] = e; |
4800 // result = t1 | 4816 // result = t1 |
4801 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4817 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); |
4802 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 4818 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
4803 visit(arguments.head); | 4819 visit(arguments.head); |
4804 HInstruction value = pop(); | 4820 HInstruction value = pop(); |
4805 pushInvokeDynamic( | 4821 pushInvokeDynamic( |
4806 node, | 4822 node, |
4807 elements.getSelector(node), | 4823 elements.getSelector(node), |
4808 inferenceResults.typeOfSend(node, elements), | 4824 elementInferenceResults.typeOfSend(node), |
4809 [receiver, index, value]); | 4825 [receiver, index, value]); |
4810 pop(); | 4826 pop(); |
4811 stack.add(value); | 4827 stack.add(value); |
4812 }); | 4828 }); |
4813 } else { | 4829 } else { |
4814 handleComplexOperatorSend(node, getterInstruction, arguments); | 4830 handleComplexOperatorSend(node, getterInstruction, arguments); |
4815 HInstruction value = pop(); | 4831 HInstruction value = pop(); |
4816 pushInvokeDynamic( | 4832 pushInvokeDynamic(node, elements.getSelector(node), |
4817 node, | 4833 elementInferenceResults.typeOfSend(node), [receiver, index, value]); |
4818 elements.getSelector(node), | |
4819 inferenceResults.typeOfSend(node, elements), | |
4820 [receiver, index, value]); | |
4821 pop(); | 4834 pop(); |
4822 if (node.isPostfix) { | 4835 if (node.isPostfix) { |
4823 stack.add(getterInstruction); | 4836 stack.add(getterInstruction); |
4824 } else { | 4837 } else { |
4825 stack.add(value); | 4838 stack.add(value); |
4826 } | 4839 } |
4827 } | 4840 } |
4828 } | 4841 } |
4829 } | 4842 } |
4830 | 4843 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5014 } | 5027 } |
5015 return; | 5028 return; |
5016 } | 5029 } |
5017 | 5030 |
5018 if (Elements.isInstanceSend(node, elements)) { | 5031 if (Elements.isInstanceSend(node, elements)) { |
5019 void generateAssignment(HInstruction receiver) { | 5032 void generateAssignment(HInstruction receiver) { |
5020 // desugars `e.x op= e2` to `e.x = e.x op e2` | 5033 // desugars `e.x op= e2` to `e.x = e.x op e2` |
5021 generateInstanceGetterWithCompiledReceiver( | 5034 generateInstanceGetterWithCompiledReceiver( |
5022 node, | 5035 node, |
5023 elements.getGetterSelectorInComplexSendSet(node), | 5036 elements.getGetterSelectorInComplexSendSet(node), |
5024 inferenceResults.typeOfGetter(node, elements), | 5037 elementInferenceResults.typeOfGetter(node), |
5025 receiver); | 5038 receiver); |
5026 HInstruction getterInstruction = pop(); | 5039 HInstruction getterInstruction = pop(); |
5027 if (node.isIfNullAssignment) { | 5040 if (node.isIfNullAssignment) { |
5028 SsaBranchBuilder brancher = | 5041 SsaBranchBuilder brancher = |
5029 new SsaBranchBuilder(this, compiler, node); | 5042 new SsaBranchBuilder(this, compiler, node); |
5030 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 5043 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
5031 visit(node.arguments.head); | 5044 visit(node.arguments.head); |
5032 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); | 5045 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); |
5033 }); | 5046 }); |
5034 } else { | 5047 } else { |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5477 } | 5490 } |
5478 | 5491 |
5479 TypeMask type = _inferredTypeOfNewList(node); | 5492 TypeMask type = _inferredTypeOfNewList(node); |
5480 if (!type.containsAll(compiler.closedWorld)) { | 5493 if (!type.containsAll(compiler.closedWorld)) { |
5481 instruction.instructionType = type; | 5494 instruction.instructionType = type; |
5482 } | 5495 } |
5483 stack.add(instruction); | 5496 stack.add(instruction); |
5484 } | 5497 } |
5485 | 5498 |
5486 _inferredTypeOfNewList(ast.Node node) => | 5499 _inferredTypeOfNewList(ast.Node node) => |
5487 inferenceResults.typeOfNewList(sourceElement, node) ?? | 5500 inferenceResults.resultOf(sourceElement).typeOfNewList(node) ?? |
5488 compiler.commonMasks.dynamicType; | 5501 compiler.commonMasks.dynamicType; |
5489 | 5502 |
5490 visitConditional(ast.Conditional node) { | 5503 visitConditional(ast.Conditional node) { |
5491 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 5504 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); |
5492 brancher.handleConditional(() => visit(node.condition), | 5505 brancher.handleConditional(() => visit(node.condition), |
5493 () => visit(node.thenExpression), () => visit(node.elseExpression)); | 5506 () => visit(node.thenExpression), () => visit(node.elseExpression)); |
5494 } | 5507 } |
5495 | 5508 |
5496 visitStringInterpolation(ast.StringInterpolation node) { | 5509 visitStringInterpolation(ast.StringInterpolation node) { |
5497 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 5510 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5573 visit(node.expression); | 5586 visit(node.expression); |
5574 HInstruction expression = pop(); | 5587 HInstruction expression = pop(); |
5575 pushInvokeStatic(node, helpers.streamIteratorConstructor, | 5588 pushInvokeStatic(node, helpers.streamIteratorConstructor, |
5576 [expression, graph.addConstantNull(compiler)]); | 5589 [expression, graph.addConstantNull(compiler)]); |
5577 streamIterator = pop(); | 5590 streamIterator = pop(); |
5578 | 5591 |
5579 void buildInitializer() {} | 5592 void buildInitializer() {} |
5580 | 5593 |
5581 HInstruction buildCondition() { | 5594 HInstruction buildCondition() { |
5582 Selector selector = Selectors.moveNext; | 5595 Selector selector = Selectors.moveNext; |
5583 TypeMask mask = inferenceResults.typeOfIteratorMoveNext(node, elements); | 5596 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
5584 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 5597 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
5585 HInstruction future = pop(); | 5598 HInstruction future = pop(); |
5586 push(new HAwait( | 5599 push(new HAwait( |
5587 future, | 5600 future, |
5588 new TypeMask.subclass( | 5601 new TypeMask.subclass( |
5589 coreClasses.objectClass, compiler.closedWorld))); | 5602 coreClasses.objectClass, compiler.closedWorld))); |
5590 return popBoolified(); | 5603 return popBoolified(); |
5591 } | 5604 } |
5592 | 5605 |
5593 void buildBody() { | 5606 void buildBody() { |
5594 Selector call = Selectors.current; | 5607 Selector call = Selectors.current; |
5595 TypeMask callMask = | 5608 TypeMask callMask = elementInferenceResults.typeOfIteratorCurrent(node); |
5596 inferenceResults.typeOfIteratorCurrent(node, elements); | |
5597 pushInvokeDynamic(node, call, callMask, [streamIterator]); | 5609 pushInvokeDynamic(node, call, callMask, [streamIterator]); |
5598 | 5610 |
5599 ast.Node identifier = node.declaredIdentifier; | 5611 ast.Node identifier = node.declaredIdentifier; |
5600 Element variable = elements.getForInVariable(node); | 5612 Element variable = elements.getForInVariable(node); |
5601 Selector selector = elements.getSelector(identifier); | 5613 Selector selector = elements.getSelector(identifier); |
5602 HInstruction value = pop(); | 5614 HInstruction value = pop(); |
5603 if (identifier.asSend() != null && | 5615 if (identifier.asSend() != null && |
5604 Elements.isInstanceSend(identifier, elements)) { | 5616 Elements.isInstanceSend(identifier, elements)) { |
5605 TypeMask mask = inferenceResults.typeOfSend(identifier, elements); | 5617 TypeMask mask = elementInferenceResults.typeOfSend(identifier); |
5606 HInstruction receiver = generateInstanceSendReceiver(identifier); | 5618 HInstruction receiver = generateInstanceSendReceiver(identifier); |
5607 assert(receiver != null); | 5619 assert(receiver != null); |
5608 generateInstanceSetterWithCompiledReceiver(null, receiver, value, | 5620 generateInstanceSetterWithCompiledReceiver(null, receiver, value, |
5609 selector: selector, mask: mask, location: identifier); | 5621 selector: selector, mask: mask, location: identifier); |
5610 } else { | 5622 } else { |
5611 generateNonInstanceSetter(null, variable, value, location: identifier); | 5623 generateNonInstanceSetter(null, variable, value, location: identifier); |
5612 } | 5624 } |
5613 pop(); // Pop the value pushed by the setter call. | 5625 pop(); // Pop the value pushed by the setter call. |
5614 | 5626 |
5615 visit(node.body); | 5627 visit(node.body); |
(...skipping 18 matching lines...) Expand all Loading... | |
5634 // The 'get iterator' selector for this node has the inferred receiver type. | 5646 // The 'get iterator' selector for this node has the inferred receiver type. |
5635 // If the receiver supports JavaScript indexing we generate an indexing loop | 5647 // If the receiver supports JavaScript indexing we generate an indexing loop |
5636 // instead of allocating an iterator object. | 5648 // instead of allocating an iterator object. |
5637 | 5649 |
5638 // This scheme recognizes for-in on direct lists. It does not recognize all | 5650 // This scheme recognizes for-in on direct lists. It does not recognize all |
5639 // uses of ArrayIterator. They still occur when the receiver is an Iterable | 5651 // uses of ArrayIterator. They still occur when the receiver is an Iterable |
5640 // with a `get iterator` method that delegates to another Iterable and the | 5652 // with a `get iterator` method that delegates to another Iterable and the |
5641 // method is inlined. We would require full scalar replacement in that | 5653 // method is inlined. We would require full scalar replacement in that |
5642 // case. | 5654 // case. |
5643 | 5655 |
5644 TypeMask mask = inferenceResults.typeOfIterator(node, elements); | 5656 TypeMask mask = elementInferenceResults.typeOfIterator(node); |
5645 | 5657 |
5646 ClosedWorld closedWorld = compiler.closedWorld; | 5658 ClosedWorld closedWorld = compiler.closedWorld; |
5647 if (mask != null && | 5659 if (mask != null && |
5648 mask.satisfies(helpers.jsIndexableClass, closedWorld) && | 5660 mask.satisfies(helpers.jsIndexableClass, closedWorld) && |
5649 // String is indexable but not iterable. | 5661 // String is indexable but not iterable. |
5650 !mask.satisfies(helpers.jsStringClass, closedWorld)) { | 5662 !mask.satisfies(helpers.jsStringClass, closedWorld)) { |
5651 return buildSyncForInIndexable(node, mask); | 5663 return buildSyncForInIndexable(node, mask); |
5652 } | 5664 } |
5653 buildSyncForInIterator(node); | 5665 buildSyncForInIterator(node); |
5654 } | 5666 } |
5655 | 5667 |
5656 buildSyncForInIterator(ast.SyncForIn node) { | 5668 buildSyncForInIterator(ast.SyncForIn node) { |
5657 // Generate a structure equivalent to: | 5669 // Generate a structure equivalent to: |
5658 // Iterator<E> $iter = <iterable>.iterator; | 5670 // Iterator<E> $iter = <iterable>.iterator; |
5659 // while ($iter.moveNext()) { | 5671 // while ($iter.moveNext()) { |
5660 // <declaredIdentifier> = $iter.current; | 5672 // <declaredIdentifier> = $iter.current; |
5661 // <body> | 5673 // <body> |
5662 // } | 5674 // } |
5663 | 5675 |
5664 // The iterator is shared between initializer, condition and body. | 5676 // The iterator is shared between initializer, condition and body. |
5665 HInstruction iterator; | 5677 HInstruction iterator; |
5666 | 5678 |
5667 void buildInitializer() { | 5679 void buildInitializer() { |
5668 Selector selector = Selectors.iterator; | 5680 Selector selector = Selectors.iterator; |
5669 TypeMask mask = inferenceResults.typeOfIterator(node, elements); | 5681 TypeMask mask = elementInferenceResults.typeOfIterator(node); |
5670 visit(node.expression); | 5682 visit(node.expression); |
5671 HInstruction receiver = pop(); | 5683 HInstruction receiver = pop(); |
5672 pushInvokeDynamic(node, selector, mask, [receiver]); | 5684 pushInvokeDynamic(node, selector, mask, [receiver]); |
5673 iterator = pop(); | 5685 iterator = pop(); |
5674 } | 5686 } |
5675 | 5687 |
5676 HInstruction buildCondition() { | 5688 HInstruction buildCondition() { |
5677 Selector selector = Selectors.moveNext; | 5689 Selector selector = Selectors.moveNext; |
5678 TypeMask mask = inferenceResults.typeOfIteratorMoveNext(node, elements); | 5690 TypeMask mask = elementInferenceResults.typeOfIteratorMoveNext(node); |
5679 pushInvokeDynamic(node, selector, mask, [iterator]); | 5691 pushInvokeDynamic(node, selector, mask, [iterator]); |
5680 return popBoolified(); | 5692 return popBoolified(); |
5681 } | 5693 } |
5682 | 5694 |
5683 void buildBody() { | 5695 void buildBody() { |
5684 Selector call = Selectors.current; | 5696 Selector call = Selectors.current; |
5685 TypeMask mask = inferenceResults.typeOfIteratorCurrent(node, elements); | 5697 TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node); |
5686 pushInvokeDynamic(node, call, mask, [iterator]); | 5698 pushInvokeDynamic(node, call, mask, [iterator]); |
5687 buildAssignLoopVariable(node, pop()); | 5699 buildAssignLoopVariable(node, pop()); |
5688 visit(node.body); | 5700 visit(node.body); |
5689 } | 5701 } |
5690 | 5702 |
5691 loopHandler.handleLoop( | 5703 loopHandler.handleLoop( |
5692 node, buildInitializer, buildCondition, () {}, buildBody); | 5704 node, buildInitializer, buildCondition, () {}, buildBody); |
5693 } | 5705 } |
5694 | 5706 |
5695 buildAssignLoopVariable(ast.ForIn node, HInstruction value) { | 5707 buildAssignLoopVariable(ast.ForIn node, HInstruction value) { |
5696 ast.Node identifier = node.declaredIdentifier; | 5708 ast.Node identifier = node.declaredIdentifier; |
5697 Element variable = elements.getForInVariable(node); | 5709 Element variable = elements.getForInVariable(node); |
5698 Selector selector = elements.getSelector(identifier); | 5710 Selector selector = elements.getSelector(identifier); |
5699 | 5711 |
5700 if (identifier.asSend() != null && | 5712 if (identifier.asSend() != null && |
5701 Elements.isInstanceSend(identifier, elements)) { | 5713 Elements.isInstanceSend(identifier, elements)) { |
5702 TypeMask mask = inferenceResults.typeOfSend(identifier, elements); | 5714 TypeMask mask = elementInferenceResults.typeOfSend(identifier); |
5703 HInstruction receiver = generateInstanceSendReceiver(identifier); | 5715 HInstruction receiver = generateInstanceSendReceiver(identifier); |
5704 assert(receiver != null); | 5716 assert(receiver != null); |
5705 generateInstanceSetterWithCompiledReceiver(null, receiver, value, | 5717 generateInstanceSetterWithCompiledReceiver(null, receiver, value, |
5706 selector: selector, mask: mask, location: identifier); | 5718 selector: selector, mask: mask, location: identifier); |
5707 } else { | 5719 } else { |
5708 generateNonInstanceSetter(null, variable, value, location: identifier); | 5720 generateNonInstanceSetter(null, variable, value, location: identifier); |
5709 } | 5721 } |
5710 pop(); // Discard the value pushed by the setter call. | 5722 pop(); // Discard the value pushed by the setter call. |
5711 } | 5723 } |
5712 | 5724 |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6631 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments, | 6643 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments, |
6632 {InterfaceType instanceType}) { | 6644 {InterfaceType instanceType}) { |
6633 AstInliningState state = new AstInliningState( | 6645 AstInliningState state = new AstInliningState( |
6634 function, | 6646 function, |
6635 returnLocal, | 6647 returnLocal, |
6636 returnType, | 6648 returnType, |
6637 resolvedAst, | 6649 resolvedAst, |
6638 stack, | 6650 stack, |
6639 localsHandler, | 6651 localsHandler, |
6640 inTryStatement, | 6652 inTryStatement, |
6641 allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function)); | 6653 isCalledOnce(function), |
Johnni Winther
2016/11/03 08:50:21
Reinsert the transfer of the `allInlinedFunctionsC
Siggi Cherem (dart-lang)
2016/11/03 21:12:15
Note that I replaced "isFunctionCalledOnce" with "
Johnni Winther
2016/11/04 07:30:52
Acknowledged.
| |
6654 elementInferenceResults); | |
6642 resolvedAst = functionResolvedAst; | 6655 resolvedAst = functionResolvedAst; |
6656 elementInferenceResults = inferenceResults.resultOf(function); | |
6643 inliningStack.add(state); | 6657 inliningStack.add(state); |
6644 | 6658 |
6645 // Setting up the state of the (AST) builder is performed even when the | 6659 // Setting up the state of the (AST) builder is performed even when the |
6646 // inlined function is in IR, because the irInliner uses the [returnElement] | 6660 // inlined function is in IR, because the irInliner uses the [returnElement] |
6647 // of the AST builder. | 6661 // of the AST builder. |
6648 setupStateForInlining(function, compiledArguments, | 6662 setupStateForInlining(function, compiledArguments, |
6649 instanceType: instanceType); | 6663 instanceType: instanceType); |
6650 } | 6664 } |
6651 | 6665 |
6652 void leaveInlinedMethod() { | 6666 void leaveInlinedMethod() { |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6953 } | 6967 } |
6954 | 6968 |
6955 class AstInliningState extends InliningState { | 6969 class AstInliningState extends InliningState { |
6956 final Local oldReturnLocal; | 6970 final Local oldReturnLocal; |
6957 final DartType oldReturnType; | 6971 final DartType oldReturnType; |
6958 final ResolvedAst oldResolvedAst; | 6972 final ResolvedAst oldResolvedAst; |
6959 final List<HInstruction> oldStack; | 6973 final List<HInstruction> oldStack; |
6960 final LocalsHandler oldLocalsHandler; | 6974 final LocalsHandler oldLocalsHandler; |
6961 final bool inTryStatement; | 6975 final bool inTryStatement; |
6962 final bool allFunctionsCalledOnce; | 6976 final bool allFunctionsCalledOnce; |
6977 final GlobalTypeInferenceElementResult oldElementInferenceResults; | |
6963 | 6978 |
6964 AstInliningState( | 6979 AstInliningState( |
6965 FunctionElement function, | 6980 FunctionElement function, |
6966 this.oldReturnLocal, | 6981 this.oldReturnLocal, |
6967 this.oldReturnType, | 6982 this.oldReturnType, |
6968 this.oldResolvedAst, | 6983 this.oldResolvedAst, |
6969 this.oldStack, | 6984 this.oldStack, |
6970 this.oldLocalsHandler, | 6985 this.oldLocalsHandler, |
6971 this.inTryStatement, | 6986 this.inTryStatement, |
6972 this.allFunctionsCalledOnce) | 6987 this.allFunctionsCalledOnce, |
6988 this.oldElementInferenceResults) | |
6973 : super(function); | 6989 : super(function); |
6974 } | 6990 } |
6975 | 6991 |
6976 class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> { | 6992 class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> { |
6977 final ClosedWorld closedWorld; | 6993 final ClosedWorld closedWorld; |
6978 | 6994 |
6979 TypeBuilder(this.closedWorld); | 6995 TypeBuilder(this.closedWorld); |
6980 | 6996 |
6981 void visit(DartType type, SsaBuilder builder) => type.accept(this, builder); | 6997 void visit(DartType type, SsaBuilder builder) => type.accept(this, builder); |
6982 | 6998 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7056 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7072 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
7057 unaliased.accept(this, builder); | 7073 unaliased.accept(this, builder); |
7058 } | 7074 } |
7059 | 7075 |
7060 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7076 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
7061 JavaScriptBackend backend = builder.compiler.backend; | 7077 JavaScriptBackend backend = builder.compiler.backend; |
7062 ClassElement cls = backend.helpers.DynamicRuntimeType; | 7078 ClassElement cls = backend.helpers.DynamicRuntimeType; |
7063 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); | 7079 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); |
7064 } | 7080 } |
7065 } | 7081 } |
OLD | NEW |