From 144cc1521a587a9ee99876db464ddb8d6f6da986 Mon Sep 17 00:00:00 2001
From: Tomas Stupka <tomas.stupka@oracle.com>
Date: Wed, 4 Oct 2017 20:20:33 +0200
Subject: [PATCH] added Rf_lock/Rf_unLockBinding upcalls

---
 .../ffi/impl/common/JavaUpCallsRFFIImpl.java  | 10 +++
 .../truffle/r/ffi/impl/nodes/EnvNodes.java    | 80 +++++++++++++++++++
 .../r/ffi/impl/upcalls/StdUpCallsRFFI.java    |  8 ++
 .../Rinternals_truffle_common.h               | 14 ++--
 4 files changed, 106 insertions(+), 6 deletions(-)
 create mode 100644 com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index e60d227d77..79b8172bce 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -748,6 +748,16 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         return ((REnvironment) env).bindingIsLocked(((RSymbol) sym).getName()) ? 1 : 0;
     }
 
+    @Override
+    public int R_LockBinding(Object sym, Object env) {
+        throw implementedAsNode();
+    }
+
+    @Override
+    public int R_unLockBinding(Object sym, Object env) {
+        throw implementedAsNode();
+    }
+
     @Override
     @TruffleBoundary
     public Object R_FindNamespace(Object name) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java
new file mode 100644
index 0000000000..57441100e9
--- /dev/null
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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
+ * 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.ffi.impl.nodes;
+
+import com.oracle.truffle.api.dsl.Fallback;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.dsl.TypeSystemReference;
+import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.guaranteeInstanceOf;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.RTypes;
+import com.oracle.truffle.r.runtime.env.REnvironment;
+
+public class EnvNodes {
+
+    @TypeSystemReference(RTypes.class)
+    public abstract static class LockBindingNode extends FFIUpCallNode.Arg2 {
+
+        @Specialization
+        Object lock(RSymbol sym, REnvironment env) {
+            // TODO copied from EnvFunctions.LockBinding
+            env.lockBinding(sym.getName());
+            return RNull.instance;
+        }
+
+        @Fallback
+        Object lock(Object sym, Object env) {
+            guaranteeInstanceOf(sym, RSymbol.class);
+            guaranteeInstanceOf(env, REnvironment.class);
+            throw RInternalError.shouldNotReachHere();
+        }
+
+        public static LockBindingNode create() {
+            return EnvNodesFactory.LockBindingNodeGen.create();
+        }
+    }
+
+    @TypeSystemReference(RTypes.class)
+    public abstract static class UnlockBindingNode extends FFIUpCallNode.Arg2 {
+
+        @Specialization
+        Object unlock(RSymbol sym, REnvironment env) {
+            // TODO copied from EnvFunctions.LockBinding
+            env.unlockBinding(sym.getName());
+            return RNull.instance;
+        }
+
+        @Fallback
+        Object unlock(Object sym, Object env) {
+            guaranteeInstanceOf(sym, RSymbol.class);
+            guaranteeInstanceOf(env, REnvironment.class);
+            throw RInternalError.shouldNotReachHere();
+        }
+
+        public static UnlockBindingNode create() {
+            return EnvNodesFactory.UnlockBindingNodeGen.create();
+        }
+    }
+}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
index 84f515f076..26c9a460b1 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
@@ -32,6 +32,8 @@ import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.TAG;
 import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.CoerceVectorNode;
 import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.VectorToPairListNode;
 import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes;
+import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.LockBindingNode;
+import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.UnlockBindingNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CARNode;
@@ -226,6 +228,12 @@ public interface StdUpCallsRFFI {
 
     int R_BindingIsLocked(Object sym, Object env);
 
+    @RFFIUpCallNode(LockBindingNode.class)
+    int R_LockBinding(Object sym, Object env);
+
+    @RFFIUpCallNode(UnlockBindingNode.class)
+    int R_unLockBinding(Object sym, Object env);
+
     Object R_FindNamespace(Object name);
 
     @RFFIRunGC
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
index 2c608e5e66..699f70c482 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
@@ -1170,7 +1170,7 @@ int NAMED(SEXP x) {
     TRACE0();
     int result = (int) ((call_NAMED) callbacks[NAMED_x])(x);
     checkExitCall();
-    return result;;
+    return result;
 }
 
 int REFCNT(SEXP x) {
@@ -1233,7 +1233,7 @@ int IS_S4_OBJECT(SEXP x) {
     TRACE0();
     int result = (int) ((call_IS_S4_OBJECT) callbacks[IS_S4_OBJECT_x])(x);
     checkExitCall();
-    return result;;
+    return result;
 }
 
 void SET_S4_OBJECT(SEXP x) {
@@ -1307,12 +1307,14 @@ Rboolean R_EnvironmentIsLocked(SEXP env) {
 
 void R_LockBinding(SEXP sym, SEXP env) {
     TRACE0();
-    unimplemented("R_LockBinding");
+    ((call_R_LockBinding) callbacks[R_LockBinding_x])(sym, env);
+    checkExitCall();
 }
 
 void R_unLockBinding(SEXP sym, SEXP env) {
     TRACE0();
-    unimplemented("R_unLockBinding");
+    ((call_R_unLockBinding) callbacks[R_unLockBinding_x])(sym, env);
+    checkExitCall();
 }
 
 void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env) {
@@ -1324,7 +1326,7 @@ Rboolean R_BindingIsLocked(SEXP sym, SEXP env) {
     TRACE0();
     Rboolean result = (Rboolean) ((call_R_BindingIsLocked) callbacks[R_BindingIsLocked_x])(sym, env);
     checkExitCall();
-    return result;;
+    return result;
 }
 
 Rboolean R_BindingIsActive(SEXP sym, SEXP env) {
@@ -1567,7 +1569,7 @@ Rboolean R_compute_identical(SEXP x, SEXP y, int flags) {
     TRACE0();
     Rboolean result = (Rboolean) ((call_R_compute_identical) callbacks[R_compute_identical_x])(x, y, flags);
     checkExitCall();
-    return result;;
+    return result;
 }
 
 void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) {
-- 
GitLab