Chromium Code Reviews| Index: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| index d97440f5e98ef3855c7ff0295751fa50722725b7..0c67dcc38c4061c8d04e980a5c88874aeda58913 100644 |
| --- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| +++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| @@ -335,6 +335,9 @@ class OldEmitter implements Emitter { |
| str += parameter; |
| body += ("this." + field + " = " + parameter + ";\n"); |
| } |
| + if (supportsDirectProtoAccess) |
| + body += "if (this." + #deferredAction + ") this." + #deferredAction |
| + + "();"; |
| str += ") {\n" + body + "}\n"; |
| str += name + ".builtin$cls=\"" + name + "\";\n"; |
| str += "$desc=$collectedClasses." + name + "[1];\n"; |
| @@ -349,7 +352,8 @@ class OldEmitter implements Emitter { |
| str += accessors.join(""); |
| return str; |
| - }''', { 'hasIsolateSupport': hasIsolateSupport, |
| + }''', { 'deferredAction': js.string(namer.deferredAction), |
| + 'hasIsolateSupport': hasIsolateSupport, |
| 'fieldNamesProperty': js.string(fieldNamesProperty)}); |
| // Declare a function called "generateAccessor". This is used in |
| @@ -423,13 +427,7 @@ class OldEmitter implements Emitter { |
| // If the browser supports changing the prototype via __proto__, we make |
| // use of that feature. Otherwise, we copy the properties into a new |
| // constructor. |
| - (function () { |
| - var cls = function () {}; |
| - cls.prototype = {'p': {}}; |
| - var object = new cls(); |
| - return object.__proto__ && |
| - object.__proto__.p === cls.prototype.p; |
| - })() ? |
| + supportsDirectProtoAccess ? |
| function(constructor, superConstructor) { |
| var prototype = constructor.prototype; |
| prototype.__proto__ = superConstructor.prototype; |
| @@ -529,6 +527,9 @@ class OldEmitter implements Emitter { |
| var prototype = constructor.prototype; |
| prototype.constructor = constructor; |
| prototype.#isObject = constructor; |
| + // Ensure that all stubs have been generated. |
| + if (constructor.prototype.#deferredAction) |
| + constructor.prototype.#deferredAction(); |
| return; |
| } |
| finishClass(superclass); |
| @@ -541,13 +542,28 @@ class OldEmitter implements Emitter { |
| var prototype = inheritFrom(constructor, superConstructor); |
| if (#hasNativeClasses) |
| - if (Object.prototype.hasOwnProperty.call(prototype, $specProperty)) |
| - #nativeInfoHandler |
| + if (Object.prototype.hasOwnProperty.call(prototype, $specProperty)) { |
| + #nativeInfoHandler; |
| + // As native classes can come into existence without a constructor |
| + // call, we have to ensure that the class has been fully |
| + // initialized. |
| + if (constructor.prototype.#deferredAction) |
| + constructor.prototype.#deferredAction(); |
| + } |
| + // Interceptors (or rather their prototypes) are also used without |
| + // first instantiating them first. |
|
floitsch
2015/03/06 14:54:09
delete first "first".
|
| + if (superclass === #interceptorClassName && |
| + constructor.prototype.#deferredAction) { |
| + constructor.prototype.#deferredAction(); |
| + } |
| } |
| - }''', {'finishedClassesAccess': finishedClassesAccess, |
| + }''', {'deferredAction': namer.deferredAction, |
| + 'finishedClassesAccess': finishedClassesAccess, |
| 'needsMixinSupport': needsMixinSupport, |
| 'hasNativeClasses': hasNativeClasses, |
| 'nativeInfoHandler': nativeInfoHandler, |
| + 'interceptorClassName': |
| + js.string(namer.getNameOfClass(backend.jsInterceptorClass)), |
| 'isObject' : namer.operatorIs(compiler.objectClass) }); |
| } |
| @@ -1141,6 +1157,21 @@ class OldEmitter implements Emitter { |
| output.add(N); |
| } |
| + void emitSupportsDirectProtoAccess(CodeOutput output) { |
| + jsAst.Statement supportsDirectProtoAccess = js.statement(r''' |
| + var supportsDirectProtoAccess = (function () { |
| + var cls = function () {}; |
| + cls.prototype = {'p': {}}; |
| + var object = new cls(); |
| + return object.__proto__ && |
| + object.__proto__.p === cls.prototype.p; |
| + })(); |
| + '''); |
| + |
| + output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); |
| + output.add(N); |
| + } |
| + |
| void writeLibraryDescriptors(CodeOutput output, LibraryElement library) { |
| var uri = ""; |
| if (!compiler.enableMinification || backend.mustPreserveUris) { |
| @@ -1370,6 +1401,7 @@ class OldEmitter implements Emitter { |
| // Using a named function here produces easier to read stack traces in |
| // Chrome/V8. |
| mainOutput.add('(function(${namer.currentIsolate})$_{\n'); |
| + emitSupportsDirectProtoAccess(mainOutput); |
| if (compiler.hasIncrementalSupport) { |
| mainOutput.addBuffer(jsAst.prettyPrint(js.statement( |
| """ |