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 SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 | 1315 |
1316 // Bail out early if the inlining decision is in the cache and we can't | 1316 // Bail out early if the inlining decision is in the cache and we can't |
1317 // inline (no need to check the hard constraints). | 1317 // inline (no need to check the hard constraints). |
1318 bool cachedCanBeInlined = | 1318 bool cachedCanBeInlined = |
1319 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 1319 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
1320 if (cachedCanBeInlined == false) return false; | 1320 if (cachedCanBeInlined == false) return false; |
1321 | 1321 |
1322 bool meetsHardConstraints() { | 1322 bool meetsHardConstraints() { |
1323 if (compiler.disableInlining) return false; | 1323 if (compiler.disableInlining) return false; |
1324 | 1324 |
1325 assert(selector != null | 1325 assert(invariant( |
1326 || Elements.isStaticOrTopLevel(element) | 1326 currentNode != null ? currentNode : element, |
1327 || element.isGenerativeConstructorBody); | 1327 selector != null || |
| 1328 Elements.isStaticOrTopLevel(element) || |
| 1329 element.isGenerativeConstructorBody, |
| 1330 message: "Missing selector for inlining of $element.")); |
1328 if (selector != null && !selector.applies(function, compiler.world)) { | 1331 if (selector != null && !selector.applies(function, compiler.world)) { |
1329 return false; | 1332 return false; |
1330 } | 1333 } |
1331 | 1334 |
1332 // Don't inline operator== methods if the parameter can be null. | 1335 // Don't inline operator== methods if the parameter can be null. |
1333 if (element.name == '==') { | 1336 if (element.name == '==') { |
1334 if (element.enclosingClass != compiler.objectClass | 1337 if (element.enclosingClass != compiler.objectClass |
1335 && providedArguments[1].canBeNull()) { | 1338 && providedArguments[1].canBeNull()) { |
1336 return false; | 1339 return false; |
1337 } | 1340 } |
(...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3239 | 3242 |
3240 HInstruction generateInstanceSendReceiver(ast.Send send) { | 3243 HInstruction generateInstanceSendReceiver(ast.Send send) { |
3241 assert(Elements.isInstanceSend(send, elements)); | 3244 assert(Elements.isInstanceSend(send, elements)); |
3242 if (send.receiver == null) { | 3245 if (send.receiver == null) { |
3243 return localsHandler.readThis(); | 3246 return localsHandler.readThis(); |
3244 } | 3247 } |
3245 visit(send.receiver); | 3248 visit(send.receiver); |
3246 return pop(); | 3249 return pop(); |
3247 } | 3250 } |
3248 | 3251 |
3249 String noSuchMethodTargetSymbolString(ErroneousElement error, | 3252 String noSuchMethodTargetSymbolString(Element error, [String prefix]) { |
3250 [String prefix]) { | |
3251 String result = error.name; | 3253 String result = error.name; |
3252 if (prefix == "set") return "$result="; | 3254 if (prefix == "set") return "$result="; |
3253 return result; | 3255 return result; |
3254 } | 3256 } |
3255 | 3257 |
3256 /** | 3258 /** |
3257 * Returns a set of interceptor classes that contain the given | 3259 * Returns a set of interceptor classes that contain the given |
3258 * [selector]. | 3260 * [selector]. |
3259 */ | 3261 */ |
3260 void generateInstanceGetterWithCompiledReceiver(ast.Send send, | 3262 void generateInstanceGetterWithCompiledReceiver(ast.Send send, |
(...skipping 20 matching lines...) Expand all Loading... |
3281 } | 3283 } |
3282 | 3284 |
3283 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that | 3285 /// Inserts a call to checkDeferredIsLoaded if the send has a prefix that |
3284 /// resolves to a deferred library. | 3286 /// resolves to a deferred library. |
3285 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { | 3287 void generateIsDeferredLoadedCheckOfSend(ast.Send node) { |
3286 generateIsDeferredLoadedCheckIfNeeded( | 3288 generateIsDeferredLoadedCheckIfNeeded( |
3287 compiler.deferredLoadTask.deferredPrefixElement(node, elements), | 3289 compiler.deferredLoadTask.deferredPrefixElement(node, elements), |
3288 node); | 3290 node); |
3289 } | 3291 } |
3290 | 3292 |
| 3293 void handleInvalidStaticGet(ast.Send node, Element element) { |
| 3294 generateThrowNoSuchMethod( |
| 3295 node, |
| 3296 noSuchMethodTargetSymbolString(element, 'get'), |
| 3297 argumentNodes: const Link<ast.Node>()); |
| 3298 } |
| 3299 |
3291 /// Generate read access of an unresolved static or top level entity. | 3300 /// Generate read access of an unresolved static or top level entity. |
3292 void generateStaticUnresolvedGet(ast.Send node, Element element) { | 3301 void generateStaticUnresolvedGet(ast.Send node, Element element) { |
3293 if (element is ErroneousElement) { | 3302 if (element is ErroneousElement) { |
3294 // An erroneous element indicates an unresolved static getter. | 3303 // An erroneous element indicates an unresolved static getter. |
3295 generateThrowNoSuchMethod( | 3304 handleInvalidStaticGet(node, element); |
3296 node, | |
3297 noSuchMethodTargetSymbolString(element, 'get'), | |
3298 argumentNodes: const Link<ast.Node>()); | |
3299 } else { | 3305 } else { |
3300 // This happens when [element] has parse errors. | 3306 // This happens when [element] has parse errors. |
3301 assert(invariant(node, element == null || element.isErroneous)); | 3307 assert(invariant(node, element == null || element.isErroneous)); |
3302 // TODO(ahe): Do something like the above, that is, emit a runtime | 3308 // TODO(ahe): Do something like the above, that is, emit a runtime |
3303 // error. | 3309 // error. |
3304 stack.add(graph.addConstantNull(compiler)); | 3310 stack.add(graph.addConstantNull(compiler)); |
3305 } | 3311 } |
3306 } | 3312 } |
3307 | 3313 |
3308 /// Read a static or top level [field] of constant value. | 3314 /// Read a static or top level [field] of constant value. |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3900 @override | 3906 @override |
3901 visitLocalFunctionInvoke( | 3907 visitLocalFunctionInvoke( |
3902 ast.Send node, | 3908 ast.Send node, |
3903 LocalFunctionElement function, | 3909 LocalFunctionElement function, |
3904 ast.NodeList arguments, | 3910 ast.NodeList arguments, |
3905 CallStructure callStructure, | 3911 CallStructure callStructure, |
3906 _) { | 3912 _) { |
3907 generateCallInvoke(node, localsHandler.readLocal(function)); | 3913 generateCallInvoke(node, localsHandler.readLocal(function)); |
3908 } | 3914 } |
3909 | 3915 |
| 3916 @override |
| 3917 visitLocalFunctionIncompatibleInvoke( |
| 3918 ast.Send node, |
| 3919 LocalFunctionElement function, |
| 3920 ast.NodeList arguments, |
| 3921 CallStructure callStructure, |
| 3922 _) { |
| 3923 generateCallInvoke(node, localsHandler.readLocal(function)); |
| 3924 } |
| 3925 |
3910 void handleForeignJs(ast.Send node) { | 3926 void handleForeignJs(ast.Send node) { |
3911 Link<ast.Node> link = node.arguments; | 3927 Link<ast.Node> link = node.arguments; |
3912 // Don't visit the first argument, which is the type, and the second | 3928 // Don't visit the first argument, which is the type, and the second |
3913 // argument, which is the foreign code. | 3929 // argument, which is the foreign code. |
3914 if (link.isEmpty || link.tail.isEmpty) { | 3930 if (link.isEmpty || link.tail.isEmpty) { |
3915 compiler.internalError(node.argumentsNode, | 3931 compiler.internalError(node.argumentsNode, |
3916 'At least two arguments expected.'); | 3932 'At least two arguments expected.'); |
3917 } | 3933 } |
3918 native.NativeBehavior nativeBehavior = | 3934 native.NativeBehavior nativeBehavior = |
3919 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 3935 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5140 ast.Send node, | 5156 ast.Send node, |
5141 FunctionElement getter, | 5157 FunctionElement getter, |
5142 ast.NodeList arguments, | 5158 ast.NodeList arguments, |
5143 CallStructure callStructure, | 5159 CallStructure callStructure, |
5144 _) { | 5160 _) { |
5145 generateStaticGetterGet(node, getter); | 5161 generateStaticGetterGet(node, getter); |
5146 generateCallInvoke(node, pop()); | 5162 generateCallInvoke(node, pop()); |
5147 } | 5163 } |
5148 | 5164 |
5149 @override | 5165 @override |
| 5166 void visitTopLevelSetterGet( |
| 5167 ast.Send node, |
| 5168 MethodElement setter, |
| 5169 _) { |
| 5170 handleInvalidStaticGet(node, setter); |
| 5171 } |
| 5172 |
| 5173 @override |
| 5174 void visitStaticSetterGet( |
| 5175 ast.Send node, |
| 5176 MethodElement setter, |
| 5177 _) { |
| 5178 handleInvalidStaticGet(node, setter); |
| 5179 } |
| 5180 |
| 5181 @override |
5150 void visitUnresolvedGet( | 5182 void visitUnresolvedGet( |
5151 ast.Send node, | 5183 ast.Send node, |
5152 Element element, | 5184 Element element, |
5153 _) { | 5185 _) { |
5154 generateStaticUnresolvedGet(node, element); | 5186 generateStaticUnresolvedGet(node, element); |
5155 } | 5187 } |
5156 | 5188 |
| 5189 void handleInvalidStaticInvoke(ast.Send node, Element element) { |
| 5190 generateThrowNoSuchMethod(node, |
| 5191 noSuchMethodTargetSymbolString(element), |
| 5192 argumentNodes: node.arguments); |
| 5193 } |
| 5194 |
| 5195 @override |
| 5196 void visitStaticSetterInvoke( |
| 5197 ast.Send node, |
| 5198 MethodElement setter, |
| 5199 ast.NodeList arguments, |
| 5200 CallStructure callStructure, |
| 5201 _) { |
| 5202 handleInvalidStaticInvoke(node, setter); |
| 5203 } |
| 5204 |
| 5205 @override |
| 5206 void visitTopLevelSetterInvoke( |
| 5207 ast.Send node, |
| 5208 MethodElement setter, |
| 5209 ast.NodeList arguments, |
| 5210 CallStructure callStructure, |
| 5211 _) { |
| 5212 handleInvalidStaticInvoke(node, setter); |
| 5213 } |
| 5214 |
5157 @override | 5215 @override |
5158 void visitUnresolvedInvoke( | 5216 void visitUnresolvedInvoke( |
5159 ast.Send node, | 5217 ast.Send node, |
5160 Element element, | 5218 Element element, |
5161 ast.NodeList arguments, | 5219 ast.NodeList arguments, |
5162 Selector selector, | 5220 Selector selector, |
5163 _) { | 5221 _) { |
5164 if (element is ErroneousElement) { | 5222 if (element is ErroneousElement) { |
5165 // An erroneous element indicates that the funciton could not be | 5223 // An erroneous element indicates that the funciton could not be |
5166 // resolved (a warning has been issued). | 5224 // resolved (a warning has been issued). |
5167 generateThrowNoSuchMethod(node, | 5225 handleInvalidStaticInvoke(node, element); |
5168 noSuchMethodTargetSymbolString(element), | |
5169 argumentNodes: node.arguments); | |
5170 } else { | 5226 } else { |
5171 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 5227 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
5172 stack.add(graph.addConstantNull(compiler)); | 5228 stack.add(graph.addConstantNull(compiler)); |
5173 } | 5229 } |
5174 return; | 5230 return; |
5175 } | 5231 } |
5176 | 5232 |
5177 HConstant addConstantString(String string) { | 5233 HConstant addConstantString(String string) { |
5178 ast.DartString dartString = new ast.DartString.literal(string); | 5234 ast.DartString dartString = new ast.DartString.literal(string); |
5179 ConstantValue constant = constantSystem.createString(dartString); | 5235 ConstantValue constant = constantSystem.createString(dartString); |
(...skipping 2647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7827 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 7883 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
7828 unaliased.accept(this, builder); | 7884 unaliased.accept(this, builder); |
7829 } | 7885 } |
7830 | 7886 |
7831 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 7887 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
7832 JavaScriptBackend backend = builder.compiler.backend; | 7888 JavaScriptBackend backend = builder.compiler.backend; |
7833 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 7889 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
7834 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 7890 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
7835 } | 7891 } |
7836 } | 7892 } |
OLD | NEW |