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 js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1259 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { | 1259 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { |
| 1260 emitDynamicFunctionGetter(member, defineInstanceMember); | 1260 emitDynamicFunctionGetter(member, defineInstanceMember); |
| 1261 } | 1261 } |
| 1262 } | 1262 } |
| 1263 } | 1263 } |
| 1264 | 1264 |
| 1265 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { | 1265 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { |
| 1266 // Do not generate no such method handlers if there is no class. | 1266 // Do not generate no such method handlers if there is no class. |
| 1267 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; | 1267 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; |
| 1268 | 1268 |
| 1269 String noSuchMethodName = | 1269 String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
| 1270 namer.publicInstanceMethodNameByArity(Compiler.NO_SUCH_METHOD, 2); | 1270 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
| 1271 | 1271 |
| 1272 // Keep track of the JavaScript names we've already added so we | 1272 // Keep track of the JavaScript names we've already added so we |
| 1273 // do not introduce duplicates (bad for code size). | 1273 // do not introduce duplicates (bad for code size). |
| 1274 Set<String> addedJsNames = new Set<String>(); | 1274 Set<String> addedJsNames = new Set<String>(); |
| 1275 | 1275 |
| 1276 // Keep track of the noSuchMethod holders for each possible | 1276 // Keep track of the noSuchMethod holders for each possible |
| 1277 // receiver type. | 1277 // receiver type. |
| 1278 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = | 1278 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = |
| 1279 new Map<ClassElement, Set<ClassElement>>(); | 1279 new Map<ClassElement, Set<ClassElement>>(); |
| 1280 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { | 1280 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { |
| 1281 ClassElement element = type.element; | 1281 ClassElement element = type.element; |
| 1282 Set<ClassElement> result = noSuchMethodHolders[element]; | 1282 Set<ClassElement> result = noSuchMethodHolders[element]; |
| 1283 if (result == null) { | 1283 if (result == null) { |
| 1284 // For now, we check the entire world to see if an object of | 1284 // For now, we check the entire world to see if an object of |
| 1285 // the given type may have a user-defined noSuchMethod | 1285 // the given type may have a user-defined noSuchMethod |
| 1286 // implementation. We could do better by only looking at | 1286 // implementation. We could do better by only looking at |
| 1287 // instantiated (or otherwise needed) classes. | 1287 // instantiated (or otherwise needed) classes. |
| 1288 result = compiler.world.findNoSuchMethodHolders(type); | 1288 result = compiler.world.findNoSuchMethodHolders(type); |
| 1289 noSuchMethodHolders[element] = result; | 1289 noSuchMethodHolders[element] = result; |
| 1290 } | 1290 } |
| 1291 return result; | 1291 return result; |
| 1292 } | 1292 } |
| 1293 | 1293 |
| 1294 CodeBuffer generateMethod(String methodName, Selector selector) { | 1294 CodeBuffer generateMethod(String methodName, Selector selector) { |
|
ahe
2012/10/29 12:14:05
Could you rename this function while you're at it?
| |
| 1295 // Values match JSInvocationMirror in js-helper library. | |
| 1296 const int METHOD = 0; | |
| 1297 const int GETTER = 1; | |
| 1298 const int SETTER = 2; | |
| 1299 int type = METHOD; | |
|
ahe
2012/10/29 12:14:05
In a compiler, type means something else. Please f
| |
| 1300 if (selector.isGetter()) { | |
| 1301 type = GETTER; | |
| 1302 } else if (selector.isSetter()) { | |
| 1303 type = SETTER; | |
| 1304 } | |
| 1295 CodeBuffer args = new CodeBuffer(); | 1305 CodeBuffer args = new CodeBuffer(); |
| 1296 for (int i = 0; i < selector.argumentCount; i++) { | 1306 for (int i = 0; i < selector.argumentCount; i++) { |
| 1297 if (i != 0) args.add(', '); | 1307 if (i != 0) args.add(', '); |
| 1298 args.add('\$$i'); | 1308 args.add('\$$i'); |
| 1299 } | 1309 } |
| 1310 CodeBuffer argNames = new CodeBuffer(); | |
| 1311 List<SourceString> names = selector.getOrderedNamedArguments(); | |
| 1312 for (int i = 0; i < names.length; i++) { | |
| 1313 if (i != 0) argNames.add(', '); | |
| 1314 argNames.add('"'); | |
| 1315 argNames.add(names[i].slowToString()); | |
| 1316 argNames.add('"'); | |
| 1317 } | |
| 1318 String internalName = namer.instanceMethodInvocationName( | |
| 1319 selector.library, new SourceString(methodName), selector); | |
| 1300 CodeBuffer buffer = new CodeBuffer(); | 1320 CodeBuffer buffer = new CodeBuffer(); |
| 1301 buffer.add('function($args) {\n'); | 1321 buffer.add('function($args) {\n'); |
| 1302 buffer.add(' return this.$noSuchMethodName("$methodName", [$args]);\n'); | 1322 buffer.add(' return this.$noSuchMethodName(' |
|
ahe
2012/10/29 12:14:05
Notice that $noSuchMethodName is string interpolat
| |
| 1323 '\$.createInvocationMirror("$methodName", "$internalName",' | |
|
ahe
2012/10/29 12:14:05
The same should be done here. The namer needs to h
| |
| 1324 ' $type, [$args], [$argNames]));\n'); | |
| 1303 buffer.add(' }'); | 1325 buffer.add(' }'); |
| 1304 return buffer; | 1326 return buffer; |
| 1305 } | 1327 } |
| 1306 | 1328 |
| 1307 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 1329 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
| 1308 // Cache the object class and type. | 1330 // Cache the object class and type. |
| 1309 ClassElement objectClass = compiler.objectClass; | 1331 ClassElement objectClass = compiler.objectClass; |
| 1310 DartType objectType = objectClass.computeType(compiler); | 1332 DartType objectType = objectClass.computeType(compiler); |
| 1311 | 1333 |
| 1312 for (Selector selector in selectors) { | 1334 for (Selector selector in selectors) { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1578 const String HOOKS_API_USAGE = """ | 1600 const String HOOKS_API_USAGE = """ |
| 1579 // Generated by dart2js, the Dart to JavaScript compiler. | 1601 // Generated by dart2js, the Dart to JavaScript compiler. |
| 1580 // The code supports the following hooks: | 1602 // The code supports the following hooks: |
| 1581 // dartPrint(message) - if this function is defined it is called | 1603 // dartPrint(message) - if this function is defined it is called |
| 1582 // instead of the Dart [print] method. | 1604 // instead of the Dart [print] method. |
| 1583 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1605 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 1584 // method will not be invoked directly. | 1606 // method will not be invoked directly. |
| 1585 // Instead, a closure that will invoke [main] is | 1607 // Instead, a closure that will invoke [main] is |
| 1586 // passed to [dartMainRunner]. | 1608 // passed to [dartMainRunner]. |
| 1587 """; | 1609 """; |
| OLD | NEW |