From 59535ef033b32a8497190f0e37fffc2b4f90b88b Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Tue, 31 Jan 2017 17:20:23 -0800
Subject: [PATCH] rffi: rewrite all global variables to function calls

---
 .../fficall/src/include/Defn.h                |  13 +-
 .../fficall/src/jni/Makefile                  |   2 +-
 .../fficall/src/jni/variables.c               | 343 +++++++++++++++---
 .../fficall/src/variable_defs/variable_defs.h | 155 --------
 com.oracle.truffle.r.native/include/Makefile  |   8 +-
 .../include/ed_GraphicsEngine                 |   3 -
 .../include/ed_Rinterface_gcntx               |  23 --
 .../include/ed_Rinterface_variables           |  23 --
 .../include/ed_Rinternals                     | 114 ------
 .../truffle/r/runtime/ffi/RFFIVariables.java  |  10 +-
 mx.fastr/mx_fastr.py                          |   2 +
 mx.fastr/mx_fastr_edinclude.py                | 214 +++++++++++
 mx.fastr/mx_fastr_mkgramrd.py                 |   9 +-
 13 files changed, 529 insertions(+), 390 deletions(-)
 delete mode 100644 com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
 delete mode 100644 com.oracle.truffle.r.native/include/ed_GraphicsEngine
 delete mode 100644 com.oracle.truffle.r.native/include/ed_Rinterface_gcntx
 delete mode 100644 com.oracle.truffle.r.native/include/ed_Rinterface_variables
 delete mode 100644 com.oracle.truffle.r.native/include/ed_Rinternals
 create mode 100644 mx.fastr/mx_fastr_edinclude.py

diff --git a/com.oracle.truffle.r.native/fficall/src/include/Defn.h b/com.oracle.truffle.r.native/fficall/src/include/Defn.h
index c210dc30c1..b401a7c0b7 100644
--- a/com.oracle.truffle.r.native/fficall/src/include/Defn.h
+++ b/com.oracle.truffle.r.native/fficall/src/include/Defn.h
@@ -46,15 +46,18 @@ void Rf_checkArityCall(SEXP, SEXP, SEXP);
 /* ../main/devices.c, used in memory.c, gnuwin32/extra.c */
 #define R_MaxDevices 64
 
-extern SEXP R_DeviceSymbol;
-extern SEXP R_DevicesSymbol;
-extern Rboolean FASTR_Interactive();
-#define R_Interactive FASTR_Interactive()
+extern SEXP FASTR_R_DevicesSymbol();
+#define R_DevicesSymbol FASTR_R_DevicesSymbol()
+extern SEXP FASTR_R_DeviceSymbol();
+#define R_DeviceSymbol FASTR_R_DeviceSymbol()
+extern Rboolean FASTR_R_Interactive();
+#define R_Interactive FASTR_R_Interactive()
 extern Rboolean R_Visible;
 int	R_ReadConsole(const char *, unsigned char *, int, int);
 extern const char *FASTR_R_Home();
 #define R_Home FASTR_R_Home()
-extern const char *R_TempDir;
+extern const char *FASTR_R_TempDir();
+#define R_TempDir FASTR_R_TempDir()
 
 //#define HAVE_MBSTATE_T 1 // actually from config.h
 
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Makefile b/com.oracle.truffle.r.native/fficall/src/jni/Makefile
index cf8d9aea86..865ff0f99f 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Makefile
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Makefile
@@ -53,7 +53,7 @@ $(OBJ):
 	mkdir -p $(OBJ)
 
 $(OBJ)/%.o: %.c $(TOPDIR)/include/Rinternals.h $(C_HDRS)
-	$(CC) $(CFLAGS) $(INCLUDES) -I../variable_defs -c $< -o $@
+	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
 
 # for debugging, to see what's really being compiled
 $(OBJ)/%.E: %.c $(TOPDIR)/include/Rinternals.h
diff --git a/com.oracle.truffle.r.native/fficall/src/jni/variables.c b/com.oracle.truffle.r.native/fficall/src/jni/variables.c
index 54ed8a8fa7..827b2d40e8 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/variables.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/variables.c
@@ -29,7 +29,6 @@
 #include <jni.h>
 #include <Rinterface.h>
 #include <rffiutils.h>
-#include <variable_defs.h>
 
 jmethodID R_GlobalEnvMethodID;
 jmethodID R_BaseEnvMethodID;
@@ -38,23 +37,103 @@ jmethodID R_NamespaceRegistryMethodID;
 jmethodID R_InteractiveMethodID;
 jmethodID R_GlobalContextMethodID;
 
