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

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: Fix a long line. 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 2507 matching lines...) Expand 10 before | Expand all | Expand 10 after
2518 } 2518 }
2519 2519
2520 HInstruction getRuntimeTypeInfo(HInstruction target) { 2520 HInstruction getRuntimeTypeInfo(HInstruction target) {
2521 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN); 2521 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(), target, HType.UNKNOWN);
2522 return pop(); 2522 return pop();
2523 } 2523 }
2524 2524
2525 // TODO(karlklose): change construction of the representations to be GVN'able 2525 // TODO(karlklose): change construction of the representations to be GVN'able
2526 // (dartbug.com/7182). 2526 // (dartbug.com/7182).
2527 List<HInstruction> buildTypeArgumentRepresentations(DartType type) { 2527 List<HInstruction> buildTypeArgumentRepresentations(DartType type) {
2528 HInstruction createForeignArray(String code, inputs) {
2529 return createForeign(code, HType.READABLE_ARRAY, inputs);
2530 }
2531
2532 // Compute the representation of the type arguments, including access 2528 // Compute the representation of the type arguments, including access
2533 // to the runtime type information for type variables as instructions. 2529 // to the runtime type information for type variables as instructions.
2534 HInstruction representations; 2530 HInstruction representations;
2535 if (type.element.isTypeVariable()) { 2531 if (type.kind == TypeKind.TYPE_VARIABLE) {
2536 return <HInstruction>[addTypeVariableReference(type)]; 2532 return <HInstruction>[addTypeVariableReference(type)];
2537 } else { 2533 } else {
2538 assert(type.element.isClass()); 2534 assert(type.element.isClass());
2539 List<HInstruction> arguments = <HInstruction>[]; 2535 List<HInstruction> arguments = <HInstruction>[];
2540 InterfaceType interface = type; 2536 InterfaceType interface = type;
2541 for (DartType argument in interface.typeArguments) { 2537 for (DartType argument in interface.typeArguments) {
2542 List<HInstruction> inputs = <HInstruction>[]; 2538 List<HInstruction> inputs = <HInstruction>[];
2543 String template = rti.getTypeRepresentation(argument, (variable) { 2539 String template = rti.getTypeRepresentation(argument, (variable) {
2544 HInstruction runtimeType = addTypeVariableReference(variable); 2540 HInstruction runtimeType = addTypeVariableReference(variable);
2545 inputs.add(runtimeType); 2541 inputs.add(runtimeType);
2546 }); 2542 });
2547 HInstruction representation = createForeignArray(template, inputs); 2543 HInstruction representation =
2544 createForeign(template, HType.READABLE_ARRAY, inputs);
2548 add(representation); 2545 add(representation);
2549 arguments.add(representation); 2546 arguments.add(representation);
2550 } 2547 }
2551 return arguments; 2548 return arguments;
2552 } 2549 }
2553 } 2550 }
2554 2551
2555 visitOperatorSend(node) { 2552 visitOperatorSend(node) {
2556 Operator op = node.selector; 2553 Operator op = node.selector;
2557 if (const SourceString("[]") == op.source) { 2554 if (const SourceString("[]") == op.source) {
(...skipping 20 matching lines...) Expand all
2578 DartType type = elements.getType(typeAnnotation); 2575 DartType type = elements.getType(typeAnnotation);
2579 if (type.isMalformed) { 2576 if (type.isMalformed) {
2580 String reasons = Types.fetchReasonsFromMalformedType(type); 2577 String reasons = Types.fetchReasonsFromMalformedType(type);
2581 if (compiler.enableTypeAssertions) { 2578 if (compiler.enableTypeAssertions) {
2582 generateMalformedSubtypeError(node, expression, type, reasons); 2579 generateMalformedSubtypeError(node, expression, type, reasons);
2583 } else { 2580 } else {
2584 generateRuntimeError(node, '$type is malformed: $reasons'); 2581 generateRuntimeError(node, '$type is malformed: $reasons');
2585 } 2582 }
2586 return; 2583 return;
2587 } 2584 }
2588 if (type.element.isTypeVariable()) {
2589 // TODO(karlklose): remove this check when the backend can deal with
2590 // checks of the form [:o is T:] where [:T:] is a type variable.
2591 stack.add(graph.addConstantBool(true, constantSystem));
2592 return;
2593 }
2594 2585
2595 HInstruction instruction; 2586 HInstruction instruction;
2596 if (type.element.isTypeVariable() || 2587 if (type.kind == TypeKind.TYPE_VARIABLE) {
2597 RuntimeTypeInformation.hasTypeArguments(type)) { 2588 List<HInstruction> representations =
2589 buildTypeArgumentRepresentations(type);
2590 assert(representations.length == 1);
2591 HInstruction runtimeType = addTypeVariableReference(type);
2592 Element helper = backend.getGetObjectIsSubtype();
2593 HInstruction helperCall = new HStatic(helper);
2594 add(helperCall);
2595 List<HInstruction> inputs = <HInstruction>[helperCall, expression,
2596 runtimeType];
2597 instruction = new HInvokeStatic(inputs, HType.BOOLEAN);
2598 add(instruction);
2599 compiler.enqueuer.codegen.registerIsCheck(type);
2600
2601 } else if (RuntimeTypeInformation.hasTypeArguments(type)) {
2598 2602
2599 void argumentsCheck() { 2603 void argumentsCheck() {
2600 HInstruction typeInfo = getRuntimeTypeInfo(expression); 2604 HInstruction typeInfo = getRuntimeTypeInfo(expression);
2601 Element helper = backend.getCheckArguments(); 2605 Element helper = backend.getCheckArguments();
2602 HInstruction helperCall = new HStatic(helper); 2606 HInstruction helperCall = new HStatic(helper);
2603 add(helperCall); 2607 add(helperCall);
2604 List<HInstruction> representations = 2608 List<HInstruction> representations =
2605 buildTypeArgumentRepresentations(type); 2609 buildTypeArgumentRepresentations(type);
2606 Element element = type.element; 2610 Element element = type.element;
2607 String substitution = backend.namer.substitutionName(element); 2611 String substitution = backend.namer.substitutionName(element);
2608 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) { 2612 if (backend.emitter.nativeEmitter.requiresNativeIsCheck(element)) {
2609 substitution = '$substitution()'; 2613 substitution = '$substitution()';
2610 } 2614 }
2611 HInstruction fieldGet = 2615 HInstruction fieldGet =
2612 createForeign('#.$substitution', HType.UNKNOWN, [expression]); 2616 createForeign('#.$substitution', HType.UNKNOWN, [expression]);
2613 HInstruction representationList = new HLiteralList(representations); 2617 HInstruction representationList = new HLiteralList(representations);
2614 add(fieldGet); 2618 add(fieldGet);
2615 add(representationList); 2619 add(representationList);
2616 List<HInstruction> inputs = <HInstruction>[helperCall, 2620 List<HInstruction> inputs = <HInstruction>[helperCall,
2617 fieldGet, 2621 fieldGet,
2618 typeInfo, 2622 typeInfo,
2619 representationList]; 2623 representationList];
2620 push(new HInvokeStatic(inputs, HType.UNKNOWN)); 2624 push(new HInvokeStatic(inputs, HType.UNKNOWN));
2621 } 2625 }
2622 2626
2623 void classCheck() { push(new HIs(type, <HInstruction>[expression])); } 2627 void classCheck() { push(new HIs(type, <HInstruction>[expression])); }
2624 2628
2625 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); 2629 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node);
2626 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck, isAnd: true ); 2630 branchBuilder.handleLogicalAndOr(classCheck, argumentsCheck,
2631 isAnd: true);
2627 instruction = pop(); 2632 instruction = pop();
2628 } else { 2633 } else {
2629 instruction = new HIs(type, <HInstruction>[expression]); 2634 instruction = new HIs(type, <HInstruction>[expression]);
2630 add(instruction); 2635 add(instruction);
2631 } 2636 }
2632 if (isNot) { 2637 if (isNot) {
2633 instruction = new HNot(instruction); 2638 instruction = new HNot(instruction);
2634 add(instruction); 2639 add(instruction);
2635 } 2640 }
2636 stack.add(instruction); 2641 stack.add(instruction);
(...skipping 2334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4971 new HSubGraphBlockInformation(elseBranch.graph)); 4976 new HSubGraphBlockInformation(elseBranch.graph));
4972 4977
4973 HBasicBlock conditionStartBlock = conditionBranch.block; 4978 HBasicBlock conditionStartBlock = conditionBranch.block;
4974 conditionStartBlock.setBlockFlow(info, joinBlock); 4979 conditionStartBlock.setBlockFlow(info, joinBlock);
4975 SubGraph conditionGraph = conditionBranch.graph; 4980 SubGraph conditionGraph = conditionBranch.graph;
4976 HIf branch = conditionGraph.end.last; 4981 HIf branch = conditionGraph.end.last;
4977 assert(branch is HIf); 4982 assert(branch is HIf);
4978 branch.blockInformation = conditionStartBlock.blockFlow; 4983 branch.blockInformation = conditionStartBlock.blockFlow;
4979 } 4984 }
4980 } 4985 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698