| 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 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 } | 166 } |
| 167 assert(graph.isValid()); | 167 assert(graph.isValid()); |
| 168 bool inLoop = functionsCalledInLoop.contains(element); | 168 bool inLoop = functionsCalledInLoop.contains(element); |
| 169 if (!inLoop) { | 169 if (!inLoop) { |
| 170 Selector selector = selectorsCalledInLoop[element.name]; | 170 Selector selector = selectorsCalledInLoop[element.name]; |
| 171 inLoop = selector !== null && selector.applies(element, compiler); | 171 inLoop = selector !== null && selector.applies(element, compiler); |
| 172 } | 172 } |
| 173 graph.calledInLoop = inLoop; | 173 graph.calledInLoop = inLoop; |
| 174 if (compiler.tracer.enabled) { | 174 if (compiler.tracer.enabled) { |
| 175 String name; | 175 String name; |
| 176 if (element.enclosingElement !== null && | 176 if (element.isMember()) { |
| 177 element.enclosingElement.kind == ElementKind.CLASS) { | 177 String className = element.getEnclosingClass().name.slowToString(); |
| 178 String className = element.enclosingElement.name.slowToString(); | |
| 179 String memberName = element.name.slowToString(); | 178 String memberName = element.name.slowToString(); |
| 180 name = "$className.$memberName"; | 179 name = "$className.$memberName"; |
| 181 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { | 180 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { |
| 182 name = "$name (body)"; | 181 name = "$name (body)"; |
| 183 } | 182 } |
| 184 } else { | 183 } else { |
| 185 name = "${element.name.slowToString()}"; | 184 name = "${element.name.slowToString()}"; |
| 186 } | 185 } |
| 187 compiler.tracer.traceCompilation(name); | 186 compiler.tracer.traceCompilation(name); |
| 188 compiler.tracer.traceGraph('builder', graph); | 187 compiler.tracer.traceGraph('builder', graph); |
| 189 } | 188 } |
| 190 return graph; | 189 return graph; |
| 191 }); | 190 }); |
| 192 } | 191 } |
| 193 | 192 |
| 194 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { | 193 HGraph compileConstructor(SsaBuilder builder, WorkItem work) { |
| 195 // The body of the constructor will be generated in a separate function. | 194 // The body of the constructor will be generated in a separate function. |
| 196 final ClassElement classElement = work.element.enclosingElement; | 195 final ClassElement classElement = work.element.getEnclosingClass(); |
| 197 return builder.buildFactory(classElement, work.element); | 196 return builder.buildFactory(classElement, work.element); |
| 198 } | 197 } |
| 199 } | 198 } |
| 200 | 199 |
| 201 /** | 200 /** |
| 202 * Keeps track of locals (including parameters and phis) when building. The | 201 * Keeps track of locals (including parameters and phis) when building. The |
| 203 * 'this' reference is treated as parameter and hence handled by this class, | 202 * 'this' reference is treated as parameter and hence handled by this class, |
| 204 * too. | 203 * too. |
| 205 */ | 204 */ |
| 206 class LocalsHandler { | 205 class LocalsHandler { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 if (closureData.isClosure()) { | 331 if (closureData.isClosure()) { |
| 333 // Inside closure redirect references to itself to [:this:]. | 332 // Inside closure redirect references to itself to [:this:]. |
| 334 HInstruction thisInstruction = new HThis(); | 333 HInstruction thisInstruction = new HThis(); |
| 335 builder.add(thisInstruction); | 334 builder.add(thisInstruction); |
| 336 updateLocal(closureData.closureElement, thisInstruction); | 335 updateLocal(closureData.closureElement, thisInstruction); |
| 337 } else if (function.isInstanceMember() | 336 } else if (function.isInstanceMember() |
| 338 || function.isGenerativeConstructor()) { | 337 || function.isGenerativeConstructor()) { |
| 339 // Once closures have been mapped to classes their instance members might | 338 // Once closures have been mapped to classes their instance members might |
| 340 // not have any thisElement if the closure was created inside a static | 339 // not have any thisElement if the closure was created inside a static |
| 341 // context. | 340 // context. |
| 342 ClassElement cls = function.enclosingElement; | 341 ClassElement cls = function.getEnclosingClass(); |
| 343 Type type = cls.computeType(builder.compiler); | 342 Type type = cls.computeType(builder.compiler); |
| 344 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); | 343 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| 345 builder.add(thisInstruction); | 344 builder.add(thisInstruction); |
| 346 directLocals[closureData.thisElement] = thisInstruction; | 345 directLocals[closureData.thisElement] = thisInstruction; |
| 347 } | 346 } |
| 348 } | 347 } |
| 349 | 348 |
| 350 bool hasValueForDirectLocal(Element element) { | 349 bool hasValueForDirectLocal(Element element) { |
| 351 assert(element !== null); | 350 assert(element !== null); |
| 352 assert(isAccessedDirectly(element)); | 351 assert(isAccessedDirectly(element)); |
| 353 return directLocals[element] !== null; | 352 return directLocals[element] !== null; |
| 354 } | 353 } |
| 355 | 354 |
| 356 /** | 355 /** |
| 357 * Returns true if the local can be accessed directly. Boxed variables or | 356 * Returns true if the local can be accessed directly. Boxed variables or |
| 358 * captured variables that are stored in the closure-field return [false]. | 357 * captured variables that are stored in the closure-field return [false]. |
| 359 */ | 358 */ |
| 360 bool isAccessedDirectly(Element element) { | 359 bool isAccessedDirectly(Element element) { |
| 361 assert(element !== null); | 360 assert(element !== null); |
| 362 return redirectionMapping[element] === null | 361 return redirectionMapping[element] === null |
| 363 && !closureData.usedVariablesInTry.contains(element); | 362 && !closureData.usedVariablesInTry.contains(element); |
| 364 } | 363 } |
| 365 | 364 |
| 366 bool isStoredInClosureField(Element element) { | 365 bool isStoredInClosureField(Element element) { |
| 367 assert(element !== null); | 366 assert(element !== null); |
| 368 if (isAccessedDirectly(element)) return false; | 367 if (isAccessedDirectly(element)) return false; |
| 369 Element redirectTarget = redirectionMapping[element]; | 368 Element redirectTarget = redirectionMapping[element]; |
| 370 if (redirectTarget == null) return false; | 369 if (redirectTarget == null) return false; |
| 371 if (redirectTarget.enclosingElement.kind == ElementKind.CLASS) { | 370 if (redirectTarget.isMember()) { |
| 372 assert(redirectTarget is ClosureFieldElement); | 371 assert(redirectTarget is ClosureFieldElement); |
| 373 return true; | 372 return true; |
| 374 } | 373 } |
| 375 return false; | 374 return false; |
| 376 } | 375 } |
| 377 | 376 |
| 378 bool isBoxed(Element element) { | 377 bool isBoxed(Element element) { |
| 379 if (isAccessedDirectly(element)) return false; | 378 if (isAccessedDirectly(element)) return false; |
| 380 if (isStoredInClosureField(element)) return false; | 379 if (isStoredInClosureField(element)) return false; |
| 381 return redirectionMapping[element] !== null; | 380 return redirectionMapping[element] !== null; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 } | 424 } |
| 426 | 425 |
| 427 HType cachedTypeOfThis; | 426 HType cachedTypeOfThis; |
| 428 | 427 |
| 429 HInstruction readThis() { | 428 HInstruction readThis() { |
| 430 HInstruction res = readLocal(closureData.thisElement); | 429 HInstruction res = readLocal(closureData.thisElement); |
| 431 if (res.guaranteedType === null) { | 430 if (res.guaranteedType === null) { |
| 432 if (cachedTypeOfThis === null) { | 431 if (cachedTypeOfThis === null) { |
| 433 assert(closureData.isClosure()); | 432 assert(closureData.isClosure()); |
| 434 Element element = closureData.thisElement; | 433 Element element = closureData.thisElement; |
| 435 ClassElement cls = element.enclosingElement.enclosingElement; | 434 ClassElement cls = element.enclosingElement.getEnclosingClass(); |
| 436 Type type = cls.computeType(builder.compiler); | 435 Type type = cls.computeType(builder.compiler); |
| 437 cachedTypeOfThis = new HBoundedType.nonNull(type); | 436 cachedTypeOfThis = new HBoundedType.nonNull(type); |
| 438 } | 437 } |
| 439 res.guaranteedType = cachedTypeOfThis; | 438 res.guaranteedType = cachedTypeOfThis; |
| 440 } | 439 } |
| 441 return res; | 440 return res; |
| 442 } | 441 } |
| 443 | 442 |
| 444 HLocalValue getLocal(Element element) { | 443 HLocalValue getLocal(Element element) { |
| 445 // If the element is a parameter, we already have a | 444 // If the element is a parameter, we already have a |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { | 853 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { |
| 855 assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR); | 854 assert(constructor.kind === ElementKind.GENERATIVE_CONSTRUCTOR); |
| 856 if (constructor is SynthesizedConstructorElement) return null; | 855 if (constructor is SynthesizedConstructorElement) return null; |
| 857 FunctionExpression node = constructor.parseNode(compiler); | 856 FunctionExpression node = constructor.parseNode(compiler); |
| 858 // If we know the body doesn't have any code, we don't generate | 857 // If we know the body doesn't have any code, we don't generate |
| 859 // it. | 858 // it. |
| 860 if (node.body.asBlock() !== null) { | 859 if (node.body.asBlock() !== null) { |
| 861 NodeList statements = node.body.asBlock().statements; | 860 NodeList statements = node.body.asBlock().statements; |
| 862 if (statements.isEmpty()) return null; | 861 if (statements.isEmpty()) return null; |
| 863 } | 862 } |
| 864 ClassElement classElement = constructor.enclosingElement; | 863 ClassElement classElement = constructor.getEnclosingClass(); |
| 865 ConstructorBodyElement bodyElement; | 864 ConstructorBodyElement bodyElement; |
| 866 for (Link<Element> backendMembers = classElement.backendMembers; | 865 for (Link<Element> backendMembers = classElement.backendMembers; |
| 867 !backendMembers.isEmpty(); | 866 !backendMembers.isEmpty(); |
| 868 backendMembers = backendMembers.tail) { | 867 backendMembers = backendMembers.tail) { |
| 869 Element backendMember = backendMembers.head; | 868 Element backendMember = backendMembers.head; |
| 870 if (backendMember.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { | 869 if (backendMember.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { |
| 871 ConstructorBodyElement body = backendMember; | 870 ConstructorBodyElement body = backendMember; |
| 872 if (body.constructor == constructor) { | 871 if (body.constructor == constructor) { |
| 873 bodyElement = backendMember; | 872 bodyElement = backendMember; |
| 874 break; | 873 break; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); | 961 assert(!arguments.isEmpty() && arguments.tail.isEmpty()); |
| 963 visit(arguments.head); | 962 visit(arguments.head); |
| 964 fieldValues[elements[init]] = pop(); | 963 fieldValues[elements[init]] = pop(); |
| 965 } | 964 } |
| 966 } | 965 } |
| 967 } | 966 } |
| 968 | 967 |
| 969 if (!foundSuperOrRedirect) { | 968 if (!foundSuperOrRedirect) { |
| 970 // No super initializer found. Try to find the default constructor if | 969 // No super initializer found. Try to find the default constructor if |
| 971 // the class is not Object. | 970 // the class is not Object. |
| 972 ClassElement enclosingClass = constructor.enclosingElement; | 971 ClassElement enclosingClass = constructor.getEnclosingClass(); |
| 973 ClassElement superClass = enclosingClass.superclass; | 972 ClassElement superClass = enclosingClass.superclass; |
| 974 if (enclosingClass != compiler.objectClass) { | 973 if (enclosingClass != compiler.objectClass) { |
| 975 assert(superClass !== null); | 974 assert(superClass !== null); |
| 976 assert(superClass.isResolved); | 975 assert(superClass.isResolved); |
| 977 FunctionElement target = superClass.lookupConstructor(superClass.name); | 976 FunctionElement target = superClass.lookupConstructor(superClass.name); |
| 978 if (target === null) { | 977 if (target === null) { |
| 979 compiler.internalError("no default constructor available"); | 978 compiler.internalError("no default constructor available"); |
| 980 } | 979 } |
| 981 inlineSuperOrRedirect(target, | 980 inlineSuperOrRedirect(target, |
| 982 Selector.INVOCATION_0, | 981 Selector.INVOCATION_0, |
| (...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 add(target); | 2255 add(target); |
| 2257 inputs = <HInstruction>[target]; | 2256 inputs = <HInstruction>[target]; |
| 2258 addDynamicSendArgumentsToList(node, inputs); | 2257 addDynamicSendArgumentsToList(node, inputs); |
| 2259 push(new HInvokeClosure(selector, inputs)); | 2258 push(new HInvokeClosure(selector, inputs)); |
| 2260 } | 2259 } |
| 2261 } | 2260 } |
| 2262 | 2261 |
| 2263 visitNewSend(Send node) { | 2262 visitNewSend(Send node) { |
| 2264 computeType(element) { | 2263 computeType(element) { |
| 2265 Element originalElement = elements[node]; | 2264 Element originalElement = elements[node]; |
| 2266 if (originalElement.enclosingElement === compiler.listClass) { | 2265 if (originalElement.getEnclosingClass() === compiler.listClass) { |
| 2267 if (node.arguments.isEmpty()) { | 2266 if (node.arguments.isEmpty()) { |
| 2268 return HType.EXTENDABLE_ARRAY; | 2267 return HType.EXTENDABLE_ARRAY; |
| 2269 } else { | 2268 } else { |
| 2270 return HType.MUTABLE_ARRAY; | 2269 return HType.MUTABLE_ARRAY; |
| 2271 } | 2270 } |
| 2272 } else if (element.isGenerativeConstructor()) { | 2271 } else if (element.isGenerativeConstructor()) { |
| 2273 ClassElement cls = element.enclosingElement; | 2272 ClassElement cls = element.getEnclosingClass(); |
| 2274 return new HBoundedType.exact(cls.type); | 2273 return new HBoundedType.exact(cls.type); |
| 2275 } else { | 2274 } else { |
| 2276 return HType.UNKNOWN; | 2275 return HType.UNKNOWN; |
| 2277 } | 2276 } |
| 2278 } | 2277 } |
| 2279 | 2278 |
| 2280 Selector selector = elements.getSelector(node); | 2279 Selector selector = elements.getSelector(node); |
| 2281 Element element = elements[node]; | 2280 Element element = elements[node]; |
| 2282 if (compiler.enqueuer.resolution.getCachedElements(element) === null) { | 2281 if (compiler.enqueuer.resolution.getCachedElements(element) === null) { |
| 2283 compiler.internalError("Unresolved element: $element", node: node); | 2282 compiler.internalError("Unresolved element: $element", node: node); |
| (...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3599 new HSubGraphBlockInformation(elseBranch.graph)); | 3598 new HSubGraphBlockInformation(elseBranch.graph)); |
| 3600 | 3599 |
| 3601 HBasicBlock conditionStartBlock = conditionBranch.block; | 3600 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 3602 conditionStartBlock.setBlockFlow(info, joinBlock); | 3601 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 3603 SubGraph conditionGraph = conditionBranch.graph; | 3602 SubGraph conditionGraph = conditionBranch.graph; |
| 3604 HIf branch = conditionGraph.end.last; | 3603 HIf branch = conditionGraph.end.last; |
| 3605 assert(branch is HIf); | 3604 assert(branch is HIf); |
| 3606 branch.blockInformation = conditionStartBlock.blockFlow; | 3605 branch.blockInformation = conditionStartBlock.blockFlow; |
| 3607 } | 3606 } |
| 3608 } | 3607 } |
| OLD | NEW |