| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 /// Registry used to enqueue work during codegen, may be null to avoid | 138 /// Registry used to enqueue work during codegen, may be null to avoid |
| 139 /// enqueing any work. | 139 /// enqueing any work. |
| 140 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be | 140 // TODO(sigmund,johnniwinther): get rid of registry entirely. We should be |
| 141 // able to return the impact as a result after building and avoid enqueing | 141 // able to return the impact as a result after building and avoid enqueing |
| 142 // things here. Later the codegen task can decide whether to enqueue | 142 // things here. Later the codegen task can decide whether to enqueue |
| 143 // something. In the past this didn't matter as much because the SSA graph was | 143 // something. In the past this didn't matter as much because the SSA graph was |
| 144 // used only for codegen, but currently we want to experiment using it for | 144 // used only for codegen, but currently we want to experiment using it for |
| 145 // code-analysis too. | 145 // code-analysis too. |
| 146 final CodegenRegistry registry; | 146 final CodegenRegistry registry; |
| 147 | 147 |
| 148 /// All results from the global type-inference analysis. | |
| 149 final GlobalTypeInferenceResults inferenceResults; | |
| 150 | |
| 151 /// Results from the global type-inference analysis corresponding to the | 148 /// Results from the global type-inference analysis corresponding to the |
| 152 /// current element being visited. | 149 /// current element being visited. |
| 153 /// | 150 /// |
| 154 /// Invariant: this property is updated together with [resolvedAst]. | 151 /// Invariant: this property is updated together with [resolvedAst]. |
| 155 GlobalTypeInferenceElementResult elementInferenceResults; | 152 GlobalTypeInferenceElementResult elementInferenceResults; |
| 156 | 153 |
| 157 final JavaScriptBackend backend; | 154 final JavaScriptBackend backend; |
| 158 final ConstantSystem constantSystem; | 155 final ConstantSystem constantSystem; |
| 159 final RuntimeTypesSubstitutions rtiSubstitutions; | 156 final RuntimeTypesSubstitutions rtiSubstitutions; |
| 160 | 157 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 this.target, | 195 this.target, |
| 199 this.resolvedAst, | 196 this.resolvedAst, |
| 200 this.registry, | 197 this.registry, |
| 201 JavaScriptBackend backend, | 198 JavaScriptBackend backend, |
| 202 this.closedWorld, | 199 this.closedWorld, |
| 203 this.nativeEmitter, | 200 this.nativeEmitter, |
| 204 SourceInformationStrategy sourceInformationFactory) | 201 SourceInformationStrategy sourceInformationFactory) |
| 205 : this.infoReporter = backend.compiler.dumpInfoTask, | 202 : this.infoReporter = backend.compiler.dumpInfoTask, |
| 206 this.backend = backend, | 203 this.backend = backend, |
| 207 this.constantSystem = backend.constantSystem, | 204 this.constantSystem = backend.constantSystem, |
| 208 this.rtiSubstitutions = backend.rtiSubstitutions, | 205 this.rtiSubstitutions = backend.rtiSubstitutions { |
| 209 this.inferenceResults = backend.compiler.globalInference.results { | |
| 210 assert(target.isImplementation); | 206 assert(target.isImplementation); |
| 211 compiler = backend.compiler; | 207 compiler = backend.compiler; |
| 212 elementInferenceResults = _resultOf(target); | 208 elementInferenceResults = _resultOf(target); |
| 213 assert(elementInferenceResults != null); | 209 assert(elementInferenceResults != null); |
| 214 graph.element = target; | 210 graph.element = target; |
| 215 sourceElementStack.add(target); | 211 sourceElementStack.add(target); |
| 216 sourceInformationBuilder = | 212 sourceInformationBuilder = |
| 217 sourceInformationFactory.createBuilderForContext(resolvedAst); | 213 sourceInformationFactory.createBuilderForContext(resolvedAst); |
| 218 graph.sourceInformation = | 214 graph.sourceInformation = |
| 219 sourceInformationBuilder.buildVariableDeclaration(); | 215 sourceInformationBuilder.buildVariableDeclaration(); |
| 220 localsHandler = new LocalsHandler(this, target, null, compiler); | 216 localsHandler = new LocalsHandler( |
| 217 this, target, null, backend.nativeData, backend.interceptorData); |
| 221 loopHandler = new SsaLoopHandler(this); | 218 loopHandler = new SsaLoopHandler(this); |
| 222 typeBuilder = new TypeBuilder(this); | 219 typeBuilder = new TypeBuilder(this); |
| 223 } | 220 } |
| 224 | 221 |
| 225 BackendHelpers get helpers => backend.helpers; | 222 BackendHelpers get helpers => backend.helpers; |
| 226 | 223 |
| 227 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 224 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
| 228 | 225 |
| 229 Element get targetElement => target; | 226 Element get targetElement => target; |
| 230 | 227 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 253 MemberElement get sourceElement => sourceElementStack.last; | 250 MemberElement get sourceElement => sourceElementStack.last; |
| 254 | 251 |
| 255 /// Helper to retrieve global inference results for [element] with special | 252 /// Helper to retrieve global inference results for [element] with special |
| 256 /// care for `ConstructorBodyElement`s which don't exist at the time the | 253 /// care for `ConstructorBodyElement`s which don't exist at the time the |
| 257 /// global analysis run. | 254 /// global analysis run. |
| 258 /// | 255 /// |
| 259 /// Note: this helper is used selectively. When we know that we are in a | 256 /// Note: this helper is used selectively. When we know that we are in a |
| 260 /// context were we don't expect to see a constructor body element, we | 257 /// context were we don't expect to see a constructor body element, we |
| 261 /// directly fetch the data from the global inference results. | 258 /// directly fetch the data from the global inference results. |
| 262 GlobalTypeInferenceElementResult _resultOf(MemberElement element) => | 259 GlobalTypeInferenceElementResult _resultOf(MemberElement element) => |
| 263 inferenceResults.resultOfMember( | 260 globalInferenceResults.resultOfMember( |
| 264 element is ConstructorBodyElementX ? element.constructor : element); | 261 element is ConstructorBodyElementX ? element.constructor : element); |
| 265 | 262 |
| 266 /// Build the graph for [target]. | 263 /// Build the graph for [target]. |
| 267 HGraph build() { | 264 HGraph build() { |
| 268 assert(invariant(target, target.isImplementation)); | 265 assert(invariant(target, target.isImplementation)); |
| 269 HInstruction.idCounter = 0; | 266 HInstruction.idCounter = 0; |
| 270 // TODO(sigmund): remove `result` and return graph directly, need to ensure | 267 // TODO(sigmund): remove `result` and return graph directly, need to ensure |
| 271 // that it can never be null (see result in buildFactory for instance). | 268 // that it can never be null (see result in buildFactory for instance). |
| 272 var result; | 269 var result; |
| 273 if (target.isGenerativeConstructor) { | 270 if (target.isGenerativeConstructor) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 // Generative constructors of native classes should not be called directly | 447 // Generative constructors of native classes should not be called directly |
| 451 // and have an extra argument that causes problems with inlining. | 448 // and have an extra argument that causes problems with inlining. |
| 452 if (function.isGenerativeConstructor && | 449 if (function.isGenerativeConstructor && |
| 453 backend.nativeData.isNativeOrExtendsNative(function.enclosingClass)) { | 450 backend.nativeData.isNativeOrExtendsNative(function.enclosingClass)) { |
| 454 return false; | 451 return false; |
| 455 } | 452 } |
| 456 | 453 |
| 457 // A generative constructor body is not seen by global analysis, | 454 // A generative constructor body is not seen by global analysis, |
| 458 // so we should not query for its type. | 455 // so we should not query for its type. |
| 459 if (!function.isGenerativeConstructorBody) { | 456 if (!function.isGenerativeConstructorBody) { |
| 460 if (inferenceResults.resultOfMember(function).throwsAlways) { | 457 if (globalInferenceResults.resultOfMember(function).throwsAlways) { |
| 461 isReachable = false; | 458 isReachable = false; |
| 462 return false; | 459 return false; |
| 463 } | 460 } |
| 464 } | 461 } |
| 465 | 462 |
| 466 return true; | 463 return true; |
| 467 } | 464 } |
| 468 | 465 |
| 469 bool doesNotContainCode() { | 466 bool doesNotContainCode() { |
| 470 // A function with size 1 does not contain any code. | 467 // A function with size 1 does not contain any code. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 return false; | 581 return false; |
| 585 } | 582 } |
| 586 | 583 |
| 587 bool get allInlinedFunctionsCalledOnce { | 584 bool get allInlinedFunctionsCalledOnce { |
| 588 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; | 585 return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce; |
| 589 } | 586 } |
| 590 | 587 |
| 591 bool isFunctionCalledOnce(MethodElement element) { | 588 bool isFunctionCalledOnce(MethodElement element) { |
| 592 // ConstructorBodyElements are not in the type inference graph. | 589 // ConstructorBodyElements are not in the type inference graph. |
| 593 if (element is ConstructorBodyElement) return false; | 590 if (element is ConstructorBodyElement) return false; |
| 594 return inferenceResults.resultOfMember(element).isCalledOnce; | 591 return globalInferenceResults.resultOfMember(element).isCalledOnce; |
| 595 } | 592 } |
| 596 | 593 |
| 597 bool isCalledOnce(MethodElement element) { | 594 bool isCalledOnce(MethodElement element) { |
| 598 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); | 595 return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element); |
| 599 } | 596 } |
| 600 | 597 |
| 601 inlinedFrom(ResolvedAst resolvedAst, f()) { | 598 inlinedFrom(ResolvedAst resolvedAst, f()) { |
| 602 MemberElement element = resolvedAst.element; | 599 MemberElement element = resolvedAst.element; |
| 603 assert(element is FunctionElement || element is VariableElement); | 600 assert(element is FunctionElement || element is VariableElement); |
| 604 return reporter.withCurrentElement(element.implementation, () { | 601 return reporter.withCurrentElement(element.implementation, () { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 * When inlining a function, [:return:] statements are not emitted as | 788 * When inlining a function, [:return:] statements are not emitted as |
| 792 * [HReturn] instructions. Instead, the value of a synthetic element is | 789 * [HReturn] instructions. Instead, the value of a synthetic element is |
| 793 * updated in the [localsHandler]. This function creates such an element and | 790 * updated in the [localsHandler]. This function creates such an element and |
| 794 * stores it in the [returnLocal] field. | 791 * stores it in the [returnLocal] field. |
| 795 */ | 792 */ |
| 796 void setupStateForInlining( | 793 void setupStateForInlining( |
| 797 FunctionElement function, List<HInstruction> compiledArguments, | 794 FunctionElement function, List<HInstruction> compiledArguments, |
| 798 {ResolutionInterfaceType instanceType}) { | 795 {ResolutionInterfaceType instanceType}) { |
| 799 ResolvedAst resolvedAst = function.resolvedAst; | 796 ResolvedAst resolvedAst = function.resolvedAst; |
| 800 assert(resolvedAst != null); | 797 assert(resolvedAst != null); |
| 801 localsHandler = new LocalsHandler(this, function, instanceType, compiler); | 798 localsHandler = new LocalsHandler(this, function, instanceType, |
| 799 backend.nativeData, backend.interceptorData); |
| 802 localsHandler.closureData = | 800 localsHandler.closureData = |
| 803 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 801 closureToClassMapper.getClosureToClassMapping(resolvedAst); |
| 804 returnLocal = new SyntheticLocal("result", function); | 802 returnLocal = new SyntheticLocal("result", function); |
| 805 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); | 803 localsHandler.updateLocal(returnLocal, graph.addConstantNull(closedWorld)); |
| 806 | 804 |
| 807 inTryStatement = false; // TODO(lry): why? Document. | 805 inTryStatement = false; // TODO(lry): why? Document. |
| 808 | 806 |
| 809 int argumentIndex = 0; | 807 int argumentIndex = 0; |
| 810 if (function.isInstanceMember) { | 808 if (function.isInstanceMember) { |
| 811 localsHandler.updateLocal(localsHandler.closureData.thisLocal, | 809 localsHandler.updateLocal(localsHandler.closureData.thisLocal, |
| 812 compiledArguments[argumentIndex++]); | 810 compiledArguments[argumentIndex++]); |
| 813 } | 811 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 if (parameter.isInitializingFormal) { | 955 if (parameter.isInitializingFormal) { |
| 958 InitializingFormalElement fieldParameterElement = parameter; | 956 InitializingFormalElement fieldParameterElement = parameter; |
| 959 fieldValues[fieldParameterElement.fieldElement] = argument; | 957 fieldValues[fieldParameterElement.fieldElement] = argument; |
| 960 } | 958 } |
| 961 }); | 959 }); |
| 962 | 960 |
| 963 // Build the initializers in the context of the new constructor. | 961 // Build the initializers in the context of the new constructor. |
| 964 ResolvedAst oldResolvedAst = resolvedAst; | 962 ResolvedAst oldResolvedAst = resolvedAst; |
| 965 resolvedAst = callee.resolvedAst; | 963 resolvedAst = callee.resolvedAst; |
| 966 final oldElementInferenceResults = elementInferenceResults; | 964 final oldElementInferenceResults = elementInferenceResults; |
| 967 elementInferenceResults = inferenceResults.resultOfMember(callee); | 965 elementInferenceResults = globalInferenceResults.resultOfMember(callee); |
| 968 ClosureClassMap oldClosureData = localsHandler.closureData; | 966 ClosureClassMap oldClosureData = localsHandler.closureData; |
| 969 ClosureClassMap newClosureData = | 967 ClosureClassMap newClosureData = |
| 970 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 968 closureToClassMapper.getClosureToClassMapping(resolvedAst); |
| 971 localsHandler.closureData = newClosureData; | 969 localsHandler.closureData = newClosureData; |
| 972 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 970 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
| 973 localsHandler.enterScope(resolvedAst.node, callee); | 971 localsHandler.enterScope(resolvedAst.node, callee); |
| 974 } | 972 } |
| 975 buildInitializers(callee, constructorResolvedAsts, fieldValues); | 973 buildInitializers(callee, constructorResolvedAsts, fieldValues); |
| 976 localsHandler.closureData = oldClosureData; | 974 localsHandler.closureData = oldClosureData; |
| 977 resolvedAst = oldResolvedAst; | 975 resolvedAst = oldResolvedAst; |
| 978 elementInferenceResults = oldElementInferenceResults; | 976 elementInferenceResults = oldElementInferenceResults; |
| 979 }); | 977 }); |
| 980 } | 978 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 // Unassigned fields of native classes are not initialized to | 1130 // Unassigned fields of native classes are not initialized to |
| 1133 // prevent overwriting pre-initialized native properties. | 1131 // prevent overwriting pre-initialized native properties. |
| 1134 if (!backend.nativeData.isNativeOrExtendsNative(classElement)) { | 1132 if (!backend.nativeData.isNativeOrExtendsNative(classElement)) { |
| 1135 fieldValues[member] = graph.addConstantNull(closedWorld); | 1133 fieldValues[member] = graph.addConstantNull(closedWorld); |
| 1136 } | 1134 } |
| 1137 } else { | 1135 } else { |
| 1138 ast.Node right = initializer; | 1136 ast.Node right = initializer; |
| 1139 ResolvedAst savedResolvedAst = resolvedAst; | 1137 ResolvedAst savedResolvedAst = resolvedAst; |
| 1140 resolvedAst = fieldResolvedAst; | 1138 resolvedAst = fieldResolvedAst; |
| 1141 final oldElementInferenceResults = elementInferenceResults; | 1139 final oldElementInferenceResults = elementInferenceResults; |
| 1142 elementInferenceResults = inferenceResults.resultOfMember(member); | 1140 elementInferenceResults = |
| 1141 globalInferenceResults.resultOfMember(member); |
| 1143 // In case the field initializer uses closures, run the | 1142 // In case the field initializer uses closures, run the |
| 1144 // closure to class mapper. | 1143 // closure to class mapper. |
| 1145 compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst); | 1144 closureToClassMapper.getClosureToClassMapping(resolvedAst); |
| 1146 inlinedFrom(fieldResolvedAst, () => right.accept(this)); | 1145 inlinedFrom(fieldResolvedAst, () => right.accept(this)); |
| 1147 resolvedAst = savedResolvedAst; | 1146 resolvedAst = savedResolvedAst; |
| 1148 elementInferenceResults = oldElementInferenceResults; | 1147 elementInferenceResults = oldElementInferenceResults; |
| 1149 fieldValues[member] = pop(); | 1148 fieldValues[member] = pop(); |
| 1150 } | 1149 } |
| 1151 }); | 1150 }); |
| 1152 }); | 1151 }); |
| 1153 } | 1152 } |
| 1154 | 1153 |
| 1155 /** | 1154 /** |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1297 List bodyCallInputs = <HInstruction>[]; | 1296 List bodyCallInputs = <HInstruction>[]; |
| 1298 if (isNativeUpgradeFactory) { | 1297 if (isNativeUpgradeFactory) { |
| 1299 if (interceptor == null) { | 1298 if (interceptor == null) { |
| 1300 ConstantValue constant = new InterceptorConstantValue(classElement); | 1299 ConstantValue constant = new InterceptorConstantValue(classElement); |
| 1301 interceptor = graph.addConstant(constant, closedWorld); | 1300 interceptor = graph.addConstant(constant, closedWorld); |
| 1302 } | 1301 } |
| 1303 bodyCallInputs.add(interceptor); | 1302 bodyCallInputs.add(interceptor); |
| 1304 } | 1303 } |
| 1305 bodyCallInputs.add(newObject); | 1304 bodyCallInputs.add(newObject); |
| 1306 ast.Node node = constructorResolvedAst.node; | 1305 ast.Node node = constructorResolvedAst.node; |
| 1307 ClosureClassMap parameterClosureData = compiler.closureToClassMapper | 1306 ClosureClassMap parameterClosureData = |
| 1308 .getClosureToClassMapping(constructorResolvedAst); | 1307 closureToClassMapper.getClosureToClassMapping(constructorResolvedAst); |
| 1309 | 1308 |
| 1310 FunctionSignature functionSignature = body.functionSignature; | 1309 FunctionSignature functionSignature = body.functionSignature; |
| 1311 // Provide the parameters to the generative constructor body. | 1310 // Provide the parameters to the generative constructor body. |
| 1312 functionSignature.orderedForEachParameter((ParameterElement parameter) { | 1311 functionSignature.orderedForEachParameter((ParameterElement parameter) { |
| 1313 // If [parameter] is boxed, it will be a field in the box passed as the | 1312 // If [parameter] is boxed, it will be a field in the box passed as the |
| 1314 // last parameter. So no need to directly pass it. | 1313 // last parameter. So no need to directly pass it. |
| 1315 if (!localsHandler.isBoxed(parameter)) { | 1314 if (!localsHandler.isBoxed(parameter)) { |
| 1316 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1315 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| 1317 } | 1316 } |
| 1318 }); | 1317 }); |
| (...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2988 // Until now we only handle these as getters. | 2987 // Until now we only handle these as getters. |
| 2989 invariant(node, deferredLoader.isDeferredLoaderGetter); | 2988 invariant(node, deferredLoader.isDeferredLoaderGetter); |
| 2990 FunctionEntity loadFunction = helpers.loadLibraryWrapper; | 2989 FunctionEntity loadFunction = helpers.loadLibraryWrapper; |
| 2991 PrefixElement prefixElement = deferredLoader.enclosingElement; | 2990 PrefixElement prefixElement = deferredLoader.enclosingElement; |
| 2992 String loadId = | 2991 String loadId = |
| 2993 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); | 2992 compiler.deferredLoadTask.getImportDeferName(node, prefixElement); |
| 2994 var inputs = [ | 2993 var inputs = [ |
| 2995 graph.addConstantString(new ast.DartString.literal(loadId), closedWorld) | 2994 graph.addConstantString(new ast.DartString.literal(loadId), closedWorld) |
| 2996 ]; | 2995 ]; |
| 2997 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, | 2996 push(new HInvokeStatic(loadFunction, inputs, commonMasks.nonNullType, |
| 2998 targetCanThrow: false)..sourceInformation = sourceInformation); | 2997 targetCanThrow: false) |
| 2998 ..sourceInformation = sourceInformation); |
| 2999 } | 2999 } |
| 3000 | 3000 |
| 3001 generateSuperNoSuchMethodSend( | 3001 generateSuperNoSuchMethodSend( |
| 3002 ast.Send node, Selector selector, List<HInstruction> arguments) { | 3002 ast.Send node, Selector selector, List<HInstruction> arguments) { |
| 3003 String name = selector.name; | 3003 String name = selector.name; |
| 3004 | 3004 |
| 3005 ClassElement cls = currentNonClosureClass; | 3005 ClassElement cls = currentNonClosureClass; |
| 3006 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 3006 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
| 3007 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 3007 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
| 3008 ClassElement objectClass = commonElements.objectClass; | 3008 ClassElement objectClass = commonElements.objectClass; |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3424 var constant = inputs[0]; | 3424 var constant = inputs[0]; |
| 3425 int value = constant.constant.primitiveValue; | 3425 int value = constant.constant.primitiveValue; |
| 3426 if (0 <= value && value < 0x100000000) canThrow = false; | 3426 if (0 <= value && value < 0x100000000) canThrow = false; |
| 3427 } | 3427 } |
| 3428 HForeignCode foreign = new HForeignCode(code, elementType, inputs, | 3428 HForeignCode foreign = new HForeignCode(code, elementType, inputs, |
| 3429 nativeBehavior: behavior, | 3429 nativeBehavior: behavior, |
| 3430 throwBehavior: canThrow | 3430 throwBehavior: canThrow |
| 3431 ? native.NativeThrowBehavior.MAY | 3431 ? native.NativeThrowBehavior.MAY |
| 3432 : native.NativeThrowBehavior.NEVER); | 3432 : native.NativeThrowBehavior.NEVER); |
| 3433 push(foreign); | 3433 push(foreign); |
| 3434 if (inferenceResults.isFixedArrayCheckedForGrowable(send)) { | 3434 if (globalInferenceResults.isFixedArrayCheckedForGrowable(send)) { |
| 3435 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); | 3435 js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array'); |
| 3436 // We set the instruction as [canThrow] to avoid it being dead code. | 3436 // We set the instruction as [canThrow] to avoid it being dead code. |
| 3437 // We need a finer grained side effect. | 3437 // We need a finer grained side effect. |
| 3438 add(new HForeignCode(code, commonMasks.nullType, [stack.last], | 3438 add(new HForeignCode(code, commonMasks.nullType, [stack.last], |
| 3439 throwBehavior: native.NativeThrowBehavior.MAY)); | 3439 throwBehavior: native.NativeThrowBehavior.MAY)); |
| 3440 } | 3440 } |
| 3441 } else if (isGrowableListConstructorCall) { | 3441 } else if (isGrowableListConstructorCall) { |
| 3442 push(buildLiteralList(<HInstruction>[])); | 3442 push(buildLiteralList(<HInstruction>[])); |
| 3443 stack.last.instructionType = elementType; | 3443 stack.last.instructionType = elementType; |
| 3444 } else { | 3444 } else { |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4089 } else if (element.isSetter) { | 4089 } else if (element.isSetter) { |
| 4090 code = "# = #"; | 4090 code = "# = #"; |
| 4091 } else { | 4091 } else { |
| 4092 var args = new List.filled(arguments.length, '#').join(','); | 4092 var args = new List.filled(arguments.length, '#').join(','); |
| 4093 code = element.isConstructor ? "new #($args)" : "#($args)"; | 4093 code = element.isConstructor ? "new #($args)" : "#($args)"; |
| 4094 } | 4094 } |
| 4095 js.Template codeTemplate = js.js.parseForeignJS(code); | 4095 js.Template codeTemplate = js.js.parseForeignJS(code); |
| 4096 nativeBehavior.codeTemplate = codeTemplate; | 4096 nativeBehavior.codeTemplate = codeTemplate; |
| 4097 | 4097 |
| 4098 return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs, | 4098 return new HForeignCode(codeTemplate, commonMasks.dynamicType, inputs, |
| 4099 nativeBehavior: nativeBehavior)..sourceInformation = sourceInformation; | 4099 nativeBehavior: nativeBehavior) |
| 4100 ..sourceInformation = sourceInformation; |
| 4100 } | 4101 } |
| 4101 | 4102 |
| 4102 void pushInvokeStatic( | 4103 void pushInvokeStatic( |
| 4103 ast.Node location, MethodElement element, List<HInstruction> arguments, | 4104 ast.Node location, MethodElement element, List<HInstruction> arguments, |
| 4104 {TypeMask typeMask, | 4105 {TypeMask typeMask, |
| 4105 ResolutionInterfaceType instanceType, | 4106 ResolutionInterfaceType instanceType, |
| 4106 SourceInformation sourceInformation}) { | 4107 SourceInformation sourceInformation}) { |
| 4107 assert(element.isDeclaration); | 4108 assert(element.isDeclaration); |
| 4108 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. | 4109 // TODO(johnniwinther): Use [sourceInformation] instead of [location]. |
| 4109 if (tryInlineMethod(element, null, null, arguments, location, | 4110 if (tryInlineMethod(element, null, null, arguments, location, |
| (...skipping 2644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6754 this.oldReturnLocal, | 6755 this.oldReturnLocal, |
| 6755 this.oldReturnType, | 6756 this.oldReturnType, |
| 6756 this.oldResolvedAst, | 6757 this.oldResolvedAst, |
| 6757 this.oldStack, | 6758 this.oldStack, |
| 6758 this.oldLocalsHandler, | 6759 this.oldLocalsHandler, |
| 6759 this.inTryStatement, | 6760 this.inTryStatement, |
| 6760 this.allFunctionsCalledOnce, | 6761 this.allFunctionsCalledOnce, |
| 6761 this.oldElementInferenceResults) | 6762 this.oldElementInferenceResults) |
| 6762 : super(function); | 6763 : super(function); |
| 6763 } | 6764 } |
| OLD | NEW |