Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class NsmEmitter extends CodeEmitterHelper { | 7 class NsmEmitter extends CodeEmitterHelper { |
| 8 final List<Selector> trivialNsmHandlers = <Selector>[]; | 8 final List<Selector> trivialNsmHandlers = <Selector>[]; |
| 9 | 9 |
| 10 /// If this is true then we can generate the noSuchMethod handlers at startup | 10 /// If this is true then we can generate the noSuchMethod handlers at startup |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 String internalName = namer.invocationMirrorInternalName(selector); | 74 String internalName = namer.invocationMirrorInternalName(selector); |
| 75 String reflectionName = emitter.getReflectionName(selector, internalName); | 75 String reflectionName = emitter.getReflectionName(selector, internalName); |
| 76 if (!haveVeryFewNoSuchMemberHandlers && | 76 if (!haveVeryFewNoSuchMemberHandlers && |
| 77 isTrivialNsmHandler(type, argNames, selector, internalName) && | 77 isTrivialNsmHandler(type, argNames, selector, internalName) && |
| 78 reflectionName == null) { | 78 reflectionName == null) { |
| 79 trivialNsmHandlers.add(selector); | 79 trivialNsmHandlers.add(selector); |
| 80 return null; | 80 return null; |
| 81 } | 81 } |
| 82 | 82 |
| 83 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); | 83 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); |
| 84 jsAst.Expression expression = js('this.#(this, #(#, #, #, #, #))', [ | 84 jsAst.Expression expression = |
| 85 noSuchMethodName, | 85 js('''this.#noSuchMethodName(this, |
| 86 backend.emitter.staticFunctionAccess( | 86 #createInvocationMirror(#methodName, |
| 87 backend.getCreateInvocationMirror()), | 87 #internalName, |
| 88 js.string(compiler.enableMinification ? | 88 #type, |
| 89 internalName : methodName), | 89 #arguments, |
| 90 js.string(internalName), | 90 #namedArguments))''', |
| 91 js.number(type), | 91 {'noSuchMethodName': noSuchMethodName, |
| 92 new jsAst.ArrayInitializer(parameterNames.map(js).toList()), | 92 'createInvocationMirror': |
| 93 new jsAst.ArrayInitializer(argNames)]); | 93 backend.emitter.staticFunctionAccess( |
| 94 backend.getCreateInvocationMirror()), | |
| 95 'methodName': | |
| 96 js.string(compiler.enableMinification | |
| 97 ? internalName : methodName), | |
| 98 'internalName': js.string(internalName), | |
| 99 'type': js.number(type), | |
| 100 'arguments': | |
| 101 new jsAst.ArrayInitializer(parameterNames.map(js).toList()), | |
| 102 'namedArguments': new jsAst.ArrayInitializer(argNames)}); | |
| 94 | 103 |
| 95 if (backend.isInterceptedName(selector.name)) { | 104 if (backend.isInterceptedName(selector.name)) { |
| 96 return js(r'function($receiver, #) { return # }', | 105 return js(r'function($receiver, #) { return # }', |
| 97 [parameterNames, expression]); | 106 [parameterNames, expression]); |
| 98 } else { | 107 } else { |
| 99 return js(r'function(#) { return # }', [parameterNames, expression]); | 108 return js(r'function(#) { return # }', [parameterNames, expression]); |
| 100 } | 109 } |
| 101 } | 110 } |
| 102 | 111 |
| 103 for (String jsName in addedJsNames.keys.toList()..sort()) { | 112 for (String jsName in addedJsNames.keys.toList()..sort()) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 // Startup code that loops over the method names and puts handlers on the | 279 // Startup code that loops over the method names and puts handlers on the |
| 271 // Object class to catch noSuchMethod invocations. | 280 // Object class to catch noSuchMethod invocations. |
| 272 ClassElement objectClass = compiler.objectClass; | 281 ClassElement objectClass = compiler.objectClass; |
| 273 jsAst.Expression createInvocationMirror = backend.emitter | 282 jsAst.Expression createInvocationMirror = backend.emitter |
| 274 .staticFunctionAccess(backend.getCreateInvocationMirror()); | 283 .staticFunctionAccess(backend.getCreateInvocationMirror()); |
| 275 String noSuchMethodName = namer.publicInstanceMethodNameByArity( | 284 String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
| 276 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); | 285 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
| 277 var type = 0; | 286 var type = 0; |
| 278 if (useDiffEncoding) { | 287 if (useDiffEncoding) { |
| 279 statements.add(js.statement('''{ | 288 statements.add(js.statement('''{ |
| 280 var objectClassObject = | 289 var objectClassObject = |
|
floitsch
2014/12/29 18:09:12
fits on one line?
zarah
2014/12/30 10:29:26
Done.
| |
| 281 collectedClasses[#], // # is name of class Object. | 290 collectedClasses[#objectClass], |
| 282 shortNames = #.split(","), // # is diffEncoding. | 291 shortNames = #diffEncoding.split(","), |
| 283 nameNumber = 0, | 292 nameNumber = 0, |
| 284 diffEncodedString = shortNames[0], | 293 diffEncodedString = shortNames[0], |
| 285 calculatedShortNames = [0, 1]; // 0, 1 are args for splice. | 294 calculatedShortNames = [0, 1]; // 0, 1 are args for splice. |
| 286 // If we are loading a deferred library the object class will not be i n | 295 // If we are loading a deferred library the object class will not be i n |
| 287 // the collectedClasses so objectClassObject is undefined, and we skip | 296 // the collectedClasses so objectClassObject is undefined, and we skip |
| 288 // setting up the names. | 297 // setting up the names. |
| 289 | 298 |
| 290 if (objectClassObject) { | 299 if (objectClassObject) { |
| 291 if (objectClassObject instanceof Array) | 300 if (objectClassObject instanceof Array) |
| 292 objectClassObject = objectClassObject[1]; | 301 objectClassObject = objectClassObject[1]; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 309 for (var remaining = nameNumber; | 318 for (var remaining = nameNumber; |
| 310 remaining > 0; | 319 remaining > 0; |
| 311 remaining = (remaining / 88) | 0) { | 320 remaining = (remaining / 88) | 0) { |
| 312 codes.unshift(${$HASH} + remaining % 88); | 321 codes.unshift(${$HASH} + remaining % 88); |
| 313 } | 322 } |
| 314 calculatedShortNames.push( | 323 calculatedShortNames.push( |
| 315 String.fromCharCode.apply(String, codes)); | 324 String.fromCharCode.apply(String, codes)); |
| 316 } | 325 } |
| 317 shortNames.splice.apply(shortNames, calculatedShortNames); | 326 shortNames.splice.apply(shortNames, calculatedShortNames); |
| 318 } | 327 } |
| 319 }''', [ | 328 }''', {'objectClass': js.string(namer.getNameOfClass(objectClass)), |
| 320 js.string(namer.getNameOfClass(objectClass)), | 329 'diffEncoding': js.string('$diffEncoding')})); |
| 321 js.string('$diffEncoding')])); | |
| 322 } else { | 330 } else { |
| 323 // No useDiffEncoding version. | 331 // No useDiffEncoding version. |
| 324 Iterable<String> longs = trivialNsmHandlers.map((selector) => | 332 Iterable<String> longs = trivialNsmHandlers.map((selector) => |
| 325 selector.invocationMirrorMemberName); | 333 selector.invocationMirrorMemberName); |
| 326 statements.add(js.statement( | 334 statements.add(js.statement( |
| 327 'var objectClassObject = collectedClasses[#],' | 335 'var objectClassObject = collectedClasses[#objectClass],' |
| 328 ' shortNames = #.split(",")', [ | 336 ' shortNames = #diffEncoding.split(",")', { |
|
floitsch
2014/12/29 18:09:12
move the "{" to the next line.
At least for the co
zarah
2014/12/30 10:29:26
Done.
| |
| 329 js.string(namer.getNameOfClass(objectClass)), | 337 'objectClass': js.string(namer.getNameOfClass(objectClass)), |
| 330 js.string('$diffEncoding')])); | 338 'diffEncoding': js.string('$diffEncoding')})); |
| 331 if (!minify) { | 339 if (!minify) { |
| 332 statements.add(js.statement('var longNames = #.split(",")', | 340 statements.add(js.statement('var longNames = #longs.split(",")', |
|
floitsch
2014/12/29 18:09:12
ok. But I didn't find it hard to read.
zarah
2014/12/30 10:29:26
Acknowledged.
| |
| 333 js.string(longs.join(',')))); | 341 {'longs': js.string(longs.join(','))})); |
| 334 } | 342 } |
| 335 statements.add(js.statement( | 343 statements.add(js.statement( |
| 336 'if (objectClassObject instanceof Array)' | 344 'if (objectClassObject instanceof Array)' |
| 337 ' objectClassObject = objectClassObject[1];')); | 345 ' objectClassObject = objectClassObject[1];')); |
| 338 } | 346 } |
| 339 | 347 |
| 340 // TODO(9631): This is no longer valid for native methods. | 348 // TODO(9631): This is no longer valid for native methods. |
| 341 String whatToPatch = emitter.nativeEmitter.handleNoSuchMethod ? | 349 String whatToPatch = emitter.nativeEmitter.handleNoSuchMethod ? |
| 342 "Object.prototype" : | 350 "Object.prototype" : |
| 343 "objectClassObject"; | 351 "objectClassObject"; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 359 for (var j = 0; j < shortNames.length; j++) { | 367 for (var j = 0; j < shortNames.length; j++) { |
| 360 var type = 0; | 368 var type = 0; |
| 361 var short = shortNames[j]; | 369 var short = shortNames[j]; |
| 362 if (short[0] == "${namer.getterPrefix[0]}") type = 1; | 370 if (short[0] == "${namer.getterPrefix[0]}") type = 1; |
| 363 if (short[0] == "${namer.setterPrefix[0]}") type = 2; | 371 if (short[0] == "${namer.setterPrefix[0]}") type = 2; |
| 364 // Generate call to: | 372 // Generate call to: |
| 365 // | 373 // |
| 366 // createInvocationMirror(String name, internalName, type, | 374 // createInvocationMirror(String name, internalName, type, |
| 367 // arguments, argumentNames) | 375 // arguments, argumentNames) |
| 368 // | 376 // |
| 369 $whatToPatch[short] = (function(name, short, type, #) { | 377 $whatToPatch[short] = (function(name, short, |
| 378 type, #sliceOffsetParams) { | |
| 370 return function() { | 379 return function() { |
| 371 return this.#(this, | 380 return this.#noSuchMethodName(this, |
| 372 #(name, short, type, | 381 #createInvocationMirror(name, short, type, |
| 373 Array.prototype.slice.call(arguments, #), | 382 Array.prototype.slice.call(arguments, |
| 374 [])); | 383 #sliceOffsetParams), |
| 384 [])); | |
| 375 } | 385 } |
| 376 })(#[j], short, type, #); | 386 })(#names[j], short, type, #sliceOffsetArguments); |
| 377 } | 387 } |
| 378 }''', [ | 388 }''', { |
| 379 sliceOffsetParams, // parameter | 389 'sliceOffsetParams': sliceOffsetParams, |
| 380 noSuchMethodName, | 390 'noSuchMethodName': noSuchMethodName, |
| 381 createInvocationMirror, | 391 'createInvocationMirror': createInvocationMirror, |
| 382 sliceOffsetParams, // argument to slice | 392 'names': minify ? 'shortNames' : 'longNames', |
| 383 minify ? 'shortNames' : 'longNames', | 393 'sliceOffsetArguments': sliceOffsetArguments})); |
| 384 sliceOffsetArguments | |
| 385 ])); | |
| 386 | 394 |
| 387 return statements; | 395 return statements; |
| 388 } | 396 } |
| 389 } | 397 } |
| OLD | NEW |