From 6e813bd0c0072f27b5aa68ecf54a3ccf28888db8 Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Wed, 22 Jun 2016 14:33:47 -0700
Subject: [PATCH] rffi: fixes for findVar and friends (argument ordering)

---
 .../fficall/src/jni/Rinternals.c              | 16 +++++++-----
 .../r/runtime/ffi/jnr/CallRFFIHelper.java     | 25 +++++++++++++------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
index 344dcd7bc8..5d5cf9f4d1 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
@@ -40,6 +40,7 @@ static jmethodID Rf_findfunMethodID;
 static jmethodID Rf_defineVarMethodID;
 static jmethodID Rf_findVarMethodID;
 static jmethodID Rf_findVarInFrameMethodID;
+static jmethodID Rf_findVarInFrame3MethodID;
 static jmethodID Rf_getAttribMethodID;
 static jmethodID Rf_setAttribMethodID;
 static jmethodID Rf_isStringMethodID;
@@ -128,6 +129,7 @@ void init_internals(JNIEnv *env) {
 	Rf_defineVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_defineVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1);
 	Rf_findVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVar", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
 	Rf_findVarInFrameMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVarInFrame", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
+	Rf_findVarInFrame3MethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVarInFrame3", "(Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;", 1);
 	Rf_getAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_getAttrib", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
 	Rf_setAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_setAttrib", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1);
 	Rf_isStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_isString", "(Ljava/lang/Object;)I", 1);
@@ -322,20 +324,22 @@ SEXP Rf_findFun(SEXP symbol, SEXP rho) {
 	return checkRef(thisenv, result);
 }
 
-SEXP Rf_findVar(SEXP symbol, SEXP rho) {
+SEXP Rf_findVar(SEXP sym, SEXP rho) {
 	JNIEnv *thisenv = getEnv();
-	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarMethodID, symbol, rho);
+	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarMethodID, sym, rho);
     return checkRef(thisenv, result);
 }
 
-SEXP Rf_findVarInFrame(SEXP symbol, SEXP rho) {
+SEXP Rf_findVarInFrame(SEXP rho, SEXP sym) {
 	JNIEnv *thisenv = getEnv();
-	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarInFrameMethodID, symbol, rho);
+	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarInFrameMethodID, rho, sym);
     return checkRef(thisenv, result);
 }
 
-SEXP Rf_findVarInFrame3(SEXP symbol, SEXP rho, Rboolean b) {
-	return unimplemented("Rf_findVarInFrame3");
+SEXP Rf_findVarInFrame3(SEXP rho, SEXP sym, Rboolean b) {
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarInFrame3MethodID, rho, sym, b);
+    return checkRef(thisenv, result);
 }
 
 SEXP Rf_getAttrib(SEXP vec, SEXP name) {
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java
index 901969f1ef..976b619929 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java
@@ -245,16 +245,24 @@ public class CallRFFIHelper {
     }
 
     public static Object Rf_findVar(Object symbolArg, Object envArg) {
+        // WARNING: argument order reversed from Rf_findVarInFrame!
         RFFIUtils.traceUpCall("Rf_findVar", symbolArg, envArg);
-        return findVarInFrameHelper(symbolArg, envArg, true);
+        return findVarInFrameHelper(envArg, symbolArg, true);
     }
 
-    public static Object Rf_findVarInFrame(Object symbolArg, Object envArg) {
-        RFFIUtils.traceUpCall("Rf_findVarInFrame", symbolArg, envArg);
-        return findVarInFrameHelper(symbolArg, envArg, false);
+    public static Object Rf_findVarInFrame(Object envArg, Object symbolArg) {
+        RFFIUtils.traceUpCall("Rf_findVarInFrame", envArg, symbolArg);
+        return findVarInFrameHelper(envArg, symbolArg, false);
     }
 
-    private static Object findVarInFrameHelper(Object symbolArg, Object envArg, boolean inherits) {
+    public static Object Rf_findVarInFrame3(Object envArg, Object symbolArg, @SuppressWarnings("unused") int doGet) {
+        // GNU R has code for IS_USER_DATBASE that uses doGet
+        // This is a lookup in the single environment (envArg) only, i.e. inherits=false
+        RFFIUtils.traceUpCall("Rf_findVarInFrame3", envArg, symbolArg);
+        return findVarInFrameHelper(envArg, symbolArg, false);
+    }
+
+    private static Object findVarInFrameHelper(Object envArg, Object symbolArg, boolean inherits) {
         if (envArg == RNull.instance) {
             throw RError.error(RError.SHOW_CALLER2, RError.Message.USE_NULL_ENV_DEFUNCT);
         }
@@ -269,6 +277,7 @@ public class CallRFFIHelper {
                 return value;
             }
             if (!inherits) {
+                // simgle frame lookup
                 break;
             }
             env = env.getParent();
@@ -854,8 +863,10 @@ public class CallRFFIHelper {
     public static Object ENCLOS(Object x) {
         RFFIUtils.traceUpCall("ENCLOS", x);
         REnvironment env = guaranteeInstanceOf(x, REnvironment.class);
-        REnvironment result = env.getParent();
-        assert result != null;
+        Object result = env.getParent();
+        if (result == null) {
+            result = RNull.instance;
+        }
         return result;
     }
 
-- 
GitLab