From 46e9591e9a4f703e1ade0039dc313d2ca3e3d89c Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Mon, 12 Jun 2017 09:33:30 +0200
Subject: [PATCH] FortranAndCFunctions: pass 'hasStrings' to CRFFI.

---
 .../src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java |  9 +--------
 .../truffle/r/ffi/impl/llvm/TruffleLLVM_C.java       |  2 +-
 .../oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java  | 12 ++++++------
 .../builtin/base/foreign/FortranAndCFunctions.java   |  5 ++++-
 .../src/com/oracle/truffle/r/runtime/ffi/CRFFI.java  |  6 +++++-
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
index 824e34a248..2148bacc3b 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/jni/JNI_C.java
@@ -39,18 +39,11 @@ public class JNI_C implements CRFFI {
          */
         @Override
         @TruffleBoundary
-        public void execute(NativeCallInfo nativeCallInfo, Object[] args) {
+        public void execute(NativeCallInfo nativeCallInfo, Object[] args, boolean hasStrings) {
             synchronized (JNI_C.class) {
                 if (traceEnabled()) {
                     traceDownCall(nativeCallInfo.name, args);
                 }
-                boolean hasStrings = false;
-                for (int i = 0; i < args.length; i++) {
-                    if (args[i] instanceof byte[][]) {
-                        hasStrings = true;
-                        break;
-                    }
-                }
                 c(nativeCallInfo.address.asAddress(), args, hasStrings);
             }
         }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
index 8ec43a990d..42e9037d12 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java
@@ -40,7 +40,7 @@ class TruffleLLVM_C implements CRFFI {
         private int numArgs;
 
         @Override
-        public synchronized void execute(NativeCallInfo nativeCallInfo, Object[] args) {
+        public synchronized void execute(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings) {
             TruffleLLVM_DLL.ensureParsed(nativeCallInfo);
             Object[] wargs = wrap(args);
             try {
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
index 939549b4f6..56ec23201e 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java
@@ -42,7 +42,7 @@ public class TruffleNFI_C implements CRFFI {
         @Child private Node bindNode = Message.createInvoke(1).createNode();
 
         @Specialization(guards = "args.length == 0")
-        protected void invokeCall0(NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args,
+        protected void invokeCall0(NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -56,7 +56,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 1")
-        protected void invokeCall1(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall1(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -71,7 +71,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 2")
-        protected void invokeCall2(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall2(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -86,7 +86,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 3")
-        protected void invokeCall3(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall3(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -101,7 +101,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Specialization(guards = "args.length == 4")
-        protected void invokeCall4(NativeCallInfo nativeCallInfo, Object[] args,
+        protected void invokeCall4(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings,
                         @Cached("createExecute(args.length)") Node executeNode) {
             synchronized (TruffleNFI_Call.class) {
                 try {
@@ -116,7 +116,7 @@ public class TruffleNFI_C implements CRFFI {
         }
 
         @Fallback
-        protected void invokeCallN(@SuppressWarnings("unused") NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args) {
+        protected void invokeCallN(@SuppressWarnings("unused") NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings) {
             synchronized (TruffleNFI_Call.class) {
                 throw RInternalError.unimplemented(".C (too many args)");
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
index b1c2b49fce..9665e68e30 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java
@@ -85,6 +85,7 @@ public class FortranAndCFunctions {
             Object[] array = args.getArguments();
             int[] argTypes = new int[array.length];
             Object[] nativeArgs = new Object[array.length];
+            boolean hasStrings = false;
             for (int i = 0; i < array.length; i++) {
                 Object arg = array[i];
                 if (arg instanceof RAbstractDoubleVector) {
@@ -104,10 +105,12 @@ public class FortranAndCFunctions {
                     }
                     nativeArgs[i] = checkNAs(node, i + 1, dataAsInt);
                 } else if (arg instanceof RAbstractStringVector) {
+                    hasStrings = true;
                     argTypes[i] = VECTOR_STRING;
                     checkNAs(node, i + 1, (RAbstractStringVector) arg);
                     nativeArgs[i] = encodeStrings((RAbstractStringVector) arg);
                 } else if (arg instanceof String) {
+                    hasStrings = true;
                     argTypes[i] = SCALAR_STRING;
                     checkNAs(node, i + 1, RString.valueOf((String) arg));
                     nativeArgs[i] = new byte[][]{encodeString((String) arg)};
@@ -124,7 +127,7 @@ public class FortranAndCFunctions {
                     throw node.error(RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1);
                 }
             }
-            invokeCNode.execute(nativeCallInfo, nativeArgs);
+            invokeCNode.execute(nativeCallInfo, nativeArgs, hasStrings);
             // we have to assume that the native method updated everything
             RStringVector listNames = validateArgNames(array.length, args.getSignature());
             Object[] results = new Object[array.length];
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
index f5b547d987..c914be958f 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
@@ -33,8 +33,12 @@ public interface CRFFI {
          * Invoke the native method identified by {@code symbolInfo} passing it the arguments in
          * {@code args}. The values in {@code args} should be native types,e.g., {@code double[]}
          * not {@code RDoubleVector}. Strings are already converted to 2-dimensional byte arrays.
+         *
+         * @param hasStrings if {@code true}, then the {@code args} array may contain one or more
+         *            values of type {@code byte[][]}, which represent arrays of strings in ASCII
+         *            encoding.
          */
-        public abstract void execute(NativeCallInfo nativeCallInfo, Object[] args);
+        public abstract void execute(NativeCallInfo nativeCallInfo, Object[] args, boolean hasStrings);
     }
 
     InvokeCNode createInvokeCNode();
-- 
GitLab