Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1528)

Unified Diff: sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart

Issue 238633007: Redo "Add more MiniJsParser functionality." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
index ffe3b52d87108ebe009699203fdc2cbd207f9520..59eb43e75935f982ffe07faf74b0524f93303dec 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -15,8 +15,15 @@ const DEFAULT_ARGUMENTS_INDEX = 5;
const bool VALIDATE_DATA = false;
// TODO(ahe): This code should be integrated in CodeEmitterTask.finishClasses.
-String getReflectionDataParser(String classesCollector,
- JavaScriptBackend backend) {
+jsAst.Expression getReflectionDataParser(String classesCollector,
+ JavaScriptBackend backend) {
+ var text = getReflectionDataParserAsString(classesCollector, backend);
+ return js(text);
+}
+
+
+String getReflectionDataParserAsString(String classesCollector,
+ JavaScriptBackend backend) {
Namer namer = backend.namer;
Compiler compiler = backend.compiler;
Element closureFromTearOff = compiler.findHelper('closureFromTearOff');
@@ -30,7 +37,7 @@ String getReflectionDataParser(String classesCollector,
} else {
// Default values for mocked-up test libraries.
tearOffAccess =
- 'function() { throw "Helper \'closureFromTearOff\' missing." }';
+ r'''function() { throw 'Helper \'closureFromTearOff\' missing.' }''';
tearOffGlobalObjectName = 'MissingHelperFunction';
tearOffGlobalObject = '($tearOffAccess())';
}
@@ -47,31 +54,107 @@ String getReflectionDataParser(String classesCollector,
String methodsWithOptionalArgumentsField =
namer.methodsWithOptionalArgumentsField;
+ String unmangledNameIndex = backend.mustRetainMetadata
+ ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
+ : ' 2 * optionalParameterCount + requiredParameterCount + 3';
+
+
String header = '''
(function (reflectionData) {
"use strict";
-'''
+
// [map] returns an object literal that V8 shouldn't try to optimize with a
// hidden class. This prevents a potential performance problem where V8 tries
// to build a hidden class for an object used as a hashMap.
-'''
+
function map(x){x={x:x};delete x.x;return x}
''';
- String unmangledNameIndex = backend.mustRetainMetadata
- ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
- : ' 2 * optionalParameterCount + requiredParameterCount + 3';
+ String processStatics = '''
+ function processStatics(descriptor) {
+ for (var property in descriptor) {
+ if (!hasOwnProperty.call(descriptor, property)) continue;
+ if (property === "${namer.classDescriptorProperty}") continue;
+ var element = descriptor[property];
+ var firstChar = property.substring(0, 1);
+ var previousProperty;
+ if (firstChar === "+") {
+ mangledGlobalNames[previousProperty] = property.substring(1);
+ var flag = descriptor[property];
+ if (flag > 0)
+ descriptor[previousProperty].$reflectableField = flag;
+ if (element && element.length)
+ init.typeInformation[previousProperty] = element;
+ } else if (firstChar === "@") {
+ property = property.substring(1);
+ ${namer.currentIsolate}[property][$metadataField] = element;
+ } else if (firstChar === "*") {
+ globalObject[previousProperty].$defaultValuesField = element;
+ var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
+ if (!optionalMethods) {
+ descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
+ }
+ optionalMethods[property] = previousProperty;
+ } else if (typeof element === "function") {
+ globalObject[previousProperty = property] = element;
+ functions.push(property);
+ init.globalFunctions[property] = element;
+ } else if (element.constructor === Array) {
+ addStubs(globalObject, element, property,
+ true, descriptor, functions);
+ } else {
+ 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(init.statics[property] = element[prop]);
+ } 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);
+ }
+ }
+ }
+''';
+
/**
* See [dart2js.js_emitter.ContainerBuilder.addMemberMethod] for format of
* [array].
*/
String addStubs = '''
- function addStubs(descriptor, array, name, isStatic,''' // Break long line.
- ''' originalDescriptor, functions) {
- var f, funcs =''' // Break long line.
- ''' [originalDescriptor[name] =''' // Break long line.
- ''' descriptor[name] = f = ${readFunction("array", "$FUNCTION_INDEX")}];
+ function addStubs(descriptor, array, name, isStatic,
+ originalDescriptor, functions) {
+ var f, funcs =
+ [originalDescriptor[name] =
+ descriptor[name] = f = ${readFunction("array", "$FUNCTION_INDEX")}];
f.\$stubName = name;
functions.push(name);
for (var index = $FUNCTION_INDEX; index < array.length; index += 2) {
@@ -97,8 +180,8 @@ String getReflectionDataParser(String classesCollector,
var optionalParameterInfo = ${readInt("array", "1")};
var optionalParameterCount = optionalParameterInfo >> 1;
var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
- var isIntercepted =''' // Break long line.
- ''' requiredParameterCount + optionalParameterCount != funcs[0].length;
+ var isIntercepted =
+ requiredParameterCount + optionalParameterCount != funcs[0].length;
var functionTypeIndex = ${readFunctionType("array", "2")};
var unmangledNameIndex = $unmangledNameIndex;
var isReflectable = array.length > unmangledNameIndex;
@@ -107,9 +190,7 @@ String getReflectionDataParser(String classesCollector,
f = tearOff(funcs, array, isStatic, name, isIntercepted);
descriptor[name].\$getter = f;
f.\$getterStub = true;
-'''
- /* Used to create an isolate using spawnFunction.*/
-'''
+ // Used to create an isolate using spawnFunction.
if (isStatic) init.globalFunctions[name] = f;
originalDescriptor[getterStubName] = descriptor[getterStubName] = f;
funcs.push(f);
@@ -125,18 +206,16 @@ String getReflectionDataParser(String classesCollector,
}
var mangledNames = isStatic ? init.mangledGlobalNames : init.mangledNames;
var unmangledName = ${readString("array", "unmangledNameIndex")};
-'''
// The function is either a getter, a setter, or a method.
// If it is a method, it might also have a tear-off closure.
// The unmangledName is the same as the getter-name.
-'''
var reflectionName = unmangledName;
if (getterStubName) mangledNames[getterStubName] = reflectionName;
if (isSetter) {
reflectionName += "=";
} else if (!isGetter) {
- reflectionName += ":" + requiredParameterCount +''' // Break long line.
- ''' ":" + optionalParameterCount;
+ reflectionName += ":" + requiredParameterCount +
+ ":" + optionalParameterCount;
}
mangledNames[name] = reflectionName;
funcs[0].$reflectionNameField = reflectionName;
@@ -149,41 +228,41 @@ String getReflectionDataParser(String classesCollector,
String tearOff = '''
function tearOffGetterNoCsp(funcs, reflectionInfo, name, isIntercepted) {
return isIntercepted
- ? new Function("funcs", "reflectionInfo", "name",''' // Break long line.
- ''' "$tearOffGlobalObjectName", "c",
+ ? new Function("funcs", "reflectionInfo", "name",
+ "$tearOffGlobalObjectName", "c",
"return function tearOff_" + name + (functionCounter++)+ "(x) {" +
"if (c === null) c = $tearOffAccess(" +
"this, funcs, reflectionInfo, false, [x], name);" +
"return new c(this, funcs[0], x, name);" +
"}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null)
- : new Function("funcs", "reflectionInfo", "name",''' // Break long line.
- ''' "$tearOffGlobalObjectName", "c",
+ : new Function("funcs", "reflectionInfo", "name",
+ "$tearOffGlobalObjectName", "c",
"return function tearOff_" + name + (functionCounter++)+ "() {" +
"if (c === null) c = $tearOffAccess(" +
"this, funcs, reflectionInfo, false, [], name);" +
"return new c(this, funcs[0], null, name);" +
- "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null)
+ "}")(funcs, reflectionInfo, name, $tearOffGlobalObject, null);
}
function tearOffGetterCsp(funcs, reflectionInfo, name, isIntercepted) {
var cache = null;
return isIntercepted
? function(x) {
- if (cache === null) cache = $tearOffAccess(''' // Break long line.
- '''this, funcs, reflectionInfo, false, [x], name);
- return new cache(this, funcs[0], x, name)
+ if (cache === null) cache = $tearOffAccess(
+ this, funcs, reflectionInfo, false, [x], name);
+ return new cache(this, funcs[0], x, name);
}
: function() {
- if (cache === null) cache = $tearOffAccess(''' // Break long line.
- '''this, funcs, reflectionInfo, false, [], name);
- return new cache(this, funcs[0], null, name)
- }
+ if (cache === null) cache = $tearOffAccess(
+ this, funcs, reflectionInfo, false, [], name);
+ return new cache(this, funcs[0], null, name);
+ };
}
function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) {
var cache;
return isStatic
? function() {
- if (cache === void 0) cache = $tearOffAccess(''' // Break long line.
- '''this, funcs, reflectionInfo, true, [], name).prototype;
+ if (cache === void 0) cache = $tearOffAccess(
+ this, funcs, reflectionInfo, true, [], name).prototype;
return cache;
}
: tearOffGetter(funcs, reflectionInfo, name, isIntercepted);
@@ -211,7 +290,7 @@ String getReflectionDataParser(String classesCollector,
var length = reflectionData.length;
for (var i = 0; i < length; i++) {
var data = reflectionData[i];
-'''
+
// [data] contains these elements:
// 0. The library name (not unique).
// 1. The library URI (unique).
@@ -222,7 +301,7 @@ String getReflectionDataParser(String classesCollector,
// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
//
// The entries of [data] are built in [assembleProgram] above.
-'''
+
var name = data[0];
var uri = data[1];
var metadata = data[2];
@@ -234,80 +313,6 @@ String getReflectionDataParser(String classesCollector,
var functions = [];
''';
- String processStatics = '''
- function processStatics(descriptor) {
- for (var property in descriptor) {
- if (!hasOwnProperty.call(descriptor, property)) continue;
- if (property === "${namer.classDescriptorProperty}") continue;
- var element = descriptor[property];
- var firstChar = property.substring(0, 1);
- var previousProperty;
- if (firstChar === "+") {
- mangledGlobalNames[previousProperty] = property.substring(1);
- var flag = descriptor[property];
- if (flag > 0) ''' // Break long line.
- '''descriptor[previousProperty].$reflectableField = flag;
- if (element && element.length) ''' // Break long line.
- '''init.typeInformation[previousProperty] = element;
- } else if (firstChar === "@") {
- property = property.substring(1);
- ${namer.currentIsolate}[property][$metadataField] = element;
- } else if (firstChar === "*") {
- globalObject[previousProperty].$defaultValuesField = element;
- var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
- if (!optionalMethods) {
- descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
- }
- optionalMethods[property] = previousProperty;
- } else if (typeof element === "function") {
- globalObject[previousProperty = property] = element;
- functions.push(property);
- init.globalFunctions[property] = element;
- } else if (element.constructor === Array) {
- addStubs(globalObject, element, property, ''' // Break long line.
- '''true, descriptor, functions);
- } else {
- 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(init.statics[property] = element[prop]);
- } else if (firstChar === "+") {
- mangledNames[previousProp] = prop.substring(1);
- var flag = element[prop];
- if (flag > 0) ''' // Break long line.
- '''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 &&''' // Break long line.
- ''' elem.constructor === Array &&''' // Break long line.
- ''' prop !== "<>") {
- addStubs(newDesc, elem, prop, false, element, []);
- } else {
- newDesc[previousProp = prop] = elem;
- }
- }
- }
- $classesCollector[property] = [globalObject, newDesc];
- classes.push(property);
- }
- }
- }
-''';
-
String footer = '''
processStatics(descriptor);
libraries.push([name, uri, classes, functions, metadata, fields, isRoot,

Powered by Google App Engine
This is Rietveld 408576698