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 2570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2581 return new HForeign(new LiteralDartString(code), type, inputs); | 2581 return new HForeign(new LiteralDartString(code), type, inputs); |
2582 } | 2582 } |
2583 | 2583 |
2584 HInstruction getRuntimeTypeInfo(HInstruction target) { | 2584 HInstruction getRuntimeTypeInfo(HInstruction target) { |
2585 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); | 2585 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); |
2586 return pop(); | 2586 return pop(); |
2587 } | 2587 } |
2588 | 2588 |
2589 // TODO(karlklose): change construction of the representations to be GVN'able | 2589 // TODO(karlklose): change construction of the representations to be GVN'able |
2590 // (dartbug.com/7182). | 2590 // (dartbug.com/7182). |
2591 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { | 2591 HInstruction buildTypeArgumentRepresentations(DartType type) { |
2592 // Compute the representation of the type arguments, including access | 2592 // Compute the representation of the type arguments, including access |
2593 // to the runtime type information for type variables as instructions. | 2593 // to the runtime type information for type variables as instructions. |
2594 HInstruction representations; | |
2595 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2594 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2596 return <HInstruction>[addTypeVariableReference(type)]; | 2595 return new HLiteralList(<HInstruction>[addTypeVariableReference(type)]); |
2597 } else { | 2596 } else { |
2598 assert(type.element.isClass()); | 2597 assert(type.element.isClass()); |
2599 List<HInstruction> arguments = <HInstruction>[]; | |
2600 InterfaceType interface = type; | 2598 InterfaceType interface = type; |
2599 List<HInstruction> inputs = <HInstruction>[]; | |
2600 bool first = true; | |
2601 List<String> templates = <String>[]; | |
2601 for (DartType argument in interface.typeArguments) { | 2602 for (DartType argument in interface.typeArguments) { |
2602 List<HInstruction> inputs = <HInstruction>[]; | 2603 templates.add(rti.getTypeRepresentation(argument, (variable) { |
2603 String template = rti.getTypeRepresentation(argument, (variable) { | |
2604 HInstruction runtimeType = addTypeVariableReference(variable); | 2604 HInstruction runtimeType = addTypeVariableReference(variable); |
2605 inputs.add(runtimeType); | 2605 inputs.add(runtimeType); |
2606 }); | 2606 })); |
2607 HInstruction representation = | |
2608 createForeign(template, HType.READABLE_ARRAY, inputs); | |
2609 add(representation); | |
2610 arguments.add(representation); | |
2611 } | 2607 } |
ngeoffray
2013/03/07 10:13:57
Move the code below in the else part. Or just remo
karlklose
2013/03/07 11:22:18
It is in the else part.
| |
2612 return arguments; | 2608 String template = '[${templates.join(', ')}]'; |
2609 HInstruction representation = | |
2610 createForeign(template, HType.READABLE_ARRAY, inputs); | |
2611 return representation; | |
2613 } | 2612 } |
2614 } | 2613 } |
2615 | 2614 |
2616 visitOperatorSend(node) { | 2615 visitOperatorSend(node) { |
2617 Operator op = node.selector; | 2616 Operator op = node.selector; |
2618 if (const SourceString("[]") == op.source) { | 2617 if (const SourceString("[]") == op.source) { |
2619 visitDynamicSend(node); | 2618 visitDynamicSend(node); |
2620 } else if (const SourceString("&&") == op.source || | 2619 } else if (const SourceString("&&") == op.source || |
2621 const SourceString("||") == op.source) { | 2620 const SourceString("||") == op.source) { |
2622 visitLogicalAndOr(node, op); | 2621 visitLogicalAndOr(node, op); |
(...skipping 19 matching lines...) Expand all Loading... | |
2642 if (compiler.enableTypeAssertions) { | 2641 if (compiler.enableTypeAssertions) { |
2643 generateMalformedSubtypeError(node, expression, type, reasons); | 2642 generateMalformedSubtypeError(node, expression, type, reasons); |
2644 } else { | 2643 } else { |
2645 generateRuntimeError(node, '$type is malformed: $reasons'); | 2644 generateRuntimeError(node, '$type is malformed: $reasons'); |
2646 } | 2645 } |
2647 return; | 2646 return; |
2648 } | 2647 } |
2649 | 2648 |
2650 HInstruction instruction; | 2649 HInstruction instruction; |
2651 if (type.kind == TypeKind.TYPE_VARIABLE) { | 2650 if (type.kind == TypeKind.TYPE_VARIABLE) { |
2652 List<HInstruction> representations = | |
2653 buildTypeArgumentRepresentations(type); | |
2654 assert(representations.length == 1); | |
2655 HInstruction runtimeType = addTypeVariableReference(type); | 2651 HInstruction runtimeType = addTypeVariableReference(type); |
2656 Element helper = backend.getGetObjectIsSubtype(); | 2652 Element helper = backend.getGetObjectIsSubtype(); |
2657 HInstruction helperCall = new HStatic(helper); | 2653 HInstruction helperCall = new HStatic(helper); |
2658 add(helperCall); | 2654 add(helperCall); |
2659 List<HInstruction> inputs = <HInstruction>[helperCall, expression, | 2655 List<HInstruction> inputs = <HInstruction>[helperCall, expression, |
2660 runtimeType]; | 2656 runtimeType]; |
2661 instruction = new HInvokeStatic(inputs, HType.BOOLEAN); | 2657 instruction = new HInvokeStatic(inputs, HType.BOOLEAN); |
2662 add(instruction); | 2658 add(instruction); |
2663 compiler.enqueuer.codegen.registerIsCheck(type); | 2659 compiler.enqueuer.codegen.registerIsCheck(type); |
2664 | 2660 |
2665 } else if (RuntimeTypeInformation.hasTypeArguments(type)) { | 2661 } else if (RuntimeTypeInformation.hasTypeArguments(type)) { |
2666 | 2662 |
2667 void argumentsCheck() { | 2663 void argumentsCheck() { |
2668 HInstruction typeInfo = getRuntimeTypeInfo(expression); | 2664 HInstruction typeInfo = getRuntimeTypeInfo(expression); |
2669 Element helper = backend.getCheckArguments(); | 2665 Element helper = backend.getCheckArguments(); |
2670 HInstruction helperCall = new HStatic(helper); | 2666 HInstruction helperCall = new HStatic(helper); |
2671 add(helperCall); | 2667 add(helperCall); |
2672 List<HInstruction> representations = | 2668 HInstruction representations = |
2673 buildTypeArgumentRepresentations(type); | 2669 buildTypeArgumentRepresentations(type); |
2670 add(representations); | |
2674 Element element = type.element; | 2671 Element element = type.element; |
2675 String substitution = backend.namer.substitutionName(element); | 2672 String substitution = backend.namer.substitutionName(element); |
2676 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { | 2673 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { |
2677 substitution = '$substitution()'; | 2674 substitution = '$substitution()'; |
2678 } | 2675 } |
2679 HInstruction fieldGet = | 2676 HInstruction fieldGet = |
2680 createForeign('#.$substitution', HType.UNKNOWN, [expression]); | 2677 createForeign('#.$substitution', HType.UNKNOWN, [expression]); |
2681 HInstruction representationList = new HLiteralList(representations); | |
2682 add(fieldGet); | 2678 add(fieldGet); |
2683 add(representationList); | |
2684 List<HInstruction> inputs = <HInstruction>[helperCall, | 2679 List<HInstruction> inputs = <HInstruction>[helperCall, |
2685 fieldGet, | 2680 fieldGet, |
2686 typeInfo, | 2681 typeInfo, |
2687 representationList]; | 2682 representations]; |
2688 push(new HInvokeStatic(inputs, HType.UNKNOWN)); | 2683 push(new HInvokeStatic(inputs, HType.UNKNOWN)); |
2689 } | 2684 } |
2690 | 2685 |
2691 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } | 2686 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } |
2692 | 2687 |
2693 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); | 2688 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
2694 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, | 2689 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, |
2695 isAnd: true); | 2690 isAnd: true); |
2696 instruction = pop(); | 2691 instruction = pop(); |
2697 } else { | 2692 } else { |
(...skipping 2397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5095 new HSubGraphBlockInformation(elseBranch.graph)); | 5090 new HSubGraphBlockInformation(elseBranch.graph)); |
5096 | 5091 |
5097 HBasicBlock conditionStartBlock = conditionBranch.block; | 5092 HBasicBlock conditionStartBlock = conditionBranch.block; |
5098 conditionStartBlock.setBlockFlow(info, joinBlock); | 5093 conditionStartBlock.setBlockFlow(info, joinBlock); |
5099 SubGraph conditionGraph = conditionBranch.graph; | 5094 SubGraph conditionGraph = conditionBranch.graph; |
5100 HIf branch = conditionGraph.end.last; | 5095 HIf branch = conditionGraph.end.last; |
5101 assert(branch is HIf); | 5096 assert(branch is HIf); |
5102 branch.blockInformation = conditionStartBlock.blockFlow; | 5097 branch.blockInformation = conditionStartBlock.blockFlow; |
5103 } | 5098 } |
5104 } | 5099 } |
OLD | NEW |