From 26d90709d9f6010cc4959f033c890e9b81e4fe2f Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Wed, 15 Nov 2017 17:43:20 +0100
Subject: [PATCH] Added missing guard.

---
 .../truffle/r/nodes/builtin/base/Slot.java    | 35 ++++++++++++-------
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
index e58454418a..b1055e6c04 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Slot.java
@@ -17,8 +17,8 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.foreign;
 import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
 import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
 
-import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.interop.TruffleObject;
@@ -44,6 +44,11 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 @RBuiltin(name = "@", kind = PRIMITIVE, parameterNames = {"", ""}, nonEvalArgs = 1, behavior = COMPLEX)
 public abstract class Slot extends RBuiltinNode.Arg2 {
 
+    private static final int UNINITIALIZED = 0;
+    private static final int IS_LHS = 1;
+    private static final int IS_NOT_LHS = 2;
+
+    @CompilationFinal private int isLhsState = UNINITIALIZED;
     @Child private UpdateShareableChildValueNode sharedAttrUpdate = UpdateShareableChildValueNode.create();
     @Child private AccessSlotNode accessSlotNode = AccessSlotNodeGen.create(true);
 
@@ -71,24 +76,28 @@ public abstract class Slot extends RBuiltinNode.Arg2 {
         return unwrapParent instanceof RSyntaxCall && ((RSyntaxCall) unwrapParent).getSyntaxLHS() == n;
     }
 
-    protected boolean isForeignObject(Object obj) {
-        return RRuntime.isForeignObject(obj);
+    private boolean isLhsOfCall() {
+        if (isLhsState == UNINITIALIZED) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            Node unwrapParent = RASTUtils.unwrapParent(this);
+            assert ((BuiltinCallNode) unwrapParent).getBuiltin() == this;
+            if (unwrapParent instanceof BuiltinCallNode && isLhsOfSyntaxCall(((RBaseNode) unwrapParent).asRSyntaxNode())) {
+                isLhsState = IS_LHS;
+            } else {
+                isLhsState = IS_NOT_LHS;
+            }
+        }
+        return isLhsState == IS_LHS;
     }
 
-    protected boolean isLhsOfCall() {
-        CompilerAsserts.neverPartOfCompilation();
-        Node unwrapParent = RASTUtils.unwrapParent(this);
-        assert ((BuiltinCallNode) unwrapParent).getBuiltin() == this;
-        return unwrapParent instanceof BuiltinCallNode && isLhsOfSyntaxCall(((RBaseNode) unwrapParent).asRSyntaxNode());
+    protected boolean isLhsOfForeignCall(Object o) {
+        return RRuntime.isForeignObject(o) && isLhsOfCall();
     }
 
-    @Specialization(guards = {"isForeignObject(object)", "lhsOfCall"})
+    @Specialization(guards = "isLhsOfForeignCall(object)")
     protected Object getSlot(TruffleObject object, Object nameObj,
-                    @Cached("isLhsOfCall()") boolean lhsOfCall,
                     @Cached("createClassProfile()") ValueProfile nameObjProfile) {
 
-        assert lhsOfCall;
-
         String name = getName(nameObjProfile.profile(nameObj));
         assert Utils.isInterned(name);
 
@@ -96,7 +105,7 @@ public abstract class Slot extends RBuiltinNode.Arg2 {
         return RCallNode.createDeferredMemberAccess(object, name);
     }
 
-    @Specialization
+    @Specialization(guards = "!isLhsOfForeignCall(object)")
     protected Object getSlot(Object object, Object nameObj,
                     @Cached("createClassProfile()") ValueProfile nameObjProfile) {
         String name = getName(nameObjProfile.profile(nameObj));
-- 
GitLab