| Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/compiler/implementation/ssa/builder.dart (revision 14875)
|
| +++ sdk/lib/_internal/compiler/implementation/ssa/builder.dart (working copy)
|
| @@ -50,7 +50,6 @@
|
| // interceptor classes.
|
| JavaScriptBackend backend = compiler.backend;
|
| if (backend.shouldInterceptSelector(selector)) {
|
| - backend.addInterceptedSelector(selector);
|
| return backend.getInterceptorMethod;
|
| }
|
|
|
| @@ -409,9 +408,9 @@
|
| });
|
| if (closureData.isClosure()) {
|
| // Inside closure redirect references to itself to [:this:].
|
| - HInstruction thisInstruction = new HThis(closureData.thisElement);
|
| - builder.graph.entry.addAtEntry(thisInstruction);
|
| - updateLocal(closureData.closureElement, thisInstruction);
|
| + builder.thisInstruction = new HThis(closureData.thisElement);
|
| + builder.graph.entry.addAtEntry(builder.thisInstruction);
|
| + updateLocal(closureData.closureElement, builder.thisInstruction);
|
| } else if (element.isInstanceMember()
|
| || element.isGenerativeConstructor()) {
|
| // Once closures have been mapped to classes their instance members might
|
| @@ -419,12 +418,20 @@
|
| // context.
|
| ClassElement cls = element.getEnclosingClass();
|
| DartType type = cls.computeType(builder.compiler);
|
| - HInstruction thisInstruction = new HThis(closureData.thisElement,
|
| - new HBoundedType.nonNull(type));
|
| - thisInstruction.sourceElement = closureData.thisElement;
|
| - builder.graph.entry.addAtEntry(thisInstruction);
|
| - directLocals[closureData.thisElement] = thisInstruction;
|
| + builder.thisInstruction = new HThis(closureData.thisElement,
|
| + new HBoundedType.nonNull(type));
|
| + builder.graph.entry.addAtEntry(builder.thisInstruction);
|
| + directLocals[closureData.thisElement] = builder.thisInstruction;
|
| }
|
| +
|
| + if (builder.backend.isInterceptorClass(element.getEnclosingClass())) {
|
| + Element parameter = new Element(
|
| + const SourceString('receiver'), ElementKind.VARIABLE, element);
|
| + HParameterValue value = new HParameterValue(parameter);
|
| + builder.graph.entry.addAfter(
|
| + directLocals[closureData.thisElement], value);
|
| + directLocals[closureData.thisElement] = value;
|
| + }
|
| }
|
|
|
| bool hasValueForDirectLocal(Element element) {
|
| @@ -892,6 +899,7 @@
|
| LocalsHandler localsHandler;
|
| HInstruction rethrowableException;
|
| Map<Element, HInstruction> parameters;
|
| + HInstruction thisInstruction;
|
| final RuntimeTypeInformation rti;
|
| HParameterValue lastAddedParameter;
|
|
|
| @@ -2282,34 +2290,37 @@
|
| assert(selector.isGetter());
|
| SourceString getterName = selector.name;
|
| Element interceptor = null;
|
| - if (elements[send] == null && methodInterceptionEnabled) {
|
| + if (methodInterceptionEnabled) {
|
| interceptor = interceptors.getStaticInterceptor(selector);
|
| }
|
| bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
|
| - if (interceptor != null) {
|
| - if (interceptor == backend.getInterceptorMethod) {
|
| - // If we're using an interceptor class, emit a call to the
|
| - // interceptor method and then the actual dynamic call on the
|
| - // interceptor object.
|
| + if (interceptor == backend.getInterceptorMethod && interceptor != null) {
|
| + // If we're using an interceptor class, emit a call to the
|
| + // interceptor method and then the actual dynamic call on the
|
| + // interceptor object.
|
| + HInstruction instruction;
|
| + if (backend.isInterceptorClass(currentElement.getEnclosingClass())
|
| + && send.receiver == null) {
|
| + instruction = thisInstruction;
|
| + } else {
|
| HStatic target = new HStatic(interceptor);
|
| add(target);
|
| - HInstruction instruction =
|
| - new HInvokeStatic(<HInstruction>[target, receiver]);
|
| + 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);
|
| }
|
| + 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 if (elements[send] == null && interceptor != null) {
|
| + // 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);
|
| @@ -2362,13 +2373,16 @@
|
| Selector selector = elements.getSelector(send);
|
| assert(selector.isSetter());
|
| SourceString setterName = selector.name;
|
| - Element staticInterceptor = null;
|
| - if (elements[send] == null && methodInterceptionEnabled) {
|
| - staticInterceptor = interceptors.getStaticInterceptor(selector);
|
| + Element interceptor = null;
|
| + if (methodInterceptionEnabled) {
|
| + interceptor = interceptors.getStaticInterceptor(selector);
|
| }
|
| bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector);
|
| - if (staticInterceptor != null) {
|
| - HStatic target = new HStatic(staticInterceptor);
|
| + if (interceptor != null && interceptor == backend.getInterceptorMethod) {
|
| + compiler.internalError(
|
| + 'Unimplemented intercepted setter call with interceptor classes');
|
| + } else if (interceptor != null && elements[send] == null) {
|
| + HStatic target = new HStatic(interceptor);
|
| add(target);
|
| List<HInstruction> inputs = <HInstruction>[target, receiver, value];
|
| addWithPosition(new HInvokeInterceptor(selector, inputs), send);
|
| @@ -2633,30 +2647,34 @@
|
| }
|
|
|
| Element interceptor = null;
|
| - if (methodInterceptionEnabled && elements[node] == null) {
|
| + if (methodInterceptionEnabled) {
|
| interceptor = interceptors.getStaticInterceptor(selector);
|
| }
|
| +
|
| if (interceptor != null) {
|
| - // TODO(ngeoffray): The receiver never being null is currently the
|
| - // case, but should be 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);
|
| + if (backend.isInterceptorClass(currentElement.getEnclosingClass())
|
| + && node.receiver == null) {
|
| + inputs.add(thisInstruction);
|
| + inputs.add(localsHandler.readThis());
|
| + } else {
|
| + 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);
|
| + HInstruction instruction = new HInvokeDynamicMethod(selector, inputs);
|
| pushWithPosition(instruction, node);
|
| - } else {
|
| + return;
|
| + } else if (elements[node] == null) {
|
| HStatic target = new HStatic(interceptor);
|
| add(target);
|
| inputs.add(target);
|
| @@ -2664,8 +2682,8 @@
|
| inputs.add(pop());
|
| addGenericSendArgumentsToList(node.arguments, inputs);
|
| pushWithPosition(new HInvokeInterceptor(selector, inputs), node);
|
| + return;
|
| }
|
| - return;
|
| }
|
|
|
| Element element = elements[node];
|
|
|