From c326636f8d7b4195f4dc2ab26ae06a7fc5c675de Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Fri, 10 Feb 2017 13:15:57 +0100
Subject: [PATCH] remove unnecessary NodeField annotations in write variable
 hierarchy

---
 .../truffle/r/nodes/builtin/base/Mapply.java  |   2 +-
 .../r/nodes/access/BaseWriteVariableNode.java |   9 +-
 .../access/WriteLocalFrameVariableNode.java   | 127 ++++++------------
 .../access/WriteSuperFrameVariableNode.java   |  52 +++----
 .../WriteSuperFrameVariableNodeHelper.java    |  42 ------
 .../r/nodes/access/WriteVariableNode.java     |  26 ++--
 .../nodes/access/WriteVariableSyntaxNode.java |  41 +++---
 .../truffle/r/nodes/binary/BinaryNode.java    |   2 +-
 .../truffle/r/nodes/control/ForNode.java      |  10 +-
 .../control/ReplacementDispatchNode.java      |  27 +++-
 .../r/nodes/control/ReplacementNode.java      |  12 +-
 .../truffle/r/nodes/objects/LoadMethod.java   |   8 +-
 .../r/nodes/unary/CastToVectorNode.java       |   2 +-
 .../r/nodes/unary/ConvertBooleanNode.java     |   2 +-
 14 files changed, 149 insertions(+), 213 deletions(-)
 delete mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNodeHelper.java

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
index 4fd7a02227..f51a45e0d9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java
@@ -88,7 +88,7 @@ public abstract class Mapply extends RBuiltinNode {
             this.vectorElementName = "*" + AnonymousFrameVariable.create(vectorElementName);
             this.lengthNode = insert(LengthNodeGen.create());
             this.indexedLoadNode = insert(SubscriptNodeGen.create());
-            this.writeVectorElementNode = insert(WriteVariableNode.createAnonymous(this.vectorElementName, null, Mode.REGULAR));
+            this.writeVectorElementNode = insert(WriteVariableNode.createAnonymous(this.vectorElementName, Mode.REGULAR, null));
             this.argName = argName;
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
index 62d0f967d3..24f773ecef 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java
@@ -24,8 +24,6 @@ package com.oracle.truffle.r.nodes.access;
 
 import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.dsl.NodeChild;
-import com.oracle.truffle.api.dsl.NodeField;
-import com.oracle.truffle.api.dsl.NodeFields;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotKind;
@@ -38,7 +36,6 @@ import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 
 @NodeChild(value = "rhs", type = RNode.class)
-@NodeFields({@NodeField(name = "name", type = Object.class)})
 /**
  * Common code/state for all the variants of {@code WriteVariableNode}. At this level, we just have
  * a {@code name} for the variable and expression {@code rhs} to be assigned to.
@@ -47,6 +44,10 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
  */
 abstract class BaseWriteVariableNode extends WriteVariableNode {
 
+    protected BaseWriteVariableNode(Object name) {
+        super(name);
+    }
+
     private final ConditionProfile isObjectProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isCurrentProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile isShareableProfile = ConditionProfile.createBinaryProfile();
@@ -136,7 +137,7 @@ abstract class BaseWriteVariableNode extends WriteVariableNode {
         return isKind(frameSlot, FrameSlotKind.Double);
     }
 
-    private boolean isKind(FrameSlot frameSlot, FrameSlotKind kind) {
+    protected boolean isKind(FrameSlot frameSlot, FrameSlotKind kind) {
         if (frameSlot.getKind() == kind) {
             return true;
         } else {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
index 7e26af3cfc..19807b04e4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,118 +22,73 @@
  */
 package com.oracle.truffle.r.nodes.access;
 
-import static com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.findOrAddFrameSlot;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.dsl.NodeField;
-import com.oracle.truffle.api.dsl.NodeFields;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.ImportStatic;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.VirtualFrame;
-import com.oracle.truffle.api.nodes.NodeCost;
-import com.oracle.truffle.api.nodes.NodeInfo;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
-import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNodeFactory.ResolvedWriteLocalFrameVariableNodeGen;
-import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNodeFactory.UnresolvedWriteLocalFrameVariableNodeGen;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.RNode;
 
 /**
  * {@link WriteLocalFrameVariableNode} captures a write to the "local", i.e., current, frame. There
  * are several clients capturing different "kinds" of writes to the frame, e.g. saving an argument,
- * a source-level write, a a write helper for another source node (e.g. {@code ForNode}.
- *
- * The state starts out a "unresolved" and transforms to "resolved".
+ * a source-level write, a a write helper for another source node (e.g. {@code ForNode}).
  */
+@ImportStatic(FrameSlotKind.class)
 public abstract class WriteLocalFrameVariableNode extends BaseWriteVariableNode {
 
-    public static WriteLocalFrameVariableNode create(String name, RNode rhs, Mode mode) {
-        return UnresolvedWriteLocalFrameVariableNodeGen.create(rhs, name, mode);
+    public static WriteLocalFrameVariableNode create(Object name, Mode mode, RNode rhs) {
+        return WriteLocalFrameVariableNodeGen.create(name, mode, rhs);
     }
 
     public static WriteLocalFrameVariableNode createForRefCount(Object name) {
-        return UnresolvedWriteLocalFrameVariableNodeGen.create(null, name, Mode.INVISIBLE);
+        return WriteLocalFrameVariableNodeGen.create(name, Mode.INVISIBLE, null);
     }
 
-    @NodeField(name = "mode", type = Mode.class)
-    @NodeInfo(cost = NodeCost.UNINITIALIZED)
-    abstract static class UnresolvedWriteLocalFrameVariableNode extends WriteLocalFrameVariableNode {
-
-        public abstract Mode getMode();
-
-        @Specialization
-        protected byte doLogical(VirtualFrame frame, byte value) {
-            resolveAndSet(frame, value, FrameSlotKind.Byte);
-            return value;
-        }
+    private final Mode mode;
 
-        @Specialization
-        protected int doInteger(VirtualFrame frame, int value) {
-            resolveAndSet(frame, value, FrameSlotKind.Int);
-            return value;
-        }
+    private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile();
+    private final BranchProfile invalidateProfile = BranchProfile.create();
 
-        @Specialization
-        protected double doDouble(VirtualFrame frame, double value) {
-            resolveAndSet(frame, value, FrameSlotKind.Double);
-            return value;
-        }
-
-        @Specialization
-        protected Object doObject(VirtualFrame frame, Object value) {
-            resolveAndSet(frame, value, FrameSlotKind.Object);
-            return value;
-        }
-
-        private void resolveAndSet(VirtualFrame frame, Object value, FrameSlotKind initialKind) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            // it's slow path (unconditional replace) so toString() is fine as well
-            if (getName().toString().isEmpty()) {
-                throw RError.error(RError.NO_CALLER, RError.Message.ZERO_LENGTH_VARIABLE);
-            }
-            FrameSlot frameSlot = findOrAddFrameSlot(frame.getFrameDescriptor(), getName(), initialKind);
-            replace(ResolvedWriteLocalFrameVariableNode.create(getRhs(), getName(), frameSlot, getMode())).execute(frame, value);
-        }
+    protected WriteLocalFrameVariableNode(Object name, Mode mode) {
+        super(name);
+        this.mode = mode;
     }
 
-    @NodeFields({@NodeField(name = "frameSlot", type = FrameSlot.class), @NodeField(name = "mode", type = Mode.class)})
-    abstract static class ResolvedWriteLocalFrameVariableNode extends WriteLocalFrameVariableNode {
-
-        private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile();
-        private final BranchProfile invalidateProfile = BranchProfile.create();
-
-        public abstract Mode getMode();
-
-        private static ResolvedWriteLocalFrameVariableNode create(RNode rhs, Object name, FrameSlot frameSlot, Mode mode) {
-            return ResolvedWriteLocalFrameVariableNodeGen.create(rhs, name, frameSlot, mode);
-        }
+    protected FrameSlot findOrAddFrameSlot(VirtualFrame frame, FrameSlotKind initialKind) {
+        return FrameSlotChangeMonitor.findOrAddFrameSlot(frame.getFrameDescriptor(), getName(), initialKind);
+    }
 
-        @Specialization(guards = "isLogicalKind(frame, frameSlot)")
-        protected byte doLogical(VirtualFrame frame, FrameSlot frameSlot, byte value) {
-            FrameSlotChangeMonitor.setByteAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
-            return value;
-        }
+    @Specialization(guards = "isLogicalKind(frame, frameSlot)")
+    protected byte doLogical(VirtualFrame frame, byte value,
+                    @Cached("findOrAddFrameSlot(frame, Byte)") FrameSlot frameSlot) {
+        FrameSlotChangeMonitor.setByteAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
+        return value;
+    }
 
-        @Specialization(guards = "isIntegerKind(frame, frameSlot)")
-        protected int doInteger(VirtualFrame frame, FrameSlot frameSlot, int value) {
-            FrameSlotChangeMonitor.setIntAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
-            return value;
-        }
+    @Specialization(guards = "isIntegerKind(frame, frameSlot)")
+    protected int doInteger(VirtualFrame frame, int value,
+                    @Cached("findOrAddFrameSlot(frame, Int)") FrameSlot frameSlot) {
+        FrameSlotChangeMonitor.setIntAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
+        return value;
+    }
 
-        @Specialization(guards = "isDoubleKind(frame, frameSlot)")
-        protected double doDouble(VirtualFrame frame, FrameSlot frameSlot, double value) {
-            FrameSlotChangeMonitor.setDoubleAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
-            return value;
-        }
+    @Specialization(guards = "isDoubleKind(frame, frameSlot)")
+    protected double doDouble(VirtualFrame frame, double value,
+                    @Cached("findOrAddFrameSlot(frame, Double)") FrameSlot frameSlot) {
+        FrameSlotChangeMonitor.setDoubleAndInvalidate(frame, frameSlot, value, false, invalidateProfile);
+        return value;
+    }
 
-        @Specialization
-        protected Object doObject(VirtualFrame frame, FrameSlot frameSlot, Object value) {
-            Object newValue = shareObjectValue(frame, frameSlot, storedObjectProfile.profile(value), getMode(), false);
-            FrameSlotChangeMonitor.setObjectAndInvalidate(frame, frameSlot, newValue, false, invalidateProfile);
-            return value;
-        }
+    @Specialization
+    protected Object doObject(VirtualFrame frame, Object value,
+                    @Cached("findOrAddFrameSlot(frame, Object)") FrameSlot frameSlot) {
+        Object newValue = shareObjectValue(frame, frameSlot, storedObjectProfile.profile(value), mode, false);
+        FrameSlotChangeMonitor.setObjectAndInvalidate(frame, frameSlot, newValue, false, invalidateProfile);
+        return value;
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
index c3d06849fa..8d5de24ba4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@ import static com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.find
 
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.dsl.NodeChild;
-import com.oracle.truffle.api.dsl.NodeChildren;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotKind;
@@ -35,10 +34,8 @@ import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.api.profiles.ValueProfile;
-import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNodeFactory.UnresolvedWriteLocalFrameVariableNodeGen;
 import com.oracle.truffle.r.nodes.access.WriteSuperFrameVariableNodeFactory.ResolvedWriteSuperFrameVariableNodeGen;
 import com.oracle.truffle.r.runtime.RArguments;
-import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -50,8 +47,12 @@ import com.oracle.truffle.r.runtime.nodes.RNode;
  */
 abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
 
-    static WriteVariableNode create(String name, RNode rhs, Mode mode) {
-        return new UnresolvedWriteSuperFrameVariableNode(name, rhs, mode);
+    protected WriteSuperFrameVariableNode(Object name) {
+        super(name);
+    }
+
+    static WriteVariableNode create(String name, Mode mode, RNode rhs) {
+        return new UnresolvedWriteSuperFrameVariableNode(name, mode, rhs);
     }
 
     protected abstract void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame);
@@ -63,7 +64,8 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
         return value;
     }
 
-    @NodeChildren({@NodeChild(value = "enclosingFrame", type = AccessEnclosingFrameNode.class), @NodeChild(value = "frameSlotNode", type = FrameSlotNode.class)})
+    @NodeChild(value = "enclosingFrame", type = AccessEnclosingFrameNode.class)
+    @NodeChild(value = "frameSlotNode", type = FrameSlotNode.class)
     protected abstract static class ResolvedWriteSuperFrameVariableNode extends WriteSuperFrameVariableNode {
 
         private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile();
@@ -72,7 +74,8 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
 
         private final Mode mode;
 
-        public ResolvedWriteSuperFrameVariableNode(Mode mode) {
+        public ResolvedWriteSuperFrameVariableNode(Object name, Mode mode) {
+            super(name);
             this.mode = mode;
         }
 
@@ -105,18 +108,12 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
 
         @Child private RNode rhs;
 
-        private final String name;
         private final Mode mode;
 
-        UnresolvedWriteSuperFrameVariableNode(String name, RNode rhs, Mode mode) {
-            this.rhs = rhs;
-            this.name = name;
+        UnresolvedWriteSuperFrameVariableNode(Object name, Mode mode, RNode rhs) {
+            super(name);
             this.mode = mode;
-        }
-
-        @Override
-        public String getName() {
-            return name;
+            this.rhs = rhs;
         }
 
         @Override
@@ -127,9 +124,6 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
         @Override
         public void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            if (name.isEmpty()) {
-                throw RError.error(RError.NO_CALLER, RError.Message.ZERO_LENGTH_VARIABLE);
-            }
             final WriteSuperFrameVariableNode writeNode;
             if (REnvironment.isGlobalEnvFrame(enclosingFrame)) {
                 /*
@@ -137,11 +131,11 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
                  * in the chain, needs the rhs and enclosingFrame nodes
                  */
                 AccessEnclosingFrameNode enclosingFrameNode = RArguments.getEnclosingFrame(frame) == enclosingFrame ? new AccessEnclosingFrameNode() : null;
-                writeNode = ResolvedWriteSuperFrameVariableNodeGen.create(mode, rhs, enclosingFrameNode,
-                                FrameSlotNode.create(findOrAddFrameSlot(enclosingFrame.getFrameDescriptor(), name, FrameSlotKind.Illegal)), name);
+                writeNode = ResolvedWriteSuperFrameVariableNodeGen.create(getName(), mode, rhs, enclosingFrameNode,
+                                FrameSlotNode.create(findOrAddFrameSlot(enclosingFrame.getFrameDescriptor(), getName(), FrameSlotKind.Illegal)));
             } else {
-                ResolvedWriteSuperFrameVariableNode actualWriteNode = ResolvedWriteSuperFrameVariableNodeGen.create(mode, null, null, FrameSlotNode.create(name), name);
-                writeNode = new WriteSuperFrameVariableConditionalNode(actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(name, null, mode), rhs);
+                ResolvedWriteSuperFrameVariableNode actualWriteNode = ResolvedWriteSuperFrameVariableNodeGen.create(getName(), mode, null, null, FrameSlotNode.createTemp(getName(), false));
+                writeNode = new WriteSuperFrameVariableConditionalNode(getName(), actualWriteNode, new UnresolvedWriteSuperFrameVariableNode(getName(), mode, null), rhs);
             }
             replace(writeNode).execute(frame, value, enclosingFrame);
         }
@@ -154,7 +148,7 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
                 execute(frame, value, enclosingFrame);
             } else {
                 // we're in global scope, do a local write instead
-                replace(UnresolvedWriteLocalFrameVariableNodeGen.create(rhs, name, mode)).execute(frame, value);
+                replace(WriteLocalFrameVariableNode.create(getName(), mode, rhs)).execute(frame, value);
             }
         }
     }
@@ -169,17 +163,13 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode {
         private final ConditionProfile hasValueProfile = ConditionProfile.createBinaryProfile();
         private final ConditionProfile nullSuperFrameProfile = ConditionProfile.createBinaryProfile();
 
-        WriteSuperFrameVariableConditionalNode(ResolvedWriteSuperFrameVariableNode writeNode, WriteSuperFrameVariableNode nextNode, RNode rhs) {
+        WriteSuperFrameVariableConditionalNode(Object name, ResolvedWriteSuperFrameVariableNode writeNode, WriteSuperFrameVariableNode nextNode, RNode rhs) {
+            super(name);
             this.writeNode = writeNode;
             this.nextNode = nextNode;
             this.rhs = rhs;
         }
 
-        @Override
-        public Object getName() {
-            return writeNode.getName();
-        }
-
         @Override
         public RNode getRhs() {
             return rhs;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNodeHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNodeHelper.java
deleted file mode 100644
index 29e9f0bdcc..0000000000
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNodeHelper.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.r.nodes.access;
-
-import com.oracle.truffle.api.frame.MaterializedFrame;
-import com.oracle.truffle.api.frame.VirtualFrame;
-
-/**
- * Helper class for the WriteSuperFrame variants. This ought to be a static class in
- * {@link WriteSuperFrameVariableNode} but that causes compilation problems.
- */
-abstract class WriteSuperFrameVariableNodeHelper extends BaseWriteVariableNode {
-
-    public abstract void execute(VirtualFrame frame, Object value, MaterializedFrame enclosingFrame);
-
-    @Override
-    public final Object execute(VirtualFrame frame) {
-        Object value = getRhs().execute(frame);
-        execute(frame, value);
-        return value;
-    }
-}
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
index d8bd5afed8..9416b60d27 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,15 @@ public abstract class WriteVariableNode extends RNode {
         INVISIBLE
     }
 
-    public abstract Object getName();
+    private final Object name;
+
+    protected WriteVariableNode(Object name) {
+        this.name = name;
+    }
+
+    public final Object getName() {
+        return name;
+    }
 
     public abstract RNode getRhs();
 
@@ -54,27 +62,27 @@ public abstract class WriteVariableNode extends RNode {
      */
     public static WriteVariableNode createArgSave(String name, RNode rhs) {
         if (FastROptions.InvisibleArgs.getBooleanValue()) {
-            return WriteLocalFrameVariableNode.create(name, rhs, Mode.INVISIBLE);
+            return WriteLocalFrameVariableNode.create(name, Mode.INVISIBLE, rhs);
         } else {
-            return WriteLocalFrameVariableNode.create(name, rhs, Mode.REGULAR);
+            return WriteLocalFrameVariableNode.create(name, Mode.REGULAR, rhs);
         }
     }
 
     /**
      * Variant for anonymous variables in the current frame.
      */
-    public static WriteVariableNode createAnonymous(String name, RNode rhs, Mode mode) {
-        return WriteLocalFrameVariableNode.create(name, rhs, mode);
+    public static WriteVariableNode createAnonymous(String name, Mode mode, RNode rhs) {
+        return WriteLocalFrameVariableNode.create(name, mode, rhs);
     }
 
     /**
      * Variant for anonymous variables in either the current or a super frame..
      */
-    public static WriteVariableNode createAnonymous(String name, RNode rhs, Mode mode, boolean isSuper) {
+    public static WriteVariableNode createAnonymous(String name, Mode mode, RNode rhs, boolean isSuper) {
         if (isSuper) {
-            return WriteSuperFrameVariableNode.create(name, rhs, mode);
+            return WriteSuperFrameVariableNode.create(name, mode, rhs);
         } else {
-            return WriteLocalFrameVariableNode.create(name, rhs, mode);
+            return WriteLocalFrameVariableNode.create(name, mode, rhs);
         }
     }
 }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java
index 2840ed66f3..3954247291 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteVariableSyntaxNode.java
@@ -27,18 +27,19 @@ import static com.oracle.truffle.api.nodes.NodeCost.NONE;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.NodeInfo;
+import com.oracle.truffle.api.nodes.UnexpectedResultException;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode;
 import com.oracle.truffle.r.nodes.control.OperatorNode;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
-import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.nodes.RNode;
-import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxElement;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 
+/**
+ * This node represents a write to a variable on the syntax level, i.e., in the R source code.
+ */
 @NodeInfo(cost = NONE)
 public final class WriteVariableSyntaxNode extends OperatorNode {
 
@@ -47,25 +48,10 @@ public final class WriteVariableSyntaxNode extends OperatorNode {
 
     private final RSyntaxElement lhs;
 
-    public WriteVariableSyntaxNode(SourceSection source, RSyntaxLookup operator, RSyntaxElement lhs, RNode rhs, boolean isSuper) {
+    public WriteVariableSyntaxNode(SourceSection source, RSyntaxLookup operator, RSyntaxElement lhs, String name, RNode rhs, boolean isSuper) {
         super(source, operator);
         this.lhs = lhs;
-        String name;
-        if (lhs instanceof RSyntaxLookup) {
-            name = ((RSyntaxLookup) lhs).getIdentifier();
-        } else if (lhs instanceof RSyntaxConstant) {
-            RSyntaxConstant c = (RSyntaxConstant) lhs;
-            if (c.getValue() instanceof String) {
-                name = (String) c.getValue();
-            } else {
-                // "this" needs to be initialized for error reporting to work
-                this.write = WriteVariableNode.createAnonymous("dummy", rhs, Mode.REGULAR, isSuper);
-                throw RError.error(this, RError.Message.INVALID_LHS, "do_set");
-            }
-        } else {
-            throw RInternalError.unimplemented("unexpected lhs type in replacement: " + lhs.getClass());
-        }
-        this.write = WriteVariableNode.createAnonymous(name, rhs, Mode.REGULAR, isSuper);
+        this.write = WriteVariableNode.createAnonymous(name, Mode.REGULAR, rhs, isSuper);
         assert write != null;
     }
 
@@ -79,6 +65,21 @@ public final class WriteVariableSyntaxNode extends OperatorNode {
         return write.execute(frame);
     }
 
+    @Override
+    public int executeInteger(VirtualFrame frame) throws UnexpectedResultException {
+        return write.executeInteger(frame);
+    }
+
+    @Override
+    public double executeDouble(VirtualFrame frame) throws UnexpectedResultException {
+        return write.executeDouble(frame);
+    }
+
+    @Override
+    public byte executeByte(VirtualFrame frame) throws UnexpectedResultException {
+        return write.executeByte(frame);
+    }
+
     @Override
     public Object visibleExecute(VirtualFrame frame) {
         Object result = write.execute(frame);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNode.java
index bccc9d44c5..36f9c1ca75 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
index c8825078e7..d50558d620 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ForNode.java
@@ -62,9 +62,9 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn
         String rangeName = AnonymousFrameVariable.create("FOR_RANGE");
         String lengthName = AnonymousFrameVariable.create("FOR_LENGTH");
 
-        this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, null, Mode.REGULAR);
-        this.writeRangeNode = WriteVariableNode.createAnonymous(rangeName, range, Mode.REGULAR);
-        this.writeLengthNode = WriteVariableNode.createAnonymous(lengthName, RLengthNodeGen.create(ReadVariableNode.create(rangeName)), Mode.REGULAR);
+        this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, Mode.REGULAR, null);
+        this.writeRangeNode = WriteVariableNode.createAnonymous(rangeName, Mode.REGULAR, range);
+        this.writeLengthNode = WriteVariableNode.createAnonymous(lengthName, Mode.REGULAR, RLengthNodeGen.create(ReadVariableNode.create(rangeName)));
         this.loopNode = Truffle.getRuntime().createLoopNode(new ForRepeatingNode(this, var.getIdentifier(), body, indexName, lengthName, rangeName));
     }
 
@@ -96,12 +96,12 @@ public final class ForNode extends AbstractLoopNode implements RSyntaxNode, RSyn
 
         ForRepeatingNode(ForNode forNode, String var, RNode body, String indexName, String lengthName, String rangeName) {
             this.forNode = forNode;
-            this.writeElementNode = WriteVariableNode.createAnonymous(var, createIndexedLoad(indexName, rangeName), Mode.REGULAR, false);
+            this.writeElementNode = WriteVariableNode.createAnonymous(var, Mode.REGULAR, createIndexedLoad(indexName, rangeName), false);
             this.body = body;
 
             this.readIndexNode = ReadVariableNode.create(indexName);
             this.readLengthNode = ReadVariableNode.create(lengthName);
-            this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, null, Mode.REGULAR);
+            this.writeIndexNode = WriteVariableNode.createAnonymous(indexName, Mode.REGULAR, null);
             // pre-initialize the profile so that loop exits to not deoptimize
             conditionProfile.profile(false);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
index ffd2040d06..4be2260ed9 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java
@@ -37,6 +37,7 @@ import com.oracle.truffle.r.nodes.access.WriteVariableSyntaxNode;
 import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.nodes.RNode;
@@ -91,14 +92,36 @@ public final class ReplacementDispatchNode extends OperatorNode {
 
     public RNode create(boolean isVoid) {
         RNode replacement;
-        if (lhs.asRSyntaxNode() instanceof RSyntaxCall) {
+        RSyntaxNode lhsSyntax = lhs.asRSyntaxNode();
+        if (lhsSyntax instanceof RSyntaxCall) {
             replacement = createReplacementNode(isVoid);
         } else {
-            replacement = new WriteVariableSyntaxNode(getLazySourceSection(), operator, lhs.asRSyntaxNode(), rhs, isSuper);
+            replacement = createWriteVariableNode(lhsSyntax);
         }
         return replace(replacement);
     }
 
+    private RNode createWriteVariableNode(RSyntaxNode lhsSyntax) {
+        String name;
+        if (lhsSyntax instanceof RSyntaxLookup) {
+            name = ((RSyntaxLookup) lhsSyntax).getIdentifier();
+        } else if (lhsSyntax instanceof RSyntaxConstant) {
+            RSyntaxConstant c = (RSyntaxConstant) lhsSyntax;
+            if (c.getValue() instanceof String) {
+                name = (String) c.getValue();
+            } else {
+                // "this" needs to be initialized for error reporting to work
+                throw RError.error(this, RError.Message.INVALID_LHS, "do_set");
+            }
+        } else {
+            throw RInternalError.unimplemented("unexpected lhs type in replacement: " + lhsSyntax.getClass());
+        }
+        if (name.isEmpty()) {
+            throw RError.error(RError.NO_CALLER, RError.Message.ZERO_LENGTH_VARIABLE);
+        }
+        return new WriteVariableSyntaxNode(getLazySourceSection(), operator, lhsSyntax, name, rhs, isSuper);
+    }
+
     @Override
     public ArgumentsSignature getSyntaxSignature() {
         return ArgumentsSignature.empty(2);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
index 8fea392249..5986bdbb7b 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -174,7 +174,7 @@ abstract class ReplacementNode extends OperatorNode {
             super(source, operator, lhs);
             this.rhs = rhs;
 
-            this.storeRhs = WriteVariableNode.createAnonymous("*rhs*" + tempNamesStartIndex, rhs, WriteVariableNode.Mode.INVISIBLE);
+            this.storeRhs = WriteVariableNode.createAnonymous("*rhs*" + tempNamesStartIndex, WriteVariableNode.Mode.INVISIBLE, rhs);
             this.removeRhs = RemoveAndAnswerNode.create("*rhs*" + tempNamesStartIndex);
         }
 
@@ -368,7 +368,7 @@ abstract class ReplacementNode extends OperatorNode {
             for (int i = calls.size() - 1, tmpIndex = 0; i >= 1; i--, tmpIndex++) {
                 ReadVariableNode newFirstArg = ReadVariableNode.create("*tmp*" + (tempNamesStartIndex + tmpIndex));
                 RNode update = createSpecialFunctionQuery(calls.get(i), newFirstArg, codeBuilderContext);
-                instructions.add(WriteVariableNode.createAnonymous("*tmp*" + (tempNamesStartIndex + tmpIndex + 1), update, WriteVariableNode.Mode.INVISIBLE));
+                instructions.add(WriteVariableNode.createAnonymous("*tmp*" + (tempNamesStartIndex + tmpIndex + 1), WriteVariableNode.Mode.INVISIBLE, update));
             }
             /*
              * Create the update calls, for "a(b(x)) <- z", this would be `a<-` and `b<-`, the
@@ -379,14 +379,14 @@ abstract class ReplacementNode extends OperatorNode {
                 String tmprName = i == 0 ? ("*rhs*" + tempNamesStartIndex) : ("*tmpr*" + (tempNamesStartIndex + i - 1));
                 RNode update = createFunctionUpdate(source, ReadVariableNode.create("*tmp*" + tmpIndex), ReadVariableNode.create(tmprName), calls.get(i), codeBuilderContext);
                 if (i < calls.size() - 1) {
-                    instructions.add(WriteVariableNode.createAnonymous("*tmpr*" + (tempNamesStartIndex + i), update, WriteVariableNode.Mode.INVISIBLE));
+                    instructions.add(WriteVariableNode.createAnonymous("*tmpr*" + (tempNamesStartIndex + i), WriteVariableNode.Mode.INVISIBLE, update));
                 } else {
-                    instructions.add(WriteVariableNode.createAnonymous(targetVarName, update, WriteVariableNode.Mode.REGULAR, isSuper));
+                    instructions.add(WriteVariableNode.createAnonymous(targetVarName, WriteVariableNode.Mode.REGULAR, update, isSuper));
                 }
             }
 
             this.updates = instructions.toArray(new RNode[instructions.size()]);
-            this.targetTmpWrite = WriteVariableNode.createAnonymous(getTargetTmpName(tempNamesStartIndex), target, WriteVariableNode.Mode.INVISIBLE);
+            this.targetTmpWrite = WriteVariableNode.createAnonymous(getTargetTmpName(tempNamesStartIndex), WriteVariableNode.Mode.INVISIBLE, target);
             this.targetTmpRemove = RemoveAndAnswerNode.create(getTargetTmpName(tempNamesStartIndex));
         }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
index 748dd665f7..449eabf4bd 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java
@@ -51,10 +51,10 @@ abstract class LoadMethod extends RBaseNode {
     @Child private GetFixedAttributeNode definedAttrAccess = GetFixedAttributeNode.create(RRuntime.R_DEFINED);
     @Child private GetFixedAttributeNode nextMethodAttrAccess = GetFixedAttributeNode.create(RRuntime.R_NEXT_METHOD);
     @Child private GetFixedAttributeNode sourceAttrAccess = GetFixedAttributeNode.create(RRuntime.R_SOURCE);
-    @Child private WriteLocalFrameVariableNode writeRTarget = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_TARGET, null, WriteVariableNode.Mode.REGULAR);
-    @Child private WriteLocalFrameVariableNode writeRDefined = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_DEFINED, null, WriteVariableNode.Mode.REGULAR);
-    @Child private WriteLocalFrameVariableNode writeRNextMethod = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_NEXT_METHOD, null, WriteVariableNode.Mode.REGULAR);
-    @Child private WriteLocalFrameVariableNode writeRMethod = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_METHOD, null, WriteVariableNode.Mode.REGULAR);
+    @Child private WriteLocalFrameVariableNode writeRTarget = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_TARGET, WriteVariableNode.Mode.REGULAR, null);
+    @Child private WriteLocalFrameVariableNode writeRDefined = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_DEFINED, WriteVariableNode.Mode.REGULAR, null);
+    @Child private WriteLocalFrameVariableNode writeRNextMethod = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_NEXT_METHOD, WriteVariableNode.Mode.REGULAR, null);
+    @Child private WriteLocalFrameVariableNode writeRMethod = WriteLocalFrameVariableNode.create(RRuntime.R_DOT_METHOD, WriteVariableNode.Mode.REGULAR, null);
     @Child private LocalReadVariableNode methodsEnvRead = LocalReadVariableNode.create("methods", true);
     @Child private ReadVariableNode loadMethodFind;
     @Child private CallRFunctionNode loadMethodCall;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
index ff0088f66c..f645d23f52 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
index df64052e58..9a4fe5e046 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ConvertBooleanNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
-- 
GitLab