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 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 2230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2241 if (member.isField()) { | 2241 if (member.isField()) { |
2242 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 2242 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
2243 assert(capturedLocal != null); | 2243 assert(capturedLocal != null); |
2244 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2244 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
2245 } | 2245 } |
2246 }); | 2246 }); |
2247 | 2247 |
2248 HType type = new HType.nonNullExact( | 2248 HType type = new HType.nonNullExact( |
2249 compiler.functionClass.computeType(compiler), | 2249 compiler.functionClass.computeType(compiler), |
2250 compiler); | 2250 compiler); |
2251 push(new HForeignNew(closureClassElement, type, capturedVariables)); | 2251 HInstruction newClosure = |
2252 new HForeignNew(closureClassElement, type, capturedVariables); | |
2253 ClassElement thisClass = work.element.getEnclosingClass(); | |
ngeoffray
2013/03/13 09:30:46
thisClass can be null right? Don't you need to che
Johnni Winther
2013/03/22 07:30:24
Stale
| |
2254 if (compiler.world.needsRti(thisClass) && | |
2255 callElement.computeType(compiler).containsTypeVariables) { | |
2256 add(newClosure); | |
2257 | |
2258 Element forwardRuntimeTypeInfo = backend.getForwardRuntimeTypeInfo(); | |
2259 HInstruction forwardRuntimeTypeInfoCall = | |
2260 new HStatic(forwardRuntimeTypeInfo); | |
2261 add(forwardRuntimeTypeInfoCall); | |
2262 | |
2263 String substitutionName = backend.namer.substitutionName(thisClass); | |
2264 HInstruction substitution = | |
2265 createForeign('this.$substitutionName', HType.UNKNOWN, []); | |
ngeoffray
2013/03/13 09:30:46
Change "this" to use #.
Johnni Winther
2013/03/22 07:30:24
Stale
| |
2266 add(substitution); | |
2267 | |
2268 HInstruction context = new HThis(thisClass, HType.UNKNOWN); | |
2269 add(context); | |
2270 | |
2271 List<HInstruction> inputs = <HInstruction>[forwardRuntimeTypeInfoCall, | |
2272 newClosure, | |
2273 substitution, | |
2274 context]; | |
2275 push(new HInvokeStatic(inputs, HType.UNKNOWN)); | |
2276 } else { | |
2277 push(newClosure); | |
2278 } | |
2252 } | 2279 } |
2253 | 2280 |
2254 visitFunctionDeclaration(FunctionDeclaration node) { | 2281 visitFunctionDeclaration(FunctionDeclaration node) { |
2255 visit(node.function); | 2282 visit(node.function); |
2256 localsHandler.updateLocal(elements[node], pop()); | 2283 localsHandler.updateLocal(elements[node], pop()); |
2257 } | 2284 } |
2258 | 2285 |
2259 visitIdentifier(Identifier node) { | 2286 visitIdentifier(Identifier node) { |
2260 if (node.isThis()) { | 2287 if (node.isThis()) { |
2261 stack.add(localsHandler.readThis()); | 2288 stack.add(localsHandler.readThis()); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2638 Node argument = node.arguments.head; | 2665 Node argument = node.arguments.head; |
2639 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2666 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
2640 bool isNot = false; | 2667 bool isNot = false; |
2641 // TODO(ngeoffray): Duplicating pattern in resolver. We should | 2668 // TODO(ngeoffray): Duplicating pattern in resolver. We should |
2642 // add a new kind of node. | 2669 // add a new kind of node. |
2643 if (typeAnnotation == null) { | 2670 if (typeAnnotation == null) { |
2644 typeAnnotation = argument.asSend().receiver; | 2671 typeAnnotation = argument.asSend().receiver; |
2645 isNot = true; | 2672 isNot = true; |
2646 } | 2673 } |
2647 DartType type = elements.getType(typeAnnotation); | 2674 DartType type = elements.getType(typeAnnotation); |
2675 type = type.unalias(compiler); | |
2648 if (type.isMalformed) { | 2676 if (type.isMalformed) { |
2649 String reasons = Types.fetchReasonsFromMalformedType(type); | 2677 String reasons = Types.fetchReasonsFromMalformedType(type); |
2650 if (compiler.enableTypeAssertions) { | 2678 if (compiler.enableTypeAssertions) { |
2651 generateMalformedSubtypeError(node, expression, type, reasons); | 2679 generateMalformedSubtypeError(node, expression, type, reasons); |
2652 } else { | 2680 } else { |
2653 generateRuntimeError(node, '$type is malformed: $reasons'); | 2681 generateRuntimeError(node, '$type is malformed: $reasons'); |
2654 } | 2682 } |
2655 return; | 2683 return; |
2656 } | 2684 } |
2657 | 2685 |
2658 HInstruction instruction; | 2686 HInstruction instruction; |
2659 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2687 if (type is FunctionType) { |
ngeoffray
2013/03/13 09:30:46
Use the kind instead?
Johnni Winther
2013/03/22 07:30:24
Done.
| |
2688 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); | |
ngeoffray
2013/03/13 09:30:46
Add a TODO that this should be done in codegen.
Johnni Winther
2013/06/21 12:19:14
Stale.
| |
2689 | |
2690 void functionTypeCheck() { | |
2691 Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); | |
2692 HInstruction isFuncSubtypeCall = new HStatic(checkFunctionSubtype); | |
2693 add(isFuncSubtypeCall); | |
2694 | |
2695 String typeSignatureName; | |
2696 HInstruction context; | |
2697 ClassElement contextClass = Types.getClassContext(type); | |
ngeoffray
2013/03/13 09:30:46
What is this?
Johnni Winther
2013/03/22 07:30:24
The class which declared the used type variables,
| |
2698 if (contextClass != null) { | |
2699 typeSignatureName = backend.namer.signatureName(type); | |
2700 context = new HThis(contextClass, HType.UNKNOWN); | |
ngeoffray
2013/03/13 09:30:46
What's this HThis? Why isn't it the one of the bui
Johnni Winther
2013/03/22 07:30:24
Changed.
| |
2701 add(context); | |
2702 } else { | |
2703 typeSignatureName = backend.namer.signatureName(type); | |
2704 context = graph.addConstantNull(constantSystem); | |
2705 } | |
2706 HInstruction typeSignature = | |
2707 createForeign('$typeSignatureName', HType.UNKNOWN, []); | |
2708 add(typeSignature); | |
2709 | |
2710 List<HInstruction> inputs = <HInstruction>[isFuncSubtypeCall, | |
2711 expression, | |
2712 typeSignature, | |
2713 context]; | |
2714 push(new HInvokeStatic(inputs, HType.UNKNOWN)); | |
2715 } | |
2716 | |
2717 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } | |
2718 | |
2719 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); | |
2720 branchBuilder.handleLogicalAndOr( | |
2721 classCheck, functionTypeCheck, isAnd: true); | |
2722 instruction = pop(); | |
2723 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | |
2660 HInstruction runtimeType = addTypeVariableReference(type); | 2724 HInstruction runtimeType = addTypeVariableReference(type); |
2661 Element helper = backend.getGetObjectIsSubtype(); | 2725 Element helper = backend.getGetObjectIsSubtype(); |
2662 HInstruction helperCall = new HStatic(helper); | 2726 HInstruction helperCall = new HStatic(helper); |
2663 add(helperCall); | 2727 add(helperCall); |
2664 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | 2728 List<HInstruction> inputs = <HInstruction>[helperCall, expression, |
2665 runtimeType]; | 2729 runtimeType]; |
2666 instruction = new HInvokeStatic(inputs, HType.BOOLEAN); | 2730 instruction = new HInvokeStatic(inputs, HType.BOOLEAN); |
2667 add(instruction); | 2731 add(instruction); |
2668 compiler.enqueuer.codegen.registerIsCheck(type, elements); | 2732 compiler.enqueuer.codegen.registerIsCheck(type, elements); |
2669 | 2733 |
(...skipping 2440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5110 new HSubGraphBlockInformation(elseBranch.graph)); | 5174 new HSubGraphBlockInformation(elseBranch.graph)); |
5111 | 5175 |
5112 HBasicBlock conditionStartBlock = conditionBranch.block; | 5176 HBasicBlock conditionStartBlock = conditionBranch.block; |
5113 conditionStartBlock.setBlockFlow(info, joinBlock); | 5177 conditionStartBlock.setBlockFlow(info, joinBlock); |
5114 SubGraph conditionGraph = conditionBranch.graph; | 5178 SubGraph conditionGraph = conditionBranch.graph; |
5115 HIf branch = conditionGraph.end.last; | 5179 HIf branch = conditionGraph.end.last; |
5116 assert(branch is HIf); | 5180 assert(branch is HIf); |
5117 branch.blockInformation = conditionStartBlock.blockFlow; | 5181 branch.blockInformation = conditionStartBlock.blockFlow; |
5118 } | 5182 } |
5119 } | 5183 } |
OLD | NEW |