diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java
new file mode 100644
index 0000000000000000000000000000000000000000..45df6f9f1920f0b49d8069efb5df6fb6bed57ed2
--- /dev/null
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.engine.interop;
+
+import com.oracle.truffle.api.interop.CanResolve;
+import com.oracle.truffle.api.interop.MessageResolution;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.engine.TruffleRLanguage;
+import com.oracle.truffle.r.runtime.conn.RConnection;
+
+@MessageResolution(receiverType = RConnection.class, language = TruffleRLanguage.class)
+public class RConnectionMR {
+    @CanResolve
+    public abstract static class RConnection extends Node {
+
+        protected static boolean test(TruffleObject receiver) {
+            return receiver instanceof RConnection;
+        }
+    }
+
+}
diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
index 0c91b000ba52e6f8a9319b5296345a20f1661dd3..428399f41fd83bad08cf5d86c59d0f6e86287b1f 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java
@@ -28,6 +28,7 @@ import com.oracle.truffle.api.interop.ForeignAccess;
 import com.oracle.truffle.api.interop.MessageResolution;
 import com.oracle.truffle.r.engine.TruffleRLanguage;
 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.context.RForeignAccessFactory;
 import com.oracle.truffle.r.runtime.data.RDouble;
@@ -92,6 +93,8 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
             return RDoubleMRForeign.ACCESS;
         } else if (obj instanceof CharSXPWrapper) {
             return CharSXPWrapperMRForeign.ACCESS;
+        } else if (obj instanceof RConnection) {
+            return RConnectionMRForeign.ACCESS;
         } else {
             if (obj instanceof RAbstractVector) {
                 return ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory());
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Makefile b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Makefile
index ce8e60537b640c72ac1312e5e01f4b9f7c39b2bc..8c9fb1057c61c58ffdeac7c13e6c74fb82f4654a 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Makefile
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Makefile
@@ -52,7 +52,7 @@ $(C_OBJECTS): | $(OBJ)
 $(OBJ):
 	mkdir -p $(OBJ)
 
-$(OBJ)/%.o: %.c $(TOPDIR)/include/Rinternals.h $(C_HDRS)
+$(OBJ)/%.o: %.c $(TOPDIR)/include/Rinternals.h rffi_callbacksindex.h $(C_HDRS)
 	$(CC) $(CFLAGS) $(INCLUDES) -I../variable_defs -c $< -o $@
 
 # for debugging, to see what's really being compiled
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacks.h b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacks.h
index d4e0e017dbd3fcb2ada97296839f23219778a4dd..a03e58c1c292b31cd68224431aa13592094104b0 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacks.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacks.h
@@ -23,138 +23,10 @@
 #ifndef CALLBACKS_H
 #define CALLBACKS_H
 
-#define CADDR_x 0
-#define CADR_x 1
-#define CAR_x 2
-#define CDDR_x 3
-#define CDR_x 4
-#define DUPLICATE_ATTRIB_x 5
-#define ENCLOS_x 6
-#define GetRNGstate_x 7
-#define INTEGER_x 8
-#define IS_S4_OBJECT_x 9
-#define LENGTH_x 10
-#define LOGICAL_x 11
-#define NAMED_x 12
-#define OBJECT_x 13
-#define PRCODE_x 14
-#define PRENV_x 15
-#define PRINTNAME_x 16
-#define PRSEEN_x 17
-#define PRVALUE_x 18
-#define PutRNGstate_x 19
-#define RAW_x 20
-#define RDEBUG_x 21
-#define REAL_x 22
-#define RSTEP_x 23
-#define R_BaseEnv_x 24
-#define R_BaseNamespace_x 25
-#define R_BindingIsLocked_x 26
-#define R_CHAR_x 27
-#define R_CleanUp_x 28
-#define R_ExternalPtrAddr_x 29
-#define R_ExternalPtrProt_x 30
-#define R_ExternalPtrTag_x 31
-#define R_FindNamespace_x 32
-#define R_GetConnection_x 33
-#define R_GlobalContext_x 34
-#define R_GlobalEnv_x 35
-#define R_HomeDir_x 36
-#define R_Interactive_x 37
-#define R_MakeExternalPtr_x 38
-#define R_NamespaceRegistry_x 39
-#define R_NewHashedEnv_x 40
-#define R_ParseVector_x 41
-#define R_PromiseExpr_x 42
-#define R_ReadConnection_x 43
-#define R_SetExternalPtrAddr_x 44
-#define R_SetExternalPtrProt_x 45
-#define R_SetExternalPtrTag_x 46
-#define R_ToplevelExec_x 47
-#define R_WriteConnection_x 48
-#define R_computeIdentical_x 49
-#define R_do_MAKE_CLASS_x 50
-#define R_getContextCall_x 51
-#define R_getContextEnv_x 52
-#define R_getContextFun_x 53
-#define R_getContextSrcRef_x 54
-#define R_getGlobalFunctionContext_x 55
-#define R_getParentFunctionContext_x 56
-#define R_insideBrowser_x 57
-#define R_isEqual_x 58
-#define R_isGlobal_x 59
-#define R_lsInternal3_x 60
-#define R_new_custom_connection_x 61
-#define R_tryEval_x 62
-#define Rf_GetOption1_x 63
-#define Rf_PairToVectorList_x 64
-#define Rf_ScalarDouble_x 65
-#define Rf_ScalarInteger_x 66
-#define Rf_ScalarLogical_x 67
-#define Rf_ScalarString_x 68
-#define Rf_allocateArray_x 69
-#define Rf_allocateMatrix_x 70
-#define Rf_allocateVector_x 71
-#define Rf_anyDuplicated_x 72
-#define Rf_asChar_x 73
-#define Rf_asInteger_x 74
-#define Rf_asLogical_x 75
-#define Rf_asReal_x 76
-#define Rf_classgets_x 77
-#define Rf_coerceVector_x 78
-#define Rf_cons_x 79
-#define Rf_copyListMatrix_x 80
-#define Rf_copyMatrix_x 81
-#define Rf_defineVar_x 82
-#define Rf_duplicate_x 83
-#define Rf_error_x 84
-#define Rf_eval_x 85
-#define Rf_findVar_x 86
-#define Rf_findVarInFrame_x 87
-#define Rf_findVarInFrame3_x 88
-#define Rf_findfun_x 89
-#define Rf_getAttrib_x 90
-#define Rf_gsetVar_x 91
-#define Rf_inherits_x 92
-#define Rf_install_x 93
-#define Rf_installChar_x 94
-#define Rf_isNull_x 95
-#define Rf_isString_x 96
-#define Rf_lengthgets_x 97
-#define Rf_mkCharLenCE_x 98
-#define Rf_ncols_x 99
-#define Rf_nrows_x 100
-#define Rf_setAttrib_x 101
-#define Rf_warning_x 102
-#define Rf_warningcall_x 103
-#define Rprintf_x 104
-#define SETCADR_x 105
-#define SETCAR_x 106
-#define SETCDR_x 107
-#define SET_RDEBUG_x 108
-#define SET_RSTEP_x 109
-#define SET_STRING_ELT_x 110
-#define SET_SYMVALUE_x 111
-#define SET_TAG_x 112
-#define SET_TYPEOF_FASTR_x 113
-#define SET_VECTOR_ELT_x 114
-#define STRING_ELT_x 115
-#define SYMVALUE_x 116
-#define TAG_x 117
-#define TYPEOF_x 118
-#define VECTOR_ELT_x 119
-#define getConnectionClassString_x 120
-#define getOpenModeString_x 121
-#define getSummaryDescription_x 122
-#define isSeekable_x 123
-#define unif_rand_x 124
-
-#define CALLBACK_TABLE_SIZE 125
+#include "rffi_callbacksindex.h"
 
 extern void* callbacks[];
 
-// TODO Use an array indexed by above
-
 // This is the complete set , including those not yet implemented
 
 typedef SEXP (*call_Rf_ScalarInteger)(int value);
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacksindex.h b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacksindex.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fcb214834f8119cd6305839457554e07c65cc56
--- /dev/null
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffi_callbacksindex.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// TODO This file should be generated automatically from RFFIUpCallMethod.main
+
+#ifndef CALLBACKSINDEX_H
+#define CALLBACKSINDEX_H
+
+#define CADDR_x 0
+#define CADR_x 1
+#define CAR_x 2
+#define CDDR_x 3
+#define CDR_x 4
+#define DUPLICATE_ATTRIB_x 5
+#define ENCLOS_x 6
+#define GetRNGstate_x 7
+#define INTEGER_x 8
+#define IS_S4_OBJECT_x 9
+#define LENGTH_x 10
+#define LOGICAL_x 11
+#define NAMED_x 12
+#define OBJECT_x 13
+#define PRCODE_x 14
+#define PRENV_x 15
+#define PRINTNAME_x 16
+#define PRSEEN_x 17
+#define PRVALUE_x 18
+#define PutRNGstate_x 19
+#define RAW_x 20
+#define RDEBUG_x 21
+#define REAL_x 22
+#define RSTEP_x 23
+#define R_BaseEnv_x 24
+#define R_BaseNamespace_x 25
+#define R_BindingIsLocked_x 26
+#define R_CHAR_x 27
+#define R_CleanUp_x 28
+#define R_ExternalPtrAddr_x 29
+#define R_ExternalPtrProt_x 30
+#define R_ExternalPtrTag_x 31
+#define R_FindNamespace_x 32
+#define R_GetConnection_x 33
+#define R_GlobalContext_x 34
+#define R_GlobalEnv_x 35
+#define R_HomeDir_x 36
+#define R_Interactive_x 37
+#define R_MakeExternalPtr_x 38
+#define R_NamespaceRegistry_x 39
+#define R_NewHashedEnv_x 40
+#define R_ParseVector_x 41
+#define R_PromiseExpr_x 42
+#define R_ReadConnection_x 43
+#define R_SetExternalPtrAddr_x 44
+#define R_SetExternalPtrProt_x 45
+#define R_SetExternalPtrTag_x 46
+#define R_ToplevelExec_x 47
+#define R_WriteConnection_x 48
+#define R_computeIdentical_x 49
+#define R_do_MAKE_CLASS_x 50
+#define R_do_new_object_x 51
+#define R_do_slot_x 52
+#define R_do_slot_assign_x 53
+#define R_getContextCall_x 54
+#define R_getContextEnv_x 55
+#define R_getContextFun_x 56
+#define R_getContextSrcRef_x 57
+#define R_getGlobalFunctionContext_x 58
+#define R_getParentFunctionContext_x 59
+#define R_insideBrowser_x 60
+#define R_isEqual_x 61
+#define R_isGlobal_x 62
+#define R_lsInternal3_x 63
+#define R_new_custom_connection_x 64
+#define R_tryEval_x 65
+#define Rf_GetOption1_x 66
+#define Rf_PairToVectorList_x 67
+#define Rf_ScalarDouble_x 68
+#define Rf_ScalarInteger_x 69
+#define Rf_ScalarLogical_x 70
+#define Rf_ScalarString_x 71
+#define Rf_allocateArray_x 72
+#define Rf_allocateMatrix_x 73
+#define Rf_allocateVector_x 74
+#define Rf_anyDuplicated_x 75
+#define Rf_asChar_x 76
+#define Rf_asInteger_x 77
+#define Rf_asLogical_x 78
+#define Rf_asReal_x 79
+#define Rf_classgets_x 80
+#define Rf_coerceVector_x 81
+#define Rf_cons_x 82
+#define Rf_copyListMatrix_x 83
+#define Rf_copyMatrix_x 84
+#define Rf_defineVar_x 85
+#define Rf_duplicate_x 86
+#define Rf_error_x 87
+#define Rf_eval_x 88
+#define Rf_findVar_x 89
+#define Rf_findVarInFrame_x 90
+#define Rf_findVarInFrame3_x 91
+#define Rf_findfun_x 92
+#define Rf_getAttrib_x 93
+#define Rf_gsetVar_x 94
+#define Rf_inherits_x 95
+#define Rf_install_x 96
+#define Rf_installChar_x 97
+#define Rf_isNull_x 98
+#define Rf_isString_x 99
+#define Rf_lengthgets_x 100
+#define Rf_mkCharLenCE_x 101
+#define Rf_ncols_x 102
+#define Rf_nrows_x 103
+#define Rf_setAttrib_x 104
+#define Rf_warning_x 105
+#define Rf_warningcall_x 106
+#define Rprintf_x 107
+#define SETCADR_x 108
+#define SETCAR_x 109
+#define SETCDR_x 110
+#define SET_RDEBUG_x 111
+#define SET_RSTEP_x 112
+#define SET_STRING_ELT_x 113
+#define SET_SYMVALUE_x 114
+#define SET_TAG_x 115
+#define SET_TYPEOF_FASTR_x 116
+#define SET_VECTOR_ELT_x 117
+#define STRING_ELT_x 118
+#define SYMVALUE_x 119
+#define TAG_x 120
+#define TYPEOF_x 121
+#define VECTOR_ELT_x 122
+#define getConnectionClassString_x 123
+#define getOpenModeString_x 124
+#define getSummaryDescription_x 125
+#define isSeekable_x 126
+#define unif_rand_x 127
+
+#define CALLBACK_TABLE_SIZE 128
+
+#endif // CALLBACKSINDEX_H
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
index f3a19b00333af052bfcc6c89b6706868e0b3988c..1b3815413391232b5a167a54e49932a66cc36c5e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java
@@ -172,6 +172,7 @@ public enum RFFIUpCallMethod {
         for (RFFIUpCallMethod f : RFFIUpCallMethod.values()) {
             System.out.printf("#define %s_x %d\n", f.name(), f.ordinal());
         }
+        System.out.printf("\n#define CALLBACK_TABLE_SIZE %d\n", RFFIUpCallMethod.values().length);
     }
 
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
index 1314faf88542c234a282bf6b2c961586f455ea08..df7d420c8b6200f86b2afaa6d244e1e3bfef8c1c 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java
@@ -31,12 +31,13 @@ import java.nio.channels.ByteChannel;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection;
 import com.oracle.truffle.r.runtime.context.RContext;
+import com.oracle.truffle.r.runtime.data.RTruffleObject;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 
 /**
  * Denotes an R {@code connection} instance used in the {@code base} I/O library.
  */
-public interface RConnection extends AutoCloseable {
+public interface RConnection extends AutoCloseable, RTruffleObject {
 
     static BaseRConnection fromIndex(int con) {
         return RContext.getInstance().stateRConnection.getConnection(con, true);