From 11c8588ab75ea9e4b2b8cba5d7cc8fd266400422 Mon Sep 17 00:00:00 2001
From: Tomas Stupka <tomas.stupka@oracle.com>
Date: Fri, 2 Feb 2018 16:51:41 +0100
Subject: [PATCH] since java lists respond to HAS_SIZE/GET_SIZE they should be
 handled like foreign arrays

---
 .../com/oracle/truffle/r/nodes/builtin/base/Unlist.java    | 7 ++++---
 .../com/oracle/truffle/r/nodes/unary/PrecedenceNode.java   | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
index b48a1b574a..3d79c24d36 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1995-2012, The R Core Team
  * Copyright (c) 2003, The R Foundation
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -193,7 +193,7 @@ public abstract class Unlist extends RBuiltinNode.Arg3 {
                     // arrays, iterables or Objects then no need to recurse
 
                     // TODO well that is not exactly correct, but would be quite crazy
-                    if (!(ct.isArray() || ct.isAssignableFrom(Iterable.class) || ct == Object.class)) {
+                    if (ct != null && !(ct.isArray() || ct.isAssignableFrom(Iterable.class) || ct == Object.class)) {
                         return size;
                     }
                 }
@@ -209,10 +209,11 @@ public abstract class Unlist extends RBuiltinNode.Arg3 {
             return totalSize;
         }
 
-        @Specialization(guards = {"isJavaIterable(obj)"})
+        @Specialization(guards = {"isJavaIterable(obj)", "!isForeignArray(obj, hasSize)"})
         protected int getJavaIterableLength(TruffleObject obj,
                         @Cached("READ.createNode()") Node read,
                         @Cached("createExecute(0).createNode()") Node execute,
+                        @SuppressWarnings("unused") @Cached("HAS_SIZE.createNode()") Node hasSize,
                         @Cached("create()") Foreign2R foreign2R) {
             int totalSize = 0;
             try {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java
index fc2f627470..d3cb285c7c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java
@@ -251,7 +251,7 @@ public abstract class PrecedenceNode extends RBaseNode {
         return LIST_PRECEDENCE;
     }
 
-    @Specialization(guards = {"isJavaIterable(obj)"})
+    @Specialization(guards = {"isJavaIterable(obj)", "!isForeignArray(obj, hasSize)"})
     protected int doJavaIterable(TruffleObject obj, boolean recursive,
                     @Cached("HAS_SIZE.createNode()") Node hasSize,
                     @Cached("READ.createNode()") Node read,
@@ -315,7 +315,7 @@ public abstract class PrecedenceNode extends RBaseNode {
 
     @TruffleBoundary
     private int getPrecedence(Class<?> ct, boolean recursive) {
-        if (recursive && ct.isArray()) {
+        if (recursive && ct != null && ct.isArray()) {
             return getPrecedence(ct.getComponentType(), true);
         }
         return getPrecedence(ct);
-- 
GitLab