| 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 89404d6882f75d2b816108ca675212a1fa3ef1c0..c9d20172b85a655466848c40fac4efa65b3edab2 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
|
| @@ -14,8 +14,9 @@ const DEFAULT_ARGUMENTS_INDEX = 5;
|
|
|
| const bool VALIDATE_DATA = false;
|
|
|
| -jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| - JavaScriptBackend backend) {
|
| +// TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses.
|
| +jsAst.Expression getReflectionDataParser(String classesCollector,
|
| + JavaScriptBackend backend) {
|
| Namer namer = backend.namer;
|
| Compiler compiler = backend.compiler;
|
| CodeEmitterTask emitter = backend.emitter;
|
| @@ -47,8 +48,6 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
|
| jsAst.Expression librariesAccess =
|
| emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
|
| - jsAst.Expression metadataAccess =
|
| - emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA);
|
|
|
| jsAst.Statement header = js.statement('''
|
| // [map] returns an object literal that V8 shouldn not try to optimize with a
|
| @@ -59,89 +58,8 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| function map(x){x=Object.create(null);x.x=0;delete x.x;return x}
|
| ''');
|
|
|
| - jsAst.Statement processClassData = js.statement('''{
|
| - function processClassData(cls, descriptor, processedClasses) {
|
| - var newDesc = {};
|
| - var previousProperty;
|
| - for (var property in descriptor) {
|
| - if (!hasOwnProperty.call(descriptor, property)) continue;
|
| - var firstChar = property.substring(0, 1);
|
| - if (property === "static") {
|
| - processStatics(#embeddedStatics[cls] = descriptor[property],
|
| - processedClasses);
|
| - } else if (firstChar === "+") {
|
| - mangledNames[previousProperty] = property.substring(1);
|
| - var flag = descriptor[property];
|
| - if (flag > 0)
|
| - descriptor[previousProperty].$reflectableField = flag;
|
| - } else if (firstChar === "@" && property !== "@") {
|
| - newDesc[property.substring(1)][$metadataField] = descriptor[property];
|
| - } else if (firstChar === "*") {
|
| - newDesc[previousProperty].$defaultValuesField = descriptor[property];
|
| - var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
|
| - if (!optionalMethods) {
|
| - newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
|
| - }
|
| - optionalMethods[property] = previousProperty;
|
| - } else {
|
| - var elem = descriptor[property];
|
| - if (property !== "${namer.classDescriptorProperty}" &&
|
| - elem != null &&
|
| - elem.constructor === Array &&
|
| - property !== "<>") {
|
| - addStubs(newDesc, elem, property, false, descriptor, []);
|
| - } else {
|
| - newDesc[previousProperty = property] = elem;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /* The 'fields' are either a constructor function or a
|
| - * string encoding fields, constructor and superclass. Gets the
|
| - * superclass and fields in the format
|
| - * 'Super;field1,field2'
|
| - * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
|
| - */
|
| - var classData = newDesc["${namer.classDescriptorProperty}"],
|
| - split, supr, fields = classData;
|
| -
|
| - if (#hasRetainedMetadata)
|
| - if (typeof classData == "object" &&
|
| - classData instanceof Array) {
|
| - classData = fields = classData[0];
|
| - }
|
| - // ${ClassBuilder.fieldEncodingDescription}.
|
| - var s = fields.split(";");
|
| - fields = s[1] == "" ? [] : s[1].split(",");
|
| - supr = s[0];
|
| - // ${ClassBuilder.functionTypeEncodingDescription}.
|
| - split = supr.split(":");
|
| - if (split.length == 2) {
|
| - supr = split[0];
|
| - var functionSignature = split[1];
|
| - if (functionSignature)
|
| - newDesc.${namer.operatorSignature} = function(s) {
|
| - return function() {
|
| - return #metadata[s];
|
| - };
|
| - }(functionSignature);
|
| - }
|
| -
|
| - if (supr) processedClasses.pending[cls] = supr;
|
| - if (#notInCspMode) {
|
| - processedClasses.combinedConstructorFunction += defineClass(cls, fields);
|
| - processedClasses.constructorsList.push(cls);
|
| - }
|
| - processedClasses.collected[cls] = [globalObject, newDesc];
|
| - classes.push(cls);
|
| - }
|
| -}''', {'embeddedStatics': staticsAccess,
|
| - 'hasRetainedMetadata': backend.hasRetainedMetadata,
|
| - 'metadata': metadataAccess,
|
| - 'notInCspMode': !compiler.useContentSecurityPolicy});
|
| -
|
| jsAst.Statement processStatics = js.statement('''
|
| - function processStatics(descriptor, processedClasses) {
|
| + function processStatics(descriptor) {
|
| for (var property in descriptor) {
|
| if (!hasOwnProperty.call(descriptor, property)) continue;
|
| if (property === "${namer.classDescriptorProperty}") continue;
|
| @@ -154,7 +72,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| if (flag > 0)
|
| descriptor[previousProperty].$reflectableField = flag;
|
| if (element && element.length)
|
| - #typeInformation[previousProperty] = element;
|
| + #[previousProperty] = element; // embedded typeInformation.
|
| } else if (firstChar === "@") {
|
| property = property.substring(1);
|
| ${namer.currentIsolate}[property][$metadataField] = element;
|
| @@ -168,22 +86,51 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| } else if (typeof element === "function") {
|
| globalObject[previousProperty = property] = element;
|
| functions.push(property);
|
| - #globalFunctions[property] = element;
|
| + #[property] = element; // embedded globalFunctions.
|
| } else if (element.constructor === Array) {
|
| addStubs(globalObject, element, property,
|
| true, descriptor, functions);
|
| } else {
|
| - // We will not enter this case if no classes are defined.
|
| - if (#hasClasses) {
|
| - previousProperty = property;
|
| - processClassData(property, element, processedClasses);
|
| + previousProperty = property;
|
| + var newDesc = {};
|
| + var previousProp;
|
| + for (var prop in element) {
|
| + if (!hasOwnProperty.call(element, prop)) continue;
|
| + firstChar = prop.substring(0, 1);
|
| + if (prop === "static") {
|
| + processStatics(#[property] = element[prop]); // embedded statics.
|
| + } else if (firstChar === "+") {
|
| + mangledNames[previousProp] = prop.substring(1);
|
| + var flag = element[prop];
|
| + if (flag > 0)
|
| + element[previousProp].$reflectableField = flag;
|
| + } else if (firstChar === "@" && prop !== "@") {
|
| + newDesc[prop.substring(1)][$metadataField] = element[prop];
|
| + } else if (firstChar === "*") {
|
| + newDesc[previousProp].$defaultValuesField = element[prop];
|
| + var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
|
| + if (!optionalMethods) {
|
| + newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
|
| + }
|
| + optionalMethods[prop] = previousProp;
|
| + } else {
|
| + var elem = element[prop];
|
| + if (prop !== "${namer.classDescriptorProperty}" &&
|
| + elem != null &&
|
| + elem.constructor === Array &&
|
| + prop !== "<>") {
|
| + addStubs(newDesc, elem, prop, false, element, []);
|
| + } else {
|
| + newDesc[previousProp = prop] = elem;
|
| + }
|
| + }
|
| }
|
| + $classesCollector[property] = [globalObject, newDesc];
|
| + classes.push(property);
|
| }
|
| }
|
| }
|
| -''', {'typeInformation': typeInformationAccess,
|
| - 'globalFunctions': globalFunctionsAccess,
|
| - 'hasClasses': oldEmitter.needsClassSupport});
|
| +''', [typeInformationAccess, globalFunctionsAccess, staticsAccess]);
|
|
|
|
|
| /**
|
| @@ -279,29 +226,18 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
|
|
| jsAst.Statement init = js.statement('''{
|
| var functionCounter = 0;
|
| - if (!#libraries) #libraries = [];
|
| - if (!#mangledNames) #mangledNames = map();
|
| - if (!#mangledGlobalNames) #mangledGlobalNames = map();
|
| - if (!#statics) #statics = map();
|
| - if (!#typeInformation) #typeInformation = map();
|
| - if (!#globalFunctions) #globalFunctions = map();
|
| - if (!#interceptedNames) #interceptedNames = map();
|
| - var libraries = #libraries;
|
| - var mangledNames = #mangledNames;
|
| - var mangledGlobalNames = #mangledGlobalNames;
|
| + if (!#) # = []; // embedded libraries.
|
| + if (!#) # = map(); // embedded mangledNames.
|
| + if (!#) # = map(); // embedded mangledGlobalNames.
|
| + if (!#) # = map(); // embedded statics.
|
| + if (!#) # = map(); // embedded typeInformation.
|
| + if (!#) # = map(); // embedded globalFunctions.
|
| + if (!#) # = map(); // embedded interceptedNames.
|
| + var libraries = #; // embeded libraries.
|
| + var mangledNames = #; // embedded mangledNames.
|
| + var mangledGlobalNames = #; // embedded mangledGlobalNames.
|
| var hasOwnProperty = Object.prototype.hasOwnProperty;
|
| var length = reflectionData.length;
|
| - var processedClasses = Object.create(null);
|
| - processedClasses.collected = Object.create(null);
|
| - processedClasses.pending = Object.create(null);
|
| - if (#notInCspMode) {
|
| - processedClasses.constructorsList = [];
|
| - // For every class processed [processedClasses.combinedConstructorFunction]
|
| - // will be updated with the corresponding constructor function.
|
| - processedClasses.combinedConstructorFunction =
|
| - "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+
|
| - "var \$desc;\\n";
|
| - }
|
| for (var i = 0; i < length; i++) {
|
| var data = reflectionData[i];
|
|
|
| @@ -326,90 +262,20 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| if (fields instanceof Array) fields = fields[0];
|
| var classes = [];
|
| var functions = [];
|
| - processStatics(descriptor, processedClasses);
|
| + processStatics(descriptor);
|
| libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
|
| globalObject]);
|
| }
|
| - if (#needsClassSupport) finishClasses(processedClasses);
|
| -}''', {'libraries': librariesAccess,
|
| - 'mangledNames': mangledNamesAccess,
|
| - 'mangledGlobalNames': mangledGlobalNamesAccess,
|
| - 'statics': staticsAccess,
|
| - 'typeInformation': typeInformationAccess,
|
| - 'globalFunctions': globalFunctionsAccess,
|
| - 'interceptedNames': interceptedNamesAccess,
|
| - 'notInCspMode': !compiler.useContentSecurityPolicy,
|
| - 'needsClassSupport': oldEmitter.needsClassSupport});
|
| -
|
| - jsAst.Expression allClassesAccess =
|
| - emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
|
| -
|
| - String specProperty = '"${namer.nativeSpecProperty}"'; // "%"
|
| -
|
| - // Class descriptions are collected in a JS object.
|
| - // 'finishClasses' takes all collected descriptions and sets up
|
| - // the prototype.
|
| - // Once set up, the constructors prototype field satisfy:
|
| - // - it contains all (local) members.
|
| - // - its internal prototype (__proto__) points to the superclass'
|
| - // prototype field.
|
| - // - the prototype's constructor field points to the JavaScript
|
| - // constructor.
|
| - // For engines where we have access to the '__proto__' we can manipulate
|
| - // the object literal directly. For other engines we have to create a new
|
| - // object and copy over the members.
|
| - jsAst.Statement finishClasses = js.statement('''{
|
| - function finishClasses(processedClasses) {
|
| - if (#debugFastObjects)
|
| - print("Number of classes: " +
|
| - Object.getOwnPropertyNames(processedClasses.collected).length);
|
| -
|
| - var allClasses = #allClasses;
|
| -
|
| - if (#inCspMode) {
|
| - constructors = dart_precompiled(processedClasses.collected);
|
| - }
|
| -
|
| - if (#notInCspMode) {
|
| - processedClasses.combinedConstructorFunction +=
|
| - "return [\\n" + processedClasses.constructorsList.join(",\\n ") +
|
| - "\\n]";
|
| - var constructors =
|
| - new Function("\$collectedClasses",
|
| - processedClasses.combinedConstructorFunction)
|
| - (processedClasses.collected);
|
| - processedClasses.combinedConstructorFunction = null;
|
| - }
|
| -
|
| - for (var i = 0; i < constructors.length; i++) {
|
| - var constructor = constructors[i];
|
| - var cls = constructor.name;
|
| - var desc = processedClasses.collected[cls];
|
| - var globalObject = \$;
|
| - if (desc instanceof Array) {
|
| - globalObject = desc[0] || \$;
|
| - desc = desc[1];
|
| - }
|
| - if (#isTreeShakingDisabled)
|
| - constructor["${namer.metadataField}"] = desc;
|
| - allClasses[cls] = constructor;
|
| - globalObject[cls] = constructor;
|
| - }
|
| - constructors = null;
|
| -
|
| - #finishClassFunction;
|
| -
|
| - #trivialNsmHandlers;
|
| -
|
| - for (var cls in processedClasses.pending) finishClass(cls);
|
| - }
|
| -}''', {'allClasses': allClassesAccess,
|
| - 'debugFastObjects': DEBUG_FAST_OBJECTS,
|
| - 'isTreeShakingDisabled': backend.isTreeShakingDisabled,
|
| - 'finishClassFunction': oldEmitter.buildFinishClass(),
|
| - 'trivialNsmHandlers': oldEmitter.buildTrivialNsmHandlers(),
|
| - 'inCspMode': compiler.useContentSecurityPolicy,
|
| - 'notInCspMode': !compiler.useContentSecurityPolicy});
|
| +}''', [librariesAccess, librariesAccess,
|
| + mangledNamesAccess, mangledNamesAccess,
|
| + mangledGlobalNamesAccess, mangledGlobalNamesAccess,
|
| + staticsAccess, staticsAccess,
|
| + typeInformationAccess, typeInformationAccess,
|
| + globalFunctionsAccess, globalFunctionsAccess,
|
| + interceptedNamesAccess, interceptedNamesAccess,
|
| + librariesAccess,
|
| + mangledNamesAccess,
|
| + mangledGlobalNamesAccess]);
|
|
|
| List<jsAst.Statement> incrementalSupport = <jsAst.Statement>[];
|
| if (compiler.hasIncrementalSupport) {
|
| @@ -422,12 +288,6 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| (function (reflectionData) {
|
| "use strict";
|
| #header;
|
| - if (#needsClassSupport) {
|
| - #defineClass;
|
| - #inheritFrom;
|
| - #finishClasses;
|
| - #processClassData;
|
| - }
|
| #processStatics;
|
| #addStubs;
|
| #tearOffCode;
|
| @@ -435,16 +295,11 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
|
| #init;
|
| })''', {
|
| 'header': header,
|
| - 'defineClass': oldEmitter.defineClassFunction,
|
| - 'inheritFrom': oldEmitter.buildInheritFrom(),
|
| - 'processClassData': processClassData,
|
| 'processStatics': processStatics,
|
| 'incrementalSupport': incrementalSupport,
|
| 'addStubs': addStubs,
|
| 'tearOffCode': tearOffCode,
|
| - 'init': init,
|
| - 'finishClasses': finishClasses,
|
| - 'needsClassSupport': oldEmitter.needsClassSupport});
|
| + 'init': init});
|
| }
|
|
|
|
|
|
|