| 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 bbe998f1f396f742fb02e2570ed10aa6e2a32156..110d156acc756a234b9a77331c9cf80e70068a9f 100644
|
| --- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| +++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
|
| @@ -5,12 +5,7 @@ import '../../cps_ir/cps_ir_nodes.dart';
|
| import '../../cps_ir/optimizers.dart' show ParentVisitor;
|
| import '../../constants/expressions.dart';
|
| import '../../constants/values.dart';
|
| -import '../../elements/elements.dart' show
|
| - ClassElement,
|
| - FieldElement,
|
| - FunctionElement,
|
| - Local,
|
| - ExecutableElement;
|
| +import '../../elements/elements.dart';
|
| import '../../js_backend/codegen/glue.dart';
|
| import '../../dart2jslib.dart' show Selector, World;
|
| import '../../cps_ir/cps_ir_builder.dart' show ThisParameterLocal;
|
| @@ -22,6 +17,16 @@ class ExplicitReceiverParameterEntity implements Local {
|
| toString() => 'ExplicitReceiverParameterEntity($executableContext)';
|
| }
|
|
|
| +/// Suggested name for an interceptor.
|
| +class InterceptorEntity extends Entity {
|
| + Entity interceptedVariable;
|
| +
|
| + InterceptorEntity(this.interceptedVariable);
|
| +
|
| + String get name => interceptedVariable.name + '_';
|
| +}
|
| +
|
| +
|
| /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
|
| /// special nodes that respect JavaScript behavior.
|
| ///
|
| @@ -38,6 +43,8 @@ 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.
|
| @@ -227,6 +234,32 @@ 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.
|
| + Interceptor getInterceptorFor(Primitive prim, Selector selector) {
|
| + Interceptor interceptor = interceptors[prim];
|
| + if (interceptor == null) {
|
| + interceptor = new Interceptor(prim);
|
| + interceptors[prim] = interceptor;
|
| + InteriorNode parent = prim.parent;
|
| + insertLetPrim(interceptor, parent.body);
|
| + if (prim.hint != null) {
|
| + interceptor.hint = new InterceptorEntity(prim.hint);
|
| + }
|
| + }
|
| + // Add the interceptor classes that can respond to the given selector.
|
| + interceptor.interceptedClasses.addAll(
|
| + _glue.getInterceptedClassesOn(selector));
|
| + return interceptor;
|
| + }
|
| +
|
| processInvokeMethod(InvokeMethod node) {
|
| Selector selector = node.selector;
|
| if (!_glue.isInterceptedSelector(selector)) return;
|
| @@ -240,13 +273,7 @@ class UnsugarVisitor extends RecursiveVisitor {
|
| // Change 'receiver.foo()' to 'this.foo(receiver)'.
|
| newReceiver = thisParameter;
|
| } else {
|
| - // TODO(sra): Move the computation of interceptedClasses to a much later
|
| - // phase and take into account the remaining uses of the interceptor.
|
| - Set<ClassElement> interceptedClasses =
|
| - _glue.getInterceptedClassesOn(selector);
|
| - _glue.registerSpecializedGetInterceptor(interceptedClasses);
|
| - newReceiver = new Interceptor(receiver, interceptedClasses);
|
| - insertLetPrim(newReceiver, node);
|
| + newReceiver = getInterceptorFor(receiver, node.selector);
|
| }
|
|
|
| node.arguments.insert(0, node.receiver);
|
|
|