| Index: lib/compiler/implementation/ssa/builder.dart
|
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart
|
| index ce942e0e8824c4dec02d3a11a5b10cfb59ffbe7c..995a244337dc3cad8ea58310f6310e68baae0a87 100644
|
| --- a/lib/compiler/implementation/ssa/builder.dart
|
| +++ b/lib/compiler/implementation/ssa/builder.dart
|
| @@ -1606,34 +1606,44 @@ class SsaBuilder implements Visitor {
|
| }
|
| }
|
|
|
| - void generateGetter(Send send, Element element) {
|
| + HInstruction generateInstanceSendReceiver(Send send) {
|
| + assert(Elements.isInstanceSend(send, elements));
|
| + if (send.receiver == null) {
|
| + return localsHandler.readThis();
|
| + }
|
| + visit(send.receiver);
|
| + return pop();
|
| + }
|
| +
|
| + void generateInstanceGetterWithCompiledReceiver(Send send,
|
| + HInstruction receiver) {
|
| + assert(Elements.isInstanceSend(send, elements));
|
| + SourceString getterName = send.selector.asIdentifier().source;
|
| Selector selector = elements.getSelector(send);
|
| + Element staticInterceptor = null;
|
| + if (methodInterceptionEnabled) {
|
| + staticInterceptor = interceptors.getStaticGetInterceptor(getterName);
|
| + }
|
| + if (staticInterceptor != null) {
|
| + HStatic target = new HStatic(staticInterceptor);
|
| + add(target);
|
| + List<HInstruction> inputs = <HInstruction>[target, receiver];
|
| + push(new HInvokeInterceptor(selector, getterName, true, inputs));
|
| + } else {
|
| + push(new HInvokeDynamicGetter(selector, null, getterName, receiver));
|
| + }
|
| + }
|
| +
|
| + void generateGetter(Send send, Element element) {
|
| if (Elements.isStaticOrTopLevelField(element)) {
|
| + Selector selector = elements.getSelector(send);
|
| push(new HStatic(element));
|
| if (element.kind == ElementKind.GETTER) {
|
| push(new HInvokeStatic(selector, <HInstruction>[pop()]));
|
| }
|
| } else if (Elements.isInstanceSend(send, elements)) {
|
| - HInstruction receiver;
|
| - if (send.receiver == null) {
|
| - receiver = localsHandler.readThis();
|
| - } else {
|
| - visit(send.receiver);
|
| - receiver = pop();
|
| - }
|
| - SourceString getterName = send.selector.asIdentifier().source;
|
| - Element staticInterceptor = null;
|
| - if (methodInterceptionEnabled) {
|
| - staticInterceptor = interceptors.getStaticGetInterceptor(getterName);
|
| - }
|
| - if (staticInterceptor != null) {
|
| - HStatic target = new HStatic(staticInterceptor);
|
| - add(target);
|
| - List<HInstruction> inputs = <HInstruction>[target, receiver];
|
| - push(new HInvokeInterceptor(selector, getterName, true, inputs));
|
| - } else {
|
| - push(new HInvokeDynamicGetter(selector, null, getterName, receiver));
|
| - }
|
| + HInstruction receiver = generateInstanceSendReceiver(send);
|
| + generateInstanceGetterWithCompiledReceiver(send, receiver);
|
| } else if (Elements.isStaticOrTopLevelFunction(element)) {
|
| push(new HStatic(element));
|
| compiler.registerGetOfStaticFunction(element);
|
| @@ -1642,9 +1652,31 @@ class SsaBuilder implements Visitor {
|
| }
|
| }
|
|
|
| - void generateSetter(SendSet send, Element element, HInstruction value) {
|
| + void generateInstanceSetterWithCompiledReceiver(Send send,
|
| + HInstruction receiver,
|
| + HInstruction value) {
|
| + assert(Elements.isInstanceSend(send, elements));
|
| + SourceString dartSetterName = send.selector.asIdentifier().source;
|
| Selector selector = elements.getSelector(send);
|
| + Element staticInterceptor = null;
|
| + if (methodInterceptionEnabled) {
|
| + staticInterceptor = interceptors.getStaticSetInterceptor(dartSetterName);
|
| + }
|
| + if (staticInterceptor != null) {
|
| + HStatic target = new HStatic(staticInterceptor);
|
| + add(target);
|
| + List<HInstruction> inputs = <HInstruction>[target, receiver, value];
|
| + add(new HInvokeInterceptor(selector, dartSetterName, false, inputs));
|
| + } else {
|
| + add(new HInvokeDynamicSetter(selector, null, dartSetterName,
|
| + receiver, value));
|
| + }
|
| + stack.add(value);
|
| + }
|
| +
|
| + void generateSetter(SendSet send, Element element, HInstruction value) {
|
| if (Elements.isStaticOrTopLevelField(element)) {
|
| + Selector selector = elements.getSelector(send);
|
| if (element.kind == ElementKind.SETTER) {
|
| HStatic target = new HStatic(element);
|
| add(target);
|
| @@ -1654,29 +1686,8 @@ class SsaBuilder implements Visitor {
|
| }
|
| stack.add(value);
|
| } else if (element === null || Elements.isInstanceField(element)) {
|
| - SourceString dartSetterName = send.selector.asIdentifier().source;
|
| - HInstruction receiver;
|
| - if (send.receiver == null) {
|
| - receiver = localsHandler.readThis();
|
| - } else {
|
| - visit(send.receiver);
|
| - receiver = pop();
|
| - }
|
| - Element staticInterceptor = null;
|
| - if (methodInterceptionEnabled) {
|
| - staticInterceptor =
|
| - interceptors.getStaticSetInterceptor(dartSetterName);
|
| - }
|
| - if (staticInterceptor != null) {
|
| - HStatic target = new HStatic(staticInterceptor);
|
| - add(target);
|
| - List<HInstruction> inputs = <HInstruction>[target, receiver, value];
|
| - add(new HInvokeInterceptor(selector, dartSetterName, false, inputs));
|
| - } else {
|
| - add(new HInvokeDynamicSetter(selector, null, dartSetterName,
|
| - receiver, value));
|
| - }
|
| - stack.add(value);
|
| + HInstruction receiver = generateInstanceSendReceiver(send);
|
| + generateInstanceSetterWithCompiledReceiver(send, receiver, value);
|
| } else {
|
| localsHandler.updateLocal(element, value);
|
| stack.add(value);
|
| @@ -2201,7 +2212,15 @@ class SsaBuilder implements Visitor {
|
| Element element = elements[node];
|
| bool isCompoundAssignment = !node.arguments.isEmpty();
|
| bool isPrefix = !node.isPostfix; // Compound assignments are prefix.
|
| - generateGetter(node, elements[node.selector]);
|
| +
|
| + // [receiver] is only used if the node is an instance send.
|
| + HInstruction receiver = null;
|
| + if (Elements.isInstanceSend(node, elements)) {
|
| + receiver = generateInstanceSendReceiver(node);
|
| + generateInstanceGetterWithCompiledReceiver(node, receiver);
|
| + } else {
|
| + generateGetter(node, elements[node.selector]);
|
| + }
|
| HInstruction left = pop();
|
| HInstruction right;
|
| if (isCompoundAssignment) {
|
| @@ -2213,7 +2232,13 @@ class SsaBuilder implements Visitor {
|
| visitBinary(left, op, right);
|
| HInstruction operation = pop();
|
| assert(operation !== null);
|
| - generateSetter(node, element, operation);
|
| + if (Elements.isInstanceSend(node, elements)) {
|
| + assert(receiver !== null);
|
| + generateInstanceSetterWithCompiledReceiver(node, receiver, operation);
|
| + } else {
|
| + assert(receiver === null);
|
| + generateSetter(node, element, operation);
|
| + }
|
| if (!isPrefix) {
|
| pop();
|
| stack.add(left);
|
|
|