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

Unified Diff: pkg/compiler/lib/src/js_backend/codegen/unsugar.dart

Issue 1312393002: dart2js cps: Use 'this' instead of receiver when possible. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Cleanup Created 5 years, 4 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: pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
index 0bcc9df4e7306a36a7030bf8a3cf8678404b6d31..e7226103f74b8cd56a5047aef9ff51a9db0240ff 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -52,7 +52,15 @@ class UnsugarVisitor extends RecursiveVisitor {
UnsugarVisitor(this._glue);
+ bool methodUsesReceiverArgument(FunctionElement function) {
+ assert(_glue.isInterceptedMethod(function));
+ ClassElement clazz = function.enclosingClass.declaration;
+ return _glue.isInterceptorClass(clazz) ||
+ _glue.isUsedAsMixin(clazz);
+ }
+
void rewrite(FunctionDefinition function) {
+ thisParameter = function.thisParameter;
bool inInterceptedMethod = _glue.isInterceptedMethod(function.element);
if (function.element.name == '==' &&
@@ -64,7 +72,6 @@ class UnsugarVisitor extends RecursiveVisitor {
}
if (inInterceptedMethod) {
- thisParameter = function.thisParameter;
ThisParameterLocal holder = thisParameter.hint;
explicitReceiverParameter = new Parameter(
new ExplicitReceiverParameterEntity(
@@ -75,7 +82,7 @@ class UnsugarVisitor extends RecursiveVisitor {
// Set all parent pointers.
_parentVisitor.visit(function);
- if (inInterceptedMethod) {
+ if (inInterceptedMethod && methodUsesReceiverArgument(function.element)) {
explicitReceiverParameter.substituteFor(thisParameter);
}
@@ -235,8 +242,13 @@ class UnsugarVisitor extends RecursiveVisitor {
/// The type propagation pass will later narrow the set of interceptors
/// based on the input type, and the let sinking pass will propagate the
/// getInterceptor call closer to its use when this is profitable.
- Interceptor getInterceptorFor(Primitive prim, Selector selector,
- SourceInformation sourceInformation) {
+ Primitive getInterceptorFor(Primitive prim, Selector selector,
+ SourceInformation sourceInformation) {
+ if (prim == explicitReceiverParameter) {
+ // If the receiver is the explicit receiver, we are calling a method in
+ // the same interceptor.
+ return thisParameter;
+ }
assert(prim is! Interceptor);
Interceptor interceptor = interceptors[prim];
if (interceptor == null) {
@@ -255,37 +267,24 @@ class UnsugarVisitor extends RecursiveVisitor {
}
processInvokeMethod(InvokeMethod node) {
- Selector selector = node.selector;
- if (!_glue.isInterceptedSelector(selector)) return;
-
- Primitive receiver = node.receiver.definition;
- Primitive newReceiver;
-
- if (receiver == explicitReceiverParameter) {
- // If the receiver is the explicit receiver, we are calling a method in
- // the same interceptor:
- // Change 'receiver.foo()' to 'this.foo(receiver)'.
- newReceiver = thisParameter;
- } else {
- newReceiver = getInterceptorFor(
- receiver, node.selector, node.sourceInformation);
+ if (_glue.isInterceptedSelector(node.selector)) {
+ // Rewrite `x.foo()` => `INTERCEPTOR.foo(x, ..)`.
+ Primitive receiver = node.receiver.definition;
+ Primitive newReceiver =
+ getInterceptorFor(receiver, node.selector, node.sourceInformation);
+ node.arguments.insert(0, node.receiver);
+ node.receiver = new Reference<Primitive>(newReceiver);
}
-
- node.arguments.insert(0, node.receiver);
- node.receiver = new Reference<Primitive>(newReceiver);
}
processInvokeMethodDirectly(InvokeMethodDirectly node) {
if (_glue.isInterceptedMethod(node.target)) {
- Primitive nullPrim = nullConstant;
- insertLetPrim(nullPrim, node);
+ // Rewrite `x.foo()` => `INTERCEPTOR.foo(x, ..)`.
+ Primitive receiver = node.receiver.definition;
+ Primitive newReceiver =
+ getInterceptorFor(receiver, node.selector, node.sourceInformation);
node.arguments.insert(0, node.receiver);
- // TODO(sra): `null` is not adequate. Interceptors project the class
- // hierarchy onto an interceptor hierarchy. A super call that does a
- // method call will use the javascript 'this' parameter to avoid calling
- // getInterceptor again, so the receiver must be the interceptor (likely
- // `this`), not `null`.
- node.receiver = new Reference<Primitive>(nullPrim);
+ node.receiver = new Reference<Primitive>(newReceiver);
}
}

Powered by Google App Engine
This is Rietveld 408576698