Skip to content
Snippets Groups Projects
Commit b7b8d7c1 authored by Lukas Stadler's avatar Lukas Stadler
Browse files

Merge pull request #59 in G/fastr from...

Merge pull request #59 in G/fastr from ~LUKAS.STADLER_ORACLE.COM/fastr:feature/tests_recall to master

* commit '90203e3d':
  implement Recall using RCallNode
parents f977cf27 90203e3d
No related branches found
No related tags found
No related merge requests found
......@@ -28,16 +28,16 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.r.nodes.access.FrameSlotNode;
import com.oracle.truffle.r.nodes.access.variables.LocalReadVariableNode;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.nodes.function.CallMatcherNode;
import com.oracle.truffle.r.nodes.function.GetCallerFrameNode;
import com.oracle.truffle.r.nodes.function.RCallNode;
import com.oracle.truffle.r.runtime.ArgumentsSignature;
import com.oracle.truffle.r.runtime.RArguments;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.Utils;
import com.oracle.truffle.r.runtime.builtins.RBuiltin;
import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
import com.oracle.truffle.r.runtime.data.RFunction;
......@@ -51,21 +51,27 @@ public abstract class Recall extends RBuiltinNode {
private final BranchProfile errorProfile = BranchProfile.create();
@Child private LocalReadVariableNode readArgs = LocalReadVariableNode.create(ArgumentsSignature.VARARG_NAME, false);
@Child private CallMatcherNode call = CallMatcherNode.create(false, false);
@Child private GetCallerFrameNode callerFrame = new GetCallerFrameNode();
private final Object argsIdentifier = new Object();
@Child private RCallNode call = RCallNode.createExplicitCall(argsIdentifier);
@Child private FrameSlotNode slot = FrameSlotNode.createTemp(argsIdentifier, true);
@Specialization
protected Object recall(VirtualFrame frame, @SuppressWarnings("unused") RArgsValuesAndNames args) {
/*
* The args passed to the Recall internal are ignored, they are always "...". Instead, this
* builtin looks at the arguments passed to the surrounding function.
*/
Frame cframe = Utils.getCallerFrame(frame, FrameAccess.READ_ONLY);
Frame cframe = callerFrame.execute(frame);
RFunction function = RArguments.getFunction(cframe);
if (function == null) {
errorProfile.enter();
throw RError.error(this, RError.Message.RECALL_CALLED_OUTSIDE_CLOSURE);
throw RError.error(RError.SHOW_CALLER, RError.Message.RECALL_CALLED_OUTSIDE_CLOSURE);
}
/*
* The args passed to the Recall internal are ignored, they are always "...". Instead, this
* builtin looks at the arguments passed to the surrounding function.
*/
RArgsValuesAndNames actualArgs = (RArgsValuesAndNames) readArgs.execute(frame);
return call.execute(frame, actualArgs.getSignature(), actualArgs.getArguments(), function, null, null);
frame.setObject(slot.executeFrameSlot(frame), actualArgs);
return call.execute(frame, function);
}
}
......@@ -22,7 +22,7 @@ public class TestBuiltin_Recall extends TestBase {
assertEval("{ f<-function(i) { if(i<=1) 1 else i*Recall(i-1) } ; f(10) }");
assertEval("{ f<-function(i) { if(i<=1) 1 else i*Recall(i-1) } ; g <- f ; f <- sum ; g(10) }");
assertEval("{ f<-function(i) { if (i==1) { 1 } else if (i==2) { 1 } else { Recall(i-1) + Recall(i-2) } } ; f(10) }");
assertEval(Output.IgnoreErrorContext, "{ Recall(10) }");
assertEval("{ Recall(10) }");
// Recall with more then 1 argument
assertEval("{ f <- function(tarDepth,curDepth) { if (tarDepth == curDepth) {curDepth} else {Recall(tarDepth,curDepth+1)}}; f(3,0) }");
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment