diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
index 0a753d19f9a50841ed17702d326c28cbb8ac7a5a..a987ca171a446b048e9ca8afe8f211f9081f4a27 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
@@ -516,6 +516,14 @@ public class ListMR {
         }
     }
 
+    private static boolean isBoxed(@SuppressWarnings("unused") TruffleObject receiver) {
+        return false;
+    }
+
+    private static boolean isNull(@SuppressWarnings("unused") TruffleObject receiver) {
+        return false;
+    }
+
     private static boolean hasSize(@SuppressWarnings("unused") TruffleObject receiver) {
         return true;
     }
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java
index 9eb74afcf60d565e36f434cc99999da76d8de51d..a2482be68e27a7e78078c850134e79bdc4f09fc4 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java
@@ -53,13 +53,7 @@ import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
 import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode;
 import com.oracle.truffle.r.nodes.control.RLengthNode;
 import com.oracle.truffle.r.runtime.data.NativeDataAccess;
-import com.oracle.truffle.r.runtime.data.RDoubleVector;
-import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RLogical;
-import com.oracle.truffle.r.runtime.data.RLogicalVector;
-import com.oracle.truffle.r.runtime.data.RObject;
-import com.oracle.truffle.r.runtime.data.RRawVector;
-import com.oracle.truffle.r.runtime.data.RVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.interop.Foreign2R;
 import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen;
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_PkgInit.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_PkgInit.java
deleted file mode 100644
index b1147fa64c28605f1a444964b7ddab5e766d7047..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_PkgInit.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.common;
-
-import com.oracle.truffle.r.runtime.ffi.DLL;
-import com.oracle.truffle.r.runtime.ffi.DLL.CEntry;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.DotSymbol;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
-
-public abstract class Generic_PkgInit implements PkgInitUpCalls {
-    @Override
-    public int registerRoutines(DLLInfo dllInfo, int nstOrd, int num, long routines) {
-        DotSymbol[] array = new DotSymbol[num];
-        for (int i = 0; i < num; i++) {
-            Object sym = setSymbol(dllInfo, nstOrd, routines, i);
-            array[i] = (DotSymbol) sym;
-        }
-        dllInfo.setNativeSymbols(nstOrd, array);
-        return 0;
-    }
-
-    @Override
-    public int registerCCallable(String pkgName, String functionName, Object address) {
-        DLLInfo lib = DLL.safeFindLibrary(pkgName);
-        lib.registerCEntry(new CEntry(functionName, new SymbolHandle(address)));
-        return 0;
-    }
-
-    @Override
-    public int useDynamicSymbols(DLLInfo dllInfo, int value) {
-        return DLL.useDynamicSymbols(dllInfo, value);
-    }
-
-    @Override
-    public int forceSymbols(DLLInfo dllInfo, int value) {
-        return DLL.forceSymbols(dllInfo, value);
-    }
-
-    @Override
-    public DotSymbol setDotSymbolValues(DLLInfo dllInfo, String name, Object fun, int numArgs) {
-        DotSymbol result = new DotSymbol(name, new SymbolHandle(fun), numArgs);
-        return result;
-    }
-
-    protected abstract Object setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index);
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index d442fd81969469279567de6fdadec4f09978eec3..a76e4ee4ebe8b9ccb474c0f7c0684491fb07c4cd 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -29,6 +29,7 @@ import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.unimplemented;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -80,6 +81,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RList;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RNull;
+import com.oracle.truffle.r.runtime.data.RObject;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RPromise;
 import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise;
@@ -214,7 +216,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public Object R_do_MAKE_CLASS(Object clazz) {
+    public Object R_do_MAKE_CLASS(String clazz) {
         String name = "getClass";
         RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name));
         return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), true, null, clazz);
