diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
index d6cb56c52a3a6d8b7e86c6d17fbc479a6ed26f03..621292af809b246636c5832544e47c4257068b49 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java
@@ -166,6 +166,7 @@ final class REngine implements Engine, Engine.Timings {
         suppressWarnings = true;
         MaterializedFrame baseFrame = RRuntime.createNonFunctionFrame("base");
         REnvironment.baseInitialize(baseFrame, globalFrame);
+        context.getStateRFFI().initializeVariables(context);
         RBuiltinPackages.loadBase(context.getLanguage(), baseFrame);
         RGraphics.initialize();
         if (FastROptions.LoadProfiles.getBooleanValue()) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
index 2cb4a8f384790baca1c3203e0ce689124498cb2e..5c79a86f02a3b756f4f1e8ade745cb7d3eae469b 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java
@@ -98,7 +98,7 @@ final class TruffleLLVM_Call implements CallRFFI {
             initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName));
         }
         Node executeNode = Message.createExecute(2).createNode();
-        RFFIVariables[] variables = RFFIVariables.initialize();
+        RFFIVariables[] variables = RFFIVariables.initialize(context);
         boolean isNullSetting = RContext.getRForeignAccessFactory().setIsNull(false);
         try {
             for (int i = 0; i < variables.length; i++) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java
index 0da0076b0839627541466a880149b9aa729264dd..98e0686ee817454c1cc954275231502ea30784ce 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java
@@ -150,12 +150,13 @@ final class TruffleNFI_Context extends RFFIContext {
 
     public TruffleObject defaultLibrary;
 
-    private void initVariables() {
+    @Override
+    public void initializeVariables(RContext context) {
         synchronized (TruffleNFI_Context.class) {
             if (!variablesInitialized) {
                 variablesInitialized = true;
                 Node executeNode = Message.createExecute(2).createNode();
-                RFFIVariables[] variables = RFFIVariables.initialize();
+                RFFIVariables[] variables = RFFIVariables.initialize(context);
                 boolean isNullSetting = RContext.getRForeignAccessFactory().setIsNull(false);
                 try {
                     for (int i = 0; i < variables.length; i++) {
@@ -275,7 +276,6 @@ final class TruffleNFI_Context extends RFFIContext {
                     assert defaultLibrary != null && rlibDLLInfo != null;
                     break;
             }
-            initVariables();
             return this;
         } finally {
             if (traceEnabled()) {
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h
index ddd5559aaf398c8d73947a9468e7a0c1b119d229..74232025ecb89fc46affde1b7678ec5f246788c4 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h
@@ -27,58 +27,63 @@
 
 #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_EmptyEnv_x 5
-#define R_Srcref_x 6
-#define R_Bracket2Symbol_x 7
-#define R_BracketSymbol_x 8
-#define R_BraceSymbol_x 9
-#define R_DoubleColonSymbol_x 10
-#define R_ClassSymbol_x 11
-#define R_DeviceSymbol_x 12
-#define R_DevicesSymbol_x 13
-#define R_DimNamesSymbol_x 14
-#define R_DimSymbol_x 15
-#define R_DollarSymbol_x 16
-#define R_DotsSymbol_x 17
-#define R_DropSymbol_x 18
-#define R_LastvalueSymbol_x 19
-#define R_LevelsSymbol_x 20
-#define R_ModeSymbol_x 21
-#define R_NameSymbol_x 22
-#define R_NamesSymbol_x 23
-#define R_NaRmSymbol_x 24
-#define R_PackageSymbol_x 25
-#define R_QuoteSymbol_x 26
-#define R_RowNamesSymbol_x 27
-#define R_SeedsSymbol_x 28
-#define R_SourceSymbol_x 29
-#define R_TspSymbol_x 30
-#define R_dot_defined_x 31
-#define R_dot_Method_x 32
-#define R_dot_target_x 33
-#define R_dot_packageName_x 34
-#define R_dot_Generic_x 35
-#define R_SrcrefSymbol_x 36
-#define R_SrcfileSymbol_x 37
-#define R_NaString_x 38
-#define R_NaN_x 39
-#define R_PosInf_x 40
-#define R_NegInf_x 41
-#define R_NaReal_x 42
-#define R_NaInt_x 43
-#define R_BlankString_x 44
-#define R_BlankScalarString_x 45
-#define R_BaseSymbol_x 46
-#define R_NamespaceEnvSymbol_x 47
-#define R_RestartToken_x 48
-#define R_SortListSymbol_x 49
-#define R_SpecSymbol_x 50
-#define R_TripleColonSymbol_x 51
-#define R_PreviousSymbol_x 52
+#define R_GlobalEnv_x 2
+#define R_BaseEnv_x 3
+#define R_BaseNamespace_x 4
+#define R_NamespaceRegistry_x 5
+#define R_Interactive_x 6
+#define R_NilValue_x 7
+#define R_UnboundValue_x 8
+#define R_MissingArg_x 9
+#define R_EmptyEnv_x 10
+#define R_Srcref_x 11
+#define R_Bracket2Symbol_x 12
+#define R_BracketSymbol_x 13
+#define R_BraceSymbol_x 14
+#define R_DoubleColonSymbol_x 15
+#define R_ClassSymbol_x 16
+#define R_DeviceSymbol_x 17
+#define R_DevicesSymbol_x 18
+#define R_DimNamesSymbol_x 19
+#define R_DimSymbol_x 20
+#define R_DollarSymbol_x 21
+#define R_DotsSymbol_x 22
+#define R_DropSymbol_x 23
+#define R_LastvalueSymbol_x 24
+#define R_LevelsSymbol_x 25
+#define R_ModeSymbol_x 26
+#define R_NameSymbol_x 27
+#define R_NamesSymbol_x 28
+#define R_NaRmSymbol_x 29
+#define R_PackageSymbol_x 30
+#define R_QuoteSymbol_x 31
+#define R_RowNamesSymbol_x 32
+#define R_SeedsSymbol_x 33
+#define R_SourceSymbol_x 34
+#define R_TspSymbol_x 35
+#define R_dot_defined_x 36
+#define R_dot_Method_x 37
+#define R_dot_target_x 38
+#define R_dot_packageName_x 39
+#define R_dot_Generic_x 40
+#define R_SrcrefSymbol_x 41
+#define R_SrcfileSymbol_x 42
+#define R_NaString_x 43
+#define R_NaN_x 44
+#define R_PosInf_x 45
+#define R_NegInf_x 46
+#define R_NaReal_x 47
+#define R_NaInt_x 48
+#define R_BlankString_x 49
+#define R_BlankScalarString_x 50
+#define R_BaseSymbol_x 51
+#define R_NamespaceEnvSymbol_x 52
+#define R_RestartToken_x 53
+#define R_SortListSymbol_x 54
+#define R_SpecSymbol_x 55
+#define R_TripleColonSymbol_x 56
+#define R_PreviousSymbol_x 57
 
-#define VARIABLES_TABLE_SIZE 53
+#define VARIABLES_TABLE_SIZE 58
 
 #endif // RFFI_VARIABLESINDEX_H
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c
index 6a68f5cb209d12e41c50bdc2c8e853b93025d575..ed88cdaf12b052b8e4f84a5ca1ddea180c8461ce 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c
@@ -20,6 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#define NO_FASTR_REDEFINE
 #include <string.h>
 #include <Rinterface.h>
 #include <trufflenfi.h>
@@ -56,6 +57,11 @@ char *copystring(char *value) {
 
 char* R_Home;
 char* R_TempDir;
+SEXP R_GlobalEnv;
+SEXP R_BaseEnv;
+SEXP R_BaseNamespace;
+SEXP R_NamespaceRegistry;
+Rboolean R_Interactive;
 SEXP R_NilValue;
 SEXP R_UnboundValue;
 SEXP R_MissingArg;
@@ -102,7 +108,7 @@ SEXP R_BlankString;
 SEXP R_BlankScalarString;
 SEXP R_BaseSymbol; /* "base" */
 SEXP R_NamespaceEnvSymbol; /* ".__NAMESPACE__." */
-SEXP R_RestartToken;
+SEXP R_RestartToken; /* "" */
 SEXP R_SortListSymbol; /* "sort.list" */
 SEXP R_SpecSymbol; /* "spec" */
 SEXP R_TripleColonSymbol; /* ":::" */
@@ -122,6 +128,7 @@ void Call_initvar_double(int index, double value) {
 
 void Call_initvar_int(int index, int value) {
     switch (index) {
+        case R_Interactive_x: R_Interactive = value; break;
         case R_NaInt_x: R_NaInt = value; break;
         default:
             printf("Call_initvar_int: unimplemented index %d\n", index);
@@ -142,6 +149,10 @@ void Call_initvar_string(int index, char* value) {
 void Call_initvar_obj(TruffleEnv* env, int index, void* value) {
     init_utils(env);
     switch (index) {
+        case R_GlobalEnv_x: R_GlobalEnv = value; break;
+        case R_BaseEnv_x: R_BaseEnv = value; break;
+        case R_BaseNamespace_x: R_BaseNamespace = value; break;
+        case R_NamespaceRegistry_x: R_NamespaceRegistry = value; break;
         case R_NilValue_x: R_NilValue = value; break;
         case R_UnboundValue_x: R_UnboundValue = value; break;
         case R_MissingArg_x: R_MissingArg = value; break;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java
index 3e9013d19efd678e2f1db8ef8cebcb7b7c95d42c..848300a58a428dff3e1b9f4e25df014844e6d13a 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIContext.java
@@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RObject;
 
 /**
@@ -94,6 +95,12 @@ public abstract class RFFIContext extends RFFI {
         }
     }
 
+    /**
+     * Invoked during RContext initialization, but after the global environment is set up.
+     */
+    public void initializeVariables(RContext context) {
+    }
+
     public long beforeDowncall() {
         callDepth++;
         return 0;
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
index 897acb3dbc8375c2920d94ff11e09b188877c0dd..eb9fef097ac5f72a0c442294da71b7ee4945a69d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
 import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.TempPathName;
+import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RMissing;
@@ -41,7 +42,12 @@ import com.oracle.truffle.r.runtime.env.REnvironment;
  */
 public enum RFFIVariables {
     R_Home(REnvVars.rHome()),
-    R_TempDir(null), // Set later
+    R_TempDir("dummy string"), // Set later
+    R_GlobalEnv(null), // Set later
+    R_BaseEnv(null), // Set later
+    R_BaseNamespace(null), // Set later
+    R_NamespaceRegistry(null), // Set later
+    R_Interactive(0), // Set later
     R_NilValue(RNull.instance),
     R_UnboundValue(RUnboundValue.instance),
     R_MissingArg(RMissing.instance),
@@ -88,7 +94,7 @@ public enum RFFIVariables {
     R_BlankScalarString(RDataFactory.createStringVectorFromScalar("")),
     R_BaseSymbol(RDataFactory.createSymbol("base")),
     R_NamespaceEnvSymbol(RDataFactory.createSymbol(".__NAMESPACE__.")),
-    R_RestartToken(null),
+    R_RestartToken(RDataFactory.createSymbol("")),
     R_SortListSymbol(RDataFactory.createSymbol("sort.list")),
     R_SpecSymbol(RDataFactory.createSymbol("spec")),
     R_TripleColonSymbol(RDataFactory.createSymbol(":::")),
@@ -113,8 +119,13 @@ public enum RFFIVariables {
     /**
      * Sets {@link #R_TempDir} for the initial context.
      */
-    public static RFFIVariables[] initialize() {
+    public static RFFIVariables[] initialize(RContext context) {
         R_TempDir.value = TempPathName.tempDirPath();
+        R_GlobalEnv.value = RContext.getInstance().stateREnvironment.getGlobalEnv();
+        R_BaseEnv.value = RContext.getInstance().stateREnvironment.getBaseEnv();
+        R_BaseNamespace.value = RContext.getInstance().stateREnvironment.getBaseNamespace();
+        R_NamespaceRegistry.value = RContext.getInstance().stateREnvironment.getNamespaceRegistry();
+        R_Interactive.value = context.isInteractive() ? 1 : 0;
         return values();
     }
 
@@ -124,7 +135,6 @@ public enum RFFIVariables {
      * class.
      */
     public static void main(String[] args) {
-        R_TempDir.value = "dummy string";
         System.out.println("// Update com.oracle.truffle.r.native/fficall/src/common/rffi_variablesindex.h with the following: \n");
         System.out.println("// Generated by RFFIVariables.java:\n");
         for (RFFIVariables var : RFFIVariables.values()) {
@@ -137,7 +147,9 @@ public enum RFFIVariables {
         System.out.println("// Generated by RFFIVariables.java:\n");
 
         for (RFFIVariables val : values()) {
-            if (val.value instanceof Double) {
+            if (val == RFFIVariables.R_Interactive) {
+                System.out.printf("Rboolean %s;\n", val.name());
+            } else if (val.value instanceof Double) {
                 System.out.printf("double %s;\n", val.name());
             } else if (val.value instanceof Integer) {
                 System.out.printf("int %s;\n", val.name());
diff --git a/mx.fastr/mx_fastr_edinclude.py b/mx.fastr/mx_fastr_edinclude.py
index a132401b39513018019010e8a90f42980c57182b..0032c54979c0af20778ea657a9375c0eb1fdea47 100644
--- a/mx.fastr/mx_fastr_edinclude.py
+++ b/mx.fastr/mx_fastr_edinclude.py
@@ -105,19 +105,16 @@ def ed_r_internals(gnu_dir):
                     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))
+    f.write('LibExtern SEXP {0};\n'.format(var))
+    f.write('#ifndef NO_FASTR_REDEFINE\n')
     f.write('#define {0} FASTR_{0}()\n'.format(var))
+    f.write('#endif\n')
     f.write('#else\n')
     f.write(line)
     f.write('#endif\n')
@@ -150,7 +147,10 @@ interactive_rewrite = '''
 #include <R_ext/RStartup.h>
 #ifdef FASTR
 extern Rboolean FASTR_R_Interactive();
+extern Rboolean R_Interactive;
+#ifndef NO_FASTR_REDEFINE
 #define R_Interactive FASTR_R_Interactive()
+#endif
 #else
 '''