Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 14840) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -46,6 +46,14 @@ |
| } |
| Element getStaticInterceptor(Selector selector) { |
| + // Check if we have an interceptor implemented with classes. |
|
ahe
2012/11/13 12:42:41
How about:
// Check if we have an interceptor met
ngeoffray
2012/11/13 12:51:50
Done.
|
| + JavaScriptBackend backend = compiler.backend; |
| + if (backend.shouldInterceptSelector(selector)) { |
| + backend.addInterceptedSelector(selector); |
| + return backend.getInterceptorMethod; |
| + } |
| + |
| + // Fall back to the old interceptor mechanism. |
| String name = selector.name.slowToString(); |
| if (selector.isGetter()) { |
| // TODO(lrn): If there is no get-interceptor, but there is a |
| @@ -400,8 +408,8 @@ |
| }); |
| if (closureData.isClosure()) { |
| // Inside closure redirect references to itself to [:this:]. |
| - HInstruction thisInstruction = new HThis(); |
| - builder.add(thisInstruction); |
| + HInstruction thisInstruction = new HThis(closureData.thisElement); |
| + builder.graph.entry.addAtEntry(thisInstruction); |
| updateLocal(closureData.closureElement, thisInstruction); |
| } else if (element.isInstanceMember() |
| || element.isGenerativeConstructor()) { |
| @@ -410,8 +418,10 @@ |
| // context. |
| ClassElement cls = element.getEnclosingClass(); |
| DartType type = cls.computeType(builder.compiler); |
| - HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| - builder.add(thisInstruction); |
| + HInstruction thisInstruction = new HThis(closureData.thisElement, |
| + new HBoundedType.nonNull(type)); |
| + thisInstruction.sourceElement = closureData.thisElement; |
| + builder.graph.entry.addAtEntry(thisInstruction); |
| directLocals[closureData.thisElement] = thisInstruction; |
| } |
| } |
| @@ -2270,17 +2280,35 @@ |
| : elements.getSelector(send.selector); |
| assert(selector.isGetter()); |
| SourceString getterName = selector.name; |
| - Element staticInterceptor = null; |
| + Element interceptor = null; |
| if (elements[send] == null && methodInterceptionEnabled) { |
| - staticInterceptor = interceptors.getStaticInterceptor(selector); |
| + interceptor = interceptors.getStaticInterceptor(selector); |
| } |
| bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
| - if (staticInterceptor != null) { |
| - HStatic target = new HStatic(staticInterceptor); |
| - add(target); |
| - List<HInstruction> inputs = <HInstruction>[target, receiver]; |
| - pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), |
| - send); |
| + if (interceptor != null) { |
| + if (interceptor == backend.getInterceptorMethod) { |
| + // If we're using an interceptor class, emit a call to the |
| + // interceptor method and then the actuall dynamic call on the |
|
ahe
2012/11/13 12:42:41
actuall -> actual
ngeoffray
2012/11/13 12:51:50
Done.
|
| + // interceptor object. |
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + HInstruction instruction = |
| + new HInvokeStatic(<HInstruction>[target, receiver]); |
| + add(instruction); |
| + instruction = new HInvokeDynamicGetter( |
| + selector, null, instruction, !hasGetter); |
| + // Add the receiver as an argument to the getter call on the |
| + // interceptor. |
| + instruction.inputs.add(receiver); |
| + pushWithPosition(instruction, send); |
| + } else { |
| + // Use the old, deprecated interceptor mechanism. |
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + List<HInstruction> inputs = <HInstruction>[target, receiver]; |
| + pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), |
| + send); |
| + } |
| } else { |
| pushWithPosition( |
| new HInvokeDynamicGetter(selector, null, receiver, !hasGetter), send); |
| @@ -2608,13 +2636,33 @@ |
| interceptor = interceptors.getStaticInterceptor(selector); |
| } |
| if (interceptor != null) { |
| - HStatic target = new HStatic(interceptor); |
| - add(target); |
| - inputs.add(target); |
| - visit(node.receiver); |
| - inputs.add(pop()); |
| - addGenericSendArgumentsToList(node.arguments, inputs); |
| - pushWithPosition(new HInvokeInterceptor(selector, inputs), node); |
| + // TODO(ngeoffray): This is currently the case, but should be |
|
ahe
2012/11/13 12:42:41
What does "This" mean here?
ngeoffray
2012/11/13 12:51:50
The assertion. Comment added.
|
| + // updated once we start implementing more of the interceptors class. |
| + assert(node.receiver != null); |
| + if (interceptor == backend.getInterceptorMethod) { |
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + visit(node.receiver); |
| + HInstruction receiver = pop(); |
| + HInstruction instruction = |
| + new HInvokeStatic(<HInstruction>[target, receiver]); |
| + add(instruction); |
| + inputs.add(instruction); |
| + inputs.add(receiver); |
| + addDynamicSendArgumentsToList(node, inputs); |
| + // The first entry in the inputs list is the interceptor. The |
| + // second is the receiver, and the others are the arguments. |
| + instruction = new HInvokeDynamicMethod(selector, inputs); |
| + pushWithPosition(instruction, node); |
| + } else { |
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + inputs.add(target); |
| + visit(node.receiver); |
| + inputs.add(pop()); |
| + addGenericSendArgumentsToList(node.arguments, inputs); |
| + pushWithPosition(new HInvokeInterceptor(selector, inputs), node); |
| + } |
| return; |
| } |