Chromium Code Reviews| 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); |
|
floitsch
2015/07/17 17:19:46
Was the 'register' call no necessary?
asgerf
2015/07/20 09:10:57
No, code generation handles that. This call was a
|
| - newReceiver = new Interceptor(receiver, interceptedClasses); |
| - insertLetPrim(newReceiver, node); |
| + newReceiver = getInterceptorFor(receiver, node.selector); |
| } |
| node.arguments.insert(0, node.receiver); |