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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 const String mainBoilerplate = ''' | 57 const String mainBoilerplate = ''' |
58 (function() { | 58 (function() { |
59 // Copies the own properties from [from] to [to]. | 59 // Copies the own properties from [from] to [to]. |
60 function copyProperties(from, to) { | 60 function copyProperties(from, to) { |
61 var keys = Object.keys(from); | 61 var keys = Object.keys(from); |
62 for (var i = 0; i < keys.length; i++) { | 62 for (var i = 0; i < keys.length; i++) { |
63 to[keys[i]] = from[keys[i]]; | 63 to[keys[i]] = from[keys[i]]; |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 var supportsDirectProtoAccess = (function () { | 67 // Only use direct proto access to construct the prototype chain (instead of |
68 var cls = function () {}; | 68 // copying properties) on platforms where we know it works well (Chrome / d8). |
69 cls.prototype = {'p': {}}; | 69 var supportsDirectProtoAccess = #directAccessTestExpression; |
70 var object = new cls(); | |
71 return object.__proto__ && | |
72 object.__proto__.p === cls.prototype.p; | |
73 })(); | |
74 | 70 |
75 var functionsHaveName = (function() { | 71 var functionsHaveName = (function() { |
76 function t() {}; | 72 function t() {}; |
77 return (typeof t.name == 'string') | 73 return (typeof t.name == 'string') |
78 })(); | 74 })(); |
79 | 75 |
80 var isChrome = (typeof window != 'undefined') && | 76 var isChrome = (typeof window != 'undefined') && |
81 (typeof window.chrome != 'undefined'); | 77 (typeof window.chrome != 'undefined'); |
82 | 78 |
83 // Sets the name property of functions, if the JS engine doesn't set the name | 79 // Sets the name property of functions, if the JS engine doesn't set the name |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 343 |
348 // Sets up the native support. | 344 // Sets up the native support. |
349 // Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags. | 345 // Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags. |
350 #nativeSupport; | 346 #nativeSupport; |
351 | 347 |
352 // Invokes main (making sure that it records the 'current-script' value). | 348 // Invokes main (making sure that it records the 'current-script' value). |
353 #invokeMain; | 349 #invokeMain; |
354 })() | 350 })() |
355 '''; | 351 '''; |
356 | 352 |
| 353 /// An expression that returns `true` if `__proto__` can be assigned to stitch |
| 354 /// together a prototype chain, and the performance is good. |
| 355 const String directAccessTestExpression = r''' |
| 356 (function () { |
| 357 var cls = function () {}; |
| 358 cls.prototype = {'p': {}}; |
| 359 var object = new cls(); |
| 360 if (!(object.__proto__ && object.__proto__.p === cls.prototype.p)) |
| 361 return false; |
| 362 |
| 363 try { |
| 364 // Are we running on a platform where the performance is good? |
| 365 // (i.e. Chrome or d8). |
| 366 |
| 367 // Chrome userAgent? |
| 368 if (typeof navigator != "undefined" && |
| 369 typeof navigator.userAgent == "string" && |
| 370 navigator.userAgent.indexOf("Chrome/") >= 0) return true; |
| 371 // d8 version() looks like "N.N.N.N", jsshell version() like "N". |
| 372 if (typeof version == "function" && |
| 373 version.length == 0) { |
| 374 var v = version(); |
| 375 if (/^\d+\.\d+\.\d+\.\d+$/.test(v)) return true; |
| 376 } |
| 377 } catch(_) {} |
| 378 |
| 379 return false; |
| 380 })() |
| 381 '''; |
| 382 |
357 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment. | 383 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment. |
358 /// | 384 /// |
359 /// However, at specific moments they need to contribute their data. | 385 /// However, at specific moments they need to contribute their data. |
360 /// For example, once the holders have been created, they are included into | 386 /// For example, once the holders have been created, they are included into |
361 /// the main holders. | 387 /// the main holders. |
362 const String deferredBoilerplate = ''' | 388 const String deferredBoilerplate = ''' |
363 function(inherit, mixin, lazy, makeConstList, convertToFastObject, | 389 function(inherit, mixin, lazy, makeConstList, convertToFastObject, |
364 installTearOff, setFunctionNamesIfNecessary, updateHolder, updateTypes, | 390 installTearOff, setFunctionNamesIfNecessary, updateHolder, updateTypes, |
365 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags, | 391 setOrUpdateInterceptorsByTag, setOrUpdateLeafTags, |
366 #embeddedGlobalsObject, holdersList, #staticState) { | 392 #embeddedGlobalsObject, holdersList, #staticState) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 } | 455 } |
430 | 456 |
431 js.Statement emitMainFragment(Program program, | 457 js.Statement emitMainFragment(Program program, |
432 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) { | 458 Map<DeferredFragment, _DeferredFragmentHash> deferredLoadHashes) { |
433 MainFragment fragment = program.fragments.first; | 459 MainFragment fragment = program.fragments.first; |
434 | 460 |
435 Iterable<Holder> nonStaticStateHolders = | 461 Iterable<Holder> nonStaticStateHolders = |
436 program.holders.where((Holder holder) => !holder.isStaticStateHolder); | 462 program.holders.where((Holder holder) => !holder.isStaticStateHolder); |
437 | 463 |
438 return js.js.statement(mainBoilerplate, { | 464 return js.js.statement(mainBoilerplate, { |
| 465 'directAccessTestExpression': js.js(directAccessTestExpression), |
439 'typeNameProperty': js.string(ModelEmitter.typeNameProperty), | 466 'typeNameProperty': js.string(ModelEmitter.typeNameProperty), |
440 'cyclicThrow': backend.emitter | 467 'cyclicThrow': backend.emitter |
441 .staticFunctionAccess(backend.helpers.cyclicThrowHelper), | 468 .staticFunctionAccess(backend.helpers.cyclicThrowHelper), |
442 'operatorIsPrefix': js.string(namer.operatorIsPrefix), | 469 'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
443 'tearOffCode': new js.Block(buildTearOffCode(backend)), | 470 'tearOffCode': new js.Block(buildTearOffCode(backend)), |
444 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES), | 471 'embeddedTypes': generateEmbeddedGlobalAccess(TYPES), |
445 'embeddedInterceptorTags': | 472 'embeddedInterceptorTags': |
446 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG), | 473 generateEmbeddedGlobalAccess(INTERCEPTORS_BY_TAG), |
447 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS), | 474 'embeddedLeafTags': generateEmbeddedGlobalAccess(LEAF_TAGS), |
448 'embeddedGlobalsObject': js.js("init"), | 475 'embeddedGlobalsObject': js.js("init"), |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1314 } | 1341 } |
1315 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1342 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
1316 js.objectLiteral(interceptorsByTag))); | 1343 js.objectLiteral(interceptorsByTag))); |
1317 statements.add( | 1344 statements.add( |
1318 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); | 1345 js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags))); |
1319 statements.add(subclassAssignment); | 1346 statements.add(subclassAssignment); |
1320 | 1347 |
1321 return new js.Block(statements); | 1348 return new js.Block(statements); |
1322 } | 1349 } |
1323 } | 1350 } |
OLD | NEW |