+// The variables have been rewritten as functions in Rinternals.h
+// Apart from those that are RContext specific in FastR, the rest are
+// stored here as JNI globals refs.
+
+static SEXP R_EmptyEnv_static;
+static SEXP R_Srcref_static;
+static SEXP R_NilValue_static;
+static SEXP R_UnboundValue_static;
+static SEXP R_MissingArg_static;
+static SEXP R_BaseSymbol_static;
+static SEXP R_Bracket2Symbol_static;   /* "[[" */
+static SEXP R_BracketSymbol_static;    /* "[" */
+static SEXP R_BraceSymbol_static;      /* "{" */
+static SEXP R_ClassSymbol_static;     /* "class" */
+static SEXP R_DeviceSymbol_static;     /* ".Device" */
+static SEXP R_DevicesSymbol_static;     /* ".Devices" */
+static SEXP R_DimNamesSymbol_static;   /* "dimnames" */
+static SEXP R_DimSymbol_static;     /* "dim" */
+static SEXP R_DollarSymbol_static;     /* "$" */
+static SEXP R_DotsSymbol_static;     /* "..." */
+static SEXP R_DropSymbol_static;     /* "drop" */
+static SEXP R_LastvalueSymbol_static;  /* ".Last.value" */
+static SEXP R_LevelsSymbol_static;     /* "levels" */
+static SEXP R_ModeSymbol_static;     /* "mode" */
+static SEXP R_NameSymbol_static;     /* "name" */
+static SEXP R_NamesSymbol_static;     /* "names" */
+static SEXP R_NaRmSymbol_static;     /* "na.rm" */
+static SEXP R_PackageSymbol_static;    /* "package" */
+static SEXP R_QuoteSymbol_static;     /* "quote" */
+static SEXP R_RowNamesSymbol_static;   /* "row.names" */
+static SEXP R_SeedsSymbol_static;     /* ".Random.seed" */
+static SEXP R_SourceSymbol_static;     /* "source" */
+static SEXP R_TspSymbol_static;     /* "tsp" */
+static SEXP R_dot_defined_static;      /* ".defined" */
+static SEXP R_dot_Method_static;       /* ".Method" */
+static SEXP R_dot_target_static;       /* ".target" */
+static SEXP R_NaString_static;	    /* NA_STRING as a CHARSXP */
+static SEXP R_BlankString_static;	    /* "" as a CHARSXP */
+static SEXP R_BlankScalarString_static;	    /* "" as a STRSXP */
+static SEXP	R_NamespaceEnvSymbol_static;   // ".__NAMESPACE__."
+
+// Symbols not part of public API but used in FastR tools implementation
+static SEXP R_SrcrefSymbol_static;
+static SEXP R_SrcfileSymbol_static;
+static SEXP R_RestartToken_static;
+
+// logical constants
+static SEXP R_TrueValue_static;
+static SEXP R_FalseValue_static;
+static SEXP R_LogicalNAValue_static;
+
+static const char *R_Home_static;
+static const char *R_TempDir_static;
+
+// Arith.h
+double R_NaN;		/* IEEE NaN */
+double R_PosInf;	/* IEEE Inf */
+double R_NegInf;	/* IEEE -Inf */
+double R_NaReal;	/* NA_REAL: IEEE */
+int R_NaInt;	/* NA_INTEGER:= INT_MIN currently */
+
+// various ignored flags and variables nevertheless needed to resolve symbols
+Rboolean R_Visible;
+Rboolean R_interrupts_suspended;
+int R_interrupts_pending;
+Rboolean mbcslocale;
+Rboolean useaqua;
+char* OutDec = ".";
+Rboolean utf8locale = FALSE;
+Rboolean mbcslocale = FALSE;
+Rboolean latin1locale = FALSE;
+int R_dec_min_exponent = -308;
+int max_contour_segments = 25000;
+
+// from sys-std.c
+#include <R_ext/eventloop.h>
+
+static InputHandler BasicInputHandler = {2, -1, NULL};
+InputHandler *R_InputHandlers = &BasicInputHandler;
+
 // R_GlobalEnv et al are not a variables in FASTR as they are RContext specific
-SEXP FASTR_GlobalEnv() {
+SEXP FASTR_R_GlobalEnv() {
 	JNIEnv *env = getEnv();
 	return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_GlobalEnvMethodID);
 }
 
-SEXP FASTR_BaseEnv() {
+SEXP FASTR_R_BaseEnv() {
 	JNIEnv *env = getEnv();
 	return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_BaseEnvMethodID);
 }
 
-SEXP FASTR_BaseNamespace() {
+SEXP FASTR_R_BaseNamespace() {
 	JNIEnv *env = getEnv();
 	return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_BaseNamespaceMethodID);
 }
 
-SEXP FASTR_NamespaceRegistry() {
+SEXP FASTR_R_NamespaceRegistry() {
 	JNIEnv *env = getEnv();
 	return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_NamespaceRegistryMethodID);
 }
@@ -65,27 +144,177 @@ CTXT FASTR_GlobalContext() {
     return addGlobalRef(env, res, 0);
 }
 
-static const char *R_Home_local;
-static void *R_NilValue_local;
-static void *R_UnboundValue_local;
-
 char *FASTR_R_Home() {
-	return (char *)R_Home_local;
+	return (char *) R_Home_static;
+}
+
+char *FASTR_R_TempDir() {
+	return (char *) R_TempDir_static;
 }
 
