From 83036161cb8d5449c65c59978606b2c255032d81 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Wed, 13 Jul 2016 19:49:48 +0200
Subject: [PATCH] fix calls with erroneous "string" targets

---
 .../truffle/r/nodes/builtin/base/Call.java    | 11 ++++------
 .../com/oracle/truffle/r/nodes/RASTUtils.java |  7 ++-----
 .../r/nodes/function/RCallerHelper.java       | 20 +++++++++++++++++--
 3 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
index 5a7652c91b..ed7e87edb2 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java
@@ -28,6 +28,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.nodes.RASTUtils;
+import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RBuiltin;
@@ -66,17 +67,12 @@ public abstract class Call extends RBuiltinNode {
 
     @TruffleBoundary
     private static RLanguage makeCall(String name, RArgsValuesAndNames args) {
-        return makeCall0(name, false, args);
-    }
-
-    @TruffleBoundary
-    private static RLanguage makeCall(RFunction function, RArgsValuesAndNames args) {
-        return makeCall0(function, false, args);
+        return makeCall0(ReadVariableNode.createFunctionLookup(RSyntaxNode.EAGER_DEPARSE, name), false, args);
     }
 
     @TruffleBoundary
     protected static RLanguage makeCallSourceUnavailable(String name, RArgsValuesAndNames args) {
-        return makeCall0(name, true, args);
+        return makeCall0(ReadVariableNode.createFunctionLookup(RSyntaxNode.EAGER_DEPARSE, name), true, args);
     }
 
     @TruffleBoundary
@@ -92,6 +88,7 @@ public abstract class Call extends RBuiltinNode {
      */
     @TruffleBoundary
     private static RLanguage makeCall0(Object fn, boolean sourceUnavailable, RArgsValuesAndNames argsAndNames) {
+        assert !(fn instanceof String);
         int argLength = argsAndNames == null ? 0 : argsAndNames.getLength();
         RSyntaxNode[] args = new RSyntaxNode[argLength];
         Object[] values = argsAndNames == null ? null : argsAndNames.getArguments();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
index 72995574f0..098ec29439 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java
@@ -231,14 +231,11 @@ public class RASTUtils {
             return RCallNode.createCall(sourceSection, (ReadVariableNode) fn, signature, arguments);
         } else if (fn instanceof NamedRNode) {
             return RCallNode.createCall(RSyntaxNode.SOURCE_UNAVAILABLE, (NamedRNode) fn, signature, arguments);
-        } else if (fn instanceof RFunction) {
-            RFunction rfn = (RFunction) fn;
-            return RCallNode.createCall(sourceSection, ConstantNode.create(rfn), signature, arguments);
         } else if (fn instanceof RCallNode) {
             return RCallNode.createCall(sourceSection, (RCallNode) fn, signature, arguments);
         } else {
-            // this of course would not make much sense if trying to evaluate this call, yet it's
-            // syntactically possible, for example as a result of:
+            // apart from RFunction, this of course would not make much sense if trying to evaluate
+            // this call, yet it's syntactically possible, for example as a result of:
             // f<-function(x,y) sys.call(); x<-f(7, 42); x[c(2,3)]
             return RCallNode.createCall(sourceSection, ConstantNode.create(fn), signature, arguments);
         }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
index ae91e5ca92..794b388afc 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallerHelper.java
@@ -26,11 +26,15 @@ import java.util.function.Supplier;
 
 import com.oracle.truffle.r.nodes.RASTUtils;
 import com.oracle.truffle.r.nodes.access.ConstantNode;
+import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
 import com.oracle.truffle.r.runtime.RCaller;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RPromise;
+import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup;
 import com.oracle.truffle.r.runtime.nodes.RSyntaxNode;
 
 /**
@@ -51,7 +55,18 @@ public final class RCallerHelper {
      * @param arguments array with arguments and corresponding names. This method strips any
      *            {@code RMissing} arguments and unrolls all varargs withint arguments array.
      */
-    public static Supplier<RSyntaxNode> createFromArguments(final Object function, final RArgsValuesAndNames arguments) {
+    public static Supplier<RSyntaxNode> createFromArguments(RFunction function, RArgsValuesAndNames arguments) {
+        return createFromArgumentsInternal(function, arguments);
+    }
+
+    /**
+     * @see #createFromArguments(RFunction, RArgsValuesAndNames)
+     */
+    public static Supplier<RSyntaxNode> createFromArguments(String function, RArgsValuesAndNames arguments) {
+        return createFromArgumentsInternal(function, arguments);
+    }
+
+    public static Supplier<RSyntaxNode> createFromArgumentsInternal(final Object function, final RArgsValuesAndNames arguments) {
         return new Supplier<RSyntaxNode>() {
 
             RSyntaxNode syntaxNode = null;
@@ -87,7 +102,8 @@ public final class RCallerHelper {
                             index++;
                         }
                     }
-                    syntaxNode = RASTUtils.createCall(function, true, ArgumentsSignature.get(signature), syntaxArguments);
+                    Object replacedFunction = function instanceof String ? ReadVariableNode.createFunctionLookup(RSyntaxNode.EAGER_DEPARSE, (String) function) : function;
+                    syntaxNode = RASTUtils.createCall(replacedFunction, true, ArgumentsSignature.get(signature), syntaxArguments);
                 }
                 return syntaxNode;
             }
-- 
GitLab