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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/nsm_emitter.dart

Issue 897643002: dart2js: move generation of noSuchMethodStubs into ClassStubGenerator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merged changes from depending cl. Created 5 years, 10 months 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
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/class_stub_generator.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(AddPropertyFunction addProperty) { 21 void emitNoSuchMethodHandlers(AddPropertyFunction addProperty) {
22 22
23 Map<String, Selector> jsNames = <String, Selector>{}; 23 ClassStubGenerator generator =
24 24 new ClassStubGenerator(compiler, namer, backend);
25 Map<String, Selector> computeSelectorsForNsmHandlers() {
26 // Do not generate no such method handlers if there is no class.
27 if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) {
28 return jsNames;
29 }
30
31 void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) {
32 TypeMask objectSubclassTypeMask =
33 new TypeMask.subclass(compiler.objectClass, compiler.world);
34
35 for (Selector selector in selectors) {
36 TypeMask mask = selector.mask;
37 if (mask == null) mask = objectSubclassTypeMask;
38
39 if (!mask.needsNoSuchMethodHandling(selector, compiler.world)) {
40 continue;
41 }
42 String jsName = namer.invocationMirrorInternalName(selector);
43 jsNames[jsName] = selector;
44 }
45 }
46
47 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers);
48 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers);
49 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers);
50 return jsNames;
51 }
52
53 jsAst.Expression generateMethod(Selector selector) {
54 // Values match JSInvocationMirror in js-helper library.
55 int type = selector.invocationMirrorKind;
56 List<String> parameterNames =
57 new List.generate(selector.argumentCount, (i) => '\$$i');
58
59 List<jsAst.Expression> argNames =
60 selector.getOrderedNamedArguments().map((String name) =>
61 js.string(name)).toList();
62
63 String methodName = selector.invocationMirrorMemberName;
64 String internalName = namer.invocationMirrorInternalName(selector);
65
66 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
67 jsAst.Expression expression =
68 js('''this.#noSuchMethodName(this,
69 #createInvocationMirror(#methodName,
70 #internalName,
71 #type,
72 #arguments,
73 #namedArguments))''',
74 {'noSuchMethodName': namer.noSuchMethodName,
75 'createInvocationMirror':
76 backend.emitter.staticFunctionAccess(
77 backend.getCreateInvocationMirror()),
78 'methodName':
79 js.string(compiler.enableMinification
80 ? internalName : methodName),
81 'internalName': js.string(internalName),
82 'type': js.number(type),
83 'arguments':
84 new jsAst.ArrayInitializer(parameterNames.map(js).toList()),
85 'namedArguments': new jsAst.ArrayInitializer(argNames)});
86
87 if (backend.isInterceptedName(selector.name)) {
88 return js(r'function($receiver, #) { return # }',
89 [parameterNames, expression]);
90 } else {
91 return js(r'function(#) { return # }', [parameterNames, expression]);
92 }
93 }
94 25
95 // Keep track of the JavaScript names we've already added so we 26 // Keep track of the JavaScript names we've already added so we
96 // do not introduce duplicates (bad for code size). 27 // do not introduce duplicates (bad for code size).
97 Map<String, Selector> addedJsNames = computeSelectorsForNsmHandlers(); 28 Map<String, Selector> addedJsNames
29 = generator.computeSelectorsForNsmHandlers();
98 30
99 // Set flag used by generateMethod helper below. If we have very few 31 // Set flag used by generateMethod helper below. If we have very few
100 // handlers we use addProperty for them all, rather than try to generate 32 // handlers we use addProperty for them all, rather than try to generate
101 // them at runtime. 33 // them at runtime.
102 bool haveVeryFewNoSuchMemberHandlers = 34 bool haveVeryFewNoSuchMemberHandlers =
103 (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS); 35 (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS);
104 for (String jsName in addedJsNames.keys.toList()..sort()) { 36 for (String jsName in addedJsNames.keys.toList()..sort()) {
105 Selector selector = addedJsNames[jsName]; 37 Selector selector = addedJsNames[jsName];
106 String reflectionName = emitter.getReflectionName(selector, jsName); 38 String reflectionName = emitter.getReflectionName(selector, jsName);
107 39
108 if (reflectionName != null) { 40 if (reflectionName != null) {
109 emitter.mangledFieldNames[jsName] = reflectionName; 41 emitter.mangledFieldNames[jsName] = reflectionName;
110 } 42 }
111 43
112 List<jsAst.Expression> argNames = 44 List<jsAst.Expression> argNames =
113 selector.getOrderedNamedArguments().map((String name) => 45 selector.getOrderedNamedArguments().map((String name) =>
114 js.string(name)).toList(); 46 js.string(name)).toList();
115 int type = selector.invocationMirrorKind; 47 int type = selector.invocationMirrorKind;
116 if (!haveVeryFewNoSuchMemberHandlers && 48 if (!haveVeryFewNoSuchMemberHandlers &&
117 isTrivialNsmHandler(type, argNames, selector, jsName) && 49 isTrivialNsmHandler(type, argNames, selector, jsName) &&
118 reflectionName == null) { 50 reflectionName == null) {
119 trivialNsmHandlers.add(selector); 51 trivialNsmHandlers.add(selector);
120 } 52 }
121 53
122 jsAst.Expression method = generateMethod(selector); 54 jsAst.Expression method = generator.generateStubForNoSuchMethod(selector);
123 if (method != null) { 55 if (method != null) {
124 addProperty(jsName, method); 56 addProperty(jsName, method);
125 if (reflectionName != null) { 57 if (reflectionName != null) {
126 bool accessible = compiler.world.allFunctions.filter(selector).any( 58 bool accessible = compiler.world.allFunctions.filter(selector).any(
127 (Element e) => backend.isAccessibleByReflection(e)); 59 (Element e) => backend.isAccessibleByReflection(e));
128 addProperty('+$reflectionName', js(accessible ? '2' : '0')); 60 addProperty('+$reflectionName', js(accessible ? '2' : '0'));
129 } 61 }
130 } 62 }
131 } 63 }
132 } 64 }
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 }''', { 324 }''', {
393 'sliceOffsetParams': sliceOffsetParams, 325 'sliceOffsetParams': sliceOffsetParams,
394 'noSuchMethodName': namer.noSuchMethodName, 326 'noSuchMethodName': namer.noSuchMethodName,
395 'createInvocationMirror': createInvocationMirror, 327 'createInvocationMirror': createInvocationMirror,
396 'names': minify ? 'shortNames' : 'longNames', 328 'names': minify ? 'shortNames' : 'longNames',
397 'sliceOffsetArguments': sliceOffsetArguments})); 329 'sliceOffsetArguments': sliceOffsetArguments}));
398 330
399 return statements; 331 return statements;
400 } 332 }
401 } 333 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/class_stub_generator.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698