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

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

Issue 2818463002: Remove Compiler and JavaScriptBackend from interceptor_stub_generator. (Closed)
Patch Set: Created 3 years, 8 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.js_emitter.interceptor_stub_generator; 5 library dart2js.js_emitter.interceptor_stub_generator;
6 6
7 import '../compiler.dart' show Compiler; 7 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
8
9 import '../common_elements.dart';
8 import '../constants/values.dart'; 10 import '../constants/values.dart';
9 import '../elements/entities.dart'; 11 import '../elements/entities.dart';
10 import '../elements/types.dart' show InterfaceType; 12 import '../elements/types.dart' show InterfaceType;
11 import '../js/js.dart' as jsAst; 13 import '../js/js.dart' as jsAst;
12 import '../js/js.dart' show js; 14 import '../js/js.dart' show js;
13 import '../js_backend/js_backend.dart' 15 import '../js_backend/namer.dart' show Namer;
14 show 16 import '../js_backend/constant_handler_javascript.dart'
15 CustomElementsCodegenAnalysis, 17 show JavaScriptConstantCompiler;
16 JavaScriptBackend, 18 import '../js_backend/custom_elements_analysis.dart'
17 JavaScriptConstantCompiler, 19 show CustomElementsCodegenAnalysis;
18 Namer; 20 import '../js_backend/native_data.dart';
21 import '../js_backend/interceptor_data.dart';
22 import '../native/enqueue.dart';
23 import '../options.dart';
19 import '../universe/selector.dart' show Selector; 24 import '../universe/selector.dart' show Selector;
25 import '../universe/world_builder.dart' show CodegenWorldBuilder;
20 import '../world.dart' show ClosedWorld; 26 import '../world.dart' show ClosedWorld;
21 27
22 import 'code_emitter_task.dart' show Emitter; 28 import 'code_emitter_task.dart' show CodeEmitterTask, Emitter;
23 29
24 class InterceptorStubGenerator { 30 class InterceptorStubGenerator {
25 final Compiler compiler; 31 final CompilerOptions _options;
26 final Namer namer; 32 final CommonElements _commonElements;
27 final JavaScriptBackend backend; 33 final CodeEmitterTask _emitterTask;
28 final ClosedWorld closedWorld; 34 final NativeCodegenEnqueuer _nativeCodegenEnqueuer;
35 final JavaScriptConstantCompiler _constants;
36 final Namer _namer;
37 final NativeData _nativeData;
38 final InterceptorData _interceptorData;
39 final OneShotInterceptorData _oneShotInterceptorData;
40 final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis;
41 final CodegenWorldBuilder _codegenWorldBuilder;
42 final ClosedWorld _closedWorld;
29 43
30 InterceptorStubGenerator( 44 InterceptorStubGenerator(
31 this.compiler, this.namer, this.backend, this.closedWorld); 45 this._options,
46 this._commonElements,
47 this._emitterTask,
48 this._nativeCodegenEnqueuer,
49 this._constants,
50 this._namer,
51 this._nativeData,
52 this._interceptorData,
53 this._oneShotInterceptorData,
54 this._customElementsCodegenAnalysis,
55 this._codegenWorldBuilder,
56 this._closedWorld);
32 57
33 Emitter get emitter => backend.emitter.emitter; 58 Emitter get _emitter => _emitterTask.emitter;
34 59
35 jsAst.Expression generateGetInterceptorMethod(Set<ClassEntity> classes) { 60 jsAst.Expression generateGetInterceptorMethod(Set<ClassEntity> classes) {
36 jsAst.Expression interceptorFor(ClassEntity cls) { 61 jsAst.Expression interceptorFor(ClassEntity cls) {
37 return backend.emitter.interceptorPrototypeAccess(cls); 62 return _emitterTask.interceptorPrototypeAccess(cls);
38 } 63 }
39 64
40 /** 65 /**
41 * Build a JavaScrit AST node for doing a type check on 66 * Build a JavaScrit AST node for doing a type check on
42 * [cls]. [cls] must be a non-native interceptor class. 67 * [cls]. [cls] must be a non-native interceptor class.
43 */ 68 */
44 jsAst.Statement buildInterceptorCheck(ClassEntity cls) { 69 jsAst.Statement buildInterceptorCheck(ClassEntity cls) {
45 jsAst.Expression condition; 70 jsAst.Expression condition;
46 assert(backend.interceptorData.isInterceptedClass(cls)); 71 assert(_interceptorData.isInterceptedClass(cls));
47 if (cls == compiler.commonElements.jsBoolClass) { 72 if (cls == _commonElements.jsBoolClass) {
48 condition = js('(typeof receiver) == "boolean"'); 73 condition = js('(typeof receiver) == "boolean"');
49 } else if (cls == compiler.commonElements.jsIntClass || 74 } else if (cls == _commonElements.jsIntClass ||
50 cls == compiler.commonElements.jsDoubleClass || 75 cls == _commonElements.jsDoubleClass ||
51 cls == compiler.commonElements.jsNumberClass) { 76 cls == _commonElements.jsNumberClass) {
52 throw 'internal error'; 77 throw 'internal error';
53 } else if (cls == compiler.commonElements.jsArrayClass || 78 } else if (cls == _commonElements.jsArrayClass ||
54 cls == compiler.commonElements.jsMutableArrayClass || 79 cls == _commonElements.jsMutableArrayClass ||
55 cls == compiler.commonElements.jsFixedArrayClass || 80 cls == _commonElements.jsFixedArrayClass ||
56 cls == compiler.commonElements.jsExtendableArrayClass) { 81 cls == _commonElements.jsExtendableArrayClass) {
57 condition = js('receiver.constructor == Array'); 82 condition = js('receiver.constructor == Array');
58 } else if (cls == compiler.commonElements.jsStringClass) { 83 } else if (cls == _commonElements.jsStringClass) {
59 condition = js('(typeof receiver) == "string"'); 84 condition = js('(typeof receiver) == "string"');
60 } else if (cls == compiler.commonElements.jsNullClass) { 85 } else if (cls == _commonElements.jsNullClass) {
61 condition = js('receiver == null'); 86 condition = js('receiver == null');
62 } else { 87 } else {
63 throw 'internal error'; 88 throw 'internal error';
64 } 89 }
65 return js.statement('if (#) return #', [condition, interceptorFor(cls)]); 90 return js.statement('if (#) return #', [condition, interceptorFor(cls)]);
66 } 91 }
67 92
68 bool hasArray = false; 93 bool hasArray = false;
69 bool hasBool = false; 94 bool hasBool = false;
70 bool hasDouble = false; 95 bool hasDouble = false;
71 bool hasInt = false; 96 bool hasInt = false;
72 bool hasNull = false; 97 bool hasNull = false;
73 bool hasNumber = false; 98 bool hasNumber = false;
74 bool hasString = false; 99 bool hasString = false;
75 bool hasNative = false; 100 bool hasNative = false;
76 bool anyNativeClasses = 101 bool anyNativeClasses = _nativeCodegenEnqueuer.hasInstantiatedNativeClasses;
77 backend.nativeCodegenEnqueuer.hasInstantiatedNativeClasses;
78 102
79 for (ClassEntity cls in classes) { 103 for (ClassEntity cls in classes) {
80 if (cls == compiler.commonElements.jsArrayClass || 104 if (cls == _commonElements.jsArrayClass ||
81 cls == compiler.commonElements.jsMutableArrayClass || 105 cls == _commonElements.jsMutableArrayClass ||
82 cls == compiler.commonElements.jsFixedArrayClass || 106 cls == _commonElements.jsFixedArrayClass ||
83 cls == compiler.commonElements.jsExtendableArrayClass) 107 cls == _commonElements.jsExtendableArrayClass)
84 hasArray = true; 108 hasArray = true;
85 else if (cls == compiler.commonElements.jsBoolClass) 109 else if (cls == _commonElements.jsBoolClass)
86 hasBool = true; 110 hasBool = true;
87 else if (cls == compiler.commonElements.jsDoubleClass) 111 else if (cls == _commonElements.jsDoubleClass)
88 hasDouble = true; 112 hasDouble = true;
89 else if (cls == compiler.commonElements.jsIntClass) 113 else if (cls == _commonElements.jsIntClass)
90 hasInt = true; 114 hasInt = true;
91 else if (cls == compiler.commonElements.jsNullClass) 115 else if (cls == _commonElements.jsNullClass)
92 hasNull = true; 116 hasNull = true;
93 else if (cls == compiler.commonElements.jsNumberClass) 117 else if (cls == _commonElements.jsNumberClass)
94 hasNumber = true; 118 hasNumber = true;
95 else if (cls == compiler.commonElements.jsStringClass) 119 else if (cls == _commonElements.jsStringClass)
96 hasString = true; 120 hasString = true;
97 else { 121 else {
98 // The set of classes includes classes mixed-in to interceptor classes 122 // The set of classes includes classes mixed-in to interceptor classes
99 // and user extensions of native classes. 123 // and user extensions of native classes.
100 // 124 //
101 // The set of classes also includes the 'primitive' interceptor 125 // The set of classes also includes the 'primitive' interceptor
102 // PlainJavaScriptObject even when it has not been resolved, since it is 126 // PlainJavaScriptObject even when it has not been resolved, since it is
103 // only resolved through the reference in getNativeInterceptor when 127 // only resolved through the reference in getNativeInterceptor when
104 // getNativeInterceptor is marked as used. Guard against probing 128 // getNativeInterceptor is marked as used. Guard against probing
105 // unresolved PlainJavaScriptObject by testing for anyNativeClasses. 129 // unresolved PlainJavaScriptObject by testing for anyNativeClasses.
106 130
107 if (anyNativeClasses) { 131 if (anyNativeClasses) {
108 if (backend.nativeData.isNativeOrExtendsNative(cls)) hasNative = true; 132 if (_nativeData.isNativeOrExtendsNative(cls)) hasNative = true;
109 } 133 }
110 } 134 }
111 } 135 }
112 if (hasDouble) { 136 if (hasDouble) {
113 hasNumber = true; 137 hasNumber = true;
114 } 138 }
115 if (hasInt) hasNumber = true; 139 if (hasInt) hasNumber = true;
116 140
117 if (classes.containsAll(backend.interceptorData.interceptedClasses)) { 141 if (classes.containsAll(_interceptorData.interceptedClasses)) {
118 // I.e. this is the general interceptor. 142 // I.e. this is the general interceptor.
119 hasNative = anyNativeClasses; 143 hasNative = anyNativeClasses;
120 } 144 }
121 145
122 List<jsAst.Statement> statements = <jsAst.Statement>[]; 146 List<jsAst.Statement> statements = <jsAst.Statement>[];
123 147
124 if (hasNumber) { 148 if (hasNumber) {
125 jsAst.Statement whenNumber; 149 jsAst.Statement whenNumber;
126 150
127 /// Note: there are two number classes in play: Dart's [num], 151 /// Note: there are two number classes in play: Dart's [num],
128 /// and JavaScript's Number (typeof receiver == 'number'). This 152 /// and JavaScript's Number (typeof receiver == 'number'). This
129 /// is the fallback used when we have determined that receiver 153 /// is the fallback used when we have determined that receiver
130 /// is a JavaScript Number. 154 /// is a JavaScript Number.
131 jsAst.Expression interceptorForNumber = interceptorFor(hasDouble 155 jsAst.Expression interceptorForNumber = interceptorFor(hasDouble
132 ? compiler.commonElements.jsDoubleClass 156 ? _commonElements.jsDoubleClass
133 : compiler.commonElements.jsNumberClass); 157 : _commonElements.jsNumberClass);
134 158
135 if (hasInt) { 159 if (hasInt) {
136 whenNumber = js.statement( 160 whenNumber = js.statement(
137 '''{ 161 '''{
138 if (Math.floor(receiver) == receiver) return #; 162 if (Math.floor(receiver) == receiver) return #;
139 return #; 163 return #;
140 }''', 164 }''',
141 [ 165 [interceptorFor(_commonElements.jsIntClass), interceptorForNumber]);
142 interceptorFor(compiler.commonElements.jsIntClass),
143 interceptorForNumber
144 ]);
145 } else { 166 } else {
146 whenNumber = js.statement('return #', interceptorForNumber); 167 whenNumber = js.statement('return #', interceptorForNumber);
147 } 168 }
148 statements 169 statements
149 .add(js.statement('if (typeof receiver == "number") #;', whenNumber)); 170 .add(js.statement('if (typeof receiver == "number") #;', whenNumber));
150 } 171 }
151 172
152 if (hasString) { 173 if (hasString) {
153 statements 174 statements.add(buildInterceptorCheck(_commonElements.jsStringClass));
154 .add(buildInterceptorCheck(compiler.commonElements.jsStringClass));
155 } 175 }
156 if (hasNull) { 176 if (hasNull) {
157 statements 177 statements.add(buildInterceptorCheck(_commonElements.jsNullClass));
158 .add(buildInterceptorCheck(compiler.commonElements.jsNullClass));
159 } else { 178 } else {
160 // Returning "undefined" or "null" here will provoke a JavaScript 179 // Returning "undefined" or "null" here will provoke a JavaScript
161 // TypeError which is later identified as a null-error by 180 // TypeError which is later identified as a null-error by
162 // [unwrapException] in js_helper.dart. 181 // [unwrapException] in js_helper.dart.
163 statements.add(js.statement('if (receiver == null) return receiver')); 182 statements.add(js.statement('if (receiver == null) return receiver'));
164 } 183 }
165 if (hasBool) { 184 if (hasBool) {
166 statements 185 statements.add(buildInterceptorCheck(_commonElements.jsBoolClass));
167 .add(buildInterceptorCheck(compiler.commonElements.jsBoolClass));
168 } 186 }
169 // TODO(ahe): It might be faster to check for Array before 187 // TODO(ahe): It might be faster to check for Array before
170 // function and bool. 188 // function and bool.
171 if (hasArray) { 189 if (hasArray) {
172 statements 190 statements.add(buildInterceptorCheck(_commonElements.jsArrayClass));
173 .add(buildInterceptorCheck(compiler.commonElements.jsArrayClass));
174 } 191 }
175 192
176 if (hasNative) { 193 if (hasNative) {
177 statements.add(js.statement( 194 statements.add(js.statement(
178 r'''{ 195 r'''{
179 if (typeof receiver != "object") { 196 if (typeof receiver != "object") {
180 if (typeof receiver == "function" ) return #; 197 if (typeof receiver == "function" ) return #;
181 return receiver; 198 return receiver;
182 } 199 }
183 if (receiver instanceof #) return receiver; 200 if (receiver instanceof #) return receiver;
184 return #(receiver); 201 return #(receiver);
185 }''', 202 }''',
186 [ 203 [
187 interceptorFor(compiler.commonElements.jsJavaScriptFunctionClass), 204 interceptorFor(_commonElements.jsJavaScriptFunctionClass),
188 backend.emitter 205 _emitter.constructorAccess(_commonElements.objectClass),
189 .constructorAccess(compiler.commonElements.objectClass), 206 _emitter.staticFunctionAccess(
190 backend.emitter.staticFunctionAccess( 207 _commonElements.getNativeInterceptorMethod)
191 compiler.commonElements.getNativeInterceptorMethod)
192 ])); 208 ]));
193 } else { 209 } else {
194 ClassEntity jsUnknown = 210 ClassEntity jsUnknown = _commonElements.jsUnknownJavaScriptObjectClass;
195 compiler.commonElements.jsUnknownJavaScriptObjectClass; 211 if (_codegenWorldBuilder.directlyInstantiatedClasses
196 if (compiler.codegenWorldBuilder.directlyInstantiatedClasses
197 .contains(jsUnknown)) { 212 .contains(jsUnknown)) {
198 statements.add(js.statement('if (!(receiver instanceof #)) return #;', [ 213 statements.add(js.statement('if (!(receiver instanceof #)) return #;', [
199 backend.emitter 214 _emitter.constructorAccess(_commonElements.objectClass),
200 .constructorAccess(compiler.commonElements.objectClass),
201 interceptorFor(jsUnknown) 215 interceptorFor(jsUnknown)
202 ])); 216 ]));
203 } 217 }
204 218
205 statements.add(js.statement('return receiver')); 219 statements.add(js.statement('return receiver'));
206 } 220 }
207 221
208 return js('''function(receiver) { #; }''', new jsAst.Block(statements)); 222 return js('''function(receiver) { #; }''', new jsAst.Block(statements));
209 } 223 }
210 224
225 jsAst.Call _generateIsJsIndexableCall(
226 jsAst.Expression use1, jsAst.Expression use2) {
227 String dispatchPropertyName = embeddedNames.DISPATCH_PROPERTY_NAME;
228 jsAst.Expression dispatchProperty =
229 _emitter.generateEmbeddedGlobalAccess(dispatchPropertyName);
230
231 // We pass the dispatch property record to the isJsIndexable
232 // helper rather than reading it inside the helper to increase the
233 // chance of making the dispatch record access monomorphic.
234 jsAst.PropertyAccess record =
235 new jsAst.PropertyAccess(use2, dispatchProperty);
236
237 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record];
238 FunctionEntity helper = _commonElements.isJsIndexable;
239 jsAst.Expression helperExpression = _emitter.staticFunctionAccess(helper);
240 return new jsAst.Call(helperExpression, arguments);
241 }
242
211 // Returns a statement that takes care of performance critical 243 // Returns a statement that takes care of performance critical
212 // common case for a one-shot interceptor, or null if there is no 244 // common case for a one-shot interceptor, or null if there is no
213 // fast path. 245 // fast path.
214 jsAst.Statement _fastPathForOneShotInterceptor( 246 jsAst.Statement _fastPathForOneShotInterceptor(
215 Selector selector, Set<ClassEntity> classes) { 247 Selector selector, Set<ClassEntity> classes) {
216 if (selector.isOperator) { 248 if (selector.isOperator) {
217 String name = selector.name; 249 String name = selector.name;
218 if (name == '==') { 250 if (name == '==') {
219 return js.statement('''{ 251 return js.statement('''{
220 if (receiver == null) return a0 == null; 252 if (receiver == null) return a0 == null;
221 if (typeof receiver != "object") 253 if (typeof receiver != "object")
222 return a0 != null && receiver === a0; 254 return a0 != null && receiver === a0;
223 }'''); 255 }''');
224 } 256 }
225 if (!classes.contains(compiler.commonElements.jsIntClass) && 257 if (!classes.contains(_commonElements.jsIntClass) &&
226 !classes.contains(compiler.commonElements.jsNumberClass) && 258 !classes.contains(_commonElements.jsNumberClass) &&
227 !classes.contains(compiler.commonElements.jsDoubleClass)) { 259 !classes.contains(_commonElements.jsDoubleClass)) {
228 return null; 260 return null;
229 } 261 }
230 if (selector.argumentCount == 1) { 262 if (selector.argumentCount == 1) {
231 // The following operators do not map to a JavaScript operator. 263 // The following operators do not map to a JavaScript operator.
232 if (name == '~/' || name == '<<' || name == '%' || name == '>>') { 264 if (name == '~/' || name == '<<' || name == '%' || name == '>>') {
233 return null; 265 return null;
234 } 266 }
235 jsAst.Expression result = js('receiver $name a0'); 267 jsAst.Expression result = js('receiver $name a0');
236 if (name == '&' || name == '|' || name == '^') { 268 if (name == '&' || name == '|' || name == '^') {
237 result = js('# >>> 0', result); 269 result = js('# >>> 0', result);
(...skipping 26 matching lines...) Expand all
264 // 296 //
265 // For an index set operation, this code generates: 297 // For an index set operation, this code generates:
266 // 298 //
267 // if (typeof a0 === "number") { 299 // if (typeof a0 === "number") {
268 // if (receiver.constructor == Array && !receiver.immutable$list) { 300 // if (receiver.constructor == Array && !receiver.immutable$list) {
269 // if (a0 >>> 0 === a0 && a0 < receiver.length) { 301 // if (a0 >>> 0 === a0 && a0 < receiver.length) {
270 // return receiver[a0] = a1; 302 // return receiver[a0] = a1;
271 // } 303 // }
272 // } 304 // }
273 // } 305 // }
274 bool containsArray = 306 bool containsArray = classes.contains(_commonElements.jsArrayClass);
275 classes.contains(compiler.commonElements.jsArrayClass); 307 bool containsString = classes.contains(_commonElements.jsStringClass);
276 bool containsString = 308 bool containsJsIndexable = _closedWorld
277 classes.contains(compiler.commonElements.jsStringClass); 309 .isImplemented(_commonElements.jsIndexingBehaviorInterface) &&
278 bool containsJsIndexable = closedWorld.isImplemented(
279 compiler.commonElements.jsIndexingBehaviorInterface) &&
280 classes.any((cls) { 310 classes.any((cls) {
281 return closedWorld.isSubtypeOf( 311 return _closedWorld.isSubtypeOf(
282 cls, compiler.commonElements.jsIndexingBehaviorInterface); 312 cls, _commonElements.jsIndexingBehaviorInterface);
283 }); 313 });
284 // The index set operator requires a check on its set value in 314 // The index set operator requires a check on its set value in
285 // checked mode, so we don't optimize the interceptor if the 315 // checked mode, so we don't optimize the interceptor if the
286 // compiler has type assertions enabled. 316 // _compiler has type assertions enabled.
287 if (selector.isIndexSet && 317 if (selector.isIndexSet &&
288 (compiler.options.enableTypeAssertions || !containsArray)) { 318 (_options.enableTypeAssertions || !containsArray)) {
289 return null; 319 return null;
290 } 320 }
291 if (!containsArray && !containsString) { 321 if (!containsArray && !containsString) {
292 return null; 322 return null;
293 } 323 }
294 jsAst.Expression arrayCheck = js('receiver.constructor == Array'); 324 jsAst.Expression arrayCheck = js('receiver.constructor == Array');
295 jsAst.Expression indexableCheck = 325 jsAst.Expression indexableCheck =
296 backend.generateIsJsIndexableCall(js('receiver'), js('receiver')); 326 _generateIsJsIndexableCall(js('receiver'), js('receiver'));
297 327
298 jsAst.Expression orExp(left, right) { 328 jsAst.Expression orExp(left, right) {
299 return left == null ? right : js('# || #', [left, right]); 329 return left == null ? right : js('# || #', [left, right]);
300 } 330 }
301 331
302 if (selector.isIndex) { 332 if (selector.isIndex) {
303 jsAst.Expression typeCheck; 333 jsAst.Expression typeCheck;
304 if (containsArray) { 334 if (containsArray) {
305 typeCheck = arrayCheck; 335 typeCheck = arrayCheck;
306 } 336 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 return receiver[a0] = a1; 369 return receiver[a0] = a1;
340 ''', 370 ''',
341 typeCheck); 371 typeCheck);
342 } 372 }
343 } 373 }
344 return null; 374 return null;
345 } 375 }
346 376
347 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) { 377 jsAst.Expression generateOneShotInterceptor(jsAst.Name name) {
348 Selector selector = 378 Selector selector =
349 backend.oneShotInterceptorData.getOneShotInterceptorSelector(name); 379 _oneShotInterceptorData.getOneShotInterceptorSelector(name);
350 Set<ClassEntity> classes = 380 Set<ClassEntity> classes =
351 backend.interceptorData.getInterceptedClassesOn(selector.name); 381 _interceptorData.getInterceptedClassesOn(selector.name);
352 jsAst.Name getInterceptorName = namer.nameForGetInterceptor(classes); 382 jsAst.Name getInterceptorName = _namer.nameForGetInterceptor(classes);
353 383
354 List<String> parameterNames = <String>[]; 384 List<String> parameterNames = <String>[];
355 parameterNames.add('receiver'); 385 parameterNames.add('receiver');
356 386
357 if (selector.isSetter) { 387 if (selector.isSetter) {
358 parameterNames.add('value'); 388 parameterNames.add('value');
359 } else { 389 } else {
360 for (int i = 0; i < selector.argumentCount; i++) { 390 for (int i = 0; i < selector.argumentCount; i++) {
361 parameterNames.add('a$i'); 391 parameterNames.add('a$i');
362 } 392 }
363 } 393 }
364 394
365 jsAst.Name invocationName = backend.namer.invocationName(selector); 395 jsAst.Name invocationName = _namer.invocationName(selector);
366 String globalObject = namer 396 String globalObject =
367 .globalObjectForLibrary(compiler.commonElements.interceptorsLibrary); 397 _namer.globalObjectForLibrary(_commonElements.interceptorsLibrary);
368 398
369 jsAst.Statement optimizedPath = 399 jsAst.Statement optimizedPath =
370 _fastPathForOneShotInterceptor(selector, classes); 400 _fastPathForOneShotInterceptor(selector, classes);
371 if (optimizedPath == null) optimizedPath = js.statement(';'); 401 if (optimizedPath == null) optimizedPath = js.statement(';');
372 402
373 return js('function(#) { #; return #.#(receiver).#(#) }', [ 403 return js('function(#) { #; return #.#(receiver).#(#) }', [
374 parameterNames, 404 parameterNames,
375 optimizedPath, 405 optimizedPath,
376 globalObject, 406 globalObject,
377 getInterceptorName, 407 getInterceptorName,
378 invocationName, 408 invocationName,
379 parameterNames 409 parameterNames
380 ]); 410 ]);
381 } 411 }
382 412
383 jsAst.ArrayInitializer generateTypeToInterceptorMap() { 413 jsAst.ArrayInitializer generateTypeToInterceptorMap() {
384 // TODO(sra): Perhaps inject a constant instead? 414 // TODO(sra): Perhaps inject a constant instead?
385 CustomElementsCodegenAnalysis analysis = 415 CustomElementsCodegenAnalysis analysis = _customElementsCodegenAnalysis;
386 backend.customElementsCodegenAnalysis;
387 if (!analysis.needsTable) return null; 416 if (!analysis.needsTable) return null;
388 417
389 List<jsAst.Expression> elements = <jsAst.Expression>[]; 418 List<jsAst.Expression> elements = <jsAst.Expression>[];
390 JavaScriptConstantCompiler handler = backend.constants;
391 List<ConstantValue> constants = 419 List<ConstantValue> constants =
392 handler.getConstantsForEmission(emitter.compareConstants); 420 _constants.getConstantsForEmission(_emitter.compareConstants);
393 for (ConstantValue constant in constants) { 421 for (ConstantValue constant in constants) {
394 if (constant is TypeConstantValue && 422 if (constant is TypeConstantValue &&
395 constant.representedType is InterfaceType) { 423 constant.representedType is InterfaceType) {
396 InterfaceType type = constant.representedType; 424 InterfaceType type = constant.representedType;
397 ClassEntity classElement = type.element; 425 ClassEntity classElement = type.element;
398 if (!analysis.needsClass(classElement)) continue; 426 if (!analysis.needsClass(classElement)) continue;
399 427
400 elements.add(emitter.constantReference(constant)); 428 elements.add(_emitter.constantReference(constant));
401 elements.add(backend.emitter.interceptorClassAccess(classElement)); 429 elements.add(_emitter.interceptorClassAccess(classElement));
402 430
403 // Create JavaScript Object map for by-name lookup of generative 431 // Create JavaScript Object map for by-name lookup of generative
404 // constructors. For example, the class A has three generative 432 // constructors. For example, the class A has three generative
405 // constructors 433 // constructors
406 // 434 //
407 // class A { 435 // class A {
408 // A() {} 436 // A() {}
409 // A.foo() {} 437 // A.foo() {}
410 // A.bar() {} 438 // A.bar() {}
411 // } 439 // }
412 // 440 //
413 // Which are described by the map 441 // Which are described by the map
414 // 442 //
415 // {"": A.A$, "foo": A.A$foo, "bar": A.A$bar} 443 // {"": A.A$, "foo": A.A$foo, "bar": A.A$bar}
416 // 444 //
417 // We expect most of the time the map will be a singleton. 445 // We expect most of the time the map will be a singleton.
418 var properties = []; 446 var properties = [];
419 for (ConstructorEntity member in analysis.constructors(classElement)) { 447 for (ConstructorEntity member in analysis.constructors(classElement)) {
420 properties.add(new jsAst.Property(js.string(member.name), 448 properties.add(new jsAst.Property(
421 backend.emitter.staticFunctionAccess(member))); 449 js.string(member.name), _emitter.staticFunctionAccess(member)));
422 } 450 }
423 451
424 var map = new jsAst.ObjectInitializer(properties); 452 var map = new jsAst.ObjectInitializer(properties);
425 elements.add(map); 453 elements.add(map);
426 } 454 }
427 } 455 }
428 456
429 return new jsAst.ArrayInitializer(elements); 457 return new jsAst.ArrayInitializer(elements);
430 } 458 }
431 } 459 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698