Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/js_emitter/nsm_emitter.dart

Issue 27524003: Generate tear-off closures dynamically. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r30954 Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
59 // at runtime. 59 // them 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++) {
69 parameters.add(new jsAst.Parameter('\$$i')); 69 parameters.add(new jsAst.Parameter('\$$i'));
(...skipping 27 matching lines...) Expand all
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698