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; |
} |