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 b32d2ebd75900d2c15806c897424d872d08c8b33..78c0a5f01891293040f679506d138ab6c022cc66 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
@@ -35,7 +35,6 @@ 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.java.JavaInterop;
 import com.oracle.truffle.api.nodes.ExplodeLoop;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.r.ffi.impl.common.RFFIUtils;
@@ -51,7 +50,6 @@ import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
 import com.oracle.truffle.r.runtime.ffi.RFFIVariables;
-import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
 
 public class TruffleNFI_Call implements CallRFFI {
 
@@ -71,11 +69,6 @@ public class TruffleNFI_Call implements CallRFFI {
         }
     }
 
-    /**
-     * Nesting of native calls is rare but can happen and the cleanup needs to be per call.
-     */
-    private static int callDepth;
-
     public TruffleNFI_Call() {
         initialize();
     }
@@ -136,89 +129,6 @@ public class TruffleNFI_Call implements CallRFFI {
         }
     }
 
-    private enum ReturnArray {
-        INTEGER_CREATE("([sint32], sint32): uint64", 2),
-        DOUBLE_CREATE("([double], sint32): uint64", 2),
-        BYTE_CREATE("([uint8], sint32, sint32): uint64", 3),
-        INTEGER_EXISTING("(uint64): void", 1),
-        DOUBLE_EXISTING("(uint64): void", 1),
-        BYTE_EXISTING("(uint64): void", 1),
-        FREE("(uint64): void", 1);
-
-        private final String signature;
-        private final String funName;
-        private TruffleObject function;
-        private final Node executeNode;
-
-        ReturnArray(String signature, int numArgs) {
-            this.signature = signature;
-            this.funName = "return_" + name();
-            this.executeNode = Message.createExecute(numArgs).createNode();
-        }
-    }
-
-    private static void initReturnArray() {
-        Node bind = Message.createInvoke(1).createNode();
-        for (ReturnArray returnArrayFun : ReturnArray.values()) {
-            SymbolHandle symbolHandle = DLL.findSymbol(returnArrayFun.funName, null); // libR
-            try {
-                returnArrayFun.function = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", returnArrayFun.signature);
-            } catch (InteropException ex) {
-                throw RInternalError.shouldNotReachHere(ex);
-            }
-        }
-    }
-
-    // TODO Nodify?
-    static long returnArrayCreate(Object array, boolean isString) {
-        try {
-            if (array instanceof int[]) {
-                return (long) ForeignAccess.sendExecute(ReturnArray.INTEGER_CREATE.executeNode, ReturnArray.INTEGER_CREATE.function, JavaInterop.asTruffleObject(array), ((int[]) array).length);
-            } else if (array instanceof double[]) {
-                return (long) ForeignAccess.sendExecute(ReturnArray.DOUBLE_CREATE.executeNode, ReturnArray.DOUBLE_CREATE.function, JavaInterop.asTruffleObject(array), ((double[]) array).length);
-            } else if (array instanceof byte[]) {
-                return (long) ForeignAccess.sendExecute(ReturnArray.BYTE_CREATE.executeNode, ReturnArray.BYTE_CREATE.function, JavaInterop.asTruffleObject(array), ((byte[]) array).length,
-                                isString ? 1 : 0);
-            } else {
-                throw RInternalError.shouldNotReachHere();
-            }
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-
-    static void returnArrayExisting(SEXPTYPE type, long address) {
-        try {
-            switch (type) {
-                case INTSXP:
-                case LGLSXP:
-                    ForeignAccess.sendExecute(ReturnArray.INTEGER_EXISTING.executeNode, ReturnArray.INTEGER_EXISTING.function, address);
-                    break;
-                case REALSXP:
-                    ForeignAccess.sendExecute(ReturnArray.DOUBLE_EXISTING.executeNode, ReturnArray.DOUBLE_EXISTING.function, address);
-                    break;
-                case CHARSXP:
-                case RAWSXP:
-                    ForeignAccess.sendExecute(ReturnArray.BYTE_EXISTING.executeNode, ReturnArray.BYTE_EXISTING.function, address);
-                    break;
-                default:
-                    throw RInternalError.shouldNotReachHere();
-
-            }
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-
-    static void freeArray(long address) {
-        Node executeNode = Message.createExecute(1).createNode();
-        try {
-            ForeignAccess.sendExecute(executeNode, ReturnArray.FREE.function, address);
-        } catch (InteropException ex) {
-            throw RInternalError.shouldNotReachHere(ex);
-        }
-    }
-
     private static void initialize() {
         RFFIUtils.initializeTracing();
         if (traceEnabled()) {
@@ -227,7 +137,6 @@ public class TruffleNFI_Call implements CallRFFI {
         try {
             initCallbacks(new TruffleNFI_UpCallsRFFIImpl());
             initVariables();
-            initReturnArray();
         } finally {
             if (traceEnabled()) {
                 traceDownCallReturn("initialize", null);
@@ -364,8 +273,6 @@ public class TruffleNFI_Call implements CallRFFI {
             args[i] = ffiWrapNodes[i].execute(args[i]);
         }
         boolean isNullSetting = RContext.getRForeignAccessFactory().setIsNull(false);
-        TruffleNFI_NativeArray.callEnter(callDepth);
-        callDepth++;
         return isNullSetting;
     }
 
@@ -373,9 +280,7 @@ public class TruffleNFI_Call implements CallRFFI {
         if (traceEnabled()) {
             traceDownCallReturn(name, result);
         }
-        TruffleNFI_NativeArray.callEnter(callDepth);
         RContext.getRForeignAccessFactory().setIsNull(isNullSetting);
-        callDepth--;
     }
 
     @Override
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_NativeArray.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_NativeArray.java
deleted file mode 100644
index b0b4566be2c7b6fb30f7677599e0aa5c07bcae55..0000000000000000000000000000000000000000
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_NativeArray.java
+++ /dev/null
@@ -1,166 +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 java.util.Arrays;
-
-import com.oracle.truffle.r.runtime.RInternalError;
-import com.oracle.truffle.r.runtime.RRuntime;
-import com.oracle.truffle.r.runtime.data.RIntVector;
-import com.oracle.truffle.r.runtime.data.RLogicalVector;
-import com.oracle.truffle.r.runtime.gnur.SEXPTYPE;
-
-/**
- * Support for the {@code INTEGER, LOGICAL, ...} functions in the RFFI, which must return the same
- * array while an FFI call is in progress.
- */
-public class TruffleNFI_NativeArray {
-    private static int tableHwm;
-    private static int[] hwmStack = new int[16];
-    private static Info[] table = new Info[64];
-
-    static {
-        initTableElements(0);
-    }
-
-    private static class Info {
-        /**
-         * E.g., {@link RIntVector}.
-         */
-        Object x;
-        /**
-         * internal array, e.g. {@code int[]}.
-         */
-        Object array;
-        /**
-         * {@code null} unless {@code x} is an {@link RLogicalVector}, in which case it is the
-         * underlying {@code byte[]}.
-         */
-        byte[] logicalByteArray;
-
-        long arrayAddress;
-    }
-
-    private static void initTableElements(int startIndex) {
-        for (int i = startIndex; i < table.length; i++) {
-            table[i] = new Info();
-        }
-    }
-
-    static void callEnter(int callDepth) {
-        hwmStack[callDepth] = tableHwm;
-    }
-
-    static void callExit(int callDepth) {
-        int oldHwm = hwmStack[callDepth - 1];
-        for (int i = oldHwm; i < tableHwm; i++) {
-            Info info = table[i];
-            if (info.x != null) {
-                if (info.logicalByteArray != null) {
-                    boolean seenNA = false;
-                    int[] xai = (int[]) info.array;
-                    for (int j = 0; j < xai.length; j++) {
-                        int xaival = xai[j];
-                        byte xal;
-                        if (xaival == RRuntime.INT_NA) {
-                            seenNA = true;
-                            xal = RRuntime.LOGICAL_NA;
-                        } else {
-                            xal = (byte) xaival;
-                        }
-                        info.logicalByteArray[j] = xal;
-                    }
-                    if (seenNA) {
-                        RLogicalVector lv = (RLogicalVector) info.x;
-                        lv.setComplete(false);
-                    }
-                }
-                TruffleNFI_Call.freeArray(info.arrayAddress);
-            }
-        }
-        tableHwm = oldHwm;
-    }
-
-    /**
-     * Searches table for an entry matching {@code x}.
-     *
-     * @return the associated native array address or {@code 0} if not found.
-     */
-    static long findArray(Object x) {
-        for (int i = 0; i < tableHwm; i++) {
-            if (table[i].x == x) {
-                return table[i].arrayAddress;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * Records that the {@code array} associated with object {@code x} has been requested by the
-     * native code from, e.g., an {@code INTEGER(x)} function.
-     *
-     * @return the native array address
-     */
-    static long recordArray(Object x, Object array, SEXPTYPE type) {
-        Object xa;
-        byte[] logicalByteArray = null;
-        boolean isString = false;
-        switch (type) {
-            case INTSXP:
-            case REALSXP:
-            case RAWSXP:
-            case CHARSXP:
-                isString = type == SEXPTYPE.CHARSXP;
-                xa = array;
-                break;
-
-            case LGLSXP: {
-                byte[] xal = (byte[]) array;
-                // RFFI wants int*
-                int[] xai = new int[xal.length];
-                for (int i = 0; i < xai.length; i++) {
-                    byte lval = xal[i];
-                    xai[i] = RRuntime.isNA(lval) ? RRuntime.INT_NA : lval;
-                }
-                xa = xai;
-                logicalByteArray = xal;
-                break;
-            }
-
-            default:
-                throw RInternalError.shouldNotReachHere();
-
-        }
-        if (tableHwm == table.length) {
-            table = Arrays.copyOf(table, table.length * 2);
-            initTableElements(tableHwm);
-        }
-        Info t = table[tableHwm];
-        t.x = x;
-        t.array = xa;
-        t.logicalByteArray = logicalByteArray;
-        t.arrayAddress = TruffleNFI_Call.returnArrayCreate(xa, isString);
-        tableHwm++;
-        return t.arrayAddress;
-    }
-}
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 24de7551e03ff2933c240d6f964e7fb38c12ea32..f4efebafbe9047ad42123705048e5ba9c87b280e 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
@@ -53,46 +53,3 @@ void *ensure_string(const char * x) {
 }
 
 #include "../truffle_common/Rinternals_truffle_common.h"
-
-long return_INTEGER_CREATE(int *value, int len) {
-	int* idata = malloc(len * sizeof(int));
-	memcpy(idata, value, len * sizeof(int));
-	return_int = idata;
-	return (long) idata;
-}
-
-long return_DOUBLE_CREATE(double *value, int len) {
-	double* ddata = malloc(len * sizeof(double));
-	memcpy(ddata, value, len * sizeof(double));
-	return_double = ddata;
-	return (long) ddata;
-}
-
-long return_BYTE_CREATE(char *value, int len, int isString) {
-	if (isString) {
-		len += 1;
-	}
-	char* bdata = malloc(len * sizeof(char));
-	memcpy(bdata, value, len * sizeof(char));
-	if (isString) {
-		bdata[len] = 0;
-	}
-	return_byte = bdata;
-	return (long) bdata;
-}
-
-void return_INTEGER_EXISTING(long address) {
-	return_int = (int*) address;
-}
-
-void return_DOUBLE_EXISTING(long address) {
-	return_double = (double*) address;
-}
-
-void return_BYTE_EXISTING(long address) {
-	return_byte = (char*) address;
-}
-
-void return_FREE(void *address) {
-//	free(address);
-}