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

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

Issue 10942028: Support class and typedef literals as expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add a test for literals. Created 8 years, 1 month 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 class Interceptors { 7 class Interceptors {
8 Compiler compiler; 8 Compiler compiler;
9 Interceptors(Compiler this.compiler); 9 Interceptors(Compiler this.compiler);
10 10
(...skipping 2909 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 2920
2921 // Construct the runtime type information. 2921 // Construct the runtime type information.
2922 StringBuffer runtimeCode = new StringBuffer(); 2922 StringBuffer runtimeCode = new StringBuffer();
2923 List<HInstruction> runtimeCodeInputs = <HInstruction>[]; 2923 List<HInstruction> runtimeCodeInputs = <HInstruction>[];
2924 if (runtimeTypeIsUsed) { 2924 if (runtimeTypeIsUsed) {
2925 String runtimeTypeString = 2925 String runtimeTypeString =
2926 rti.generateRuntimeTypeString(element, rtiInputs.length); 2926 rti.generateRuntimeTypeString(element, rtiInputs.length);
2927 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs); 2927 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs);
2928 add(runtimeType); 2928 add(runtimeType);
2929 runtimeCodeInputs.add(runtimeType); 2929 runtimeCodeInputs.add(runtimeType);
2930 runtimeCode.add('runtimeType: #'); 2930 runtimeCode.add("runtimeType: '#'");
2931 } 2931 }
2932 if (needsRti) { 2932 if (needsRti) {
2933 if (runtimeTypeIsUsed) runtimeCode.add(', '); 2933 if (runtimeTypeIsUsed) runtimeCode.add(', ');
2934 String typeVariablesString = 2934 String typeVariablesString =
2935 RuntimeTypeInformation.generateTypeVariableString(element, 2935 RuntimeTypeInformation.generateTypeVariableString(element,
2936 rtiInputs.length); 2936 rtiInputs.length);
2937 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs); 2937 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs);
2938 add(typeInfo); 2938 add(typeInfo);
2939 runtimeCodeInputs.add(typeInfo); 2939 runtimeCodeInputs.add(typeInfo);
2940 runtimeCode.add('#'); 2940 runtimeCode.add('#');
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 generateWrongArgumentCountError(node, constructor, node.arguments); 2992 generateWrongArgumentCountError(node, constructor, node.arguments);
2993 return; 2993 return;
2994 } 2994 }
2995 2995
2996 if (type.element.modifiers.isAbstract() && 2996 if (type.element.modifiers.isAbstract() &&
2997 constructor.isGenerativeConstructor()) { 2997 constructor.isGenerativeConstructor()) {
2998 generateAbstractClassInstantiationError(node, type.name.slowToString()); 2998 generateAbstractClassInstantiationError(node, type.name.slowToString());
2999 return; 2999 return;
3000 } 3000 }
3001 if (compiler.world.needsRti(constructor.enclosingElement)) { 3001 if (compiler.world.needsRti(constructor.enclosingElement)) {
3002 type.arguments.forEach((DartType argument) { 3002 if (!type.arguments.isEmpty) {
3003 inputs.add(analyzeTypeArgument(argument, node)); 3003 type.arguments.forEach((DartType argument) {
3004 }); 3004 inputs.add(analyzeTypeArgument(argument, node));
3005 });
3006 } else if (compiler.enabledRuntimeType) {
3007 Link<DartType> variables =
3008 constructor.getEnclosingClass().typeVariables;
3009 if (!variables.isEmpty) {
3010 // If the class has type variables but no type arguments have been
3011 // provided, add [:dynamic:] as argument for all type variables.
ngeoffray 2012/10/31 10:33:03 Can't we find that at runtime instead?
karlklose 2012/10/31 13:01:18 We could by wrapping each type variable in a call
ngeoffray 2012/10/31 14:32:43 What other solution are you thinking of? One that
3012 DartString stringDynamic = new DartString.literal('dynamic');
3013 HInstruction input = graph.addConstantString(stringDynamic,
3014 node,
3015 constantSystem);
3016 variables.forEach((_) => inputs.add(input));
3017 }
3018 }
3005 } 3019 }
3006 3020
3007 HType elementType = computeType(constructor); 3021 HType elementType = computeType(constructor);
3008 HInstruction newInstance = new HInvokeStatic(inputs, elementType); 3022 HInstruction newInstance = new HInvokeStatic(inputs, elementType);
3009 pushWithPosition(newInstance, node); 3023 pushWithPosition(newInstance, node);
3010 3024
3011 // The List constructor forwards to a Dart static method that does 3025 // The List constructor forwards to a Dart static method that does
3012 // not know about the type argument. Therefore we special case 3026 // not know about the type argument. Therefore we special case
3013 // this constructor to have the setRuntimeTypeInfo called where 3027 // this constructor to have the setRuntimeTypeInfo called where
3014 // the 'new' is done. 3028 // the 'new' is done.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 if (returnType != null) instruction.guaranteedType = returnType; 3080 if (returnType != null) instruction.guaranteedType = returnType;
3067 pushWithPosition(instruction, node); 3081 pushWithPosition(instruction, node);
3068 } else { 3082 } else {
3069 generateGetter(node, element); 3083 generateGetter(node, element);
3070 List<HInstruction> inputs = <HInstruction>[pop()]; 3084 List<HInstruction> inputs = <HInstruction>[pop()];
3071 addDynamicSendArgumentsToList(node, inputs); 3085 addDynamicSendArgumentsToList(node, inputs);
3072 pushWithPosition(new HInvokeClosure(selector, inputs), node); 3086 pushWithPosition(new HInvokeClosure(selector, inputs), node);
3073 } 3087 }
3074 } 3088 }
3075 3089
3090 HConstant addConstantString(Send node, String string) {
3091 DartString dartString = new DartString.literal(string);
3092 Constant constant = constantSystem.createString(dartString, node);
3093 return graph.addConstant(constant);
3094 }
3095
3096 visitTypeReferenceSend(Send node) {
3097 Element element = elements[node];
3098 HInstruction name;
3099 Element helper =
3100 compiler.findHelper(RuntimeTypeInformation.CACHE_HELPER_NAME);
3101 if (element.isClass()) {
3102 String string = rti.generateRuntimeTypeString(element, 0);
3103 name = addConstantString(node.selector, string);
3104 } else if (element.isTypedef()) {
3105 // TODO(karlklose): implement support for type variables in typedefs.
3106 name = addConstantString(node.selector, rti.getName(element));
3107 } else if (element.isTypeVariable()) {
3108 // TODO(6248): implement support for type variables.
3109 compiler.unimplemented('first class type for type variable', node: node);
3110 } else {
3111 internalError('unexpected element $element', node: node);
3112 }
3113 pushInvokeHelper1(helper, name);
3114 if (node.isFunctionObjectInvocation) {
3115 // This send is of the form 'e(...)', where e is resolved to a type
3116 // reference.
ngeoffray 2012/10/31 10:33:03 Please add a comment that you're doing a regular c
karlklose 2012/10/31 13:01:18 Done.
3117 HInstruction target = pop();
3118 Selector selector = elements.getSelector(node);
3119 selector = new Selector.callClosure(selector.argumentCount,
3120 selector.namedArguments);
3121 List<HInstruction> inputs = <HInstruction>[target];
3122 addDynamicSendArgumentsToList(node, inputs);
3123 push(new HInvokeDynamicMethod(selector, inputs));
ngeoffray 2012/10/31 10:33:03 Could you use HInvokeDynamicClosure? You should no
karlklose 2012/10/31 13:01:18 Yes, it works!
3124 }
3125 // Enable the runtime type cache, so that the emitter generates one even
3126 // if we do not have [runtimeType] in the program.
ngeoffray 2012/10/31 10:33:03 How can that happen?
karlklose 2012/10/31 13:01:18 If we use a class literal, but not the runtimeType
3127 compiler.enableRuntimeTypeCache();
3128 }
3129
3076 visitGetterSend(Send node) { 3130 visitGetterSend(Send node) {
3077 generateGetter(node, elements[node]); 3131 generateGetter(node, elements[node]);
3078 } 3132 }
3079 3133
3080 // TODO(antonm): migrate rest of SsaBuilder to internalError. 3134 // TODO(antonm): migrate rest of SsaBuilder to internalError.
3081 internalError(String reason, {Node node}) { 3135 internalError(String reason, {Node node}) {
3082 compiler.internalError(reason, node: node); 3136 compiler.internalError(reason, node: node);
3083 } 3137 }
3084 3138
3085 void generateError(Node node, String message, Element helper) { 3139 void generateError(Node node, String message, Element helper) {
3086 DartString messageObject = new DartString.literal(message); 3140 HInstruction errorMessage = addConstantString(node, message);
3087 Constant messageConstant =
3088 constantSystem.createString(messageObject, node);
3089 HInstruction errorMessage = graph.addConstant(messageConstant);
3090 pushInvokeHelper1(helper, errorMessage); 3141 pushInvokeHelper1(helper, errorMessage);
3091 } 3142 }
3092 3143
3093 void generateRuntimeError(Node node, String message) { 3144 void generateRuntimeError(Node node, String message) {
3094 generateError(node, message, interceptors.getThrowRuntimeError()); 3145 generateError(node, message, interceptors.getThrowRuntimeError());
3095 } 3146 }
3096 3147
3097 void generateAbstractClassInstantiationError(Node node, String message) { 3148 void generateAbstractClassInstantiationError(Node node, String message) {
3098 generateError(node, 3149 generateError(node,
3099 message, 3150 message,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3259 } else { 3310 } else {
3260 assert(const SourceString("++") == op.source || 3311 assert(const SourceString("++") == op.source ||
3261 const SourceString("--") == op.source || 3312 const SourceString("--") == op.source ||
3262 node.assignmentOperator.source.stringValue.endsWith("=")); 3313 node.assignmentOperator.source.stringValue.endsWith("="));
3263 Element element = elements[node]; 3314 Element element = elements[node];
3264 bool isCompoundAssignment = !node.arguments.isEmpty; 3315 bool isCompoundAssignment = !node.arguments.isEmpty;
3265 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. 3316 bool isPrefix = !node.isPostfix; // Compound assignments are prefix.
3266 3317
3267 // [receiver] is only used if the node is an instance send. 3318 // [receiver] is only used if the node is an instance send.
3268 HInstruction receiver = null; 3319 HInstruction receiver = null;
3269 if (Elements.isInstanceSend(node, elements)) { 3320 Element selectorElement = elements[node.selector];
ngeoffray 2012/10/31 10:33:03 Why is the class on the selector and not the recei
karlklose 2012/10/31 13:01:18 It is on both, but I changed it to read it from th
3321 if (!Elements.isUnresolved(selectorElement)
3322 && selectorElement.impliesType()) {
3323 visitTypeReferenceSend(node);
3324 } else if (Elements.isInstanceSend(node, elements)) {
3270 receiver = generateInstanceSendReceiver(node); 3325 receiver = generateInstanceSendReceiver(node);
3271 generateInstanceGetterWithCompiledReceiver(node, receiver); 3326 generateInstanceGetterWithCompiledReceiver(node, receiver);
3272 } else { 3327 } else {
3273 generateGetter(node, elements[node.selector]); 3328 generateGetter(node, elements[node.selector]);
3274 } 3329 }
3275 HInstruction left = pop(); 3330 HInstruction left = pop();
3276 HInstruction right; 3331 HInstruction right;
3277 if (isCompoundAssignment) { 3332 if (isCompoundAssignment) {
3278 visit(node.argumentsNode); 3333 visit(node.argumentsNode);
3279 right = pop(); 3334 right = pop();
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after
4586 new HSubGraphBlockInformation(elseBranch.graph)); 4641 new HSubGraphBlockInformation(elseBranch.graph));
4587 4642
4588 HBasicBlock conditionStartBlock = conditionBranch.block; 4643 HBasicBlock conditionStartBlock = conditionBranch.block;
4589 conditionStartBlock.setBlockFlow(info, joinBlock); 4644 conditionStartBlock.setBlockFlow(info, joinBlock);
4590 SubGraph conditionGraph = conditionBranch.graph; 4645 SubGraph conditionGraph = conditionBranch.graph;
4591 HIf branch = conditionGraph.end.last; 4646 HIf branch = conditionGraph.end.last;
4592 assert(branch is HIf); 4647 assert(branch is HIf);
4593 branch.blockInformation = conditionStartBlock.blockFlow; 4648 branch.blockInformation = conditionStartBlock.blockFlow;
4594 } 4649 }
4595 } 4650 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698