Chromium Code Reviews| Index: pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart |
| diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart |
| index befd7a9eecab363baf9fb7d562ace1830f108a0e..d5fef22b3d533fdadac96a71eee72e3b0067ca35 100644 |
| --- a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart |
| +++ b/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart |
| @@ -53,17 +53,49 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| jsAst.Expression metadataAccess = |
| emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA); |
| + |
| jsAst.Statement processClassData = js.statement('''{ |
| + function markerFun() {} |
| + function finishAddStubsHelper(prototype) { |
| + var prototype = prototype || this; |
| + var object; |
| + while (prototype.#deferredAction != markerFun) { |
| + if (prototype.hasOwnProperty(#deferredActionString)) { |
| + delete prototype.#deferredAction; // Intended to make it slow, too. |
| + var properties = Object.keys(prototype); |
| + for (var index = 0; index < properties.length; index++) { |
| + var property = properties[index]; |
| + var firstChar = property.charCodeAt(0); |
| + var elem; |
| + if (property !== "${namer.classDescriptorProperty}" && |
| + property !== "$reflectableField" && |
| + firstChar !== 43 && // 43 is aka "+". |
|
floitsch
2015/03/06 14:54:09
Please add comment what this is for. The "+" and "
herhut
2015/03/09 14:28:35
Done.
|
| + firstChar !== 42 && // 42 is aka "*" |
| + (elem = prototype[property]) != null && |
| + elem.constructor === Array && |
| + property !== "<>") { |
| + addStubs(prototype, elem, property, false, null); |
| + } |
| + } |
| + convertToFastObject(prototype); |
| + } |
| + prototype = prototype.__proto__; |
| + } |
| + } |
| + |
| function processClassData(cls, descriptor, processedClasses) { |
| descriptor = convertToSlowObject(descriptor); // Use a slow object. |
| var previousProperty; |
| var properties = Object.keys(descriptor); |
| + var hasDeferredWork = false; |
| + var deferWork = supportsDirectProtoAccess && cls != #objectClassName; |
| for (var i = 0; i < properties.length; i++) { |
| var property = properties[i]; |
| var firstChar = property.charCodeAt(0); |
| if (property === "static") { |
| processStatics(#embeddedStatics[cls] = descriptor.static, |
| processedClasses); |
| + delete descriptor.static; |
|
floitsch
2015/03/06 14:54:09
we don't need it for reflection?
herhut
2015/03/09 14:28:35
No, statics are collected separately in an array t
|
| } else if (firstChar === 43) { // 43 is aka "+". |
| mangledNames[previousProperty] = property.substring(1); |
| var flag = descriptor[property]; |
| @@ -82,12 +114,19 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| elem != null && |
| elem.constructor === Array && |
| property !== "<>") { |
| - addStubs(descriptor, elem, property, false, []); |
| + if (deferWork) { |
| + hasDeferredWork = true; |
| + } else { |
| + addStubs(descriptor, elem, property, false, null); |
| + } |
| } else { |
| previousProperty = property; |
| } |
| } |
| } |
| + |
| + if (hasDeferredWork) |
| + descriptor.#deferredAction = finishAddStubsHelper; |
| /* The 'fields' are either a constructor function or a |
| * string encoding fields, constructor and superclass. Gets the |
| @@ -128,10 +167,14 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| processedClasses.collected[cls] = [globalObject, descriptor]; |
| classes.push(cls); |
| } |
| -}''', {'embeddedStatics': staticsAccess, |
| +}''', {'deferredAction': namer.deferredAction, |
| + 'deferredActionString': js.string(namer.deferredAction), |
| + 'embeddedStatics': staticsAccess, |
| 'hasRetainedMetadata': backend.hasRetainedMetadata, |
| 'metadata': metadataAccess, |
| - 'notInCspMode': !compiler.useContentSecurityPolicy}); |
| + 'notInCspMode': !compiler.useContentSecurityPolicy, |
| + 'objectClassName': |
| + js.string(namer.getNameOfClass(compiler.objectClass))}); |
| // TODO(zarah): Remove empty else branches in output when if(#hole) is false. |
| jsAst.Statement processStatics = js.statement(''' |
| @@ -195,7 +238,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| } |
| var funcs = [descriptor[name] = descriptor[alias] = f]; |
| f.\$stubName = name; |
| - functions.push(name); |
| + if (isStatic) functions.push(name); |
| for (; index < array.length; index += 2) { |
| f = array[index + 1]; |
| if (typeof f != "function") break; |
| @@ -203,7 +246,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| funcs.push(f); |
| if (f.\$stubName) { |
| descriptor[f.\$stubName] = f; |
| - functions.push(f.\$stubName); |
| + if (isStatic) functions.push(f.\$stubName); |
| } |
| } |
| index++; |
| @@ -230,10 +273,12 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter, |
| descriptor[name].\$getter = f; |
| f.\$getterStub = true; |
| // Used to create an isolate using spawnFunction. |
| - if (isStatic) #globalFunctions[name] = f; |
| + if (isStatic) { |
| + #globalFunctions[name] = f; |
| + functions.push(getterStubName); |
| + } |
| descriptor[getterStubName] = f; |
| funcs.push(f); |
| - if (getterStubName) functions.push(getterStubName); |
| f.\$stubName = getterStubName; |
| f.\$callName = null; |
| // Update the interceptedNames map (which only exists if `invokeOn` was |