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

Unified Diff: lib/compiler/implementation/emitter.dart

Issue 10363002: Create isolate constructor dynamically. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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
« no previous file with comments | « lib/compiler/implementation/compile_time_constants.dart ('k') | lib/compiler/implementation/namer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/emitter.dart
diff --git a/lib/compiler/implementation/emitter.dart b/lib/compiler/implementation/emitter.dart
index e14c8efe9aa794ab37668f1d89e615077ade5ce7..199d3b4b3331f90125c0e0964f5116ae9982fd14 100644
--- a/lib/compiler/implementation/emitter.dart
+++ b/lib/compiler/implementation/emitter.dart
@@ -28,7 +28,9 @@ class CodeEmitterTask extends CompilerTask {
final NativeEmitter nativeEmitter;
StringBuffer boundClosureBuffer;
StringBuffer mainBuffer;
- String isolatePrototype;
+ /** Shorter access to [initialStaticValuesName]. Both here in the code, as
+ well as in the generated code. */
+ String initialStatics;
kasperl 2012/05/03 12:30:18 isolateProperties?
floitsch 2012/05/03 14:24:01 Done.
CodeEmitterTask(Compiler compiler)
: namer = compiler.namer,
@@ -41,8 +43,13 @@ class CodeEmitterTask extends CompilerTask {
String get defineClassName() => '${namer.ISOLATE}.\$defineClass';
kasperl 2012/05/03 12:30:18 I think I'd prefer to break before => in this enti
floitsch 2012/05/03 14:24:01 Done.
String get finishClassesName() => '${namer.ISOLATE}.\$finishClasses';
+ String get finishIsolateConstructorName()
+ => '${namer.ISOLATE}.\$finishIsolateConstructor';
+ String get pendingClassesName() => '${namer.ISOLATE}.\$pendingClasses';
+ String get initialStaticValuesName()
+ => '${namer.ISOLATE}.${namer.INITIAL_STATICS}';
- String buildDefineClassFunction(String isolate) {
+ String get defineClassFunction() {
kasperl 2012/05/03 12:30:18 It feels a bit weird to me that these are getters.
floitsch 2012/05/03 14:24:01 If they weren't going through other getters (which
// Example:
// defineClass("A", "B",
// function(x) { /* The JavaScript constructor. */
@@ -57,15 +64,15 @@ class CodeEmitterTask extends CompilerTask {
// });
return """
function(cls, superclass, constructor, prototype) {
- $isolate.prototype[cls] = constructor;
+ $initialStaticValuesName[cls] = constructor;
constructor.prototype = prototype;
if (superclass !== "") {
- $isolate.pendingClasses[cls] = superclass;
+ $pendingClassesName[cls] = superclass;
}
}""";
}
- String buildFinishClassesFunction(String isolate) {
+ String get finishClassesFunction() {
// 'defineClass' does not require the classes to be constructed in order.
// Classes are initially just stored in the 'pendingClasses' field.
// 'finishClasses' takes all pending classes and sets up the prototype.
@@ -80,10 +87,10 @@ function(cls, superclass, constructor, prototype) {
// object and copy over the members.
return '''
function() {
- var pendingClasses = $isolate.pendingClasses;
+ var pendingClasses = $pendingClassesName;
'''/* FinishClasses can be called multiple times. This means that we need to
clear the pendingClasses property. */'''
- $isolate.pendingClasses = {};
+ $pendingClassesName = {};
var finishedClasses = {};
function finishClass(cls) {
if (finishedClasses[cls]) return;
@@ -92,8 +99,8 @@ function() {
'''/* The superclass is only false (empty string) for Dart's Object class. */'''
if (!superclass) return;
finishClass(superclass);
- var constructor = $isolate.prototype[cls];
- var superConstructor = $isolate.prototype[superclass];
+ var constructor = $initialStaticValuesName[cls];
+ var superConstructor = $initialStaticValuesName[superclass];
var prototype = constructor.prototype;
if (prototype.__proto__) {
'''/* On Firefox and Webkit browsers we can manipulate the __proto__
@@ -120,16 +127,46 @@ function() {
}
}
for (var cls in pendingClasses) finishClass(cls);
-};
-''';
+}''';
+ }
+
+ String get finishIsolateConstructorFunction() {
+ return """function(oldIsolate) {
+ var initialStatics = oldIsolate.${namer.INITIAL_STATICS};
+ var isolatePrototype = oldIsolate.prototype;
+ var str = "{\\n";
+"""/* We fetch the initial static values from the same location as before. */"""
kasperl 2012/05/03 12:30:18 Somehow this "embedded comment" make it harder to
floitsch 2012/05/03 14:24:01 Done.
+ str += "var initialStatics = ${namer.ISOLATE}.${namer.INITIAL_STATICS};\\n";
+ for (var staticName in initialStatics) {
+ if (Object.prototype.hasOwnProperty.call(initialStatics, staticName)) {
+ str += "this." + staticName + "= initialStatics." + staticName + ";\\n";
+ }
+ }
+ str += "}\\n";
+ var newIsolate = new Function(str);
+ newIsolate.prototype = isolatePrototype;
+ isolatePrototype.constructor = newIsolate;
+ newIsolate.${namer.INITIAL_STATICS} = initialStatics;
+ return newIsolate;
+}""";
}
void addDefineClassAndFinishClassFunctionsIfNecessary(StringBuffer buffer) {
String isolate = namer.ISOLATE;
- buffer.add("$defineClassName = ${buildDefineClassFunction(isolate)};\n");
- buffer.add("$isolate.pendingClasses = {};\n");
- buffer.add("$finishClassesName = ${buildFinishClassesFunction(isolate)};");
- buffer.add("\n");
+ buffer.add("$defineClassName = $defineClassFunction;\n");
+ buffer.add("$pendingClassesName = {};\n");
+ buffer.add("$finishClassesName = $finishClassesFunction;\n");
+ }
+
+ void emitFinishIsolateConstructor(StringBuffer buffer) {
+ String name = finishIsolateConstructorName;
+ String value = finishIsolateConstructorFunction;
+ buffer.add("$name = $value;\n");
+ }
+
+ void emitFinishIsolateConstructorInvocation(StringBuffer buffer) {
+ String isolate = namer.ISOLATE;
+ buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n");
}
void addParameterStub(FunctionElement member,
@@ -443,10 +480,8 @@ function() {
String functionNamer(Element element)) {
generatedCode.forEach((Element element, String codeBlock) {
if (!element.isInstanceMember()) {
- buffer.add(isolatePrototype);
- buffer.add('.${functionNamer(element)} = ');
- buffer.add(codeBlock);
- buffer.add(';\n\n');
+ String functionName = functionNamer(element);
+ buffer.add('$initialStatics.$functionName = $codeBlock;\n\n');
}
});
}
@@ -475,12 +510,10 @@ function() {
String invocationName =
namer.instanceMethodName(element.getLibrary(), callElement.name,
parameterCount);
- buffer.add(isolatePrototype);
- buffer.add(".$staticName.$invocationName = ");
- buffer.add(isolatePrototype);
- buffer.add(".$staticName;\n");
+ String fieldAccess = '$initialStatics.$staticName';
+ buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n");
addParameterStubs(callElement, (String name, String value) {
- buffer.add('$isolatePrototype.$staticName.$name = $value;\n');
+ buffer.add('$fieldAccess.$name = $value;\n');
});
}
}
@@ -586,18 +619,11 @@ function() {
}
void emitStaticNonFinalFieldInitializations(StringBuffer buffer) {
- // Adds initializations inside the Isolate constructor.
- // Example:
- // function Isolate() {
- // this.staticNonFinal = Isolate.prototype.someVal;
- // ...
- // }
ConstantHandler handler = compiler.constantHandler;
List<VariableElement> staticNonFinalFields =
handler.getStaticNonFinalFieldsForEmission();
- if (!staticNonFinalFields.isEmpty()) buffer.add('\n');
for (Element element in staticNonFinalFields) {
- buffer.add(' this.${namer.getName(element)} = ');
+ buffer.add('$initialStatics.${namer.getName(element)} = ');
compiler.withCurrentElement(element, () {
handler.writeJsCodeForVariable(buffer, element);
});
@@ -619,14 +645,14 @@ function() {
addedMakeConstantList = true;
emitMakeConstantList(buffer);
}
- buffer.add('$isolatePrototype.$name = ');
+ buffer.add('$initialStatics.$name = ');
handler.writeJsCode(buffer, constant);
buffer.add(';\n');
}
}
void emitMakeConstantList(StringBuffer buffer) {
- buffer.add(isolatePrototype);
+ buffer.add(namer.ISOLATE);
buffer.add(@'''.makeConstantList = function(list) {
list.immutable$list = true;
list.fixed$length = true;
@@ -808,13 +834,11 @@ if (typeof window != 'undefined' && typeof document != 'undefined' &&
String assembleProgram() {
measure(() {
- mainBuffer.add('function ${namer.ISOLATE}() {');
- emitStaticNonFinalFieldInitializations(mainBuffer);
- mainBuffer.add('}\n');
+ mainBuffer.add('function ${namer.ISOLATE}() {}\n');
mainBuffer.add('init();\n\n');
// Shorten the code by using [namer.CURRENT_ISOLATE] as temporary.
- isolatePrototype = namer.CURRENT_ISOLATE;
- mainBuffer.add('var $isolatePrototype = ${namer.ISOLATE}.prototype;\n');
+ initialStatics = namer.CURRENT_ISOLATE;
+ mainBuffer.add('var $initialStatics = $initialStaticValuesName;\n');
emitClasses(mainBuffer);
mainBuffer.add(boundClosureBuffer);
// Clear the buffer, so that we can reuse it for the native classes.
@@ -824,18 +848,28 @@ if (typeof window != 'undefined' && typeof document != 'undefined' &&
// We need to finish the classes before we construct compile time
// constants.
emitFinishClassesInvocationIfNecessary(mainBuffer);
+ // Static field initializations require the classes to be set up.
+ emitStaticNonFinalFieldInitializations(mainBuffer);
emitCompileTimeConstants(mainBuffer);
- isolatePrototype = '${namer.ISOLATE}.prototype;\n';
- mainBuffer.add(
- 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
+ initialStatics = initialStaticValuesName;
+ // The following code should not use the short-hand for the
+ // initialStatics.
+ mainBuffer.add('var ${namer.CURRENT_ISOLATE} = null;\n');
nativeEmitter.emitDynamicDispatchMetadata();
nativeEmitter.assembleCode(mainBuffer);
mainBuffer.add(boundClosureBuffer);
emitFinishClassesInvocationIfNecessary(mainBuffer);
+
+ emitFinishIsolateConstructorInvocation(mainBuffer);
+ mainBuffer.add(
+ 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
+
emitMain(mainBuffer);
mainBuffer.add('function init() {\n');
+ mainBuffer.add(' $initialStatics = {};\n');
addDefineClassAndFinishClassFunctionsIfNecessary(mainBuffer);
+ emitFinishIsolateConstructor(mainBuffer);
mainBuffer.add('}\n');
compiler.assembledCode = mainBuffer.toString();
});
« no previous file with comments | « lib/compiler/implementation/compile_time_constants.dart ('k') | lib/compiler/implementation/namer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698