From 4749b1bdefc8dbbc6d5e3ba4ecc5cea0501e72cb Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Thu, 22 Mar 2018 10:51:03 +0100 Subject: [PATCH] create RSyntaxFunction only for valid function literals, RSyntaxCall otherwise --- .../oracle/truffle/r/nodes/builtin/base/Call.java | 4 +++- .../oracle/truffle/r/runtime/data/RPairList.java | 13 ++++++++++++- 2 files changed, 15 insertions(+), 2 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 339b01a16a..c603e2fc90 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 008adde909..82b98b7354 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; -- GitLab