Chromium Code Reviews| 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 |