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

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

Issue 15888010: Re-apply "Implement operator== and hashCode for bound 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 23383)
+++ sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart (working copy)
@@ -58,7 +58,6 @@
bool needsInheritFunction = false;
bool needsDefineClass = false;
bool needsMixinSupport = false;
- bool needsClosureClass = false;
bool needsLazyInitializer = false;
final Namer namer;
ConstantEmitter constantEmitter;
@@ -1756,19 +1755,6 @@
return (ClassElement cls) => !unneededClasses.contains(cls);
}
- void emitClosureClassIfNeeded(CodeBuffer buffer) {
- // The closure class could have become necessary because of the generation
- // 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));
- }
- }
-
void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
if (needsDefineClass) {
buffer.write('$finishClassesName($classesCollector,'
@@ -1855,7 +1841,7 @@
String staticName = namer.getName(element);
String superName = namer.getName(compiler.closureClass);
String name = 'Closure\$${element.name.slowToString()}';
- needsClosureClass = true;
+ assert(instantiatedClasses.contains(closureClass));
ClassElement closureClassElement = new ClosureClassElement(
null, new SourceString(name), compiler, element,
@@ -1877,7 +1863,7 @@
// 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(
+ emitClosureClassHeader(
mangledName, superName, <String>[invocationName, methodName],
closureBuilder);
@@ -1889,7 +1875,7 @@
closureBuilder.addProperty(operator, js('true'));
});
- // TODO(ngeoffray): Cache common base classes for clsures, bound
+ // TODO(ngeoffray): Cache common base classes for closures, bound
// closures, and static closures that have common type checks.
boundClosures.add(
js('$classesCollector.$mangledName = #',
@@ -1899,10 +1885,10 @@
}
}
- void emitBoundClosureClassHeader(String mangledName,
- String superName,
- List<String> fieldNames,
- ClassBuilder builder) {
+ void emitClosureClassHeader(String mangledName,
+ String superName,
+ List<String> fieldNames,
+ ClassBuilder builder) {
builder.addProperty('',
js.string("$superName;${fieldNames.join(',')}"));
}
@@ -1915,6 +1901,7 @@
void emitDynamicFunctionGetter(FunctionElement member,
DefineStubFunction defineStub) {
assert(invariant(member, member.isDeclaration));
+ assert(instantiatedClasses.contains(boundClosureClass));
// For every method that has the same name as a property-get we create a
// getter that returns a bound closure. Say we have a class 'A' with method
// 'foo' and somewhere in the code there is a dynamic property get of
@@ -1924,8 +1911,7 @@
// foo(x, y, z) { ... } // Original function.
// get foo { return new BoundClosure499(this, "foo"); }
// }
- // class BoundClosure499 extends Closure {
- // var self;
+ // class BoundClosure499 extends BoundClosure {
// BoundClosure499(this.self, this.name);
// $call3(x, y, z) { return self[name](x, y, z); }
// }
@@ -1946,15 +1932,13 @@
bool inInterceptor = backend.isInterceptedMethod(member);
if (inInterceptor) {
cache = interceptorClosureCache;
- extraArg = 'receiver';
} else {
cache = boundClosureCache;
}
- List<String> fieldNames = compiler.enableMinification
- ? inInterceptor ? const ['a', 'b', 'c']
- : const ['a', 'b']
- : inInterceptor ? const ['self', 'target', 'receiver']
- : const ['self', 'target'];
+ List<String> fieldNames = <String>[];
+ compiler.boundClosureClass.forEachInstanceField((_, Element field) {
+ fieldNames.add(namer.getName(field));
+ });
Iterable<Element> typedefChecks =
getTypedefChecksOn(member.computeType(compiler));
@@ -1983,12 +1967,11 @@
member.getCompilationUnit());
String mangledName = namer.getName(closureClassElement);
String superName = namer.getName(closureClassElement.superclass);
- needsClosureClass = true;
// Define the constructor with a name so that Object.toString can
// find the class name of the closure class.
ClassBuilder boundClosureBuilder = new ClassBuilder();
- emitBoundClosureClassHeader(
+ emitClosureClassHeader(
mangledName, superName, fieldNames, boundClosureBuilder);
// Now add the methods on the closure class. The instance method does not
// have the correct name. Since [addParameterStubs] use the name to create
@@ -2044,8 +2027,12 @@
arguments.add(js('this'));
arguments.add(js.string(targetName));
if (inInterceptor) {
- parameters.add(extraArg);
- arguments.add(js(extraArg));
+ String receiverArg = fieldNames[2];
+ parameters.add(receiverArg);
+ arguments.add(js(receiverArg));
+ } else {
+ // Put null in the intercepted receiver field.
+ arguments.add(new jsAst.LiteralNull());
}
jsAst.Expression getterFunction = js.fun(
@@ -2997,7 +2984,6 @@
}
emitStaticFunctionClosures();
- emitClosureClassIfNeeded(mainBuffer);
addComment('Bound closures', mainBuffer);
// Now that we have emitted all classes, we know all the bound

Powered by Google App Engine
This is Rietveld 408576698