| 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 |