From 820dadd1f7bc7ea3f3cd832d4409f0f75d102485 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Tue, 10 Oct 2017 10:07:33 +0200
Subject: [PATCH] fix file.copy, allow LC_ALL in Sys.setlocale, various
 functions from utils.c, implement CDDR, CADR, ...

---
 .../ffi/impl/common/JavaUpCallsRFFIImpl.java  |  25 ++
 .../r/ffi/impl/nodes/ListAccessNodes.java     | 107 +++++-
 .../r/ffi/impl/upcalls/StdUpCallsRFFI.java    |  20 +
 .../fficall/src/common/rffi_upcallsindex.h    | 341 +++++++++---------
 .../fficall/src/common/util_fastr.c           | 172 ++++++++-
 .../Rinternals_truffle_common.h               |  31 +-
 .../r/nodes/builtin/base/FileFunctions.java   |  34 +-
 .../r/nodes/builtin/base/LocaleFunctions.java |  24 +-
 8 files changed, 543 insertions(+), 211 deletions(-)

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 7e6193122e..0826a4ee5e 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
@@ -676,6 +676,11 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         throw implementedAsNode();
     }
 
+    @Override
+    public Object CAAR(Object e) {
+        throw implementedAsNode();
+    }
+
     @Override
     public Object CDR(Object e) {
         throw implementedAsNode();
@@ -686,16 +691,36 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         throw implementedAsNode();
     }
 
+    @Override
+    public Object CDAR(Object e) {
+        throw implementedAsNode();
+    }
+
     @Override
     public Object CADDR(Object e) {
         throw implementedAsNode();
     }
 
+    @Override
+    public Object CADDDR(Object e) {
+        throw implementedAsNode();
+    }
+
+    @Override
+    public Object CAD4R(Object e) {
+        throw implementedAsNode();
+    }
+
     @Override
     public Object CDDR(Object e) {
         throw implementedAsNode();
     }
 
+    @Override
+    public Object CDDDR(Object e) {
+        throw implementedAsNode();
+    }
+
     @Override
     public Object SET_TAG(Object x, Object y) {
         if (x instanceof RPairList) {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
index 051567f2a2..9e8c18a8c8 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java
@@ -26,9 +26,14 @@ import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.dsl.TypeSystemReference;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CAARNodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CAD4RNodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADDDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CARNodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDARNodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDDDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDRNodeGen;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.SETCARNodeGen;
@@ -94,6 +99,22 @@ public final class ListAccessNodes {
         }
     }
 
+    @TypeSystemReference(RTypes.class)
+    public abstract static class CAARNode extends FFIUpCallNode.Arg1 {
+
+        @Child private CARNode car1 = CARNode.create();
+        @Child private CARNode car2 = CARNode.create();
+
+        @Specialization
+        protected Object caar(Object value) {
+            return car2.executeObject(car1.executeObject(value));
+        }
+
+        public static CAARNode create() {
+            return CAARNodeGen.create();
+        }
+    }
+
     @TypeSystemReference(RTypes.class)
     public static final class SETCADRNode extends FFIUpCallNode.Arg2 {
         @Child private SETCARNode setcarNode = SETCARNode.create();
@@ -196,6 +217,21 @@ public final class ListAccessNodes {
         }
     }
 
+    @TypeSystemReference(RTypes.class)
+    public abstract static class CDARNode extends FFIUpCallNode.Arg1 {
+        @Child private CARNode car = CARNode.create();
+        @Child private CDRNode cdr = CDRNode.create();
+
+        @Specialization
+        protected Object cdar(Object value) {
+            return cdr.executeObject(car.executeObject(value));
+        }
+
+        public static CDARNode create() {
+            return CDARNodeGen.create();
+        }
+    }
+
     @TypeSystemReference(RTypes.class)
     public abstract static class CADDRNode extends FFIUpCallNode.Arg1 {
         @Specialization
@@ -218,6 +254,52 @@ public final class ListAccessNodes {
         }
     }
 
+    @TypeSystemReference(RTypes.class)
+    public abstract static class CADDDRNode extends FFIUpCallNode.Arg1 {
+        @Specialization
+        protected Object cadddr(RPairList pl) {
+            RPairList tmp = (RPairList) pl.cddr();
+            return tmp.cadr();
+        }
+
+        @Specialization
+        protected Object cadddr(RLanguage lang) {
+            return lang.getDataAtAsObject(3);
+        }
+
+        @Fallback
+        protected Object cadddr(@SuppressWarnings("unused") Object obj) {
+            throw RInternalError.unimplemented("CADDDR only works on pair lists and language objects");
+        }
+
+        public static CADDDRNode create() {
+            return CADDDRNodeGen.create();
+        }
+    }
+
+    @TypeSystemReference(RTypes.class)
+    public abstract static class CAD4RNode extends FFIUpCallNode.Arg1 {
+        @Specialization
+        protected Object cad4r(RPairList pl) {
+            RPairList tmp = (RPairList) pl.cddr();
+            return tmp.caddr();
+        }
+
+        @Specialization
+        protected Object cad4r(RLanguage lang) {
+            return lang.getDataAtAsObject(4);
+        }
+
+        @Fallback
+        protected Object cad4r(@SuppressWarnings("unused") Object obj) {
+            throw RInternalError.unimplemented("CAD4R only works on pair lists and language objects");
+        }
+
+        public static CAD4RNode create() {
+            return CAD4RNodeGen.create();
+        }
+    }
+
     @TypeSystemReference(RTypes.class)
     public abstract static class CDDRNode extends FFIUpCallNode.Arg1 {
         @Specialization
@@ -226,7 +308,7 @@ public final class ListAccessNodes {
         }
 
         @Specialization
-        protected Object cdr(RLanguage lang) {
+        protected Object cddr(RLanguage lang) {
             RPairList l = lang.getPairList();
             return l.cddr();
         }
@@ -240,4 +322,27 @@ public final class ListAccessNodes {
             return CDDRNodeGen.create();
         }
     }
+
+    @TypeSystemReference(RTypes.class)
+    public abstract static class CDDDRNode extends FFIUpCallNode.Arg1 {
+        @Specialization
+        protected Object cdddr(RPairList pl) {
+            return pl.cddr();
+        }
+
+        @Specialization
+        protected Object cdddr(RLanguage lang) {
+            RPairList l = (RPairList) lang.getPairList().cddr();
+            return l.cdr();
+        }
+
+        @Fallback
+        protected Object cdddr(@SuppressWarnings("unused") Object obj) {
+            throw RInternalError.unimplemented("CDDDR only works on pair lists and language objects");
+        }
+
+        public static CDDDRNode create() {
+            return CDDDRNodeGen.create();
+        }
+    }
 }
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 26c9a460b1..9138e92393 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
@@ -34,9 +34,14 @@ import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.VectorToPairListNode;
 import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes;
 import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.LockBindingNode;
 import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.UnlockBindingNode;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAARNode;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAD4RNode;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CARNode;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CDARNode;
+import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CDDDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CDDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CDRNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.SETCADRNode;
@@ -200,18 +205,33 @@ public interface StdUpCallsRFFI {
     @RFFIUpCallNode(CARNode.class)
     Object CAR(Object e);
 
+    @RFFIUpCallNode(CAARNode.class)
+    Object CAAR(Object e);
+
     @RFFIUpCallNode(CDRNode.class)
     Object CDR(Object e);
 
+    @RFFIUpCallNode(CDARNode.class)
+    Object CDAR(Object e);
+
     @RFFIUpCallNode(CADRNode.class)
     Object CADR(Object e);
 
     @RFFIUpCallNode(CADDRNode.class)
     Object CADDR(Object e);
 
+    @RFFIUpCallNode(CADDDRNode.class)
+    Object CADDDR(Object e);
+
+    @RFFIUpCallNode(CAD4RNode.class)
+    Object CAD4R(Object e);
+
     @RFFIUpCallNode(CDDRNode.class)
     Object CDDR(Object e);
 
+    @RFFIUpCallNode(CDDDRNode.class)
+    Object CDDDR(Object e);
+
     Object SET_TAG(Object x, Object y);
 
     @RFFIUpCallNode(SETCARNode.class)
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 c149521873..faf4a45a09 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
@@ -3,174 +3,179 @@
 #define RFFI_UPCALLSINDEX_H
 
 #define ATTRIB_x 0
-#define CADDR_x 1
-#define CADR_x 2
-#define CAR_x 3
-#define CDDR_x 4
-#define CDR_x 5
-#define CLOENV_x 6
-#define COMPLEX_x 7
-#define DUPLICATE_ATTRIB_x 8
-#define ENCLOS_x 9
-#define FASTR_getConnectionChar_x 10
-#define GetRNGstate_x 11
-#define INTEGER_x 12
-#define IS_S4_OBJECT_x 13
-#define LENGTH_x 14
-#define LOGICAL_x 15
-#define NAMED_x 16
-#define OBJECT_x 17
-#define PRCODE_x 18
-#define PRENV_x 19
-#define PRINTNAME_x 20
-#define PRSEEN_x 21
-#define PRVALUE_x 22
-#define PutRNGstate_x 23
-#define RAW_x 24
-#define RDEBUG_x 25
-#define REAL_x 26
-#define RSTEP_x 27
-#define R_BaseEnv_x 28
-#define R_BaseNamespace_x 29
-#define R_BindingIsLocked_x 30
-#define R_CHAR_x 31
-#define R_CleanUp_x 32
-#define R_ExternalPtrAddr_x 33
-#define R_ExternalPtrProtected_x 34
-#define R_ExternalPtrTag_x 35
-#define R_FindNamespace_x 36
-#define R_GetConnection_x 37
-#define R_GlobalContext_x 38
-#define R_GlobalEnv_x 39
-#define R_Home_x 40
-#define R_HomeDir_x 41
-#define R_Interactive_x 42
-#define R_LockBinding_x 43
-#define R_MakeExternalPtr_x 44
-#define R_MethodsNamespace_x 45
-#define R_NamespaceRegistry_x 46
-#define R_NewHashedEnv_x 47
-#define R_ParseVector_x 48
-#define R_PreserveObject_x 49
-#define R_PromiseExpr_x 50
-#define R_ProtectWithIndex_x 51
-#define R_ReadConnection_x 52
-#define R_ReleaseObject_x 53
-#define R_Reprotect_x 54
-#define R_SetExternalPtrAddr_x 55
-#define R_SetExternalPtrProtected_x 56
-#define R_SetExternalPtrTag_x 57
-#define R_TempDir_x 58
-#define R_ToplevelExec_x 59
-#define R_WriteConnection_x 60
-#define R_alloc_x 61
-#define R_compute_identical_x 62
-#define R_do_MAKE_CLASS_x 63
-#define R_do_new_object_x 64
-#define R_do_slot_x 65
-#define R_do_slot_assign_x 66
-#define R_getClassDef_x 67
-#define R_getContextCall_x 68
-#define R_getContextEnv_x 69
-#define R_getContextFun_x 70
-#define R_getContextSrcRef_x 71
-#define R_getGlobalFunctionContext_x 72
-#define R_getParentFunctionContext_x 73
-#define R_has_slot_x 74
-#define R_insideBrowser_x 75
-#define R_isEqual_x 76
-#define R_isGlobal_x 77
-#define R_lsInternal3_x 78
-#define R_new_custom_connection_x 79
-#define R_tryEval_x 80
-#define R_unLockBinding_x 81
-#define Rf_GetOption1_x 82
-#define Rf_NonNullStringMatch_x 83
-#define Rf_PairToVectorList_x 84
-#define Rf_ScalarDouble_x 85
-#define Rf_ScalarInteger_x 86
-#define Rf_ScalarLogical_x 87
-#define Rf_ScalarString_x 88
-#define Rf_VectorToPairList_x 89
-#define Rf_allocArray_x 90
-#define Rf_allocMatrix_x 91
-#define Rf_allocVector_x 92
-#define Rf_any_duplicated_x 93
-#define Rf_asChar_x 94
-#define Rf_asCharacterFactor_x 95
-#define Rf_asInteger_x 96
-#define Rf_asLogical_x 97
-#define Rf_asReal_x 98
-#define Rf_classgets_x 99
-#define Rf_coerceVector_x 100
-#define Rf_cons_x 101
-#define Rf_copyListMatrix_x 102
-#define Rf_copyMatrix_x 103
-#define Rf_copyMostAttrib_x 104
-#define Rf_defineVar_x 105
-#define Rf_dunif_x 106
-#define Rf_duplicate_x 107
-#define Rf_error_x 108
-#define Rf_errorcall_x 109
-#define Rf_eval_x 110
-#define Rf_findFun_x 111
-#define Rf_findVar_x 112
-#define Rf_findVarInFrame_x 113
-#define Rf_findVarInFrame3_x 114
-#define Rf_getAttrib_x 115
-#define Rf_gsetVar_x 116
-#define Rf_inherits_x 117
-#define Rf_install_x 118
-#define Rf_installChar_x 119
-#define Rf_isNull_x 120
-#define Rf_isString_x 121
-#define Rf_lengthgets_x 122
-#define Rf_match_x 123
-#define Rf_mkCharLenCE_x 124
-#define Rf_namesgets_x 125
-#define Rf_ncols_x 126
-#define Rf_nrows_x 127
-#define Rf_protect_x 128
-#define Rf_punif_x 129
-#define Rf_qunif_x 130
-#define Rf_runif_x 131
-#define Rf_setAttrib_x 132
-#define Rf_str2type_x 133
-#define Rf_unprotect_x 134
-#define Rf_unprotect_ptr_x 135
-#define Rf_warning_x 136
-#define Rf_warningcall_x 137
-#define Rprintf_x 138
-#define SETCADR_x 139
-#define SETCAR_x 140
-#define SETCDR_x 141
-#define SET_NAMED_FASTR_x 142
-#define SET_RDEBUG_x 143
-#define SET_RSTEP_x 144
-#define SET_S4_OBJECT_x 145
-#define SET_STRING_ELT_x 146
-#define SET_SYMVALUE_x 147
-#define SET_TAG_x 148
-#define SET_TYPEOF_FASTR_x 149
-#define SET_VECTOR_ELT_x 150
-#define STRING_ELT_x 151
-#define SYMVALUE_x 152
-#define TAG_x 153
-#define TYPEOF_x 154
-#define UNSET_S4_OBJECT_x 155
-#define VECTOR_ELT_x 156
-#define forceSymbols_x 157
-#define getCCallable_x 158
-#define getConnectionClassString_x 159
-#define getOpenModeString_x 160
-#define getSummaryDescription_x 161
-#define isSeekable_x 162
-#define registerCCallable_x 163
-#define registerRoutines_x 164
-#define setDotSymbolValues_x 165
-#define unif_rand_x 166
-#define useDynamicSymbols_x 167
+#define CAAR_x 1
+#define CAD4R_x 2
+#define CADDDR_x 3
+#define CADDR_x 4
+#define CADR_x 5
+#define CAR_x 6
+#define CDAR_x 7
+#define CDDDR_x 8
+#define CDDR_x 9
+#define CDR_x 10
+#define CLOENV_x 11
+#define COMPLEX_x 12
+#define DUPLICATE_ATTRIB_x 13
+#define ENCLOS_x 14
+#define FASTR_getConnectionChar_x 15
+#define GetRNGstate_x 16
+#define INTEGER_x 17
+#define IS_S4_OBJECT_x 18
+#define LENGTH_x 19
+#define LOGICAL_x 20
+#define NAMED_x 21
+#define OBJECT_x 22
+#define PRCODE_x 23
+#define PRENV_x 24
+#define PRINTNAME_x 25
+#define PRSEEN_x 26
+#define PRVALUE_x 27
+#define PutRNGstate_x 28
+#define RAW_x 29
+#define RDEBUG_x 30
+#define REAL_x 31
+#define RSTEP_x 32
+#define R_BaseEnv_x 33
+#define R_BaseNamespace_x 34
+#define R_BindingIsLocked_x 35
+#define R_CHAR_x 36
+#define R_CleanUp_x 37
+#define R_ExternalPtrAddr_x 38
+#define R_ExternalPtrProtected_x 39
+#define R_ExternalPtrTag_x 40
+#define R_FindNamespace_x 41
+#define R_GetConnection_x 42
+#define R_GlobalContext_x 43
+#define R_GlobalEnv_x 44
+#define R_Home_x 45
+#define R_HomeDir_x 46
+#define R_Interactive_x 47
+#define R_LockBinding_x 48
+#define R_MakeExternalPtr_x 49
+#define R_MethodsNamespace_x 50
+#define R_NamespaceRegistry_x 51
+#define R_NewHashedEnv_x 52
+#define R_ParseVector_x 53
+#define R_PreserveObject_x 54
+#define R_PromiseExpr_x 55
+#define R_ProtectWithIndex_x 56
+#define R_ReadConnection_x 57
+#define R_ReleaseObject_x 58
+#define R_Reprotect_x 59
+#define R_SetExternalPtrAddr_x 60
+#define R_SetExternalPtrProtected_x 61
+#define R_SetExternalPtrTag_x 62
+#define R_TempDir_x 63
+#define R_ToplevelExec_x 64
+#define R_WriteConnection_x 65
+#define R_alloc_x 66
+#define R_compute_identical_x 67
+#define R_do_MAKE_CLASS_x 68
+#define R_do_new_object_x 69
+#define R_do_slot_x 70
+#define R_do_slot_assign_x 71
+#define R_getClassDef_x 72
+#define R_getContextCall_x 73
+#define R_getContextEnv_x 74
+#define R_getContextFun_x 75
+#define R_getContextSrcRef_x 76
+#define R_getGlobalFunctionContext_x 77
+#define R_getParentFunctionContext_x 78
+#define R_has_slot_x 79
+#define R_insideBrowser_x 80
+#define R_isEqual_x 81
+#define R_isGlobal_x 82
+#define R_lsInternal3_x 83
+#define R_new_custom_connection_x 84
+#define R_tryEval_x 85
+#define R_unLockBinding_x 86
+#define Rf_GetOption1_x 87
+#define Rf_NonNullStringMatch_x 88
+#define Rf_PairToVectorList_x 89
+#define Rf_ScalarDouble_x 90
+#define Rf_ScalarInteger_x 91
+#define Rf_ScalarLogical_x 92
+#define Rf_ScalarString_x 93
+#define Rf_VectorToPairList_x 94
+#define Rf_allocArray_x 95
+#define Rf_allocMatrix_x 96
+#define Rf_allocVector_x 97
+#define Rf_any_duplicated_x 98
+#define Rf_asChar_x 99
+#define Rf_asCharacterFactor_x 100
+#define Rf_asInteger_x 101
+#define Rf_asLogical_x 102
+#define Rf_asReal_x 103
+#define Rf_classgets_x 104
+#define Rf_coerceVector_x 105
+#define Rf_cons_x 106
+#define Rf_copyListMatrix_x 107
+#define Rf_copyMatrix_x 108
+#define Rf_copyMostAttrib_x 109
+#define Rf_defineVar_x 110
+#define Rf_dunif_x 111
+#define Rf_duplicate_x 112
+#define Rf_error_x 113
+#define Rf_errorcall_x 114
+#define Rf_eval_x 115
+#define Rf_findFun_x 116
+#define Rf_findVar_x 117
+#define Rf_findVarInFrame_x 118
+#define Rf_findVarInFrame3_x 119
+#define Rf_getAttrib_x 120
+#define Rf_gsetVar_x 121
+#define Rf_inherits_x 122
+#define Rf_install_x 123
+#define Rf_installChar_x 124
+#define Rf_isNull_x 125
+#define Rf_isString_x 126
+#define Rf_lengthgets_x 127
+#define Rf_match_x 128
+#define Rf_mkCharLenCE_x 129
+#define Rf_namesgets_x 130
+#define Rf_ncols_x 131
+#define Rf_nrows_x 132
+#define Rf_protect_x 133
+#define Rf_punif_x 134
+#define Rf_qunif_x 135
+#define Rf_runif_x 136
+#define Rf_setAttrib_x 137
+#define Rf_str2type_x 138
+#define Rf_unprotect_x 139
+#define Rf_unprotect_ptr_x 140
+#define Rf_warning_x 141
+#define Rf_warningcall_x 142
+#define Rprintf_x 143
+#define SETCADR_x 144
+#define SETCAR_x 145
+#define SETCDR_x 146
+#define SET_NAMED_FASTR_x 147
+#define SET_RDEBUG_x 148
+#define SET_RSTEP_x 149
+#define SET_S4_OBJECT_x 150
+#define SET_STRING_ELT_x 151
+#define SET_SYMVALUE_x 152
+#define SET_TAG_x 153
+#define SET_TYPEOF_FASTR_x 154
+#define SET_VECTOR_ELT_x 155
+#define STRING_ELT_x 156
+#define SYMVALUE_x 157
+#define TAG_x 158
+#define TYPEOF_x 159
+#define UNSET_S4_OBJECT_x 160
+#define VECTOR_ELT_x 161
+#define forceSymbols_x 162
+#define getCCallable_x 163
+#define getConnectionClassString_x 164
+#define getOpenModeString_x 165
+#define getSummaryDescription_x 166
+#define isSeekable_x 167
+#define registerCCallable_x 168
+#define registerRoutines_x 169
+#define setDotSymbolValues_x 170
+#define unif_rand_x 171
+#define useDynamicSymbols_x 172
 
-#define UPCALLS_TABLE_SIZE 168
+#define UPCALLS_TABLE_SIZE 173
 
 #endif // RFFI_UPCALLSINDEX_H
diff --git a/com.oracle.truffle.r.native/fficall/src/common/util_fastr.c b/com.oracle.truffle.r.native/fficall/src/common/util_fastr.c
index a715a69fcb..4d61935029 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/util_fastr.c
+++ b/com.oracle.truffle.r.native/fficall/src/common/util_fastr.c
@@ -5,13 +5,14 @@
  *
  * Copyright (c) 1995-2015, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
 
 #include <Rinternals.h>
 #include <stdlib.h>
+#include <float.h>
 #include <R_ext/RS.h>
 
 #define _(Source) (Source)
@@ -218,3 +219,172 @@ SEXP nthcdr(SEXP s, int n)
     else error(_("'nthcdr' needs a list to CDR down"));
     return R_NilValue;/* for -Wall */
 }
+
+#define LDOUBLE double
+
+double R_strtod5(const char *str, char **endptr, char dec,
+                 Rboolean NA, int exact)
+{
+    LDOUBLE ans = 0.0, p10 = 10.0, fac = 1.0;
+    int n, expn = 0, sign = 1, ndigits = 0, exph = -1;
+    const char *p = str;
+
+    /* optional whitespace */
+    while (isspace(*p)) p++;
+
+    if (NA && strncmp(p, "NA", 2) == 0) {
+        ans = NA_REAL;
+        p += 2;
+        goto done;
+    }
+
+   /* optional sign */
+    switch (*p) {
+    case '-': sign = -1;
+    case '+': p++;
+    default: ;
+    }
+
+    if (strncasecmp(p, "NaN", 3) == 0) {
+        ans = R_NaN;
+        p += 3;
+        goto done;
+    /* C99 specifies this: must come first to avoid 'inf' match */
+    } else if (strncasecmp(p, "infinity", 8) == 0) {
+        ans = R_PosInf;
+        p += 8;
+        goto done;
+    } else if (strncasecmp(p, "Inf", 3) == 0) {
+        ans = R_PosInf;
+        p += 3;
+        goto done;
+    }
+
+    if(strlen(p) > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+        /* This will overflow to Inf if appropriate */
+        for(p += 2; p; p++) {
+            if('0' <= *p && *p <= '9') ans = 16*ans + (*p -'0');
+            else if('a' <= *p && *p <= 'f') ans = 16*ans + (*p -'a' + 10);
+            else if('A' <= *p && *p <= 'F') ans = 16*ans + (*p -'A' + 10);
+            else if(*p == dec) {exph = 0; continue;}
+            else break;
+            if (exph >= 0) exph += 4;
+        }
+#define strtod_EXACT_CLAUSE                                             \
+        if(exact && ans > 0x1.fffffffffffffp52) {                       \
+            if(exact == NA_LOGICAL)                                     \
+                warning(_(                                              \
+                "accuracy loss in conversion from \"%s\" to numeric"),  \
+                        str);                                           \
+            else {                                                      \
+                ans = NA_REAL;                                          \
+                p = str; /* back out */                                 \
+                goto done;                                              \
+            }                                                           \
+        }
+        strtod_EXACT_CLAUSE;
+        if (*p == 'p' || *p == 'P') {
+            int expsign = 1;
+            double p2 = 2.0;
+            switch(*++p) {
+            case '-': expsign = -1;
+            case '+': p++;
+            default: ;
+            }
+            /* The test for n is in response to PR#16358; it's not right if the exponent is
+               very large, but the overflow or underflow below will handle it. */
+#define MAX_EXPONENT_PREFIX 9999
+            for (n = 0; *p >= '0' && *p <= '9'; p++) n = (n < MAX_EXPONENT_PREFIX) ? n * 10 + (*p - '0') : n;
+            if (ans != 0.0) { /* PR#15976:  allow big exponents on 0 */
+                expn += expsign * n;
+                if(exph > 0) {
+                    if (expn - exph < -122) {   /* PR#17199:  fac may overflow below if expn - exph is too small.
+                                                   2^-122 is a bit bigger than 1E-37, so should be fine on all systems */
+                        for (n = exph, fac = 1.0; n; n >>= 1, p2 *= p2)
+                            if (n & 1) fac *= p2;
+                        ans /= fac;
+                        p2 = 2.0;
+                    } else
+                        expn -= exph;
+                }
+                if (expn < 0) {
+                    for (n = -expn, fac = 1.0; n; n >>= 1, p2 *= p2)
+                        if (n & 1) fac *= p2;
+                    ans /= fac;
+                } else {
+                    for (n = expn, fac = 1.0; n; n >>= 1, p2 *= p2)
+                        if (n & 1) fac *= p2;
+                    ans *= fac;
+                }
+            }
+        }
+        goto done;
+    }
+
+    for ( ; *p >= '0' && *p <= '9'; p++, ndigits++) ans = 10*ans + (*p - '0');
+    if (*p == dec)
+        for (p++; *p >= '0' && *p <= '9'; p++, ndigits++, expn--)
+            ans = 10*ans + (*p - '0');
+    if (ndigits == 0) {
+        ans = NA_REAL;
+        p = str; /* back out */
+        goto done;
+    }
+    strtod_EXACT_CLAUSE;
+
+    if (*p == 'e' || *p == 'E') {
+        int expsign = 1;
+        switch(*++p) {
+        case '-': expsign = -1;
+        case '+': p++;
+        default: ;
+        }
+        for (n = 0; *p >= '0' && *p <= '9'; p++) n = (n < MAX_EXPONENT_PREFIX) ? n * 10 + (*p - '0') : n;
+        expn += expsign * n;
+    }
+
+    /* avoid unnecessary underflow for large negative exponents */
+    if (expn + ndigits < -300) {
+        for (n = 0; n < ndigits; n++) ans /= 10.0;
+        expn += ndigits;
+    }
+    if (expn < -307) { /* use underflow, not overflow */
+        for (n = -expn, fac = 1.0; n; n >>= 1, p10 *= p10)
+            if (n & 1) fac /= p10;
+        ans *= fac;
+    } else if (expn < 0) { /* positive powers are exact */
+        for (n = -expn, fac = 1.0; n; n >>= 1, p10 *= p10)
+            if (n & 1) fac *= p10;
+        ans /= fac;
+    } else if (ans != 0.0) { /* PR#15976:  allow big exponents on 0, e.g. 0E4933 */
+        for (n = expn, fac = 1.0; n; n >>= 1, p10 *= p10)
+            if (n & 1) fac *= p10;
+        ans *= fac;
+    }
+
+    /* explicit overflow to infinity */
+    if (ans > DBL_MAX) {
+        if (endptr) *endptr = (char *) p;
+        return (sign > 0) ? R_PosInf : R_NegInf;
+    }
+
+done:
+    if (endptr) *endptr = (char *) p;
+    return sign * (double) ans;
+}
+
+
+double R_strtod4(const char *str, char **endptr, char dec, Rboolean NA)
+{
+    return R_strtod5(str, endptr, dec, NA, FALSE);
+}
+
+double R_strtod(const char *str, char **endptr)
+{
+    return R_strtod5(str, endptr, '.', FALSE, FALSE);
+}
+
+double R_atof(const char *str)
+{
+    return R_strtod5(str, NULL, '.', FALSE, FALSE);
+}
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 699f70c482..cc43c6ff9c 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
@@ -663,14 +663,16 @@ SEXP PRINTNAME(SEXP e) {
 
 SEXP CAAR(SEXP e) {
     TRACE0();
-    unimplemented("CAAR");
-    return NULL;
+    SEXP result = ((call_CAAR) callbacks[CAAR_x])(e);
+    checkExitCall();
+    return result;
 }
 
 SEXP CDAR(SEXP e) {
     TRACE0();
-    unimplemented("CDAR");
-    return NULL;
+    SEXP result = ((call_CDAR) callbacks[CDAR_x])(e);
+    checkExitCall();
+    return result;
 }
 
 SEXP CADR(SEXP e) {
@@ -689,8 +691,9 @@ SEXP CDDR(SEXP e) {
 
 SEXP CDDDR(SEXP e) {
     TRACE0();
-    unimplemented("CDDDR");
-    return NULL;
+    SEXP result = ((call_CDDDR) callbacks[CDDDR_x])(e);
+    checkExitCall();
+    return result;
 }
 
 SEXP CADDR(SEXP e) {
@@ -702,14 +705,16 @@ SEXP CADDR(SEXP e) {
 
 SEXP CADDDR(SEXP e) {
     TRACE0();
-    unimplemented("CADDDR");
-    return NULL;
+    SEXP result = ((call_CADDDR) callbacks[CADDDR_x])(e);
+    checkExitCall();
+    return result;
 }
 
 SEXP CAD4R(SEXP e) {
     TRACE0();
-    unimplemented("CAD4R");
-    return NULL;
+    SEXP result = ((call_CAD4R) callbacks[CAD4R_x])(e);
+    checkExitCall();
+    return result;
 }
 
 int MISSING(SEXP x) {
@@ -1364,7 +1369,7 @@ 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");
@@ -1375,7 +1380,7 @@ double R_strtod(const char *c, char **end) {
     TRACE0();
     unimplemented("R_strtod");
     return 0;
-}
+}*/
 
 SEXP R_PromiseExpr(SEXP x) {
     TRACE0();
@@ -1509,7 +1514,7 @@ SEXP R_do_slot_assign(SEXP obj, SEXP name, SEXP value) {
 
 int R_has_slot(SEXP obj, SEXP name) {
     TRACE(TARGpp, obj, name);
-    SEXP result = ((call_R_has_slot) callbacks[R_has_slot_x])(obj, name);
+    int result = ((call_R_has_slot) callbacks[R_has_slot_x])(obj, name);
     checkExitCall();
     return result;
 }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
index acd936402b..ddddd0287c 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java
@@ -913,10 +913,8 @@ public class FileFunctions {
                 if (copyMode || copyDate) {
                     copyOptions = new CopyOption[overwrite ? 2 : 1];
                     copyOptions[overwrite ? 1 : 0] = StandardCopyOption.COPY_ATTRIBUTES;
-                } else if (overwrite) {
-                    copyOptions = new CopyOption[1];
                 } else {
-                    copyOptions = new CopyOption[0];
+                    copyOptions = new CopyOption[overwrite ? 1 : 0];
                 }
                 if (overwrite) {
                     copyOptions[0] = StandardCopyOption.REPLACE_EXISTING;
@@ -938,20 +936,20 @@ public class FileFunctions {
 
                 for (int i = 0; i < lenFrom; i++) {
                     String from = vecFrom.getDataAt(i % lenFrom);
-                    String to = vecTo.getDataAt(i % lenTo);
-                    Path fromPathKeepRel = fileSystem.getPath(Utils.tildeExpand(from, true));
-                    if (toDir != null && !fromPathKeepRel.isAbsolute()) {
-                        to = toDir.resolve(fromPathKeepRel.getFileName()).toString();
-                    }
                     Path fromPath = fileSystem.getPath(Utils.tildeExpand(from));
+                    String to = vecTo.getDataAt(i % lenTo);
                     Path toPath = fileSystem.getPath(Utils.tildeExpand(to));
-                    status[i] = RRuntime.LOGICAL_TRUE;
+                    assert !recursive || toDir != null;
+                    status[i] = RRuntime.LOGICAL_FALSE;
                     try {
-                        if (recursive && Files.isDirectory(fromPath)) {
-                            // to is just one dir (checked above)
-                            boolean copyError = copyDir(fromPath, toPath, copyOptions);
-                            if (copyError) {
-                                status[i] = RRuntime.LOGICAL_FALSE;
+                        if (toDir != null) {
+                            toPath = toDir.resolve(fromPath.getFileName());
+                        }
+                        if (Files.isDirectory(fromPath)) {
+                            if (recursive) {
+                                assert toDir != null;
+                                // to is just one dir (checked above)
+                                status[i] = RRuntime.asLogical(copyDir(fromPath, toPath, copyOptions));
                             }
                         } else {
                             // copy to existing files is skipped unless overWrite
@@ -960,15 +958,11 @@ public class FileFunctions {
                                  * toB Be careful if toPath is a directory, if empty Java will
                                  * replace it with a plain file, otherwise the copy will fail
                                  */
-                                if (Files.isDirectory(toPath)) {
-                                    Path fromFileNamePath = fromPath.getFileName();
-                                    toPath = toPath.resolve(fromFileNamePath);
-                                }
                                 Files.copy(fromPath, toPath, copyOptions);
+                                status[i] = RRuntime.LOGICAL_TRUE;
                             }
                         }
                     } catch (UnsupportedOperationException | IOException ex) {
-                        status[i] = RRuntime.LOGICAL_FALSE;
                         warning(RError.Message.FILE_CANNOT_COPY, from, to, ex.getMessage());
                     }
                 }
@@ -1014,7 +1008,7 @@ public class FileFunctions {
         private boolean copyDir(Path fromDir, Path toDir, CopyOption[] copyOptions) throws IOException {
             DirCopy dirCopy = new DirCopy(fromDir, toDir, copyOptions);
             Files.walkFileTree(fromDir, dirCopy);
-            return dirCopy.error;
+            return !dirCopy.error;
         }
     }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LocaleFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LocaleFunctions.java
index ddbc3242d7..49df208d7e 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LocaleFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LocaleFunctions.java
@@ -87,8 +87,12 @@ public class LocaleFunctions {
             }
         }
 
-        private static int getLCCategory(int category) {
-            return category - 2;
+        private static boolean isAll(int category) {
+            return category == 1;
+        }
+
+        private static LC getLCCategory(int category) {
+            return LC.values()[category - 2];
         }
     }
 
@@ -109,8 +113,7 @@ public class LocaleFunctions {
         }
 
         protected String getLocaleData(int category) {
-            String data = "";
-            if (category == 1) {
+            if (LC.isAll(category)) {
                 // "LC_ALL"
                 StringBuilder sb = new StringBuilder();
                 for (int i = 0; i < ALL_CATEGORIES.length; i++) {
@@ -122,11 +125,10 @@ public class LocaleFunctions {
                         }
                     }
                 }
-                data = sb.toString();
+                return sb.toString();
             } else {
-                data = LC.values()[LC.getLCCategory(category)].getLCEnvVar();
+                return LC.getLCCategory(category).getLCEnvVar();
             }
-            return data;
         }
     }
 
@@ -142,7 +144,13 @@ public class LocaleFunctions {
         @Specialization
         @TruffleBoundary
         protected Object setLocale(int category, String locale) {
-            LC.values()[LC.getLCCategory(category)].value = locale;
+            if (LC.isAll(category)) {
+                for (LC lc : LC.values()) {
+                    lc.value = locale;
+                }
+            } else {
+                LC.getLCCategory(category).value = locale;
+            }
             return locale;
         }
     }
-- 
GitLab