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 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 sourceInformationBuilder = sourceInformationFactory.createBuilderForContext( | 1111 sourceInformationBuilder = sourceInformationFactory.createBuilderForContext( |
1112 target); | 1112 target); |
1113 } | 1113 } |
1114 | 1114 |
1115 BackendHelpers get helpers => backend.helpers; | 1115 BackendHelpers get helpers => backend.helpers; |
1116 | 1116 |
1117 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 1117 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
1118 | 1118 |
1119 DiagnosticReporter get reporter => compiler.reporter; | 1119 DiagnosticReporter get reporter => compiler.reporter; |
1120 | 1120 |
| 1121 CoreClasses get coreClasses => compiler.coreClasses; |
| 1122 |
1121 @override | 1123 @override |
1122 SemanticSendVisitor get sendVisitor => this; | 1124 SemanticSendVisitor get sendVisitor => this; |
1123 | 1125 |
1124 @override | 1126 @override |
1125 void visitNode(ast.Node node) { | 1127 void visitNode(ast.Node node) { |
1126 internalError(node, "Unhandled node: $node"); | 1128 internalError(node, "Unhandled node: $node"); |
1127 } | 1129 } |
1128 | 1130 |
1129 @override | 1131 @override |
1130 void apply(ast.Node node, [_]) { | 1132 void apply(ast.Node node, [_]) { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 if (!selector.applies(function, compiler.world)) return false; | 1373 if (!selector.applies(function, compiler.world)) return false; |
1372 if (mask != null && !mask.canHit(function, selector, compiler.world)) { | 1374 if (mask != null && !mask.canHit(function, selector, compiler.world)) { |
1373 return false; | 1375 return false; |
1374 } | 1376 } |
1375 } | 1377 } |
1376 | 1378 |
1377 if (backend.isJsInterop(element)) return false; | 1379 if (backend.isJsInterop(element)) return false; |
1378 | 1380 |
1379 // Don't inline operator== methods if the parameter can be null. | 1381 // Don't inline operator== methods if the parameter can be null. |
1380 if (element.name == '==') { | 1382 if (element.name == '==') { |
1381 if (element.enclosingClass != compiler.objectClass | 1383 if (element.enclosingClass != coreClasses.objectClass |
1382 && providedArguments[1].canBeNull()) { | 1384 && providedArguments[1].canBeNull()) { |
1383 return false; | 1385 return false; |
1384 } | 1386 } |
1385 } | 1387 } |
1386 | 1388 |
1387 // Generative constructors of native classes should not be called directly | 1389 // Generative constructors of native classes should not be called directly |
1388 // and have an extra argument that causes problems with inlining. | 1390 // and have an extra argument that causes problems with inlining. |
1389 if (element.isGenerativeConstructor | 1391 if (element.isGenerativeConstructor |
1390 && backend.isNativeOrExtendsNative(element.enclosingClass)) { | 1392 && backend.isNativeOrExtendsNative(element.enclosingClass)) { |
1391 return false; | 1393 return false; |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 } | 2571 } |
2570 } | 2572 } |
2571 | 2573 |
2572 HInstruction _trustType(HInstruction original, DartType type) { | 2574 HInstruction _trustType(HInstruction original, DartType type) { |
2573 assert(compiler.trustTypeAnnotations); | 2575 assert(compiler.trustTypeAnnotations); |
2574 assert(type != null); | 2576 assert(type != null); |
2575 type = localsHandler.substInContext(type); | 2577 type = localsHandler.substInContext(type); |
2576 type = type.unaliased; | 2578 type = type.unaliased; |
2577 if (type.isDynamic) return original; | 2579 if (type.isDynamic) return original; |
2578 if (!type.isInterfaceType) return original; | 2580 if (!type.isInterfaceType) return original; |
| 2581 if (type.isObject) return original; |
2579 // The type element is either a class or the void element. | 2582 // The type element is either a class or the void element. |
2580 Element element = type.element; | 2583 Element element = type.element; |
2581 if (element == compiler.objectClass) return original; | |
2582 TypeMask mask = new TypeMask.subtype(element, compiler.world); | 2584 TypeMask mask = new TypeMask.subtype(element, compiler.world); |
2583 return new HTypeKnown.pinned(mask, original); | 2585 return new HTypeKnown.pinned(mask, original); |
2584 } | 2586 } |
2585 | 2587 |
2586 HInstruction _checkType(HInstruction original, DartType type, int kind) { | 2588 HInstruction _checkType(HInstruction original, DartType type, int kind) { |
2587 assert(compiler.enableTypeAssertions); | 2589 assert(compiler.enableTypeAssertions); |
2588 assert(type != null); | 2590 assert(type != null); |
2589 type = localsHandler.substInContext(type); | 2591 type = localsHandler.substInContext(type); |
2590 HInstruction other = buildTypeConversion(original, type, kind); | 2592 HInstruction other = buildTypeConversion(original, type, kind); |
2591 registry?.registerIsCheck(type); | 2593 registry?.registerIsCheck(type); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2645 | 2647 |
2646 void dup() { | 2648 void dup() { |
2647 stack.add(stack.last); | 2649 stack.add(stack.last); |
2648 } | 2650 } |
2649 | 2651 |
2650 HInstruction popBoolified() { | 2652 HInstruction popBoolified() { |
2651 HInstruction value = pop(); | 2653 HInstruction value = pop(); |
2652 if (_checkOrTrustTypes) { | 2654 if (_checkOrTrustTypes) { |
2653 return potentiallyCheckOrTrustType( | 2655 return potentiallyCheckOrTrustType( |
2654 value, | 2656 value, |
2655 compiler.boolClass.rawType, | 2657 compiler.coreTypes.boolType, |
2656 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 2658 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
2657 } | 2659 } |
2658 HInstruction result = new HBoolify(value, backend.boolType); | 2660 HInstruction result = new HBoolify(value, backend.boolType); |
2659 add(result); | 2661 add(result); |
2660 return result; | 2662 return result; |
2661 } | 2663 } |
2662 | 2664 |
2663 HInstruction attachPosition(HInstruction target, ast.Node node) { | 2665 HInstruction attachPosition(HInstruction target, ast.Node node) { |
2664 if (node != null) { | 2666 if (node != null) { |
2665 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); | 2667 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3238 | 3240 |
3239 List<HInstruction> capturedVariables = <HInstruction>[]; | 3241 List<HInstruction> capturedVariables = <HInstruction>[]; |
3240 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | 3242 closureClassElement.closureFields.forEach((ClosureFieldElement field) { |
3241 Local capturedLocal = | 3243 Local capturedLocal = |
3242 nestedClosureData.getLocalVariableForClosureField(field); | 3244 nestedClosureData.getLocalVariableForClosureField(field); |
3243 assert(capturedLocal != null); | 3245 assert(capturedLocal != null); |
3244 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 3246 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
3245 }); | 3247 }); |
3246 | 3248 |
3247 TypeMask type = | 3249 TypeMask type = |
3248 new TypeMask.nonNullExact(compiler.functionClass, compiler.world); | 3250 new TypeMask.nonNullExact(coreClasses.functionClass, compiler.world); |
3249 push(new HForeignNew(closureClassElement, type, capturedVariables) | 3251 push(new HForeignNew(closureClassElement, type, capturedVariables) |
3250 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); | 3252 ..sourceInformation = sourceInformationBuilder.buildCreate(node)); |
3251 | 3253 |
3252 Element methodElement = nestedClosureData.closureElement; | 3254 Element methodElement = nestedClosureData.closureElement; |
3253 registry?.registerInstantiatedClosure(methodElement); | 3255 registry?.registerInstantiatedClosure(methodElement); |
3254 } | 3256 } |
3255 | 3257 |
3256 visitFunctionDeclaration(ast.FunctionDeclaration node) { | 3258 visitFunctionDeclaration(ast.FunctionDeclaration node) { |
3257 assert(isReachable); | 3259 assert(isReachable); |
3258 visit(node.function); | 3260 visit(node.function); |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4536 ..sourceInformation = sourceInformation); | 4538 ..sourceInformation = sourceInformation); |
4537 } | 4539 } |
4538 | 4540 |
4539 generateSuperNoSuchMethodSend(ast.Send node, | 4541 generateSuperNoSuchMethodSend(ast.Send node, |
4540 Selector selector, | 4542 Selector selector, |
4541 List<HInstruction> arguments) { | 4543 List<HInstruction> arguments) { |
4542 String name = selector.name; | 4544 String name = selector.name; |
4543 | 4545 |
4544 ClassElement cls = currentNonClosureClass; | 4546 ClassElement cls = currentNonClosureClass; |
4545 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 4547 Element element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
4546 if (compiler.enabledInvokeOn | 4548 if (compiler.enabledInvokeOn && !element.enclosingClass.isObject) { |
4547 && element.enclosingElement.declaration != compiler.objectClass) { | |
4548 // Register the call as dynamic if [noSuchMethod] on the super | 4549 // Register the call as dynamic if [noSuchMethod] on the super |
4549 // class is _not_ the default implementation from [Object], in | 4550 // class is _not_ the default implementation from [Object], in |
4550 // case the [noSuchMethod] implementation calls | 4551 // case the [noSuchMethod] implementation calls |
4551 // [JSInvocationMirror._invokeOn]. | 4552 // [JSInvocationMirror._invokeOn]. |
4552 registry?.registerSelectorUse(selector); | 4553 registry?.registerSelectorUse(selector); |
4553 } | 4554 } |
4554 String publicName = name; | 4555 String publicName = name; |
4555 if (selector.isSetter) publicName += '='; | 4556 if (selector.isSetter) publicName += '='; |
4556 | 4557 |
4557 ConstantValue nameConstant = constantSystem.createString( | 4558 ConstantValue nameConstant = constantSystem.createString( |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5204 newInstance.instructionType = elementType; | 5205 newInstance.instructionType = elementType; |
5205 if (context != null) { | 5206 if (context != null) { |
5206 context.allocatedFixedLists.add(newInstance); | 5207 context.allocatedFixedLists.add(newInstance); |
5207 } | 5208 } |
5208 } | 5209 } |
5209 | 5210 |
5210 // The List constructor forwards to a Dart static method that does | 5211 // The List constructor forwards to a Dart static method that does |
5211 // not know about the type argument. Therefore we special case | 5212 // not know about the type argument. Therefore we special case |
5212 // this constructor to have the setRuntimeTypeInfo called where | 5213 // this constructor to have the setRuntimeTypeInfo called where |
5213 // the 'new' is done. | 5214 // the 'new' is done. |
5214 if (backend.classNeedsRti(compiler.listClass) && | 5215 if (backend.classNeedsRti(coreClasses.listClass) && |
5215 (isFixedListConstructorCall || isGrowableListConstructorCall || | 5216 (isFixedListConstructorCall || isGrowableListConstructorCall || |
5216 isJSArrayTypedConstructor)) { | 5217 isJSArrayTypedConstructor)) { |
5217 newInstance = handleListConstructor(type, send, pop()); | 5218 newInstance = handleListConstructor(type, send, pop()); |
5218 stack.add(newInstance); | 5219 stack.add(newInstance); |
5219 } | 5220 } |
5220 | 5221 |
5221 // Finally, if we called a redirecting factory constructor, check the type. | 5222 // Finally, if we called a redirecting factory constructor, check the type. |
5222 if (isRedirected) { | 5223 if (isRedirected) { |
5223 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); | 5224 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); |
5224 if (checked != newInstance) { | 5225 if (checked != newInstance) { |
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7147 // TODO(sigurdm): In an internal library a function could be declared: | 7148 // TODO(sigurdm): In an internal library a function could be declared: |
7148 // | 7149 // |
7149 // _FutureImpl foo async => 1; | 7150 // _FutureImpl foo async => 1; |
7150 // | 7151 // |
7151 // This should be valid (because the actual value returned from an async | 7152 // This should be valid (because the actual value returned from an async |
7152 // function is a `_FutureImpl`), but currently false is returned in this | 7153 // function is a `_FutureImpl`), but currently false is returned in this |
7153 // case. | 7154 // case. |
7154 return type.isDynamic || | 7155 return type.isDynamic || |
7155 type.isObject || | 7156 type.isObject || |
7156 (type is InterfaceType && | 7157 (type is InterfaceType && |
7157 type.element == compiler.futureClass); | 7158 type.element == coreClasses.futureClass); |
7158 } | 7159 } |
7159 | 7160 |
7160 visitReturn(ast.Return node) { | 7161 visitReturn(ast.Return node) { |
7161 if (identical(node.beginToken.stringValue, 'native')) { | 7162 if (identical(node.beginToken.stringValue, 'native')) { |
7162 native.handleSsaNative(this, node.expression); | 7163 native.handleSsaNative(this, node.expression); |
7163 return; | 7164 return; |
7164 } | 7165 } |
7165 HInstruction value; | 7166 HInstruction value; |
7166 if (node.expression == null) { | 7167 if (node.expression == null) { |
7167 value = graph.addConstantNull(compiler); | 7168 value = graph.addConstantNull(compiler); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7200 visitYield(ast.Yield node) { | 7201 visitYield(ast.Yield node) { |
7201 visit(node.expression); | 7202 visit(node.expression); |
7202 HInstruction yielded = pop(); | 7203 HInstruction yielded = pop(); |
7203 add(new HYield(yielded, node.hasStar)); | 7204 add(new HYield(yielded, node.hasStar)); |
7204 } | 7205 } |
7205 | 7206 |
7206 visitAwait(ast.Await node) { | 7207 visitAwait(ast.Await node) { |
7207 visit(node.expression); | 7208 visit(node.expression); |
7208 HInstruction awaited = pop(); | 7209 HInstruction awaited = pop(); |
7209 // TODO(herhut): Improve this type. | 7210 // TODO(herhut): Improve this type. |
7210 push(new HAwait(awaited, new TypeMask.subclass(compiler.objectClass, | 7211 push(new HAwait(awaited, new TypeMask.subclass( |
7211 compiler.world))); | 7212 coreClasses.objectClass, compiler.world))); |
7212 } | 7213 } |
7213 | 7214 |
7214 visitTypeAnnotation(ast.TypeAnnotation node) { | 7215 visitTypeAnnotation(ast.TypeAnnotation node) { |
7215 reporter.internalError(node, | 7216 reporter.internalError(node, |
7216 'Visiting type annotation in SSA builder.'); | 7217 'Visiting type annotation in SSA builder.'); |
7217 } | 7218 } |
7218 | 7219 |
7219 visitVariableDefinitions(ast.VariableDefinitions node) { | 7220 visitVariableDefinitions(ast.VariableDefinitions node) { |
7220 assert(isReachable); | 7221 assert(isReachable); |
7221 for (Link<ast.Node> link = node.definitions.nodes; | 7222 for (Link<ast.Node> link = node.definitions.nodes; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7364 [expression, graph.addConstantNull(compiler)]); | 7365 [expression, graph.addConstantNull(compiler)]); |
7365 streamIterator = pop(); | 7366 streamIterator = pop(); |
7366 | 7367 |
7367 void buildInitializer() {} | 7368 void buildInitializer() {} |
7368 | 7369 |
7369 HInstruction buildCondition() { | 7370 HInstruction buildCondition() { |
7370 Selector selector = elements.getMoveNextSelector(node); | 7371 Selector selector = elements.getMoveNextSelector(node); |
7371 TypeMask mask = elements.getMoveNextTypeMask(node); | 7372 TypeMask mask = elements.getMoveNextTypeMask(node); |
7372 pushInvokeDynamic(node, selector, mask, [streamIterator]); | 7373 pushInvokeDynamic(node, selector, mask, [streamIterator]); |
7373 HInstruction future = pop(); | 7374 HInstruction future = pop(); |
7374 push(new HAwait(future, new TypeMask.subclass(compiler.objectClass, | 7375 push(new HAwait(future, |
7375 compiler.world))); | 7376 new TypeMask.subclass(coreClasses.objectClass, compiler.world))); |
7376 return popBoolified(); | 7377 return popBoolified(); |
7377 } | 7378 } |
7378 void buildBody() { | 7379 void buildBody() { |
7379 Selector call = elements.getCurrentSelector(node); | 7380 Selector call = elements.getCurrentSelector(node); |
7380 TypeMask callMask = elements.getCurrentTypeMask(node); | 7381 TypeMask callMask = elements.getCurrentTypeMask(node); |
7381 pushInvokeDynamic(node, call, callMask, [streamIterator]); | 7382 pushInvokeDynamic(node, call, callMask, [streamIterator]); |
7382 | 7383 |
7383 ast.Node identifier = node.declaredIdentifier; | 7384 ast.Node identifier = node.declaredIdentifier; |
7384 Element variable = elements.getForInVariable(node); | 7385 Element variable = elements.getForInVariable(node); |
7385 Selector selector = elements.getSelector(identifier); | 7386 Selector selector = elements.getSelector(identifier); |
(...skipping 26 matching lines...) Expand all Loading... |
7412 handleLoop(node, | 7413 handleLoop(node, |
7413 buildInitializer, | 7414 buildInitializer, |
7414 buildCondition, | 7415 buildCondition, |
7415 buildUpdate, | 7416 buildUpdate, |
7416 buildBody); | 7417 buildBody); |
7417 }, () { | 7418 }, () { |
7418 pushInvokeDynamic(node, | 7419 pushInvokeDynamic(node, |
7419 Selectors.cancel, | 7420 Selectors.cancel, |
7420 null, | 7421 null, |
7421 [streamIterator]); | 7422 [streamIterator]); |
7422 push(new HAwait(pop(), new TypeMask.subclass(compiler.objectClass, | 7423 push(new HAwait(pop(), new TypeMask.subclass( |
7423 compiler.world))); | 7424 coreClasses.objectClass, compiler.world))); |
7424 pop(); | 7425 pop(); |
7425 }); | 7426 }); |
7426 } | 7427 } |
7427 | 7428 |
7428 visitSyncForIn(ast.SyncForIn node) { | 7429 visitSyncForIn(ast.SyncForIn node) { |
7429 // The 'get iterator' selector for this node has the inferred receiver type. | 7430 // The 'get iterator' selector for this node has the inferred receiver type. |
7430 // If the receiver supports JavaScript indexing we generate an indexing loop | 7431 // If the receiver supports JavaScript indexing we generate an indexing loop |
7431 // instead of allocating an iterator object. | 7432 // instead of allocating an iterator object. |
7432 | 7433 |
7433 // This scheme recognizes for-in on direct lists. It does not recognize all | 7434 // This scheme recognizes for-in on direct lists. It does not recognize all |
(...skipping 1707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9141 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 9142 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
9142 unaliased.accept(this, builder); | 9143 unaliased.accept(this, builder); |
9143 } | 9144 } |
9144 | 9145 |
9145 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9146 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
9146 JavaScriptBackend backend = builder.compiler.backend; | 9147 JavaScriptBackend backend = builder.compiler.backend; |
9147 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 9148 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
9148 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9149 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
9149 } | 9150 } |
9150 } | 9151 } |
OLD | NEW |