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 339b01a16afa14bdf336809406edf50eb8238b0b..c603e2fc90eed41f694873549c2ef4be7f3375ab 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 @@ -42,6 +42,7 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; @@ -74,7 +75,8 @@ public abstract class Call extends RBuiltinNode.Arg2 { @TruffleBoundary public static RPairList makeCall(TruffleRLanguage language, RSyntaxNode target, Object[] arguments, ArgumentsSignature signature) { assert arguments.length == signature.getLength(); - if (target instanceof RSyntaxLookup && "function".equals(((RSyntaxLookup) target).getIdentifier()) && arguments.length >= 2) { + if (target instanceof RSyntaxLookup && "function".equals(((RSyntaxLookup) target).getIdentifier()) && arguments.length >= 2 && + (arguments[1] == RNull.instance || arguments[1] instanceof RPairList)) { // this optimization is not strictly necessary, `function` builtin is functional too. FunctionExpressionNode function = FunctionBuiltin.createFunctionExpressionNode(language, arguments[0], arguments[1]); return RDataFactory.createLanguage(Closure.createLanguageClosure(function.asRNode())); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index 008adde90936990776a01cc1e36708d6eafa8bb7..82b98b73542ad9d18000a9ca25dab46e5bcf8d4d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -46,6 +46,7 @@ import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; @@ -132,7 +133,17 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra if (node instanceof RSyntaxCall) { RSyntaxCall call = (RSyntaxCall) node; if (call.getSyntaxLHS() instanceof RSyntaxLookup && ((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier().equals("function")) { - assert false : "calls to 'function' should be instances of RSyntaxFunction"; + boolean valid = true; + valid &= call.getSyntaxSignature().getLength() >= 2; + if (valid) { + RSyntaxElement argList = call.getSyntaxArguments()[1]; + valid &= argList instanceof RSyntaxConstant; + if (valid) { + Object list = ((RSyntaxConstant) argList).getValue(); + valid &= list instanceof RNull || list instanceof RPairList; + } + } + assert !valid : "valid calls to 'function' should be instances of RSyntaxFunction"; } } else { assert node instanceof RSyntaxFunction : "invalid contents of 'language' pairlist: " + node;