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 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 HParameterValue param = addParameter(typeVariable.element); | 1620 HParameterValue param = addParameter(typeVariable.element); |
1621 localsHandler.directLocals[typeVariable.element] = param; | 1621 localsHandler.directLocals[typeVariable.element] = param; |
1622 }); | 1622 }); |
1623 } | 1623 } |
1624 } | 1624 } |
1625 | 1625 |
1626 HInstruction potentiallyCheckType( | 1626 HInstruction potentiallyCheckType( |
1627 HInstruction original, DartType type, | 1627 HInstruction original, DartType type, |
1628 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { | 1628 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
1629 if (!compiler.enableTypeAssertions) return original; | 1629 if (!compiler.enableTypeAssertions) return original; |
| 1630 type = type.unalias(compiler); |
1630 HInstruction other = original.convertType(compiler, type, kind); | 1631 HInstruction other = original.convertType(compiler, type, kind); |
1631 if (other != original) add(other); | 1632 if (other != original) add(other); |
| 1633 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); |
1632 return other; | 1634 return other; |
1633 } | 1635 } |
1634 | 1636 |
1635 HGraph closeFunction() { | 1637 HGraph closeFunction() { |
1636 // TODO(kasperl): Make this goto an implicit return. | 1638 // TODO(kasperl): Make this goto an implicit return. |
1637 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); | 1639 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); |
1638 graph.finalize(); | 1640 graph.finalize(); |
1639 return graph; | 1641 return graph; |
1640 } | 1642 } |
1641 | 1643 |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; | 2226 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; |
2225 assert(capturedLocal != null); | 2227 assert(capturedLocal != null); |
2226 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | 2228 capturedVariables.add(localsHandler.readLocal(capturedLocal)); |
2227 } | 2229 } |
2228 }); | 2230 }); |
2229 | 2231 |
2230 HType type = new HType.nonNullExact( | 2232 HType type = new HType.nonNullExact( |
2231 compiler.functionClass.computeType(compiler), | 2233 compiler.functionClass.computeType(compiler), |
2232 compiler); | 2234 compiler); |
2233 push(new HForeignNew(closureClassElement, type, capturedVariables)); | 2235 push(new HForeignNew(closureClassElement, type, capturedVariables)); |
| 2236 |
| 2237 Element methodElement = nestedClosureData.closureElement; |
| 2238 if (compiler.backend.methodNeedsRti(methodElement)) { |
| 2239 compiler.backend.registerGenericClosure( |
| 2240 methodElement, compiler.enqueuer.codegen, work.resolutionTree); |
| 2241 } |
2234 } | 2242 } |
2235 | 2243 |
2236 visitFunctionDeclaration(FunctionDeclaration node) { | 2244 visitFunctionDeclaration(FunctionDeclaration node) { |
2237 visit(node.function); | 2245 visit(node.function); |
2238 localsHandler.updateLocal(elements[node], pop()); | 2246 localsHandler.updateLocal(elements[node], pop()); |
2239 } | 2247 } |
2240 | 2248 |
2241 visitIdentifier(Identifier node) { | 2249 visitIdentifier(Identifier node) { |
2242 if (node.isThis()) { | 2250 if (node.isThis()) { |
2243 stack.add(localsHandler.readThis()); | 2251 stack.add(localsHandler.readThis()); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2602 inputs.add(runtimeType); | 2610 inputs.add(runtimeType); |
2603 })); | 2611 })); |
2604 } | 2612 } |
2605 String template = '[${templates.join(', ')}]'; | 2613 String template = '[${templates.join(', ')}]'; |
2606 HInstruction representation = | 2614 HInstruction representation = |
2607 createForeign(template, HType.READABLE_ARRAY, inputs); | 2615 createForeign(template, HType.READABLE_ARRAY, inputs); |
2608 return representation; | 2616 return representation; |
2609 } | 2617 } |
2610 } | 2618 } |
2611 | 2619 |
2612 visitOperatorSend(node) { | 2620 visitOperatorSend(Send node) { |
2613 Operator op = node.selector; | 2621 Operator op = node.selector; |
2614 if (const SourceString("[]") == op.source) { | 2622 if (const SourceString("[]") == op.source) { |
2615 visitDynamicSend(node); | 2623 visitDynamicSend(node); |
2616 } else if (const SourceString("&&") == op.source || | 2624 } else if (const SourceString("&&") == op.source || |
2617 const SourceString("||") == op.source) { | 2625 const SourceString("||") == op.source) { |
2618 visitLogicalAndOr(node, op); | 2626 visitLogicalAndOr(node, op); |
2619 } else if (const SourceString("!") == op.source) { | 2627 } else if (const SourceString("!") == op.source) { |
2620 visitLogicalNot(node); | 2628 visitLogicalNot(node); |
2621 } else if (node.argumentsNode is Prefix) { | 2629 } else if (node.argumentsNode is Prefix) { |
2622 visitUnary(node, op); | 2630 visitUnary(node, op); |
(...skipping 24 matching lines...) Expand all Loading... |
2647 HInstruction expression = pop(); | 2655 HInstruction expression = pop(); |
2648 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2656 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
2649 bool isNot = false; | 2657 bool isNot = false; |
2650 // TODO(ngeoffray): Duplicating pattern in resolver. We should | 2658 // TODO(ngeoffray): Duplicating pattern in resolver. We should |
2651 // add a new kind of node. | 2659 // add a new kind of node. |
2652 if (typeAnnotation == null) { | 2660 if (typeAnnotation == null) { |
2653 typeAnnotation = argument.asSend().receiver; | 2661 typeAnnotation = argument.asSend().receiver; |
2654 isNot = true; | 2662 isNot = true; |
2655 } | 2663 } |
2656 DartType type = elements.getType(typeAnnotation); | 2664 DartType type = elements.getType(typeAnnotation); |
| 2665 type = type.unalias(compiler); |
2657 if (type.isMalformed) { | 2666 if (type.isMalformed) { |
2658 String reasons = Types.fetchReasonsFromMalformedType(type); | 2667 String reasons = Types.fetchReasonsFromMalformedType(type); |
2659 if (compiler.enableTypeAssertions) { | 2668 if (compiler.enableTypeAssertions) { |
2660 generateMalformedSubtypeError(node, expression, type, reasons); | 2669 generateMalformedSubtypeError(node, expression, type, reasons); |
2661 } else { | 2670 } else { |
2662 generateRuntimeError(node, '$type is malformed: $reasons'); | 2671 generateRuntimeError(node, '$type is malformed: $reasons'); |
2663 } | 2672 } |
2664 return; | 2673 return; |
2665 } | 2674 } |
2666 | 2675 |
2667 HInstruction instruction; | 2676 HInstruction instruction; |
2668 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2677 if (type.kind == TypeKind.FUNCTION) { |
| 2678 Element checkFunctionSubtype = backend.getCheckFunctionSubtype(); |
| 2679 HInstruction isFuncSubtypeCall = new HStatic(checkFunctionSubtype); |
| 2680 add(isFuncSubtypeCall); |
| 2681 |
| 2682 HInstruction signatureName = graph.addConstantString( |
| 2683 new DartString.literal(backend.namer.getFunctionTypeName(type)), |
| 2684 node, constantSystem); |
| 2685 |
| 2686 HInstruction context; |
| 2687 HInstruction contextName; |
| 2688 if (type.containsTypeVariables) { |
| 2689 context = localsHandler.readThis(); |
| 2690 |
| 2691 ClassElement contextClass = Types.getClassContext(type); |
| 2692 contextName = graph.addConstantString( |
| 2693 new DartString.literal(backend.namer.getName(contextClass)), |
| 2694 node, constantSystem); |
| 2695 } else { |
| 2696 context = graph.addConstantNull(constantSystem); |
| 2697 contextName = graph.addConstantNull(constantSystem); |
| 2698 } |
| 2699 |
| 2700 List<HInstruction> inputs = <HInstruction>[isFuncSubtypeCall, |
| 2701 expression, |
| 2702 signatureName, |
| 2703 context, |
| 2704 contextName]; |
| 2705 HInstruction call = new HInvokeStatic(inputs, HType.UNKNOWN); |
| 2706 add(call); |
| 2707 instruction = new HIs(type, <HInstruction>[expression, call], |
| 2708 HIs.COMPOUND_CHECK); |
| 2709 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
2669 HInstruction runtimeType = addTypeVariableReference(type); | 2710 HInstruction runtimeType = addTypeVariableReference(type); |
2670 Element helper = backend.getGetObjectIsSubtype(); | 2711 Element helper = backend.getGetObjectIsSubtype(); |
2671 HInstruction helperCall = new HStatic(helper); | 2712 HInstruction helperCall = new HStatic(helper); |
2672 add(helperCall); | 2713 add(helperCall); |
2673 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | 2714 List<HInstruction> inputs = <HInstruction>[helperCall, expression, |
2674 runtimeType]; | 2715 runtimeType]; |
2675 HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN); | 2716 HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN); |
2676 add(call); | 2717 add(call); |
2677 instruction = new HIs(type, <HInstruction>[expression, call], | 2718 instruction = new HIs(type, <HInstruction>[expression, call], |
2678 HIs.VARIABLE_CHECK); | 2719 HIs.VARIABLE_CHECK); |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3034 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { | 3075 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { |
3035 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); | 3076 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); |
3036 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { | 3077 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { |
3037 handleForeignSetCurrentIsolate(node); | 3078 handleForeignSetCurrentIsolate(node); |
3038 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { | 3079 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { |
3039 handleForeignCreateIsolate(node); | 3080 handleForeignCreateIsolate(node); |
3040 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { | 3081 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { |
3041 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); | 3082 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); |
3042 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { | 3083 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { |
3043 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); | 3084 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); |
| 3085 } else if (name == const SourceString('JS_SIGNATURE_NAME')) { |
| 3086 stack.add(addConstantString(node, backend.namer.operatorSignature())); |
| 3087 } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) { |
| 3088 stack.add(addConstantString(node, backend.namer.functionTypeTag())); |
| 3089 } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) { |
| 3090 stack.add(addConstantString(node, |
| 3091 backend.namer.functionTypeVoidReturnTag())); |
| 3092 } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) { |
| 3093 stack.add(addConstantString(node, |
| 3094 backend.namer.functionTypeReturnTypeTag())); |
| 3095 } else if (name == |
| 3096 const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) { |
| 3097 stack.add(addConstantString(node, |
| 3098 backend.namer.functionTypeRequiredParametersTag())); |
| 3099 } else if (name == |
| 3100 const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) { |
| 3101 stack.add(addConstantString(node, |
| 3102 backend.namer.functionTypeOptionalParametersTag())); |
| 3103 } else if (name == |
| 3104 const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) { |
| 3105 stack.add(addConstantString(node, |
| 3106 backend.namer.functionTypeNamedParametersTag())); |
3044 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { | 3107 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { |
3045 handleForeignDartObjectJsConstructorFunction(node); | 3108 handleForeignDartObjectJsConstructorFunction(node); |
3046 } else { | 3109 } else { |
3047 throw "Unknown foreign: ${selector}"; | 3110 throw "Unknown foreign: ${selector}"; |
3048 } | 3111 } |
3049 } | 3112 } |
3050 | 3113 |
3051 generateSuperNoSuchMethodSend(Send node, | 3114 generateSuperNoSuchMethodSend(Send node, |
3052 Selector selector, | 3115 Selector selector, |
3053 List<HInstruction> arguments) { | 3116 List<HInstruction> arguments) { |
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5110 new HSubGraphBlockInformation(elseBranch.graph)); | 5173 new HSubGraphBlockInformation(elseBranch.graph)); |
5111 | 5174 |
5112 HBasicBlock conditionStartBlock = conditionBranch.block; | 5175 HBasicBlock conditionStartBlock = conditionBranch.block; |
5113 conditionStartBlock.setBlockFlow(info, joinBlock); | 5176 conditionStartBlock.setBlockFlow(info, joinBlock); |
5114 SubGraph conditionGraph = conditionBranch.graph; | 5177 SubGraph conditionGraph = conditionBranch.graph; |
5115 HIf branch = conditionGraph.end.last; | 5178 HIf branch = conditionGraph.end.last; |
5116 assert(branch is HIf); | 5179 assert(branch is HIf); |
5117 branch.blockInformation = conditionStartBlock.blockFlow; | 5180 branch.blockInformation = conditionStartBlock.blockFlow; |
5118 } | 5181 } |
5119 } | 5182 } |
OLD | NEW |