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

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