| 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 |