Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2943 | 2943 |
| 2944 // Construct the runtime type information. | 2944 // Construct the runtime type information. |
| 2945 StringBuffer runtimeCode = new StringBuffer(); | 2945 StringBuffer runtimeCode = new StringBuffer(); |
| 2946 List<HInstruction> runtimeCodeInputs = <HInstruction>[]; | 2946 List<HInstruction> runtimeCodeInputs = <HInstruction>[]; |
| 2947 if (runtimeTypeIsUsed) { | 2947 if (runtimeTypeIsUsed) { |
| 2948 String runtimeTypeString = | 2948 String runtimeTypeString = |
| 2949 rti.generateRuntimeTypeString(element, rtiInputs.length); | 2949 rti.generateRuntimeTypeString(element, rtiInputs.length); |
| 2950 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs); | 2950 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs); |
| 2951 add(runtimeType); | 2951 add(runtimeType); |
| 2952 runtimeCodeInputs.add(runtimeType); | 2952 runtimeCodeInputs.add(runtimeType); |
| 2953 runtimeCode.add('runtimeType: #'); | 2953 runtimeCode.add("runtimeType: '#'"); |
| 2954 } | 2954 } |
| 2955 if (needsRti) { | 2955 if (needsRti) { |
| 2956 if (runtimeTypeIsUsed) runtimeCode.add(', '); | 2956 if (runtimeTypeIsUsed) runtimeCode.add(', '); |
| 2957 String typeVariablesString = | 2957 String typeVariablesString = |
| 2958 RuntimeTypeInformation.generateTypeVariableString(element, | 2958 RuntimeTypeInformation.generateTypeVariableString(element, |
| 2959 rtiInputs.length); | 2959 rtiInputs.length); |
| 2960 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs); | 2960 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs); |
| 2961 add(typeInfo); | 2961 add(typeInfo); |
| 2962 runtimeCodeInputs.add(typeInfo); | 2962 runtimeCodeInputs.add(typeInfo); |
| 2963 runtimeCode.add('#'); | 2963 runtimeCode.add('#'); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3015 generateWrongArgumentCountError(node, constructor, node.arguments); | 3015 generateWrongArgumentCountError(node, constructor, node.arguments); |
| 3016 return; | 3016 return; |
| 3017 } | 3017 } |
| 3018 | 3018 |
| 3019 if (type.element.modifiers.isAbstract() && | 3019 if (type.element.modifiers.isAbstract() && |
| 3020 constructor.isGenerativeConstructor()) { | 3020 constructor.isGenerativeConstructor()) { |
| 3021 generateAbstractClassInstantiationError(node, type.name.slowToString()); | 3021 generateAbstractClassInstantiationError(node, type.name.slowToString()); |
| 3022 return; | 3022 return; |
| 3023 } | 3023 } |
| 3024 if (compiler.world.needsRti(constructor.enclosingElement)) { | 3024 if (compiler.world.needsRti(constructor.enclosingElement)) { |
| 3025 type.arguments.forEach((DartType argument) { | 3025 if (!type.arguments.isEmpty) { |
| 3026 inputs.add(analyzeTypeArgument(argument, node)); | 3026 type.arguments.forEach((DartType argument) { |
| 3027 }); | 3027 inputs.add(analyzeTypeArgument(argument, node)); |
| 3028 }); | |
| 3029 } else if (compiler.enabledRuntimeType) { | |
| 3030 Link<DartType> variables = | |
| 3031 constructor.getEnclosingClass().typeVariables; | |
| 3032 if (!variables.isEmpty) { | |
| 3033 // If the class has type variables but no type arguments have been | |
| 3034 // provided, add [:dynamic:] as argument for all type variables. | |
| 3035 DartString stringDynamic = new DartString.literal('dynamic'); | |
| 3036 HInstruction input = graph.addConstantString(stringDynamic, | |
| 3037 node, | |
| 3038 constantSystem); | |
| 3039 variables.forEach((_) => inputs.add(input)); | |
| 3040 } | |
| 3041 } | |
| 3028 } | 3042 } |
| 3029 | 3043 |
| 3030 HType elementType = computeType(constructor); | 3044 HType elementType = computeType(constructor); |
| 3031 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 3045 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
| 3032 pushWithPosition(newInstance, node); | 3046 pushWithPosition(newInstance, node); |
| 3033 | 3047 |
| 3034 // The List constructor forwards to a Dart static method that does | 3048 // The List constructor forwards to a Dart static method that does |
| 3035 // not know about the type argument. Therefore we special case | 3049 // not know about the type argument. Therefore we special case |
| 3036 // this constructor to have the setRuntimeTypeInfo called where | 3050 // this constructor to have the setRuntimeTypeInfo called where |
| 3037 // the 'new' is done. | 3051 // the 'new' is done. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3089 if (returnType != null) instruction.guaranteedType = returnType; | 3103 if (returnType != null) instruction.guaranteedType = returnType; |
| 3090 pushWithPosition(instruction, node); | 3104 pushWithPosition(instruction, node); |
| 3091 } else { | 3105 } else { |
| 3092 generateGetter(node, element); | 3106 generateGetter(node, element); |
| 3093 List<HInstruction> inputs = <HInstruction>[pop()]; | 3107 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 3094 addDynamicSendArgumentsToList(node, inputs); | 3108 addDynamicSendArgumentsToList(node, inputs); |
| 3095 pushWithPosition(new HInvokeClosure(selector, inputs), node); | 3109 pushWithPosition(new HInvokeClosure(selector, inputs), node); |
| 3096 } | 3110 } |
| 3097 } | 3111 } |
| 3098 | 3112 |
| 3113 HConstant addConstantString(Identifier node, String string) { | |
| 3114 DartString dartString = new DartString.literal(string); | |
| 3115 Constant constant = constantSystem.createString(dartString, node); | |
| 3116 return graph.addConstant(constant); | |
| 3117 } | |
| 3118 | |
| 3119 visitTypeReferenceSend(Send node) { | |
| 3120 Element element = elements[node]; | |
| 3121 HInstruction name; | |
| 3122 Element helper = | |
| 3123 compiler.findHelper(RuntimeTypeInformation.CACHE_HELPER_NAME); | |
| 3124 if (element.isClass()) { | |
| 3125 String string = rti.generateRuntimeTypeString(element, 0); | |
| 3126 name = addConstantString(node.selector, string); | |
| 3127 } else if (element.isTypedef()) { | |
| 3128 // TODO(karlklose): implement support for type variables in typedefs. | |
| 3129 name = addConstantString(node.selector, rti.getName(element)); | |
| 3130 } else if (element.isTypeVariable()) { | |
| 3131 // TODO(6248): implement support for type variables. | |
| 3132 compiler.unimplemented('first class type for type variable', node: node); | |
| 3133 } else { | |
| 3134 internalError('unexpected element $element', node: node); | |
| 3135 } | |
| 3136 pushInvokeHelper1(helper, name); | |
| 3137 if (node.isCall) { | |
| 3138 // This send is of the form 'e(...)', where e is resolved to a type | |
| 3139 // reference. We create a regular closure call on the result of the type | |
| 3140 // reference instead of creating a NoSuchMethodError to avoid pulling it | |
| 3141 // in if it is not used (e.g., in a try/catch). | |
| 3142 HInstruction target = pop(); | |
| 3143 Selector selector = elements.getSelector(node); | |
| 3144 List<HInstruction> inputs = <HInstruction>[target]; | |
| 3145 addDynamicSendArgumentsToList(node, inputs); | |
| 3146 push(new HInvokeClosure(selector, inputs)); | |
| 3147 } | |
| 3148 } | |
| 3149 | |
| 3099 visitGetterSend(Send node) { | 3150 visitGetterSend(Send node) { |
| 3100 generateGetter(node, elements[node]); | 3151 generateGetter(node, elements[node]); |
| 3101 } | 3152 } |
| 3102 | 3153 |
| 3103 // TODO(antonm): migrate rest of SsaBuilder to internalError. | 3154 // TODO(antonm): migrate rest of SsaBuilder to internalError. |
| 3104 internalError(String reason, {Node node}) { | 3155 internalError(String reason, {Node node}) { |
| 3105 compiler.internalError(reason, node: node); | 3156 compiler.internalError(reason, node: node); |
| 3106 } | 3157 } |
| 3107 | 3158 |
| 3108 void generateError(Node node, String message, Element helper) { | 3159 void generateError(Node node, String message, Element helper) { |
| 3109 DartString messageObject = new DartString.literal(message); | 3160 HInstruction errorMessage = addConstantString(node, message); |
| 3110 Constant messageConstant = | |
| 3111 constantSystem.createString(messageObject, node); | |
| 3112 HInstruction errorMessage = graph.addConstant(messageConstant); | |
| 3113 pushInvokeHelper1(helper, errorMessage); | 3161 pushInvokeHelper1(helper, errorMessage); |
| 3114 } | 3162 } |
| 3115 | 3163 |
| 3116 void generateRuntimeError(Node node, String message) { | 3164 void generateRuntimeError(Node node, String message) { |
| 3117 generateError(node, message, interceptors.getThrowRuntimeError()); | 3165 generateError(node, message, interceptors.getThrowRuntimeError()); |
| 3118 } | 3166 } |
| 3119 | 3167 |
| 3120 void generateAbstractClassInstantiationError(Node node, String message) { | 3168 void generateAbstractClassInstantiationError(Node node, String message) { |
| 3121 generateError(node, | 3169 generateError(node, |
| 3122 message, | 3170 message, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3202 // TODO(karlklose): add type representation | 3250 // TODO(karlklose): add type representation |
| 3203 ConstantHandler handler = compiler.constantHandler; | 3251 ConstantHandler handler = compiler.constantHandler; |
| 3204 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3252 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3205 stack.add(graph.addConstant(constant)); | 3253 stack.add(graph.addConstant(constant)); |
| 3206 } else { | 3254 } else { |
| 3207 visitNewSend(node.send, elements.getType(node)); | 3255 visitNewSend(node.send, elements.getType(node)); |
| 3208 } | 3256 } |
| 3209 } | 3257 } |
| 3210 | 3258 |
| 3211 visitSendSet(SendSet node) { | 3259 visitSendSet(SendSet node) { |
| 3260 Element element = elements[node]; | |
| 3261 if (!Elements.isUnresolved(element) && element.impliesType()) { | |
| 3262 Identifier selector = node.selector; | |
| 3263 generateThrowNoSuchMethod(node, selector.source.slowToString(), | |
| 3264 argumentNodes: node.arguments); | |
| 3265 return; | |
| 3266 } | |
| 3212 Operator op = node.assignmentOperator; | 3267 Operator op = node.assignmentOperator; |
| 3213 if (node.isSuperCall) { | 3268 if (node.isSuperCall) { |
| 3214 Element element = elements[node]; | |
| 3215 if (element == null) return generateSuperNoSuchMethodSend(node); | 3269 if (element == null) return generateSuperNoSuchMethodSend(node); |
| 3216 HInstruction target = new HStatic(element); | 3270 HInstruction target = new HStatic(element); |
| 3217 HInstruction context = localsHandler.readThis(); | 3271 HInstruction context = localsHandler.readThis(); |
| 3218 add(target); | 3272 add(target); |
| 3219 var inputs = <HInstruction>[target, context]; | 3273 var inputs = <HInstruction>[target, context]; |
| 3220 addDynamicSendArgumentsToList(node, inputs); | 3274 addDynamicSendArgumentsToList(node, inputs); |
| 3221 if (!identical(node.assignmentOperator.source.stringValue, '=')) { | 3275 if (!identical(node.assignmentOperator.source.stringValue, '=')) { |
| 3222 compiler.unimplemented('complex super assignment', | 3276 compiler.unimplemented('complex super assignment', |
| 3223 node: node.assignmentOperator); | 3277 node: node.assignmentOperator); |
| 3224 } | 3278 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3282 } else { | 3336 } else { |
| 3283 assert(const SourceString("++") == op.source || | 3337 assert(const SourceString("++") == op.source || |
| 3284 const SourceString("--") == op.source || | 3338 const SourceString("--") == op.source || |
| 3285 node.assignmentOperator.source.stringValue.endsWith("=")); | 3339 node.assignmentOperator.source.stringValue.endsWith("=")); |
| 3286 Element element = elements[node]; | 3340 Element element = elements[node]; |
| 3287 bool isCompoundAssignment = !node.arguments.isEmpty; | 3341 bool isCompoundAssignment = !node.arguments.isEmpty; |
| 3288 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 3342 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
| 3289 | 3343 |
| 3290 // [receiver] is only used if the node is an instance send. | 3344 // [receiver] is only used if the node is an instance send. |
| 3291 HInstruction receiver = null; | 3345 HInstruction receiver = null; |
| 3346 Element selectorElement = elements[node]; | |
|
ahe
2012/11/05 09:47:05
This is unused.
| |
| 3292 if (Elements.isInstanceSend(node, elements)) { | 3347 if (Elements.isInstanceSend(node, elements)) { |
| 3293 receiver = generateInstanceSendReceiver(node); | 3348 receiver = generateInstanceSendReceiver(node); |
| 3294 generateInstanceGetterWithCompiledReceiver(node, receiver); | 3349 generateInstanceGetterWithCompiledReceiver(node, receiver); |
| 3295 } else { | 3350 } else { |
| 3296 generateGetter(node, elements[node.selector]); | 3351 generateGetter(node, elements[node.selector]); |
| 3297 } | 3352 } |
| 3298 HInstruction left = pop(); | 3353 HInstruction left = pop(); |
| 3299 HInstruction right; | 3354 HInstruction right; |
| 3300 if (isCompoundAssignment) { | 3355 if (isCompoundAssignment) { |
| 3301 visit(node.argumentsNode); | 3356 visit(node.argumentsNode); |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4609 new HSubGraphBlockInformation(elseBranch.graph)); | 4664 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4610 | 4665 |
| 4611 HBasicBlock conditionStartBlock = conditionBranch.block; | 4666 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4612 conditionStartBlock.setBlockFlow(info, joinBlock); | 4667 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4613 SubGraph conditionGraph = conditionBranch.graph; | 4668 SubGraph conditionGraph = conditionBranch.graph; |
| 4614 HIf branch = conditionGraph.end.last; | 4669 HIf branch = conditionGraph.end.last; |
| 4615 assert(branch is HIf); | 4670 assert(branch is HIf); |
| 4616 branch.blockInformation = conditionStartBlock.blockFlow; | 4671 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4617 } | 4672 } |
| 4618 } | 4673 } |
| OLD | NEW |