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 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1247 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { | 1247 if (compiler.codegenWorld.hasInvokedGetter(member, compiler)) { |
1248 emitDynamicFunctionGetter(member, defineInstanceMember); | 1248 emitDynamicFunctionGetter(member, defineInstanceMember); |
1249 } | 1249 } |
1250 } | 1250 } |
1251 } | 1251 } |
1252 | 1252 |
1253 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { | 1253 void emitNoSuchMethodHandlers(DefineMemberFunction defineInstanceMember) { |
1254 // Do not generate no such method handlers if there is no class. | 1254 // Do not generate no such method handlers if there is no class. |
1255 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; | 1255 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; |
1256 | 1256 |
1257 String noSuchMethodName = namer.publicInstanceMethodNameByArity( | 1257 String noSuchMethodName = |
1258 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); | 1258 namer.publicInstanceMethodNameByArity(Compiler.NO_SUCH_METHOD, 2); |
1259 | 1259 |
1260 // Keep track of the JavaScript names we've already added so we | 1260 // Keep track of the JavaScript names we've already added so we |
1261 // do not introduce duplicates (bad for code size). | 1261 // do not introduce duplicates (bad for code size). |
1262 Set<String> addedJsNames = new Set<String>(); | 1262 Set<String> addedJsNames = new Set<String>(); |
1263 | 1263 |
1264 // Keep track of the noSuchMethod holders for each possible | 1264 // Keep track of the noSuchMethod holders for each possible |
1265 // receiver type. | 1265 // receiver type. |
1266 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = | 1266 Map<ClassElement, Set<ClassElement>> noSuchMethodHolders = |
1267 new Map<ClassElement, Set<ClassElement>>(); | 1267 new Map<ClassElement, Set<ClassElement>>(); |
1268 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { | 1268 Set<ClassElement> noSuchMethodHoldersFor(DartType type) { |
1269 ClassElement element = type.element; | 1269 ClassElement element = type.element; |
1270 Set<ClassElement> result = noSuchMethodHolders[element]; | 1270 Set<ClassElement> result = noSuchMethodHolders[element]; |
1271 if (result == null) { | 1271 if (result == null) { |
1272 // For now, we check the entire world to see if an object of | 1272 // For now, we check the entire world to see if an object of |
1273 // the given type may have a user-defined noSuchMethod | 1273 // the given type may have a user-defined noSuchMethod |
1274 // implementation. We could do better by only looking at | 1274 // implementation. We could do better by only looking at |
1275 // instantiated (or otherwise needed) classes. | 1275 // instantiated (or otherwise needed) classes. |
1276 result = compiler.world.findNoSuchMethodHolders(type); | 1276 result = compiler.world.findNoSuchMethodHolders(type); |
1277 noSuchMethodHolders[element] = result; | 1277 noSuchMethodHolders[element] = result; |
1278 } | 1278 } |
1279 return result; | 1279 return result; |
1280 } | 1280 } |
1281 | 1281 |
1282 CodeBuffer generateMethod(String methodName, Selector selector) { | 1282 CodeBuffer generateMethod(String methodName, Selector selector) { |
1283 // Values match JSInvocationMirror in js-helper library. | |
1284 const int METHOD = 0; | |
1285 const int GETTER = 1; | |
1286 const int SETTER = 2; | |
1287 int type = METHOD; | |
1288 if (selector.isGetter()) { | |
1289 type = GETTER; | |
1290 } else if (selector.isSetter()) { | |
1291 type = SETTER; | |
1292 } | |
1293 CodeBuffer args = new CodeBuffer(); | 1283 CodeBuffer args = new CodeBuffer(); |
1294 for (int i = 0; i < selector.argumentCount; i++) { | 1284 for (int i = 0; i < selector.argumentCount; i++) { |
1295 if (i != 0) args.add(', '); | 1285 if (i != 0) args.add(', '); |
1296 args.add('\$$i'); | 1286 args.add('\$$i'); |
1297 } | 1287 } |
1298 CodeBuffer argNames = new CodeBuffer(); | |
1299 List<SourceString> names = selector.getOrderedNamedArguments(); | |
1300 for (int i = 0; i < names.length; i++) { | |
1301 if (i != 0) argNames.add(', '); | |
1302 argNames.add('"'); | |
1303 argNames.add(names[i].slowToString()); | |
1304 argNames.add('"'); | |
1305 } | |
1306 String internalName = namer.instanceMethodInvocationName( | |
1307 selector.library, new SourceString(methodName), selector); | |
1308 CodeBuffer buffer = new CodeBuffer(); | 1288 CodeBuffer buffer = new CodeBuffer(); |
1309 buffer.add('function($args) {\n'); | 1289 buffer.add('function($args) {\n'); |
1310 buffer.add(' return this.$noSuchMethodName(' | 1290 buffer.add(' return this.$noSuchMethodName("$methodName", [$args]);\n'); |
1311 '\$.createInvocationMirror("$methodName", "$internalName",' | |
1312 ' $type, [$args], [$argNames]));\n'); | |
1313 buffer.add(' }'); | 1291 buffer.add(' }'); |
1314 return buffer; | 1292 return buffer; |
1315 } | 1293 } |
1316 | 1294 |
1317 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 1295 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
1318 // Cache the object class and type. | 1296 // Cache the object class and type. |
1319 ClassElement objectClass = compiler.objectClass; | 1297 ClassElement objectClass = compiler.objectClass; |
1320 DartType objectType = objectClass.computeType(compiler); | 1298 DartType objectType = objectClass.computeType(compiler); |
1321 | 1299 |
1322 for (Selector selector in selectors) { | 1300 for (Selector selector in selectors) { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 const String HOOKS_API_USAGE = """ | 1566 const String HOOKS_API_USAGE = """ |
1589 // Generated by dart2js, the Dart to JavaScript compiler. | 1567 // Generated by dart2js, the Dart to JavaScript compiler. |
1590 // The code supports the following hooks: | 1568 // The code supports the following hooks: |
1591 // dartPrint(message) - if this function is defined it is called | 1569 // dartPrint(message) - if this function is defined it is called |
1592 // instead of the Dart [print] method. | 1570 // instead of the Dart [print] method. |
1593 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1571 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1594 // method will not be invoked directly. | 1572 // method will not be invoked directly. |
1595 // Instead, a closure that will invoke [main] is | 1573 // Instead, a closure that will invoke [main] is |
1596 // passed to [dartMainRunner]. | 1574 // passed to [dartMainRunner]. |
1597 """; | 1575 """; |
OLD | NEW |