From a3e66cf3900c11ad2c82847e3a91aeecfc69af56 Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Mon, 30 Mar 2015 13:51:59 +0200 Subject: [PATCH] CallArgumentsNode.evaluateFlatten to evaluate and flatten in one step --- .../r/nodes/function/CallArgumentsNode.java | 59 +++++++++++++++++-- .../r/nodes/function/GroupDispatchNode.java | 17 +----- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java index 6563d5ff14..f9e95e8bb9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallArgumentsNode.java @@ -25,19 +25,21 @@ package com.oracle.truffle.r.nodes.function; import java.util.*; import com.oracle.truffle.api.*; -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.*; -import com.oracle.truffle.r.nodes.instrument.CreateWrapper; -import com.oracle.truffle.api.instrument.ProbeNode; +import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.access.variables.*; +import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseCheckHelperNode; +import com.oracle.truffle.r.nodes.instrument.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RPromise.Closure; -import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.env.*; /** * This class denotes a list of {@link #getArguments()} together with their names given to a @@ -52,6 +54,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public class CallArgumentsNode extends ArgumentsNode implements UnmatchedArguments { @Child private FrameSlotNode varArgsSlotNode; + @Child private PromiseCheckHelperNode promiseHelper; /** * If a supplied argument is a {@link ReadVariableNode} whose name is "...", this field contains @@ -282,6 +285,54 @@ public class CallArgumentsNode extends ArgumentsNode implements UnmatchedArgumen } } + @ExplodeLoop + public RArgsValuesAndNames evaluateFlatten(VirtualFrame frame) { + int size = arguments.length; + RArgsValuesAndNames varArgInfo = null; + ArgumentsSignature resultSignature = null; + String[] names = null; + if (containsVarArgsSymbol()) { + varArgInfo = getVarargsAndNames(frame); + size += (varArgInfo.length() - 1) * varArgsSymbolIndices.length; + names = new String[size]; + } else { + resultSignature = signature; + } + Object[] values = new Object[size]; + int vargsSymbolsIndex = 0; + int index = 0; + for (int i = 0; i < arguments.length; i++) { + if (vargsSymbolsIndex < varArgsSymbolIndices.length && varArgsSymbolIndices[vargsSymbolsIndex] == i) { + index = flattenVarArgs(frame, varArgInfo, names, values, index); + vargsSymbolsIndex++; + } else { + values[index] = arguments[i] == null ? RMissing.instance : arguments[i].execute(frame); + if (names != null) { + names[index] = signature.getName(i); + } + index++; + } + } + if (resultSignature == null) { + resultSignature = ArgumentsSignature.get(names); + } + return new RArgsValuesAndNames(values, resultSignature); + } + + private int flattenVarArgs(VirtualFrame frame, RArgsValuesAndNames varArgInfo, String[] names, Object[] values, int startIndex) { + int index = startIndex; + for (int j = 0; j < varArgInfo.length(); j++) { + if (promiseHelper == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + promiseHelper = insert(new PromiseCheckHelperNode()); + } + values[index] = promiseHelper.checkEvaluate(frame, varArgInfo.getValues()[j]); + names[index] = varArgInfo.getSignature().getName(j); + index++; + } + return index; + } + @TruffleBoundary public static RNode wrapVarArgValue(Object varArgValue, int varArgIndex) { if (varArgValue instanceof RPromise) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java index 28b1c7ad4c..6afdb0f6e4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/GroupDispatchNode.java @@ -67,21 +67,6 @@ public final class GroupDispatchNode extends RNode { return getSourceSection(); } - protected RArgsValuesAndNames evalArgs(VirtualFrame frame) { - UnrolledVariadicArguments unrolledArgs = callArgsNode.executeFlatten(frame); - RNode[] unevaledArgs = unrolledArgs.getArguments(); - Object[] evaledArgs = new Object[unevaledArgs.length]; - for (int i = 0; i < unevaledArgs.length; ++i) { - if (unevaledArgs[i] != null) { - evaledArgs[i] = unevaledArgs[i].execute(frame); - } else { - evaledArgs[i] = RMissing.instance; - } - } - // Delay assignment to allow recursion - return new RArgsValuesAndNames(evaledArgs, unrolledArgs.getSignature()); - } - @Override public boolean isSyntax() { return true; @@ -115,7 +100,7 @@ public final class GroupDispatchNode extends RNode { @Override public Object execute(VirtualFrame frame) { - RArgsValuesAndNames argAndNames = evalArgs(frame); + RArgsValuesAndNames argAndNames = callArgsNode.evaluateFlatten(frame); Object[] evaluatedArgs = argAndNames.getValues(); RStringVector typeL = evaluatedArgs.length == 0 ? null : getArgClass(evaluatedArgs[0]); -- GitLab