| Index: pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| index 1b7beca01128d80d4827b02b3bfdcfc47b111e52..69e3deaa21a3b486efac3a8551506f72e54028b8 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
|
| @@ -64,13 +64,9 @@ function copyProperties(from, to) {
|
| }
|
| }
|
|
|
| -var supportsDirectProtoAccess = (function () {
|
| - var cls = function () {};
|
| - cls.prototype = {'p': {}};
|
| - var object = new cls();
|
| - return object.__proto__ &&
|
| - object.__proto__.p === cls.prototype.p;
|
| -})();
|
| +// Only use direct proto access to construct the prototype chain (instead of
|
| +// copying properties) on platforms where we know it works well (Chrome / d8).
|
| +var supportsDirectProtoAccess = #directAccessTestExpression;
|
|
|
| var functionsHaveName = (function() {
|
| function t() {};
|
| @@ -354,6 +350,36 @@ var #staticStateDeclaration = {};
|
| })()
|
| ''';
|
|
|
| +/// An expression that returns `true` if `__proto__` can be assigned to stitch
|
| +/// together a prototype chain, and the performance is good.
|
| +const String directAccessTestExpression = r'''
|
| + (function () {
|
| + var cls = function () {};
|
| + cls.prototype = {'p': {}};
|
| + var object = new cls();
|
| + if (!(object.__proto__ && object.__proto__.p === cls.prototype.p))
|
| + return false;
|
| +
|
| + try {
|
| + // Are we running on a platform where the performance is good?
|
| + // (i.e. Chrome or d8).
|
| +
|
| + // Chrome userAgent?
|
| + if (typeof navigator != "undefined" &&
|
| + typeof navigator.userAgent == "string" &&
|
| + navigator.userAgent.indexOf("Chrome/") >= 0) return true;
|
| + // d8 version() looks like "N.N.N.N", jsshell version() like "N".
|
| + if (typeof version == "function" &&
|
| + version.length == 0) {
|
| + var v = version();
|
| + if (/^\d+\.\d+\.\d+\.\d+$/.test(v)) return true;
|
| + }
|
| + } catch(_) {}
|
| +
|
| + return false;
|
| + })()
|
| +''';
|
| +
|
| /// Deferred fragments (aka 'hunks') are built similarly to the main fragment.
|
| ///
|
| /// However, at specific moments they need to contribute their data.
|
| @@ -436,6 +462,7 @@ class FragmentEmitter {
|
| program.holders.where((Holder holder) => !holder.isStaticStateHolder);
|
|
|
| return js.js.statement(mainBoilerplate, {
|
| + 'directAccessTestExpression': js.js(directAccessTestExpression),
|
| 'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
|
| 'cyclicThrow': backend.emitter
|
| .staticFunctionAccess(backend.helpers.cyclicThrowHelper),
|
|
|