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 e7226103f74b8cd56a5047aef9ff51a9db0240ff..9913065e6d8e11d21bb2f7dc5674ae18cbe28a30 100644 |
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart |
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart |
@@ -43,8 +43,6 @@ class UnsugarVisitor extends RecursiveVisitor { |
Parameter thisParameter; |
Parameter explicitReceiverParameter; |
- Map<Primitive, Interceptor> interceptors = <Primitive, Interceptor>{}; |
- |
// In a catch block, rethrow implicitly throws the block's exception |
// parameter. This is the exception parameter when nested in a catch |
// block and null otherwise. |
@@ -233,59 +231,54 @@ class UnsugarVisitor extends RecursiveVisitor { |
// worry about unlinking. |
} |
- /// Returns an interceptor for the given value, capable of responding to |
- /// [selector]. |
- /// |
- /// A single getInterceptor call will be created per primitive, bound |
- /// immediately after the primitive is bound. |
- /// |
- /// 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. |
- Primitive getInterceptorFor(Primitive prim, Selector selector, |
- SourceInformation sourceInformation) { |
- if (prim == explicitReceiverParameter) { |
+ 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. |
- return thisParameter; |
- } |
- assert(prim is! Interceptor); |
- Interceptor interceptor = interceptors[prim]; |
- if (interceptor == null) { |
- interceptor = new Interceptor(prim, sourceInformation); |
- interceptors[prim] = interceptor; |
- InteriorNode parent = prim.parent; |
- insertLetPrim(interceptor, parent.body); |
- if (prim.hint != null) { |
- interceptor.hint = new InterceptorEntity(prim.hint); |
+ // the same interceptor: |
+ // Change 'receiver.foo()' to 'this.foo(receiver)'. |
+ newReceiver = thisParameter; |
+ } else { |
+ LetCont contBinding = node.parent; |
+ newReceiver = new Interceptor(receiver, node.sourceInformation) |
+ ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector)); |
+ if (receiver.hint != null) { |
+ newReceiver.hint = new InterceptorEntity(receiver.hint); |
} |
+ insertLetPrim(newReceiver, contBinding); |
} |
- // Add the interceptor classes that can respond to the given selector. |
- interceptor.interceptedClasses.addAll( |
- _glue.getInterceptedClassesOn(selector)); |
- return interceptor; |
- } |
- |
- processInvokeMethod(InvokeMethod node) { |
- 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)) { |
- // 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); |
+ if (!_glue.isInterceptedMethod(node.target)) return; |
+ |
+ Selector selector = node.selector; |
+ 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 { |
+ LetCont contBinding = node.parent; |
+ newReceiver = new Interceptor(receiver, node.sourceInformation) |
+ ..interceptedClasses.addAll(_glue.getInterceptedClassesOn(selector)); |
+ if (receiver.hint != null) { |
+ newReceiver.hint = new InterceptorEntity(receiver.hint); |
+ } |
+ insertLetPrim(newReceiver, contBinding); |
} |
+ node.arguments.insert(0, node.receiver); |
+ node.receiver = new Reference<Primitive>(newReceiver); |
} |
processBranch(Branch node) { |