| 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 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
| 9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
| 10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 Selector selector, | 1211 Selector selector, |
| 1212 List<HInstruction> providedArguments, | 1212 List<HInstruction> providedArguments, |
| 1213 ast.Node currentNode) { | 1213 ast.Node currentNode) { |
| 1214 // TODO(johnniwinther): Register this on the [registry]. Currently the | 1214 // TODO(johnniwinther): Register this on the [registry]. Currently the |
| 1215 // [CodegenRegistry] calls the enqueuer, but [element] should _not_ be | 1215 // [CodegenRegistry] calls the enqueuer, but [element] should _not_ be |
| 1216 // enqueued. | 1216 // enqueued. |
| 1217 backend.registerStaticUse(element, compiler.enqueuer.codegen); | 1217 backend.registerStaticUse(element, compiler.enqueuer.codegen); |
| 1218 | 1218 |
| 1219 // Ensure that [element] is an implementation element. | 1219 // Ensure that [element] is an implementation element. |
| 1220 element = element.implementation; | 1220 element = element.implementation; |
| 1221 |
| 1222 if (compiler.elementHasCompileTimeError(element)) return false; |
| 1223 |
| 1221 FunctionElement function = element; | 1224 FunctionElement function = element; |
| 1222 bool insideLoop = loopNesting > 0 || graph.calledInLoop; | 1225 bool insideLoop = loopNesting > 0 || graph.calledInLoop; |
| 1223 | 1226 |
| 1224 // Bail out early if the inlining decision is in the cache and we can't | 1227 // Bail out early if the inlining decision is in the cache and we can't |
| 1225 // inline (no need to check the hard constraints). | 1228 // inline (no need to check the hard constraints). |
| 1226 bool cachedCanBeInlined = | 1229 bool cachedCanBeInlined = |
| 1227 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 1230 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
| 1228 if (cachedCanBeInlined == false) return false; | 1231 if (cachedCanBeInlined == false) return false; |
| 1229 | 1232 |
| 1230 bool meetsHardConstraints() { | 1233 bool meetsHardConstraints() { |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 | 1836 |
| 1834 Element target = constructor.definingConstructor.implementation; | 1837 Element target = constructor.definingConstructor.implementation; |
| 1835 bool match = Selector.addForwardingElementArgumentsToList( | 1838 bool match = Selector.addForwardingElementArgumentsToList( |
| 1836 constructor, | 1839 constructor, |
| 1837 arguments, | 1840 arguments, |
| 1838 target, | 1841 target, |
| 1839 compileArgument, | 1842 compileArgument, |
| 1840 handleConstantForOptionalParameter, | 1843 handleConstantForOptionalParameter, |
| 1841 compiler.world); | 1844 compiler.world); |
| 1842 if (!match) { | 1845 if (!match) { |
| 1846 if (compiler.elementHasCompileTimeError(constructor)) { |
| 1847 return; |
| 1848 } |
| 1843 // If this fails, the selector we constructed for the call to a | 1849 // If this fails, the selector we constructed for the call to a |
| 1844 // forwarding constructor in a mixin application did not match the | 1850 // forwarding constructor in a mixin application did not match the |
| 1845 // constructor (which, for example, may happen when the libraries are | 1851 // constructor (which, for example, may happen when the libraries are |
| 1846 // not compatible for private names, see issue 20394). | 1852 // not compatible for private names, see issue 20394). |
| 1847 compiler.internalError(constructor, | 1853 compiler.internalError(constructor, |
| 1848 'forwarding constructor call does not match'); | 1854 'forwarding constructor call does not match'); |
| 1849 } | 1855 } |
| 1850 inlineSuperOrRedirect( | 1856 inlineSuperOrRedirect( |
| 1851 target, | 1857 target, |
| 1852 arguments, | 1858 arguments, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 * Run through the fields of [cls] and add their potential | 1934 * Run through the fields of [cls] and add their potential |
| 1929 * initializers. | 1935 * initializers. |
| 1930 * | 1936 * |
| 1931 * Invariant: [classElement] must be an implementation element. | 1937 * Invariant: [classElement] must be an implementation element. |
| 1932 */ | 1938 */ |
| 1933 void buildFieldInitializers(ClassElement classElement, | 1939 void buildFieldInitializers(ClassElement classElement, |
| 1934 Map<Element, HInstruction> fieldValues) { | 1940 Map<Element, HInstruction> fieldValues) { |
| 1935 assert(invariant(classElement, classElement.isImplementation)); | 1941 assert(invariant(classElement, classElement.isImplementation)); |
| 1936 classElement.forEachInstanceField( | 1942 classElement.forEachInstanceField( |
| 1937 (ClassElement enclosingClass, VariableElement member) { | 1943 (ClassElement enclosingClass, VariableElement member) { |
| 1944 if (compiler.elementHasCompileTimeError(member)) return; |
| 1938 compiler.withCurrentElement(member, () { | 1945 compiler.withCurrentElement(member, () { |
| 1939 TreeElements definitions = member.treeElements; | 1946 TreeElements definitions = member.treeElements; |
| 1940 ast.Node node = member.node; | 1947 ast.Node node = member.node; |
| 1941 ast.Expression initializer = member.initializer; | 1948 ast.Expression initializer = member.initializer; |
| 1942 if (initializer == null) { | 1949 if (initializer == null) { |
| 1943 // Unassigned fields of native classes are not initialized to | 1950 // Unassigned fields of native classes are not initialized to |
| 1944 // prevent overwriting pre-initialized native properties. | 1951 // prevent overwriting pre-initialized native properties. |
| 1945 if (!Elements.isNativeOrExtendsNative(classElement)) { | 1952 if (!Elements.isNativeOrExtendsNative(classElement)) { |
| 1946 fieldValues[member] = graph.addConstantNull(compiler); | 1953 fieldValues[member] = graph.addConstantNull(compiler); |
| 1947 } | 1954 } |
| (...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3202 HInstruction receiver = generateInstanceSendReceiver(send); | 3209 HInstruction receiver = generateInstanceSendReceiver(send); |
| 3203 generateInstanceGetterWithCompiledReceiver( | 3210 generateInstanceGetterWithCompiledReceiver( |
| 3204 send, elements.getSelector(send), receiver); | 3211 send, elements.getSelector(send), receiver); |
| 3205 } else if (Elements.isStaticOrTopLevelFunction(element)) { | 3212 } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| 3206 // TODO(5346): Try to avoid the need for calling [declaration] before | 3213 // TODO(5346): Try to avoid the need for calling [declaration] before |
| 3207 // creating an [HStatic]. | 3214 // creating an [HStatic]. |
| 3208 push(new HStatic(element.declaration, backend.nonNullType)); | 3215 push(new HStatic(element.declaration, backend.nonNullType)); |
| 3209 // TODO(ahe): This should be registered in codegen. | 3216 // TODO(ahe): This should be registered in codegen. |
| 3210 registry.registerGetOfStaticFunction(element.declaration); | 3217 registry.registerGetOfStaticFunction(element.declaration); |
| 3211 } else if (Elements.isErroneousElement(element)) { | 3218 } else if (Elements.isErroneousElement(element)) { |
| 3212 // An erroneous element indicates an unresolved static getter. | 3219 if (element is ErroneousElement) { |
| 3213 generateThrowNoSuchMethod(send, | 3220 // An erroneous element indicates an unresolved static getter. |
| 3214 noSuchMethodTargetSymbolString(element, 'get'), | 3221 generateThrowNoSuchMethod( |
| 3215 argumentNodes: const Link<ast.Node>()); | 3222 send, |
| 3223 noSuchMethodTargetSymbolString(element, 'get'), |
| 3224 argumentNodes: const Link<ast.Node>()); |
| 3225 } else { |
| 3226 // TODO(ahe): Do something like the above, that is, emit a runtime |
| 3227 // error. |
| 3228 stack.add(graph.addConstantNull(compiler)); |
| 3229 } |
| 3216 } else { | 3230 } else { |
| 3217 LocalElement local = element; | 3231 LocalElement local = element; |
| 3218 stack.add(localsHandler.readLocal(local)); | 3232 stack.add(localsHandler.readLocal(local)); |
| 3219 } | 3233 } |
| 3220 } | 3234 } |
| 3221 | 3235 |
| 3222 void generateInstanceSetterWithCompiledReceiver(ast.Send send, | 3236 void generateInstanceSetterWithCompiledReceiver(ast.Send send, |
| 3223 HInstruction receiver, | 3237 HInstruction receiver, |
| 3224 HInstruction value, | 3238 HInstruction value, |
| 3225 {Selector selector, | 3239 {Selector selector, |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4280 assert(invariant(send, selector != null, | 4294 assert(invariant(send, selector != null, |
| 4281 message: 'Constructor Symbol.validated is missing')); | 4295 message: 'Constructor Symbol.validated is missing')); |
| 4282 } | 4296 } |
| 4283 | 4297 |
| 4284 bool isRedirected = constructorDeclaration.isRedirectingFactory; | 4298 bool isRedirected = constructorDeclaration.isRedirectingFactory; |
| 4285 InterfaceType type = elements.getType(node); | 4299 InterfaceType type = elements.getType(node); |
| 4286 InterfaceType expectedType = | 4300 InterfaceType expectedType = |
| 4287 constructorDeclaration.computeEffectiveTargetType(type); | 4301 constructorDeclaration.computeEffectiveTargetType(type); |
| 4288 expectedType = localsHandler.substInContext(expectedType); | 4302 expectedType = localsHandler.substInContext(expectedType); |
| 4289 | 4303 |
| 4304 if (compiler.elementHasCompileTimeError(constructor)) { |
| 4305 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 4306 stack.add(graph.addConstantNull(compiler)); |
| 4307 return; |
| 4308 } |
| 4290 if (checkTypeVariableBounds(node, type)) return; | 4309 if (checkTypeVariableBounds(node, type)) return; |
| 4291 | 4310 |
| 4292 var inputs = <HInstruction>[]; | 4311 var inputs = <HInstruction>[]; |
| 4293 if (constructor.isGenerativeConstructor && | 4312 if (constructor.isGenerativeConstructor && |
| 4294 Elements.isNativeOrExtendsNative(constructor.enclosingClass)) { | 4313 Elements.isNativeOrExtendsNative(constructor.enclosingClass)) { |
| 4295 // Native class generative constructors take a pre-constructed object. | 4314 // Native class generative constructors take a pre-constructed object. |
| 4296 inputs.add(graph.addConstantNull(compiler)); | 4315 inputs.add(graph.addConstantNull(compiler)); |
| 4297 } | 4316 } |
| 4298 // TODO(5347): Try to avoid the need for calling [implementation] before | 4317 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 4299 // calling [makeStaticArgumentList]. | 4318 // calling [makeStaticArgumentList]. |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4647 } | 4666 } |
| 4648 | 4667 |
| 4649 visitNewExpression(ast.NewExpression node) { | 4668 visitNewExpression(ast.NewExpression node) { |
| 4650 Element element = elements[node.send]; | 4669 Element element = elements[node.send]; |
| 4651 final bool isSymbolConstructor = element == compiler.symbolConstructor; | 4670 final bool isSymbolConstructor = element == compiler.symbolConstructor; |
| 4652 if (!Elements.isErroneousElement(element)) { | 4671 if (!Elements.isErroneousElement(element)) { |
| 4653 ConstructorElement function = element; | 4672 ConstructorElement function = element; |
| 4654 element = function.effectiveTarget; | 4673 element = function.effectiveTarget; |
| 4655 } | 4674 } |
| 4656 if (Elements.isErroneousElement(element)) { | 4675 if (Elements.isErroneousElement(element)) { |
| 4676 if (element is !ErroneousElement) { |
| 4677 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 4678 stack.add(graph.addConstantNull(compiler)); |
| 4679 return; |
| 4680 } |
| 4657 ErroneousElement error = element; | 4681 ErroneousElement error = element; |
| 4658 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 4682 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 4659 generateThrowNoSuchMethod( | 4683 generateThrowNoSuchMethod( |
| 4660 node.send, | 4684 node.send, |
| 4661 noSuchMethodTargetSymbolString(error, 'constructor'), | 4685 noSuchMethodTargetSymbolString(error, 'constructor'), |
| 4662 argumentNodes: node.send.arguments); | 4686 argumentNodes: node.send.arguments); |
| 4663 } else { | 4687 } else { |
| 4664 Message message = error.messageKind.message(error.messageArguments); | 4688 Message message = error.messageKind.message(error.messageArguments); |
| 4665 generateRuntimeError(node.send, message.toString()); | 4689 generateRuntimeError(node.send, message.toString()); |
| 4666 } | 4690 } |
| (...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6635 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6659 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6636 unaliased.accept(this, builder); | 6660 unaliased.accept(this, builder); |
| 6637 } | 6661 } |
| 6638 | 6662 |
| 6639 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6663 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6640 JavaScriptBackend backend = builder.compiler.backend; | 6664 JavaScriptBackend backend = builder.compiler.backend; |
| 6641 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 6665 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 6642 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 6666 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 6643 } | 6667 } |
| 6644 } | 6668 } |
| OLD | NEW |