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

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: Address comments. Created 7 years, 9 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 2566 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698