From 8114c7958c04e53b8142680f305abdf04e148998 Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Mon, 7 Aug 2017 18:32:00 +0200
Subject: [PATCH] Enabling Polyglot SDK tests for FastR

---
 .../com/oracle/truffle/r/engine/interop/ListMR.java | 12 ++++++++++++
 .../r/nodes/access/vector/ExtractVectorNode.java    | 10 ++++++----
 .../r/nodes/access/vector/ReplaceVectorNode.java    | 13 ++++++++-----
 .../truffle/r/test/engine/interop/ListMRTest.java   |  2 +-
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
index 6a873e0868..3aef2f8989 100644
--- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
+++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java
@@ -242,6 +242,18 @@ public class ListMR {
 
         protected abstract Object execute(VirtualFrame frame, TruffleObject receiver, Object idx);
 
+        @Specialization
+        protected Object read(VirtualFrame frame, TruffleObject receiver, double idx,
+                        @Cached("createKeyInfoNode()") ListKeyInfoImplNode keyInfo) {
+            return read(frame, receiver, (int) idx, keyInfo);
+        }
+
+        @Specialization
+        protected Object read(VirtualFrame frame, TruffleObject receiver, long idx,
+                        @Cached("createKeyInfoNode()") ListKeyInfoImplNode keyInfo) {
+            return read(frame, receiver, (int) idx, keyInfo);
+        }
+
         @Specialization
         protected Object read(VirtualFrame frame, TruffleObject receiver, int idx,
                         @Cached("createKeyInfoNode()") ListKeyInfoImplNode keyInfo) {
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
index 6ea4760139..dc5d38c017 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java
@@ -181,6 +181,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
     protected Object accessFieldByVectorPositions(TruffleObject object, Object[] positions, @SuppressWarnings("unused") Object exact, @SuppressWarnings("unused") Object dropDimensions,
                     @Cached("READ.createNode()") Node foreignRead,
                     @Cached("KEY_INFO.createNode()") Node keyInfoNode,
+                    @Cached("HAS_SIZE.createNode()") Node hasSizeNode,
                     @Cached("create()") CastStringNode castNode,
                     @Cached("createFirstString()") FirstStringNode firstString,
                     @Cached("IS_NULL.createNode()") Node isNullNode,
@@ -193,7 +194,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
 
         try {
             for (int i = 0; i < vec.getLength(); i++) {
-                Object res = read(this, vec.getDataAtAsObject(i), foreignRead, keyInfoNode, object, firstString, castNode);
+                Object res = read(this, vec.getDataAtAsObject(i), foreignRead, keyInfoNode, hasSizeNode, object, firstString, castNode);
                 if (RRuntime.isForeignObject(res)) {
                     if (ForeignAccess.sendIsNull(isNullNode, (TruffleObject) res)) {
                         res = RNull.instance;
@@ -215,6 +216,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
     protected Object accessField(TruffleObject object, Object[] positions, @SuppressWarnings("unused") Object exact, @SuppressWarnings("unused") Object dropDimensions,
                     @Cached("READ.createNode()") Node foreignRead,
                     @Cached("KEY_INFO.createNode()") Node keyInfoNode,
+                    @Cached("HAS_SIZE.createNode()") Node hasSizeNode,
                     @Cached("positions.length") @SuppressWarnings("unused") int cachedLength,
                     @Cached("create()") CastStringNode castNode,
                     @Cached("createFirstString()") FirstStringNode firstString,
@@ -231,7 +233,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
             // TODO implicite unboxing ok? method calls seem to behave this way
             Object result = object;
             for (int i = 0; i < pos.length; i++) {
-                result = read(this, pos[i], foreignRead, keyInfoNode, (TruffleObject) result, firstString, castNode);
+                result = read(this, pos[i], foreignRead, keyInfoNode, hasSizeNode, (TruffleObject) result, firstString, castNode);
                 if (pos.length > 1 && i < pos.length - 1) {
                     assert result instanceof TruffleObject;
                 }
@@ -254,7 +256,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
         return foreign2RNode.execute(obj);
     }
 
-    public static Object read(RBaseNode caller, Object positions, Node foreignRead, Node keyInfoNode, TruffleObject object, FirstStringNode firstString, CastStringNode castNode)
+    public static Object read(RBaseNode caller, Object positions, Node foreignRead, Node keyInfoNode, Node hasSizeNode, TruffleObject object, FirstStringNode firstString, CastStringNode castNode)
                     throws RError, InteropException {
         Object pos = positions;
         if (pos instanceof Integer) {
@@ -272,7 +274,7 @@ public abstract class ExtractVectorNode extends RBaseNode {
         }
 
         int info = ForeignAccess.sendKeyInfo(keyInfoNode, object, pos);
-        if (KeyInfo.isReadable(info)) {
+        if (KeyInfo.isReadable(info) || ForeignAccess.sendHasSize(hasSizeNode, object)) {
             return ForeignAccess.sendRead(foreignRead, object, pos);
         } else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) {
             TruffleObject clazz = toJavaClass(object);
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
index 190797cdd4..3d822b62e8 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java
@@ -105,7 +105,8 @@ public abstract class ReplaceVectorNode extends RBaseNode {
     protected Object accessField(TruffleObject object, Object[] positions, Object value,
                     @Cached("WRITE.createNode()") Node foreignWrite,
                     @Cached("READ.createNode()") Node foreignRead,
-                    @Cached("KEY_INFO.createNode()") Node keyInfo,
+                    @Cached("KEY_INFO.createNode()") Node keyInfoNode,
+                    @Cached("HAS_SIZE.createNode()") Node hasSizeNode,
                     @SuppressWarnings("unused") @Cached("positions.length") int cachedLength,
                     @Cached("create()") CastStringNode castNode,
                     @Cached("createFirstString()") FirstStringNode firstString,
@@ -114,16 +115,17 @@ public abstract class ReplaceVectorNode extends RBaseNode {
         try {
             TruffleObject result = object;
             for (int i = 0; i < positions.length - 1; i++) {
-                result = (TruffleObject) ExtractVectorNode.read(this, positions[i], foreignRead, keyInfo, result, firstString, castNode);
+                result = (TruffleObject) ExtractVectorNode.read(this, positions[i], foreignRead, keyInfoNode, hasSizeNode, result, firstString, castNode);
             }
-            write(positions[positions.length - 1], foreignWrite, keyInfo, result, writtenValue, firstString, castNode, r2Foreign);
+            write(positions[positions.length - 1], foreignWrite, keyInfoNode, hasSizeNode, result, writtenValue, firstString, castNode, r2Foreign);
             return object;
         } catch (InteropException e) {
             throw RError.interopError(RError.findParentRBase(this), e, object);
         }
     }
 
-    private void write(Object position, Node foreignWrite, Node keyInfoNode, TruffleObject object, Object writtenValue, FirstStringNode firstString, CastStringNode castNode, R2Foreign r2Foreign)
+    private void write(Object position, Node foreignWrite, Node keyInfoNode, Node hasSizeNode, TruffleObject object, Object writtenValue, FirstStringNode firstString, CastStringNode castNode,
+                    R2Foreign r2Foreign)
                     throws InteropException, RError {
         Object pos = position;
         if (pos instanceof Integer) {
@@ -142,7 +144,8 @@ public abstract class ReplaceVectorNode extends RBaseNode {
         }
 
         int info = ForeignAccess.sendKeyInfo(keyInfoNode, object, pos);
-        if (KeyInfo.isWritable(info)) {
+        if (KeyInfo.isWritable(info) || ForeignAccess.sendHasSize(hasSizeNode, object) ||
+                        (pos instanceof String && !JavaInterop.isJavaObject(Object.class, object))) {
             ForeignAccess.sendWrite(foreignWrite, object, pos, r2Foreign.execute(writtenValue));
             return;
         } else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) {
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java
index 9d21903108..984ed43dec 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java
@@ -77,12 +77,12 @@ public class ListMRTest extends AbstractMRTest {
 
         assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, 0));
         assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, 1));
+        assertEquals(4d, ForeignAccess.sendRead(Message.READ.createNode(), l, 5d));
         assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, 2));
         assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, 4) instanceof RNull);
 
         assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, -1), UnknownIdentifierException.class);
         assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 0f), UnknownIdentifierException.class);
-        assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 4d), UnknownIdentifierException.class);
 
         assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, "nnnoooonnne"), UnknownIdentifierException.class);
         assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 100), UnknownIdentifierException.class);
-- 
GitLab