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

Unified Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 742873002: Isolates: allow sending of arbitrary objects in dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Support CSP mode. Created 6 years 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: 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 b429495122bb9b9332d8a176daa666445ecd3cbb..7f5bc4a0d6e014f6f34a9f94ab6d13ef9749ca8e 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -74,9 +74,8 @@ class OldEmitter implements Emitter {
* precompiled function.
*
* To save space, dart2js normally generates constructors and accessors
- * dynamically. This doesn't work in CSP mode, and may impact startup time
- * negatively. So dart2js will emit these functions to a separate file that
- * can be optionally included to support CSP mode or for faster startup.
+ * dynamically. This doesn't work in CSP mode, so dart2js emits them directly
+ * when in CSP mode.
*/
Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions =
new Map<OutputUnit, List<jsAst.Node>>();
@@ -166,6 +165,11 @@ class OldEmitter implements Emitter {
String get makeConstListProperty
=> namer.getMappedInstanceName('makeConstantList');
+ /// The name of the property that contains all field names.
+ ///
+ /// This property is added to constructors when isolate support is enabled.
+ static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__";
+
/// For deferred loading we communicate the initializers via this global var.
final String deferredInitializers = r"$dart_deferred_initializers";
@@ -182,7 +186,7 @@ class OldEmitter implements Emitter {
}
jsAst.Expression isolateLazyInitializerAccess(Element element) {
- return jsAst.js('#.#', [namer.globalObjectFor(element),
+ return jsAst.js('#.#', [namer.globalObjectFor(element),
namer.getLazyInitializerName(element)]);
}
@@ -190,7 +194,7 @@ class OldEmitter implements Emitter {
return jsAst.js('#.#()',
[namer.globalObjectFor(element), namer.getStaticClosureName(element)]);
}
-
+
jsAst.PropertyAccess globalPropertyAccess(Element element) {
String name = namer.getNameX(element);
jsAst.PropertyAccess pa = new jsAst.PropertyAccess.field(
@@ -198,19 +202,19 @@ class OldEmitter implements Emitter {
name);
return pa;
}
-
+
jsAst.PropertyAccess staticFieldAccess(Element element) {
return globalPropertyAccess(element);
}
-
+
jsAst.PropertyAccess staticFunctionAccess(Element element) {
return globalPropertyAccess(element);
}
-
+
jsAst.PropertyAccess classAccess(Element element) {
return globalPropertyAccess(element);
}
-
+
jsAst.PropertyAccess typedefAccess(Element element) {
return globalPropertyAccess(element);
}
@@ -288,7 +292,7 @@ class OldEmitter implements Emitter {
}''');
}
- List get defineClassFunction {
+ List<jsAst.Node> get defineClassFunction {
// First the class name, then the field names in an array and the members
// (inside an Object literal).
// The caller can also pass in the constructor as a function if needed.
@@ -303,45 +307,99 @@ class OldEmitter implements Emitter {
// },
// });
- var defineClass = js('''function(name, fields) {
- var accessors = [];
-
- var str = "function " + name + "(";
- var body = "";
+ bool hasIsolateSupport = compiler.hasIsolateSupport;
+ String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
- for (var i = 0; i < fields.length; i++) {
- if(i != 0) str += ", ";
-
- var field = generateAccessor(fields[i], accessors, name);
- var parameter = "parameter_" + field;
- str += parameter;
- body += ("this." + field + " = " + parameter + ";\\n");
- }
- str += ") {\\n" + body + "}\\n";
- str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
- str += "\$desc=\$collectedClasses." + name + ";\\n";
- str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n";
- str += name + ".prototype = \$desc;\\n";
- if (typeof defineClass.name != "string") {
- str += name + ".name=\\"" + name + "\\";\\n";
- }
- str += accessors.join("");
+ jsAst.Expression defineClass = js('''
+ function(name, fields) {
+ var accessors = [];
+
+ var str = "function " + name + "(";
+ var body = "";
+ if (#hasIsolateSupport) { var fieldNames = ""; }
+
+ for (var i = 0; i < fields.length; i++) {
+ if(i != 0) str += ", ";
+
+ var field = generateAccessor(fields[i], accessors, name);
+ if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
+ var parameter = "parameter_" + field;
+ str += parameter;
+ body += ("this." + field + " = " + parameter + ";\\n");
+ }
+ str += ") {\\n" + body + "}\\n";
+ str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
+ str += "\$desc=\$collectedClasses." + name + ";\\n";
+ str += "if(\$desc instanceof Array) \$desc = \$desc[1];\\n";
+ str += name + ".prototype = \$desc;\\n";
+ if (typeof defineClass.name != "string") {
+ str += name + ".name=\\"" + name + "\\";\\n";
+ }
+ if (#hasIsolateSupport) {
+ str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n";
+ }
+ str += accessors.join("");
+
+ return str;
+ }''', { 'hasIsolateSupport': hasIsolateSupport });
- return str;
- }''');
// Declare a function called "generateAccessor". This is used in
// defineClassFunction (it's a local declaration in init()).
- List<jsAst.Node> saveDefineClass = [];
- if (compiler.hasIncrementalSupport) {
- saveDefineClass.add(
- js(r'self.$dart_unsafe_eval.defineClass = defineClass'));
- }
- return [
+ List result = <jsAst.Node>[
generateAccessorFunction,
js('$generateAccessorHolder = generateAccessor'),
new jsAst.FunctionDeclaration(
- new jsAst.VariableDeclaration('defineClass'), defineClass) ]
- ..addAll(saveDefineClass);
+ new jsAst.VariableDeclaration('defineClass'), defineClass) ];
+
+ if (compiler.hasIncrementalSupport) {
+ result.add(
+ js(r'self.$dart_unsafe_eval.defineClass = defineClass'));
+ }
+
+ if (hasIsolateSupport) {
+ jsAst.Expression classIdExtractorAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR);
+ var classIdExtractorAssignment =
+ js('# = function(o) { return o.constructor.name; }',
+ classIdExtractorAccess);
+
+ jsAst.Expression classFieldsExtractorAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR);
+ var classFieldsExtractorAssignment = js('''
+ # = function(o) {
+ var fieldNames = o.constructor.$fieldNamesProperty;
+ if (!fieldNames) return []; // TODO(floitsch): do something else here.
+ var result = [];
+ result.length = fieldNames.length;
+ for (var i = 0; i < fieldNames.length; i++) {
+ result[i] = o[fieldNames[i]];
+ }
+ return result;
+ }''', classFieldsExtractorAccess);
+
+ jsAst.Expression instanceFromClassIdAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID);
+ jsAst.Expression allClassesAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
+ var instanceFromClassIdAssignment =
+ js('# = function(name) { return new #[name](); }',
+ [instanceFromClassIdAccess, allClassesAccess]);
+
+ jsAst.Expression initializeEmptyInstanceAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE);
+ var initializeEmptyInstanceAssignment = js('''
+ # = function(name, o, fields) {
+ #[name].apply(o, fields);
+ return o;
+ }''', [ initializeEmptyInstanceAccess, allClassesAccess ]);
+
+ result.addAll([classIdExtractorAssignment,
+ classFieldsExtractorAssignment,
+ instanceFromClassIdAssignment,
+ initializeEmptyInstanceAssignment]);
+ }
+
+ return result;
}
/** Needs defineClass to be defined. */
@@ -1310,25 +1368,34 @@ class OldEmitter implements Emitter {
void emitPrecompiledConstructor(OutputUnit outputUnit,
String constructorName,
- jsAst.Expression constructorAst) {
+ jsAst.Expression constructorAst,
+ List<String> fields) {
cspPrecompiledFunctionFor(outputUnit).add(
new jsAst.FunctionDeclaration(
new jsAst.VariableDeclaration(constructorName), constructorAst));
- cspPrecompiledFunctionFor(outputUnit).add(
- js.statement(r'''{
- #.builtin$cls = #;
- if (!"name" in #)
- #.name = #;
- $desc=$collectedClasses.#;
+
+ String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
+ bool hasIsolateSupport = compiler.hasIsolateSupport;
+ jsAst.Node fieldNamesArray =
+ hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
+
+ cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
+ {
+ #constructorName.builtin$cls = #constructorNameString;
+ if (!"name" in #constructorName)
+ #constructorName.name = #constructorNameString;
+ $desc = $collectedClasses.#constructorName;
if ($desc instanceof Array) $desc = $desc[1];
- #.prototype = $desc;
+ #constructorName.prototype = $desc;
+ ''' /* next string is not a raw string */ '''
+ if (#hasIsolateSupport) {
+ #constructorName.$fieldNamesProperty = #fieldNamesArray;
+ }
}''',
- [ constructorName, js.string(constructorName),
- constructorName,
- constructorName, js.string(constructorName),
- constructorName,
- constructorName
- ]));
+ {"constructorName": constructorName,
+ "constructorNameString": js.string(constructorName),
+ "hasIsolateSupport": hasIsolateSupport,
+ "fieldNamesArray": fieldNamesArray}));
cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
}
@@ -1391,9 +1458,11 @@ class OldEmitter implements Emitter {
// Also emit a trivial constructor for CSP mode.
String constructorName = mangledName;
jsAst.Expression constructorAst = js('function() {}');
+ List<String> fieldNames = [];
emitPrecompiledConstructor(mainOutputUnit,
constructorName,
- constructorAst);
+ constructorAst,
+ fieldNames);
}
}

Powered by Google App Engine
This is Rietveld 408576698