| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 final SsaCodeGeneratorTask generator; | 8 final SsaCodeGeneratorTask generator; |
| 9 final SsaBuilderTask builder; | 9 final SsaBuilderTask builder; |
| 10 final SsaOptimizerTask optimizer; | 10 final SsaOptimizerTask optimizer; |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 this.rti = backend.rti, | 1100 this.rti = backend.rti, |
| 1101 this.elements = work.resolutionTree { | 1101 this.elements = work.resolutionTree { |
| 1102 graph.element = work.element; | 1102 graph.element = work.element; |
| 1103 localsHandler = new LocalsHandler(this, work.element, null); | 1103 localsHandler = new LocalsHandler(this, work.element, null); |
| 1104 sourceElementStack.add(work.element); | 1104 sourceElementStack.add(work.element); |
| 1105 sourceInformationBuilder = | 1105 sourceInformationBuilder = |
| 1106 sourceInformationFactory.createBuilderForContext( | 1106 sourceInformationFactory.createBuilderForContext( |
| 1107 work.element.implementation); | 1107 work.element.implementation); |
| 1108 } | 1108 } |
| 1109 | 1109 |
| 1110 BackendHelpers get helpers => backend.helpers; |
| 1110 | 1111 |
| 1111 DiagnosticReporter get reporter => compiler.reporter; | 1112 DiagnosticReporter get reporter => compiler.reporter; |
| 1112 | 1113 |
| 1113 // TODO(johnniwinther): Avoid the need for this. | 1114 // TODO(johnniwinther): Avoid the need for this. |
| 1114 Resolution get resolution => compiler.resolution; | 1115 Resolution get resolution => compiler.resolution; |
| 1115 | 1116 |
| 1116 @override | 1117 @override |
| 1117 SemanticSendVisitor get sendVisitor => this; | 1118 SemanticSendVisitor get sendVisitor => this; |
| 1118 | 1119 |
| 1119 @override | 1120 @override |
| (...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2233 /// Helper to identify instructions that read a type variable without | 2234 /// Helper to identify instructions that read a type variable without |
| 2234 /// substitution (that is, directly use the index). These instructions | 2235 /// substitution (that is, directly use the index). These instructions |
| 2235 /// are of the form: | 2236 /// are of the form: |
| 2236 /// HInvokeStatic(getTypeArgumentByIndex, this, index) | 2237 /// HInvokeStatic(getTypeArgumentByIndex, this, index) |
| 2237 /// | 2238 /// |
| 2238 /// Return `true` if [instruction] is of that form and the index is the | 2239 /// Return `true` if [instruction] is of that form and the index is the |
| 2239 /// next index in the sequence (held in [expectedIndex]). | 2240 /// next index in the sequence (held in [expectedIndex]). |
| 2240 bool isIndexedTypeArgumentGet(HInstruction instruction) { | 2241 bool isIndexedTypeArgumentGet(HInstruction instruction) { |
| 2241 if (instruction is! HInvokeStatic) return false; | 2242 if (instruction is! HInvokeStatic) return false; |
| 2242 HInvokeStatic invoke = instruction; | 2243 HInvokeStatic invoke = instruction; |
| 2243 if (invoke.element != backend.getGetTypeArgumentByIndex()) { | 2244 if (invoke.element != helpers.getTypeArgumentByIndex) { |
| 2244 return false; | 2245 return false; |
| 2245 } | 2246 } |
| 2246 HConstant index = invoke.inputs[1]; | 2247 HConstant index = invoke.inputs[1]; |
| 2247 HInstruction newSource = invoke.inputs[0]; | 2248 HInstruction newSource = invoke.inputs[0]; |
| 2248 if (newSource is! HThis) { | 2249 if (newSource is! HThis) { |
| 2249 return false; | 2250 return false; |
| 2250 } | 2251 } |
| 2251 if (source == null) { | 2252 if (source == null) { |
| 2252 // This is the first match. Extract the context class for the type | 2253 // This is the first match. Extract the context class for the type |
| 2253 // variables and get the list of type variables to keep track of how | 2254 // variables and get the list of type variables to keep track of how |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2557 } | 2558 } |
| 2558 | 2559 |
| 2559 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, | 2560 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, |
| 2560 String message) { | 2561 String message) { |
| 2561 HInstruction subtypeInstruction = | 2562 HInstruction subtypeInstruction = |
| 2562 analyzeTypeArgument(localsHandler.substInContext(subtype)); | 2563 analyzeTypeArgument(localsHandler.substInContext(subtype)); |
| 2563 HInstruction supertypeInstruction = | 2564 HInstruction supertypeInstruction = |
| 2564 analyzeTypeArgument(localsHandler.substInContext(supertype)); | 2565 analyzeTypeArgument(localsHandler.substInContext(supertype)); |
| 2565 HInstruction messageInstruction = | 2566 HInstruction messageInstruction = |
| 2566 graph.addConstantString(new ast.DartString.literal(message), compiler); | 2567 graph.addConstantString(new ast.DartString.literal(message), compiler); |
| 2567 Element element = backend.getAssertIsSubtype(); | 2568 Element element = helpers.assertIsSubtype; |
| 2568 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction, | 2569 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction, |
| 2569 messageInstruction]; | 2570 messageInstruction]; |
| 2570 HInstruction assertIsSubtype = new HInvokeStatic( | 2571 HInstruction assertIsSubtype = new HInvokeStatic( |
| 2571 element, inputs, subtypeInstruction.instructionType); | 2572 element, inputs, subtypeInstruction.instructionType); |
| 2572 registry.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 2573 registry.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 2573 add(assertIsSubtype); | 2574 add(assertIsSubtype); |
| 2574 } | 2575 } |
| 2575 | 2576 |
| 2576 HGraph closeFunction() { | 2577 HGraph closeFunction() { |
| 2577 // TODO(kasperl): Make this goto an implicit return. | 2578 // TODO(kasperl): Make this goto an implicit return. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2629 | 2630 |
| 2630 visitAssert(ast.Assert node) { | 2631 visitAssert(ast.Assert node) { |
| 2631 if (!compiler.enableUserAssertions) return; | 2632 if (!compiler.enableUserAssertions) return; |
| 2632 | 2633 |
| 2633 if (!node.hasMessage) { | 2634 if (!node.hasMessage) { |
| 2634 // Generate: | 2635 // Generate: |
| 2635 // | 2636 // |
| 2636 // assertHelper(condition); | 2637 // assertHelper(condition); |
| 2637 // | 2638 // |
| 2638 visit(node.condition); | 2639 visit(node.condition); |
| 2639 pushInvokeStatic(node, backend.assertHelperMethod, [pop()]); | 2640 pushInvokeStatic(node, helpers.assertHelper, [pop()]); |
| 2640 pop(); | 2641 pop(); |
| 2641 return; | 2642 return; |
| 2642 } | 2643 } |
| 2643 // Assert has message. Generate: | 2644 // Assert has message. Generate: |
| 2644 // | 2645 // |
| 2645 // if (assertTest(condition)) assertThrow(message); | 2646 // if (assertTest(condition)) assertThrow(message); |
| 2646 // | 2647 // |
| 2647 void buildCondition() { | 2648 void buildCondition() { |
| 2648 visit(node.condition); | 2649 visit(node.condition); |
| 2649 pushInvokeStatic(node, backend.assertTestMethod, [pop()]); | 2650 pushInvokeStatic(node, helpers.assertTest, [pop()]); |
| 2650 } | 2651 } |
| 2651 void fail() { | 2652 void fail() { |
| 2652 visit(node.message); | 2653 visit(node.message); |
| 2653 pushInvokeStatic(node, backend.assertThrowMethod, [pop()]); | 2654 pushInvokeStatic(node, helpers.assertThrow, [pop()]); |
| 2654 pop(); | 2655 pop(); |
| 2655 } | 2656 } |
| 2656 handleIf(node, | 2657 handleIf(node, |
| 2657 visitCondition: buildCondition, | 2658 visitCondition: buildCondition, |
| 2658 visitThen: fail); | 2659 visitThen: fail); |
| 2659 } | 2660 } |
| 2660 | 2661 |
| 2661 visitBlock(ast.Block node) { | 2662 visitBlock(ast.Block node) { |
| 2662 assert(!isAborted()); | 2663 assert(!isAborted()); |
| 2663 if (!isReachable) return; // This can only happen when inlining. | 2664 if (!isReachable) return; // This can only happen when inlining. |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3386 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. | 3387 /// Inserts a call to checkDeferredIsLoaded for [prefixElement]. |
| 3387 /// If [prefixElement] is [null] ndo nothing. | 3388 /// If [prefixElement] is [null] ndo nothing. |
| 3388 void generateIsDeferredLoadedCheckIfNeeded(PrefixElement prefixElement, | 3389 void generateIsDeferredLoadedCheckIfNeeded(PrefixElement prefixElement, |
| 3389 ast.Node location) { | 3390 ast.Node location) { |
| 3390 if (prefixElement == null) return; | 3391 if (prefixElement == null) return; |
| 3391 String loadId = | 3392 String loadId = |
| 3392 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); | 3393 compiler.deferredLoadTask.getImportDeferName(location, prefixElement); |
| 3393 HInstruction loadIdConstant = addConstantString(loadId); | 3394 HInstruction loadIdConstant = addConstantString(loadId); |
| 3394 String uri = prefixElement.deferredImport.uri.toString(); | 3395 String uri = prefixElement.deferredImport.uri.toString(); |
| 3395 HInstruction uriConstant = addConstantString(uri); | 3396 HInstruction uriConstant = addConstantString(uri); |
| 3396 Element helper = backend.getCheckDeferredIsLoaded(); | 3397 Element helper = helpers.checkDeferredIsLoaded; |
| 3397 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); | 3398 pushInvokeStatic(location, helper, [loadIdConstant, uriConstant]); |
| 3398 pop(); | 3399 pop(); |
| 3399 } | 3400 } |
| 3400 | 3401 |
| 3401 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 3402 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
| 3402 /// resolves to a deferred library. | 3403 /// resolves to a deferred library. |
| 3403 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 3404 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
| 3404 generateIsDeferredLoadedCheckIfNeeded( | 3405 generateIsDeferredLoadedCheckIfNeeded( |
| 3405 compiler.deferredLoadTask.deferredPrefixElement(node, elements), | 3406 compiler.deferredLoadTask.deferredPrefixElement(node, elements), |
| 3406 node); | 3407 node); |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3824 pushInvokeDynamic( | 3825 pushInvokeDynamic( |
| 3825 node, | 3826 node, |
| 3826 new Selector.call( | 3827 new Selector.call( |
| 3827 new PrivateName('_isTest', backend.jsHelperLibrary), | 3828 new PrivateName('_isTest', backend.jsHelperLibrary), |
| 3828 CallStructure.ONE_ARG), | 3829 CallStructure.ONE_ARG), |
| 3829 null, | 3830 null, |
| 3830 arguments); | 3831 arguments); |
| 3831 return new HIs.compound(type, expression, pop(), backend.boolType); | 3832 return new HIs.compound(type, expression, pop(), backend.boolType); |
| 3832 } else if (type.isTypeVariable) { | 3833 } else if (type.isTypeVariable) { |
| 3833 HInstruction runtimeType = addTypeVariableReference(type); | 3834 HInstruction runtimeType = addTypeVariableReference(type); |
| 3834 Element helper = backend.getCheckSubtypeOfRuntimeType(); | 3835 Element helper = helpers.checkSubtypeOfRuntimeType; |
| 3835 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 3836 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| 3836 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); | 3837 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); |
| 3837 HInstruction call = pop(); | 3838 HInstruction call = pop(); |
| 3838 return new HIs.variable(type, expression, call, backend.boolType); | 3839 return new HIs.variable(type, expression, call, backend.boolType); |
| 3839 } else if (RuntimeTypes.hasTypeArguments(type)) { | 3840 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 3840 ClassElement element = type.element; | 3841 ClassElement element = type.element; |
| 3841 Element helper = backend.getCheckSubtype(); | 3842 Element helper = helpers.checkSubtype; |
| 3842 HInstruction representations = | 3843 HInstruction representations = |
| 3843 buildTypeArgumentRepresentations(type); | 3844 buildTypeArgumentRepresentations(type); |
| 3844 add(representations); | 3845 add(representations); |
| 3845 js.Name operator = backend.namer.operatorIs(element); | 3846 js.Name operator = backend.namer.operatorIs(element); |
| 3846 HInstruction isFieldName = addConstantStringFromName(operator); | 3847 HInstruction isFieldName = addConstantStringFromName(operator); |
| 3847 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) | 3848 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) |
| 3848 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 3849 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
| 3849 : graph.addConstantNull(compiler); | 3850 : graph.addConstantNull(compiler); |
| 3850 List<HInstruction> inputs = <HInstruction>[expression, | 3851 List<HInstruction> inputs = <HInstruction>[expression, |
| 3851 isFieldName, | 3852 isFieldName, |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4501 registry.registerSelectorUse(selector); | 4502 registry.registerSelectorUse(selector); |
| 4502 } | 4503 } |
| 4503 String publicName = name; | 4504 String publicName = name; |
| 4504 if (selector.isSetter) publicName += '='; | 4505 if (selector.isSetter) publicName += '='; |
| 4505 | 4506 |
| 4506 ConstantValue nameConstant = constantSystem.createString( | 4507 ConstantValue nameConstant = constantSystem.createString( |
| 4507 new ast.DartString.literal(publicName)); | 4508 new ast.DartString.literal(publicName)); |
| 4508 | 4509 |
| 4509 js.Name internalName = backend.namer.invocationName(selector); | 4510 js.Name internalName = backend.namer.invocationName(selector); |
| 4510 | 4511 |
| 4511 Element createInvocationMirror = backend.getCreateInvocationMirror(); | 4512 Element createInvocationMirror = helpers.createInvocationMirror; |
| 4512 var argumentsInstruction = buildLiteralList(arguments); | 4513 var argumentsInstruction = buildLiteralList(arguments); |
| 4513 add(argumentsInstruction); | 4514 add(argumentsInstruction); |
| 4514 | 4515 |
| 4515 var argumentNames = new List<HInstruction>(); | 4516 var argumentNames = new List<HInstruction>(); |
| 4516 for (String argumentName in selector.namedArguments) { | 4517 for (String argumentName in selector.namedArguments) { |
| 4517 ConstantValue argumentNameConstant = | 4518 ConstantValue argumentNameConstant = |
| 4518 constantSystem.createString(new ast.DartString.literal(argumentName)); | 4519 constantSystem.createString(new ast.DartString.literal(argumentName)); |
| 4519 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); | 4520 argumentNames.add(graph.addConstant(argumentNameConstant, compiler)); |
| 4520 } | 4521 } |
| 4521 var argumentNamesInstruction = buildLiteralList(argumentNames); | 4522 var argumentNamesInstruction = buildLiteralList(argumentNames); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4804 compiler); | 4805 compiler); |
| 4805 | 4806 |
| 4806 if (needsSubstitutionForTypeVariableAccess(cls)) { | 4807 if (needsSubstitutionForTypeVariableAccess(cls)) { |
| 4807 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to | 4808 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to |
| 4808 // string concatenation in the implementation), and may prevent | 4809 // string concatenation in the implementation), and may prevent |
| 4809 // segmentation of '$'. | 4810 // segmentation of '$'. |
| 4810 js.Name substitutionName = backend.namer.runtimeTypeName(cls); | 4811 js.Name substitutionName = backend.namer.runtimeTypeName(cls); |
| 4811 HInstruction substitutionNameInstr = graph.addConstantStringFromName( | 4812 HInstruction substitutionNameInstr = graph.addConstantStringFromName( |
| 4812 substitutionName, compiler); | 4813 substitutionName, compiler); |
| 4813 pushInvokeStatic(null, | 4814 pushInvokeStatic(null, |
| 4814 backend.getGetRuntimeTypeArgument(), | 4815 helpers.getRuntimeTypeArgument, |
| 4815 [target, substitutionNameInstr, index], | 4816 [target, substitutionNameInstr, index], |
| 4816 typeMask: backend.dynamicType, | 4817 typeMask: backend.dynamicType, |
| 4817 sourceInformation: sourceInformation); | 4818 sourceInformation: sourceInformation); |
| 4818 } else { | 4819 } else { |
| 4819 pushInvokeStatic( | 4820 pushInvokeStatic( |
| 4820 null, | 4821 null, |
| 4821 backend.getGetTypeArgumentByIndex(), | 4822 helpers.getTypeArgumentByIndex, |
| 4822 [target, index], | 4823 [target, index], |
| 4823 typeMask: backend.dynamicType, | 4824 typeMask: backend.dynamicType, |
| 4824 sourceInformation: sourceInformation); | 4825 sourceInformation: sourceInformation); |
| 4825 } | 4826 } |
| 4826 return pop(); | 4827 return pop(); |
| 4827 } | 4828 } |
| 4828 | 4829 |
| 4829 // TODO(karlklose): this is needed to avoid a bug where the resolved type is | 4830 // TODO(karlklose): this is needed to avoid a bug where the resolved type is |
| 4830 // not stored on a type annotation in the closure translator. Remove when | 4831 // not stored on a type annotation in the closure translator. Remove when |
| 4831 // fixed. | 4832 // fixed. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4937 type = localsHandler.substInContext(type); | 4938 type = localsHandler.substInContext(type); |
| 4938 type.typeArguments.forEach((DartType argument) { | 4939 type.typeArguments.forEach((DartType argument) { |
| 4939 inputs.add(analyzeTypeArgument(argument)); | 4940 inputs.add(analyzeTypeArgument(argument)); |
| 4940 }); | 4941 }); |
| 4941 // TODO(15489): Register at codegen. | 4942 // TODO(15489): Register at codegen. |
| 4942 registry.registerInstantiatedType(type); | 4943 registry.registerInstantiatedType(type); |
| 4943 return callSetRuntimeTypeInfo(type.element, inputs, newObject); | 4944 return callSetRuntimeTypeInfo(type.element, inputs, newObject); |
| 4944 } | 4945 } |
| 4945 | 4946 |
| 4946 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { | 4947 void copyRuntimeTypeInfo(HInstruction source, HInstruction target) { |
| 4947 Element copyHelper = backend.getCopyTypeArguments(); | 4948 Element copyHelper = helpers.copyTypeArguments; |
| 4948 pushInvokeStatic(null, copyHelper, [source, target], | 4949 pushInvokeStatic(null, copyHelper, [source, target], |
| 4949 sourceInformation: target.sourceInformation); | 4950 sourceInformation: target.sourceInformation); |
| 4950 pop(); | 4951 pop(); |
| 4951 } | 4952 } |
| 4952 | 4953 |
| 4953 HInstruction callSetRuntimeTypeInfo(ClassElement element, | 4954 HInstruction callSetRuntimeTypeInfo(ClassElement element, |
| 4954 List<HInstruction> rtiInputs, | 4955 List<HInstruction> rtiInputs, |
| 4955 HInstruction newObject) { | 4956 HInstruction newObject) { |
| 4956 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { | 4957 if (!backend.classNeedsRti(element) || element.typeVariables.isEmpty) { |
| 4957 return newObject; | 4958 return newObject; |
| 4958 } | 4959 } |
| 4959 | 4960 |
| 4960 HInstruction typeInfo = buildLiteralList(rtiInputs); | 4961 HInstruction typeInfo = buildLiteralList(rtiInputs); |
| 4961 add(typeInfo); | 4962 add(typeInfo); |
| 4962 | 4963 |
| 4963 // Set the runtime type information on the object. | 4964 // Set the runtime type information on the object. |
| 4964 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); | 4965 Element typeInfoSetterElement = helpers.setRuntimeTypeInfo; |
| 4965 pushInvokeStatic( | 4966 pushInvokeStatic( |
| 4966 null, | 4967 null, |
| 4967 typeInfoSetterElement, | 4968 typeInfoSetterElement, |
| 4968 <HInstruction>[newObject, typeInfo], | 4969 <HInstruction>[newObject, typeInfo], |
| 4969 typeMask: backend.dynamicType, | 4970 typeMask: backend.dynamicType, |
| 4970 sourceInformation: newObject.sourceInformation); | 4971 sourceInformation: newObject.sourceInformation); |
| 4971 | 4972 |
| 4972 // The new object will now be referenced through the | 4973 // The new object will now be referenced through the |
| 4973 // `setRuntimeTypeInfo` call. We therefore set the type of that | 4974 // `setRuntimeTypeInfo` call. We therefore set the type of that |
| 4974 // instruction to be of the object's type. | 4975 // instruction to be of the object's type. |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5534 } | 5535 } |
| 5535 } | 5536 } |
| 5536 | 5537 |
| 5537 /// Generate the literal for [typeVariable] in the current context. | 5538 /// Generate the literal for [typeVariable] in the current context. |
| 5538 void generateTypeVariableLiteral(ast.Send node, | 5539 void generateTypeVariableLiteral(ast.Send node, |
| 5539 TypeVariableType typeVariable) { | 5540 TypeVariableType typeVariable) { |
| 5540 DartType type = localsHandler.substInContext(typeVariable); | 5541 DartType type = localsHandler.substInContext(typeVariable); |
| 5541 HInstruction value = analyzeTypeArgument(type, | 5542 HInstruction value = analyzeTypeArgument(type, |
| 5542 sourceInformation: sourceInformationBuilder.buildGet(node)); | 5543 sourceInformation: sourceInformationBuilder.buildGet(node)); |
| 5543 pushInvokeStatic(node, | 5544 pushInvokeStatic(node, |
| 5544 backend.getRuntimeTypeToString(), | 5545 helpers.runtimeTypeToString, |
| 5545 [value], | 5546 [value], |
| 5546 typeMask: backend.stringType); | 5547 typeMask: backend.stringType); |
| 5547 pushInvokeStatic(node, | 5548 pushInvokeStatic(node, |
| 5548 backend.getCreateRuntimeType(), | 5549 helpers.createRuntimeType, |
| 5549 [pop()]); | 5550 [pop()]); |
| 5550 } | 5551 } |
| 5551 | 5552 |
| 5552 /// Generate a call to a type literal. | 5553 /// Generate a call to a type literal. |
| 5553 void generateTypeLiteralCall(ast.Send node) { | 5554 void generateTypeLiteralCall(ast.Send node) { |
| 5554 // This send is of the form 'e(...)', where e is resolved to a type | 5555 // This send is of the form 'e(...)', where e is resolved to a type |
| 5555 // reference. We create a regular closure call on the result of the type | 5556 // reference. We create a regular closure call on the result of the type |
| 5556 // reference instead of creating a NoSuchMethodError to avoid pulling it | 5557 // reference instead of creating a NoSuchMethodError to avoid pulling it |
| 5557 // in if it is not used (e.g., in a try/catch). | 5558 // in if it is not used (e.g., in a try/catch). |
| 5558 HInstruction target = pop(); | 5559 HInstruction target = pop(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5581 internalError(Spannable node, String reason) { | 5582 internalError(Spannable node, String reason) { |
| 5582 reporter.internalError(node, reason); | 5583 reporter.internalError(node, reason); |
| 5583 } | 5584 } |
| 5584 | 5585 |
| 5585 void generateError(ast.Node node, String message, Element helper) { | 5586 void generateError(ast.Node node, String message, Element helper) { |
| 5586 HInstruction errorMessage = addConstantString(message); | 5587 HInstruction errorMessage = addConstantString(message); |
| 5587 pushInvokeStatic(node, helper, [errorMessage]); | 5588 pushInvokeStatic(node, helper, [errorMessage]); |
| 5588 } | 5589 } |
| 5589 | 5590 |
| 5590 void generateRuntimeError(ast.Node node, String message) { | 5591 void generateRuntimeError(ast.Node node, String message) { |
| 5591 generateError(node, message, backend.getThrowRuntimeError()); | 5592 generateError(node, message, helpers.throwRuntimeError); |
| 5592 } | 5593 } |
| 5593 | 5594 |
| 5594 void generateTypeError(ast.Node node, String message) { | 5595 void generateTypeError(ast.Node node, String message) { |
| 5595 generateError(node, message, backend.getThrowTypeError()); | 5596 generateError(node, message, helpers.throwTypeError); |
| 5596 } | 5597 } |
| 5597 | 5598 |
| 5598 void generateAbstractClassInstantiationError(ast.Node node, String message) { | 5599 void generateAbstractClassInstantiationError(ast.Node node, String message) { |
| 5599 generateError(node, | 5600 generateError(node, |
| 5600 message, | 5601 message, |
| 5601 backend.getThrowAbstractClassInstantiationError()); | 5602 helpers.throwAbstractClassInstantiationError); |
| 5602 } | 5603 } |
| 5603 | 5604 |
| 5604 void generateThrowNoSuchMethod(ast.Node diagnosticNode, | 5605 void generateThrowNoSuchMethod(ast.Node diagnosticNode, |
| 5605 String methodName, | 5606 String methodName, |
| 5606 {Link<ast.Node> argumentNodes, | 5607 {Link<ast.Node> argumentNodes, |
| 5607 List<HInstruction> argumentValues, | 5608 List<HInstruction> argumentValues, |
| 5608 List<String> existingArguments, | 5609 List<String> existingArguments, |
| 5609 SourceInformation sourceInformation}) { | 5610 SourceInformation sourceInformation}) { |
| 5610 Element helper = backend.getThrowNoSuchMethod(); | 5611 Element helper = helpers.throwNoSuchMethod; |
| 5611 ConstantValue receiverConstant = | 5612 ConstantValue receiverConstant = |
| 5612 constantSystem.createString(new ast.DartString.empty()); | 5613 constantSystem.createString(new ast.DartString.empty()); |
| 5613 HInstruction receiver = graph.addConstant(receiverConstant, compiler); | 5614 HInstruction receiver = graph.addConstant(receiverConstant, compiler); |
| 5614 ast.DartString dartString = new ast.DartString.literal(methodName); | 5615 ast.DartString dartString = new ast.DartString.literal(methodName); |
| 5615 ConstantValue nameConstant = constantSystem.createString(dartString); | 5616 ConstantValue nameConstant = constantSystem.createString(dartString); |
| 5616 HInstruction name = graph.addConstant(nameConstant, compiler); | 5617 HInstruction name = graph.addConstant(nameConstant, compiler); |
| 5617 if (argumentValues == null) { | 5618 if (argumentValues == null) { |
| 5618 argumentValues = <HInstruction>[]; | 5619 argumentValues = <HInstruction>[]; |
| 5619 argumentNodes.forEach((argumentNode) { | 5620 argumentNodes.forEach((argumentNode) { |
| 5620 visit(argumentNode); | 5621 visit(argumentNode); |
| (...skipping 1587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7208 return new JumpHandler(this, element); | 7209 return new JumpHandler(this, element); |
| 7209 } | 7210 } |
| 7210 | 7211 |
| 7211 visitAsyncForIn(ast.AsyncForIn node) { | 7212 visitAsyncForIn(ast.AsyncForIn node) { |
| 7212 // The async-for is implemented with a StreamIterator. | 7213 // The async-for is implemented with a StreamIterator. |
| 7213 HInstruction streamIterator; | 7214 HInstruction streamIterator; |
| 7214 | 7215 |
| 7215 visit(node.expression); | 7216 visit(node.expression); |
| 7216 HInstruction expression = pop(); | 7217 HInstruction expression = pop(); |
| 7217 pushInvokeStatic(node, | 7218 pushInvokeStatic(node, |
| 7218 backend.getStreamIteratorConstructor(), | 7219 helpers.streamIteratorConstructor, |
| 7219 [expression, graph.addConstantNull(compiler)]); | 7220 [expression, graph.addConstantNull(compiler)]); |
| 7220 streamIterator = pop(); | 7221 streamIterator = pop(); |
| 7221 | 7222 |
| 7222 void buildInitializer() {} | 7223 void buildInitializer() {} |
| 7223 | 7224 |
| 7224 HInstruction buildCondition() { | 7225 HInstruction buildCondition() { |
| 7225 Selector selector = elements.getMoveNextSelector(node); | 7226 Selector selector = elements.getMoveNextSelector(node); |
| 7226 TypeMask mask = elements.getMoveNextTypeMask(node); | 7227 TypeMask mask = elements.getMoveNextTypeMask(node); |
| 7227 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 7228 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
| 7228 HInstruction future = pop(); | 7229 HInstruction future = pop(); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7393 void buildConcurrentModificationErrorCheck() { | 7394 void buildConcurrentModificationErrorCheck() { |
| 7394 if (originalLength == null) return; | 7395 if (originalLength == null) return; |
| 7395 // The static call checkConcurrentModificationError() is expanded in | 7396 // The static call checkConcurrentModificationError() is expanded in |
| 7396 // codegen to: | 7397 // codegen to: |
| 7397 // | 7398 // |
| 7398 // array.length == _end || throwConcurrentModificationError(array) | 7399 // array.length == _end || throwConcurrentModificationError(array) |
| 7399 // | 7400 // |
| 7400 HInstruction length = buildGetLength(); | 7401 HInstruction length = buildGetLength(); |
| 7401 push(new HIdentity(length, originalLength, null, boolType)); | 7402 push(new HIdentity(length, originalLength, null, boolType)); |
| 7402 pushInvokeStatic(node, | 7403 pushInvokeStatic(node, |
| 7403 backend.getCheckConcurrentModificationError(), | 7404 helpers.checkConcurrentModificationError, |
| 7404 [pop(), array]); | 7405 [pop(), array]); |
| 7405 pop(); | 7406 pop(); |
| 7406 } | 7407 } |
| 7407 | 7408 |
| 7408 void buildInitializer() { | 7409 void buildInitializer() { |
| 7409 visit(node.expression); | 7410 visit(node.expression); |
| 7410 array = pop(); | 7411 array = pop(); |
| 7411 isFixed = isFixedLength(array.instructionType, compiler); | 7412 isFixed = isFixedLength(array.instructionType, compiler); |
| 7412 localsHandler.updateLocal(indexVariable, | 7413 localsHandler.updateLocal(indexVariable, |
| 7413 graph.addConstantInt(0, compiler)); | 7414 graph.addConstantInt(0, compiler)); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7855 if (switchCases.isEmpty) { | 7856 if (switchCases.isEmpty) { |
| 7856 return; | 7857 return; |
| 7857 } | 7858 } |
| 7858 | 7859 |
| 7859 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); | 7860 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); |
| 7860 HBasicBlock expressionEnd = close(switchInstruction); | 7861 HBasicBlock expressionEnd = close(switchInstruction); |
| 7861 LocalsHandler savedLocals = localsHandler; | 7862 LocalsHandler savedLocals = localsHandler; |
| 7862 | 7863 |
| 7863 List<HStatementInformation> statements = <HStatementInformation>[]; | 7864 List<HStatementInformation> statements = <HStatementInformation>[]; |
| 7864 bool hasDefault = false; | 7865 bool hasDefault = false; |
| 7865 Element getFallThroughErrorElement = backend.getFallThroughError(); | 7866 Element getFallThroughErrorElement = helpers.fallThroughError; |
| 7866 HasNextIterator<ast.Node> caseIterator = | 7867 HasNextIterator<ast.Node> caseIterator = |
| 7867 new HasNextIterator<ast.Node>(switchCases.iterator); | 7868 new HasNextIterator<ast.Node>(switchCases.iterator); |
| 7868 while (caseIterator.hasNext) { | 7869 while (caseIterator.hasNext) { |
| 7869 ast.SwitchCase switchCase = caseIterator.next(); | 7870 ast.SwitchCase switchCase = caseIterator.next(); |
| 7870 HBasicBlock block = graph.addNewBlock(); | 7871 HBasicBlock block = graph.addNewBlock(); |
| 7871 for (ConstantValue constant in getConstants(switchCase)) { | 7872 for (ConstantValue constant in getConstants(switchCase)) { |
| 7872 HConstant hConstant = graph.addConstant(constant, compiler); | 7873 HConstant hConstant = graph.addConstant(constant, compiler); |
| 7873 switchInstruction.inputs.add(hConstant); | 7874 switchInstruction.inputs.add(hConstant); |
| 7874 hConstant.usedBy.add(switchInstruction); | 7875 hConstant.usedBy.add(switchInstruction); |
| 7875 expressionEnd.addSuccessor(block); | 7876 expressionEnd.addSuccessor(block); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8101 startCatchBlock = graph.addNewBlock(); | 8102 startCatchBlock = graph.addNewBlock(); |
| 8102 open(startCatchBlock); | 8103 open(startCatchBlock); |
| 8103 // Note that the name of this local is irrelevant. | 8104 // Note that the name of this local is irrelevant. |
| 8104 SyntheticLocal local = | 8105 SyntheticLocal local = |
| 8105 new SyntheticLocal('exception', localsHandler.executableContext); | 8106 new SyntheticLocal('exception', localsHandler.executableContext); |
| 8106 exception = new HLocalValue(local, backend.nonNullType); | 8107 exception = new HLocalValue(local, backend.nonNullType); |
| 8107 add(exception); | 8108 add(exception); |
| 8108 HInstruction oldRethrowableException = rethrowableException; | 8109 HInstruction oldRethrowableException = rethrowableException; |
| 8109 rethrowableException = exception; | 8110 rethrowableException = exception; |
| 8110 | 8111 |
| 8111 pushInvokeStatic(node, backend.getExceptionUnwrapper(), [exception]); | 8112 pushInvokeStatic(node, helpers.exceptionUnwrapper, [exception]); |
| 8112 HInvokeStatic unwrappedException = pop(); | 8113 HInvokeStatic unwrappedException = pop(); |
| 8113 tryInstruction.exception = exception; | 8114 tryInstruction.exception = exception; |
| 8114 Link<ast.Node> link = node.catchBlocks.nodes; | 8115 Link<ast.Node> link = node.catchBlocks.nodes; |
| 8115 | 8116 |
| 8116 void pushCondition(ast.CatchBlock catchBlock) { | 8117 void pushCondition(ast.CatchBlock catchBlock) { |
| 8117 if (catchBlock.onKeyword != null) { | 8118 if (catchBlock.onKeyword != null) { |
| 8118 DartType type = elements.getType(catchBlock.type); | 8119 DartType type = elements.getType(catchBlock.type); |
| 8119 if (type == null) { | 8120 if (type == null) { |
| 8120 reporter.internalError(catchBlock.type, 'On with no type.'); | 8121 reporter.internalError(catchBlock.type, 'On with no type.'); |
| 8121 } | 8122 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8147 ast.CatchBlock catchBlock = link.head; | 8148 ast.CatchBlock catchBlock = link.head; |
| 8148 link = link.tail; | 8149 link = link.tail; |
| 8149 if (catchBlock.exception != null) { | 8150 if (catchBlock.exception != null) { |
| 8150 LocalVariableElement exceptionVariable = | 8151 LocalVariableElement exceptionVariable = |
| 8151 elements[catchBlock.exception]; | 8152 elements[catchBlock.exception]; |
| 8152 localsHandler.updateLocal(exceptionVariable, | 8153 localsHandler.updateLocal(exceptionVariable, |
| 8153 unwrappedException); | 8154 unwrappedException); |
| 8154 } | 8155 } |
| 8155 ast.Node trace = catchBlock.trace; | 8156 ast.Node trace = catchBlock.trace; |
| 8156 if (trace != null) { | 8157 if (trace != null) { |
| 8157 pushInvokeStatic(trace, backend.getTraceFromException(), [exception]); | 8158 pushInvokeStatic(trace, helpers.traceFromException, [exception]); |
| 8158 HInstruction traceInstruction = pop(); | 8159 HInstruction traceInstruction = pop(); |
| 8159 LocalVariableElement traceVariable = elements[trace]; | 8160 LocalVariableElement traceVariable = elements[trace]; |
| 8160 localsHandler.updateLocal(traceVariable, traceInstruction); | 8161 localsHandler.updateLocal(traceVariable, traceInstruction); |
| 8161 } | 8162 } |
| 8162 visit(catchBlock); | 8163 visit(catchBlock); |
| 8163 } | 8164 } |
| 8164 | 8165 |
| 8165 void visitElse() { | 8166 void visitElse() { |
| 8166 if (link.isEmpty) { | 8167 if (link.isEmpty) { |
| 8167 closeAndGotoExit( | 8168 closeAndGotoExit( |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8996 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 8997 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 8997 unaliased.accept(this, builder); | 8998 unaliased.accept(this, builder); |
| 8998 } | 8999 } |
| 8999 | 9000 |
| 9000 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9001 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 9001 JavaScriptBackend backend = builder.compiler.backend; | 9002 JavaScriptBackend backend = builder.compiler.backend; |
| 9002 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 9003 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 9003 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9004 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 9004 } | 9005 } |
| 9005 } | 9006 } |
| OLD | NEW |