Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1074)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 12210142: Implement is-checks against type variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Do not emit Object.isObject. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2564 matching lines...) Expand 10 before | Expand all | Expand 10 after
2575 } 2575 }
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) {
2586 return createForeign(code, HType.READABLE_ARRAY, inputs);
2587 }
2588
2589 // Compute the representation of the type arguments, including access 2585 // Compute the representation of the type arguments, including access
2590 // to the runtime type information for type variables as instructions. 2586 // to the runtime type information for type variables as instructions.
2591 HInstruction representations; 2587 HInstruction representations;
2592 if (type.element.isTypeVariable()) { 2588 if (type.kind == TypeKind.TYPE_VARIABLE) {
2593 return <HInstruction>[addTypeVariableReference(type)]; 2589 return <HInstruction>[addTypeVariableReference(type)];
2594 } else { 2590 } else {
2595 assert(type.element.isClass()); 2591 assert(type.element.isClass());
2596 List<HInstruction> arguments = <HInstruction>[]; 2592 List<HInstruction> arguments = <HInstruction>[];
2597 InterfaceType interface = type; 2593 InterfaceType interface = type;
2598 for (DartType argument in interface.typeArguments) { 2594 for (DartType argument in interface.typeArguments) {
2599 List<HInstruction> inputs = <HInstruction>[]; 2595 List<HInstruction> inputs = <HInstruction>[];
2600 String template = rti.getTypeRepresentation(argument, (variable) { 2596 String template = rti.getTypeRepresentation(argument, (variable) {
2601 HInstruction runtimeType = addTypeVariableReference(variable); 2597 HInstruction runtimeType = addTypeVariableReference(variable);
2602 inputs.add(runtimeType); 2598 inputs.add(runtimeType);
2603 }); 2599 });
2604 HInstruction representation = createForeignArray(template, inputs); 2600 HInstruction representation =
2601 createForeign(template, HType.READABLE_ARRAY, inputs);
2605 add(representation); 2602 add(representation);
2606 arguments.add(representation); 2603 arguments.add(representation);
2607 } 2604 }
2608 return arguments; 2605 return arguments;
2609 } 2606 }
2610 } 2607 }
2611 2608
2612 visitOperatorSend(node) { 2609 visitOperatorSend(node) {
2613 Operator op = node.selector; 2610 Operator op = node.selector;
2614 if (const SourceString("[]") == op.source) { 2611 if (const SourceString("[]") == op.source) {
(...skipping 11 matching lines...) Expand all
2626 Node argument = node.arguments.head; 2623 Node argument = node.arguments.head;
2627 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); 2624 TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
2628 bool isNot = false; 2625 bool isNot = false;
2629 // TODO(ngeoffray): Duplicating pattern in resolver. We should 2626 // TODO(ngeoffray): Duplicating pattern in resolver. We should
2630 // add a new kind of node. 2627 // add a new kind of node.
2631 if (typeAnnotation == null) { 2628 if (typeAnnotation == null) {
2632 typeAnnotation = argument.asSend().receiver; 2629 typeAnnotation = argument.asSend().receiver;
2633 isNot = true; 2630 isNot = true;
2634 } 2631 }
2635 DartType type = elements.getType(typeAnnotation); 2632 DartType type = elements.getType(typeAnnotation);
2633 compiler.enqueuer.codegen.registerIsCheck(type);
ngeoffray 2013/02/19 09:00:41 Do you need this? Won't the static helper enqueue
2636 if (type.isMalformed) { 2634 if (type.isMalformed) {
2637 String reasons = Types.fetchReasonsFromMalformedType(type); 2635 String reasons = Types.fetchReasonsFromMalformedType(type);
2638 if (compiler.enableTypeAssertions) { 2636 if (compiler.enableTypeAssertions) {
2639 generateMalformedSubtypeError(node, expression, type, reasons); 2637 generateMalformedSubtypeError(node, expression, type, reasons);
2640 } else { 2638 } else {
2641 generateRuntimeError(node, '$type is malformed: $reasons'); 2639 generateRuntimeError(node, '$type is malformed: $reasons');
2642 } 2640 }
2643 return; 2641 return;
2644 } 2642 }
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 2643
2652 HInstruction instruction; 2644 HInstruction instruction;
2653 if (type.element.isTypeVariable() || 2645 if (type.kind == TypeKind.TYPE_VARIABLE) {
2654 RuntimeTypeInformation.hasTypeArguments(type)) { 2646 List<HInstruction> representations =
2647 buildTypeArgumentRepresentations(type);
2648 assert(representations.length == 1);
2649 HInstruction runtimeType = addTypeVariableReference(type);
2650 Element helper =
2651 compiler.findHelper(const SourceString('objectIsSubtype'));
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
2659 } else if (RuntimeTypeInformation.hasTypeArguments(type)) {
2655 2660
2656 void argumentsCheck() { 2661 void argumentsCheck() {
2657 HInstruction typeInfo = getRuntimeTypeInfo(expression); 2662 HInstruction typeInfo = getRuntimeTypeInfo(expression);
2658 Element helper = backend.getCheckArguments(); 2663 Element helper = backend.getCheckArguments();
2659 HInstruction helperCall = new HStatic(helper); 2664 HInstruction helperCall = new HStatic(helper);
2660 add(helperCall); 2665 add(helperCall);
2661 List<HInstruction> representations = 2666 List<HInstruction> representations =
2662 buildTypeArgumentRepresentations(type); 2667 buildTypeArgumentRepresentations(type);
2663 Element element = type.element; 2668 Element element = type.element;
2664 String substitution = backend.namer.substitutionName(element); 2669 String substitution = backend.namer.substitutionName(element);
2665 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { 2670 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
2666 substitution = '$substitution()'; 2671 substitution = '$substitution()';
2667 } 2672 }
2668 HInstruction fieldGet = 2673 HInstruction fieldGet =
2669 createForeign('#.$substitution', HType.UNKNOWN, [expression]); 2674 createForeign('#.$substitution', HType.UNKNOWN, [expression]);
2670 HInstruction representationList = new HLiteralList(representations); 2675 HInstruction representationList = new HLiteralList(representations);
2671 add(fieldGet); 2676 add(fieldGet);
2672 add(representationList); 2677 add(representationList);
2673 List<HInstruction> inputs = <HInstruction>[helperCall, 2678 List<HInstruction> inputs = <HInstruction>[helperCall,
2674 fieldGet, 2679 fieldGet,
2675 typeInfo, 2680 typeInfo,
2676 representationList]; 2681 representationList];
2677 push(new HInvokeStatic(inputs, HType.UNKNOWN)); 2682 push(new HInvokeStatic(inputs, HType.UNKNOWN));
2678 } 2683 }
2679 2684
2680 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } 2685 void classCheck() { push(new HIs(type, <HInstruction>[expression])); }
2681 2686
2682 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); 2687 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
2683 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, isAnd: true ); 2688 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck,
2689 isAnd: true);
2684 instruction = pop(); 2690 instruction = pop();
2685 } else { 2691 } else {
2686 instruction = new HIs(type, <HInstruction>[expression]); 2692 instruction = new HIs(type, <HInstruction>[expression]);
2687 add(instruction); 2693 add(instruction);
2688 } 2694 }
2689 if (isNot) { 2695 if (isNot) {
2690 instruction = new HNot(instruction); 2696 instruction = new HNot(instruction);
2691 add(instruction); 2697 add(instruction);
2692 } 2698 }
2693 stack.add(instruction); 2699 stack.add(instruction);
(...skipping 2378 matching lines...) Expand 10 before | Expand all | Expand 10 after
5072 new HSubGraphBlockInformation(elseBranch.graph)); 5078 new HSubGraphBlockInformation(elseBranch.graph));
5073 5079
5074 HBasicBlock conditionStartBlock = conditionBranch.block; 5080 HBasicBlock conditionStartBlock = conditionBranch.block;
5075 conditionStartBlock.setBlockFlow(info, joinBlock); 5081 conditionStartBlock.setBlockFlow(info, joinBlock);
5076 SubGraph conditionGraph = conditionBranch.graph; 5082 SubGraph conditionGraph = conditionBranch.graph;
5077 HIf branch = conditionGraph.end.last; 5083 HIf branch = conditionGraph.end.last;
5078 assert(branch is HIf); 5084 assert(branch is HIf);
5079 branch.blockInformation = conditionStartBlock.blockFlow; 5085 branch.blockInformation = conditionStartBlock.blockFlow;
5080 } 5086 }
5081 } 5087 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698