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

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

Issue 12211012: Revert "Implement substitution for type variables." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 2569 matching lines...) Expand 10 before | Expand all | Expand 10 after
2580 } else { 2580 } else {
2581 assert(type.element.isClass()); 2581 assert(type.element.isClass());
2582 List<HInstruction> arguments = <HInstruction>[]; 2582 List<HInstruction> arguments = <HInstruction>[];
2583 InterfaceType interface = type; 2583 InterfaceType interface = type;
2584 for (DartType argument in interface.typeArguments) { 2584 for (DartType argument in interface.typeArguments) {
2585 List<HInstruction> inputs = <HInstruction>[]; 2585 List<HInstruction> inputs = <HInstruction>[];
2586 String template = rti.getTypeRepresentation(argument, (variable) { 2586 String template = rti.getTypeRepresentation(argument, (variable) {
2587 HInstruction runtimeType = getTypeArgument(variable); 2587 HInstruction runtimeType = getTypeArgument(variable);
2588 add(runtimeType); 2588 add(runtimeType);
2589 inputs.add(runtimeType); 2589 inputs.add(runtimeType);
2590 return '#';
2591 }); 2590 });
2592 HInstruction representation = createForeignArray(template, inputs); 2591 HInstruction representation = createForeignArray(template, inputs);
2593 add(representation); 2592 add(representation);
2594 arguments.add(representation); 2593 arguments.add(representation);
2595 } 2594 }
2596 return arguments; 2595 return arguments;
2597 } 2596 }
2598 } 2597 }
2599 2598
2600 visitOperatorSend(node) { 2599 visitOperatorSend(node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2634 // TODO(karlklose): remove this check when the backend can deal with 2633 // TODO(karlklose): remove this check when the backend can deal with
2635 // checks of the form [:o is T:] where [:T:] is a type variable. 2634 // checks of the form [:o is T:] where [:T:] is a type variable.
2636 stack.add(graph.addConstantBool(true, constantSystem)); 2635 stack.add(graph.addConstantBool(true, constantSystem));
2637 return; 2636 return;
2638 } 2637 }
2639 2638
2640 HInstruction instruction; 2639 HInstruction instruction;
2641 if (type.element.isTypeVariable() || 2640 if (type.element.isTypeVariable() ||
2642 RuntimeTypeInformation.hasTypeArguments(type)) { 2641 RuntimeTypeInformation.hasTypeArguments(type)) {
2643 HInstruction typeInfo = getRuntimeTypeInfo(expression); 2642 HInstruction typeInfo = getRuntimeTypeInfo(expression);
2644 Element helper = 2643 // TODO(karlklose): make isSubtype a HInstruction to enable
2645 compiler.findHelper(const SourceString('checkArguments')); 2644 // optimizations?
2646 HInstruction helperCall = new HStatic(helper); 2645 Element helper = compiler.findHelper(const SourceString('isSubtype'));
2647 add(helperCall); 2646 HInstruction isSubtype = new HStatic(helper);
2647 add(isSubtype);
2648 // Build a list of representations for the type arguments.
2648 List<HInstruction> representations = 2649 List<HInstruction> representations =
2649 buildTypeArgumentRepresentations(type); 2650 buildTypeArgumentRepresentations(type);
2650 String substitution = backend.namer.substitutionName(type.element); 2651 // For each type argument, build a call to isSubtype, with the type
2651 HInstruction fieldGet = 2652 // argument as first and the representation of the tested type as
2652 createForeign('#.$substitution', HType.UNKNOWN, [expression]); 2653 // second argument.
2653 HInstruction representationList = new HLiteralList(representations); 2654 List<HInstruction> checks = <HInstruction>[];
2654 add(fieldGet); 2655 int index = 0;
2655 add(representationList); 2656 representations.forEach((HInstruction representation) {
2656 List<HInstruction> inputs = <HInstruction>[helperCall, 2657 HInstruction position = graph.addConstantInt(index, constantSystem);
2657 fieldGet, 2658 // Get the index'th type argument from the runtime type information.
2658 typeInfo, 2659 HInstruction typeArgument =
2659 representationList]; 2660 createForeign('#[#]', HType.UNKNOWN, [typeInfo, position]);
2660 HInstruction check = new HInvokeStatic(inputs); 2661 add(typeArgument);
2661 add(check); 2662 // Create the call to isSubtype.
2662 instruction = new HIs(type, <HInstruction>[expression, check]); 2663 List<HInstruction> inputs =
2664 <HInstruction>[isSubtype, typeArgument, representation];
2665 HInstruction call = new HInvokeStatic(inputs);
2666 add(call);
2667 checks.add(call);
2668 index++;
2669 });
2670 instruction = new HIs(type, <HInstruction>[expression]..addAll(checks));
2663 } else { 2671 } else {
2664 instruction = new HIs(type, <HInstruction>[expression]); 2672 instruction = new HIs(type, <HInstruction>[expression]);
2665 } 2673 }
2666 if (isNot) { 2674 if (isNot) {
2667 add(instruction); 2675 add(instruction);
2668 instruction = new HNot(instruction); 2676 instruction = new HNot(instruction);
2669 } 2677 }
2670 push(instruction); 2678 push(instruction);
2671 } else if (const SourceString("as") == op.source) { 2679 } else if (const SourceString("as") == op.source) {
2672 visit(node.receiver); 2680 visit(node.receiver);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2998 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) { 3006 } else if (name == const SourceString('DART_CLOSURE_TO_JS')) {
2999 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS'); 3007 handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
3000 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { 3008 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) {
3001 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 3009 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
3002 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { 3010 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) {
3003 handleForeignSetCurrentIsolate(node); 3011 handleForeignSetCurrentIsolate(node);
3004 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { 3012 } else if (name == const SourceString('JS_CREATE_ISOLATE')) {
3005 handleForeignCreateIsolate(node); 3013 handleForeignCreateIsolate(node);
3006 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { 3014 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
3007 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3015 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3008 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3009 stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
3010 } else { 3016 } else {
3011 throw "Unknown foreign: ${selector}"; 3017 throw "Unknown foreign: ${selector}";
3012 } 3018 }
3013 } 3019 }
3014 3020
3015 generateSuperNoSuchMethodSend(Send node) { 3021 generateSuperNoSuchMethodSend(Send node) {
3016 Selector selector = elements.getSelector(node); 3022 Selector selector = elements.getSelector(node);
3017 SourceString name = selector.name; 3023 SourceString name = selector.name;
3018 3024
3019 ClassElement cls = currentElement.getEnclosingClass(); 3025 ClassElement cls = currentElement.getEnclosingClass();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 */ 3124 */
3119 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { 3125 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) {
3120 assert(invariant(currentNode, 3126 assert(invariant(currentNode,
3121 !compiler.enableTypeAssertions || !argument.isMalformed, 3127 !compiler.enableTypeAssertions || !argument.isMalformed,
3122 message: '$argument is malformed in checked mode')); 3128 message: '$argument is malformed in checked mode'));
3123 if (argument == compiler.types.dynamicType || argument.isMalformed) { 3129 if (argument == compiler.types.dynamicType || argument.isMalformed) {
3124 // Represent [dynamic] as [null]. 3130 // Represent [dynamic] as [null].
3125 return graph.addConstantNull(constantSystem); 3131 return graph.addConstantNull(constantSystem);
3126 } 3132 }
3127 3133
3128 // The inputs are shared between invocations of the helper. 3134 // These variables are shared between invocations of the helper.
3135 HInstruction typeInfo;
3129 List<HInstruction> inputs = <HInstruction>[]; 3136 List<HInstruction> inputs = <HInstruction>[];
3130 3137
3131 /** 3138 /**
3132 * Helper to create an instruction that gets the value of a type variable. 3139 * Helper to create an instruction that gets the value of a type variable.
3133 */ 3140 */
3134 String addTypeVariableReference(TypeVariableType type) { 3141 void addTypeVariableReference(TypeVariableType type) {
3135 Element member = currentElement; 3142 Element member = currentElement;
3136 if (member.enclosingElement.isClosure()) { 3143 if (member.enclosingElement.isClosure()) {
3137 ClosureClassElement closureClass = member.enclosingElement; 3144 ClosureClassElement closureClass = member.enclosingElement;
3138 member = closureClass.methodElement; 3145 member = closureClass.methodElement;
3139 member = member.getOutermostEnclosingMemberOrTopLevel(); 3146 member = member.getOutermostEnclosingMemberOrTopLevel();
3140 } 3147 }
3141 if (member.isFactoryConstructor()) { 3148 if (member.isFactoryConstructor()) {
3142 // The type variable is stored in a parameter of the method. 3149 // The type variable is stored in a parameter of the factory.
3143 inputs.add(localsHandler.readLocal(type.element)); 3150 inputs.add(localsHandler.readLocal(type.element));
3144 } else if (member.isInstanceMember() || 3151 } else if (member.isInstanceMember()
3145 member.isGenerativeConstructor()) { 3152 || member.isGenerativeConstructor()) {
3146 // The type variable is stored in [this]. 3153 // The type variable is stored in [this].
3154 if (typeInfo == null) {
3155 pushInvokeHelper1(backend.getGetRuntimeTypeInfo(),
3156 localsHandler.readThis());
3157 typeInfo = pop();
3158 }
3147 int index = RuntimeTypeInformation.getTypeVariableIndex(type); 3159 int index = RuntimeTypeInformation.getTypeVariableIndex(type);
3148 pushInvokeHelper2(backend.getGetRuntimeTypeArgument(), 3160 HInstruction foreign = createForeign('#[$index]', HType.STRING,
3149 localsHandler.readThis(), 3161 <HInstruction>[typeInfo]);
3150 graph.addConstantInt(index, constantSystem)); 3162 add(foreign);
3151 inputs.add(pop()); 3163 inputs.add(foreign);
3152 } else { 3164 } else {
3153 // TODO(ngeoffray): Match the VM behavior and throw an 3165 // TODO(ngeoffray): Match the VM behavior and throw an
3154 // exception at runtime. 3166 // exception at runtime.
3155 compiler.cancel('Unimplemented unresolved type variable', 3167 compiler.cancel('Unimplemented unresolved type variable',
3156 node: currentNode); 3168 node: currentNode);
3157 } 3169 }
3158 return '#';
3159 } 3170 }
3160 3171
3161 String template = rti.getTypeRepresentation(argument, 3172 String template = rti.getTypeRepresentation(argument,
3162 addTypeVariableReference); 3173 addTypeVariableReference);
3163 HInstruction result = createForeign(template, HType.STRING, inputs); 3174 HInstruction result = createForeign(template, HType.STRING, inputs);
3164 add(result); 3175 add(result);
3165 return result; 3176 return result;
3166 } 3177 }
3167 3178
3168 void handleListConstructor(InterfaceType type, 3179 void handleListConstructor(InterfaceType type,
3169 Node currentNode, 3180 Node currentNode,
3170 HInstruction newObject) { 3181 HInstruction newObject) {
3171 if (!compiler.world.needsRti(type.element)) return; 3182 if (!compiler.world.needsRti(type.element)) return;
3183 List<HInstruction> inputs = <HInstruction>[];
3172 if (!type.isRaw) { 3184 if (!type.isRaw) {
3173 List<HInstruction> inputs = <HInstruction>[];
3174 type.typeArguments.forEach((DartType argument) { 3185 type.typeArguments.forEach((DartType argument) {
3175 inputs.add(analyzeTypeArgument(argument, currentNode)); 3186 inputs.add(analyzeTypeArgument(argument, currentNode));
3176 }); 3187 });
3177 callSetRuntimeTypeInfo(type.element, inputs, newObject);
3178 } 3188 }
3189 callSetRuntimeTypeInfo(type.element, inputs, newObject);
3179 } 3190 }
3180 3191
3181 void callSetRuntimeTypeInfo(ClassElement element, 3192 void callSetRuntimeTypeInfo(ClassElement element,
3182 List<HInstruction> rtiInputs, 3193 List<HInstruction> rtiInputs,
3183 HInstruction newObject) { 3194 HInstruction newObject) {
3184 if (!compiler.world.needsRti(element) || element.typeVariables.isEmpty) { 3195 if (!compiler.world.needsRti(element) || element.typeVariables.isEmpty) {
3185 return; 3196 return;
3186 } 3197 }
3187 3198
3188 HInstruction typeInfo = new HLiteralList(rtiInputs); 3199 HInstruction typeInfo = new HLiteralList(rtiInputs);
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after
4989 new HSubGraphBlockInformation(elseBranch.graph)); 5000 new HSubGraphBlockInformation(elseBranch.graph));
4990 5001
4991 HBasicBlock conditionStartBlock = conditionBranch.block; 5002 HBasicBlock conditionStartBlock = conditionBranch.block;
4992 conditionStartBlock.setBlockFlow(info, joinBlock); 5003 conditionStartBlock.setBlockFlow(info, joinBlock);
4993 SubGraph conditionGraph = conditionBranch.graph; 5004 SubGraph conditionGraph = conditionBranch.graph;
4994 HIf branch = conditionGraph.end.last; 5005 HIf branch = conditionGraph.end.last;
4995 assert(branch is HIf); 5006 assert(branch is HIf);
4996 branch.blockInformation = conditionStartBlock.blockFlow; 5007 branch.blockInformation = conditionStartBlock.blockFlow;
4997 } 5008 }
4998 } 5009 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698