diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index 43e94209b96cefff28bafc4d3ded94244ab86bbf..26612698417fded8af940440169b54085947ab03 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -359,22 +359,24 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS RBuiltinDescriptor builtin = builtinProfile.profile(function.getRBuiltin()); RArgsValuesAndNames argAndNames = (RArgsValuesAndNames) explicitArgs.execute(frame); - Object dispatchObject = argAndNames.getArgument(0); - - if (isAttributableProfile.profile(dispatchObject instanceof RAttributeStorage) && isS4Profile.profile(((RAttributeStorage) dispatchObject).isS4())) { - RList list = (RList) promiseHelperNode.checkEvaluate(frame, REnvironment.getRegisteredNamespace("methods").get(".BasicFunsList")); - // TODO create a node that looks up the name in the names attribute - int index = list.getElementIndexByName(builtin.getName()); - if (index != -1) { - RFunction basicFun = (RFunction) list.getDataAt(index); - Object result = call.execute(frame, basicFun, argAndNames, null, null); - if (result != RRuntime.DEFERRED_DEFAULT_MARKER) { - return result; + RStringVector type = null; + if (!argAndNames.isEmpty()) { + Object dispatchObject = argAndNames.getArgument(0); + if (isAttributableProfile.profile(dispatchObject instanceof RAttributeStorage) && isS4Profile.profile(((RAttributeStorage) dispatchObject).isS4())) { + RList list = (RList) promiseHelperNode.checkEvaluate(frame, REnvironment.getRegisteredNamespace("methods").get(".BasicFunsList")); + // TODO create a node that looks up the name in the names attribute + int index = list.getElementIndexByName(builtin.getName()); + if (index != -1) { + RFunction basicFun = (RFunction) list.getDataAt(index); + Object result = call.execute(frame, basicFun, argAndNames, null, null); + if (result != RRuntime.DEFERRED_DEFAULT_MARKER) { + return result; + } } } + type = classHierarchyNode.execute(promiseHelperNode.checkEvaluate(frame, dispatchObject)); } - RStringVector type = argAndNames.isEmpty() ? null : classHierarchyNode.execute(promiseHelperNode.checkEvaluate(frame, dispatchObject)); S3Args s3Args; RFunction resultFunction; if (implicitTypeProfile.profile(type != null)) { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java index acdd29b2c6a3286c511c852f0c59036bef5d2efe..85d9ed9b4db6ea6b7c5de1ecba7517ee1cf65f12 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_docall.java @@ -48,5 +48,7 @@ public class TestBuiltin_docall extends TestBase { assertEval("{ boo <- function(c) ls(parent.frame(2)); foo <- function(a,b) boo(a); bar <- function(x,z) do.call('foo', list(parse(text='goo()'),2)); bar() }"); assertEval("{ boo <- function(c) ls(parent.frame(3)); foo <- function(a,b) boo(a); bar <- function(x,z) do.call('foo', list(parse(text='goo()'),2)); baz <- function(bazX) bar(bazX,1); baz(); }"); assertEval("{ f1 <- function(a) ls(parent.frame(2)); f2 <- function(b) f1(b); f3 <- function(c) f2(c); f4 <- function(d) do.call('f3', list(d)); f4(42); }"); + + assertEval("do.call('c', list())"); } }