| 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 WorkItem { | 5 class WorkItem { |
| 6 final Element element; | 6 final Element element; |
| 7 TreeElements resolutionTree; | 7 TreeElements resolutionTree; |
| 8 Function run; | 8 Function run; |
| 9 Map<int, BailoutInfo> bailouts = null; | 9 Map<int, BailoutInfo> bailouts = null; |
| 10 bool allowSpeculativeOptimization = true; | 10 bool allowSpeculativeOptimization = true; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 library.define(new ForeignElement( | 179 library.define(new ForeignElement( |
| 180 const SourceString('JS'), library), this); | 180 const SourceString('JS'), library), this); |
| 181 library.define(new ForeignElement( | 181 library.define(new ForeignElement( |
| 182 const SourceString('UNINTERCEPTED'), library), this); | 182 const SourceString('UNINTERCEPTED'), library), this); |
| 183 library.define(new ForeignElement( | 183 library.define(new ForeignElement( |
| 184 const SourceString('JS_HAS_EQUALS'), library), this); | 184 const SourceString('JS_HAS_EQUALS'), library), this); |
| 185 } | 185 } |
| 186 | 186 |
| 187 void enqueueInvokedInstanceMethods() { | 187 void enqueueInvokedInstanceMethods() { |
| 188 // TODO(floitsch): find a more efficient way of doing this. | 188 // TODO(floitsch): find a more efficient way of doing this. |
| 189 |
| 189 // Run through the classes and see if we need to compile methods. | 190 // Run through the classes and see if we need to compile methods. |
| 190 for (ClassElement classElement in universe.instantiatedClasses) { | 191 for (ClassElement classElement in universe.instantiatedClasses) { |
| 191 for (ClassElement currentClass = classElement; | 192 for (ClassElement currentClass = classElement; |
| 192 currentClass !== null; | 193 currentClass !== null; |
| 193 currentClass = currentClass.superclass) { | 194 currentClass = currentClass.superclass) { |
| 194 // TODO(floitsch): we don't need to add members that have been | 195 // TODO(floitsch): we don't need to add members that have been |
| 195 // overwritten by subclasses. | 196 // overwritten by subclasses. |
| 196 for (Element member in currentClass.members) { | 197 for (Element member in currentClass.members) { |
| 197 if (universe.generatedCode[member] !== null) continue; | 198 if (universe.generatedCode[member] !== null) continue; |
| 198 if (!member.isInstanceMember()) continue; | 199 if (!member.isInstanceMember()) continue; |
| 199 if (member.kind == ElementKind.FUNCTION) { | 200 if (member.kind == ElementKind.FUNCTION) { |
| 200 Set<Selector> selectors = universe.invokedNames[member.name]; | 201 Set<Selector> selectors = universe.invokedNames[member.name]; |
| 201 if (selectors != null) { | 202 if (selectors != null) { |
| 202 for (Selector selector in selectors) { | 203 for (Selector selector in selectors) { |
| 203 if (selector.applies(this, member)) { | 204 if (selector.applies(this, member)) { |
| 204 addToWorklist(member); | 205 addToWorklist(member); |
| 205 break; | 206 break; |
| 206 } | 207 } |
| 207 } | 208 } |
| 208 } | 209 } |
| 209 // If there is a property access with the same name as a method we | 210 // If there is a property access with the same name as a method we |
| 210 // need to emit the method. | 211 // need to emit the method. |
| 211 if (universe.invokedGetters.contains(member.name)) { | 212 if (universe.invokedGetters.contains(member.name)) { |
| 212 addToWorklist(member); | 213 addToWorklist(member); |
| 213 } | 214 } |
| 214 } else if (member.kind == ElementKind.GETTER) { | 215 } else if (member.kind == ElementKind.GETTER) { |
| 215 if (universe.invokedGetters.contains(member.name)) { | 216 if (universe.invokedGetters.contains(member.name)) { |
| 216 addToWorklist(member); | 217 addToWorklist(member); |
| 217 } | 218 } |
| 219 // A method invocation like in o.foo(x, y) might actually be an |
| 220 // invocation of the getter foo followed by an invocation of the |
| 221 // returned closure. |
| 222 Set<Selector> invokedSelectors = universe.invokedNames[member.name]; |
| 223 // We don't know what selectors the returned closure accepts. If |
| 224 // the set contains any selector we have to assume that it matches. |
| 225 if (invokedSelectors !== null && !invokedSelectors.isEmpty()) { |
| 226 addToWorklist(member); |
| 227 } |
| 218 } else if (member.kind === ElementKind.SETTER) { | 228 } else if (member.kind === ElementKind.SETTER) { |
| 219 if (universe.invokedSetters.contains(member.name)) { | 229 if (universe.invokedSetters.contains(member.name)) { |
| 220 addToWorklist(member); | 230 addToWorklist(member); |
| 221 } | 231 } |
| 222 } | 232 } |
| 233 |
| 234 // Make sure that the closure understands a call with the given |
| 235 // selector. For a method-invocation of the form o.foo(a: 499), we |
| 236 // need to make sure that closures can handle the optional argument if |
| 237 // there exists a field or getter 'foo'. |
| 238 if (member.kind === ElementKind.GETTER || |
| 239 member.kind === ElementKind.FIELD) { |
| 240 Set<Selector> invokedSelectors = universe.invokedNames[member.name]; |
| 241 if (invokedSelectors != null) { |
| 242 for (Selector selector in invokedSelectors) { |
| 243 registerDynamicInvocation(Namer.CLOSURE_INVOCATION_NAME, |
| 244 selector); |
| 245 } |
| 246 } |
| 247 } |
| 223 } | 248 } |
| 224 } | 249 } |
| 225 } | 250 } |
| 226 } | 251 } |
| 227 | 252 |
| 228 void runCompiler(Script script) { | 253 void runCompiler(Script script) { |
| 229 scanBuiltinLibraries(); | 254 scanBuiltinLibraries(); |
| 230 mainApp = new LibraryElement(script); | 255 mainApp = new LibraryElement(script); |
| 231 Element element; | 256 Element element; |
| 232 withCurrentElement(mainApp, () { | 257 withCurrentElement(mainApp, () { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 | 399 |
| 375 class CompilerCancelledException implements Exception { | 400 class CompilerCancelledException implements Exception { |
| 376 final String reason; | 401 final String reason; |
| 377 CompilerCancelledException(this.reason); | 402 CompilerCancelledException(this.reason); |
| 378 | 403 |
| 379 String toString() { | 404 String toString() { |
| 380 String banner = 'compiler cancelled'; | 405 String banner = 'compiler cancelled'; |
| 381 return (reason !== null) ? '$banner: $reason' : '$banner'; | 406 return (reason !== null) ? '$banner: $reason' : '$banner'; |
| 382 } | 407 } |
| 383 } | 408 } |
| OLD | NEW |