OLD | NEW |
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 /// | 48 /// |
49 /// The emitter doesn't try to be clever and emits everything beforehand. This | 49 /// The emitter doesn't try to be clever and emits everything beforehand. This |
50 /// increases the output size, but improves performance. | 50 /// increases the output size, but improves performance. |
51 /// | 51 /// |
52 // The code relies on the fact that all Dart code is inside holders. As such | 52 // The code relies on the fact that all Dart code is inside holders. As such |
53 // we can use "global" names however we want. As long as we don't shadow | 53 // we can use "global" names however we want. As long as we don't shadow |
54 // JavaScript variables (like `Array`) we are free to chose whatever variable | 54 // JavaScript variables (like `Array`) we are free to chose whatever variable |
55 // names we want. Furthermore, the pretty-printer minifies local variables, thus | 55 // names we want. Furthermore, the pretty-printer minifies local variables, thus |
56 // reducing their size. | 56 // reducing their size. |
57 const String mainBoilerplate = ''' | 57 const String mainBoilerplate = ''' |
58 { | |
59 // Declare deferred-initializer global, which is used to keep track of the | |
60 // loaded fragments. | |
61 #deferredInitializer; | |
62 | |
63 (function() { | 58 (function() { |
64 // Copies the own properties from [from] to [to]. | 59 // Copies the own properties from [from] to [to]. |
65 function copyProperties(from, to) { | 60 function copyProperties(from, to) { |
66 var keys = Object.keys(from); | 61 var keys = Object.keys(from); |
67 for (var i = 0; i < keys.length; i++) { | 62 for (var i = 0; i < keys.length; i++) { |
68 to[keys[i]] = from[keys[i]]; | 63 to[keys[i]] = from[keys[i]]; |
69 } | 64 } |
70 } | 65 } |
71 | 66 |
72 var supportsDirectProtoAccess = (function () { | 67 var supportsDirectProtoAccess = (function () { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 343 |
349 // Emits the embedded globals. | 344 // Emits the embedded globals. |
350 #embeddedGlobals; | 345 #embeddedGlobals; |
351 | 346 |
352 // Sets up the native support. | 347 // Sets up the native support. |
353 // Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags. | 348 // Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags. |
354 #nativeSupport; | 349 #nativeSupport; |
355 | 350 |
356 // Invokes main (making sure that it records the 'current-script' value). | 351 // Invokes main (making sure that it records the 'current-script' value). |
357 #invokeMain; | 352 #invokeMain; |
358 })(); | 353 })() |
359 }'''; | 354 '''; |
360 | 355 |
361 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment. | 356 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment. |
362 /// | 357 /// |
363 /// However, at specific moments they need to contribute their data. | 358 /// However, at specific moments they need to contribute their data. |
364 /// For example, once the holders have been created, they are included into | 359 /// For example, once the holders have been created, they are included into |
365 /// the main holders. | 360 /// the main holders. |
366 const String deferredBoilerplate = ''' | 361 const String deferredBoilerplate = ''' |
367 function(inherit, mixin, lazy, makeConstList, convertToFastObject, | 362 function(inherit, mixin, lazy, makeConstList, convertToFastObject, |
368 installTearOff, setFunctionNamesIfNecessary, updateHolder, updateTypes, | 363 installTearOff, setFunctionNamesIfNecessary, updateHolder, updateTypes, |
369 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags, | 364 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 429 |
435 js.Statement emitMainFragment( | 430 js.Statement emitMainFragment( |
436 Program program, | 431 Program program, |
437 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) { | 432 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) { |
438 MainFragment fragment = program.fragments.first; | 433 MainFragment fragment = program.fragments.first; |
439 | 434 |
440 Iterable<Holder> nonStaticStateHolders = program.holders | 435 Iterable<Holder> nonStaticStateHolders = program.holders |
441 .where((Holder holder) => !holder.isStaticStateHolder); | 436 .where((Holder holder) => !holder.isStaticStateHolder); |
442 | 437 |
443 return js.js.statement(mainBoilerplate, | 438 return js.js.statement(mainBoilerplate, |
444 {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap), | 439 {'typeNameProperty': js.string(ModelEmitter.typeNameProperty), |
445 'typeNameProperty': js.string(ModelEmitter.typeNameProperty), | |
446 'cyclicThrow': backend.emitter.staticFunctionAccess( | 440 'cyclicThrow': backend.emitter.staticFunctionAccess( |
447 backend.helpers.cyclicThrowHelper), | 441 backend.helpers.cyclicThrowHelper), |
448 'operatorIsPrefix': js.string(namer.operatorIsPrefix), | 442 'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
449 'tearOffCode': new js.Block(buildTearOffCode(backend)), | 443 'tearOffCode': new js.Block(buildTearOffCode(backend)), |
450 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES), | 444 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES), |
451 'embeddedInterceptorTags': | 445 'embeddedInterceptorTags': |
452 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG), | 446 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG), |
453 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS), | 447 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS), |
454 'embeddedGlobalsObject': js.js("init"), | 448 'embeddedGlobalsObject': js.js("init"), |
455 'holdersList': new js.ArrayInitializer(nonStaticStateHolders | 449 'holdersList': new js.ArrayInitializer(nonStaticStateHolders |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 'tearOffs': emitInstallTearOffs(fragment), | 503 'tearOffs': emitInstallTearOffs(fragment), |
510 'constants': emitConstants(fragment), | 504 'constants': emitConstants(fragment), |
511 'staticNonFinalFields': emitStaticNonFinalFields(fragment), | 505 'staticNonFinalFields': emitStaticNonFinalFields(fragment), |
512 'lazyStatics': emitLazilyInitializedStatics(fragment), | 506 'lazyStatics': emitLazilyInitializedStatics(fragment), |
513 'types': deferredTypes, | 507 'types': deferredTypes, |
514 // TODO(floitsch): only call emitNativeSupport if we need native. | 508 // TODO(floitsch): only call emitNativeSupport if we need native. |
515 'nativeSupport': emitNativeSupport(fragment), | 509 'nativeSupport': emitNativeSupport(fragment), |
516 }); | 510 }); |
517 } | 511 } |
518 | 512 |
519 js.Statement emitDeferredInitializerGlobal(Map loadMap) { | |
520 if (loadMap.isEmpty) return new js.Block.empty(); | |
521 | |
522 String global = ModelEmitter.deferredInitializersGlobal; | |
523 return js.js.statement( | |
524 "if (typeof($global) === 'undefined') var # = Object.create(null);", | |
525 new js.VariableDeclaration(global, allowRename: false)); | |
526 } | |
527 | |
528 /// Emits all holders, except for the static-state holder. | 513 /// Emits all holders, except for the static-state holder. |
529 /// | 514 /// |
530 /// The emitted holders contain classes (only the constructors) and all | 515 /// The emitted holders contain classes (only the constructors) and all |
531 /// static functions. | 516 /// static functions. |
532 js.Statement emitHolders(List<Holder> holders, Fragment fragment) { | 517 js.Statement emitHolders(List<Holder> holders, Fragment fragment) { |
533 // Skip the static-state holder in this function. | 518 // Skip the static-state holder in this function. |
534 holders = holders | 519 holders = holders |
535 .where((Holder holder) => !holder.isStaticStateHolder) | 520 .where((Holder holder) => !holder.isStaticStateHolder) |
536 .toList(growable: false); | 521 .toList(growable: false); |
537 | 522 |
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 } | 1298 } |
1314 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1299 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
1315 js.objectLiteral(interceptorsByTag))); | 1300 js.objectLiteral(interceptorsByTag))); |
1316 statements.add(js.js.statement("setOrUpdateLeafTags(#);", | 1301 statements.add(js.js.statement("setOrUpdateLeafTags(#);", |
1317 js.objectLiteral(leafTags))); | 1302 js.objectLiteral(leafTags))); |
1318 statements.add(subclassAssignment); | 1303 statements.add(subclassAssignment); |
1319 | 1304 |
1320 return new js.Block(statements); | 1305 return new js.Block(statements); |
1321 } | 1306 } |
1322 } | 1307 } |
OLD | NEW |