Chromium Code Reviews| Index: dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| diff --git a/dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| index 80a6e7402377046c8c993bf782297cc4238b25b6..20ff4c46a673534b5c1823e4389d00d7de78d444 100644 |
| --- a/dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| +++ b/dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart |
| @@ -1452,8 +1452,12 @@ class OldEmitter implements Emitter { |
| 'this.\$dart_unsafe_eval.patch = function(a) { eval(a) }$N'); |
| String schemaChange = |
| jsAst.prettyPrint(buildSchemaChangeFunction(), compiler).getText(); |
| + String addMethod = |
| + jsAst.prettyPrint(buildIncrementalAddMethod(), compiler).getText(); |
| mainBuffer.add( |
| 'this.\$dart_unsafe_eval.schemaChange$_=$_$schemaChange$N'); |
| + mainBuffer.add( |
| + 'this.\$dart_unsafe_eval.addMethod$_=$_$addMethod$N'); |
| } |
| if (isProgramSplit) { |
| /// We collect all the global state of the, so it can be passed to the |
| @@ -1682,6 +1686,57 @@ function(newConstructor, oldConstructor, superclass) { |
| }'''); |
| } |
| + /// Used by incremental compilation to patch up an object ([holder]) with a |
| + /// new (or updated) method. [arrayOrFunction] is either the new method, or |
| + /// an array containing the method (see |
| + /// [ContainerBuilder.addMemberMethodFromInfo]). [name] is the name of the |
| + /// new method. [isStatic] tells if method is static (or |
| + /// top-level). [globalFunctionsAccess] is a reference to |
| + /// [embeddedNames.GLOBAL_FUNCTIONS]. |
| + jsAst.Fun buildIncrementalAddMethod() { |
| + return js(r''' |
| +function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) { |
| + var arrayOrFunction = originalDescriptor[name]; |
| + var method; |
| + if (arrayOrFunction.constructor === Array) { |
| + var existing = holder[name]; |
| + var array = arrayOrFunction; |
|
Johnni Winther
2014/12/01 13:40:21
`array` is never used.
ahe
2014/12/01 14:03:38
Will do in follow up.
|
| + var descriptor = Object.create(null); |
| + this.addStubs( |
| + descriptor, arrayOrFunction, name, isStatic, originalDescriptor, []); |
| + method = descriptor[name]; |
| + for (var property in descriptor) { |
| + if (!Object.prototype.hasOwnProperty.call(descriptor, property)) continue; |
| + var stub = descriptor[property]; |
| + var existingStub = holder[property]; |
| + if (stub === method || !existingStub) { |
| + // Not replacing an existing stub. |
| + holder[property] = method; |
| + continue; |
| + } |
| + if (!stub.$getterStub) { |
| + var error = new Error("Unexpected stub."); |
| + error.stub = stub; |
| + throw error; |
| + } |
| + // Invoke the existing stub to obtain the tear-off closure. |
| + existingStub = existingStub(); |
| + // A stub already exist. Update all its references to [existing] to |
| + // [method]. |
| + for (var reference in existingStub) { |
| + if (existingStub[reference] === existing) { |
| + existingStub[reference] = method; |
| + } |
| + } |
| + } |
| + } else { |
| + method = arrayOrFunction; |
| + holder[name] = method; |
| + } |
| + if (isStatic) globalFunctionsAccess[name] = method; |
| +}'''); |
| + } |
| + |
| /// Returns a map from OutputUnit to a hash of its content. The hash uniquely |
| /// identifies the code of the output-unit. It does not include |
| /// boilerplate JS code, like the sourcemap directives or the hash |