From 8cca09822d572b0128fec6aca4908fc55c5a7150 Mon Sep 17 00:00:00 2001
From: Tomas Stupka <tomas.stupka@oracle.com>
Date: Thu, 15 Feb 2018 18:08:17 +0100
Subject: [PATCH] create RCaller in CallMatcherGenericNode based on actual
 arguments permutation

---
 .../r/nodes/function/CallMatcherNode.java        | 14 ++++++++++----
 .../truffle/r/nodes/function/RCallerHelper.java  |  4 ++--
 .../truffle/r/test/ExpectedTestOutput.test       | 10 +++++++++-
 .../r/test/builtins/TestBuiltin_matchcall.java   | 16 +++++++++++++++-
 .../r/test/builtins/TestBuiltin_meandefault.java |  5 ++---
 5 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
index fa01f31ea9..a27af4e3c7 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -343,9 +343,15 @@ public abstract class CallMatcherNode extends RBaseNode {
 
             RCaller parent = RArguments.getCall(frame).getParent();
             String genFunctionName = functionName == null ? function.getName() : functionName;
-            RCaller caller = genFunctionName == null ? RCaller.createInvalid(frame, parent)
-                            : RCaller.create(frame, RCallerHelper.createFromArguments(genFunctionName,
-                                            new RArgsValuesAndNames(reorderedArgs.getArguments(), ArgumentsSignature.empty(reorderedArgs.getLength()))));
+
+            RCaller caller;
+            if (genFunctionName == null) {
+                caller = RCaller.createInvalid(frame, parent);
+            } else {
+                Supplier<RSyntaxElement> argsSupplier = RCallerHelper.createFromArguments(genFunctionName, new RArgsValuesAndNames(suppliedArguments, suppliedSignature));
+                caller = RCaller.create(frame, parent, argsSupplier);
+            }
+
             MaterializedFrame callerFrame = (dispatchArgs instanceof S3Args) ? ((S3Args) dispatchArgs).callEnv : null;
             try {
                 return call.execute(frame, function, caller, callerFrame, reorderedArgs.getArguments(), reorderedArgs.getSignature(), function.getEnclosingFrame(), dispatchArgs);
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 4b1a0f0af8..0962add7cd 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@ public final class RCallerHelper {
         return createFromArgumentsInternal(function, arguments);
     }
 
-    public static Supplier<RSyntaxElement> createFromArgumentsInternal(final Object function, final RArgsValuesAndNames arguments) {
+    private static Supplier<RSyntaxElement> createFromArgumentsInternal(final Object function, final RArgsValuesAndNames arguments) {
         return new Supplier<RSyntaxElement>() {
 
             RSyntaxElement syntaxNode = null;
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index e4c5f5ed01..51789f4ee6 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -39069,6 +39069,14 @@ cat(... = pairlist("abc", p = 3, lab = "b"), sep = ..1, fill = 13)
 #fn3 <- function(...) { (function(...) match.call(cat, call("cat", "abc", p=3,as.symbol("...")), expand.dots = TRUE))(...) }; fn3(sep=x,lab="b",fill=13)
 cat("abc", p = 3, lab = "b", sep = ..1, fill = 13)
 
+##com.oracle.truffle.r.test.builtins.TestBuiltin_matchcall.testMatchCall#
+#{ f <- function(a, ...) { UseMethod('f1', a) };f1.default <- function(a, b=2, c=3, d=4, e=5, ...) { match.call() };f(a=1); f(a=1, b=2); f(a=1, b=2, c=3);f(a=1, b=2, d=4);f(a=1, c=3, d=4, e=5) }
+f1.default(a = 1, c = 3, d = 4, e = 5)
+
+##com.oracle.truffle.r.test.builtins.TestBuiltin_matchcall.testMatchCall#
+#{ f <- function(a, b, c, d, e) { UseMethod('f1', a) };f1.default <- function(a, b=2, c=3, d=4, e=5) { match.call() };f(a=1); f(a=1, b=2); f(a=1, b=2, c=3);f(a=1, b=2, d=4);f(a=1, c=3, d=4, e=5) }
+f1.default(a = 1, c = 3, d = 4, e = 5)
+
 ##com.oracle.truffle.r.test.builtins.TestBuiltin_matchcall.testMatchCall#
 #{ f1<-function(...) { dots <- match.call(expand.dots = FALSE)$...; dots }; f2<-function(...) f1(...); f2("a") }
 [[1]]
@@ -40700,7 +40708,7 @@ In mean.default(x = c(2L, 1L, 2L, 2L)) :
 #argv <- structure(list(x = structure(1412795929.08562, class = c('POSIXct',     'POSIXt'))), .Names = 'x');do.call('mean.POSIXct', argv)
 [1] "2014-10-08 19:18:49 GMT"
 
-##com.oracle.truffle.r.test.builtins.TestBuiltin_meandefault.testmeandefault1#Output.IgnoreWarningContext#
+##com.oracle.truffle.r.test.builtins.TestBuiltin_meandefault.testmeandefault1#
 #argv <- structure(list(x = structure(c(2L, 1L, 2L, 2L), .Label = c('FALSE',     'TRUE'), class = 'factor')), .Names = 'x');do.call('mean.default', argv)
 [1] NA
 Warning message:
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchcall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchcall.java
index 1b61c42d86..934b455fa4 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchcall.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_matchcall.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2012-2014, Purdue University
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -78,6 +78,20 @@ public class TestBuiltin_matchcall extends TestBase {
 
         assertEval("{ foo<-function(...) match.call(expand.dots=F); bar<-function(x) x; y<-42; foo(bar(y), 7) }");
 
+        assertEval("{ f <- function(a, ...) { UseMethod('f1', a) };" +
+                        "f1.default <- function(a, b=2, c=3, d=4, e=5, ...) { match.call() };" +
+                        // fill up signature cache
+                        "f(a=1); f(a=1, b=2); f(a=1, b=2, c=3);f(a=1, b=2, d=4);" +
+                        // this should be ok as well
+                        "f(a=1, c=3, d=4, e=5) }");
+
+        assertEval("{ f <- function(a, b, c, d, e) { UseMethod('f1', a) };" +
+                        "f1.default <- function(a, b=2, c=3, d=4, e=5) { match.call() };" +
+                        // fill up signature cache
+                        "f(a=1); f(a=1, b=2); f(a=1, b=2, c=3);f(a=1, b=2, d=4);" +
+                        // this should be ok as well
+                        "f(a=1, c=3, d=4, e=5) }");
+
         // TODO add tests that pass "definition" and "call" explicitly
     }
 
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_meandefault.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_meandefault.java
index dddae6feba..ccb984ffad 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_meandefault.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_meandefault.java
@@ -4,7 +4,7 @@
  * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * Copyright (c) 2014, Purdue University
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates
  *
  * All rights reserved.
  */
@@ -20,7 +20,6 @@ public class TestBuiltin_meandefault extends TestBase {
 
     @Test
     public void testmeandefault1() {
-        assertEval(Output.IgnoreWarningContext,
-                        "argv <- structure(list(x = structure(c(2L, 1L, 2L, 2L), .Label = c('FALSE',     'TRUE'), class = 'factor')), .Names = 'x');do.call('mean.default', argv)");
+        assertEval("argv <- structure(list(x = structure(c(2L, 1L, 2L, 2L), .Label = c('FALSE',     'TRUE'), class = 'factor')), .Names = 'x');do.call('mean.default', argv)");
     }
 }
-- 
GitLab