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

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

Issue 12598003: Support type variables as expressions. (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 3055 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 SourceString name = selector.name; 3066 SourceString name = selector.name;
3067 3067
3068 ClassElement cls = currentElement.getEnclosingClass(); 3068 ClassElement cls = currentElement.getEnclosingClass();
3069 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD); 3069 Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
3070 if (element.enclosingElement.declaration != compiler.objectClass) { 3070 if (element.enclosingElement.declaration != compiler.objectClass) {
3071 // Register the call as dynamic if [:noSuchMethod:] on the super class 3071 // Register the call as dynamic if [:noSuchMethod:] on the super class
3072 // is _not_ the default implementation from [:Object:], in case 3072 // is _not_ the default implementation from [:Object:], in case
3073 // the [:noSuchMethod:] implementation does an [:invokeOn:] on 3073 // the [:noSuchMethod:] implementation does an [:invokeOn:] on
3074 // the invocation mirror. 3074 // the invocation mirror.
3075 compiler.enqueuer.codegen.registerSelectorUse(selector); 3075 compiler.enqueuer.codegen.registerSelectorUse(selector);
3076 } 3076 }
3077 HStatic target = new HStatic(element); 3077 HStatic target = new HStatic(element);
3078 add(target); 3078 add(target);
3079 HInstruction self = localsHandler.readThis(); 3079 HInstruction self = localsHandler.readThis();
3080 Constant nameConstant = constantSystem.createString( 3080 Constant nameConstant = constantSystem.createString(
3081 new DartString.literal(name.slowToString()), node); 3081 new DartString.literal(name.slowToString()), node);
3082 3082
3083 String internalName = backend.namer.invocationName(selector); 3083 String internalName = backend.namer.invocationName(selector);
3084 Constant internalNameConstant = 3084 Constant internalNameConstant =
3085 constantSystem.createString(new DartString.literal(internalName), node); 3085 constantSystem.createString(new DartString.literal(internalName), node);
3086 3086
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 HInstruction target = new HInvokeSuper(inputs); 3153 HInstruction target = new HInvokeSuper(inputs);
3154 add(target); 3154 add(target);
3155 inputs = <HInstruction>[target]; 3155 inputs = <HInstruction>[target];
3156 addDynamicSendArgumentsToList(node, inputs); 3156 addDynamicSendArgumentsToList(node, inputs);
3157 Selector closureSelector = new Selector.callClosureFrom(selector); 3157 Selector closureSelector = new Selector.callClosureFrom(selector);
3158 push(new HInvokeClosure(closureSelector, inputs)); 3158 push(new HInvokeClosure(closureSelector, inputs));
3159 } 3159 }
3160 } 3160 }
3161 3161
3162 /** 3162 /**
3163 * Generate code to extract the type arguments from the object, substitute
3164 * them as an instance of the type we are testing against (if necessary), and
3165 * extract the type argument by the index of the variable in the list of type
3166 * variables for that class.
3167 */
3168 HInstruction readTypeVariable(ClassElement cls,
3169 TypeVariableElement variable) {
3170 int index = RuntimeTypeInformation.getTypeVariableIndex(variable);
3171 String substitutionNameString = backend.namer.substitutionName(cls);
3172 HInstruction substitutionName = graph.addConstantString(
3173 new LiteralDartString(substitutionNameString), null, constantSystem);
3174 HInstruction target = localsHandler.readThis();
3175 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
3176 <HInstruction>[target, substitutionName]);
3177 add(substitution);
3178 pushInvokeHelper3(backend.getGetRuntimeTypeArgument(),
3179 target,
3180 substitution,
3181 graph.addConstantInt(index, constantSystem),
3182 HType.UNKNOWN);
3183 return pop();
3184 }
3185
3186 /**
3163 * Helper to create an instruction that gets the value of a type variable. 3187 * Helper to create an instruction that gets the value of a type variable.
3164 */ 3188 */
3165 HInstruction addTypeVariableReference(TypeVariableType type) { 3189 HInstruction addTypeVariableReference(TypeVariableType type) {
3166 Element member = currentElement; 3190 Element member = currentElement;
3167 if (member.enclosingElement.isClosure()) { 3191 if (member.enclosingElement.isClosure()) {
3168 ClosureClassElement closureClass = member.enclosingElement; 3192 ClosureClassElement closureClass = member.enclosingElement;
3169 member = closureClass.methodElement; 3193 member = closureClass.methodElement;
3170 member = member.getOutermostEnclosingMemberOrTopLevel(); 3194 member = member.getOutermostEnclosingMemberOrTopLevel();
3171 } 3195 }
3172 if (member.isConstructor() 3196 if (member.isConstructor()
3173 || member.isGenerativeConstructorBody() 3197 || member.isGenerativeConstructorBody()
3174 || member.isField()) { 3198 || member.isField()) {
3175 // The type variable is stored in a parameter of the method. 3199 // The type variable is stored in a parameter of the method.
3176 return localsHandler.readLocal(type.element); 3200 return localsHandler.readLocal(type.element);
3177 } else if (member.isInstanceMember()) { 3201 } else if (member.isInstanceMember()) {
3178 // The type variable is stored on the object. Generate code to extract 3202 // The type variable is stored on the object.
3179 // the type arguments from the object, substitute them as an instance 3203 return readTypeVariable(member.getEnclosingClass(),
3180 // of the type we are testing against (if necessary), and extract the 3204 type.element);
3181 // type argument by the index of the variable in the list of type
3182 // variables for that class.
3183 int index = RuntimeTypeInformation.getTypeVariableIndex(type);
3184 HInstruction thisObject = localsHandler.readThis();
3185 String substitutionNameString =
3186 backend.namer.substitutionName(member.getEnclosingClass());
3187 HInstruction substitutionName = graph.addConstantString(
3188 new LiteralDartString(substitutionNameString), null, constantSystem);
3189 HInstruction substitution = createForeign('#[#]', HType.UNKNOWN,
3190 <HInstruction>[thisObject, substitutionName]);
3191 add(substitution);
3192 pushInvokeHelper3(backend.getGetRuntimeTypeArgument(),
3193 thisObject,
3194 substitution,
3195 graph.addConstantInt(index, constantSystem),
3196 HType.UNKNOWN);
3197 return pop();
3198 } else { 3205 } else {
3199 // TODO(ngeoffray): Match the VM behavior and throw an 3206 // TODO(ngeoffray): Match the VM behavior and throw an
3200 // exception at runtime. 3207 // exception at runtime.
3201 compiler.cancel('Unimplemented unresolved type variable', 3208 compiler.cancel('Unimplemented unresolved type variable',
3202 element: type.element); 3209 element: type.element);
3203 } 3210 }
3204 } 3211 }
3205 3212
3206 /** 3213 /**
3207 * Documentation wanted -- johnniwinther 3214 * Documentation wanted -- johnniwinther
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3415 } 3422 }
3416 3423
3417 visitTypeReferenceSend(Send node) { 3424 visitTypeReferenceSend(Send node) {
3418 Element element = elements[node]; 3425 Element element = elements[node];
3419 if (element.isClass() || element.isTypedef()) { 3426 if (element.isClass() || element.isTypedef()) {
3420 // TODO(karlklose): add type representation 3427 // TODO(karlklose): add type representation
3421 ConstantHandler handler = compiler.constantHandler; 3428 ConstantHandler handler = compiler.constantHandler;
3422 Constant constant = handler.compileNodeWithDefinitions(node, elements); 3429 Constant constant = handler.compileNodeWithDefinitions(node, elements);
3423 stack.add(graph.addConstant(constant)); 3430 stack.add(graph.addConstant(constant));
3424 } else if (element.isTypeVariable()) { 3431 } else if (element.isTypeVariable()) {
3425 // TODO(6248): implement support for type variables. 3432 HInstruction value = readTypeVariable(currentElement.getEnclosingClass(),
3426 compiler.unimplemented('first class type for type variable', node: node); 3433 element);
3434 pushInvokeHelper1(backend.getRuntimeTypeToString(),
3435 value, HType.STRING);
3436 pushInvokeHelper1(backend.getCreateRuntimeType(),
3437 pop(), HType.UNKNOWN);
3427 } else { 3438 } else {
3428 internalError('unexpected element kind $element', node: node); 3439 internalError('unexpected element kind $element', node: node);
3429 } 3440 }
3430 if (node.isCall) { 3441 if (node.isCall) {
3431 // This send is of the form 'e(...)', where e is resolved to a type 3442 // This send is of the form 'e(...)', where e is resolved to a type
3432 // reference. We create a regular closure call on the result of the type 3443 // reference. We create a regular closure call on the result of the type
3433 // reference instead of creating a NoSuchMethodError to avoid pulling it 3444 // reference instead of creating a NoSuchMethodError to avoid pulling it
3434 // in if it is not used (e.g., in a try/catch). 3445 // in if it is not used (e.g., in a try/catch).
3435 HInstruction target = pop(); 3446 HInstruction target = pop();
3436 Selector selector = elements.getSelector(node); 3447 Selector selector = elements.getSelector(node);
(...skipping 1661 matching lines...) Expand 10 before | Expand all | Expand 10 after
5098 new HSubGraphBlockInformation(elseBranch.graph)); 5109 new HSubGraphBlockInformation(elseBranch.graph));
5099 5110
5100 HBasicBlock conditionStartBlock = conditionBranch.block; 5111 HBasicBlock conditionStartBlock = conditionBranch.block;
5101 conditionStartBlock.setBlockFlow(info, joinBlock); 5112 conditionStartBlock.setBlockFlow(info, joinBlock);
5102 SubGraph conditionGraph = conditionBranch.graph; 5113 SubGraph conditionGraph = conditionBranch.graph;
5103 HIf branch = conditionGraph.end.last; 5114 HIf branch = conditionGraph.end.last;
5104 assert(branch is HIf); 5115 assert(branch is HIf);
5105 branch.blockInformation = conditionStartBlock.blockFlow; 5116 branch.blockInformation = conditionStartBlock.blockFlow;
5106 } 5117 }
5107 } 5118 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698