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

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

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

Powered by Google App Engine
This is Rietveld 408576698