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 2566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2577 } | 2577 } |
2578 | 2578 |
2579 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2579 HInstruction getRuntimeTypeInfo(HInstruction target) { |
2580 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); | 2580 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
2581 return pop(); | 2581 return pop(); |
2582 } | 2582 } |
2583 | 2583 |
2584 // TODO(karlklose): change construction of the representations to be GVN'able | 2584 // TODO(karlklose): change construction of the representations to be GVN'able |
2585 // (dartbug.com/7182). | 2585 // (dartbug.com/7182). |
2586 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { | 2586 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { |
2587 HInstruction createForeignArray(String code, inputs) { | |
2588 return createForeign(code, HType.READABLE_ARRAY, inputs); | |
2589 } | |
2590 | |
2591 // Compute the representation of the type arguments, including access | 2587 // Compute the representation of the type arguments, including access |
2592 // to the runtime type information for type variables as instructions. | 2588 // to the runtime type information for type variables as instructions. |
2593 HInstruction representations; | 2589 HInstruction representations; |
2594 if (type.element.isTypeVariable()) { | 2590 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2595 return <HInstruction>[addTypeVariableReference(type)]; | 2591 return <HInstruction>[addTypeVariableReference(type)]; |
2596 } else { | 2592 } else { |
2597 assert(type.element.isClass()); | 2593 assert(type.element.isClass()); |
2598 List<HInstruction> arguments = <HInstruction>[]; | 2594 List<HInstruction> arguments = <HInstruction>[]; |
2599 InterfaceType interface = type; | 2595 InterfaceType interface = type; |
2600 for (DartType argument in interface.typeArguments) { | 2596 for (DartType argument in interface.typeArguments) { |
2601 List<HInstruction> inputs = <HInstruction>[]; | 2597 List<HInstruction> inputs = <HInstruction>[]; |
2602 String template = rti.getTypeRepresentation(argument, (variable) { | 2598 String template = rti.getTypeRepresentation(argument, (variable) { |
2603 HInstruction runtimeType = addTypeVariableReference(variable); | 2599 HInstruction runtimeType = addTypeVariableReference(variable); |
2604 inputs.add(runtimeType); | 2600 inputs.add(runtimeType); |
2605 }); | 2601 }); |
2606 HInstruction representation = createForeignArray(template, inputs); | 2602 HInstruction representation = |
| 2603 createForeign(template, HType.READABLE_ARRAY, inputs); |
2607 add(representation); | 2604 add(representation); |
2608 arguments.add(representation); | 2605 arguments.add(representation); |
2609 } | 2606 } |
2610 return arguments; | 2607 return arguments; |
2611 } | 2608 } |
2612 } | 2609 } |
2613 | 2610 |
2614 visitOperatorSend(node) { | 2611 visitOperatorSend(node) { |
2615 Operator op = node.selector; | 2612 Operator op = node.selector; |
2616 if (const SourceString("[]") == op.source) { | 2613 if (const SourceString("[]") == op.source) { |
(...skipping 20 matching lines...) Expand all Loading... |
2637 DartType type = elements.getType(typeAnnotation); | 2634 DartType type = elements.getType(typeAnnotation); |
2638 if (type.isMalformed) { | 2635 if (type.isMalformed) { |
2639 String reasons = Types.fetchReasonsFromMalformedType(type); | 2636 String reasons = Types.fetchReasonsFromMalformedType(type); |
2640 if (compiler.enableTypeAssertions) { | 2637 if (compiler.enableTypeAssertions) { |
2641 generateMalformedSubtypeError(node, expression, type, reasons); | 2638 generateMalformedSubtypeError(node, expression, type, reasons); |
2642 } else { | 2639 } else { |
2643 generateRuntimeError(node, '$type is malformed: $reasons'); | 2640 generateRuntimeError(node, '$type is malformed: $reasons'); |
2644 } | 2641 } |
2645 return; | 2642 return; |
2646 } | 2643 } |
2647 if (type.element.isTypeVariable()) { | |
2648 // TODO(karlklose): remove this check when the backend can deal with | |
2649 // checks of the form [:o is T:] where [:T:] is a type variable. | |
2650 stack.add(graph.addConstantBool(true, constantSystem)); | |
2651 return; | |
2652 } | |
2653 | 2644 |
2654 HInstruction instruction; | 2645 HInstruction instruction; |
2655 if (type.element.isTypeVariable() || | 2646 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2656 RuntimeTypeInformation.hasTypeArguments(type)) { | 2647 List<HInstruction> representations = |
| 2648 buildTypeArgumentRepresentations(type); |
| 2649 assert(representations.length == 1); |
| 2650 HInstruction runtimeType = addTypeVariableReference(type); |
| 2651 Element helper = backend.getGetObjectIsSubtype(); |
| 2652 HInstruction helperCall = new HStatic(helper); |
| 2653 add(helperCall); |
| 2654 List<HInstruction> inputs = <HInstruction>[helperCall, expression, |
| 2655 runtimeType]; |
| 2656 instruction = new HInvokeStatic(inputs, HType.BOOLEAN); |
| 2657 add(instruction); |
| 2658 compiler.enqueuer.codegen.registerIsCheck(type); |
| 2659 |
| 2660 } else if (RuntimeTypeInformation.hasTypeArguments(type)) { |
2657 | 2661 |
2658 void argumentsCheck() { | 2662 void argumentsCheck() { |
2659 HInstruction typeInfo = getRuntimeTypeInfo(expression); | 2663 HInstruction typeInfo = getRuntimeTypeInfo(expression); |
2660 Element helper = backend.getCheckArguments(); | 2664 Element helper = backend.getCheckArguments(); |
2661 HInstruction helperCall = new HStatic(helper); | 2665 HInstruction helperCall = new HStatic(helper); |
2662 add(helperCall); | 2666 add(helperCall); |
2663 List<HInstruction> representations = | 2667 List<HInstruction> representations = |
2664 buildTypeArgumentRepresentations(type); | 2668 buildTypeArgumentRepresentations(type); |
2665 Element element = type.element; | 2669 Element element = type.element; |
2666 String substitution = backend.namer.substitutionName(element); | 2670 String substitution = backend.namer.substitutionName(element); |
2667 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { | 2671 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { |
2668 substitution = '$substitution()'; | 2672 substitution = '$substitution()'; |
2669 } | 2673 } |
2670 HInstruction fieldGet = | 2674 HInstruction fieldGet = |
2671 createForeign('#.$substitution', HType.UNKNOWN, [expression]); | 2675 createForeign('#.$substitution', HType.UNKNOWN, [expression]); |
2672 HInstruction representationList = new HLiteralList(representations); | 2676 HInstruction representationList = new HLiteralList(representations); |
2673 add(fieldGet); | 2677 add(fieldGet); |
2674 add(representationList); | 2678 add(representationList); |
2675 List<HInstruction> inputs = <HInstruction>[helperCall, | 2679 List<HInstruction> inputs = <HInstruction>[helperCall, |
2676 fieldGet, | 2680 fieldGet, |
2677 typeInfo, | 2681 typeInfo, |
2678 representationList]; | 2682 representationList]; |
2679 push(new HInvokeStatic(inputs, HType.UNKNOWN)); | 2683 push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
2680 } | 2684 } |
2681 | 2685 |
2682 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } | 2686 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } |
2683 | 2687 |
2684 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); | 2688 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
2685 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, isAnd: true
); | 2689 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, |
| 2690 isAnd: true); |
2686 instruction = pop(); | 2691 instruction = pop(); |
2687 } else { | 2692 } else { |
2688 instruction = new HIs(type, <HInstruction>[expression]); | 2693 instruction = new HIs(type, <HInstruction>[expression]); |
2689 add(instruction); | 2694 add(instruction); |
2690 } | 2695 } |
2691 if (isNot) { | 2696 if (isNot) { |
2692 instruction = new HNot(instruction); | 2697 instruction = new HNot(instruction); |
2693 add(instruction); | 2698 add(instruction); |
2694 } | 2699 } |
2695 stack.add(instruction); | 2700 stack.add(instruction); |
(...skipping 2394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5090 new HSubGraphBlockInformation(elseBranch.graph)); | 5095 new HSubGraphBlockInformation(elseBranch.graph)); |
5091 | 5096 |
5092 HBasicBlock conditionStartBlock = conditionBranch.block; | 5097 HBasicBlock conditionStartBlock = conditionBranch.block; |
5093 conditionStartBlock.setBlockFlow(info, joinBlock); | 5098 conditionStartBlock.setBlockFlow(info, joinBlock); |
5094 SubGraph conditionGraph = conditionBranch.graph; | 5099 SubGraph conditionGraph = conditionBranch.graph; |
5095 HIf branch = conditionGraph.end.last; | 5100 HIf branch = conditionGraph.end.last; |
5096 assert(branch is HIf); | 5101 assert(branch is HIf); |
5097 branch.blockInformation = conditionStartBlock.blockFlow; | 5102 branch.blockInformation = conditionStartBlock.blockFlow; |
5098 } | 5103 } |
5099 } | 5104 } |
OLD | NEW |