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

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

Issue 246633006: Revert "JS templates" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 | 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 InterceptorEmitter extends CodeEmitterHelper { 7 class InterceptorEmitter extends CodeEmitterHelper {
8 final Set<String> interceptorInvocationNames = new Set<String>(); 8 final Set<String> interceptorInvocationNames = new Set<String>();
9 9
10 void recordMangledNameOfMemberMethod(FunctionElement member, String name) { 10 void recordMangledNameOfMemberMethod(FunctionElement member, String name) {
(...skipping 11 matching lines...) Expand all
22 InterceptorConstant interceptorConstant = constant; 22 InterceptorConstant interceptorConstant = constant;
23 classes.add(interceptorConstant.dispatchedType.element); 23 classes.add(interceptorConstant.dispatchedType.element);
24 } 24 }
25 } 25 }
26 return classes; 26 return classes;
27 } 27 }
28 28
29 void emitGetInterceptorMethod(CodeBuffer buffer, 29 void emitGetInterceptorMethod(CodeBuffer buffer,
30 String key, 30 String key,
31 Set<ClassElement> classes) { 31 Set<ClassElement> classes) {
32 jsAst.Expression interceptorFor(ClassElement cls) { 32 jsAst.Statement buildReturnInterceptor(ClassElement cls) {
33 return js('#.prototype', namer.elementAccess(cls)); 33 return js.return_(js(namer.isolateAccess(cls))['prototype']);
34 } 34 }
35 35
36 /** 36 /**
37 * Build a JavaScrit AST node for doing a type check on 37 * Build a JavaScrit AST node for doing a type check on
38 * [cls]. [cls] must be a non-native interceptor class. 38 * [cls]. [cls] must be an interceptor class.
39 */ 39 */
40 jsAst.Statement buildInterceptorCheck(ClassElement cls) { 40 jsAst.Statement buildInterceptorCheck(ClassElement cls) {
41 jsAst.Expression condition; 41 jsAst.Expression condition;
42 assert(backend.isInterceptorClass(cls)); 42 assert(backend.isInterceptorClass(cls));
43 if (cls == backend.jsBoolClass) { 43 if (cls == backend.jsBoolClass) {
44 condition = js('(typeof receiver) == "boolean"'); 44 condition = js('(typeof receiver) == "boolean"');
45 } else if (cls == backend.jsIntClass || 45 } else if (cls == backend.jsIntClass ||
46 cls == backend.jsDoubleClass || 46 cls == backend.jsDoubleClass ||
47 cls == backend.jsNumberClass) { 47 cls == backend.jsNumberClass) {
48 throw 'internal error'; 48 throw 'internal error';
49 } else if (cls == backend.jsArrayClass || 49 } else if (cls == backend.jsArrayClass ||
50 cls == backend.jsMutableArrayClass || 50 cls == backend.jsMutableArrayClass ||
51 cls == backend.jsFixedArrayClass || 51 cls == backend.jsFixedArrayClass ||
52 cls == backend.jsExtendableArrayClass) { 52 cls == backend.jsExtendableArrayClass) {
53 condition = js('receiver.constructor == Array'); 53 condition = js('receiver.constructor == Array');
54 } else if (cls == backend.jsStringClass) { 54 } else if (cls == backend.jsStringClass) {
55 condition = js('(typeof receiver) == "string"'); 55 condition = js('(typeof receiver) == "string"');
56 } else if (cls == backend.jsNullClass) { 56 } else if (cls == backend.jsNullClass) {
57 condition = js('receiver == null'); 57 condition = js('receiver == null');
58 } else { 58 } else {
59 throw 'internal error'; 59 throw 'internal error';
60 } 60 }
61 return js.statement('if (#) return #', [condition, interceptorFor(cls)]); 61 return js.if_(condition, buildReturnInterceptor(cls));
62 } 62 }
63 63
64 bool hasArray = false; 64 bool hasArray = false;
65 bool hasBool = false; 65 bool hasBool = false;
66 bool hasDouble = false; 66 bool hasDouble = false;
67 bool hasInt = false; 67 bool hasInt = false;
68 bool hasNull = false; 68 bool hasNull = false;
69 bool hasNumber = false; 69 bool hasNumber = false;
70 bool hasString = false; 70 bool hasString = false;
71 bool hasNative = false; 71 bool hasNative = false;
(...skipping 29 matching lines...) Expand all
101 if (hasDouble) { 101 if (hasDouble) {
102 hasNumber = true; 102 hasNumber = true;
103 } 103 }
104 if (hasInt) hasNumber = true; 104 if (hasInt) hasNumber = true;
105 105
106 if (classes.containsAll(backend.interceptedClasses)) { 106 if (classes.containsAll(backend.interceptedClasses)) {
107 // I.e. this is the general interceptor. 107 // I.e. this is the general interceptor.
108 hasNative = anyNativeClasses; 108 hasNative = anyNativeClasses;
109 } 109 }
110 110
111 List<Statement> statements = <Statement>[]; 111 jsAst.Block block = new jsAst.Block.empty();
112 112
113 if (hasNumber) { 113 if (hasNumber) {
114 jsAst.Statement whenNumber; 114 jsAst.Statement whenNumber;
115 115
116 /// Note: there are two number classes in play: Dart's [num], 116 /// Note: there are two number classes in play: Dart's [num],
117 /// and JavaScript's Number (typeof receiver == 'number'). This 117 /// and JavaScript's Number (typeof receiver == 'number'). This
118 /// is the fallback used when we have determined that receiver 118 /// is the fallback used when we have determined that receiver
119 /// is a JavaScript Number. 119 /// is a JavaScript Number.
120 jsAst.Expression interceptorForNumber = interceptorFor( 120 jsAst.Return returnNumberClass = buildReturnInterceptor(
121 hasDouble ? backend.jsDoubleClass : backend.jsNumberClass); 121 hasDouble ? backend.jsDoubleClass : backend.jsNumberClass);
122 122
123 if (hasInt) { 123 if (hasInt) {
124 whenNumber = js.statement('''{ 124 jsAst.Expression isInt = js('Math.floor(receiver) == receiver');
125 if (Math.floor(receiver) == receiver) return #; 125 whenNumber = js.block([
126 return #; 126 js.if_(isInt, buildReturnInterceptor(backend.jsIntClass)),
127 }''', [interceptorFor(backend.jsIntClass), interceptorForNumber]); 127 returnNumberClass]);
128 } else { 128 } else {
129 whenNumber = js.statement('return #', interceptorForNumber); 129 whenNumber = returnNumberClass;
130 } 130 }
131 statements.add( 131 block.statements.add(
132 js.statement('if (typeof receiver == "number") #;', whenNumber)); 132 js.if_('(typeof receiver) == "number"',
133 whenNumber));
133 } 134 }
134 135
135 if (hasString) { 136 if (hasString) {
136 statements.add(buildInterceptorCheck(backend.jsStringClass)); 137 block.statements.add(buildInterceptorCheck(backend.jsStringClass));
137 } 138 }
138 if (hasNull) { 139 if (hasNull) {
139 statements.add(buildInterceptorCheck(backend.jsNullClass)); 140 block.statements.add(buildInterceptorCheck(backend.jsNullClass));
140 } else { 141 } else {
141 // Returning "undefined" or "null" here will provoke a JavaScript 142 // Returning "undefined" or "null" here will provoke a JavaScript
142 // TypeError which is later identified as a null-error by 143 // TypeError which is later identified as a null-error by
143 // [unwrapException] in js_helper.dart. 144 // [unwrapException] in js_helper.dart.
144 statements.add( 145 block.statements.add(js.if_('receiver == null',
145 js.statement('if (receiver == null) return receiver')); 146 js.return_(js('receiver'))));
146 } 147 }
147 if (hasBool) { 148 if (hasBool) {
148 statements.add(buildInterceptorCheck(backend.jsBoolClass)); 149 block.statements.add(buildInterceptorCheck(backend.jsBoolClass));
149 } 150 }
150 // TODO(ahe): It might be faster to check for Array before 151 // TODO(ahe): It might be faster to check for Array before
151 // function and bool. 152 // function and bool.
152 if (hasArray) { 153 if (hasArray) {
153 statements.add(buildInterceptorCheck(backend.jsArrayClass)); 154 block.statements.add(buildInterceptorCheck(backend.jsArrayClass));
154 } 155 }
155 156
156 if (hasNative) { 157 if (hasNative) {
157 statements.add(js.statement(r'''{ 158 block.statements.add(
158 if (typeof receiver != "object") return receiver; 159 js.if_(
159 if (receiver instanceof #) return receiver; 160 js('(typeof receiver) != "object"'),
160 return #(receiver); 161 js.return_(js('receiver'))));
161 }''', [ 162
162 namer.elementAccess(compiler.objectClass), 163 // if (receiver instanceof $.Object) return receiver;
163 namer.elementAccess(backend.getNativeInterceptorMethod)])); 164 // return $.getNativeInterceptor(receiver);
165 block.statements.add(
166 js.if_(js('receiver instanceof #',
167 js(namer.isolateAccess(compiler.objectClass))),
168 js.return_(js('receiver'))));
169 block.statements.add(
170 js.return_(
171 js(namer.isolateAccess(backend.getNativeInterceptorMethod))(
172 ['receiver'])));
164 173
165 } else { 174 } else {
166 ClassElement jsUnknown = backend.jsUnknownJavaScriptObjectClass; 175 ClassElement jsUnknown = backend.jsUnknownJavaScriptObjectClass;
167 if (compiler.codegenWorld.instantiatedClasses.contains(jsUnknown)) { 176 if (compiler.codegenWorld.instantiatedClasses.contains(jsUnknown)) {
168 statements.add( 177 block.statements.add(
169 js.statement('if (!(receiver instanceof #)) return #;', 178 js.if_(js('!(receiver instanceof #)',
170 [namer.elementAccess(compiler.objectClass), 179 js(namer.isolateAccess(compiler.objectClass))),
171 interceptorFor(jsUnknown)])); 180 buildReturnInterceptor(jsUnknown)));
172 } 181 }
173 182
174 statements.add(js.statement('return receiver')); 183 block.statements.add(js.return_(js('receiver')));
175 } 184 }
176 185
177 buffer.write(jsAst.prettyPrint( 186 buffer.write(jsAst.prettyPrint(
178 js('''${namer.globalObjectFor(compiler.interceptorsLibrary)}.# = 187 js('${namer.globalObjectFor(compiler.interceptorsLibrary)}.$key = #',
179 function(receiver) { #; }''', 188 js.fun(['receiver'], block)),
180 [key, statements]),
181 compiler)); 189 compiler));
182 buffer.write(N); 190 buffer.write(N);
183 } 191 }
184 192
185 /** 193 /**
186 * Emit all versions of the [:getInterceptor:] method. 194 * Emit all versions of the [:getInterceptor:] method.
187 */ 195 */
188 void emitGetInterceptorMethods(CodeBuffer buffer) { 196 void emitGetInterceptorMethods(CodeBuffer buffer) {
189 task.addComment('getInterceptor methods', buffer); 197 task.addComment('getInterceptor methods', buffer);
190 Map<String, Set<ClassElement>> specializedGetInterceptors = 198 Map<String, Set<ClassElement>> specializedGetInterceptors =
191 backend.specializedGetInterceptors; 199 backend.specializedGetInterceptors;
192 for (String name in specializedGetInterceptors.keys.toList()..sort()) { 200 for (String name in specializedGetInterceptors.keys.toList()..sort()) {
193 Set<ClassElement> classes = specializedGetInterceptors[name]; 201 Set<ClassElement> classes = specializedGetInterceptors[name];
194 emitGetInterceptorMethod(buffer, name, classes); 202 emitGetInterceptorMethod(buffer, name, classes);
195 } 203 }
196 } 204 }
197 205
198 // Returns a statement that takes care of performance critical 206 // Returns a statement that takes care of performance critical
199 // common case for a one-shot interceptor, or null if there is no 207 // common case for a one-shot interceptor, or null if there is no
200 // fast path. 208 // fast path.
201 jsAst.Statement fastPathForOneShotInterceptor(Selector selector, 209 jsAst.Statement fastPathForOneShotInterceptor(Selector selector,
202 Set<ClassElement> classes) { 210 Set<ClassElement> classes) {
211 jsAst.Expression isNumber(String variable) {
212 return js('typeof $variable == "number"');
213 }
214
215 jsAst.Expression isNotObject(String variable) {
216 return js('typeof $variable != "object"');
217 }
218
219 jsAst.Expression isInt(String variable) {
220 return isNumber(variable).binary('&&',
221 js('Math.floor($variable) == $variable'));
222 }
223
224 jsAst.Expression tripleShiftZero(jsAst.Expression receiver) {
225 return receiver.binary('>>>', js('0'));
226 }
203 227
204 if (selector.isOperator()) { 228 if (selector.isOperator()) {
205 String name = selector.name; 229 String name = selector.name;
206 if (name == '==') { 230 if (name == '==') {
207 return js.statement('''{ 231 // Unfolds to:
208 if (receiver == null) return a0 == null; 232 // if (receiver == null) return a0 == null;
209 if (typeof receiver != "object") 233 // if (typeof receiver != 'object') {
210 return a0 != null && receiver === a0; 234 // return a0 != null && receiver === a0;
211 }'''); 235 // }
236 List<jsAst.Statement> body = <jsAst.Statement>[];
237 body.add(js.if_('receiver == null', js.return_(js('a0 == null'))));
238 body.add(js.if_(
239 isNotObject('receiver'),
240 js.return_(js('a0 != null && receiver === a0'))));
241 return new jsAst.Block(body);
212 } 242 }
213 if (!classes.contains(backend.jsIntClass) 243 if (!classes.contains(backend.jsIntClass)
214 && !classes.contains(backend.jsNumberClass) 244 && !classes.contains(backend.jsNumberClass)
215 && !classes.contains(backend.jsDoubleClass)) { 245 && !classes.contains(backend.jsDoubleClass)) {
216 return null; 246 return null;
217 } 247 }
218 if (selector.argumentCount == 1) { 248 if (selector.argumentCount == 1) {
219 // The following operators do not map to a JavaScript operator. 249 // The following operators do not map to a JavaScript
250 // operator.
220 if (name == '~/' || name == '<<' || name == '%' || name == '>>') { 251 if (name == '~/' || name == '<<' || name == '%' || name == '>>') {
221 return null; 252 return null;
222 } 253 }
223 jsAst.Expression result = js('receiver $name a0'); 254 jsAst.Expression result = js('receiver').binary(name, js('a0'));
224 if (name == '&' || name == '|' || name == '^') { 255 if (name == '&' || name == '|' || name == '^') {
225 result = js('# >>> 0', result); 256 result = tripleShiftZero(result);
226 } 257 }
227 return js.statement( 258 // Unfolds to:
228 'if (typeof receiver == "number" && typeof a0 == "number")' 259 // if (typeof receiver == "number" && typeof a0 == "number")
229 ' return #;', 260 // return receiver op a0;
230 result); 261 return js.if_(
262 isNumber('receiver').binary('&&', isNumber('a0')),
263 js.return_(result));
231 } else if (name == 'unary-') { 264 } else if (name == 'unary-') {
232 return js.statement( 265 // [: if (typeof receiver == "number") return -receiver :].
233 'if (typeof receiver == "number") return -receiver'); 266 return js.if_(isNumber('receiver'),
267 js.return_(js('-receiver')));
234 } else { 268 } else {
235 assert(name == '~'); 269 assert(name == '~');
236 return js.statement(''' 270 return js.if_(isInt('receiver'),
237 if (typeof receiver == "number" && Math.floor(receiver) == receiver) 271 js.return_(js('~receiver >>> 0')));
238 return (~receiver) >>> 0;
239 ''');
240 } 272 }
241 } else if (selector.isIndex() || selector.isIndexSet()) { 273 } else if (selector.isIndex() || selector.isIndexSet()) {
242 // For an index operation, this code generates: 274 // For an index operation, this code generates:
243 // 275 //
244 // if (receiver.constructor == Array || typeof receiver == "string") { 276 // if (receiver.constructor == Array || typeof receiver == "string") {
245 // if (a0 >>> 0 === a0 && a0 < receiver.length) { 277 // if (a0 >>> 0 === a0 && a0 < receiver.length) {
246 // return receiver[a0]; 278 // return receiver[a0];
247 // } 279 // }
248 // } 280 // }
249 // 281 //
(...skipping 13 matching lines...) Expand all
263 // The index set operator requires a check on its set value in 295 // The index set operator requires a check on its set value in
264 // checked mode, so we don't optimize the interceptor if the 296 // checked mode, so we don't optimize the interceptor if the
265 // compiler has type assertions enabled. 297 // compiler has type assertions enabled.
266 if (selector.isIndexSet() 298 if (selector.isIndexSet()
267 && (compiler.enableTypeAssertions || !containsArray)) { 299 && (compiler.enableTypeAssertions || !containsArray)) {
268 return null; 300 return null;
269 } 301 }
270 if (!containsArray && !containsString) { 302 if (!containsArray && !containsString) {
271 return null; 303 return null;
272 } 304 }
305 jsAst.Expression isIntAndAboveZero = js('a0 >>> 0 === a0');
306 jsAst.Expression belowLength = js('a0 < receiver.length');
273 jsAst.Expression arrayCheck = js('receiver.constructor == Array'); 307 jsAst.Expression arrayCheck = js('receiver.constructor == Array');
274 jsAst.Expression indexableCheck = 308 jsAst.Expression indexableCheck =
275 backend.generateIsJsIndexableCall(js('receiver'), js('receiver')); 309 backend.generateIsJsIndexableCall(js('receiver'), js('receiver'));
276 310
277 jsAst.Expression orExp(left, right) { 311 jsAst.Expression orExp(left, right) {
278 return left == null ? right : js('# || #', [left, right]); 312 return left == null ? right : left.binary('||', right);
279 } 313 }
280 314
281 if (selector.isIndex()) { 315 if (selector.isIndex()) {
316 jsAst.Expression stringCheck = js('typeof receiver == "string"');
282 jsAst.Expression typeCheck; 317 jsAst.Expression typeCheck;
283 if (containsArray) { 318 if (containsArray) {
284 typeCheck = arrayCheck; 319 typeCheck = arrayCheck;
285 } 320 }
286 321
287 if (containsString) { 322 if (containsString) {
288 typeCheck = orExp(typeCheck, js('typeof receiver == "string"')); 323 typeCheck = orExp(typeCheck, stringCheck);
289 } 324 }
290 325
291 if (containsJsIndexable) { 326 if (containsJsIndexable) {
292 typeCheck = orExp(typeCheck, indexableCheck); 327 typeCheck = orExp(typeCheck, indexableCheck);
293 } 328 }
294 329
295 return js.statement(''' 330 return js.if_(typeCheck,
296 if (#) 331 js.if_(isIntAndAboveZero.binary('&&', belowLength),
297 if ((a0 >>> 0) === a0 && a0 < receiver.length) 332 js.return_(js('receiver[a0]'))));
298 return receiver[a0];
299 ''', typeCheck);
300 } else { 333 } else {
301 jsAst.Expression typeCheck; 334 jsAst.Expression typeCheck;
302 if (containsArray) { 335 if (containsArray) {
303 typeCheck = arrayCheck; 336 typeCheck = arrayCheck;
304 } 337 }
305 338
306 if (containsJsIndexable) { 339 if (containsJsIndexable) {
307 typeCheck = orExp(typeCheck, indexableCheck); 340 typeCheck = orExp(typeCheck, indexableCheck);
308 } 341 }
309 342
310 return js.statement(r''' 343 jsAst.Expression isImmutableArray = typeCheck.binary(
311 if (# && !receiver.immutable$list && 344 '&&', js(r'!receiver.immutable$list'));
312 (a0 >>> 0) === a0 && a0 < receiver.length) 345 return js.if_(isImmutableArray.binary(
313 return receiver[a0] = a1; 346 '&&', isIntAndAboveZero.binary('&&', belowLength)),
314 ''', typeCheck); 347 js.return_(js('receiver[a0] = a1')));
315 } 348 }
316 } 349 }
317 return null; 350 return null;
318 } 351 }
319 352
320 void emitOneShotInterceptors(CodeBuffer buffer) { 353 void emitOneShotInterceptors(CodeBuffer buffer) {
321 List<String> names = backend.oneShotInterceptors.keys.toList(); 354 List<String> names = backend.oneShotInterceptors.keys.toList();
322 names.sort(); 355 names.sort();
323 for (String name in names) { 356 for (String name in names) {
324 Selector selector = backend.oneShotInterceptors[name]; 357 Selector selector = backend.oneShotInterceptors[name];
325 Set<ClassElement> classes = 358 Set<ClassElement> classes =
326 backend.getInterceptedClassesOn(selector.name); 359 backend.getInterceptedClassesOn(selector.name);
327 String getInterceptorName = 360 String getInterceptorName =
328 namer.getInterceptorName(backend.getInterceptorMethod, classes); 361 namer.getInterceptorName(backend.getInterceptorMethod, classes);
329 362
330 List<String> parameterNames = <String>[]; 363 List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
331 parameterNames.add('receiver'); 364 List<jsAst.Expression> arguments = <jsAst.Expression>[];
365 parameters.add(new jsAst.Parameter('receiver'));
366 arguments.add(js('receiver'));
332 367
333 if (selector.isSetter()) { 368 if (selector.isSetter()) {
334 parameterNames.add('value'); 369 parameters.add(new jsAst.Parameter('value'));
370 arguments.add(js('value'));
335 } else { 371 } else {
336 for (int i = 0; i < selector.argumentCount; i++) { 372 for (int i = 0; i < selector.argumentCount; i++) {
337 parameterNames.add('a$i'); 373 String argName = 'a$i';
374 parameters.add(new jsAst.Parameter(argName));
375 arguments.add(js(argName));
338 } 376 }
339 } 377 }
340 378
379 List<jsAst.Statement> body = <jsAst.Statement>[];
380 jsAst.Statement optimizedPath =
381 fastPathForOneShotInterceptor(selector, classes);
382 if (optimizedPath != null) {
383 body.add(optimizedPath);
384 }
385
341 String invocationName = backend.namer.invocationName(selector); 386 String invocationName = backend.namer.invocationName(selector);
342 String globalObject = namer.globalObjectFor(compiler.interceptorsLibrary); 387 String globalObject = namer.globalObjectFor(compiler.interceptorsLibrary);
388 body.add(js.return_(
389 js(globalObject)[getInterceptorName]('receiver')[invocationName](
390 arguments)));
343 391
344 jsAst.Statement optimizedPath = 392 jsAst.Expression assignment =
345 fastPathForOneShotInterceptor(selector, classes); 393 js('${globalObject}.$name = #', js.fun(parameters, body));
346 if (optimizedPath == null) optimizedPath = js.statement(';');
347
348 jsAst.Expression assignment = js('${globalObject}.# = function(#) {'
349 ' #;'
350 ' return #.#(receiver).#(#) }',
351 [name, parameterNames,
352 optimizedPath,
353 globalObject, getInterceptorName, invocationName, parameterNames]);
354 394
355 buffer.write(jsAst.prettyPrint(assignment, compiler)); 395 buffer.write(jsAst.prettyPrint(assignment, compiler));
356 buffer.write(N); 396 buffer.write(N);
357 } 397 }
358 } 398 }
359 399
360 /** 400 /**
361 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the 401 * If [JSInvocationMirror._invokeOn] has been compiled, emit all the
362 * possible selector names that are intercepted into the 402 * possible selector names that are intercepted into the
363 * [interceptedNames] top-level variable. The implementation of 403 * [interceptedNames] top-level variable. The implementation of
(...skipping 14 matching lines...) Expand all
378 var invocationNames = interceptorInvocationNames.toList()..sort(); 418 var invocationNames = interceptorInvocationNames.toList()..sort();
379 List<jsAst.ArrayElement> elements = invocationNames.map( 419 List<jsAst.ArrayElement> elements = invocationNames.map(
380 (String invocationName) { 420 (String invocationName) {
381 jsAst.Literal str = js.string(invocationName); 421 jsAst.Literal str = js.string(invocationName);
382 return new jsAst.ArrayElement(index++, str); 422 return new jsAst.ArrayElement(index++, str);
383 }).toList(); 423 }).toList();
384 jsAst.ArrayInitializer array = 424 jsAst.ArrayInitializer array =
385 new jsAst.ArrayInitializer(invocationNames.length, elements); 425 new jsAst.ArrayInitializer(invocationNames.length, elements);
386 426
387 jsAst.Expression assignment = 427 jsAst.Expression assignment =
388 js('${task.isolateProperties}.# = #', [name, array]); 428 js('${task.isolateProperties}.$name = #', array);
389 429
390 buffer.write(jsAst.prettyPrint(assignment, compiler)); 430 buffer.write(jsAst.prettyPrint(assignment, compiler));
391 buffer.write(N); 431 buffer.write(N);
392 } 432 }
393 433
394 /** 434 /**
395 * Emit initializer for [mapTypeToInterceptor] data structure used by 435 * Emit initializer for [mapTypeToInterceptor] data structure used by
396 * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in 436 * [findInterceptorForType]. See declaration of [mapTypeToInterceptor] in
397 * `interceptors.dart`. 437 * `interceptors.dart`.
398 */ 438 */
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 var map = new jsAst.ObjectInitializer(properties); 483 var map = new jsAst.ObjectInitializer(properties);
444 elements.add(map); 484 elements.add(map);
445 } 485 }
446 } 486 }
447 } 487 }
448 488
449 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer.from(elements); 489 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer.from(elements);
450 String name = 490 String name =
451 backend.namer.getNameOfGlobalField(backend.mapTypeToInterceptor); 491 backend.namer.getNameOfGlobalField(backend.mapTypeToInterceptor);
452 jsAst.Expression assignment = 492 jsAst.Expression assignment =
453 js('${task.isolateProperties}.# = #', [name, array]); 493 js('${task.isolateProperties}.$name = #', array);
454 494
455 buffer.write(jsAst.prettyPrint(assignment, compiler)); 495 buffer.write(jsAst.prettyPrint(assignment, compiler));
456 buffer.write(N); 496 buffer.write(N);
457 } 497 }
458 } 498 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698