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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 14986002: Make static tear-off closures a class, like instance tear-off closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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_backend/emitter.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (revision 22664)
+++ sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (working copy)
@@ -158,6 +158,8 @@
checkedTypedefs.add(t.element);
}
});
+ print(compiler.resolverWorld.isChecks);
+ print(compiler.codegenWorld.isChecks);
}
ClassElement computeMixinClass(MixinApplicationElement mixinApplication) {
@@ -1759,6 +1761,10 @@
// of stubs.
ClassElement closureClass = compiler.closureClass;
if (needsClosureClass && !instantiatedClasses.contains(closureClass)) {
+ ClassElement objectClass = compiler.objectClass;
+ if (!instantiatedClasses.contains(objectClass)) {
+ generateClass(objectClass, bufferForElement(objectClass, buffer));
+ }
generateClass(closureClass, bufferForElement(closureClass, buffer));
}
}
@@ -1814,42 +1820,74 @@
}
}
+ final Map<Element, Element> staticGetters = new Map<Element, Element>();
+
void emitStaticFunctionGetters(CodeBuffer eagerBuffer) {
+ for (FunctionElement element in
+ Elements.sortedByPosition(staticGetters.keys)) {
+ Element closure = staticGetters[element];
+ CodeBuffer buffer = bufferForElement(element, eagerBuffer);
+ String closureClass = namer.isolateAccess(closure);
+ String name = namer.getStaticClosureName(element);
+ String staticName = namer.getName(element);
+
+ String closureName = namer.getStaticClosureName(element);
+ jsAst.Node assignment = js('$isolateProperties.$name = '
+ 'new $closureClass($isolateProperties.$staticName, "$closureName")');
ahe 2013/05/16 20:07:56 This broke deferred loading (and try.dartlang.org)
sra1 2013/05/16 20:28:33 This would 'just work' if static function closures
ahe 2013/05/16 20:30:44 I was thinking the same thing. Well, up to the se
+ buffer.write(jsAst.prettyPrint(assignment, compiler));
+ buffer.write('$N');
+ }
+ }
+
+ void emitStaticFunctionClosures() {
Set<FunctionElement> functionsNeedingGetter =
compiler.codegenWorld.staticFunctionsNeedingGetter;
for (FunctionElement element in
Elements.sortedByPosition(functionsNeedingGetter)) {
- CodeBuffer buffer = bufferForElement(element, eagerBuffer);
+ String staticName = namer.getName(element);
+ String superName = namer.getName(compiler.closureClass);
+ String name = 'Closure\$${element.name.slowToString()}';
+ needsClosureClass = true;
- // The static function does not have the correct name. Since
- // [addParameterStubs] use the name to create its stubs we simply
- // create a fake element with the correct name.
+ ClassElement closureClassElement = new ClosureClassElement(
+ null, new SourceString(name), compiler, element,
+ element.getCompilationUnit());
+ // Now add the methods on the closure class. The instance method does not
+ // have the correct name. Since [addParameterStubs] use the name to create
+ // its stubs we simply create a fake element with the correct name.
// Note: the callElement will not have any enclosingElement.
FunctionElement callElement =
new ClosureInvocationElement(namer.closureInvocationSelectorName,
element);
- String staticName = namer.getName(element);
+
String invocationName = namer.instanceMethodName(callElement);
- String fieldAccess = '$isolateProperties.$staticName';
- buffer.write("$fieldAccess.$invocationName$_=$_$fieldAccess$N");
+ String mangledName = namer.getName(closureClassElement);
- addParameterStubs(callElement, (String name, jsAst.Expression value) {
- jsAst.Expression assignment =
- js('$isolateProperties.$staticName.$name = #', value);
- buffer.write(jsAst.prettyPrint(assignment.toStatement(), compiler));
- buffer.write('$N');
+ // Define the constructor with a name so that Object.toString can
+ // find the class name of the closure class.
+ ClassBuilder closureBuilder = new ClassBuilder();
+ // If a static function is used as a closure we need to add its name
+ // in case it is used in spawnFunction.
+ String methodName = namer.STATIC_CLOSURE_NAME_NAME;
+ emitBoundClosureClassHeader(
+ mangledName, superName, <String>[invocationName, methodName],
+ closureBuilder);
+
+ addParameterStubs(callElement, closureBuilder.addProperty);
+
+ DartType type = element.computeType(compiler);
+ getTypedefChecksOn(type).forEach((Element typedef) {
+ String operator = namer.operatorIs(typedef);
+ closureBuilder.addProperty(operator, js('true'));
});
- // If a static function is used as a closure we need to add its name
- // in case it is used in spawnFunction.
- String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
- buffer.write('$fieldAccess.$fieldName$_=$_"$staticName"$N');
- getTypedefChecksOn(element.computeType(compiler)).forEach(
- (Element typedef) {
- String operator = namer.operatorIs(typedef);
- buffer.write('$fieldAccess.$operator$_=${_}true$N');
- }
- );
+ // TODO(ngeoffray): Cache common base classes for clsures, bound
+ // closures, and static closures that have common type checks.
+ boundClosures.add(
+ js('$classesCollector.$mangledName = #',
+ closureBuilder.toObjectInitializer()));
+
+ staticGetters[element] = closureClassElement;
}
}
@@ -2353,15 +2391,10 @@
String buildIsolateSetup(CodeBuffer buffer,
Element appMain,
Element isolateMain) {
- String mainAccess = "${namer.isolateAccess(appMain)}";
+ String mainAccess = "${namer.isolateStaticClosureAccess(appMain)}";
String currentIsolate = "${namer.CURRENT_ISOLATE}";
// Since we pass the closurized version of the main method to
// the isolate method, we must make sure that it exists.
- if (!compiler.codegenWorld.staticFunctionsNeedingGetter.contains(appMain)) {
- Selector selector = new Selector.callClosure(0);
- String invocationName = namer.invocationName(selector);
- buffer.write("$mainAccess.$invocationName = $mainAccess$N");
- }
return "${namer.isolateAccess(isolateMain)}($mainAccess)";
}
@@ -2453,8 +2486,6 @@
condition = js('(typeof receiver) == "string"');
} else if (cls == backend.jsNullClass) {
condition = js('receiver == null');
- } else if (cls == backend.jsFunctionClass) {
- condition = js('(typeof receiver) == "function"');
} else {
throw 'internal error';
}
@@ -2464,7 +2495,6 @@
bool hasArray = false;
bool hasBool = false;
bool hasDouble = false;
- bool hasFunction = false;
bool hasInt = false;
bool hasNull = false;
bool hasNumber = false;
@@ -2477,7 +2507,6 @@
cls == backend.jsExtendableArrayClass) hasArray = true;
else if (cls == backend.jsBoolClass) hasBool = true;
else if (cls == backend.jsDoubleClass) hasDouble = true;
- else if (cls == backend.jsFunctionClass) hasFunction = true;
else if (cls == backend.jsIntClass) hasInt = true;
else if (cls == backend.jsNullClass) hasNull = true;
else if (cls == backend.jsNumberClass) hasNumber = true;
@@ -2538,9 +2567,6 @@
block.statements.add(js.if_('receiver == null',
js.return_(js('receiver'))));
}
- if (hasFunction) {
- block.statements.add(buildInterceptorCheck(backend.jsFunctionClass));
- }
if (hasBool) {
block.statements.add(buildInterceptorCheck(backend.jsBoolClass));
}
@@ -2920,7 +2946,8 @@
if (!regularClasses.isEmpty ||
!deferredClasses.isEmpty ||
- !nativeClasses.isEmpty) {
+ !nativeClasses.isEmpty ||
+ !compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty) {
// Shorten the code by using "$$" as temporary.
classesCollector = r"$$";
mainBuffer.add('var $classesCollector$_=$_{}$N$n');
@@ -2966,6 +2993,7 @@
deferredBuffer.add("\$\$$_=${_}null$N$n");
}
+ emitStaticFunctionClosures();
emitClosureClassIfNeeded(mainBuffer);
addComment('Bound closures', mainBuffer);

Powered by Google App Engine
This is Rietveld 408576698