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 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2576 | 2576 |
2577 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2577 HInstruction getRuntimeTypeInfo(HInstruction target) { |
2578 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); | 2578 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
2579 return pop(); | 2579 return pop(); |
2580 } | 2580 } |
2581 | 2581 |
2582 // TODO(karlklose): change construction of the representations to be GVN'able | 2582 // TODO(karlklose): change construction of the representations to be GVN'able |
2583 // (dartbug.com/7182). | 2583 // (dartbug.com/7182). |
2584 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { | 2584 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { |
2585 HInstruction createForeignArray(String code, inputs) { | 2585 HInstruction createForeignArray(String code, inputs) { |
2586 return createForeign(code, HType.READABLE_ARRAY, inputs); | 2586 return createForeign(code, HType.READABLE_ARRAY, inputs); |
ngeoffray
2013/02/18 09:27:58
I'd remove this helper, it's only called once.
karlklose
2013/02/18 16:02:01
Done.
| |
2587 } | 2587 } |
2588 | 2588 |
2589 // Compute the representation of the type arguments, including access | 2589 // Compute the representation of the type arguments, including access |
2590 // to the runtime type information for type variables as instructions. | 2590 // to the runtime type information for type variables as instructions. |
2591 HInstruction representations; | 2591 HInstruction representations; |
2592 if (type.element.isTypeVariable()) { | 2592 if (type.element.isTypeVariable()) { |
2593 return <HInstruction>[addTypeVariableReference(type)]; | 2593 return <HInstruction>[addTypeVariableReference(type)]; |
2594 } else { | 2594 } else { |
2595 assert(type.element.isClass()); | 2595 assert(type.element.isClass()); |
2596 List<HInstruction> arguments = <HInstruction>[]; | 2596 List<HInstruction> arguments = <HInstruction>[]; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2635 DartType type = elements.getType(typeAnnotation); | 2635 DartType type = elements.getType(typeAnnotation); |
2636 if (type.isMalformed) { | 2636 if (type.isMalformed) { |
2637 String reasons = Types.fetchReasonsFromMalformedType(type); | 2637 String reasons = Types.fetchReasonsFromMalformedType(type); |
2638 if (compiler.enableTypeAssertions) { | 2638 if (compiler.enableTypeAssertions) { |
2639 generateMalformedSubtypeError(node, expression, type, reasons); | 2639 generateMalformedSubtypeError(node, expression, type, reasons); |
2640 } else { | 2640 } else { |
2641 generateRuntimeError(node, '$type is malformed: $reasons'); | 2641 generateRuntimeError(node, '$type is malformed: $reasons'); |
2642 } | 2642 } |
2643 return; | 2643 return; |
2644 } | 2644 } |
2645 if (type.element.isTypeVariable()) { | |
2646 // TODO(karlklose): remove this check when the backend can deal with | |
2647 // checks of the form [:o is T:] where [:T:] is a type variable. | |
2648 stack.add(graph.addConstantBool(true, constantSystem)); | |
2649 return; | |
2650 } | |
2651 | 2645 |
2652 HInstruction instruction; | 2646 HInstruction instruction; |
2653 if (type.element.isTypeVariable() || | 2647 if (type.element.isTypeVariable()) { |
ngeoffray
2013/02/18 09:27:58
Don't we have a check on the type to know if it's
karlklose
2013/02/18 16:02:01
No, we only have these helpers on elements. Replac
| |
2654 RuntimeTypeInformation.hasTypeArguments(type)) { | 2648 List<HInstruction> representations = |
2649 buildTypeArgumentRepresentations(type); | |
2650 assert(representations.length == 1); | |
2651 HInstruction runtimeType = representations[0]; | |
ngeoffray
2013/02/18 09:27:58
Instead of asserting it's 1 and fetching the first
karlklose
2013/02/18 16:02:01
Done.
| |
2652 Element helper = | |
2653 compiler.findHelper(const SourceString('objectIsSubtype')); | |
2654 HInstruction helperCall = new HStatic(helper); | |
2655 add(helperCall); | |
2656 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | |
2657 runtimeType]; | |
2658 instruction = new HInvokeStatic(inputs, HType.UNKNOWN); | |
ngeoffray
2013/02/18 09:27:58
HType.BOOLEAN?
karlklose
2013/02/18 16:02:01
Done.
| |
2659 add(instruction); | |
ngeoffray
2013/02/18 09:27:58
Register in codegen world?
karlklose
2013/02/18 16:02:01
Done.
| |
2660 | |
2661 } else if (RuntimeTypeInformation.hasTypeArguments(type)) { | |
2655 | 2662 |
2656 void argumentsCheck() { | 2663 void argumentsCheck() { |
2657 HInstruction typeInfo = getRuntimeTypeInfo(expression); | 2664 HInstruction typeInfo = getRuntimeTypeInfo(expression); |
2658 Element helper = | 2665 Element helper = |
2659 compiler.findHelper(const SourceString('checkArguments')); | 2666 compiler.findHelper(const SourceString('checkArguments')); |
2660 HInstruction helperCall = new HStatic(helper); | 2667 HInstruction helperCall = new HStatic(helper); |
2661 add(helperCall); | 2668 add(helperCall); |
2662 List<HInstruction> representations = | 2669 List<HInstruction> representations = |
2663 buildTypeArgumentRepresentations(type); | 2670 buildTypeArgumentRepresentations(type); |
2664 Element element = type.element; | 2671 Element element = type.element; |
2665 String substitution = backend.namer.substitutionName(element); | 2672 String substitution = backend.namer.substitutionName(element); |
2666 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { | 2673 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { |
2667 substitution = '$substitution()'; | 2674 substitution = '$substitution()'; |
2668 } | 2675 } |
2669 HInstruction fieldGet = | 2676 HInstruction fieldGet = |
2670 createForeign('#.$substitution', HType.UNKNOWN, [expression]); | 2677 createForeign('#.$substitution', HType.UNKNOWN, [expression]); |
2671 HInstruction representationList = new HLiteralList(representations); | 2678 HInstruction representationList = new HLiteralList(representations); |
2672 add(fieldGet); | 2679 add(fieldGet); |
2673 add(representationList); | 2680 add(representationList); |
2674 List<HInstruction> inputs = <HInstruction>[helperCall, | 2681 List<HInstruction> inputs = <HInstruction>[helperCall, |
2675 fieldGet, | 2682 fieldGet, |
2676 typeInfo, | 2683 typeInfo, |
2677 representationList]; | 2684 representationList]; |
2678 push(new HInvokeStatic(inputs, HType.UNKNOWN)); | 2685 push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
2679 } | 2686 } |
2680 | 2687 |
2681 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } | 2688 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } |
2682 | 2689 |
2683 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); | 2690 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
2684 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, isAnd: true ); | 2691 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, |
2692 isAnd: true); | |
2685 instruction = pop(); | 2693 instruction = pop(); |
2686 } else { | 2694 } else { |
2687 instruction = new HIs(type, <HInstruction>[expression]); | 2695 instruction = new HIs(type, <HInstruction>[expression]); |
2688 add(instruction); | 2696 add(instruction); |
2689 } | 2697 } |
2690 if (isNot) { | 2698 if (isNot) { |
2691 instruction = new HNot(instruction); | 2699 instruction = new HNot(instruction); |
2692 add(instruction); | 2700 add(instruction); |
2693 } | 2701 } |
2694 stack.add(instruction); | 2702 stack.add(instruction); |
(...skipping 2369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5064 new HSubGraphBlockInformation(elseBranch.graph)); | 5072 new HSubGraphBlockInformation(elseBranch.graph)); |
5065 | 5073 |
5066 HBasicBlock conditionStartBlock = conditionBranch.block; | 5074 HBasicBlock conditionStartBlock = conditionBranch.block; |
5067 conditionStartBlock.setBlockFlow(info, joinBlock); | 5075 conditionStartBlock.setBlockFlow(info, joinBlock); |
5068 SubGraph conditionGraph = conditionBranch.graph; | 5076 SubGraph conditionGraph = conditionBranch.graph; |
5069 HIf branch = conditionGraph.end.last; | 5077 HIf branch = conditionGraph.end.last; |
5070 assert(branch is HIf); | 5078 assert(branch is HIf); |
5071 branch.blockInformation = conditionStartBlock.blockFlow; | 5079 branch.blockInformation = conditionStartBlock.blockFlow; |
5072 } | 5080 } |
5073 } | 5081 } |
OLD | NEW |