From ed1766126a9d4f3cdf60627a773677a7b29edea0 Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Wed, 15 Jun 2016 17:39:59 -0700
Subject: [PATCH] propagate interactive state to native code

---
 .../fficall/src/jni/rfficall.c                    |  8 ++++++++
 .../fficall/src/variable_defs/variable_defs.h     |  4 +++-
 .../truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java   | 15 +++++++++++++++
 .../truffle/r/runtime/context/RContext.java       |  2 ++
 .../oracle/truffle/r/runtime/ffi/CallRFFI.java    |  5 +++++
 .../com/oracle/truffle/r/runtime/ffi/RFFI.java    |  2 +-
 .../packages/testrffi/testrffi/R/testrffi.R       |  4 ++++
 .../packages/testrffi/testrffi/src/testrffi.c     |  6 ++++++
 8 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c b/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c
index 58108f865e..8a20c51ac7 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/rfficall.c
@@ -1233,5 +1233,13 @@ Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_callVoid0(JNIEnv *env, j
 	callExit(env);
 }
 
+#include <Rinterface.h>
+
+JNIEXPORT void JNICALL
+Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_nativeSetInteractive(JNIEnv *env, jclass c, jboolean interactive) {
+	R_Interactive = interactive;
+}
+
+
 
 
diff --git a/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h b/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
index 7222c83482..fadaf488b8 100644
--- a/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
+++ b/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
@@ -80,9 +80,11 @@ int R_NaInt;	/* NA_INTEGER:= INT_MIN currently */
 const char* R_Home;
 const char* R_TempDir;
 
+// Set by a down call based on the setting in the initial context
+Rboolean R_Interactive;
+
 // various ignored flags and variables:
 Rboolean R_Visible;
-Rboolean R_Interactive;
 Rboolean R_interrupts_suspended;
 int R_interrupts_pending;
 Rboolean mbcslocale;
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
index ea66b457f6..83957a8d90 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java
@@ -104,6 +104,8 @@ public class JNI_CallRFFI implements CallRFFI {
 
     private static native void nativeSetTempDir(String tempDir);
 
+    private static native void nativeSetInteractive(boolean interactive);
+
     private static native Object call(long address, Object[] args);
 
     private static native Object call0(long address);
@@ -163,4 +165,17 @@ public class JNI_CallRFFI implements CallRFFI {
             inCritical.release();
         }
     }
+
+    @Override
+    public void setInteractive(boolean interactive) {
+        traceCall("setInteractive", interactive);
+        try {
+            inCritical.acquire();
+            nativeSetInteractive(interactive);
+        } catch (InterruptedException ex) {
+        } finally {
+            inCritical.release();
+        }
+    }
+
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
index 76441461f4..1e1cf27e2e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java
@@ -71,6 +71,7 @@ import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.ffi.RFFIContextStateFactory;
+import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 import com.oracle.truffle.r.runtime.instrument.TraceState;
 import com.oracle.truffle.r.runtime.nodes.RCodeBuilder;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
@@ -458,6 +459,7 @@ public final class RContext extends ExecutionContext implements TruffleObject {
             this.methodTableDispatchOn = info.getParent().methodTableDispatchOn;
         }
         if (isInitial && !embedded) {
+            RFFIFactory.getRFFI().getCallRFFI().setInteractive(isInteractive());
             initialContextInitialized = true;
         }
     }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
index 57aaccd52d..16a4eda25d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
@@ -47,4 +47,9 @@ public interface CallRFFI {
      * call sets the value.
      */
     void setTempDir(String tempDir);
+
+    /**
+     * Sets the {@code R_Interactive} FFI variable. Similar rationale to {#link setTmpDir}.
+     */
+    void setInteractive(boolean interactive);
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java
index 026359014b..841567fef0 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
index 0505d52341..727ab1f385 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R
@@ -45,3 +45,7 @@ rffi.isRString <- function(s) {
 rffi.invoke12 <- function() {
 	.Call("invoke12", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, PACKAGE = "testrffi")
 }
+
+rffi.interactive <- function() {
+	.Call("interactive", PACKAGE = "testrffi");
+}
diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
index 25fe335681..ec033b4875 100644
--- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
+++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c
@@ -26,6 +26,7 @@
 #include <R.h>
 #include <Rdefines.h>
 #include <Rinternals.h>
+#include <Rinterface.h>
 
 void dotCModifiedArguments(int* len, int* idata, double* rdata, int* ldata) {
     for (int i = 0; i < len[0]; i++) {
@@ -134,3 +135,8 @@ SEXP invoke_isString(SEXP s) {
 SEXP invoke12(SEXP a1, SEXP a2, SEXP a3, SEXP a4, SEXP a5, SEXP a6, SEXP a7, SEXP a8, SEXP a9, SEXP a10, SEXP a11, SEXP a12) {
 	return a12;
 }
+
+SEXP interactive(void) {
+	return ScalarLogical(R_Interactive);
+}
+
-- 
GitLab