diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
index cc2f268bcf1070ea534f29baa37af3f52b3fddb8..161c25219a125d9b88ffdf8373e9b68867f40466 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java
@@ -33,6 +33,7 @@ import java.util.List;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
 import com.oracle.truffle.api.nodes.Node;
@@ -719,4 +720,10 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess {
     public void checkDebugRequest(RFunction func) {
         RInstrumentation.checkDebugRequested(func);
     }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Class<? extends TruffleLanguage> getTruffleRLanguage() {
+        return TruffleRLanguage.class;
+    }
 }
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
index 6aa3aada262c0373c5b3a4d04ead7cc74dbe9a59..72fe424293cbb87439f36e62ac18a963e59595d0 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
@@ -26,8 +26,8 @@ import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.FFIRootNode;
 import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
-import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
 /**
  * A placeholder to keep {@code REngine} limited to calling the {@link #initialize} method. Two
@@ -64,7 +64,7 @@ public class RGraphics {
                 DLL.RegisteredNativeSymbol rns = DLL.RegisteredNativeSymbol.any();
                 DLL.SymbolHandle func = DLL.findSymbol("InitGraphics", null, rns);
                 assert func != DLL.SYMBOL_NOT_FOUND;
-                RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode().invokeVoidCall(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), new Object[0]);
+                FFIRootNode.createCallTarget().call(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), true, new Object[0]);
             }
         }
     }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
index 6161b0e4e724a3d1ddf555a888b9a41cf75a3858..c2f8f6f4e6d0c49405f732e5accc4da0a839f5a9 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
@@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.ffi.CallRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.FFIRootNode;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.GridRFFI;
 import com.oracle.truffle.r.runtime.ffi.LibPaths;
@@ -70,13 +71,13 @@ public class Generic_Grid implements GridRFFI {
         @Override
         public Object initGrid(REnvironment gridEvalEnv) {
             long initGrid = GridProvider.gridProvider().getInitGrid();
-            return callRFFINode.invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv});
+            return FFIRootNode.createCallTarget().call(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), false, new Object[]{gridEvalEnv});
         }
 
         @Override
         public Object killGrid() {
             long killGrid = GridProvider.gridProvider().getKillGrid();
-            return callRFFINode.invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]);
+            return FFIRootNode.createCallTarget().call(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), false, new Object[0]);
         }
     }
 
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
index c543c998c7d80d7ef13fb33a23d3acb64187c309..ee4a044a1f19a7438b001314ff4bc6c0a47718fc 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
@@ -49,7 +49,7 @@ import com.oracle.truffle.r.runtime.ffi.UpCallsRFFIFactory;
  */
 public class JNI_Call implements CallRFFI {
 
-    private static class JNI_CallRFFINode extends CallRFFINode {
+    public static class JNI_CallRFFINode extends CallRFFINode {
 
         @Override
         @TruffleBoundary
@@ -136,7 +136,7 @@ public class JNI_Call implements CallRFFI {
 
     private static final boolean ForceRTLDGlobal = false;
 
-    protected JNI_Call() {
+    public JNI_Call() {
         loadLibRLibrary();
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java
index 7a4a01cd501f6eca13e219621a21fff3466dc094..835b3d36e23b921d01ad2515f07ee8173188d363 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime;
 
+import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.r.runtime.context.Engine;
@@ -90,6 +91,12 @@ public interface RRuntimeASTAccess {
      */
     RLanguage getSyntaxCaller(RCaller rl);
 
+    /**
+     * Gets {@code TruffleRLanguage} avoiding project circularity.
+     */
+    @SuppressWarnings("rawtypes")
+    Class<? extends TruffleLanguage> getTruffleRLanguage();
+
     /**
      * Returns a string for a call as represented by {@code rl}, returned originally by
      * {@link #getSyntaxCaller}.
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..fbc4445e00cec62d43575f09aaea0ae69449ac78
--- /dev/null
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 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
+ * 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.runtime.ffi;
+
+import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.Truffle;
+import com.oracle.truffle.api.frame.FrameDescriptor;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.RootNode;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.data.RNull;
+
+public final class FFIRootNode extends RootNode {
+    @Child CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode();
+
+    public FFIRootNode() {
+        super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor());
+
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        Object[] args = frame.getArguments();
+        NativeCallInfo nativeCallInfo = (NativeCallInfo) args[0];
+        boolean isVoidCall = (boolean) args[1];
+        Object[] callArgs = (Object[]) args[2];
+        if (isVoidCall) {
+            callRFFINode.invokeVoidCall(nativeCallInfo, callArgs);
+            return RNull.instance;
+        } else {
+            return callRFFINode.invokeCall(nativeCallInfo, callArgs);
+        }
+    }
+
+    public static RootCallTarget createCallTarget() {
+        return Truffle.getRuntime().createCallTarget(new FFIRootNode());
+    }
+
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
index dda0917b27a66980e39009f4f8094e370ac9c384..b8490dfaae54f03a4c1fae79f647be644b5ce418 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java
@@ -23,7 +23,15 @@
 package com.oracle.truffle.r.runtime.rng.user;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.Truffle;
+import com.oracle.truffle.api.frame.FrameDescriptor;
+import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RInternalError;
+import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
@@ -67,19 +75,52 @@ public final class UserRNG implements RandomNumberGenerator {
     }
 
     private int nSeeds = 0;
-    private UserRngRFFI.UserRngRFFINode userRngRFFINode;
 
-    private UserRngRFFI.UserRngRFFINode getUserRngRFFINode() {
-        if (userRngRFFINode == null) {
-            userRngRFFINode = RFFIFactory.getRFFI().getUserRngRFFI().createUserRngRFFINode();
+    private abstract static class UserRNGRootNodeAdapter extends RootNode {
+        @Child protected UserRngRFFI.UserRngRFFINode userRngRFFINode = RFFIFactory.getRFFI().getUserRngRFFI().createUserRngRFFINode();
+
+        protected UserRNGRootNodeAdapter() {
+            super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor());
+        }
+    }
+
+    private static final class GenericUserRNGRootNode extends UserRNGRootNodeAdapter {
+        @Override
+        public Object execute(VirtualFrame frame) {
+            Object[] args = frame.getArguments();
+            Function function = (Function) args[0];
+            switch (function) {
+                case Init:
+                    userRngRFFINode.init((int) args[1]);
+                    return RNull.instance;
+                case NSeed:
+                    return userRngRFFINode.nSeed();
+                case Seedloc:
+                    userRngRFFINode.seeds((int[]) args[1]);
+                    return RNull.instance;
+                default:
+                    throw RInternalError.shouldNotReachHere();
+            }
         }
-        return userRngRFFINode;
     }
 
+    private static final class RandUserRNGRootNode extends UserRNGRootNodeAdapter {
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            return userRngRFFINode.rand();
+        }
+
+    }
+
+    private RootCallTarget callGeneric;
+    private RootCallTarget callRand;
+
     @Override
     @TruffleBoundary
     public void init(int seed) {
         DLLInfo dllInfo = DLL.findLibraryContainingSymbol(Function.Rand.symbol);
+        callGeneric = Truffle.getRuntime().createCallTarget(new GenericUserRNGRootNode());
         if (dllInfo == null) {
             throw RError.error(RError.NO_CALLER, RError.Message.RNG_SYMBOL, Function.Rand.symbol);
         }
@@ -87,13 +128,13 @@ public final class UserRNG implements RandomNumberGenerator {
             f.setSymbolHandle(dllInfo);
         }
         if (Function.Init.isDefined()) {
-            getUserRngRFFINode().init(seed);
+            callGeneric.call(Function.Init, seed);
         }
         if (Function.Seedloc.isDefined() && !Function.NSeed.isDefined()) {
             RError.warning(RError.NO_CALLER, RError.Message.RNG_READ_SEEDS);
         }
         if (Function.NSeed.isDefined()) {
-            int ns = getUserRngRFFINode().nSeed();
+            int ns = (int) callGeneric.call(Function.NSeed);
             if (ns < 0 || ns > 625) {
                 RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "seed length must be in 0...625; ignored");
             } else {
@@ -104,6 +145,7 @@ public final class UserRNG implements RandomNumberGenerator {
                  */
             }
         }
+        callRand = Truffle.getRuntime().createCallTarget(new RandUserRNGRootNode());
     }
 
     private static DLL.SymbolHandle findSymbol(String symbol, DLLInfo dllInfo, boolean optional) {
@@ -131,7 +173,7 @@ public final class UserRNG implements RandomNumberGenerator {
             return null;
         }
         int[] seeds = new int[nSeeds];
-        getUserRngRFFINode().seeds(seeds);
+        callGeneric.call(Function.Seedloc, seeds);
         int[] result = new int[nSeeds + 1];
         System.arraycopy(seeds, 0, result, 1, seeds.length);
         return result;
@@ -139,7 +181,7 @@ public final class UserRNG implements RandomNumberGenerator {
 
     @Override
     public double genrandDouble() {
-        return getUserRngRFFINode().rand();
+        return (double) callRand.call();
     }
 
     @Override
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 475db3491e56345526579054797f8b1119c3077b..5749956835828799755859ea651baf09c2ec9fd8 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -152,7 +152,6 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/D
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java,gnu_r.copyright
-com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java,gnu_r.copyright