@@ -323,7 +325,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int Rf_inherits(Object x, Object clazz) {
+    public int Rf_inherits(Object x, String clazz) {
         int result = 0;
         RStringVector hierarchy = getClassHr(x);
         for (int i = 0; i < hierarchy.getLength(); i++) {
@@ -335,12 +337,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public Object Rf_install(Object name) {
-        String nameStr = (String) name;
-        Object ret = nameSymbolCache.get(nameStr);
+    public Object Rf_install(String name) {
+        Object ret = nameSymbolCache.get(name);
         if (ret == null) {
-            ret = RDataFactory.createSymbolInterned(nameStr);
-            nameSymbolCache.put(nameStr, ret);
+            ret = RDataFactory.createSymbolInterned(name);
+            nameSymbolCache.put(name, ret);
         }
         return ret;
     }
@@ -377,25 +378,25 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int Rf_error(Object msg) {
+    public int Rf_error(String msg) {
         throw RError.error(RError.SHOW_CALLER2, RError.Message.GENERIC, msg);
     }
 
     @Override
-    public int Rf_warning(Object msg) {
+    public int Rf_warning(String msg) {
         RError.warning(RError.SHOW_CALLER2, RError.Message.GENERIC, msg);
         return 0;
     }
 
     @Override
-    public int Rf_warningcall(Object call, Object msg) {
-        RErrorHandling.warningcallRFFI(call, (String) msg);
+    public int Rf_warningcall(Object call, String msg) {
+        RErrorHandling.warningcallRFFI(call, msg);
         return 0;
     }
 
     @Override
-    public int Rf_errorcall(Object call, Object msg) {
-        RErrorHandling.errorcallRFFI(call, (String) msg);
+    public int Rf_errorcall(Object call, String msg) {
+        RErrorHandling.errorcallRFFI(call, msg);
         return 0;
     }
 
@@ -1206,8 +1207,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int Rprintf(Object message) {
-        RContext.getInstance().getConsole().print((String) message);
+    public int Rprintf(String message) {
+        RContext.getInstance().getConsole().print(message);
         return 0;
     }
 
@@ -1444,14 +1445,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public Object R_new_custom_connection(Object description, Object mode, Object className, Object connAddrObj) {
+    public Object R_new_custom_connection(String description, String mode, String className, Object connAddrObj) {
         // TODO handle encoding properly !
-        String strDescription = (String) description;
-        String strMode = (String) mode;
-        String strClassName = (String) className;
         RExternalPtr connAddr = guaranteeInstanceOf(connAddrObj, RExternalPtr.class);
         try {
-            return new NativeRConnection(strDescription, strMode, strClassName, connAddr).asVector();
+            return new NativeRConnection(description, mode, className, connAddr).asVector();
         } catch (IOException e) {
             return InvalidConnection.instance.asVector();
         }
@@ -1525,11 +1523,65 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         return REnvironment.getRegisteredNamespace("methods");
     }
 
+    @Override
+    public int R_PreserveObject(Object obj) {
+        throw RInternalError.unimplemented();
+    }
+
+    @Override
+    public int R_ReleaseObject(Object obj) {
+        throw RInternalError.unimplemented();
+    }
+
+    @Override
+    public Object Rf_protect(Object x) {
+        RContext.getInstance().protectStack.add(guaranteeInstanceOf(x, RObject.class));
+        return x;
+    }
+
+    @Override
+    public void Rf_unprotect(int x) {
+        ArrayList<RObject> stack = RContext.getInstance().protectStack;
+        for (int i = 0; i < x; i++) {
+            stack.remove(stack.size() - 1);
+        }
+    }
+
+    @Override
+    public int R_ProtectWithIndex(Object x) {
+        throw RInternalError.unimplemented();
+    }
+
+    @Override
+    public void R_Reprotect(Object x, int y) {
+        throw RInternalError.unimplemented();
+    }
+
+    @Override
+    public void Rf_unprotect_ptr(Object x) {
+        ArrayList<RObject> stack = RContext.getInstance().protectStack;
+        for (int i = stack.size() - 1; i >= 0; i--) {
+            if (stack.get(i) == x) {
+                stack.remove(i);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public int FASTR_getConnectionChar(Object obj) {
+        try {
+            return guaranteeInstanceOf(obj, RConnection.class).getc();
+        } catch (IOException e) {
+            return -1;
+        }
+    }
+
     private HashMap<String, Integer> name2typeTable;
 
     @Override
     @TruffleBoundary
-    public int Rf_str2type(Object name) {
+    public int Rf_str2type(String name) {
         if (name == null) {
             return -1;
         }
@@ -1572,7 +1624,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int registerRoutines(DLLInfo dllInfo, int nstOrd, int num, long routines) {
+    public int registerRoutines(Object dllInfoObj, int nstOrd, int num, Object routines) {
+        DLLInfo dllInfo = guaranteeInstanceOf(dllInfoObj, DLLInfo.class);
         DotSymbol[] array = new DotSymbol[num];
         for (int i = 0; i < num; i++) {
             Object sym = setSymbol(dllInfo, nstOrd, routines, i);
@@ -1590,22 +1643,25 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    public int useDynamicSymbols(DLLInfo dllInfo, int value) {
+    public int useDynamicSymbols(Object dllInfoObj, int value) {
+        DLLInfo dllInfo = guaranteeInstanceOf(dllInfoObj, DLLInfo.class);
         return DLL.useDynamicSymbols(dllInfo, value);
     }
 
     @Override
-    public int forceSymbols(DLLInfo dllInfo, int value) {
+    public int forceSymbols(Object dllInfoObj, int value) {
+        DLLInfo dllInfo = guaranteeInstanceOf(dllInfoObj, DLLInfo.class);
         return DLL.forceSymbols(dllInfo, value);
     }
 
     @Override
-    public DotSymbol setDotSymbolValues(DLLInfo dllInfo, String name, Object fun, int numArgs) {
-        DotSymbol result = new DotSymbol(name, new SymbolHandle(fun), numArgs);
-        return result;
+    public DotSymbol setDotSymbolValues(Object dllInfoObj, String name, Object fun, int numArgs) {
+        @SuppressWarnings("unused")
+        DLLInfo dllInfo = guaranteeInstanceOf(dllInfoObj, DLLInfo.class);
+        return new DotSymbol(name, new SymbolHandle(fun), numArgs);
     }
 
-    protected abstract Object setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index);
+    protected abstract Object setSymbol(DLLInfo dllInfo, int nstOrd, Object routines, int index);
 
     @Override
     public double Rf_dunif(double a, double b, double c, int d) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/PkgInitUpCalls.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/PkgInitUpCalls.java
deleted file mode 100644
index 42a795396a94d14ecc457af27357e6bcc2e7daeb..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/PkgInitUpCalls.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.common;
-
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.DotSymbol;
-
-public interface PkgInitUpCalls {
-    enum Index {
-        registerRoutines("(object, sint32, sint32, uint64): void"),
-        setDotSymbolValues("(object, string, pointer, sint32): object"),
-        useDynamicSymbols("(object, sint32): sint32"),
-        forceSymbols("(object, sint32): sint32"),
-        registerCCallable("(string, string, uint64): sint32"),
-        getCCallable("(string, string): uint64");
-
-        public final String signature;
-
-        Index(String signature) {
-            this.signature = signature;
-        }
-    }
-
-    /**
-     * This is the start, called from {@code R_RegisterRoutines}.
-     *
-     * @param dllInfo library the symbols are defined in
-     * @param nstOrd the ordinal value corresponding to
-     *            {@link com.oracle.truffle.r.runtime.ffi.DLL.NativeSymbolType}.
-     * @param num the number of functions being registered
-     * @param routines the C address of the function table (not interpreted).
-     */
-    int registerRoutines(DLLInfo dllInfo, int nstOrd, int num, long routines);
-
-    /**
-     * Internal upcall used by {@code Rdynload_setSymbol}. The {@code fun} value must be converted
-     * to a {@link TruffleObject} representing the symbol}.
-     *
-     * @param dllInfo library the symbol is defined in
-     * @param name name of function
-     * @param fun a representation of the the C address of the function (in the table)
-     * @param numArgs the number of arguments the function takes.
-     */
-    DotSymbol setDotSymbolValues(DLLInfo dllInfo, String name, Object fun, int numArgs);
-
-    /**
-     * Directly implements {@code R_useDynamicSymbols}.
-     */
-    int useDynamicSymbols(DLLInfo dllInfo, int value);
-
-    /**
-     * Directly implements {@code R_forceSymbols}.
-     */
-    int forceSymbols(DLLInfo dllInfo, int value);
-
-    /**
-     * Directly implements {@code R_RegisterCCallable}.
-     */
-    int registerCCallable(String pkgName, String functionName, Object fun);
-
-    /**
-     * Directly implements {@code R_GetCCallable}.
-     */
-    Object getCCallable(String pkgName, String functionName);
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCallMR.java
deleted file mode 100644
index 2aee305534eef04d477d5ecee985a5afb69578d6..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCallMR.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-
-@MessageResolution(receiverType = ForceSymbolsCall.class)
-public class ForceSymbolsCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class ForceSymbolsCallExecute extends Node {
-        protected java.lang.Object access(ForceSymbolsCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.forceSymbols((DLLInfo) arguments[0], (int) arguments[1]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class ForceSymbolsCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") ForceSymbolsCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCallMR.java
deleted file mode 100644
index fd4531500b9dfddff51ba8d1233fad051dd5df93..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCallMR.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-
-@MessageResolution(receiverType = GetCCallableCall.class)
-public class GetCCallableCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class GetCCallableCallExecute extends Node {
-        protected java.lang.Object access(GetCCallableCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.getCCallable((String) arguments[0], (String) arguments[1]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class GetCCallableCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") GetCCallableCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCall.java
deleted file mode 100644
index 5e820b093337d09416db11fb0442c1ed8a55f319..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCall.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
-
-public class RegisterCCallableCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
-
-    public RegisterCCallableCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
-
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof RegisterCCallableCall;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return RegisterCCallableCallMRForeign.ACCESS;
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCallMR.java
deleted file mode 100644
index d80a29b324af729d261254dd538fb32f198ab303..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterCCallableCallMR.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-
-@MessageResolution(receiverType = RegisterCCallableCall.class)
-public class RegisterCCallableCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class RegisterCCallableCallExecute extends Node {
-        protected java.lang.Object access(RegisterCCallableCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.registerCCallable((String) arguments[0], (String) arguments[1], arguments[2]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class RegisterCCallableCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") RegisterCCallableCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCall.java
deleted file mode 100644
index 1d5808a9b90f98661aa44c3f665b53e6cd36517b..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCall.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
-
-public class RegisterRoutinesCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
-
-    public RegisterRoutinesCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
-
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof RegisterRoutinesCall;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return RegisterRoutinesCallMRForeign.ACCESS;
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCallMR.java
deleted file mode 100644
index caaf0033264839fae802b15eeb18a57f0bdda648..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/RegisterRoutinesCallMR.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-
-@MessageResolution(receiverType = RegisterRoutinesCall.class)
-public class RegisterRoutinesCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class RegisterRoutinesCallExecute extends Node {
-        protected java.lang.Object access(RegisterRoutinesCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.registerRoutines((DLLInfo) arguments[0], (int) arguments[1], (int) arguments[2], (long) arguments[3]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class RegisterRoutinesCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") RegisterRoutinesCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCall.java
deleted file mode 100644
index 43ac4c8148971282872d7955826d3a8d255531c9..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCall.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
-
-public class SetDotSymbolValuesCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
-
-    public SetDotSymbolValuesCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
-
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof SetDotSymbolValuesCall;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return SetDotSymbolValuesCallMRForeign.ACCESS;
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCallMR.java
deleted file mode 100644
index e24e5a04c5616b077644982bace7c0dd66b9c0c9..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/SetDotSymbolValuesCallMR.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-
-@MessageResolution(receiverType = SetDotSymbolValuesCall.class)
-public class SetDotSymbolValuesCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class SetDotSymbolValuesCallExecute extends Node {
-        @Child private FFIUnwrapNode unwrap = new FFIUnwrapNode();
-
-        protected java.lang.Object access(SetDotSymbolValuesCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.setDotSymbolValues((DLLInfo) arguments[0], (String) unwrap.execute(arguments[1]), arguments[2], (int) arguments[3]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class SetDotSymbolValuesCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") SetDotSymbolValuesCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCall.java
deleted file mode 100644
index 23b2bb055d221cbe7919d5ac95c1e81c64c49020..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCall.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
-
-public class UseDynamicSymbolsCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
-
-    public UseDynamicSymbolsCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
-
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof UseDynamicSymbolsCall;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return UseDynamicSymbolsCallMRForeign.ACCESS;
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCallMR.java
deleted file mode 100644
index 9c53915f1f1b28bea82f8ee3f6f959b8e66076ca..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/UseDynamicSymbolsCallMR.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 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.
- */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
-
-import com.oracle.truffle.api.interop.MessageResolution;
-import com.oracle.truffle.api.interop.Resolve;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-
-@MessageResolution(receiverType = UseDynamicSymbolsCall.class)
-public class UseDynamicSymbolsCallMR {
-    @Resolve(message = "EXECUTE")
-    public abstract static class UseDynamicSymbolsCallExecute extends Node {
-        protected java.lang.Object access(UseDynamicSymbolsCall receiver, Object[] arguments) {
-            return receiver.pkgInitUpCalls.useDynamicSymbols((DLLInfo) arguments[0], (int) arguments[1]);
-        }
-    }
-
-    @Resolve(message = "IS_EXECUTABLE")
-    public abstract static class UseDynamicSymbolsCallIsExecutable extends Node {
-        protected Object access(@SuppressWarnings("unused") UseDynamicSymbolsCall receiver) {
-            return true;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNIUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNIUpCallsRFFIImpl.java
index 8ee223bad4e17c79454afa90119de26f97774191..bb34b527e9421d279638258710d9a1b7e6b8f6bd 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNIUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNIUpCallsRFFIImpl.java
@@ -76,7 +76,7 @@ public class JNIUpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
     }
 
     @Override
-    protected Object setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index) {
+    protected Object setSymbol(DLLInfo dllInfo, int nstOrd, Object routines, int index) {
         throw RInternalError.shouldNotReachHere();
     }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PkgInit.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PkgInit.java
deleted file mode 100644
index 8ae6a58474a1b58c535eb6a60dc30b36e36db67b..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PkgInit.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2014, 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.
- */
-package com.oracle.truffle.r.ffi.impl.llvm;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.InteropException;
-import com.oracle.truffle.api.interop.Message;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.ForceSymbolsCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.GetCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterRoutinesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.SetDotSymbolValuesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.UseDynamicSymbolsCall;
-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.context.RContext.ContextState;
-import com.oracle.truffle.r.runtime.ffi.DLL;
-import com.oracle.truffle.r.runtime.ffi.DLL.CEntry;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
-import com.oracle.truffle.r.ffi.impl.common.Generic_PkgInit;
-
-final class TruffleLLVM_PkgInit extends Generic_PkgInit {
-
-    private static TruffleLLVM_PkgInit trufflePkgInit;
-    private static TruffleObject setSymbolHandle;
-
-    static class ContextStateImpl implements RContext.ContextState {
-        @Override
-        public ContextState initialize(RContext context) {
-            if (context.isInitial()) {
-                TruffleLLVM_PkgInit.initialize(context);
-            }
-            return this;
-        }
-    }
-
-    private static void initialize(RContext context) {
-        trufflePkgInit = new TruffleLLVM_PkgInit();
-        setSymbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + "Rdynload_setSymbol")).asTruffleObject();
-        Node executeNode = Message.createExecute(2).createNode();
-        TruffleObject callbackSymbol = new SymbolHandle(context.getEnv().importSymbol("@" + "Rdynload_addCallback")).asTruffleObject();
-        try {
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.registerRoutines.ordinal(), new RegisterRoutinesCall(trufflePkgInit));
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.setDotSymbolValues.ordinal(), new SetDotSymbolValuesCall(trufflePkgInit));
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.useDynamicSymbols.ordinal(), new UseDynamicSymbolsCall(trufflePkgInit));
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.forceSymbols.ordinal(), new ForceSymbolsCall(trufflePkgInit));
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.registerCCallable.ordinal(), new RegisterCCallableCall(trufflePkgInit));
-            ForeignAccess.sendExecute(executeNode, callbackSymbol, PkgInitUpCalls.Index.getCCallable.ordinal(), new GetCCallableCall(trufflePkgInit));
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-
-    @Override
-    public Object getCCallable(String pkgName, String functionName) {
-        DLLInfo lib = DLL.safeFindLibrary(pkgName);
-        CEntry result = lib.lookupCEntry(functionName);
-        if (result == null) {
-            throw RError.error(RError.NO_CALLER, RError.Message.UNKNOWN_OBJECT, functionName);
-        }
-        return result.address.asTruffleObject();
-    }
-
-    @Override
-    protected Object setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index) {
-        Node executeNode = Message.createExecute(4).createNode();
-        try {
-            return ForeignAccess.sendExecute(executeNode, setSymbolHandle, dllInfo, nstOrd, routines, index);
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java
index db6c5f9183b3f5517e2b200d9dc16d5928f03729..2201a8f2c0109203ef42593cdb6054e40fc09a70 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java
@@ -33,12 +33,10 @@ import com.oracle.truffle.r.runtime.ffi.DLL;
  */
 class TruffleLLVM_RFFIContextState implements ContextState {
     TruffleLLVM_DLL.ContextStateImpl dllState;
-    TruffleLLVM_PkgInit.ContextStateImpl pkgInitState;
     TruffleLLVM_Call.ContextStateImpl callState;
 
     TruffleLLVM_RFFIContextState() {
         dllState = new TruffleLLVM_DLL.ContextStateImpl();
-        pkgInitState = new TruffleLLVM_PkgInit.ContextStateImpl();
         callState = new TruffleLLVM_Call.ContextStateImpl();
     }
 
@@ -57,7 +55,6 @@ class TruffleLLVM_RFFIContextState implements ContextState {
             DLL.loadLibR(librffiPath);
         }
         dllState.initialize(context);
-        pkgInitState.initialize(context);
         callState.initialize(context);
         return this;
     }
@@ -65,7 +62,6 @@ class TruffleLLVM_RFFIContextState implements ContextState {
     @Override
     public void beforeDispose(RContext context) {
         dllState.beforeDispose(context);
-        pkgInitState.beforeDispose(context);
         callState.beforeDispose(context);
     }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java
index 329e14e3f75bda1792c8d755c6b6dd172c6a7baf..672ca9038d4289c7b53b49bb83f3059f20ec6e5e 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java
@@ -22,39 +22,15 @@
  */
 package com.oracle.truffle.r.ffi.impl.llvm;
 
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.InteropException;
-import com.oracle.truffle.api.interop.Message;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.Generic_Tools;
-import com.oracle.truffle.r.ffi.impl.interop.tools.RConnGetCCall;
-import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.conn.RConnection;
-import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.ToolsRFFI;
 
 public class TruffleLLVM_Tools implements ToolsRFFI {
 
-    private static boolean addCallbackDone;
-
-    private static void addCallback() {
-        if (!addCallbackDone) {
-            Node executeNode = Message.createExecute(2).createNode();
-            TruffleObject callbackSymbol = new SymbolHandle(RContext.getInstance().getEnv().importSymbol("@" + "gramRd_addCallback")).asTruffleObject();
-            try {
-                ForeignAccess.sendExecute(executeNode, callbackSymbol, new RConnGetCCall());
-                addCallbackDone = true;
-            } catch (InteropException ex) {
-                throw RInternalError.shouldNotReachHere(ex);
-            }
-        }
-    }
-
     private static class TruffleLLVM_ToolsRFFINode extends Generic_Tools.Generic_ToolsRFFINode {
         /**
          * Invoke C implementation, N.B., code is not thread safe.
@@ -62,7 +38,6 @@ public class TruffleLLVM_Tools implements ToolsRFFI {
         @Override
         public synchronized Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros,
                         RLogicalVector warndups) {
-            addCallback();
             return super.execute(con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups);
         }
     }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
index 83d886b44ea85520e61bc316adabb08afc71037d..38c36620486a731d86250af493e28ab4bc67a9c0 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java
@@ -35,6 +35,7 @@ import com.oracle.truffle.r.ffi.impl.interop.NativeIntegerArray;
 import com.oracle.truffle.r.ffi.impl.interop.NativeLogicalArray;
 import com.oracle.truffle.r.ffi.impl.interop.NativeRawArray;
 import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
+import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode;
 import com.oracle.truffle.r.runtime.REnvVars;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
@@ -165,10 +166,10 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
     }
 
     @Override
-    protected Object setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index) {
+    protected Object setSymbol(DLLInfo dllInfo, int nstOrd, Object routines, int index) {
         Node executeNode = Message.createExecute(4).createNode();
         try {
-            return ForeignAccess.sendExecute(executeNode, setSymbolHandle, dllInfo, nstOrd, routines, index);
+            return FFIUnwrapNode.unwrap(ForeignAccess.sendExecute(executeNode, setSymbolHandle, dllInfo, nstOrd, routines, index));
         } catch (InteropException ex) {
             throw RInternalError.shouldNotReachHere(ex);
         }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java
index 46597448814375b801ab7d82c9703520db7da59a..74bf04cb475ed478f986f1cc298faedf974df61a 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java
@@ -56,7 +56,7 @@ import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 public class TruffleNFI_Call implements CallRFFI {
 
     private enum INIT_VAR_FUN {
-        OBJ("(env, sint32, object) : void"),
+        OBJ("(env, sint32, pointer) : void"),
         DOUBLE("(sint32, double): void"),
         STRING("(sint32, string): void"),
         INT("(sint32, sint32) : void");
@@ -78,7 +78,6 @@ public class TruffleNFI_Call implements CallRFFI {
 
     public TruffleNFI_Call() {
         initialize();
-        TruffleNFI_PkgInit.initialize();
     }
 
     private static void initVariables() {
@@ -315,7 +314,7 @@ public class TruffleNFI_Call implements CallRFFI {
     }
 
     private static class TruffleNFI_InvokeVoidCallNode extends Node implements InvokeVoidCallNode {
-        private static final String CallVoid1Sig = "(object): void";
+        private static final String CallVoid1Sig = "(pointer): void";
         private static final String CallVoid0Sig = "(): void";
         @Child private Node bindNode = Message.createInvoke(1).createNode();
         @Child private Node execute0Node = Message.createExecute(0).createNode();
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java
deleted file mode 100644
index e0741ce94720dc4a5ec9552abc4fb4a0ad8d4aa7..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2014, 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.
- */
-package com.oracle.truffle.r.ffi.impl.nfi;
-
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.InteropException;
-import com.oracle.truffle.api.interop.Message;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.r.ffi.impl.common.Generic_PkgInit;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.ForceSymbolsCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.GetCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterRoutinesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.SetDotSymbolValuesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.UseDynamicSymbolsCall;
-import com.oracle.truffle.r.runtime.RError;
-import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.ffi.DLL;
-import com.oracle.truffle.r.runtime.ffi.DLL.CEntry;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.DotSymbol;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
-
-public final class TruffleNFI_PkgInit extends Generic_PkgInit {
-
-    private static final String SETSYMBOL_SIGNATURE = "(object, sint32, uint64, sint32): object";
-    private static TruffleObject setSymbolFunction;
-
-    static void initialize() {
-        Node bind = Message.createInvoke(1).createNode();
-        SymbolHandle symbolHandle = DLL.findSymbol("Rdynload_init", null);
-        Node executeNode = Message.createExecute(2).createNode();
-        TruffleNFI_PkgInit trufflePkgInit = new TruffleNFI_PkgInit();
-        try {
-            for (PkgInitUpCalls.Index upCall : PkgInitUpCalls.Index.values()) {
-                String addCallbackSignature = String.format("(env, sint32, %s): void", upCall.signature);
-                TruffleObject addCallbackFunction = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", addCallbackSignature);
-                TruffleObject callbackObject;
-                switch (upCall) {
-                    case registerRoutines:
-                        callbackObject = new RegisterRoutinesCall(trufflePkgInit);
-                        break;
-                    case setDotSymbolValues:
-                        callbackObject = new SetDotSymbolValuesCall(trufflePkgInit);
-                        break;
-                    case useDynamicSymbols:
-                        callbackObject = new UseDynamicSymbolsCall(trufflePkgInit);
-                        break;
-                    case forceSymbols:
-                        callbackObject = new ForceSymbolsCall(trufflePkgInit);
-                        break;
-                    case registerCCallable:
-                        callbackObject = new RegisterCCallableCall(trufflePkgInit);
-                        break;
-                    case getCCallable:
-                        callbackObject = new GetCCallableCall(trufflePkgInit);
-                        break;
-                    default:
-                        throw RInternalError.shouldNotReachHere();
-                }
-                ForeignAccess.sendExecute(executeNode, addCallbackFunction, upCall.ordinal(), callbackObject);
-            }
-            symbolHandle = DLL.findSymbol("Rdynload_setSymbol", null);
-            setSymbolFunction = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", SETSYMBOL_SIGNATURE);
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-
-    @Override
-    public Object getCCallable(String pkgName, String functionName) {
-        DLLInfo lib = DLL.safeFindLibrary(pkgName);
-        CEntry result = lib.lookupCEntry(functionName);
-        if (result == null) {
-            throw RError.error(RError.NO_CALLER, RError.Message.UNKNOWN_OBJECT, functionName);
-        }
-        return result.address.asAddress();
-    }
-
-    @Override
-    protected DotSymbol setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index) {
-        Node executeNode = Message.createExecute(4).createNode();
-        try {
-            return (DotSymbol) ForeignAccess.sendExecute(executeNode, setSymbolFunction, dllInfo, nstOrd, routines, index);
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java
index 30b9bcb94c904701f2a6584222d30e9a0ebfdd10..d2cc51b30a0abf24804adaede1446a905808fcb0 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java
@@ -22,55 +22,22 @@
  */
 package com.oracle.truffle.r.ffi.impl.nfi;
 
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.InteropException;
-import com.oracle.truffle.api.interop.Message;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.Generic_Tools;
-import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.ffi.impl.interop.tools.RConnGetCCall;
 import com.oracle.truffle.r.runtime.conn.RConnection;
 import com.oracle.truffle.r.runtime.data.RLogicalVector;
 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.DLL.DLLInfo;
-import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
-import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
 import com.oracle.truffle.r.runtime.ffi.ToolsRFFI;
 
 public class TruffleNFI_Tools implements ToolsRFFI {
 
     private static class TruffleNFI_ToolsRFFINode extends Generic_Tools.Generic_ToolsRFFINode {
-        private static boolean initialized;
-
-        @Child private DLLRFFI.DLSymNode dysymNode = DLLRFFI.DLSymNode.create();
 
         @Override
         public synchronized Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros,
                         RLogicalVector warndups) {
-            if (!initialized) {
-                initCallback();
-                initialized = true;
-            }
             return super.execute(con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups);
         }
-
-        private void initCallback() {
-            DLLInfo toolsDLLInfo = DLL.findLibrary(TOOLS);
-            assert toolsDLLInfo != null;
-            SymbolHandle symbolHandle = dysymNode.execute(toolsDLLInfo.handle, "gramRd_nfi_init");
-            assert symbolHandle != DLL.SYMBOL_NOT_FOUND;
-            Node bind = Message.createInvoke(1).createNode();
-            Node executeNode = Message.createExecute(1).createNode();
-            try {
-                TruffleObject function = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", "(env, (object): sint32): void");
-                ForeignAccess.sendExecute(executeNode, function, new RConnGetCCall());
-            } catch (InteropException ex) {
-                throw RInternalError.shouldNotReachHere(ex);
-            }
-        }
     }
 
     @Override
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java
index 5729f86c9bdf7f7cf5fb3136587b2ebfabcaba2c..eca0ce803c83d8b270c2d53c44b84b6df29cc855 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java
@@ -27,15 +27,10 @@ import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.InteropException;
 import com.oracle.truffle.api.interop.Message;
 import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.UnsupportedMessageException;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.ForceSymbolsCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.GetCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterCCallableCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.RegisterRoutinesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.SetDotSymbolValuesCall;
-import com.oracle.truffle.r.ffi.impl.interop.pkginit.UseDynamicSymbolsCall;
+import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper;
@@ -48,7 +43,7 @@ import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 
 public class TruffleNFI_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
 
-    private static final String SETSYMBOL_SIGNATURE = "(object, sint32, uint64, sint32): object";
+    private static final String SETSYMBOL_SIGNATURE = "(pointer, sint32, pointer, sint32): pointer";
     private static TruffleObject setSymbolFunction;
 
     public TruffleNFI_UpCallsRFFIImpl() {
@@ -61,11 +56,19 @@ public class TruffleNFI_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
         }
     }
 
+    private static Node asPointer = Message.AS_POINTER.createNode();
+
     @Override
     public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) {
         // "bytes" is actually a Long unboxed from a NativePointer
         // TODO: handle encoding properly
-        return CharSXPWrapper.create(TruffleNFI_Utils.convertCstring(bytes, len));
+        long address;
+        try {
+            address = ForeignAccess.sendAsPointer(asPointer, (TruffleObject) bytes);
+        } catch (UnsupportedMessageException ex) {
+            throw RInternalError.shouldNotReachHere(ex);
+        }
+        return CharSXPWrapper.create(TruffleNFI_Utils.getString(address, len));
     }
 
     @Override
@@ -143,10 +146,10 @@ public class TruffleNFI_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl {
     }
 
     @Override
-    protected DotSymbol setSymbol(DLLInfo dllInfo, int nstOrd, long routines, int index) {
+    protected DotSymbol setSymbol(DLLInfo dllInfo, int nstOrd, Object routines, int index) {
         Node executeNode = Message.createExecute(4).createNode();
         try {
-            return (DotSymbol) ForeignAccess.sendExecute(executeNode, setSymbolFunction, dllInfo, nstOrd, routines, index);
+            return (DotSymbol) FFIUnwrapNode.unwrap(ForeignAccess.sendExecute(executeNode, setSymbolFunction, dllInfo, nstOrd, routines, index));
         } catch (InteropException ex) {
             throw RInternalError.shouldNotReachHere(ex);
         }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Utils.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Utils.java
index 45fb1fd383423aac2755110063571d7e9d449bc6..cceef27f87ab941ef1dc79f13b6b77d274888754 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Utils.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Utils.java
@@ -40,7 +40,7 @@ import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 
 public class TruffleNFI_Utils {
 
-    private static String getString(long address, int len) {
+    static String getString(long address, int len) {
         byte[] byteArray = new byte[len];
         for (int i = 0; i < len; i++) {
             byteArray[i] = UnsafeAdapter.UNSAFE.getByte(address + i);
@@ -48,11 +48,6 @@ public class TruffleNFI_Utils {
         return new String(byteArray, StandardCharsets.UTF_8);
     }
 
-    static String convertCstring(Object cstring, int len) {
-        long address = (long) cstring;
-        return getString(address, len);
-    }
-
     private static TruffleObject defaultLibrary;
 
     @TruffleBoundary
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/DLLUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/DLLUpCallsRFFI.java
index f4964eb0d9b336bb24c924561fb6b77c2fde2fe5..336062d6f09c01b5b1d83d6506610ab78bcd0eee 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/DLLUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/DLLUpCallsRFFI.java
@@ -23,7 +23,8 @@
 package com.oracle.truffle.r.ffi.impl.upcalls;
 
 import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
+import com.oracle.truffle.r.ffi.processor.RFFICpointer;
+import com.oracle.truffle.r.ffi.processor.RFFICstring;
 
 public interface DLLUpCallsRFFI {
 
@@ -36,7 +37,7 @@ public interface DLLUpCallsRFFI {
      * @param num the number of functions being registered
      * @param routines the C address of the function table (not interpreted).
      */
-    int registerRoutines(DLLInfo dllInfo, int nstOrd, int num, long routines);
+    int registerRoutines(Object dllInfo, int nstOrd, int num, @RFFICpointer Object routines);
 
     /**
      * Internal upcall used by {@code Rdynload_setSymbol}. The {@code fun} value must be converted
@@ -47,26 +48,27 @@ public interface DLLUpCallsRFFI {
      * @param fun a representation of the the C address of the function (in the table)
      * @param numArgs the number of arguments the function takes.
      */
-    Object setDotSymbolValues(DLLInfo dllInfo, String name, Object fun, int numArgs);
+    Object setDotSymbolValues(Object dllInfo, @RFFICstring String name, @RFFICpointer Object fun, int numArgs);
 
     /**
      * Directly implements {@code R_useDynamicSymbols}.
      */
-    int useDynamicSymbols(DLLInfo dllInfo, int value);
+    int useDynamicSymbols(Object dllInfo, int value);
 
     /**
      * Directly implements {@code R_forceSymbols}.
      */
-    int forceSymbols(DLLInfo dllInfo, int value);
+    int forceSymbols(Object dllInfo, int value);
 
     /**
      * Directly implements {@code R_RegisterCCallable}.
      */
-    int registerCCallable(String pkgName, String functionName, Object fun);
+    int registerCCallable(@RFFICstring String pkgName, @RFFICstring String functionName, @RFFICpointer Object fun);
 
     /**
      * Directly implements {@code R_GetCCallable}.
      */
-    Object getCCallable(String pkgName, String functionName);
+    @RFFICpointer
+    Object getCCallable(@RFFICstring String pkgName, @RFFICstring String functionName);
 
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java
index 3bfb5ff4670517ce4b0290d4fbec7fd665ba3685..2fb8d8a0c9e734a9d4e4d80bdb29be20b79e537f 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.ffi.impl.upcalls;
 
+import com.oracle.truffle.api.CompilerAsserts;
 import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.Message;
@@ -111,4 +112,11 @@ public final class FFIUnwrapNode extends Node {
     public static FFIUnwrapNode create() {
         return new FFIUnwrapNode();
     }
+
+    private static final FFIUnwrapNode unwrap = new FFIUnwrapNode();
+
+    public static Object unwrap(Object value) {
+        CompilerAsserts.neverPartOfCompilation();
+        return unwrap.execute(value);
+    }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
similarity index 55%
rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCall.java
rename to com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
index 591d749dd48329a25804912a6586b8503a3b68c8..b0ce956cb2ddb2c1df9addbf9dbe5742b504f514 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/GetCCallableCall.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/MemoryUpCallsRFFI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -20,26 +20,23 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
+package com.oracle.truffle.r.ffi.impl.upcalls;
 
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
+public interface MemoryUpCallsRFFI {
+    // Checkstyle: stop method name check
 
-public class GetCCallableCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
+    int R_PreserveObject(Object obj);
 
-    public GetCCallableCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
+    int R_ReleaseObject(Object obj);
 
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof GetCCallableCall;
-    }
+    Object Rf_protect(Object x);
+
+    void Rf_unprotect(int x);
+
+    int R_ProtectWithIndex(Object x);
+
+    void R_Reprotect(Object x, int y);
+
+    void Rf_unprotect_ptr(Object x);
 
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return GetCCallableCallMRForeign.ACCESS;
-    }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
index c9ace1e6345dc0b84ef0857a2fc3f0439e867985..72cd7552628087620e9d38bccb37f5ef80f9d3a2 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
@@ -91,7 +91,7 @@ public interface StdUpCallsRFFI {
 
     int /* void */ Rf_defineVar(Object symbolArg, Object value, Object envArg);
 
-    Object R_do_MAKE_CLASS(@RFFICstring Object clazz);
+    Object R_do_MAKE_CLASS(@RFFICstring String clazz);
 
     Object R_do_new_object(Object classDef);
 
@@ -111,9 +111,9 @@ public interface StdUpCallsRFFI {
 
     int /* void */ Rf_setAttrib(Object obj, Object name, Object val);
 
-    int Rf_inherits(Object x, @RFFICstring Object clazz);
+    int Rf_inherits(Object x, @RFFICstring String clazz);
 
-    Object Rf_install(@RFFICstring Object name);
+    Object Rf_install(@RFFICstring String name);
 
     Object Rf_installChar(Object name);
 
@@ -125,13 +125,13 @@ public interface StdUpCallsRFFI {
 
     Object Rf_PairToVectorList(Object x);
 
-    int /* void */ Rf_error(@RFFICstring Object msg);
+    int /* void */ Rf_error(@RFFICstring String msg);
 
-    int /* void */ Rf_warning(@RFFICstring Object msg);
+    int /* void */ Rf_warning(@RFFICstring String msg);
 
-    int /* void */ Rf_warningcall(Object call, @RFFICstring Object msg);
+    int /* void */ Rf_warningcall(Object call, @RFFICstring String msg);
 
-    int /* void */ Rf_errorcall(Object call, @RFFICstring Object msg);
+    int /* void */ Rf_errorcall(Object call, @RFFICstring String msg);
 
     Object Rf_allocVector(int mode, long n);
 
@@ -255,7 +255,7 @@ public interface StdUpCallsRFFI {
 
     int /* void */ UNSET_S4_OBJECT(Object x);
 
-    int /* void */ Rprintf(@RFFICstring Object message);
+    int /* void */ Rprintf(@RFFICstring String message);
 
     int /* void */ GetRNGstate();
 
@@ -293,7 +293,7 @@ public interface StdUpCallsRFFI {
 
     Object R_CHAR(Object x);
 
-    Object R_new_custom_connection(@RFFICstring Object description, @RFFICstring Object mode, @RFFICstring Object className, Object readAddr);
+    Object R_new_custom_connection(@RFFICstring String description, @RFFICstring String mode, @RFFICstring String className, Object readAddr);
 
     int R_ReadConnection(int fd, Object bufObj);
 
@@ -315,7 +315,9 @@ public interface StdUpCallsRFFI {
 
     Object R_MethodsNamespace();
 
-    int Rf_str2type(@RFFICstring Object name);
+    int Rf_str2type(@RFFICstring String name);
+
+    int FASTR_getConnectionChar(Object obj);
 
     double Rf_dunif(double a, double b, double c, int d);
 
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/UpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/UpCallsRFFI.java
index 19b16e44619347d86599ce1ceaa8ca6be8779105..5170de9ef05e6ded9f1315b5e5fcae144406edc0 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/UpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/UpCallsRFFI.java
@@ -28,6 +28,6 @@ import com.oracle.truffle.r.ffi.processor.RFFIUpCallRoot;
  * Aggregation of all the FFI upcall interfaces.
  */
 @RFFIUpCallRoot
-public interface UpCallsRFFI extends StdUpCallsRFFI, IDEUpCallsRFFI, VariableUpCallsRFFI, DLLUpCallsRFFI {
+public interface UpCallsRFFI extends StdUpCallsRFFI, IDEUpCallsRFFI, VariableUpCallsRFFI, DLLUpCallsRFFI, MemoryUpCallsRFFI {
 
 }
diff --git a/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java
index 4ca6eef9c418e459f823fad23b62e42084b867ff..5f4df74f1a5a34e275d289194cd536c06dd9ad88 100644
--- a/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java
+++ b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java
@@ -182,25 +182,34 @@ public final class FFIProcessor extends AbstractProcessor {
                 arguments.append(", ");
             }
             TypeMirror paramType = params.get(i).asType();
+
+            RFFICpointer[] pointerAnnotations = params.get(i).getAnnotationsByType(RFFICpointer.class);
+            RFFICstring[] stringAnnotations = params.get(i).getAnnotationsByType(RFFICstring.class);
+
             String paramName = params.get(i).getSimpleName().toString();
             String paramTypeName = getTypeName(paramType);
-            boolean isScalar = paramType.getKind().isPrimitive();
+            boolean needsUnwrap = !paramType.getKind().isPrimitive() &&
+                            !paramTypeName.equals("java.lang.String") &&
+                            pointerAnnotations.length == 0 &&
+                            (stringAnnotations.length == 0 || stringAnnotations[0].convert());
             boolean needCast = !paramTypeName.equals("java.lang.Object");
             if (needCast) {
                 arguments.append('(').append(paramTypeName).append(") ");
             }
-            if (!isScalar) {
+            if (needsUnwrap) {
                 arguments.append(paramName).append("Unwrap").append(".execute(");
                 unwrapNodes.append("                @Child private FFIUnwrapNode ").append(paramName).append("Unwrap").append(" = FFIUnwrapNode.create();\n");
             }
             arguments.append("arguments.get(").append(i).append(")");
-            if (!isScalar) {
+            if (needsUnwrap) {
                 arguments.append(')');
             }
         }
 
         TypeKind returnKind = m.getReturnType().getKind();
-        boolean needsReturnWrap = returnKind != TypeKind.VOID && !returnKind.isPrimitive() && !"java.lang.String".equals(getTypeName(m.getReturnType()));
+        boolean needsReturnWrap = returnKind != TypeKind.VOID && !returnKind.isPrimitive() &&
+                        !"java.lang.String".equals(getTypeName(m.getReturnType())) &&
+                        m.getAnnotationsByType(RFFICpointer.class).length == 0;
         if (needsReturnWrap) {
             unwrapNodes.append("                @Child private FFIWrapNode returnWrap").append(" = FFIWrapNode.create();\n");
         }
@@ -279,7 +288,11 @@ public final class FFIProcessor extends AbstractProcessor {
         w.append("                    if (RFFIUtils.traceEnabled) {\n");
         w.append("                        RFFIUtils.traceUpCall(\"" + name + "\", arguments);\n");
         w.append("                    }\n");
-        w.append("                    return ");
+        if (returnKind == TypeKind.VOID) {
+            w.append("                    ");
+        } else {
+            w.append("                    return ");
+        }
         if (needsReturnWrap) {
             w.append("returnWrap.execute(");
         }
@@ -294,6 +307,9 @@ public final class FFIProcessor extends AbstractProcessor {
         } else {
             w.append(";\n");
         }
+        if (returnKind == TypeKind.VOID) {
+            w.append("                    return 0; // void return type\n");
+        }
         w.append("                }\n");
         w.append("            });\n");
         w.append("        }\n");
@@ -397,10 +413,17 @@ public final class FFIProcessor extends AbstractProcessor {
             case "byte[]":
                 return "[uint8]";
             default:
-                if (isReturn) {
-                    if ("java.lang.String".equals(paramTypeName)) {
+                if ("java.lang.String".equals(paramTypeName)) {
+                    if (isReturn) {
+                        return "string";
+                    } else if (rffiCstring != null) {
+                        if (!rffiCstring.convert()) {
+                            processingEnv.getMessager().printMessage(Kind.ERROR, "Invalid parameter type (without conversion) " + paramTypeName, m);
+                        }
                         return "string";
                     }
+                }
+                if (isReturn) {
                     processingEnv.getMessager().printMessage(Kind.ERROR, "Invalid return type " + paramTypeName, m);
                 } else {
                     processingEnv.getMessager().printMessage(Kind.ERROR, "Invalid parameter type " + paramTypeName, m);
@@ -413,7 +436,7 @@ public final class FFIProcessor extends AbstractProcessor {
         Types types = processingEnv.getTypeUtils();
         TypeKind kind = type.getKind();
         String returnType;
-        if (kind.isPrimitive()) {
+        if (kind.isPrimitive() || kind == TypeKind.VOID) {
             returnType = kind.name().toLowerCase();
         } else {
             Element rt = types.asElement(type);
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCall.java b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/RFFICpointer.java
similarity index 54%
rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCall.java
rename to com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/RFFICpointer.java
index 74aed4bcdfe4f80dafadc052da0e8607e1d382f6..97e23443324e836f074e376b9a336a6525b53ec2 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pkginit/ForceSymbolsCall.java
+++ b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/RFFICpointer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -20,26 +20,18 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.ffi.impl.interop.pkginit;
+package com.oracle.truffle.r.ffi.processor;
 
-import com.oracle.truffle.api.interop.ForeignAccess;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.r.ffi.impl.common.PkgInitUpCalls;
-import com.oracle.truffle.r.runtime.data.RTruffleObject;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-public class ForceSymbolsCall implements RTruffleObject {
-    public final PkgInitUpCalls pkgInitUpCalls;
-
-    public ForceSymbolsCall(PkgInitUpCalls pkgInitUpCalls) {
-        this.pkgInitUpCalls = pkgInitUpCalls;
-    }
-
-    public static boolean isInstance(TruffleObject value) {
-        return value instanceof ForceSymbolsCall;
-    }
-
-    @Override
-    public ForeignAccess getForeignAccess() {
-        return ForceSymbolsCallMRForeign.ACCESS;
-    }
+/**
+ * Tags an upcall argument or return value as being (on the native side) a C pointer, which should
+ * not be processed in any way before being passed to the Java side.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+public @interface RFFICpointer {
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
index 3452fe945c59beacfd0054e3ab02dad68c8249db..c58a2d95b6586001b3d9f7a6b3a339beb35f2724 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
@@ -24,6 +24,7 @@
 #define CALLBACKS_H
 
 #include "rffi_upcallsindex.h"
+#include <Rdynload.h>
 
 extern void* *callbacks;
 
@@ -84,11 +85,6 @@ typedef const char * (*call_Rf_reEnc)(const char *x, cetype_t ce_in, cetype_t ce
 typedef SEXP (*call_Rf_mkString)(const char *s);
 typedef int (*call_Rf_ncols)(SEXP x);
 typedef int (*call_Rf_nrows)(SEXP x);
-typedef SEXP (*call_Rf_protect)(SEXP x);
-typedef void (*call_Rf_unprotect)(int x);
-typedef void (*call_R_ProtectWithIndex)(SEXP x, PROTECT_INDEX *y);
-typedef void (*call_R_Reprotect)(SEXP x, PROTECT_INDEX y);
-typedef void (*call_Rf_unprotect_ptr)(SEXP x);
 typedef void (*call_Rf_error)(const char *format, ...);
 typedef void (*call_Rf_errorcall)(SEXP x, const char *format, ...);
 typedef void (*call_Rf_warningcall)(SEXP x, const char *format, ...);
@@ -257,8 +253,6 @@ typedef SEXP (*call_R_getClassDef )(const char *what);
 typedef SEXP (*call_R_do_new_object)(SEXP class_def);
 typedef int (*call_R_check_class_and_super)(SEXP x, const char **valid, SEXP rho);
 typedef int (*call_R_check_class_etc )(SEXP x, const char **valid);
-typedef SEXP (*call_R_PreserveObject)(SEXP x);
-typedef void (*call_R_ReleaseObject)(SEXP x);
 typedef void (*call_R_dot_Last)(void);
 typedef Rboolean (*call_R_compute_identical)(SEXP x, SEXP y, int flags);
 typedef void (*call_Rf_copyListMatrix)(SEXP s, SEXP t, Rboolean byrow);
@@ -284,5 +278,25 @@ typedef double (*call_Rf_runif)(double x, double y);
 
 typedef SEXP (*call_getvar)();
 
+typedef int (*call_FASTR_getConnectionChar)(SEXP connection);
+
+
+typedef void (*call_registerRoutines)(DllInfo *dllInfo, int nstOrd, int num, const void* routines);
+typedef int (*call_useDynamicSymbols)(DllInfo *dllInfo, Rboolean value);
+typedef void * (*call_setDotSymbolValues)(DllInfo *dllInfo, char *name, void *fun, int numArgs);
+typedef int (*call_forceSymbols)(DllInfo *dllInfo, Rboolean value);
+typedef int (*call_registerCCallable)(const char *pkgname, const char *name, void *fun);
+typedef void* (*call_getCCallable)(const char *pkgname, const char *name);
+
+// memory
+
+typedef SEXP (*call_Rf_protect)(SEXP x);
+typedef void (*call_Rf_unprotect)(int x);
+typedef int (*call_R_ProtectWithIndex)(SEXP x);
+typedef void (*call_R_Reprotect)(SEXP x, int y);
+typedef void (*call_Rf_unprotect_ptr)(SEXP x);
+typedef SEXP (*call_R_PreserveObject)(SEXP x);
+typedef void (*call_R_ReleaseObject)(SEXP x);
+
 #endif
 
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
index e414fb91e6d9dd51d3e716fd0e908e96c1b28055..a9c6a9db78345aa66b322a72b2ef9a85bfd6de74 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
@@ -8,146 +8,161 @@
 #define CAR_x 3
 #define CDDR_x 4
 #define CDR_x 5
-#define DUPLICATE_ATTRIB_x 6
-#define ENCLOS_x 7
-#define GetRNGstate_x 8
-#define INTEGER_x 9
-#define IS_S4_OBJECT_x 10
-#define LENGTH_x 11
-#define LOGICAL_x 12
-#define NAMED_x 13
-#define OBJECT_x 14
-#define PRCODE_x 15
-#define PRENV_x 16
-#define PRINTNAME_x 17
-#define PRSEEN_x 18
-#define PRVALUE_x 19
-#define PutRNGstate_x 20
-#define RAW_x 21
-#define RDEBUG_x 22
-#define REAL_x 23
-#define RSTEP_x 24
-#define R_BaseEnv_x 25
-#define R_BaseNamespace_x 26
-#define R_BindingIsLocked_x 27
-#define R_CHAR_x 28
-#define R_CleanUp_x 29
-#define R_ExternalPtrAddr_x 30
-#define R_ExternalPtrProtected_x 31
-#define R_ExternalPtrTag_x 32
-#define R_FindNamespace_x 33
-#define R_GetConnection_x 34
-#define R_GlobalContext_x 35
-#define R_GlobalEnv_x 36
-#define R_Home_x 37
-#define R_HomeDir_x 38
-#define R_Interactive_x 39
-#define R_MakeExternalPtr_x 40
-#define R_MethodsNamespace_x 41
-#define R_NamespaceRegistry_x 42
-#define R_NewHashedEnv_x 43
-#define R_ParseVector_x 44
-#define R_PromiseExpr_x 45
-#define R_ReadConnection_x 46
-#define R_SetExternalPtrAddr_x 47
-#define R_SetExternalPtrProtected_x 48
-#define R_SetExternalPtrTag_x 49
-#define R_TempDir_x 50
-#define R_ToplevelExec_x 51
-#define R_WriteConnection_x 52
-#define R_compute_identical_x 53
-#define R_do_MAKE_CLASS_x 54
-#define R_do_new_object_x 55
-#define R_do_slot_x 56
-#define R_do_slot_assign_x 57
-#define R_getContextCall_x 58
-#define R_getContextEnv_x 59
-#define R_getContextFun_x 60
-#define R_getContextSrcRef_x 61
-#define R_getGlobalFunctionContext_x 62
-#define R_getParentFunctionContext_x 63
-#define R_insideBrowser_x 64
-#define R_isEqual_x 65
-#define R_isGlobal_x 66
-#define R_lsInternal3_x 67
-#define R_new_custom_connection_x 68
-#define R_tryEval_x 69
-#define Rf_GetOption1_x 70
-#define Rf_PairToVectorList_x 71
-#define Rf_ScalarDouble_x 72
-#define Rf_ScalarInteger_x 73
-#define Rf_ScalarLogical_x 74
-#define Rf_ScalarString_x 75
-#define Rf_VectorToPairList_x 76
-#define Rf_allocArray_x 77
-#define Rf_allocMatrix_x 78
-#define Rf_allocVector_x 79
-#define Rf_any_duplicated_x 80
-#define Rf_asChar_x 81
-#define Rf_asCharacterFactor_x 82
-#define Rf_asInteger_x 83
-#define Rf_asLogical_x 84
-#define Rf_asReal_x 85
-#define Rf_classgets_x 86
-#define Rf_coerceVector_x 87
-#define Rf_cons_x 88
-#define Rf_copyListMatrix_x 89
-#define Rf_copyMatrix_x 90
-#define Rf_copyMostAttrib_x 91
-#define Rf_defineVar_x 92
-#define Rf_dunif_x 93
-#define Rf_duplicate_x 94
-#define Rf_error_x 95
-#define Rf_errorcall_x 96
-#define Rf_eval_x 97
-#define Rf_findFun_x 98
-#define Rf_findVar_x 99
-#define Rf_findVarInFrame_x 100
-#define Rf_findVarInFrame3_x 101
-#define Rf_getAttrib_x 102
-#define Rf_gsetVar_x 103
-#define Rf_inherits_x 104
-#define Rf_install_x 105
-#define Rf_installChar_x 106
-#define Rf_isNull_x 107
-#define Rf_isString_x 108
-#define Rf_lengthgets_x 109
-#define Rf_mkCharLenCE_x 110
-#define Rf_namesgets_x 111
-#define Rf_ncols_x 112
-#define Rf_nrows_x 113
-#define Rf_punif_x 114
-#define Rf_qunif_x 115
-#define Rf_runif_x 116
-#define Rf_setAttrib_x 117
-#define Rf_str2type_x 118
-#define Rf_warning_x 119
-#define Rf_warningcall_x 120
-#define Rprintf_x 121
-#define SETCADR_x 122
-#define SETCAR_x 123
-#define SETCDR_x 124
-#define SET_NAMED_FASTR_x 125
-#define SET_RDEBUG_x 126
-#define SET_RSTEP_x 127
-#define SET_S4_OBJECT_x 128
-#define SET_STRING_ELT_x 129
-#define SET_SYMVALUE_x 130
-#define SET_TAG_x 131
-#define SET_TYPEOF_FASTR_x 132
-#define SET_VECTOR_ELT_x 133
-#define STRING_ELT_x 134
-#define SYMVALUE_x 135
-#define TAG_x 136
-#define TYPEOF_x 137
-#define UNSET_S4_OBJECT_x 138
-#define VECTOR_ELT_x 139
-#define getConnectionClassString_x 140
-#define getOpenModeString_x 141
-#define getSummaryDescription_x 142
-#define isSeekable_x 143
-#define unif_rand_x 144
+#define COMPLEX_x 6
+#define DUPLICATE_ATTRIB_x 7
+#define ENCLOS_x 8
+#define FASTR_getConnectionChar_x 9
+#define GetRNGstate_x 10
+#define INTEGER_x 11
+#define IS_S4_OBJECT_x 12
+#define LENGTH_x 13
+#define LOGICAL_x 14
+#define NAMED_x 15
+#define OBJECT_x 16
+#define PRCODE_x 17
+#define PRENV_x 18
+#define PRINTNAME_x 19
+#define PRSEEN_x 20
+#define PRVALUE_x 21
+#define PutRNGstate_x 22
+#define RAW_x 23
+#define RDEBUG_x 24
+#define REAL_x 25
+#define RSTEP_x 26
+#define R_BaseEnv_x 27
+#define R_BaseNamespace_x 28
+#define R_BindingIsLocked_x 29
+#define R_CHAR_x 30
+#define R_CleanUp_x 31
+#define R_ExternalPtrAddr_x 32
+#define R_ExternalPtrProtected_x 33
+#define R_ExternalPtrTag_x 34
+#define R_FindNamespace_x 35
+#define R_GetConnection_x 36
+#define R_GlobalContext_x 37
+#define R_GlobalEnv_x 38
+#define R_Home_x 39
+#define R_HomeDir_x 40
+#define R_Interactive_x 41
+#define R_MakeExternalPtr_x 42
+#define R_MethodsNamespace_x 43
+#define R_NamespaceRegistry_x 44
+#define R_NewHashedEnv_x 45
+#define R_ParseVector_x 46
+#define R_PreserveObject_x 47
+#define R_PromiseExpr_x 48
+#define R_ProtectWithIndex_x 49
+#define R_ReadConnection_x 50
+#define R_ReleaseObject_x 51
+#define R_Reprotect_x 52
+#define R_SetExternalPtrAddr_x 53
+#define R_SetExternalPtrProtected_x 54
+#define R_SetExternalPtrTag_x 55
+#define R_TempDir_x 56
+#define R_ToplevelExec_x 57
+#define R_WriteConnection_x 58
+#define R_compute_identical_x 59
+#define R_do_MAKE_CLASS_x 60
+#define R_do_new_object_x 61
+#define R_do_slot_x 62
+#define R_do_slot_assign_x 63
+#define R_getContextCall_x 64
+#define R_getContextEnv_x 65
+#define R_getContextFun_x 66
+#define R_getContextSrcRef_x 67
+#define R_getGlobalFunctionContext_x 68
+#define R_getParentFunctionContext_x 69
+#define R_insideBrowser_x 70
+#define R_isEqual_x 71
+#define R_isGlobal_x 72
+#define R_lsInternal3_x 73
+#define R_new_custom_connection_x 74
+#define R_tryEval_x 75
+#define Rf_GetOption1_x 76
+#define Rf_PairToVectorList_x 77
+#define Rf_ScalarDouble_x 78
+#define Rf_ScalarInteger_x 79
+#define Rf_ScalarLogical_x 80
+#define Rf_ScalarString_x 81
+#define Rf_VectorToPairList_x 82
+#define Rf_allocArray_x 83
+#define Rf_allocMatrix_x 84
+#define Rf_allocVector_x 85
+#define Rf_any_duplicated_x 86
+#define Rf_asChar_x 87
+#define Rf_asCharacterFactor_x 88
+#define Rf_asInteger_x 89
+#define Rf_asLogical_x 90
+#define Rf_asReal_x 91
+#define Rf_classgets_x 92
+#define Rf_coerceVector_x 93
+#define Rf_cons_x 94
+#define Rf_copyListMatrix_x 95
+#define Rf_copyMatrix_x 96
+#define Rf_copyMostAttrib_x 97
+#define Rf_defineVar_x 98
+#define Rf_dunif_x 99
+#define Rf_duplicate_x 100
+#define Rf_error_x 101
+#define Rf_errorcall_x 102
+#define Rf_eval_x 103
+#define Rf_findFun_x 104
+#define Rf_findVar_x 105
+#define Rf_findVarInFrame_x 106
+#define Rf_findVarInFrame3_x 107
+#define Rf_getAttrib_x 108
+#define Rf_gsetVar_x 109
+#define Rf_inherits_x 110
+#define Rf_install_x 111
+#define Rf_installChar_x 112
+#define Rf_isNull_x 113
+#define Rf_isString_x 114
+#define Rf_lengthgets_x 115
+#define Rf_mkCharLenCE_x 116
+#define Rf_namesgets_x 117
+#define Rf_ncols_x 118
+#define Rf_nrows_x 119
+#define Rf_protect_x 120
+#define Rf_punif_x 121
+#define Rf_qunif_x 122
+#define Rf_runif_x 123
+#define Rf_setAttrib_x 124
+#define Rf_str2type_x 125
+#define Rf_unprotect_x 126
+#define Rf_unprotect_ptr_x 127
+#define Rf_warning_x 128
+#define Rf_warningcall_x 129
+#define Rprintf_x 130
+#define SETCADR_x 131
+#define SETCAR_x 132
+#define SETCDR_x 133
+#define SET_NAMED_FASTR_x 134
+#define SET_RDEBUG_x 135
+#define SET_RSTEP_x 136
+#define SET_S4_OBJECT_x 137
+#define SET_STRING_ELT_x 138
+#define SET_SYMVALUE_x 139
+#define SET_TAG_x 140
+#define SET_TYPEOF_FASTR_x 141
+#define SET_VECTOR_ELT_x 142
+#define STRING_ELT_x 143
+#define SYMVALUE_x 144
+#define TAG_x 145
+#define TYPEOF_x 146
+#define UNSET_S4_OBJECT_x 147
+#define VECTOR_ELT_x 148
+#define forceSymbols_x 149
+#define getCCallable_x 150
+#define getConnectionClassString_x 151
+#define getOpenModeString_x 152
+#define getSummaryDescription_x 153
+#define isSeekable_x 154
+#define registerCCallable_x 155
+#define registerRoutines_x 156
+#define setDotSymbolValues_x 157
+#define unif_rand_x 158
+#define useDynamicSymbols_x 159
 
-#define UPCALLS_TABLE_SIZE 145
+#define UPCALLS_TABLE_SIZE 160
 
 #endif // RFFI_UPCALLSINDEX_H
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rdynload_fastr.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rdynload_fastr.h
index 22be14a8c138534f96c0701c2c414cbd0f94ef94..7fc0ed31af72ddbb9e3aaa7e58cf7edbb5b4d05d 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rdynload_fastr.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rdynload_fastr.h
@@ -23,120 +23,3 @@
 #include <rffiutils.h>
 #include <Rdynload.h>
 
-// The implementation must implement:
-// void *ensure_function(void *fun)
-
-typedef void (*call_registerRoutines)(DllInfo *dllInfo, int nstOrd, int num, long routines);
-typedef int (*call_useDynamicSymbols)(DllInfo *dllInfo, Rboolean value);
-typedef void * (*call_setDotSymbolValues)(DllInfo *dllInfo, char *name, void *fun, int numArgs);
-typedef int (*call_forceSymbols)(DllInfo *dllInfo, Rboolean value);
-typedef int (*call_registerCCallable)(const char *pkgname, const char *name, void *fun);
-typedef void* (*call_getCCallable)(const char *pkgname, const char *name);
-
-#define registerRoutines_x 0
-#define setDotSymbolValues_x 1
-#define useDynamicSymbols_x 2
-#define forceSymbols_x 3
-#define registerCCallable_x 4
-#define getCCallable_x 5
-#define CALLBACK_TABLE_SIZE 6
-
-// Must match ordinal value for DLL.NativeSymbolType
-#define C_NATIVE_TYPE 0
-#define CALL_NATIVE_TYPE 1
-#define FORTRAN_NATIVE_TYPE 2
-#define EXTERNAL_NATIVE_TYPE 3
-
-int
-R_registerRoutines(DllInfo *info, const R_CMethodDef * const croutines,
-		   const R_CallMethodDef * const callRoutines,
-		   const R_FortranMethodDef * const fortranRoutines,
-		   const R_ExternalMethodDef * const externalRoutines) {
-	int num;
-	if (croutines) {
-		for(num = 0; croutines[num].name != NULL; num++) {;}
-		//printf("R_registerRoutines %p,%d,%d,%p\n", info, C_NATIVE_TYPE, num, croutines);
-		((call_registerRoutines) dynload_callbacks[registerRoutines_x])(info, C_NATIVE_TYPE, num, (long) croutines);
-	}
-	if (callRoutines) {
-		for(num = 0; callRoutines[num].name != NULL; num++) {;}
-		//printf("R_registerRoutines %p,%d,%d,%p\n", info, CALL_NATIVE_TYPE, num, callRoutines);
-		((call_registerRoutines) dynload_callbacks[registerRoutines_x])(info, CALL_NATIVE_TYPE, num, (long) callRoutines);
-	}
-	if (fortranRoutines) {
-		for(num = 0; fortranRoutines[num].name != NULL; num++) {;}
-		//printf("R_registerRoutines %p,%p,%d,%d,%p\n", info, FORTRAN_NATIVE_TYPE, num, fortranRoutines);
-		((call_registerRoutines) dynload_callbacks[registerRoutines_x])(info, FORTRAN_NATIVE_TYPE, num, (long) fortranRoutines);
-	}
-	if (externalRoutines) {
-		for(num = 0; externalRoutines[num].name != NULL; num++) {;}
-		//printf("R_registerRoutines %p,%d,%d,%p\n", info, EXTERNAL_NATIVE_TYPE, num, externalRoutines);
-		((call_registerRoutines) dynload_callbacks[registerRoutines_x])(info, EXTERNAL_NATIVE_TYPE, num, (long) externalRoutines);
-	}
-    return 1;
-}
-
-Rboolean R_useDynamicSymbols(DllInfo *dllInfo, Rboolean value) {
-	//printf("R_useDynamicSymbols %p %d %p\n", dllInfo, value);
-	return ((call_useDynamicSymbols) dynload_callbacks[useDynamicSymbols_x])(dllInfo, value);
-}
-
-Rboolean R_forceSymbols(DllInfo *dllInfo, Rboolean value) {
-	//printf("R_forceSymbols %p %d\n", dllInfo, value);
-	return ((call_forceSymbols) dynload_callbacks[forceSymbols_x])(dllInfo, value);
-}
-
-
-void *Rdynload_setSymbol(DllInfo *info, int nstOrd, long routinesAddr, int index) {
-	const char *name;
-	void * fun;
-	int numArgs;
-	switch (nstOrd) {
-	case C_NATIVE_TYPE: {
-		R_CMethodDef *croutines = (R_CMethodDef *) routinesAddr;
-		name = croutines[index].name;
-		fun = croutines[index].fun;
-		numArgs = croutines[index].numArgs;
-		break;
-	}
-	case CALL_NATIVE_TYPE: {
-		R_CallMethodDef *callRoutines = (R_CallMethodDef *) routinesAddr;
-		name = callRoutines[index].name;
-		fun = callRoutines[index].fun;
-		numArgs = callRoutines[index].numArgs;
-		break;
-	}
-	case FORTRAN_NATIVE_TYPE: {
-		R_FortranMethodDef * fortranRoutines = (R_FortranMethodDef *) routinesAddr;
-		name = fortranRoutines[index].name;
-		fun = fortranRoutines[index].fun;
-		numArgs = fortranRoutines[index].numArgs;
-		break;
-	}
-	case EXTERNAL_NATIVE_TYPE: {
-		R_ExternalMethodDef * externalRoutines = (R_ExternalMethodDef *) routinesAddr;
-		name = externalRoutines[index].name;
-		fun = externalRoutines[index].fun;
-		numArgs = externalRoutines[index].numArgs;
-		break;
-	}
-	}
-	//printf("call_setDotSymbolValues %p, %s, %p, %d\n", info, name, fun, numArgs);
-	void *result = ((call_setDotSymbolValues) dynload_callbacks[setDotSymbolValues_x])(info, ensure_string(name), ensure_fun(fun), numArgs);
-	return result;
-}
-
-void R_RegisterCCallable(const char *package, const char *name, DL_FUNC fptr) {
-	//printf("R_RegisterCCallable %s %s %p\n", package, name, fptr);
-	((call_registerCCallable) dynload_callbacks[registerCCallable_x])(ensure_string(package), ensure_string(name), ensure_fun((void *)fptr));
-}
-
-DL_FUNC R_GetCCallable(const char *package, const char *name) {
-	//printf("R_GetCCallable %s %s %p\n", package, name);
-	return ((call_getCCallable) dynload_callbacks[getCCallable_x])(ensure_string(package), ensure_string(name));
-}
-
-DL_FUNC R_FindSymbol(char const *name, char const *pkg,
-		     R_RegisteredNativeSymbol *symbol) {
-    return unimplemented("R_FindSymbol");
-}
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
index 767572ed9dcd0d6a4fa390d50702bfef2615f0b6..f3a5c2850db990360e88efb8c4b24c63d3613a7a 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
@@ -25,13 +25,6 @@
    truffle_nfi and truffle_llvm directories.
    The implementation must define the following five functions:
 
-   SEXP checkRef(SEXP x)
-     Checks for 'x' being "handle" and returns the canionical handle.
-
-   SEXP newObjectHandle(SEXP x)
-
-   void releaseObjectHandle(SEXP x)
-
    char *ensure_truffle_chararray_n(const char *x, int n)
      Ensures that the sequence of 'n' bytes starting at 'x' is in the
      appropriate representation for the implementation.
@@ -43,99 +36,147 @@
    Any of these functions could be the identity function.
 */
 
+// tracing/debugging support, set to 1 and recompile to enable
+#define TRACE_UPCALLS 0    // trace upcalls
+
+#define TARGp "%s(%p)\n"
+#define TARGpp "%s(%p, %p)\n"
+#define TARGppp "%s(%p, %p, %p)\n"
+#define TARGpd "%s(%p, %d)\n"
+#define TARGppd "%s(%p, %p, %d)\n"
+#define TARGs "%s(\"%s\")\n"
+#define TARGps "%s(%p, \"%s\")\n"
+#define TARGsdd "%s(\"%s\", %d, %d)\n"
+
+#if TRACE_UPCALLS
+#define TRACE(format, ...) printf("%s " format "\n", __FUNCTION__, __VA_ARGS__)
+#define TRACE0() printf("%s\n", __FUNCTION__)
+#define TRACE1(x) printf("%s %p\n", __FUNCTION__, x)
+#define TRACE2(x, y) printf("%s %p %p\n", __FUNCTION__, x, y)
+#define TRACE3(x, y, z) printf("%s %p %p %p\n", __FUNCTION__, x, y, z)
+#else
+#define TRACE(format, ...)
+#define TRACE0()
+#define TRACE1(x)
+#define TRACE2(x, y)
+#define TRACE3(x, y, z)
+#endif
+
+#define UNIMPLEMENTED unimplemented(__FUNCTION__)
+
 // R_GlobalEnv et al are not a variables in FASTR as they are RContext specific
 SEXP FASTR_R_GlobalEnv() {
+    TRACE0();
 	return ((call_R_GlobalEnv) callbacks[R_GlobalEnv_x])();
 }
 
 SEXP FASTR_R_BaseEnv() {
+    TRACE0();
 	return ((call_R_BaseEnv) callbacks[R_BaseEnv_x])();
 }
 
 SEXP FASTR_R_BaseNamespace() {
+    TRACE0();
 	return ((call_R_BaseNamespace) callbacks[R_BaseNamespace_x])();
 }
 
 SEXP FASTR_R_NamespaceRegistry() {
+    TRACE0();
 	return ((call_R_NamespaceRegistry) callbacks[R_NamespaceRegistry_x])();
 }
 
 CTXT FASTR_GlobalContext() {
+    TRACE0();
 	return ((call_R_GlobalContext) callbacks[R_GlobalContext_x])();
 }
 
 Rboolean FASTR_R_Interactive() {
+    TRACE0();
 	return (int) ((call_R_Interactive) callbacks[R_Interactive_x])();
 }
 
 SEXP CAR(SEXP e) {
-	return checkRef(((call_CAR) callbacks[CAR_x])(e));
+    TRACE1(e);
+	return ((call_CAR) callbacks[CAR_x])(e);
 }
 
 SEXP CDR(SEXP e) {
-	return checkRef(((call_CDR) callbacks[CDR_x])(e));
+    TRACE1(e);
+	return ((call_CDR) callbacks[CDR_x])(e);
 }
 
 int LENGTH(SEXP x) {
+    TRACE1(x);
 	return ((call_LENGTH) callbacks[LENGTH_x])(x);
 }
 
 SEXP Rf_ScalarString(SEXP value) {
-	return checkRef(((call_Rf_ScalarString) callbacks[Rf_ScalarString_x])(value));
+    TRACE1(value);
+	return ((call_Rf_ScalarString) callbacks[Rf_ScalarString_x])(value);
 }
 
 SEXP Rf_mkString(const char *s) {
+    TRACE0();
 	return ScalarString(Rf_mkChar(s));
 }
 
 void Rf_gsetVar(SEXP symbol, SEXP value, SEXP rho) {
+    TRACE0();
 	((call_Rf_gsetVar) callbacks[Rf_gsetVar_x])(symbol, value, rho);
 }
 
 SEXP Rf_coerceVector(SEXP x, SEXPTYPE mode) {
-	return checkRef(((call_Rf_coerceVector) callbacks[Rf_coerceVector_x])(x, mode));
+    TRACE0();
+	return ((call_Rf_coerceVector) callbacks[Rf_coerceVector_x])(x, mode);
 }
 
 SEXP Rf_cons(SEXP car, SEXP cdr) {
-	return checkRef(((call_Rf_cons) callbacks[Rf_cons_x])(car, cdr));
+    TRACE0();
+	return ((call_Rf_cons) callbacks[Rf_cons_x])(car, cdr);
 }
 
 SEXP Rf_GetOption1(SEXP tag) {
-	return checkRef(((call_Rf_GetOption1) callbacks[Rf_GetOption1_x])(tag));
+    TRACE0();
+	return ((call_Rf_GetOption1) callbacks[Rf_GetOption1_x])(tag);
 }
 
 SEXP Rf_mkChar(const char *x) {
+    TRACE0();
 	return Rf_mkCharLenCE(x, strlen(x), CE_NATIVE);
 }
 
 SEXP Rf_mkCharCE(const char *x, cetype_t y) {
+    TRACE0();
 	return Rf_mkCharLenCE(x, strlen(x), y);
 }
 
 SEXP Rf_mkCharLen(const char *x, int y) {
+    TRACE0();
 	return Rf_mkCharLenCE(x, y, CE_NATIVE);
 }
 
 SEXP Rf_mkCharLenCE(const char *x, int len, cetype_t enc) {
-	return checkRef(((call_Rf_mkCharLenCE) callbacks[Rf_mkCharLenCE_x])(ensure_truffle_chararray_n(x, len), len, enc));
+    TRACE0();
+	return ((call_Rf_mkCharLenCE) callbacks[Rf_mkCharLenCE_x])(ensure_truffle_chararray_n(x, len), len, enc);
 }
 
 #define BUFSIZE 8192
 
-static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap)
-{
+static int Rvsnprintf(char *buf, size_t size, const char  *format, va_list ap) {
+    TRACE0();
     int val;
     val = vsnprintf(buf, size, format, ap);
     buf[size-1] = '\0';
     return val;
 }
 
-
 void Rf_errorcall(SEXP x, const char *format, ...) {
-	unimplemented("Rf_errorcall");
+    TRACE0();
+    UNIMPLEMENTED;
 }
 
 void Rf_warningcall(SEXP x, const char *format, ...) {
+    TRACE0();
 	char buf[8192];
 	va_list(ap);
 	va_start(ap,format);
@@ -145,6 +186,7 @@ void Rf_warningcall(SEXP x, const char *format, ...) {
 }
 
 void Rf_warning(const char *format, ...) {
+    TRACE0();
 	char buf[8192];
 	va_list(ap);
 	va_start(ap, format);
@@ -154,6 +196,7 @@ void Rf_warning(const char *format, ...) {
 }
 
 void Rprintf(const char *format, ...) {
+    TRACE0();
 	char buf[8192];
 	va_list(ap);
 	va_start(ap,format);
@@ -163,6 +206,7 @@ void Rprintf(const char *format, ...) {
 }
 
 void Rf_error(const char *format, ...) {
+    TRACE0();
 	// This is a bit tricky. The usual error handling model in Java is "throw RError.error(...)" but
 	// RError.error does quite a lot of stuff including potentially searching for R condition handlers
 	// and, if it finds any, does not return, but throws a different exception than RError.
@@ -174,17 +218,16 @@ void Rf_error(const char *format, ...) {
 	va_end(ap);
 	((call_Rf_error) callbacks[Rf_error_x])(ensure_string(buf));
 	// Should not reach here
-	unimplemented("Rf_error");
+	UNIMPLEMENTED;
 }
 
-
 /*
   REprintf is used by the error handler do not add
   anything unless you're sure it won't
   cause problems
 */
-void REprintf(const char *format, ...)
-{
+void REprintf(const char *format, ...) {
+    TRACE0();
 	// TODO: determine correct target for this message
 	char buf[8192];
 	va_list(ap);
@@ -195,118 +238,143 @@ void REprintf(const char *format, ...)
 }
 
 void Rvprintf(const char *format, va_list args) {
-	unimplemented("Rvprintf");
+    TRACE0();
+    UNIMPLEMENTED;
 }
+
 void REvprintf(const char *format, va_list args) {
-	unimplemented("REvprintf");
+    TRACE0();
+    UNIMPLEMENTED;
 }
 
-
 SEXP Rf_ScalarInteger(int value) {
-	return checkRef(((call_Rf_ScalarInteger) callbacks[Rf_ScalarInteger_x])(value));
+    TRACE0();
+	return ((call_Rf_ScalarInteger) callbacks[Rf_ScalarInteger_x])(value);
 }
 
 SEXP Rf_ScalarReal(double value) {
-	return checkRef(((call_Rf_ScalarReal) callbacks[Rf_ScalarDouble_x])(value));
+    TRACE0();
+	return ((call_Rf_ScalarReal) callbacks[Rf_ScalarDouble_x])(value);
 }
 
 SEXP Rf_ScalarLogical(int value) {
-	return checkRef(((call_Rf_ScalarLogical) callbacks[Rf_ScalarLogical_x])(value));
+    TRACE0();
+	return ((call_Rf_ScalarLogical) callbacks[Rf_ScalarLogical_x])(value);
 }
 
 SEXP Rf_allocVector3(SEXPTYPE t, R_xlen_t len, R_allocator_t* allocator) {
+    TRACE0();
     if (allocator != NULL) {
-  	    unimplemented("RF_allocVector with custom allocator");
-	    return NULL;
+        return UNIMPLEMENTED;
     }
-    return checkRef(((call_Rf_allocVector) callbacks[Rf_allocVector_x])(t, len));
+    return ((call_Rf_allocVector) callbacks[Rf_allocVector_x])(t, len);
 }
 
 SEXP Rf_allocArray(SEXPTYPE t, SEXP dims) {
-	return checkRef(((call_Rf_allocArray) callbacks[Rf_allocArray_x])(t, dims));
+    TRACE0();
+	return ((call_Rf_allocArray) callbacks[Rf_allocArray_x])(t, dims);
 }
 
 SEXP Rf_alloc3DArray(SEXPTYPE t, int x, int y, int z) {
-	return unimplemented("Rf_alloc3DArray");
+    TRACE0();
+	return UNIMPLEMENTED;
 }
 
 SEXP Rf_allocMatrix(SEXPTYPE mode, int nrow, int ncol) {
-	return checkRef(((call_Rf_allocMatrix) callbacks[Rf_allocMatrix_x])(mode, nrow, ncol));
+    TRACE0();
+	return ((call_Rf_allocMatrix) callbacks[Rf_allocMatrix_x])(mode, nrow, ncol);
 }
 
 SEXP Rf_allocList(int x) {
-	unimplemented("Rf_allocList)");
-	return NULL;
+    TRACE0();
+    return UNIMPLEMENTED;
 }
 
 SEXP Rf_allocSExp(SEXPTYPE t) {
-	return unimplemented("Rf_allocSExp");
+    TRACE0();
+    return UNIMPLEMENTED;
 }
 
 void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho) {
+    TRACE0();
 	((call_Rf_defineVar) callbacks[Rf_defineVar_x])(symbol, value, rho);
 }
 
 void Rf_setVar(SEXP x, SEXP y, SEXP z) {
+    TRACE0();
     unimplemented("Rf_setVar");
 }
 
 SEXP Rf_dimgets(SEXP x, SEXP y) {
+    TRACE0();
 	return unimplemented("Rf_dimgets");
 }
 
 SEXP Rf_dimnamesgets(SEXP x, SEXP y) {
+    TRACE0();
 	return unimplemented("Rf_dimnamesgets");
 }
 
 SEXP Rf_eval(SEXP expr, SEXP env) {
-	return checkRef(((call_Rf_eval) callbacks[Rf_eval_x])(expr, env));
+    TRACE0();
+	return ((call_Rf_eval) callbacks[Rf_eval_x])(expr, env);
 }
 
 SEXP Rf_findFun(SEXP symbol, SEXP rho) {
-	return checkRef(((call_Rf_findFun) callbacks[Rf_findFun_x])(symbol, rho));
+    TRACE0();
+	return ((call_Rf_findFun) callbacks[Rf_findFun_x])(symbol, rho);
 }
 
 SEXP Rf_findVar(SEXP sym, SEXP rho) {
-	return checkRef(((call_Rf_findVar) callbacks[Rf_findVar_x])(sym, rho));
+    TRACE0();
+	return ((call_Rf_findVar) callbacks[Rf_findVar_x])(sym, rho);
 }
 
 SEXP Rf_findVarInFrame(SEXP rho, SEXP sym) {
-	return checkRef(((call_Rf_findVarInFrame) callbacks[Rf_findVarInFrame_x])(rho, sym));
+    TRACE0();
+	return ((call_Rf_findVarInFrame) callbacks[Rf_findVarInFrame_x])(rho, sym);
 }
 
 SEXP Rf_findVarInFrame3(SEXP rho, SEXP sym, Rboolean b) {
-	return checkRef(((call_Rf_findVarInFrame3) callbacks[Rf_findVarInFrame3_x])(rho, sym, b));
+    TRACE0();
+	return ((call_Rf_findVarInFrame3) callbacks[Rf_findVarInFrame3_x])(rho, sym, b);
 }
 
 SEXP Rf_getAttrib(SEXP vec, SEXP name) {
+    TRACE0();
 	SEXP result = ((call_Rf_getAttrib) callbacks[Rf_getAttrib_x])(vec, name);
 //	printf("Rf_getAttrib: %p\n", result);
 	return result;
 }
 
 SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val) {
-	return checkRef(((call_Rf_setAttrib) callbacks[Rf_setAttrib_x])(vec, name, val));
+    TRACE0();
+	return ((call_Rf_setAttrib) callbacks[Rf_setAttrib_x])(vec, name, val);
 }
 
 SEXP Rf_duplicate(SEXP x) {
-	return checkRef(((call_Rf_duplicate) callbacks[Rf_duplicate_x])(x, 1));
+    TRACE0();
+	return ((call_Rf_duplicate) callbacks[Rf_duplicate_x])(x, 1);
 }
 
 SEXP Rf_shallow_duplicate(SEXP x) {
-	return checkRef(((call_Rf_duplicate) callbacks[Rf_duplicate_x])(x, 0));
+    TRACE0();
+	return ((call_Rf_duplicate) callbacks[Rf_duplicate_x])(x, 0);
 }
 
 R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) {
+    TRACE0();
 	return (R_xlen_t) ((call_Rf_any_duplicated) callbacks[Rf_any_duplicated_x])(x, from_last);
 }
 
 SEXP Rf_duplicated(SEXP x, Rboolean y) {
+    TRACE0();
 	unimplemented("Rf_duplicated");
 	return NULL;
 }
 
 SEXP Rf_applyClosure(SEXP x, SEXP y, SEXP z, SEXP a, SEXP b) {
+    TRACE0();
 	return unimplemented("Rf_applyClosure");
 }
 
@@ -315,791 +383,1064 @@ void Rf_copyMostAttrib(SEXP x, SEXP y) {
 }
 
 void Rf_copyVector(SEXP x, SEXP y) {
+    TRACE0();
 	unimplemented("Rf_copyVector");
 }
 
 int Rf_countContexts(int x, int y) {
+    TRACE0();
 	return (int) unimplemented("Rf_countContexts");
 }
 
 Rboolean Rf_inherits(SEXP x, const char * klass) {
+    TRACE0();
 	return (Rboolean) ((call_Rf_inherits) callbacks[Rf_inherits_x])(x, ensure_string(klass));
 }
 
 Rboolean Rf_isObject(SEXP s) {
+    TRACE0();
 	unimplemented("Rf_isObject");
 	return FALSE;
 }
 
 void Rf_PrintValue(SEXP x) {
+    TRACE0();
 	unimplemented("Rf_PrintValue");
 }
 
 SEXP Rf_install(const char *name) {
-	return checkRef(((call_Rf_install) callbacks[Rf_install_x])(ensure_string(name)));
+    TRACE0();
+	return ((call_Rf_install) callbacks[Rf_install_x])(ensure_string(name));
 }
 
 SEXP Rf_installChar(SEXP charsxp) {
-	return checkRef(((call_Rf_installChar) callbacks[Rf_installChar_x])(charsxp));
+    TRACE0();
+	return ((call_Rf_installChar) callbacks[Rf_installChar_x])(charsxp);
 }
 
 Rboolean Rf_isNull(SEXP s) {
+    TRACE0();
 	return (Rboolean) ((call_Rf_isNull) callbacks[Rf_isNull_x])(s);
 }
 
 Rboolean Rf_isString(SEXP s) {
+    TRACE0();
 	return (Rboolean) ((call_Rf_isString) callbacks[Rf_isString_x])(s);
 }
 
 Rboolean R_cycle_detected(SEXP s, SEXP child) {
+    TRACE0();
 	unimplemented("R_cycle_detected");
 	return 0;
 }
 
 cetype_t Rf_getCharCE(SEXP x) {
+    TRACE0();
     // unimplemented("Rf_getCharCE");
     // TODO: real implementation
     return CE_NATIVE;
 }
 
 const char *Rf_reEnc(const char *x, cetype_t ce_in, cetype_t ce_out, int subst) {
+    TRACE0();
 	// TODO proper implementation
 	return x;
 }
 
 int Rf_ncols(SEXP x) {
+    TRACE1(x);
 	return (int) ((call_Rf_ncols) callbacks[Rf_ncols_x])(x);
 }
 
 int Rf_nrows(SEXP x) {
+    TRACE1(x);
 	return (int) ((call_Rf_nrows) callbacks[Rf_nrows_x])(x);
 }
 
-
 SEXP Rf_protect(SEXP x) {
-	return x;
+    TRACE1(x);
+    return ((call_Rf_protect) callbacks[Rf_protect_x])(x);
 }
 
 void Rf_unprotect(int x) {
+    TRACE("%d", x);
+    ((call_Rf_unprotect) callbacks[Rf_unprotect_x])(x);
 }
 
 void R_ProtectWithIndex(SEXP x, PROTECT_INDEX *y) {
-	//
+    TRACE1(x);
+    *y = ((call_R_ProtectWithIndex) callbacks[R_ProtectWithIndex_x])(x);
 }
 
 void R_Reprotect(SEXP x, PROTECT_INDEX y) {
-	//
+    TRACE("%p %i", x, y);
+    return ((call_R_Reprotect) callbacks[R_Reprotect_x])(x, y);
 }
 
-
 void Rf_unprotect_ptr(SEXP x) {
-	//
+    TRACE1(x);
+    return ((call_Rf_unprotect_ptr) callbacks[Rf_unprotect_ptr_x])(x);
 }
 
-
 void R_FlushConsole(void) {
+    TRACE0();
 	// ignored
 }
 
 void R_ProcessEvents(void) {
+    TRACE0();
 	unimplemented("R_ProcessEvents");
 }
 
 // Tools package support, not in public API
 SEXP R_NewHashedEnv(SEXP parent, SEXP size) {
-	return checkRef(((call_R_NewHashedEnv) callbacks[R_NewHashedEnv_x])(parent, size));
+    TRACE2(parent, size);
+	return ((call_R_NewHashedEnv) callbacks[R_NewHashedEnv_x])(parent, size);
 }
 
 SEXP Rf_classgets(SEXP vec, SEXP klass) {
-	return checkRef(((call_Rf_classgets) callbacks[Rf_classgets_x])(vec, klass));
+    TRACE2(vec, klass);
+	return ((call_Rf_classgets) callbacks[Rf_classgets_x])(vec, klass);
 }
 
 const char *Rf_translateChar(SEXP x) {
+    TRACE1(x);
 	// TODO: proper implementation
 	const char *result = CHAR(x);
 	return result;
 }
 
 const char *Rf_translateChar0(SEXP x) {
+    TRACE1(x);
 	// TODO: proper implementation
 	const char *result = CHAR(x);
 	return result;
 }
 
 const char *Rf_translateCharUTF8(SEXP x) {
+    TRACE1(x);
 	// TODO: proper implementation
 	const char *result = CHAR(x);
 	return result;
 }
 
 SEXP Rf_lengthgets(SEXP x, R_len_t y) {
-	return checkRef(((call_Rf_lengthgets) callbacks[Rf_lengthgets_x])(x, y));
+    TRACE1(x);
+	return ((call_Rf_lengthgets) callbacks[Rf_lengthgets_x])(x, y);
 }
 
 SEXP Rf_xlengthgets(SEXP x, R_xlen_t y) {
+    TRACE1(x);
 	return unimplemented("Rf_xlengthgets");
 }
 
 SEXP R_lsInternal(SEXP env, Rboolean all) {
+    TRACE1(env);
 	return R_lsInternal3(env, all, TRUE);
 }
 
 SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted) {
-	return checkRef(((call_R_lsInternal3) callbacks[R_lsInternal3_x])(env, all, sorted));
+    TRACE0();
+	return ((call_R_lsInternal3) callbacks[R_lsInternal3_x])(env, all, sorted);
 }
 
 SEXP Rf_namesgets(SEXP x, SEXP y) {
-	return checkRef(((call_Rf_namesgets) callbacks[Rf_namesgets_x])(x, y));
+    TRACE0();
+	return ((call_Rf_namesgets) callbacks[Rf_namesgets_x])(x, y);
 }
 
 SEXP TAG(SEXP e) {
-	return checkRef(((call_TAG) callbacks[TAG_x])(e));
+    TRACE0();
+	return ((call_TAG) callbacks[TAG_x])(e);
 }
 
 SEXP PRINTNAME(SEXP e) {
-	return checkRef(((call_PRINTNAME) callbacks[PRINTNAME_x])(e));
+    TRACE0();
+	return ((call_PRINTNAME) callbacks[PRINTNAME_x])(e);
 }
 
-
 SEXP CAAR(SEXP e) {
+    TRACE0();
     unimplemented("CAAR");
     return NULL;
 }
 
 SEXP CDAR(SEXP e) {
+    TRACE0();
     unimplemented("CDAR");
     return NULL;
 }
 
 SEXP CADR(SEXP e) {
-	return checkRef(((call_CADR) callbacks[CADR_x])(e));
+    TRACE0();
+	return ((call_CADR) callbacks[CADR_x])(e);
 }
 
 SEXP CDDR(SEXP e) {
-	return checkRef(((call_CDDR) callbacks[CDDR_x])(e));
+    TRACE0();
+	return ((call_CDDR) callbacks[CDDR_x])(e);
 }
 
 SEXP CDDDR(SEXP e) {
+    TRACE0();
     unimplemented("CDDDR");
     return NULL;
 }
 
 SEXP CADDR(SEXP e) {
-	return checkRef(((call_CADDR) callbacks[CADDR_x])(e));
+    TRACE0();
+	return ((call_CADDR) callbacks[CADDR_x])(e);
 }
 
 SEXP CADDDR(SEXP e) {
+    TRACE0();
     unimplemented("CADDDR");
     return NULL;
 }
 
 SEXP CAD4R(SEXP e) {
+    TRACE0();
     unimplemented("CAD4R");
     return NULL;
 }
 
-int MISSING(SEXP x){
+int MISSING(SEXP x) {
+    TRACE0();
     unimplemented("MISSING");
     return 0;
 }
 
 void SET_MISSING(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_MISSING");
 }
 
 void SET_TAG(SEXP x, SEXP y) {
+    TRACE0();
 	((call_SET_TAG) callbacks[SET_TAG_x])(x, y);
 }
 
 SEXP SETCAR(SEXP x, SEXP y) {
-	return checkRef(((call_SETCAR) callbacks[SETCAR_x])(x, y));
+    TRACE0();
+	return ((call_SETCAR) callbacks[SETCAR_x])(x, y);
 }
 
 SEXP SETCDR(SEXP x, SEXP y) {
-	return checkRef(((call_SETCDR) callbacks[SETCDR_x])(x, y));
+    TRACE0();
+	return ((call_SETCDR) callbacks[SETCDR_x])(x, y);
 }
 
 SEXP SETCADR(SEXP x, SEXP y) {
-	return checkRef(((call_SETCADR) callbacks[SETCADR_x])(x, y));
+    TRACE0();
+	return ((call_SETCADR) callbacks[SETCADR_x])(x, y);
 }
 
 SEXP SETCADDR(SEXP x, SEXP y) {
+    TRACE0();
     unimplemented("SETCADDR");
     return NULL;
 }
 
 SEXP SETCADDDR(SEXP x, SEXP y) {
+    TRACE0();
     unimplemented("SETCADDDR");
     return NULL;
 }
 
 SEXP SETCAD4R(SEXP e, SEXP y) {
+    TRACE0();
     unimplemented("SETCAD4R");
     return NULL;
 }
 
 SEXP FORMALS(SEXP x) {
+    TRACE0();
     return unimplemented("FORMALS");
 }
 
 SEXP BODY(SEXP x) {
+    TRACE0();
 	return unimplemented("BODY");
 }
 
 SEXP CLOENV(SEXP x) {
+    TRACE0();
 	return unimplemented("CLOENV");
 }
 
 int RDEBUG(SEXP x) {
+    TRACE0();
 	return ((call_RDEBUG) callbacks[RDEBUG_x])(x);
 }
 
 int RSTEP(SEXP x) {
+    TRACE0();
 	return ((call_RSTEP) callbacks[RSTEP_x])(x);
 }
 
 int RTRACE(SEXP x) {
+    TRACE0();
 	unimplemented("RTRACE");
     return 0;
 }
 
 void SET_RDEBUG(SEXP x, int v) {
+    TRACE0();
 	((call_SET_RDEBUG) callbacks[SET_RDEBUG_x])(x, v);
 }
 
 void SET_RSTEP(SEXP x, int v) {
+    TRACE0();
 	((call_SET_RSTEP) callbacks[SET_RSTEP_x])(x, v);
 }
 
 void SET_RTRACE(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_RTRACE");
 }
 
 void SET_FORMALS(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_FORMALS");
 }
 
 void SET_BODY(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_BODY");
 }
 
 void SET_CLOENV(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_CLOENV");
 }
 
 SEXP SYMVALUE(SEXP x) {
-	return checkRef(((call_SYMVALUE) callbacks[SYMVALUE_x])(x));
+    TRACE0();
+	return ((call_SYMVALUE) callbacks[SYMVALUE_x])(x);
 }
 
 SEXP INTERNAL(SEXP x) {
+    TRACE0();
 	return unimplemented("INTERNAL");
 }
 
 int DDVAL(SEXP x) {
+    TRACE0();
 	unimplemented("DDVAL");
     return 0;
 }
 
 void SET_DDVAL(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_DDVAL");
 }
 
 void SET_SYMVALUE(SEXP x, SEXP v) {
+    TRACE0();
 	((call_SET_SYMVALUE) callbacks[SET_SYMVALUE_x])(x, v);
 }
 
 void SET_INTERNAL(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_INTERNAL");
 }
 
 SEXP FRAME(SEXP x) {
+    TRACE0();
 	return unimplemented("FRAME");
 }
 
 SEXP ENCLOS(SEXP x) {
-	return checkRef(((call_ENCLOS) callbacks[ENCLOS_x])(x));
+    TRACE0();
+	return ((call_ENCLOS) callbacks[ENCLOS_x])(x);
 }
 
 SEXP HASHTAB(SEXP x) {
+    TRACE0();
 	return unimplemented("HASHTAB");
 }
 
 int ENVFLAGS(SEXP x) {
+    TRACE0();
 	unimplemented("ENVFLAGS");
     return 0;
 }
 
 void SET_ENVFLAGS(SEXP x, int v) {
+    TRACE0();
 	unimplemented("SET_ENVFLAGS");
 }
 
 void SET_FRAME(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_FRAME");
 }
 
 void SET_ENCLOS(SEXP x, SEXP v) {
+    TRACE0();
 	unimplemented("SET_ENCLOS");
 }
 
 void SET_HASHTAB(SEXP x, SEXP v) {
+    TRACE0();
 	unimplemented("SET_HASHTAB");
 }
 
 SEXP PRCODE(SEXP x) {
-	return checkRef(((call_PRCODE) callbacks[PRCODE_x])(x));
+    TRACE0();
+	return ((call_PRCODE) callbacks[PRCODE_x])(x);
 }
 
 SEXP PRENV(SEXP x) {
-	return checkRef(((call_PRENV) callbacks[PRENV_x])(x));
+    TRACE0();
+	return ((call_PRENV) callbacks[PRENV_x])(x);
 }
 
 SEXP PRVALUE(SEXP x) {
-	return checkRef(((call_PRVALUE) callbacks[PRVALUE_x])(x));
+    TRACE0();
+	return ((call_PRVALUE) callbacks[PRVALUE_x])(x);
 }
 
 int PRSEEN(SEXP x) {
+    TRACE0();
 	return ((call_PRSEEN) callbacks[PRSEEN_x])(x);
 }
 
 void SET_PRSEEN(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_PRSEEN");
 }
 
 void SET_PRENV(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_PRENV");
 }
 
 void SET_PRVALUE(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_PRVALUE");
 }
 
 void SET_PRCODE(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_PRCODE");
 }
 
-int TRUELENGTH(SEXP x){
+int TRUELENGTH(SEXP x) {
+    TRACE0();
     unimplemented("unimplemented");
     return 0;
 }
 
-
-void SETLENGTH(SEXP x, int v){
+void SETLENGTH(SEXP x, int v) {
+    TRACE0();
     unimplemented("SETLENGTH");
 }
 
-
-void SET_TRUELENGTH(SEXP x, int v){
+void SET_TRUELENGTH(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_TRUELENGTH");
 }
 
-
-R_xlen_t XLENGTH(SEXP x){
+R_xlen_t XLENGTH(SEXP x) {
+    TRACE0();
     // xlength seems to be used for long vectors (no such thing in FastR at the moment)
     return LENGTH(x);
 }
 
-
-R_xlen_t XTRUELENGTH(SEXP x){
+R_xlen_t XTRUELENGTH(SEXP x) {
+    TRACE0();
 	unimplemented("XTRUELENGTH");
 	return 0;
 }
 
-
-int IS_LONG_VEC(SEXP x){
+int IS_LONG_VEC(SEXP x) {
+    TRACE0();
 	unimplemented("IS_LONG_VEC");
 	return 0;
 }
 
-
-int LEVELS(SEXP x){
+int LEVELS(SEXP x) {
+    TRACE0();
 	unimplemented("LEVELS");
 	return 0;
 }
 
-
-int SETLEVELS(SEXP x, int v){
+int SETLEVELS(SEXP x, int v) {
+    TRACE0();
 	unimplemented("SETLEVELS");
 	return 0;
 }
 
-Rcomplex *COMPLEX(SEXP x){
+Rcomplex *COMPLEX(SEXP x) {
+    TRACE0();
 	return (Rcomplex*) unimplemented("COMPLEX");
 }
 
 SEXP STRING_ELT(SEXP x, R_xlen_t i) {
-	return checkRef(((call_STRING_ELT) callbacks[STRING_ELT_x])(x, i));
+    TRACE0();
+	return ((call_STRING_ELT) callbacks[STRING_ELT_x])(x, i);
 }
 
-
-SEXP VECTOR_ELT(SEXP x, R_xlen_t i){
-	return checkRef(((call_VECTOR_ELT) callbacks[VECTOR_ELT_x])(x, i));
+SEXP VECTOR_ELT(SEXP x, R_xlen_t i) {
+    TRACE0();
+	return ((call_VECTOR_ELT) callbacks[VECTOR_ELT_x])(x, i);
 }
 
-void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v){
+void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v) {
+    TRACE0();
     ((call_SET_STRING_ELT) callbacks[SET_STRING_ELT_x])(x, i, v);
 }
 
-
-SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v){
-	return checkRef(((call_SET_VECTOR_ELT) callbacks[SET_VECTOR_ELT_x])(x, i, v));
+SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v) {
+    TRACE0();
+	return ((call_SET_VECTOR_ELT) callbacks[SET_VECTOR_ELT_x])(x, i, v);
 }
 
-SEXP *STRING_PTR(SEXP x){
+SEXP *STRING_PTR(SEXP x) {
+    TRACE0();
 	unimplemented("STRING_PTR");
 	return NULL;
 }
 
-
-SEXP * NORET VECTOR_PTR(SEXP x){
+SEXP * NORET VECTOR_PTR(SEXP x) {
+    TRACE0();
 	unimplemented("VECTOR_PTR");
 }
 
-SEXP Rf_asChar(SEXP x){
-	return checkRef(((call_Rf_asChar) callbacks[Rf_asChar_x])(x));
+SEXP Rf_asChar(SEXP x) {
+    TRACE0();
+	return ((call_Rf_asChar) callbacks[Rf_asChar_x])(x);
 }
 
-SEXP Rf_PairToVectorList(SEXP x){
-	return checkRef(((call_Rf_PairToVectorList) callbacks[Rf_PairToVectorList_x])(x));
+SEXP Rf_PairToVectorList(SEXP x) {
+    TRACE0();
+	return ((call_Rf_PairToVectorList) callbacks[Rf_PairToVectorList_x])(x);
 }
 
 SEXP Rf_VectorToPairList(SEXP x){
-	return checkRef(((call_Rf_VectorToPairList) callbacks[Rf_VectorToPairList_x])(x));
+	return ((call_Rf_VectorToPairList) callbacks[Rf_VectorToPairList_x])(x);
 }
 
 SEXP Rf_asCharacterFactor(SEXP x){
-	return checkRef(((call_Rf_asCharacterFactor) callbacks[Rf_asCharacterFactor_x])(x));
+	return ((call_Rf_asCharacterFactor) callbacks[Rf_asCharacterFactor_x])(x);
 }
 
-int Rf_asLogical(SEXP x){
+int Rf_asLogical(SEXP x) {
+    TRACE0();
 	return ((call_Rf_asLogical) callbacks[Rf_asLogical_x])(x);
 }
 
 int Rf_asInteger(SEXP x) {
+    TRACE0();
 	return ((call_Rf_asInteger) callbacks[Rf_asInteger_x])(x);
 }
 
 double Rf_asReal(SEXP x) {
+    TRACE0();
 	return ((call_Rf_asReal) callbacks[Rf_asReal_x])(x);
 }
 
-Rcomplex Rf_asComplex(SEXP x){
+Rcomplex Rf_asComplex(SEXP x) {
+    TRACE0();
 	unimplemented("Rf_asComplex");
 	Rcomplex c; return c;
 }
 
 int TYPEOF(SEXP x) {
+    TRACE0();
 	return (int) ((call_TYPEOF) callbacks[TYPEOF_x])(x);
 }
 
-SEXP ATTRIB(SEXP x){
+SEXP ATTRIB(SEXP x) {
+    TRACE0();
     return ((call_ATTRIB) callbacks[ATTRIB_x])(x);
 }
 
-int OBJECT(SEXP x){
+int OBJECT(SEXP x) {
+    TRACE0();
 	return (int) ((call_OBJECT) callbacks[OBJECT_x])(x);
 }
 
-int MARK(SEXP x){
+int MARK(SEXP x) {
+    TRACE0();
     unimplemented("MARK");
     return 0;
 }
 
-int NAMED(SEXP x){
+int NAMED(SEXP x) {
+    TRACE0();
 	return (int) ((call_NAMED) callbacks[NAMED_x])(x);
 }
 
-int REFCNT(SEXP x){
+int REFCNT(SEXP x) {
+    TRACE0();
     unimplemented("REFCNT");
     return 0;
 }
 
-void SET_OBJECT(SEXP x, int v){
+void SET_OBJECT(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_OBJECT");
 }
 
-void SET_TYPEOF(SEXP x, int v){
+void SET_TYPEOF(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_TYPEOF");
 }
 
-SEXP SET_TYPEOF_FASTR(SEXP x, int v){
-	return checkRef(((call_SET_TYPEOF_FASTR) callbacks[SET_TYPEOF_FASTR_x])(x, v));
+SEXP SET_TYPEOF_FASTR(SEXP x, int v) {
+    TRACE0();
+	return ((call_SET_TYPEOF_FASTR) callbacks[SET_TYPEOF_FASTR_x])(x, v);
 }
 
-void SET_NAMED(SEXP x, int v){
+void SET_NAMED(SEXP x, int v) {
+    TRACE0();
     unimplemented("SET_NAMED");
 }
 
-void SET_ATTRIB(SEXP x, SEXP v){
+void SET_ATTRIB(SEXP x, SEXP v) {
+    TRACE0();
     unimplemented("SET_ATTRIB");
 }
 
-void DUPLICATE_ATTRIB(SEXP to, SEXP from){
+void DUPLICATE_ATTRIB(SEXP to, SEXP from) {
+    TRACE0();
 	((call_DUPLICATE_ATTRIB) callbacks[DUPLICATE_ATTRIB_x])(to, from);
 }
 
 void R_qsort_I  (double *v, int *II, int i, int j) {
+    TRACE0();
 	unimplemented("R_qsort_I");
 }
 
 void R_qsort_int_I(int *iv, int *II, int i, int j) {
+    TRACE0();
 	unimplemented("R_qsort_int_I");
 }
 
 R_len_t R_BadLongVector(SEXP x, const char *y, int z) {
+    TRACE0();
 	return (R_len_t) unimplemented("R_BadLongVector");
 }
 
 int IS_S4_OBJECT(SEXP x) {
+    TRACE0();
 	return (int) ((call_IS_S4_OBJECT) callbacks[IS_S4_OBJECT_x])(x);
 }
 
 void SET_S4_OBJECT(SEXP x) {
+    TRACE0();
 	((call_SET_S4_OBJECT) callbacks[SET_S4_OBJECT_x])(x);
 }
 
 void UNSET_S4_OBJECT(SEXP x) {
+    TRACE0();
 	((call_UNSET_S4_OBJECT) callbacks[UNSET_S4_OBJECT_x])(x);
 }
 
 Rboolean R_ToplevelExec(void (*fun)(void *), void *data) {
+    TRACE0();
 	return (Rboolean) unimplemented("R_ToplevelExec");
 }
 
 SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data,
 		       void (*cleanfun)(void *), void *cleandata) {
+    TRACE0();
 	return unimplemented("R_ExecWithCleanup");
 }
 
 /* Environment and Binding Features */
 void R_RestoreHashCount(SEXP rho) {
+    TRACE0();
 	unimplemented("R_RestoreHashCount");
 }
 
 Rboolean R_IsPackageEnv(SEXP rho) {
+    TRACE0();
 	unimplemented("R_IsPackageEnv");
 }
 
 SEXP R_PackageEnvName(SEXP rho) {
+    TRACE0();
 	return unimplemented("R_PackageEnvName");
 }
 
 SEXP R_FindPackageEnv(SEXP info) {
+    TRACE0();
 	return unimplemented("R_FindPackageEnv");
 }
 
 Rboolean R_IsNamespaceEnv(SEXP rho) {
+    TRACE0();
 	return (Rboolean) unimplemented("R_IsNamespaceEnv");
 }
 
 SEXP R_FindNamespace(SEXP info) {
-	return checkRef(((call_R_FindNamespace) callbacks[R_FindNamespace_x])(info));
+    TRACE0();
+	return ((call_R_FindNamespace) callbacks[R_FindNamespace_x])(info);
 }
 
 SEXP R_NamespaceEnvSpec(SEXP rho) {
+    TRACE0();
 	return unimplemented("R_NamespaceEnvSpec");
 }
 
 void R_LockEnvironment(SEXP env, Rboolean bindings) {
+    TRACE0();
 	unimplemented("R_LockEnvironment");
 }
 
 Rboolean R_EnvironmentIsLocked(SEXP env) {
+    TRACE0();
 	unimplemented("");
 }
 
 void R_LockBinding(SEXP sym, SEXP env) {
+    TRACE0();
 	unimplemented("R_LockBinding");
 }
 
 void R_unLockBinding(SEXP sym, SEXP env) {
+    TRACE0();
 	unimplemented("R_unLockBinding");
 }
 
 void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env) {
+    TRACE0();
 	unimplemented("R_MakeActiveBinding");
 }
 
 Rboolean R_BindingIsLocked(SEXP sym, SEXP env) {
+    TRACE0();
 	return (Rboolean) ((call_R_BindingIsLocked) callbacks[R_BindingIsLocked_x])(sym, env);
 }
 
 Rboolean R_BindingIsActive(SEXP sym, SEXP env) {
+    TRACE0();
     // TODO: for now, I believe all bindings are false
     return (Rboolean)0;
 }
 
 Rboolean R_HasFancyBindings(SEXP rho) {
+    TRACE0();
 	return (Rboolean) unimplemented("R_HasFancyBindings");
 }
 
 Rboolean Rf_isS4(SEXP x) {
+    TRACE0();
     return IS_S4_OBJECT(x);
 }
 
 SEXP Rf_asS4(SEXP x, Rboolean b, int i) {
+    TRACE0();
 	unimplemented("Rf_asS4");
 }
 
 static SEXP R_tryEvalInternal(SEXP x, SEXP y, int *ErrorOccurred, int silent) {
+    TRACE0();
 	unimplemented("R_tryEvalInternal");
 }
 
 SEXP R_tryEval(SEXP x, SEXP y, int *ErrorOccurred) {
+    TRACE0();
 	return R_tryEvalInternal(x, y, ErrorOccurred, 0);
 }
 
 SEXP R_tryEvalSilent(SEXP x, SEXP y, int *ErrorOccurred) {
+    TRACE0();
 	return R_tryEvalInternal(x, y, ErrorOccurred, 1);
 }
 
 double R_atof(const char *str) {
+    TRACE0();
 	unimplemented("R_atof");
 	return 0;
 }
 
 double R_strtod(const char *c, char **end) {
+    TRACE0();
 	unimplemented("R_strtod");
 	return 0;
 }
 
 SEXP R_PromiseExpr(SEXP x) {
-	return checkRef(((call_R_PromiseExpr) callbacks[R_PromiseExpr_x])(x));
+    TRACE0();
+	return ((call_R_PromiseExpr) callbacks[R_PromiseExpr_x])(x);
 }
 
 SEXP R_ClosureExpr(SEXP x) {
+    TRACE0();
 	return unimplemented("R_ClosureExpr");
 }
 
 SEXP R_forceAndCall(SEXP e, int n, SEXP rho) {
+    TRACE0();
 	return unimplemented("R_forceAndCall");
 }
 
 SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot) {
-	return checkRef(((call_R_MakeExternalPtr) callbacks[R_MakeExternalPtr_x])(p, tag, prot));
+    TRACE0();
+	return ((call_R_MakeExternalPtr) callbacks[R_MakeExternalPtr_x])(p, tag, prot);
 }
 
 void *R_ExternalPtrAddr(SEXP s) {
+    TRACE0();
 	return ((call_R_ExternalPtrAddr) callbacks[R_ExternalPtrAddr_x])(s);
 }
 
 SEXP R_ExternalPtrTag(SEXP s) {
-	return checkRef(((call_R_ExternalPtrTag) callbacks[R_ExternalPtrTag_x])(s));
+    TRACE0();
+	return ((call_R_ExternalPtrTag) callbacks[R_ExternalPtrTag_x])(s);
 }
 
 SEXP R_ExternalPtrProtected(SEXP s) {
-	return checkRef(((call_R_ExternalPtrProtected) callbacks[R_ExternalPtrProtected_x])(s));
+    TRACE0();
+	return ((call_R_ExternalPtrProtected) callbacks[R_ExternalPtrProtected_x])(s);
 }
 
 void R_SetExternalPtrAddr(SEXP s, void *p) {
-	((call_R_SetExternalPtrProtected) callbacks[R_SetExternalPtrProtected_x])(s, p);
+    TRACE0();
+	((call_R_SetExternalPtrAddr) callbacks[R_SetExternalPtrAddr_x])(s, p);
 }
 
 void R_SetExternalPtrTag(SEXP s, SEXP tag) {
-	((call_R_SetExternalPtrProtected) callbacks[R_SetExternalPtrProtected_x])(s, tag);
+    TRACE0();
+	((call_R_SetExternalPtrTag) callbacks[R_SetExternalPtrTag_x])(s, tag);
 }
 
 void R_SetExternalPtrProtected(SEXP s, SEXP p) {
+    TRACE0();
 	((call_R_SetExternalPtrProtected) callbacks[R_SetExternalPtrProtected_x])(s, p);
 }
 
 void R_ClearExternalPtr(SEXP s) {
+    TRACE0();
 	R_SetExternalPtrAddr(s, NULL);
 }
 
 void R_RegisterFinalizer(SEXP s, SEXP fun) {
+    TRACE0();
 	// TODO implement, but not fail for now
 }
 void R_RegisterCFinalizer(SEXP s, R_CFinalizer_t fun) {
+    TRACE0();
 	// TODO implement, but not fail for now
 }
 
 void R_RegisterFinalizerEx(SEXP s, SEXP fun, Rboolean onexit) {
+    TRACE0();
 	// TODO implement, but not fail for now
 
 }
 
 void R_RegisterCFinalizerEx(SEXP s, R_CFinalizer_t fun, Rboolean onexit) {
+    TRACE0();
 	// TODO implement, but not fail for now
 }
 
 void R_RunPendingFinalizers(void) {
+    TRACE0();
 	// TODO implement, but not fail for now
 }
 
 SEXP R_MakeWeakRef(SEXP key, SEXP val, SEXP fin, Rboolean onexit) {
+    TRACE0();
 	unimplemented("R_MakeWeakRef");
 }
 
 SEXP R_MakeWeakRefC(SEXP key, SEXP val, R_CFinalizer_t fin, Rboolean onexit) {
+    TRACE0();
 	unimplemented("R_MakeWeakRefC");
 }
 
 SEXP R_WeakRefKey(SEXP w) {
+    TRACE0();
 	unimplemented("R_WeakRefKey");
 }
 
 SEXP R_WeakRefValue(SEXP w) {
+    TRACE0();
 	unimplemented("R_WeakRefValue");
 }
 
 void R_RunWeakRefFinalizer(SEXP w) {
+    TRACE0();
 	// TODO implement, but not fail for now
 }
 
 SEXP R_do_slot(SEXP obj, SEXP name) {
-	return checkRef(((call_R_do_slot) callbacks[R_do_slot_x])(obj, name));
+    TRACE0();
+	return ((call_R_do_slot) callbacks[R_do_slot_x])(obj, name);
 }
 
 SEXP R_do_slot_assign(SEXP obj, SEXP name, SEXP value) {
-	return checkRef(((call_R_do_slot_assign) callbacks[R_do_slot_assign_x])(obj, name, value));
+    TRACE0();
+	return ((call_R_do_slot_assign) callbacks[R_do_slot_assign_x])(obj, name, value);
 }
 
 int R_has_slot(SEXP obj, SEXP name) {
+    TRACE0();
 	return (int) unimplemented("R_has_slot");
 }
 
 SEXP R_do_MAKE_CLASS(const char *what) {
-	return checkRef(((call_R_do_MAKE_CLASS) callbacks[R_do_MAKE_CLASS_x])(what));
+    TRACE0();
+	return ((call_R_do_MAKE_CLASS) callbacks[R_do_MAKE_CLASS_x])(what);
 }
 
 SEXP R_getClassDef (const char *what) {
+    TRACE0();
 	return unimplemented("R_getClassDef");
 }
 
 SEXP R_do_new_object(SEXP class_def) {
-	return checkRef(((call_R_do_new_object) callbacks[R_do_new_object_x])(class_def));
+    TRACE0();
+	return ((call_R_do_new_object) callbacks[R_do_new_object_x])(class_def);
 }
 
 static SEXP nfiGetMethodsNamespace() {
-    return checkRef(((call_R_MethodsNamespace) callbacks[R_MethodsNamespace_x])());
+    TRACE0();
+    return ((call_R_MethodsNamespace) callbacks[R_MethodsNamespace_x])();
 }
 
 int R_check_class_etc (SEXP x, const char **valid) {
+    TRACE0();
 	return R_check_class_etc_helper(x, valid, nfiGetMethodsNamespace);
 }
 
-SEXP R_PreserveObject_FASTR(SEXP x) {
-	return newObjectHandle(x);
+void R_PreserveObject(SEXP x) {
+    TRACE0();
+    ((call_R_PreserveObject) callbacks[R_PreserveObject_x])(x);
 }
 
 void R_ReleaseObject(SEXP x) {
-	releaseObjectHandle(x);
+    TRACE0();
+    ((call_R_ReleaseObject) callbacks[R_ReleaseObject_x])(x);
 }
 
 void R_dot_Last(void) {
+    TRACE0();
 	unimplemented("R_dot_Last");
 }
 
-
 Rboolean R_compute_identical(SEXP x, SEXP y, int flags) {
+    TRACE0();
 	return (Rboolean) ((call_R_compute_identical) callbacks[R_compute_identical_x])(x, y, flags);
 }
 
 void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) {
+    TRACE0();
 	((call_Rf_copyListMatrix) callbacks[Rf_copyListMatrix_x])(s, t, byrow);
 }
 
 void Rf_copyMatrix(SEXP s, SEXP t, Rboolean byrow) {
+    TRACE0();
 	((call_Rf_copyMatrix) callbacks[Rf_copyMatrix_x])(s, t, byrow);
 }
 
+int FASTR_getConnectionChar(SEXP conn) {
+    TRACE0();
+    return ((call_FASTR_getConnectionChar) callbacks[FASTR_getConnectionChar_x])(conn);
+}
+
+// Must match ordinal value for DLL.NativeSymbolType
+#define C_NATIVE_TYPE 0
+#define CALL_NATIVE_TYPE 1
+#define FORTRAN_NATIVE_TYPE 2
+#define EXTERNAL_NATIVE_TYPE 3
+
+int
+R_registerRoutines(DllInfo *info, const R_CMethodDef * const croutines,
+           const R_CallMethodDef * const callRoutines,
+           const R_FortranMethodDef * const fortranRoutines,
+           const R_ExternalMethodDef * const externalRoutines) {
+    TRACE0();
+    int num;
+    if (croutines) {
+    TRACE0();
+        for(num = 0; croutines[num].name != NULL; num++) {;}
+        ((call_registerRoutines) callbacks[registerRoutines_x])(info, C_NATIVE_TYPE, num, croutines);
+    }
+    if (callRoutines) {
+    TRACE0();
+        for(num = 0; callRoutines[num].name != NULL; num++) {;}
+        ((call_registerRoutines) callbacks[registerRoutines_x])(info, CALL_NATIVE_TYPE, num, callRoutines);
+    }
+    if (fortranRoutines) {
+    TRACE0();
+        for(num = 0; fortranRoutines[num].name != NULL; num++) {;}
+        ((call_registerRoutines) callbacks[registerRoutines_x])(info, FORTRAN_NATIVE_TYPE, num, fortranRoutines);
+    }
+    if (externalRoutines) {
+    TRACE0();
+        for(num = 0; externalRoutines[num].name != NULL; num++) {;}
+        ((call_registerRoutines) callbacks[registerRoutines_x])(info, EXTERNAL_NATIVE_TYPE, num, externalRoutines);
+    }
+    return 1;
+}
+
+Rboolean R_useDynamicSymbols(DllInfo *dllInfo, Rboolean value) {
+    TRACE0();
+    return ((call_useDynamicSymbols) callbacks[useDynamicSymbols_x])(dllInfo, value);
+}
+
+Rboolean R_forceSymbols(DllInfo *dllInfo, Rboolean value) {
+    TRACE0();
+    return ((call_forceSymbols) callbacks[forceSymbols_x])(dllInfo, value);
+}
+
+void *Rdynload_setSymbol(DllInfo *info, int nstOrd, void* routinesAddr, int index) {
+    TRACE0();
+    const char *name;
+    void * fun;
+    int numArgs;
+    switch (nstOrd) {
+    TRACE0();
+    case C_NATIVE_TYPE: {
+        R_CMethodDef *croutines = (R_CMethodDef *) routinesAddr;
+        name = croutines[index].name;
+        fun = croutines[index].fun;
+        numArgs = croutines[index].numArgs;
+        break;
+    }
+    case CALL_NATIVE_TYPE: {
+        R_CallMethodDef *callRoutines = (R_CallMethodDef *) routinesAddr;
+        name = callRoutines[index].name;
+        fun = callRoutines[index].fun;
+        numArgs = callRoutines[index].numArgs;
+        break;
+    }
+    case FORTRAN_NATIVE_TYPE: {
+        R_FortranMethodDef * fortranRoutines = (R_FortranMethodDef *) routinesAddr;
+        name = fortranRoutines[index].name;
+        fun = fortranRoutines[index].fun;
+        numArgs = fortranRoutines[index].numArgs;
+        break;
+    }
+    case EXTERNAL_NATIVE_TYPE: {
+        R_ExternalMethodDef * externalRoutines = (R_ExternalMethodDef *) routinesAddr;
+        name = externalRoutines[index].name;
+        fun = externalRoutines[index].fun;
+        numArgs = externalRoutines[index].numArgs;
+        break;
+    }
+    }
+    void *result = ((call_setDotSymbolValues) callbacks[setDotSymbolValues_x])(info, ensure_string(name), fun, numArgs);
+    return result;
+}
+
+void R_RegisterCCallable(const char *package, const char *name, DL_FUNC fptr) {
+    TRACE0();
+    ((call_registerCCallable) callbacks[registerCCallable_x])(ensure_string(package), ensure_string(name), (void *)fptr);
+}
+
+DL_FUNC R_GetCCallable(const char *package, const char *name) {
+    TRACE0();
+    return ((call_getCCallable) callbacks[getCCallable_x])(ensure_string(package), ensure_string(name));
+}
+
+DL_FUNC R_FindSymbol(char const *name, char const *pkg, R_RegisteredNativeSymbol *symbol) {
+    TRACE0();
+    return unimplemented("R_FindSymbol");
+}
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rdynload_fastr.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rdynload_fastr.c
deleted file mode 100644
index 19dc2dca73536e16273a0163a318e1c7ceae20da..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rdynload_fastr.c
+++ /dev/null
@@ -1,34 +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-2012, The R Core Team
- * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-
-// Registering routines from loaded shared libraries - LLVM variant
-
-#include <truffle.h>
-#include <rffiutils.h>
-
-static void **dynload_callbacks = NULL;
-
-void *ensure_fun(void *fun) {
-	void *r = truffle_address_to_function(fun);
-	return r;
-}
-
-#include "../truffle_common/Rdynload_fastr.h"
-
-void Rdynload_addCallback(int index, void* callback) {
-	if (dynload_callbacks == NULL) {
-		dynload_callbacks = truffle_managed_malloc(CALLBACK_TABLE_SIZE * sizeof(void*));
-	}
-	dynload_callbacks[index] = callback;
-}
-
-
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
index 8d45b717ff440a384b5b5ae27002749f81be0a19..34c7f65e5be0461d61a525af613915faeeba1127 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c
@@ -47,10 +47,6 @@ void Rinternals_addCallback(int index, void *callback) {
 	callbacks[index] = callback;
 }
 
-SEXP checkRef(SEXP x) {
-	return x;
-}
-
 static char *ensure_truffle_chararray_n(const char *x, int n) {
 	if (truffle_is_truffle_object(x)) {
 		return x;
@@ -71,13 +67,6 @@ void *ensure_string(const char *x) {
 	return truffle_read_string(x);
 }
 
-static SEXP newObjectHandle(SEXP x) {
-	return x;
-}
-
-static void releaseObjectHandle(SEXP x) {
-}
-
 char *FASTR_R_Home() {
 	return ((call_R_Home) callbacks[R_Home_x])();
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c
index 99ead1d2b3fdb76f26b71295679a6b1d44e4430d..cbadacc9c00c9ecae1b6acd0ed8d3ef59bd5082b 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c
@@ -22,12 +22,12 @@
  */
 #include <rffiutils.h>
 
-SEXP unimplemented(char *name) {
+SEXP unimplemented(const char *name) {
 	printf("unimplemented %s\n", name);
 	exit(1);
 }
 
-void fatalError(char *msg) {
+void fatalError(const char *msg) {
 	printf("faatal error %s\n", msg);
     exit(1);
 }
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h
index 5306705e335e4a94b1e9c23bf016f0518a3a20a0..8413ee815ff4b060091d3c0e7560c72daa889305 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h
@@ -31,7 +31,6 @@
 
 char *ensure_truffle_chararray(const char *x);
 void *ensure_string(const char *x);
-void *ensure_fun(void *fun);
 SEXP unimplemented(char *name);
 
 #endif /* RFFIUTILS_H */
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c
deleted file mode 100644
index 685844bd897d2580568c0b6836ff7ff521984e11..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c
+++ /dev/null
@@ -1,29 +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-2012, The R Core Team
- * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates
- *
- * All rights reserved.
- */
-#include <rffiutils.h>
-
-static void **dynload_callbacks;
-
-void *ensure_fun(void *fun) {
-	return fun;
-}
-
-#include "../truffle_common/Rdynload_fastr.h"
-
-void Rdynload_init(TruffleEnv* env, int index, void* closure) {
-	(*env)->newClosureRef(env, closure);
-	if (dynload_callbacks == NULL) {
-		dynload_callbacks = malloc(CALLBACK_TABLE_SIZE * sizeof(void*));
-	}
-	dynload_callbacks[index] = closure;
-}
-
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c
index f38558150ff6c24bdcd603cfcd736c30d720c4fd..bc24bc14410f2ed6c48343dd5446d269735f5317 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c
@@ -52,17 +52,6 @@ void *ensure_string(const char * x) {
 	return (void *) x;
 }
 
-SEXP newObjectHandle(SEXP x) {
-    TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext);
-	SEXP result = (*env)->newObjectRef(env, x);
-	return result;
-}
-
-void releaseObjectHandle(SEXP x) {
-    TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext);
-	(*env)->releaseObjectRef(env, x);
-}
-
 #include "../truffle_common/Rinternals_truffle_common.h"
 
 long return_INTEGER_CREATE(int *value, int len) {
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
index 7e45c3b7b5164611720dde1f6cbda7cd34bc7c4e..19ec0060174a4d40f25cc9bf7bc61eaf688d4f91 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c
@@ -23,93 +23,15 @@
 #include <rffiutils.h>
 #include <trufflenfi.h>
 
-void* unimplemented(char *f) {
+void* unimplemented(const char *f) {
 	printf("unimplemented %s\n", f);
 	exit(1);
 }
 
-typedef struct globalRefTable_struct {
-    int permanent;
-    SEXP gref;         // The jobject (SEXP) global ref
-} GlobalRefElem;
-
-#define CACHED_GLOBALREFS_INITIAL_SIZE 64
-
-static GlobalRefElem *cachedGlobalRefs = NULL;
-static int cachedGlobalRefsHwm;
-static int cachedGlobalRefsLength;
-static TruffleContext* truffleContext;
+static TruffleContext* truffleContext = NULL;
 
 void init_utils(TruffleEnv* env) {
-	if (cachedGlobalRefs == NULL) {
+	if (truffleContext == NULL) {
 	    truffleContext = (*env)->getTruffleContext(env);
-		cachedGlobalRefs = calloc(CACHED_GLOBALREFS_INITIAL_SIZE, sizeof(GlobalRefElem));
-		cachedGlobalRefsLength = CACHED_GLOBALREFS_INITIAL_SIZE;
-		cachedGlobalRefsHwm = 0;
 	}
 }
-static SEXP findCachedGlobalRef(SEXP obj) {
-    TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext);
-    for (int i = 0; i < cachedGlobalRefsHwm; i++) {
-        GlobalRefElem elem = cachedGlobalRefs[i];
-        if (elem.gref == NULL) {
-            continue;
-        }
-        if ((*env)->isSameObject(env, elem.gref, obj)) {
-            return elem.gref;
-        }
-    }
-    return NULL;
-}
-
-SEXP addGlobalRef(SEXP obj, int permanent) {
-    SEXP gref;
-    if (cachedGlobalRefsHwm >= cachedGlobalRefsLength) {
-        int newLength = cachedGlobalRefsLength * 2;
-        SEXP newCachedGlobalRefs = calloc(newLength, sizeof(GlobalRefElem));
-        if (newCachedGlobalRefs == NULL) {
-            fatalError("FFI global refs table expansion failure");
-        }
-        memcpy(newCachedGlobalRefs, cachedGlobalRefs, cachedGlobalRefsLength * sizeof(GlobalRefElem));
-        free(cachedGlobalRefs);
-        cachedGlobalRefs = newCachedGlobalRefs;
-        cachedGlobalRefsLength = newLength;
-    }
-    TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext);
-    gref = (*env)->newObjectRef(env, obj);
-    cachedGlobalRefs[cachedGlobalRefsHwm].gref = gref;
-    cachedGlobalRefs[cachedGlobalRefsHwm].permanent = permanent;
-    cachedGlobalRefsHwm++;
-    return gref;
-}
-
-SEXP checkRef(SEXP obj) {
-    SEXP gref = findCachedGlobalRef(obj);
-    if (gref == NULL) {
-        return obj;
-    } else {
-        return gref;
-    }
-}
-
-SEXP createGlobalRef(SEXP obj, int permanent) {
-    SEXP gref = findCachedGlobalRef(obj);
-    if (gref == NULL) {
-        gref = addGlobalRef(obj, permanent);
-    }
-    return gref;
-}
-
-void releaseGlobalRef(SEXP obj) {
-    TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext);
-    for (int i = 0; i < cachedGlobalRefsHwm; i++) {
-        GlobalRefElem elem = cachedGlobalRefs[i];
-        if (elem.gref == NULL || elem.permanent) {
-            continue;
-        }
-        if ((*env)->isSameObject(env, elem.gref, obj)) {
-        	(*env)->releaseObjectRef(env, elem.gref);
-            cachedGlobalRefs[i].gref = NULL;
-        }
-    }
-}
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
index 95a1896feb750f096b559d60fcf7aa9a46c67a61..36c19e44e5ff1969b6a7b93a9a0a89e8405c07bb 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h
@@ -34,20 +34,10 @@ extern void init_utils(TruffleEnv* env);
 
 char *ensure_truffle_chararray(const char *x);
 void *ensure_string(const char *x);
-void *ensure_fun(void *fun);
 
 // use for an unimplemented API function
-void *unimplemented(char *msg) __attribute__((noreturn));
+void *unimplemented(const char *msg) __attribute__((noreturn));
 // use for any fatal error
-void fatalError(char *msg) __attribute__((noreturn));
-
-// checks x against the list of global refs, returning the global version if x matches (IsSameObject)
-SEXP checkRef(SEXP x);
-// creates a global JNI global ref from x. If permanent is non-zero, calls to
-// releaseGlobalRef are ignored and the global ref persists for the entire execution
-// (used for the R global variables such as R_NilValue).
-SEXP createGlobalRef(SEXP x, int permanent);
-// release a previously created global ref
-void releaseGlobalRef(SEXP x);
+void fatalError(const char *msg) __attribute__((noreturn));
 
 #endif
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 ba69fa6144d8252eb229ccc76c8b9f9d21cced19..bec429e25e14c4805e80f403c6e4d39c1caf29b2 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
@@ -303,46 +303,46 @@ 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_NilValue_x: R_NilValue_static = createGlobalRef(value, 1); break;
-    case R_UnboundValue_x: R_UnboundValue_static = createGlobalRef(value, 1); break;
-    case R_MissingArg_x: R_MissingArg_static = createGlobalRef(value, 1); break;
-    case R_Srcref_x: R_Srcref_static = createGlobalRef(value, 1); break;
-    case R_EmptyEnv_x: R_EmptyEnv_static = createGlobalRef(value, 1); break;
-    case R_Bracket2Symbol_x: R_Bracket2Symbol_static = createGlobalRef(value, 1); break;
-    case R_BracketSymbol_x: R_BracketSymbol_static = createGlobalRef(value, 1); break;
-    case R_BraceSymbol_x: R_BraceSymbol_static = createGlobalRef(value, 1); break;
-    case R_DoubleColonSymbol_x: R_DoubleColonSymbol_static = createGlobalRef(value, 1); break;
-    case R_ClassSymbol_x: R_ClassSymbol_static = createGlobalRef(value, 1); break;
-    case R_DeviceSymbol_x: R_DeviceSymbol_static = createGlobalRef(value, 1); break;
-    case R_DevicesSymbol_x: R_DevicesSymbol_static = createGlobalRef(value, 1); break;
-    case R_DimNamesSymbol_x: R_DimNamesSymbol_static = createGlobalRef(value, 1); break;
-    case R_DimSymbol_x: R_DimSymbol_static = createGlobalRef(value, 1); break;
-    case R_DollarSymbol_x: R_DollarSymbol_static = createGlobalRef(value, 1); break;
-    case R_DotsSymbol_x: R_DotsSymbol_static = createGlobalRef(value, 1); break;
-    case R_DropSymbol_x: R_DropSymbol_static = createGlobalRef(value, 1); break;
-    case R_LastvalueSymbol_x: R_LastvalueSymbol_static = createGlobalRef(value, 1); break;
-    case R_LevelsSymbol_x: R_LevelsSymbol_static = createGlobalRef(value, 1); break;
-    case R_ModeSymbol_x: R_ModeSymbol_static = createGlobalRef(value, 1); break;
-    case R_NameSymbol_x: R_NameSymbol_static = createGlobalRef(value, 1); break;
-    case R_NamesSymbol_x: R_NamesSymbol_static = createGlobalRef(value, 1); break;
-    case R_NaRmSymbol_x: R_NaRmSymbol_static = createGlobalRef(value, 1); break;
-    case R_PackageSymbol_x: R_PackageSymbol_static = createGlobalRef(value, 1); break;
-    case R_QuoteSymbol_x: R_QuoteSymbol_static = createGlobalRef(value, 1); break;
-    case R_RowNamesSymbol_x: R_RowNamesSymbol_static = createGlobalRef(value, 1); break;
-    case R_SeedsSymbol_x: R_SeedsSymbol_static = createGlobalRef(value, 1); break;
-    case R_SourceSymbol_x: R_SourceSymbol_static = createGlobalRef(value, 1); break;
-    case R_TspSymbol_x: R_TspSymbol_static = createGlobalRef(value, 1); break;
-    case R_dot_defined_x: R_dot_defined_static = createGlobalRef(value, 1); break;
-    case R_dot_Method_x: R_dot_Method_static = createGlobalRef(value, 1); break;
-    case R_dot_target_x: R_dot_target_static = createGlobalRef(value, 1); break;
-    case R_SrcrefSymbol_x: R_SrcrefSymbol_static = createGlobalRef(value, 1); break;
-    case R_SrcfileSymbol_x: R_SrcfileSymbol_static = createGlobalRef(value, 1); break;
-    case R_NaString_x: R_NaString_static = createGlobalRef(value, 1); break;
-    case R_BlankString_x: R_BlankString_static = createGlobalRef(value, 1); break;
-    case R_BlankScalarString_x: R_BlankString_static = createGlobalRef(value, 1); break;
-    case R_BaseSymbol_x: R_BaseSymbol_static = createGlobalRef(value, 1); break;
-    case R_NamespaceEnvSymbol_x: R_NamespaceEnvSymbol_static = createGlobalRef(value, 1); break;
-    // case R_RestartToken_x: R_RestartToken_static = createGlobalRef(value, 1); break;
+    case R_NilValue_x: R_NilValue_static = value; break;
+    case R_UnboundValue_x: R_UnboundValue_static = value; break;
+    case R_MissingArg_x: R_MissingArg_static = value; break;
+    case R_Srcref_x: R_Srcref_static = value; break;
+    case R_EmptyEnv_x: R_EmptyEnv_static = value; break;
+    case R_Bracket2Symbol_x: R_Bracket2Symbol_static = value; break;
+    case R_BracketSymbol_x: R_BracketSymbol_static = value; break;
+    case R_BraceSymbol_x: R_BraceSymbol_static = value; break;
+    case R_DoubleColonSymbol_x: R_DoubleColonSymbol_static = value; break;
+    case R_ClassSymbol_x: R_ClassSymbol_static = value; break;
+    case R_DeviceSymbol_x: R_DeviceSymbol_static = value; break;
+    case R_DevicesSymbol_x: R_DevicesSymbol_static = value; break;
+    case R_DimNamesSymbol_x: R_DimNamesSymbol_static = value; break;
+    case R_DimSymbol_x: R_DimSymbol_static = value; break;
+    case R_DollarSymbol_x: R_DollarSymbol_static = value; break;
+    case R_DotsSymbol_x: R_DotsSymbol_static = value; break;
+    case R_DropSymbol_x: R_DropSymbol_static = value; break;
+    case R_LastvalueSymbol_x: R_LastvalueSymbol_static = value; break;
+    case R_LevelsSymbol_x: R_LevelsSymbol_static = value; break;
+    case R_ModeSymbol_x: R_ModeSymbol_static = value; break;
+    case R_NameSymbol_x: R_NameSymbol_static = value; break;
+    case R_NamesSymbol_x: R_NamesSymbol_static = value; break;
+    case R_NaRmSymbol_x: R_NaRmSymbol_static = value; break;
+    case R_PackageSymbol_x: R_PackageSymbol_static = value; break;
+    case R_QuoteSymbol_x: R_QuoteSymbol_static = value; break;
+    case R_RowNamesSymbol_x: R_RowNamesSymbol_static = value; break;
+    case R_SeedsSymbol_x: R_SeedsSymbol_static = value; break;
+    case R_SourceSymbol_x: R_SourceSymbol_static = value; break;
+    case R_TspSymbol_x: R_TspSymbol_static = value; break;
+    case R_dot_defined_x: R_dot_defined_static = value; break;
+    case R_dot_Method_x: R_dot_Method_static = value; break;
+    case R_dot_target_x: R_dot_target_static = value; break;
+    case R_SrcrefSymbol_x: R_SrcrefSymbol_static = value; break;
+    case R_SrcfileSymbol_x: R_SrcfileSymbol_static = value; break;
+    case R_NaString_x: R_NaString_static = value; break;
+    case R_BlankString_x: R_BlankString_static = value; break;
+    case R_BlankScalarString_x: R_BlankString_static = value; break;
+    case R_BaseSymbol_x: R_BaseSymbol_static = value; break;
+    case R_NamespaceEnvSymbol_x: R_NamespaceEnvSymbol_static = value; break;
+    // case R_RestartToken_x: R_RestartToken_static = value; break;
     default:
     	printf("Call_initvar_obj: unimplemented index %d\n", index);
     	exit(1);
diff --git a/com.oracle.truffle.r.native/library/grid/src/sed_grid b/com.oracle.truffle.r.native/library/grid/src/sed_grid
index 507382a2dc63e0c28ab91e959f68b16f607f88b4..705c960875fd3655fe1ad20b133b381cdf92106a 100644
--- a/com.oracle.truffle.r.native/library/grid/src/sed_grid
+++ b/com.oracle.truffle.r.native/library/grid/src/sed_grid
@@ -7,4 +7,4 @@
 # adding them to that environment. See ed_state where we fix code doing this to 
 # also call R_PreserveObject and R_ReleaseObject.
 # 
-s/R_gridEvalEnv = \([[:alnum:]]*\);/R_gridEvalEnv = R_PreserveObject(\1);/g
+#s/R_gridEvalEnv = \([[:alnum:]]*\);/R_gridEvalEnv = R_PreserveObject(\1);/g
diff --git a/com.oracle.truffle.r.native/library/grid/src/sed_state b/com.oracle.truffle.r.native/library/grid/src/sed_state
index 4cd242c4b41eee792e6acbe98ad2cb42ca1d471e..4db22d493e44a62de3a406b68a4afb05e66fdbb4 100644
--- a/com.oracle.truffle.r.native/library/grid/src/sed_state
+++ b/com.oracle.truffle.r.native/library/grid/src/sed_state
@@ -7,12 +7,12 @@
 #
 # prepend R_PreserveObject call to any sd->systemSpecific assignment 
 # in form of sd->systemSpecific = (void*) variablename;
-s/sd->systemSpecific[[:space:]]*=[[:space:]]*(void\*)[[:space:]]*\([[:alnum:]_]*\);/\1 = R_PreserveObject(\1); sd->systemSpecific = (void*)\1;/g
+#s/sd->systemSpecific[[:space:]]*=[[:space:]]*(void\*)[[:space:]]*\([[:alnum:]_]*\);/\1 = R_PreserveObject(\1); sd->systemSpecific = (void*)\1;/g
 #
 # rename deglobaliseState to deglobaliseStateOriginal and prepend a 
 # new definition of deglobaliseState that calls R_ReleaseObject and 
 # the original function (note we need deglobaliseStateOriginal 
 # forward declaration)
-s/static void deglobaliseState(SEXP state)/static void deglobaliseStateOriginal(SEXP state);\
-static void deglobaliseState(SEXP state) { deglobaliseStateOriginal(state); R_ReleaseObject(state); }\
-static void deglobaliseStateOriginal(SEXP state)/g
+#s/static void deglobaliseState(SEXP state)/static void deglobaliseStateOriginal(SEXP state);\
+#static void deglobaliseState(SEXP state) { deglobaliseStateOriginal(state); R_ReleaseObject(state); }\
+#static void deglobaliseStateOriginal(SEXP state)/g
diff --git a/com.oracle.truffle.r.native/library/tools/src/gramRd_fastr.h b/com.oracle.truffle.r.native/library/tools/src/gramRd_fastr.h
index 484c68e964e8149684afcc5604cf32b636fe23fe..73d64e3ddd01772cb30a865ce3962e3e281744cb 100644
--- a/com.oracle.truffle.r.native/library/tools/src/gramRd_fastr.h
+++ b/com.oracle.truffle.r.native/library/tools/src/gramRd_fastr.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -23,6 +23,10 @@
 #ifndef GRAMRD_FASTR_H
 #define GRAMRD_FASTR_H
 
-int callGetCMethod(void *conn);
+extern int FASTR_getConnectionChar(void* conn);
+
+int callGetCMethod(void *conn) {
+    return FASTR_getConnectionChar(conn);
+}
 
 #endif //GRAMRD_FASTR_H
diff --git a/com.oracle.truffle.r.native/library/tools/src/truffle_llvm/gramRd_llvm.c b/com.oracle.truffle.r.native/library/tools/src/truffle_llvm/gramRd_llvm.c
index a6c7bdc2f870cbf0869e0e2e28795d642697a920..1578fa677f56c4b2d864e0b7d6a07758f9bd954f 100644
--- a/com.oracle.truffle.r.native/library/tools/src/truffle_llvm/gramRd_llvm.c
+++ b/com.oracle.truffle.r.native/library/tools/src/truffle_llvm/gramRd_llvm.c
@@ -20,18 +20,5 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include "../gramRd_fastr.h"
-#include <truffle.h>
 
-typedef int (*call_getc)(void *conn);
 
-static void **gramRd_callbacks = NULL;
-
-void gramRd_addCallback(void *callback) {
-	gramRd_callbacks = truffle_managed_malloc(1 * sizeof(void*));
-	gramRd_callbacks[0] = callback;
-}
-
-int callGetCMethod(void *conn) {
-	return ((call_getc) gramRd_callbacks[0])(conn);
-}
diff --git a/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c b/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c
index db70c16af36dc2bf5c8f571fa2d5e8c9a4c1bcbb..1578fa677f56c4b2d864e0b7d6a07758f9bd954f 100644
--- a/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c
+++ b/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c
@@ -20,16 +20,5 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include "../gramRd_fastr.h"
-#include <trufflenfi.h>
 
-static int (*call_RConnGetC)(void *conn);
 
-void gramRd_nfi_init(TruffleEnv* env, void *closure) {
-	(*env)->newClosureRef(env, closure);
-	call_RConnGetC = closure;
-}
-
-int callGetCMethod(void *conn) {
-	return call_RConnGetC(conn);
-}
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 dba46132d7426a6c3576968f0ea76ed5f6c61e19..c3e78ba18bb188b3524a8d6601fba3bede23a608 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
@@ -39,6 +39,7 @@ import java.nio.charset.CodingErrorAction;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -93,6 +94,7 @@ import com.oracle.truffle.r.runtime.conn.ConnectionSupport;
 import com.oracle.truffle.r.runtime.conn.StdConnections;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
+import com.oracle.truffle.r.runtime.data.RObject;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RTruffleObject;
 import com.oracle.truffle.r.runtime.env.REnvironment;
@@ -355,6 +357,7 @@ public final class RContext implements RTruffleObject {
     public final WeakHashMap<Path, REnvironment> srcfileEnvironments = new WeakHashMap<>();
     public final List<String> libraryPaths = new ArrayList<>(1);
     public final Map<Integer, Thread> threads = new ConcurrentHashMap<>();
+    public final ArrayList<RObject> protectStack = new ArrayList<>();
 
     private final AllocationReporter allocationReporter;
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java
index e5fd6e43c40d9a6cd62b7b72c546c6fd18e6a6c4..4b3194cfd373361b3c257c031055e4bd2ed20de2 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 5c069dde67df806db7e0be218e168f045c6a5555..f60ee24560486de96d77da711e89c731d5d37674 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -81,11 +81,7 @@ com.oracle.truffle.r.native/fficall/src/jni/pcre_rffi.c,gnu_r_gentleman_ihaka2.c
 com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/truffle_llvm/Memory.c,gnu_r.copyright
-com.oracle.truffle.r.native/fficall/src/truffle_llvm/pcre_rffi.c,gnu_r_gentleman_ihaka2.copyright
-com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rdynload_fastr.c,gnu_r.copyright
 com.oracle.truffle.r.native/fficall/src/truffle_nfi/Memory.c,gnu_r.copyright
-com.oracle.truffle.r.native/fficall/src/truffle_nfi/pcre_rffi.c,gnu_r_gentleman_ihaka2.copyright
-com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c,gnu_r.copyright
 com.oracle.truffle.r.native/library/base/src/registration.c,no.copyright
 com.oracle.truffle.r.native/library/grDevices/src/gzio.c,gnu_r_gentleman_ihaka.copyright
 com.oracle.truffle.r.native/library/methods/src/methods_dummy.c,no.copyright
diff --git a/mx.fastr/mx_fastr_edinclude.py b/mx.fastr/mx_fastr_edinclude.py
index 1ca1490bc01cf29bcb8a3133320c43ceb3a174e3..656ecaa88cbacf2437410d07dc3a1888041853ee 100644
--- a/mx.fastr/mx_fastr_edinclude.py
+++ b/mx.fastr/mx_fastr_edinclude.py
@@ -82,11 +82,6 @@ use_internals_begin = '''#if defined (USE_RINTERNALS_DEFS) && (defined (USE_RINT
 use_internals_end = '''#endif
 #ifdef USE_RINTERNALS
 
-'''
-preserveObject = '''#ifdef FASTR
-SEXP R_PreserveObject_FASTR(SEXP);
-#define R_PreserveObject(var) ((var) = R_PreserveObject_FASTR((var)))
-#else
 '''
 
 def ed_r_internals(gnu_dir):
@@ -114,10 +109,6 @@ def ed_r_internals(gnu_dir):
             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: