From a72708b9cc7d022b62469a60ee06d6e25979d878 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Thu, 22 Mar 2018 18:09:37 +0100
Subject: [PATCH] convert RArgsValuesAndNames to pairlist when reading from
 native API

---
 .../ffi/impl/common/JavaUpCallsRFFIImpl.java  |  6 ++++-
 .../r/ffi/impl/nodes/ListAccessNodes.java     |  3 ++-
 .../r/runtime/data/RArgsValuesAndNames.java   | 24 +++++++------------
 3 files changed, 16 insertions(+), 17 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 7bdb55e2a5..e874fcffe4 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
@@ -65,6 +65,7 @@ import com.oracle.truffle.r.runtime.context.Engine.ParseException;
 import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.CharSXPWrapper;
 import com.oracle.truffle.r.runtime.data.NativeDataAccess;
+import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RAttributable;
 import com.oracle.truffle.r.runtime.data.RAttributesLayout;
 import com.oracle.truffle.r.runtime.data.RComplexVector;
@@ -230,7 +231,6 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    @TruffleBoundary
     public Object Rf_findVar(Object symbolArg, Object envArg) {
         return findVarInFrameHelper(envArg, symbolArg, true);
     }
@@ -247,6 +247,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
         return findVarInFrameHelper(envArg, symbolArg, false);
     }
 
+    @TruffleBoundary
     private static Object findVarInFrameHelper(Object envArg, Object symbolArg, boolean inherits) {
         if (envArg == RNull.instance) {
             throw RError.error(RError.SHOW_CALLER2, RError.Message.USE_NULL_ENV_DEFUNCT);
@@ -264,6 +265,9 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
                     // env) should not show up
                     return ((RPromise) value).getRawValue();
                 }
+                if (value instanceof RArgsValuesAndNames) {
+                    return ((RArgsValuesAndNames) value).toPairlist();
+                }
                 return value;
             }
             if (!inherits) {
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 bd897ddfbc..62b743b4f5 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
@@ -97,7 +97,8 @@ public final class ListAccessNodes {
 
         @Specialization
         protected Object cdr(RArgsValuesAndNames args) {
-            return args.toPairlist().cdr();
+            // TODO: this is too late - "..." should be converted to pairlist earlier
+            return ((RPairList) args.toPairlist()).cdr();
         }
 
         @Specialization
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java
index f018216085..479a3fcc90 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java
@@ -103,22 +103,16 @@ public final class RArgsValuesAndNames extends RObject implements RTypedValue {
         return str.toString();
     }
 
-    public RPairList toPairlist() {
-        RPairList head = null;
-        assert signature.getLength() == getLength();
-        for (int i = 0; i < getLength(); i++) {
-            String name = signature.getName(i);
-            RPairList cur = RDataFactory.createPairList(getArgument(i), RNull.instance, name != null ? RDataFactory.createSymbol(name) : RNull.instance, SEXPTYPE.DOTSXP);
-
-            if (head == null) {
-                head = cur;
-            } else {
-                head.appendToEnd(cur);
-            }
+    public Object toPairlist() {
+        // special case: empty lists are represented by "missing"
+        if (isEmpty()) {
+            return RMissing.instance;
         }
-        if (head != null) {
-            return head;
+        Object current = RNull.instance;
+        for (int i = getLength() - 1; i >= 0; i--) {
+            String name = signature.getName(i);
+            current = RDataFactory.createPairList(getArgument(i), current, name != null ? RDataFactory.createSymbol(name) : RNull.instance, SEXPTYPE.DOTSXP);
         }
-        return RDataFactory.createPairList(RNull.instance);
+        return current;
     }
 }
-- 
GitLab