Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 14732) |
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy) |
| @@ -46,6 +46,20 @@ |
| } |
| Element getStaticInterceptor(Selector selector) { |
| + // Check if we have an interceptor implemented with classes. |
| + List<Element> intercepted = |
| + compiler.enqueuer.resolution.interceptedElements[selector.name]; |
| + if (intercepted != null) { |
| + for (Element element in intercepted) { |
| + if (selector.applies(element, compiler)) { |
| + JavaScriptBackend backend = compiler.backend; |
| + backend.usedInterceptors.add(selector); |
|
ahe
2012/11/12 13:24:11
A helper method instead :-)
ngeoffray
2012/11/13 11:45:16
Done.
|
| + return compiler.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 |
| @@ -401,7 +415,8 @@ |
| if (closureData.isClosure()) { |
| // Inside closure redirect references to itself to [:this:]. |
| HInstruction thisInstruction = new HThis(); |
| - builder.add(thisInstruction); |
| + thisInstruction.sourceElement = closureData.thisElement; |
|
ahe
2012/11/12 13:24:11
Should this be an argument to the constructor?
ngeoffray
2012/11/13 11:45:16
Done.
|
| + builder.graph.entry.addAtEntry(thisInstruction); |
| updateLocal(closureData.closureElement, thisInstruction); |
| } else if (element.isInstanceMember() |
| || element.isGenerativeConstructor()) { |
| @@ -411,7 +426,8 @@ |
| ClassElement cls = element.getEnclosingClass(); |
| DartType type = cls.computeType(builder.compiler); |
| HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| - builder.add(thisInstruction); |
| + thisInstruction.sourceElement = closureData.thisElement; |
| + builder.graph.entry.addAtEntry(thisInstruction); |
| directLocals[closureData.thisElement] = thisInstruction; |
| } |
| } |
| @@ -2270,17 +2286,30 @@ |
| : 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 == compiler.getInterceptorMethod) { |
|
ahe
2012/11/12 13:24:11
Add comment explaining this is the new way.
ngeoffray
2012/11/13 11:45:16
Done.
|
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + HInstruction instruction = |
| + new HInvokeStatic(<HInstruction>[target, receiver]); |
| + add(instruction); |
| + instruction = new HInvokeDynamicGetter( |
| + selector, null, instruction, true); |
|
ahe
2012/11/12 13:24:11
Document what true means here.
ngeoffray
2012/11/13 11:45:16
Done.
|
| + instruction.inputs.add(receiver); |
|
ahe
2012/11/12 13:24:11
Comment here please.
ngeoffray
2012/11/13 11:45:16
Done.
|
| + instruction.element = interceptor; |
| + pushWithPosition(instruction, send); |
| + } else { |
|
ahe
2012/11/12 13:24:11
Add comment explaining this is old style, deprecat
ngeoffray
2012/11/13 11:45:16
Done.
|
| + 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 +2637,29 @@ |
| 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); |
| + if (interceptor == compiler.getInterceptorMethod) { |
| + HStatic target = new HStatic(interceptor); |
| + add(target); |
| + visit(node.receiver); |
|
ahe
2012/11/12 13:24:11
What happens if node.receiver is null?
ngeoffray
2012/11/13 11:45:16
Cannot happen right now, but I added a comment.
|
| + 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 receiver. |
|
ahe
2012/11/12 13:24:11
Is it the last?
ngeoffray
2012/11/13 11:45:16
No second. Improved the comment.
|
| + 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; |
| } |