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

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

Issue 1761903002: dart2js cps: Keep interceptors in a separate field. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 4 years, 10 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 4ca64fa9146fd54468609f8a13c39731494bf41a..f7ff67ffc8f02436e8f1703f11c181dc2d3749e0 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -7,7 +7,6 @@ import '../../constants/values.dart';
import '../../elements/elements.dart';
import '../../js_backend/codegen/glue.dart';
import '../../universe/selector.dart' show Selector;
-import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal;
import '../../cps_ir/cps_fragment.dart';
import '../../common/names.dart';
@@ -38,8 +37,13 @@ class InterceptorEntity extends Entity {
class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
Glue _glue;
- Parameter thisParameter;
- Parameter explicitReceiverParameter;
+ FunctionDefinition function;
+
+ Parameter get receiverParameter => function.receiverParameter;
+
+ /// The interceptor of the receiver. For some methods, this is the receiver
+ /// itself, for others, it is the interceptor parameter.
+ Parameter receiverInterceptor;
// In a catch block, rethrow implicitly throws the block's exception
// parameter. This is the exception parameter when nested in a catch
@@ -50,15 +54,8 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
String get passName => 'Unsugaring';
- 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;
+ this.function = function;
bool inInterceptedMethod = _glue.isInterceptedMethod(function.element);
if (function.element.name == '==' &&
@@ -70,15 +67,16 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
}
if (inInterceptedMethod) {
- ThisParameterLocal holder = thisParameter.hint;
- explicitReceiverParameter = new Parameter(
- new ExplicitReceiverParameterEntity(holder.executableContext));
- explicitReceiverParameter.parent = function;
- function.parameters.insert(0, explicitReceiverParameter);
- }
-
- if (inInterceptedMethod && methodUsesReceiverArgument(function.element)) {
- thisParameter.replaceUsesWith(explicitReceiverParameter);
+ function.interceptorParameter = new Parameter(null)..parent = function;
+ // Since the receiver won't be compiled to "this", set a hint on it
+ // so the parameter gets a meaningful name.
+ function.receiverParameter.hint =
+ new ExplicitReceiverParameterEntity(function.element);
+ // If we need an interceptor for the receiver, use the receiver itself
+ // if possible, otherwise the interceptor argument.
+ receiverInterceptor = _glue.methodUsesReceiverArgument(function.element)
+ ? function.interceptorParameter
+ : receiverParameter;
}
visit(function);
@@ -211,45 +209,44 @@ class UnsugarVisitor extends TrampolineRecursiveVisitor implements Pass {
}
Primitive receiver = node.receiver;
- Primitive newReceiver;
+ Primitive interceptor;
- if (receiver == explicitReceiverParameter) {
- // If the receiver is the explicit receiver, we are calling a method in
+ if (receiver == receiverParameter && receiverInterceptor != null) {
+ // TODO(asgerf): This could be done by GVN.
+ // If the receiver is 'this', we are calling a method in
// the same interceptor:
// Change 'receiver.foo()' to 'this.foo(receiver)'.
- newReceiver = thisParameter;
+ interceptor = receiverInterceptor;
} else {
- newReceiver = new Interceptor(receiver, node.sourceInformation);
+ interceptor = new Interceptor(receiver, node.sourceInformation);
if (receiver.hint != null) {
- newReceiver.hint = new InterceptorEntity(receiver.hint);
+ interceptor.hint = new InterceptorEntity(receiver.hint);
}
- new LetPrim(newReceiver).insertAbove(node.parent);
+ new LetPrim(interceptor).insertAbove(node.parent);
}
- node.argumentRefs.insert(0, node.receiverRef);
- node.receiverRef = new Reference<Primitive>(newReceiver)..parent = node;
- node.callingConvention = CallingConvention.Intercepted;
+ assert(node.interceptorRef == null);
+ node.makeIntercepted(interceptor);
}
processInvokeMethodDirectly(InvokeMethodDirectly node) {
if (!_glue.isInterceptedMethod(node.target)) return;
Primitive receiver = node.receiver;
- Primitive newReceiver;
+ Primitive interceptor;
- if (receiver == explicitReceiverParameter) {
- // If the receiver is the explicit receiver, we are calling a method in
+ if (receiver == receiverParameter && receiverInterceptor != null) {
+ // If the receiver is 'this', we are calling a method in
// the same interceptor:
// Change 'receiver.foo()' to 'this.foo(receiver)'.
- newReceiver = thisParameter;
+ interceptor = receiverInterceptor;
} else {
- newReceiver = new Interceptor(receiver, node.sourceInformation);
+ interceptor = new Interceptor(receiver, node.sourceInformation);
if (receiver.hint != null) {
- newReceiver.hint = new InterceptorEntity(receiver.hint);
+ interceptor.hint = new InterceptorEntity(receiver.hint);
}
- new LetPrim(newReceiver).insertAbove(node.parent);
+ new LetPrim(interceptor).insertAbove(node.parent);
}
- node.argumentRefs.insert(0, node.receiverRef);
- node.receiverRef = new Reference<Primitive>(newReceiver)..parent = node;
- node.callingConvention = CallingConvention.Intercepted;
+ assert(node.interceptorRef == null);
+ node.makeIntercepted(interceptor);
}
}
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/task.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698