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

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

Issue 1264303002: dart2js: fix a few TODOs in the startup emitter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Emit affinity tag only once. Created 5 years, 4 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
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/native_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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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.startup_emitter.model_emitter; 5 part of dart2js.js_emitter.startup_emitter.model_emitter;
6 6
7 /// The name of the property that stores the tear-off getter on a static 7 /// The name of the property that stores the tear-off getter on a static
8 /// function. 8 /// function.
9 /// 9 ///
10 /// This property is only used when isolates are used. 10 /// This property is only used when isolates are used.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 (function() { 62 (function() {
63 // Copies the own properties from [from] to [to]. 63 // Copies the own properties from [from] to [to].
64 function copyProperties(from, to) { 64 function copyProperties(from, to) {
65 var keys = Object.keys(from); 65 var keys = Object.keys(from);
66 for (var i = 0; i < keys.length; i++) { 66 for (var i = 0; i < keys.length; i++) {
67 to[keys[i]] = from[keys[i]]; 67 to[keys[i]] = from[keys[i]];
68 } 68 }
69 } 69 }
70 70
71 var supportsDirectProtoAccess = (function () {
72 var cls = function () {};
73 cls.prototype = {'p': {}};
74 var object = new cls();
75 return object.__proto__ &&
76 object.__proto__.p === cls.prototype.p;
77 })();
78
79 var functionsHaveName = (function() {
80 function t() {};
81 return (typeof t.name == 'string')
82 })();
83
84 var isChrome = (typeof window != 'undefined') &&
85 (typeof window.chrome != 'undefined');
86
87 // Sets the name property of functions, if the JS engine doesn't set the name
88 // itself.
89 // As of 2015 only IE doesn't set the name.
90 function setFunctionNamesIfNecessary(holders) {
91 if (functionsHaveName) return;
92 for (var i = 0; i < holders.length; i++) {
93 var holder = holders[i];
94 var keys = Object.keys(holder);
95 for (var j = 0; j < keys.length; j++) {
96 var key = keys[j];
97 var f = holder[key];
98 if (typeof f == 'function') f.name = key;
99 }
100 }
101 }
102
71 // Makes [cls] inherit from [sup]. 103 // Makes [cls] inherit from [sup].
72 // On Chrome, Firefox and recent IEs this happens by updating the internal 104 // On Chrome, Firefox and recent IEs this happens by updating the internal
73 // proto-property of the classes 'prototype' field. 105 // proto-property of the classes 'prototype' field.
74 // Older IEs use `Object.create` and copy over the properties. 106 // Older IEs use `Object.create` and copy over the properties.
75 function inherit(cls, sup) { 107 function inherit(cls, sup) {
76 // TODO(floitsch): IE doesn't support changing the __proto__ property. There,
77 // we need to copy the properties instead.
78 cls.#typeNameProperty = cls.name; // Needed for RTI. 108 cls.#typeNameProperty = cls.name; // Needed for RTI.
79 cls.prototype.constructor = cls; 109 cls.prototype.constructor = cls;
80 cls.prototype[#operatorIsPrefix + cls.name] = cls; 110 cls.prototype[#operatorIsPrefix + cls.name] = cls;
81 111
82 // The superclass is only null for the Dart Object. 112 // The superclass is only null for the Dart Object.
83 if (sup != null) { 113 if (sup != null) {
84 cls.prototype.__proto__ = sup.prototype; 114 if (supportsDirectProtoAccess) {
115 // Firefox doesn't like to update the prototypes, but when setting up
116 // the hierarchy chain it's ok.
117 cls.prototype.__proto__ = sup.prototype;
118 return;
119 }
120 var clsPrototype = Object.create(sup.prototype);
121 copyProperties(cls.prototype, clsPrototype);
122 cls.prototype = clsPrototype;
85 } 123 }
86 } 124 }
87 125
88 // Mixes in the properties of [mixin] into [cls]. 126 // Mixes in the properties of [mixin] into [cls].
89 function mixin(cls, mixin) { 127 function mixin(cls, mixin) {
90 copyProperties(mixin.prototype, cls.prototype); 128 copyProperties(mixin.prototype, cls.prototype);
91 } 129 }
92 130
93 // Creates a lazy field. 131 // Creates a lazy field.
94 // 132 //
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // The runtime ensures that const-lists cannot be modified. 164 // The runtime ensures that const-lists cannot be modified.
127 function makeConstList(list) { 165 function makeConstList(list) {
128 // By assigning a function to the properties they become part of the 166 // By assigning a function to the properties they become part of the
129 // hidden class. The actual values of the fields don't matter, since we 167 // hidden class. The actual values of the fields don't matter, since we
130 // only check if they exist. 168 // only check if they exist.
131 list.immutable\$list = Array; 169 list.immutable\$list = Array;
132 list.fixed\$length = Array; 170 list.fixed\$length = Array;
133 return list; 171 return list;
134 } 172 }
135 173
174 function convertToFastObject(properties) {
175 // Create an instance that uses 'properties' as prototype. This should
176 // make 'properties' a fast object.
177 function t() {};
178 t.prototype = properties;
179 new t();
180 return properties;
181 }
182
136 // This variable is used by the tearOffCode to guarantee unique functions per 183 // This variable is used by the tearOffCode to guarantee unique functions per
137 // tear-offs. 184 // tear-offs.
138 var functionCounter = 0; 185 var functionCounter = 0;
139 #tearOffCode; 186 #tearOffCode;
140 187
141 // Each deferred hunk comes with its own types which are added to the end 188 // Each deferred hunk comes with its own types which are added to the end
142 // of the types-array. 189 // of the types-array.
143 // The `funTypes` passed to the `installTearOff` function below is relative to 190 // The `funTypes` passed to the `installTearOff` function below is relative to
144 // the hunk the function comes from. The `typesOffset` variable encodes the 191 // the hunk the function comes from. The `typesOffset` variable encodes the
145 // offset at which the new types will be added. 192 // offset at which the new types will be added.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 // This relies on the fact that types are added *after* the tear-offs have 270 // This relies on the fact that types are added *after* the tear-offs have
224 // been installed. The tear-off function uses the types-length to figure 271 // been installed. The tear-off function uses the types-length to figure
225 // out at which offset its types are located. If the types were added earlier 272 // out at which offset its types are located. If the types were added earlier
226 // the offset would be wrong. 273 // the offset would be wrong.
227 types.push.apply(types, newTypes); 274 types.push.apply(types, newTypes);
228 } 275 }
229 276
230 // Updates the given holder with the properties of the [newHolder]. 277 // Updates the given holder with the properties of the [newHolder].
231 // This function is used when a deferred fragment is initialized. 278 // This function is used when a deferred fragment is initialized.
232 function updateHolder(holder, newHolder) { 279 function updateHolder(holder, newHolder) {
233 // TODO(floitsch): updating the prototype (instead of copying) is 280 // Firefox doesn't like when important objects have their prototype chain
234 // *horribly* inefficient in Firefox. There we should just copy the 281 // updated. We therefore do this only on V8.
235 // properties. 282 if (isChrome) {
236 var oldPrototype = holder.__proto__; 283 var oldPrototype = holder.__proto__;
237 newHolder.__proto__ = oldPrototype; 284 newHolder.__proto__ = oldPrototype;
238 holder.__proto__ = newHolder; 285 holder.__proto__ = newHolder;
286 } else {
287 copyProperties(newHolder, holder);
288 }
239 return holder; 289 return holder;
240 } 290 }
241 291
242 // Every deferred hunk (i.e. fragment) is a function that we can invoke to 292 // Every deferred hunk (i.e. fragment) is a function that we can invoke to
243 // initialize it. At this moment it contributes its data to the main hunk. 293 // initialize it. At this moment it contributes its data to the main hunk.
244 function initializeDeferredHunk(hunk) { 294 function initializeDeferredHunk(hunk) {
245 // Update the typesOffset for the next deferred library. 295 // Update the typesOffset for the next deferred library.
246 typesOffset = #embeddedTypes.length; 296 typesOffset = #embeddedTypes.length;
247 297
248 // TODO(floitsch): extend natives. 298 // TODO(floitsch): extend natives.
249 hunk(inherit, mixin, lazy, makeConstList, installTearOff, 299 hunk(inherit, mixin, lazy, makeConstList, convertToFastObject, installTearOff,
250 updateHolder, updateTypes, setOrUpdateInterceptorsByTag, 300 setFunctionNamesIfNecessary, updateHolder, updateTypes,
251 setOrUpdateLeafTags, 301 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags,
252 #embeddedGlobalsObject, #holdersList, #staticState); 302 #embeddedGlobalsObject, #holdersList, #staticState);
253 } 303 }
254 304
255 // Returns the global with the given [name]. 305 // Returns the global with the given [name].
256 function getGlobalFromName(name) { 306 function getGlobalFromName(name) {
257 // TODO(floitsch): we are running through all holders. Since negative 307 // TODO(floitsch): we are running through all holders. Since negative
258 // lookups are expensive we might need to improve this. 308 // lookups are expensive we might need to improve this.
259 // Relies on the fact that all names are unique across all holders. 309 // Relies on the fact that all names are unique across all holders.
260 for (var i = 0; i < holders.length; i++) { 310 for (var i = 0; i < holders.length; i++) {
261 // The constant holder reuses the same names. Therefore we must skip it. 311 // The constant holder reuses the same names. Therefore we must skip it.
262 if (holders[i] == #constantHolderReference) continue; 312 if (holders[i] == #constantHolderReference) continue;
263 // Relies on the fact that all variables are unique. 313 // Relies on the fact that all variables are unique.
264 if (holders[i][name]) return holders[i][name]; 314 if (holders[i][name]) return holders[i][name];
265 } 315 }
266 } 316 }
267 317
268 // Creates the holders. 318 // Creates the holders.
269 #holders; 319 #holders;
270 // TODO(floitsch): if name is not set (for example in IE), run through all 320
271 // functions and set the name. 321 // If the name is not set on the functions, do it now.
322 setFunctionNamesIfNecessary(#holdersList);
272 323
273 // TODO(floitsch): we should build this object as a literal. 324 // TODO(floitsch): we should build this object as a literal.
274 var #staticStateDeclaration = {}; 325 var #staticStateDeclaration = {};
275 326
276 // Sets the prototypes of classes. 327 // Sets the prototypes of classes.
277 #prototypes; 328 #prototypes;
278 // Sets aliases of methods (on the prototypes of classes). 329 // Sets aliases of methods (on the prototypes of classes).
279 #aliases; 330 #aliases;
280 // Installs the tear-offs of functions. 331 // Installs the tear-offs of functions.
281 #tearOffs; 332 #tearOffs;
(...skipping 18 matching lines...) Expand all
300 #invokeMain; 351 #invokeMain;
301 })(); 352 })();
302 }'''; 353 }''';
303 354
304 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment. 355 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment.
305 /// 356 ///
306 /// However, at specific moments they need to contribute their data. 357 /// However, at specific moments they need to contribute their data.
307 /// For example, once the holders have been created, they are included into 358 /// For example, once the holders have been created, they are included into
308 /// the main holders. 359 /// the main holders.
309 const String deferredBoilerplate = ''' 360 const String deferredBoilerplate = '''
310 function(inherit, mixin, lazy, makeConstList, installTearOff, 361 function(inherit, mixin, lazy, makeConstList, convertToFastObject,
311 updateHolder, updateTypes, 362 installTearOff, setFunctionNamesIfNecessary, updateHolder, updateTypes,
312 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags, 363 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags,
313 #embeddedGlobalsObject, holdersList, #staticState) { 364 #embeddedGlobalsObject, holdersList, #staticState) {
314 365
315 // Builds the holders. They only contain the data for new holders. 366 // Builds the holders. They only contain the data for new holders.
316 #holders; 367 #holders;
368
369 // If the name is not set on the functions, do it now.
370 setFunctionNamesIfNecessary(#deferredHoldersList);
371
317 // Updates the holders of the main-fragment. Uses the provided holdersList to 372 // Updates the holders of the main-fragment. Uses the provided holdersList to
318 // access the main holders. 373 // access the main holders.
319 // The local holders are replaced by the combined holders. This is necessary 374 // The local holders are replaced by the combined holders. This is necessary
320 // for the inheritance setup below. 375 // for the inheritance setup below.
321 #updateHolders; 376 #updateHolders;
322 // Sets the prototypes of the new classes. 377 // Sets the prototypes of the new classes.
323 #prototypes; 378 #prototypes;
324 // Sets aliases of methods (on the prototypes of classes). 379 // Sets aliases of methods (on the prototypes of classes).
325 #aliases; 380 #aliases;
326 // Installs the tear-offs of functions. 381 // Installs the tear-offs of functions.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 424
370 js.Expression classReference(Class cls) { 425 js.Expression classReference(Class cls) {
371 return js.js('#.#', [cls.holder.name, cls.name]); 426 return js.js('#.#', [cls.holder.name, cls.name]);
372 } 427 }
373 428
374 js.Statement emitMainFragment( 429 js.Statement emitMainFragment(
375 Program program, 430 Program program,
376 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) { 431 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) {
377 MainFragment fragment = program.fragments.first; 432 MainFragment fragment = program.fragments.first;
378 433
434 Iterable<Holder> nonStaticStateHolders = program.holders
435 .where((Holder holder) => !holder.isStaticStateHolder);
436
379 return js.js.statement(mainBoilerplate, 437 return js.js.statement(mainBoilerplate,
380 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), 438 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
381 'typeNameProperty': js.string(ModelEmitter.typeNameProperty), 439 'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
382 'cyclicThrow': backend.emitter.staticFunctionAccess( 440 'cyclicThrow': backend.emitter.staticFunctionAccess(
383 backend.getCyclicThrowHelper()), 441 backend.getCyclicThrowHelper()),
384 'operatorIsPrefix': js.string(namer.operatorIsPrefix), 442 'operatorIsPrefix': js.string(namer.operatorIsPrefix),
385 'tearOffCode': new js.Block(buildTearOffCode(backend)), 443 'tearOffCode': new js.Block(buildTearOffCode(backend)),
386 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES), 444 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES),
387 'embeddedInterceptorTags': 445 'embeddedInterceptorTags':
388 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG), 446 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG),
389 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS), 447 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS),
390 'embeddedGlobalsObject': js.js("init"), 448 'embeddedGlobalsObject': js.js("init"),
391 'holdersList': new js.ArrayInitializer(program.holders.map((holder) { 449 'holdersList': new js.ArrayInitializer(nonStaticStateHolders
392 return js.js("#", holder.name); 450 .map((holder) => js.js("#", holder.name))
393 }).toList()), 451 .toList(growable: false)),
394 'staticStateDeclaration': new js.VariableDeclaration( 452 'staticStateDeclaration': new js.VariableDeclaration(
395 namer.staticStateHolder, allowRename: false), 453 namer.staticStateHolder, allowRename: false),
396 'staticState': js.js('#', namer.staticStateHolder), 454 'staticState': js.js('#', namer.staticStateHolder),
397 'constantHolderReference': buildConstantHolderReference(program), 455 'constantHolderReference': buildConstantHolderReference(program),
398 'holders': emitHolders(program.holders, fragment), 456 'holders': emitHolders(program.holders, fragment),
399 'callName': js.string(namer.callNameField), 457 'callName': js.string(namer.callNameField),
400 'argumentCount': js.string(namer.requiredParameterField), 458 'argumentCount': js.string(namer.requiredParameterField),
401 'defaultArgumentValues': js.string(namer.defaultValuesField), 459 'defaultArgumentValues': js.string(namer.defaultValuesField),
402 'prototypes': emitPrototypes(fragment), 460 'prototypes': emitPrototypes(fragment),
403 'inheritance': emitInheritance(fragment), 461 'inheritance': emitInheritance(fragment),
404 'aliases': emitInstanceMethodAliases(fragment), 462 'aliases': emitInstanceMethodAliases(fragment),
405 'tearOffs': emitInstallTearOffs(fragment), 463 'tearOffs': emitInstallTearOffs(fragment),
406 'constants': emitConstants(fragment), 464 'constants': emitConstants(fragment),
407 'staticNonFinalFields': emitStaticNonFinalFields(fragment), 465 'staticNonFinalFields': emitStaticNonFinalFields(fragment),
408 'lazyStatics': emitLazilyInitializedStatics(fragment), 466 'lazyStatics': emitLazilyInitializedStatics(fragment),
409 'embeddedGlobals': emitEmbeddedGlobals(program, deferredLoadHashes), 467 'embeddedGlobals': emitEmbeddedGlobals(program, deferredLoadHashes),
410 'nativeSupport': program.needsNativeSupport 468 'nativeSupport': program.needsNativeSupport
411 ? emitNativeSupport(fragment) 469 ? emitNativeSupport(fragment)
412 : new js.EmptyStatement(), 470 : new js.EmptyStatement(),
413 'invokeMain': fragment.invokeMain, 471 'invokeMain': fragment.invokeMain,
414 }); 472 });
415 } 473 }
416 474
417 js.Expression emitDeferredFragment(DeferredFragment fragment, 475 js.Expression emitDeferredFragment(DeferredFragment fragment,
418 js.Expression deferredTypes, 476 js.Expression deferredTypes,
419 List<Holder> holders) { 477 List<Holder> holders) {
478 List<Holder> nonStaticStateHolders = holders
479 .where((Holder holder) => !holder.isStaticStateHolder)
480 .toList(growable: false);
481
420 List<js.Statement> updateHolderAssignments = <js.Statement>[]; 482 List<js.Statement> updateHolderAssignments = <js.Statement>[];
421 for (int i = 0; i < holders.length; i++) { 483 for (int i = 0; i < nonStaticStateHolders.length; i++) {
422 Holder holder = holders[i]; 484 Holder holder = nonStaticStateHolders[i];
423 if (holder.isStaticStateHolder) continue;
424 updateHolderAssignments.add(js.js.statement( 485 updateHolderAssignments.add(js.js.statement(
425 '#holder = updateHolder(holdersList[#index], #holder)', 486 '#holder = updateHolder(holdersList[#index], #holder)',
426 {'index': js.number(i), 487 {'index': js.number(i),
427 'holder': new js.VariableUse(holder.name)})); 488 'holder': new js.VariableUse(holder.name)}));
428 } 489 }
429 490
430 // TODO(floitsch): if name is not set, run through all functions and set the
431 // name for IE.
432 // TODO(floitsch): don't just reference 'init'. 491 // TODO(floitsch): don't just reference 'init'.
433 return js.js(deferredBoilerplate, 492 return js.js(deferredBoilerplate,
434 {'embeddedGlobalsObject': new js.Parameter('init'), 493 {'embeddedGlobalsObject': new js.Parameter('init'),
435 'staticState': new js.Parameter(namer.staticStateHolder), 494 'staticState': new js.Parameter(namer.staticStateHolder),
436 'holders': emitHolders(holders, fragment), 495 'holders': emitHolders(holders, fragment),
496 'deferredHoldersList': new js.ArrayInitializer(nonStaticStateHolders
497 .map((holder) => js.js("#", holder.name))
498 .toList(growable: false)),
437 'updateHolders': new js.Block(updateHolderAssignments), 499 'updateHolders': new js.Block(updateHolderAssignments),
438 'prototypes': emitPrototypes(fragment), 500 'prototypes': emitPrototypes(fragment),
439 'inheritance': emitInheritance(fragment), 501 'inheritance': emitInheritance(fragment),
440 'aliases': emitInstanceMethodAliases(fragment), 502 'aliases': emitInstanceMethodAliases(fragment),
441 'tearOffs': emitInstallTearOffs(fragment), 503 'tearOffs': emitInstallTearOffs(fragment),
442 'constants': emitConstants(fragment), 504 'constants': emitConstants(fragment),
443 'staticNonFinalFields': emitStaticNonFinalFields(fragment), 505 'staticNonFinalFields': emitStaticNonFinalFields(fragment),
444 'lazyStatics': emitLazilyInitializedStatics(fragment), 506 'lazyStatics': emitLazilyInitializedStatics(fragment),
445 'types': deferredTypes, 507 'types': deferredTypes,
446 // TODO(floitsch): only call emitNativeSupport if we need native. 508 // TODO(floitsch): only call emitNativeSupport if we need native.
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 /// 1236 ///
1175 /// We don't try to reduce the size of the native data, but rather build 1237 /// We don't try to reduce the size of the native data, but rather build
1176 /// JavaScript object literals that contain all the information directly. 1238 /// JavaScript object literals that contain all the information directly.
1177 /// This means that the output size is bigger, but that the startup is faster. 1239 /// This means that the output size is bigger, but that the startup is faster.
1178 /// 1240 ///
1179 /// This function is the static equivalent of 1241 /// This function is the static equivalent of
1180 /// [NativeGenerator.buildNativeInfoHandler]. 1242 /// [NativeGenerator.buildNativeInfoHandler].
1181 js.Statement emitNativeSupport(Fragment fragment) { 1243 js.Statement emitNativeSupport(Fragment fragment) {
1182 List<js.Statement> statements = <js.Statement>[]; 1244 List<js.Statement> statements = <js.Statement>[];
1183 1245
1184 if (NativeGenerator.needsIsolateAffinityTagInitialization(backend)) { 1246 // The isolate-affinity tag must only be initialized once per program.
1247 if (fragment.isMainFragment &&
1248 NativeGenerator.needsIsolateAffinityTagInitialization(backend)) {
1185 statements.add(NativeGenerator.generateIsolateAffinityTagInitialization( 1249 statements.add(NativeGenerator.generateIsolateAffinityTagInitialization(
1186 backend, 1250 backend,
1187 generateEmbeddedGlobalAccess, 1251 generateEmbeddedGlobalAccess,
1188 // TODO(floitsch): convertToFastObject. (Needed for "interning" of 1252 js.js("""
1189 // strings). 1253 // On V8, the 'intern' function converts a string to a symbol, which
Siggi Cherem (dart-lang) 2015/08/04 01:54:54 any reason why not define this as a function with
floitsch 2015/08/04 11:54:53 The copy is from a different emitter. We could cre
1190 js.js("(function(x) { return x; })", []))); 1254 // makes property access much faster.
1255 function (s) {
1256 var o = {};
1257 o[s] = 1;
1258 return Object.keys(convertToFastObject(o))[0];
1259 }""", [])));
1191 } 1260 }
1192 1261
1193 Map<String, js.Expression> interceptorsByTag = <String, js.Expression>{}; 1262 Map<String, js.Expression> interceptorsByTag = <String, js.Expression>{};
1194 Map<String, js.Expression> leafTags = <String, js.Expression>{}; 1263 Map<String, js.Expression> leafTags = <String, js.Expression>{};
1195 js.Statement subclassAssignment = new js.EmptyStatement(); 1264 js.Statement subclassAssignment = new js.EmptyStatement();
1196 1265
1197 for (Library library in fragment.libraries) { 1266 for (Library library in fragment.libraries) {
1198 for (Class cls in library.classes) { 1267 for (Class cls in library.classes) {
1199 if (cls.nativeLeafTags != null) { 1268 if (cls.nativeLeafTags != null) {
1200 for (String tag in cls.nativeLeafTags) { 1269 for (String tag in cls.nativeLeafTags) {
(...skipping 22 matching lines...) Expand all
1223 } 1292 }
1224 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", 1293 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);",
1225 js.objectLiteral(interceptorsByTag))); 1294 js.objectLiteral(interceptorsByTag)));
1226 statements.add(js.js.statement("setOrUpdateLeafTags(#);", 1295 statements.add(js.js.statement("setOrUpdateLeafTags(#);",
1227 js.objectLiteral(leafTags))); 1296 js.objectLiteral(leafTags)));
1228 statements.add(subclassAssignment); 1297 statements.add(subclassAssignment);
1229 1298
1230 return new js.Block(statements); 1299 return new js.Block(statements);
1231 } 1300 }
1232 } 1301 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/native_generator.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698