-Rboolean FASTR_Interactive() {
+Rboolean FASTR_R_Interactive() {
 	JNIEnv *env = getEnv();
 	CTXT res = (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_InteractiveMethodID);
 }
 
+SEXP FASTR_R_EmptyEnv() {
+    return R_EmptyEnv_static;
+}
+
+SEXP FASTR_R_Srcref() {
+    return R_Srcref_static;
+}
+
 SEXP FASTR_R_NilValue() {
-	return R_NilValue_local;
+    return R_NilValue_static;
 }
 
 SEXP FASTR_R_UnboundValue() {
-	return R_UnboundValue_local;
+    return R_UnboundValue_static;
+}
+
+SEXP FASTR_R_MissingArg() {
+    return R_MissingArg_static;
+}
+
+SEXP FASTR_R_BaseSymbol() {
+    return R_BaseSymbol_static;
+}
+
+
+SEXP FASTR_R_BraceSymbol() {
+    return R_BraceSymbol_static;
+}
+
+SEXP FASTR_R_Bracket2Symbol() {
+    return R_Bracket2Symbol_static;
+}
+
+SEXP FASTR_R_BracketSymbol() {
+    return R_BracketSymbol_static;
+}
+
+SEXP FASTR_R_ClassSymbol() {
+    return R_ClassSymbol_static;
+}
+
+SEXP FASTR_R_DimNamesSymbol() {
+    return R_DimNamesSymbol_static;
+}
+
+SEXP FASTR_R_DimSymbol() {
+    return R_DimSymbol_static;
+}
+
+
+SEXP FASTR_R_DollarSymbol() {
+    return R_DollarSymbol_static;
+}
+
+SEXP FASTR_R_DotsSymbol() {
+    return R_DotsSymbol_static;
+}
+
+
+SEXP FASTR_R_DropSymbol() {
+    return R_DropSymbol_static;
+}
+
+SEXP FASTR_R_LastvalueSymbol() {
+    return R_LastvalueSymbol_static;
+}
+
+
+SEXP FASTR_R_LevelsSymbol() {
+    return R_LevelsSymbol_static;
+}
+
+SEXP FASTR_R_ModeSymbol() {
+    return R_ModeSymbol_static;
+}
+
+SEXP FASTR_R_NaRmSymbol() {
+    return R_NaRmSymbol_static;
+}
+
+
+SEXP FASTR_R_NameSymbol() {
+    return R_NameSymbol_static;
+}
+
+SEXP FASTR_R_NamesSymbol() {
+    return R_NamesSymbol_static;
+}
+
+
+SEXP FASTR_R_NamespaceEnvSymbol() {
+    return R_NamespaceEnvSymbol_static;
+}
+
+SEXP FASTR_R_PackageSymbol() {
+    return R_PackageSymbol_static;
+}
+
+SEXP FASTR_R_QuoteSymbol() {
+    return R_QuoteSymbol_static;
+}
+
+SEXP FASTR_R_RowNamesSymbol() {
+    return R_RowNamesSymbol_static;
+}
+
+SEXP FASTR_R_SeedsSymbol() {
+    return R_SeedsSymbol_static;
+}
+
+SEXP FASTR_R_SourceSymbol() {
+    return R_SourceSymbol_static;
 }
 
+SEXP FASTR_R_TspSymbol() {
+    return R_TspSymbol_static;
+}
+
+SEXP FASTR_R_dot_defined() {
+    return R_dot_defined_static;
+}
+
+SEXP FASTR_R_dot_Method() {
+    return R_dot_Method_static;
+}
+
+SEXP FASTR_R_dot_target() {
+    return R_dot_target_static;
+}
+
+SEXP FASTR_R_NaString() {
+    return R_NaString_static;
+}
+
+
+SEXP FASTR_R_BlankString() {
+    return R_BlankString_static;
+}
+
+SEXP FASTR_R_BlankScalarString() {
+    return R_BlankScalarString_static;
+}
+
+SEXP FASTR_R_DevicesSymbol() {
+    return R_DevicesSymbol_static;
+}
+
+SEXP FASTR_R_DeviceSymbol() {
+    return R_DeviceSymbol_static;
+}
+
+SEXP FASTR_R_SrcrefSymbol() {
+    return R_SrcrefSymbol_static;
+}
+
+SEXP FASTR_R_SrcfileSymbol() {
+    return R_SrcfileSymbol_static;
+}
 
 void init_variables(JNIEnv *env, jobjectArray initialValues) {
 	// initialValues is an array of enums
@@ -115,7 +344,7 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 		jobject value = (*env)->CallObjectMethod(env, variable, getValueMethodID);
 		if (value != NULL) {
 			if (strcmp(nameChars, "R_Home") == 0) {
-				R_Home_local = (*env)->GetStringUTFChars(env, value, NULL);
+				R_Home_static = (*env)->GetStringUTFChars(env, value, NULL);
 			} else if (strcmp(nameChars, "R_NaN") == 0) {
 				R_NaN = (*env)->CallDoubleMethod(env, value, doubleValueMethodID);
 			} else if (strcmp(nameChars, "R_PosInf") == 0) {
@@ -127,87 +356,93 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 			} else if (strcmp(nameChars, "R_NaInt") == 0) {
 				R_NaInt = (*env)->CallIntMethod(env, value, intValueMethodID);
 			} else if (strcmp(nameChars, "R_TempDir") == 0) {
-				R_TempDir = (*env)->GetStringUTFChars(env, value, NULL);
+				R_TempDir_static = (*env)->GetStringUTFChars(env, value, NULL);
 			} else {
 				SEXP ref = createGlobalRef(env, value, 1);
 				if (strcmp(nameChars, "R_EmptyEnv") == 0) {
-					R_EmptyEnv = ref;
+					R_EmptyEnv_static = ref;
 				} else if (strcmp(nameChars, "R_NilValue") == 0) {
-					R_NilValue_local = ref;
+					R_NilValue_static = ref;
 				} else if (strcmp(nameChars, "R_UnboundValue") == 0) {
-					R_UnboundValue_local = ref;
+					R_UnboundValue_static = ref;
 				} else if (strcmp(nameChars, "R_MissingArg") == 0) {
-					R_MissingArg = ref;
+					R_MissingArg_static = ref;
+				} else if (strcmp(nameChars, "R_BaseSymbol") == 0) {
+					R_BaseSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_Bracket2Symbol") == 0) {
-					R_Bracket2Symbol = ref;
+					R_Bracket2Symbol_static = ref;
 				} else if (strcmp(nameChars, "R_BracketSymbol") == 0) {
-					R_BracketSymbol = ref;
+					R_BracketSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_BraceSymbol") == 0) {
-					R_BraceSymbol = ref;
+					R_BraceSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_ClassSymbol") == 0) {
-					R_ClassSymbol = ref;
+					R_ClassSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DeviceSymbol") == 0) {
-					R_DeviceSymbol = ref;
+					R_DeviceSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DevicesSymbol") == 0) {
-					R_DevicesSymbol = ref;
+					R_DevicesSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DimNamesSymbol") == 0) {
-					R_DimNamesSymbol = ref;
+					R_DimNamesSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DimSymbol") == 0) {
-					R_DimSymbol = ref;
+					R_DimSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DollarSymbol") == 0) {
-					R_DollarSymbol = ref;
+					R_DollarSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DotsSymbol") == 0) {
-					R_DotsSymbol = ref;
+					R_DotsSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DropSymbol") == 0) {
-					R_DropSymbol = ref;
+					R_DropSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_LastvalueSymbol") == 0) {
-					R_LastvalueSymbol = ref;
+					R_LastvalueSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_LevelsSymbol") == 0) {
-					R_LevelsSymbol = ref;
+					R_LevelsSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_ModeSymbol") == 0) {
-					R_ModeSymbol = ref;
+					R_ModeSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_NameSymbol") == 0) {
-					R_NameSymbol = ref;
+					R_NameSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_NamesSymbol") == 0) {
-					R_NamesSymbol = ref;
+					R_NamesSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_NaRmSymbol") == 0) {
-					R_NaRmSymbol = ref;
+					R_NaRmSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_PackageSymbol") == 0) {
-					R_PackageSymbol = ref;
+					R_PackageSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_QuoteSymbol") == 0) {
-					R_QuoteSymbol = ref;
+					R_QuoteSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_RowNamesSymbol") == 0) {
-					R_RowNamesSymbol = ref;
+					R_RowNamesSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_SeedsSymbol") == 0) {
-					R_SeedsSymbol = ref;
+					R_SeedsSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_SourceSymbol") == 0) {
-					R_SourceSymbol = ref;
+					R_SourceSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_TspSymbol") == 0) {
-					R_TspSymbol = ref;
+					R_TspSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_dot_defined") == 0) {
-					R_dot_defined = ref;
+					R_dot_defined_static = ref;
 				} else if (strcmp(nameChars, "R_dot_Method") == 0) {
-					R_dot_Method = ref;
+					R_dot_Method_static = ref;
 				} else if (strcmp(nameChars, "R_dot_target") == 0) {
-					R_dot_target = ref;
+					R_dot_target_static = ref;
 				} else if (strcmp(nameChars, "R_SrcfileSymbol") == 0) {
-					R_SrcfileSymbol = ref;
+					R_SrcfileSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_SrcrefSymbol") == 0) {
-					R_SrcrefSymbol = ref;
+					R_SrcrefSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DimSymbol") == 0) {
-					R_DimSymbol = ref;
+					R_DimSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_DimNamesSymbol") == 0) {
-					R_DimNamesSymbol = ref;
+					R_DimNamesSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_NaString") == 0) {
-					R_NaString = ref;
+					R_NaString_static = ref;
 				} else if (strcmp(nameChars, "R_BlankString") == 0) {
-					R_BlankString = ref;
+					R_BlankString_static = ref;
+				} else if (strcmp(nameChars, "R_BlankScalarString") == 0) {
+					R_BlankScalarString_static = ref;
+				} else if (strcmp(nameChars, "R_NamespaceEnvSymbol") == 0) {
+					R_NamespaceEnvSymbol_static = ref;
 				} else if (strcmp(nameChars, "R_TrueValue") == 0) {
-				    R_TrueValue = ref;
+				    R_TrueValue_static = ref;
 				} else if (strcmp(nameChars, "R_FalseValue") == 0) {
-				    R_FalseValue = ref;
+				    R_FalseValue_static = ref;
 				} else if (strcmp(nameChars, "R_LogicalNAValue") == 0) {
-				    R_LogicalNAValue = ref;
+				    R_LogicalNAValue_static = ref;
 				} else {
 					char msg[128];
 					strcpy(msg, "non-null R variable not assigned: ");
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
deleted file mode 100644
index b206fd4556..0000000000
--- a/com.oracle.truffle.r.native/fficall/src/variable_defs/variable_defs.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * This material is distributed under the GNU General Public License
- * Version 2. You may review the terms of this license at
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * Copyright (c) 1995-2015, The R Core Team
- * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-// These are the definitions (i.e., not extern) that are defined as extern in RInternals.h.
-// They are in a a separate header to support a JNI and non-JNI implementation of their values.
-// Therefore this file must only be included by the implementation.
-// N.B. Some variables become functions in FastR, see RInternals.h
-
-/* Evaluation Environment */
-//SEXP R_GlobalEnv;
-SEXP R_EmptyEnv;
-//SEXP R_BaseEnv;
-//SEXP R_BaseNamespace;
-//SEXP R_NamespaceRegistry;
-
-//SEXP R_Srcref;
-
-/* Special Values */
-SEXP R_NilValue;
-SEXP R_UnboundValue;
-SEXP R_MissingArg;
-
-/* Symbol Table Shortcuts */
-SEXP R_Bracket2Symbol;   /* "[[" */
-SEXP R_BracketSymbol;    /* "[" */
-SEXP R_BraceSymbol;      /* "{" */
-SEXP R_ClassSymbol;     /* "class" */
-SEXP R_DeviceSymbol;     /* ".Device" */
-SEXP R_DevicesSymbol;     /* ".Devices" */
-SEXP R_DimNamesSymbol;   /* "dimnames" */
-SEXP R_DimSymbol;     /* "dim" */
-SEXP R_DollarSymbol;     /* "$" */
-SEXP R_DotsSymbol;     /* "..." */
-SEXP R_DropSymbol;     /* "drop" */
-SEXP R_LastvalueSymbol;  /* ".Last.value" */
-SEXP R_LevelsSymbol;     /* "levels" */
-SEXP R_ModeSymbol;     /* "mode" */
-SEXP R_NameSymbol;     /* "name" */
-SEXP R_NamesSymbol;     /* "names" */
-SEXP R_NaRmSymbol;     /* "na.rm" */
-SEXP R_PackageSymbol;    /* "package" */
-SEXP R_QuoteSymbol;     /* "quote" */
-SEXP R_RowNamesSymbol;   /* "row.names" */
-SEXP R_SeedsSymbol;     /* ".Random.seed" */
-SEXP R_SourceSymbol;     /* "source" */
-SEXP R_TspSymbol;     /* "tsp" */
-
-SEXP R_dot_defined;      /* ".defined" */
-SEXP R_dot_Method;       /* ".Method" */
-SEXP R_dot_target;       /* ".target" */
-SEXP R_NaString;	    /* NA_STRING as a CHARSXP */
-SEXP R_BlankString;	    /* "" as a CHARSXP */
-
-// Symbols not part of public API but used in FastR tools implementation
-SEXP R_SrcrefSymbol;
-SEXP R_SrcfileSymbol;
-
-// logical constants
-SEXP R_TrueValue;
-SEXP R_FalseValue;
-SEXP R_LogicalNAValue;
-
-// Arith.h
-double R_NaN;		/* IEEE NaN */
-double R_PosInf;	/* IEEE Inf */
-double R_NegInf;	/* IEEE -Inf */
-double R_NaReal;	/* NA_REAL: IEEE */
-int R_NaInt;	/* NA_INTEGER:= INT_MIN currently */
-
-// from Defn.h
-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_interrupts_suspended;
-int R_interrupts_pending;
-Rboolean mbcslocale;
-Rboolean useaqua;
-char* OutDec = ".";
-Rboolean utf8locale = FALSE;
-Rboolean mbcslocale = FALSE;
-Rboolean latin1locale = FALSE;
-int R_dec_min_exponent = -308;
-int max_contour_segments = 25000;
-
-// from sys-std.c
-#include <R_ext/eventloop.h>
-
-static InputHandler BasicInputHandler = {2, -1, NULL};
-InputHandler *R_InputHandlers = &BasicInputHandler;
-
-// ordinal numbers of the RVariables enum
-#define R_Home_x 0
-#define R_TempDir_x 1
-#define R_NilValue_x 2
-#define R_UnboundValue_x 3
-#define R_MissingArg_x 4
-#define R_GlobalEnv_x 5
-#define R_EmptyEnv_x 6
-#define R_BaseEnv_x 7
-#define R_BaseNamespace_x 8
-#define R_NamespaceRegistry_x 9
-#define R_Srcref_x 10
-#define R_Bracket2Symbol_x 11
-#define R_BracketSymbol_x 12
-#define R_BraceSymbol_x 13
-#define R_ClassSymbol_x 14
-#define R_DeviceSymbol_x 15
-#define R_DevicesSymbol_x 16
-#define R_DimNamesSymbol_x 17
-#define R_DimSymbol_x 18
-#define R_DollarSymbol_x 19
-#define R_DotsSymbol_x 20
-#define R_DropSymbol_x 21
-#define R_LastvalueSymbol_x 22
-#define R_LevelsSymbol_x 23
-#define R_ModeSymbol_x 24
-#define R_NameSymbol_x 25
-#define R_NamesSymbol_x 26
-#define R_NaRmSymbol_x 27
-#define R_PackageSymbol_x 28
-#define R_QuoteSymbol_x 29
-#define R_RowNamesSymbol_x 30
-#define R_SeedsSymbol_x 31
-#define R_SourceSymbol_x 32
-#define R_TspSymbol_x 33
-#define R_dot_defined_x 34
-#define R_dot_Method_x 35
-#define R_dot_target_x 36
-#define R_SrcrefSymbol_x 37
-#define R_SrcfileSymbol_x 38
-#define R_NaString_x 39
-#define R_NaN_x 40
-#define R_PosInf_x 41
-#define R_NegInf_x 42
-#define R_NaReal_x 43
-#define R_NaInt_x 44
-#define R_BlankString_x 45
-#define R_TrueValue_x 46
-#define R_FalseValue_x 47
-#define R_LogicalNAValue_x 48
-#define R_Interactive_x 49
diff --git a/com.oracle.truffle.r.native/include/Makefile b/com.oracle.truffle.r.native/include/Makefile
index 0325032547..2de8932ab1 100644
--- a/com.oracle.truffle.r.native/include/Makefile
+++ b/com.oracle.truffle.r.native/include/Makefile
@@ -44,15 +44,11 @@ R_HEADERS_TO_LINK := $(filter-out $(notdir $(R_HEADERS_LOCAL)),$(R_HEADERS_FILEN
 
 all: linked
 
-linked: ed_Rinternals ed_Rinterface_gcntx ed_Rinterface_variables ed_GraphicsEngine
+linked:
 	mkdir -p R_ext
 	$(foreach file,$(R_HEADERS_TO_LINK),ln -sf $(GNUR_HOME)/include/$(file) $(file);)
 	ln -sf src/libintl.h
-	ed $(GNUR_HOME)/include/Rinternals.h < ed_Rinternals
-	ed $(GNUR_HOME)/include/Rinterface.h < ed_Rinterface_gcntx
-# previous ed wrote to local file
-	ed Rinterface.h < ed_Rinterface_variables
-	ed $(GNUR_HOME)/include/R_ext/GraphicsEngine.h < ed_GraphicsEngine
+	mx edinclude $(GNUR_HOME)/include
 	$(foreach file,$(R_EXT_HEADERS_TO_LINK),ln -sf $(GNUR_HOME)/include/R_ext/$(file) R_ext/$(file);)
 #	cp $(R_EXT_HEADERS_LOCAL) R_ext
 	touch linked
diff --git a/com.oracle.truffle.r.native/include/ed_GraphicsEngine b/com.oracle.truffle.r.native/include/ed_GraphicsEngine
deleted file mode 100644
index 6481419d09..0000000000
--- a/com.oracle.truffle.r.native/include/ed_GraphicsEngine
+++ /dev/null
@@ -1,3 +0,0 @@
-/MAX_GRAPHICS_SYSTEMS/
-s/24/256/
-w R_ext/GraphicsEngine.h
diff --git a/com.oracle.truffle.r.native/include/ed_Rinterface_gcntx b/com.oracle.truffle.r.native/include/ed_Rinterface_gcntx
deleted file mode 100644
index 88fe94a62a..0000000000
--- a/com.oracle.truffle.r.native/include/ed_Rinterface_gcntx
+++ /dev/null
@@ -1,23 +0,0 @@
-/R_GlobalContext/
-i
-#ifdef FASTR
-typedef void *CTXT;
-typedef void *SEXP;
-extern CTXT FASTR_GlobalContext();
-#define R_GlobalContext FASTR_GlobalContext()
-extern CTXT R_getGlobalFunctionContext();
-extern CTXT R_getParentFunctionContext(CTXT);
-extern SEXP R_getContextEnv(CTXT);
-extern SEXP R_getContextFun(CTXT);
-extern SEXP R_getContextCall(CTXT);
-extern SEXP R_getContextSrcRef(CTXT);
-extern int R_insideBrowser();
-extern int R_isGlobal(CTXT);
-extern int R_isEqual(void*, void*);
-#else
-.
-+1
-a
-#endif
-.
-w Rinterface.h
diff --git a/com.oracle.truffle.r.native/include/ed_Rinterface_variables b/com.oracle.truffle.r.native/include/ed_Rinterface_variables
deleted file mode 100644
index 60a72be296..0000000000
--- a/com.oracle.truffle.r.native/include/ed_Rinterface_variables
+++ /dev/null
@@ -1,23 +0,0 @@
-/R_Interactive/
-i
-#ifdef FASTR
-extern Rboolean FASTR_Interactive();
-#define R_Interactive FASTR_Interactive()
-#else
-.
-+1
-a
-#endif
-.
-/R_Home;/
-i
-#ifdef FASTR
-extern char* FASTR_R_Home();
-#define R_Home FASTR_R_Home()
-#else
-.
-+1
-a
-#endif
-.
-w Rinterface.h
diff --git a/com.oracle.truffle.r.native/include/ed_Rinternals b/com.oracle.truffle.r.native/include/ed_Rinternals
deleted file mode 100644
index 11d0c1e557..0000000000
--- a/com.oracle.truffle.r.native/include/ed_Rinternals
+++ /dev/null
@@ -1,114 +0,0 @@
-/USE_RINTERNALS section/
-i
-#ifdef FASTR
-// packages defining USE_INTERNALS expect certain defs (e.g. isNull) to be there
-#ifdef USE_RINTERNALS
-#define USE_RINTERNALS_DEFS
-#endif
-#undef USE_RINTERNALS
-#else
-.
-+1
-a
-#endif
-.
-/typedef struct SEXPREC \*SEXP;/
-i
-#ifdef FASTR
-typedef void *SEXP;
-#define DATAPTR(x)		R_DATAPTR(x)
-void *(R_DATAPTR)(SEXP x);
-#else
-.
-+1
-a
-#endif
-.
-/R_GlobalEnv/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_GlobalEnv();
-#define R_GlobalEnv FASTR_GlobalEnv()
-#else
-.
-+1
-a
-#endif
-.
-/R_BaseEnv/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_BaseEnv();
-#define R_BaseEnv FASTR_BaseEnv()
-#else
-.
-+1
-a
-#endif
-.
-/R_BaseNamespace/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_BaseNamespace();
-#define R_BaseNamespace FASTR_BaseNamespace()
-#else
-.
-+1
-a
-#endif
-.
-/R_NamespaceRegistry/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_NamespaceRegistry();
-#define R_NamespaceRegistry FASTR_NamespaceRegistry()
-#else
-.
-+1
-a
-#endif
-.
-/R_NilValue;/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_R_NilValue();
-#define R_NilValue FASTR_R_NilValue()
-#else
-.
-+1
-a
-#endif
-.
-/R_UnboundValue;/
-i
-#ifdef FASTR
-LibExtern SEXP FASTR_R_UnboundValue();
-#define R_UnboundValue FASTR_R_UnboundValue()
-#else
-.
-+1
-a
-#endif
-.
-/R_PreserveObject/
-i
-#ifdef FASTR
-SEXP R_PreserveObject(SEXP);
-#else
-.
-+1
-a
-#endif
-.
-/#ifdef USE_RINTERNALS/
-d
-i
-#if defined (USE_RINTERNALS_DEFS) && (defined (USE_RINTERNALS) || defined (FASTR))
-.
-/macro version of R_CheckStack/
-i
-#endif
-#ifdef USE_RINTERNALS
-
-.
-w Rinternals.h
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
index 2e7b18ce9b..4b2c7df1b2 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
@@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
 
 public enum RFFIVariables {
     R_Home(REnvVars.rHome()),
-    R_TempDir(null), // Set later with setTmpDir
+    R_TempDir(null), // Set later
     R_NilValue(RNull.instance),
     R_UnboundValue(RUnboundValue.instance),
     R_MissingArg(RMissing.instance),
@@ -77,10 +77,14 @@ public enum RFFIVariables {
     R_NegInf(Double.NEGATIVE_INFINITY),
     R_NaReal(RRuntime.DOUBLE_NA),
     R_NaInt(RRuntime.INT_NA),
-    R_BlankString(RDataFactory.createStringVectorFromScalar("")),
+    R_BlankString(CharSXPWrapper.create("")),
+    R_BlankScalarString(RDataFactory.createStringVectorFromScalar("")),
     R_TrueValue(RRuntime.LOGICAL_TRUE),
     R_FalseValue(RRuntime.LOGICAL_FALSE),
-    R_LogicalNAValue(RRuntime.LOGICAL_NA);
+    R_LogicalNAValue(RRuntime.LOGICAL_NA),
+    R_BaseSymbol(RDataFactory.createSymbol("base")),
+    R_NamespaceEnvSymbol(RDataFactory.createSymbol(".__NAMESPACE__.")),
+    R_RestartToken(null);
 
     private Object value;
 
diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py
index 0e4d84ad26..70f6f5e127 100644
--- a/mx.fastr/mx_fastr.py
+++ b/mx.fastr/mx_fastr.py
@@ -32,6 +32,7 @@ import mx_fastr_junit
 from mx_fastr_dists import FastRNativeProject, FastRTestNativeProject, FastRReleaseProject, FastRNativeRecommendedProject #pylint: disable=unused-import
 import mx_copylib
 import mx_fastr_mkgramrd
+import mx_fastr_edinclude
 
 import os
 
@@ -602,6 +603,7 @@ _commands = {
     'mkgramrd': [mx_fastr_mkgramrd.mkgramrd, '[options]'],
     'rcopylib' : [mx_copylib.copylib, '[]'],
     'rupdatelib' : [mx_copylib.updatelib, '[]'],
+    'edinclude' : [mx_fastr_edinclude.edinclude, '[]'],
     'gnu-r' : [gnu_r, '[]'],
     'gnu-rscript' : [gnu_rscript, '[]'],
     'nativebuild' : [nativebuild, '[]'],
diff --git a/mx.fastr/mx_fastr_edinclude.py b/mx.fastr/mx_fastr_edinclude.py
new file mode 100644
index 0000000000..ddac3da1ce
--- /dev/null
+++ b/mx.fastr/mx_fastr_edinclude.py
@@ -0,0 +1,214 @@
+#
+# Copyright (c) 2017, 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.
+#
+import os
+from os.path import join
+import platform
+import subprocess
+import shutil
+import mx
+import mx_fastr
+
+'''
+Handles all the editing of R FFI header files from the GNUR include directory to the
+FastR include directory.
+'''
+# variables in Rinternals.h that are Java Objects and so remapped to functions
+r_internals_vars = ['R_NilValue', 'R_UnboundValue', 'R_MissingArg', 'R_GlobalEnv',
+    'R_EmptyEnv', 'R_BaseEnv', 'R_BaseNamespace', 'R_NamespaceRegistry', 'R_Srcref', 'R_Bracket2Symbol',
+    'R_BracketSymbol', 'R_BraceSymbol', 'R_ClassSymbol', 'R_DeviceSymbol', 'R_DevicesSymbol',
+    'R_DimNamesSymbol', 'R_DimSymbol', 'R_DollarSymbol', 'R_DotsSymbol', 'R_DropSymbol', 'R_LastvalueSymbol',
+    'R_LevelsSymbol', 'R_ModeSymbol', 'R_NameSymbol', 'R_NamesSymbol', 'R_NaRmSymbol', 'R_PackageSymbol',
+    'R_QuoteSymbol', 'R_RowNamesSymbol', 'R_SeedsSymbol', 'R_SourceSymbol', 'R_TspSymbol', 'R_dot_defined',
+    'R_dot_Method', 'R_dot_target', 'R_SrcrefSymbol', 'R_SrcfileSymbol', 'R_NaString', 'R_BlankString',
+    'R_BlankScalarString','R_BaseSymbol', 'R_baseSymbol', 'R_NamespaceEnvSymbol']
+
+interface_vars = ['R_Home', 'R_TempDir',]
+
+
+def edinclude(args):
+    '''
+    edit GNU include files for FASTR
+    args[0] path to GNUR include directory
+    '''
+    ed_r_internals(args[0])
+    ed_r_interface(args[0])
+    ed_graphicsengine(args[0])
+
+use_internals_section = '''#ifdef FASTR
+// packages defining USE_INTERNALS expect certain defs (e.g. isNull) to be there
+#ifdef USE_RINTERNALS
+#define USE_RINTERNALS_DEFS
+#endif
+#undef USE_RINTERNALS
+#else
+'''
+
+sexp = '''#ifdef FASTR
+typedef void *SEXP;
+#define DATAPTR(x)\t\tR_DATAPTR(x)
+void *(R_DATAPTR)(SEXP x);
+#else
+'''
+use_internals_begin = '''#if defined (USE_RINTERNALS_DEFS) && (defined (USE_RINTERNALS) || defined (FASTR))
+'''
+use_internals_end = '''#endif
+#ifdef USE_RINTERNALS
+
+'''
+preserveObject = '''#ifdef FASTR
+SEXP R_PreserveObject(SEXP);
+#else
+'''
+
+def ed_r_internals(gnu_dir):
+    r_internals_h = join(gnu_dir,'Rinternals.h')
+    with open(r_internals_h) as f:
+        lines = f.readlines()
+
+    use_rinternals_count = 0;
+    with open('Rinternals.h', 'w') as f:
+        for line in lines:
+            if '== USE_RINTERNALS section' in line:
+                f.write(use_internals_section)
+                f.write(line)
+                f.write('#endif\n')
+            elif 'typedef struct SEXPREC *SEXP' in line:
+                f.write(sexp)
+                f.write(line)
+                f.write('#endif\n')
+            elif '#ifdef USE_RINTERNALS' in line:
+                if use_rinternals_count > 0:
+                    f.write(use_internals_begin)
+                else:
+                    f.write(line)
+                    use_rinternals_count = 1
+            elif 'macro version of R_CheckStack' in line:
+                f.write(use_internals_end)
+                f.write(line);
+            elif 'R_PreserveObject' in line:
+                f.write(preserveObject)
+                f.write(line)
+                f.write('#endif\n')
+            elif 'LibExtern' in line:
+                var = is_internal_var(line)
+                if var:
+                    rewrite_var(f, var, line)
+                else:
+                    f.write(line)
+            elif 'R_RestartToken' in line:
+                f.write('#ifdef FASTR\n')
+                f.write('SEXP FASTR_R_RestartToken();\n')
+                f.write('#else\n')
+                f.write(line)
+                f.write('#endif\n')
+            else:
+                f.write(line)
+
+def rewrite_var(f, var, line):
+    f.write('#ifdef FASTR\n')
+    f.write('LibExtern SEXP FASTR_{0}();\n'.format(var))
+    if var == 'R_baseSymbol': # alias
+        f.write('#define {0} FASTR_R_BaseSymbol()\n'.format(var))
+    else:
+        f.write('#define {0} FASTR_{0}()\n'.format(var))
+    f.write('#else\n')
+    # Ugly special case, comment split on two lines, just
+    if var == 'R_EmptyEnv':
+        split = line.split(';')
+        f.write(split[0])
+        f.write(';\n')
+        f.write('#endif\n')
+        f.write(split[1])
+    else:
+        f.write(line)
+        f.write('#endif\n')
+
+def is_internal_var(line):
+    for var in r_internals_vars:
+        varsemi = var + ';'
+        if varsemi in line:
+            return var
+    return None
+
+context_defs = '''#ifdef FASTR
+typedef void *CTXT;
+typedef void *SEXP;
+extern CTXT FASTR_GlobalContext();
+#define R_GlobalContext FASTR_GlobalContext()
+extern CTXT R_getGlobalFunctionContext();
+extern CTXT R_getParentFunctionContext(CTXT);
+extern SEXP R_getContextEnv(CTXT);
+extern SEXP R_getContextFun(CTXT);
+extern SEXP R_getContextCall(CTXT);
+extern SEXP R_getContextSrcRef(CTXT);
+extern int R_insideBrowser();
+extern int R_isGlobal(CTXT);
+extern int R_isEqual(void*, void*);
+#else
+'''
+
+interactive_rewrite = '''#ifdef FASTR
+extern Rboolean FASTR_R_Interactive();
+#define R_Interactive FASTR_R_Interactive()
+#else
+'''
+
+rhome_rewrite = '''#ifdef FASTR
+extern char* FASTR_R_Home();
+#define R_Home FASTR_R_Home()
+#else
+'''
+
+def ed_r_interface(gnu_dir):
+    r_interface_h = join(gnu_dir,'Rinterface.h')
+    with open(r_interface_h) as f:
+        lines = f.readlines()
+
+    with open('Rinterface.h', 'w') as f:
+        for line in lines:
+            if 'R_GlobalContext' in line:
+                f.write(context_defs)
+                f.write(line)
+                f.write('#endif\n')
+            elif 'R_Interactive' in line:
+                f.write(interactive_rewrite)
+                f.write(line)
+                f.write('#endif\n')
+            elif 'R_Home;' in line:
+                f.write(rhome_rewrite)
+                f.write(line)
+                f.write('#endif\n')
+            else:
+                f.write(line)
+
+def ed_graphicsengine(gnu_dir):
+    graphicsengine_h = join(gnu_dir, 'R_ext', 'GraphicsEngine.h')
+    with open(graphicsengine_h) as f:
+        lines = f.readlines()
+
+    with open(join('R_ext', 'GraphicsEngine.h'), 'w') as f:
+        for line in lines:
+            if 'MAX_GRAPHICS_SYSTEMS' in line:
+                f.write(line.replace('24', '256'))
+            else:
+                f.write(line)
diff --git a/mx.fastr/mx_fastr_mkgramrd.py b/mx.fastr/mx_fastr_mkgramrd.py
index 5ca3f5c429..2018341f3b 100644
--- a/mx.fastr/mx_fastr_mkgramrd.py
+++ b/mx.fastr/mx_fastr_mkgramrd.py
@@ -26,8 +26,10 @@ def mkgramrd(args):
     converts GNU R gramRd.c into one suitable for invoking via FastR
     '''
     parse_defs = '''
-extern SEXP R_SrcrefSymbol;
-extern SEXP R_SrcfileSymbol;
+extern SEXP FASTR_R_SrcrefSymbol();
+#define R_SrcrefSymbol FASTR_R_SrcrefSymbol()
+extern SEXP FASTR_R_SrcfileSymbol();
+#define R_SrcfileSymbol FASTR_R_SrcfileSymbol()
 extern int R_ParseContextLast;
 #define R_EOF -1
 #define PARSE_ERROR_SIZE 256
@@ -37,7 +39,8 @@ static char    R_ParseContext[PARSE_CONTEXT_SIZE];
 int    R_ParseContextLast;
 int    R_ParseContextLine;
 int R_ParseError;
-extern SEXP R_EmptyEnv;
+extern SEXP FASTR_R_EmptyEnv();
+#define R_EmptyEnv FASTR_R_EmptyEnv()
 extern SEXP R_NewHashedEnv(SEXP a, SEXP b);
 
 char *dgettext(const char *p, const char *msgid) {
-- 
GitLab