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 |
| 11 /// time, instead of them being emitted as part of the Object class. | 11 /// time, instead of them being emitted as part of the Object class. |
| 12 bool get generateTrivialNsmHandlers => true; | 12 bool get generateTrivialNsmHandlers => true; |
| 13 | 13 |
| 14 // If we need fewer than this many noSuchMethod handlers we can save space by | 14 // If we need fewer than this many noSuchMethod handlers we can save space by |
| 15 // just emitting them in JS, rather than emitting the JS needed to generate | 15 // just emitting them in JS, rather than emitting the JS needed to generate |
| 16 // them at run time. | 16 // them at run time. |
| 17 static const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10; | 17 static const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10; |
| 18 | 18 |
| 19 static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4; | 19 static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4; |
| 20 | 20 |
| 21 void emitNoSuchMethodHandlers(DefineStubFunction defineStub) { | 21 void emitNoSuchMethodHandlers(AddPropertyFunction addProperty) { |
| 22 // Do not generate no such method handlers if there is no class. | 22 // Do not generate no such method handlers if there is no class. |
| 23 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; | 23 if (compiler.codegenWorld.instantiatedClasses.isEmpty) return; |
| 24 | 24 |
| 25 String noSuchMethodName = namer.publicInstanceMethodNameByArity( | 25 String noSuchMethodName = namer.publicInstanceMethodNameByArity( |
| 26 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); | 26 Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT); |
| 27 | 27 |
| 28 // Keep track of the JavaScript names we've already added so we | 28 // Keep track of the JavaScript names we've already added so we |
| 29 // do not introduce duplicates (bad for code size). | 29 // do not introduce duplicates (bad for code size). |
| 30 Map<String, Selector> addedJsNames = new Map<String, Selector>(); | 30 Map<String, Selector> addedJsNames = new Map<String, Selector>(); |
| 31 | 31 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 48 task.mangledFieldNames[jsName] = reflectionName; | 48 task.mangledFieldNames[jsName] = reflectionName; |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); | 53 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| 54 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); | 54 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
| 55 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); | 55 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
| 56 | 56 |
| 57 // Set flag used by generateMethod helper below. If we have very few | 57 // Set flag used by generateMethod helper below. If we have very few |
| 58 // handlers we use defineStub for them all, rather than try to generate them | 58 // handlers we use addProperty for them all, rather than try to generate the m |
|
ngeoffray
2013/12/04 14:38:28
Line too long.
Johnni Winther
2013/12/05 11:49:56
Long line.
ahe
2013/12/06 15:57:54
Done.
ahe
2013/12/06 15:57:54
Done.
| |
| 59 // at runtime. | 59 // at runtime. |
| 60 bool haveVeryFewNoSuchMemberHandlers = | 60 bool haveVeryFewNoSuchMemberHandlers = |
| 61 (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS); | 61 (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS); |
| 62 | 62 |
| 63 jsAst.Expression generateMethod(String jsName, Selector selector) { | 63 jsAst.Expression generateMethod(String jsName, Selector selector) { |
| 64 // Values match JSInvocationMirror in js-helper library. | 64 // Values match JSInvocationMirror in js-helper library. |
| 65 int type = selector.invocationMirrorKind; | 65 int type = selector.invocationMirrorKind; |
| 66 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; | 66 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; |
| 67 CodeBuffer args = new CodeBuffer(); | 67 CodeBuffer args = new CodeBuffer(); |
| 68 for (int i = 0; i < selector.argumentCount; i++) { | 68 for (int i = 0; i < selector.argumentCount; i++) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 97 parameters = backend.isInterceptedName(selector.name) | 97 parameters = backend.isInterceptedName(selector.name) |
| 98 ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters)) | 98 ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters)) |
| 99 : parameters; | 99 : parameters; |
| 100 return js.fun(parameters, js.return_(expression)); | 100 return js.fun(parameters, js.return_(expression)); |
| 101 } | 101 } |
| 102 | 102 |
| 103 for (String jsName in addedJsNames.keys.toList()..sort()) { | 103 for (String jsName in addedJsNames.keys.toList()..sort()) { |
| 104 Selector selector = addedJsNames[jsName]; | 104 Selector selector = addedJsNames[jsName]; |
| 105 jsAst.Expression method = generateMethod(jsName, selector); | 105 jsAst.Expression method = generateMethod(jsName, selector); |
| 106 if (method != null) { | 106 if (method != null) { |
| 107 defineStub(jsName, method); | 107 addProperty(jsName, method); |
| 108 String reflectionName = task.getReflectionName(selector, jsName); | 108 String reflectionName = task.getReflectionName(selector, jsName); |
| 109 if (reflectionName != null) { | 109 if (reflectionName != null) { |
| 110 bool accessible = compiler.world.allFunctions.filter(selector).any( | 110 bool accessible = compiler.world.allFunctions.filter(selector).any( |
| 111 (Element e) => backend.isAccessibleByReflection(e)); | 111 (Element e) => backend.isAccessibleByReflection(e)); |
| 112 defineStub('+$reflectionName', js(accessible ? '1' : '0')); | 112 addProperty('+$reflectionName', js(accessible ? '1' : '0')); |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Identify the noSuchMethod handlers that are so simple that we can | 118 // Identify the noSuchMethod handlers that are so simple that we can |
| 119 // generate them programatically. | 119 // generate them programatically. |
| 120 bool isTrivialNsmHandler( | 120 bool isTrivialNsmHandler( |
| 121 int type, List argNames, Selector selector, String internalName) { | 121 int type, List argNames, Selector selector, String internalName) { |
| 122 if (!generateTrivialNsmHandlers) return false; | 122 if (!generateTrivialNsmHandlers) return false; |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 [js.return_(js( | 356 [js.return_(js( |
| 357 'this.$noSuchMethodName(' | 357 'this.$noSuchMethodName(' |
| 358 'this, ' | 358 'this, ' |
| 359 '$createInvocationMirror(' | 359 '$createInvocationMirror(' |
| 360 'name, short, type, ' | 360 'name, short, type, ' |
| 361 '$slice(arguments$sliceOffsetParam), []))'))]))])) | 361 '$slice(arguments$sliceOffsetParam), []))'))]))])) |
| 362 ]) | 362 ]) |
| 363 ]); | 363 ]); |
| 364 } | 364 } |
| 365 } | 365 } |
| OLD | NEW |