From 3f79355d9bba68b3ddecd56bc29cfd3316cc443e Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Mon, 23 Jul 2018 11:44:28 +0200 Subject: [PATCH] Fix error during reporting argument matching error --- .../r/nodes/function/ArgumentMatcher.java | 30 +++++++++++++++++-- .../r/test/functions/TestFunctions.java | 4 +++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java index 8483c48025..ea6eb2d621 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java @@ -31,6 +31,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotTypeException; import com.oracle.truffle.api.nodes.ExplodeLoop; @@ -293,10 +294,33 @@ public class ArgumentMatcher { CompilerAsserts.neverPartOfCompilation(); Frame frame = Utils.getActualCurrentFrame(); try { - // TODO: this error handling code takes many assumptions about the argument types + // TODO: GNUR would show "name = value" in the error, but here we seem to be getting + // only the value. FrameSlot frameSlot = frame.getFrameDescriptor().findFrameSlot(ArgumentsSignature.VARARG_NAME); - RArgsValuesAndNames varArg = (RArgsValuesAndNames) FrameSlotChangeMonitor.getObject(frameSlot, frame); - RPromise promise = (RPromise) varArg.getArguments()[((VarArgNode) node).getIndex()]; + if (frameSlot == null) { + // If the formal signature does not have "...", but the actual does pass + // "...", then the current frame will not contain slot for "..." and we should + // reach + // to caller frame to get it. + frame = Utils.getCallerFrame(RArguments.getCall(frame), FrameAccess.READ_ONLY); + frameSlot = frame.getFrameDescriptor().findFrameSlot(ArgumentsSignature.VARARG_NAME); + } + if (frameSlot == null) { + assert false : "could not find frame slot for ..."; + return "<unknown from ...>"; + } + Object varArgObj = FrameSlotChangeMonitor.getObject(frameSlot, frame); + if (!(varArgObj instanceof RArgsValuesAndNames)) { + assert false : "frame slot for ... does not contain RArgsValuesAndNames"; + return "<unknown from ...>"; + } + RArgsValuesAndNames varArgs = (RArgsValuesAndNames) varArgObj; + Object varArg = varArgs.getArguments()[((VarArgNode) node).getIndex()]; + if (!(varArg instanceof RPromise)) { + assert false : "... did not contain promise as the value at index " + ((VarArgNode) node).getIndex(); + return "<unknown from ...>"; + } + RPromise promise = (RPromise) varArg; return RDeparse.deparseSyntaxElement(promise.getRep().asRSyntaxNode()); } catch (FrameSlotTypeException | ClassCastException e) { throw RInternalError.shouldNotReachHere(); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java index b6880f25ed..4a7aa545a0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/functions/TestFunctions.java @@ -274,6 +274,10 @@ public class TestFunctions extends TestBase { assertEval("{ foo <- function(xaaa, ...) list(xaa=xaaa, ...); foo(xa=4,xaa=5); }"); assertEval("list(`...`=NULL);"); assertEval("`$<-`(someNonesense = list(), anotherNonesense = 'foo', 42)"); + + // Unmatched argument from delegated "..." + // FastR does not provide "c=3", but only "3" in the error message + assertEval(Output.IgnoreErrorMessage, "foo <- function(...) bar(...); bar <- function(a,b) list(a,b); foo(a=1,b=2,c=3);"); } @Test -- GitLab