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

remove use of RPromise in Return

parent 18d7a3a9
No related branches found
No related tags found
No related merge requests found
...@@ -25,60 +25,35 @@ package com.oracle.truffle.r.nodes.builtin.base; ...@@ -25,60 +25,35 @@ package com.oracle.truffle.r.nodes.builtin.base;
import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX;
import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode;
import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RArguments;
import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RCaller;
import com.oracle.truffle.r.runtime.ReturnException; import com.oracle.truffle.r.runtime.ReturnException;
import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.builtins.RBuiltin;
import com.oracle.truffle.r.runtime.data.RMissing;
import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RPromise;
/** /**
* In the normal case, we are returning from the currently executing function, but in the case where * Return a value from the currently executing function, which is identified by the
* "return" was passed as an argument (promise) (e.g. in tryCatch) to a function, we will be * {@link RArguments#getCall(com.oracle.truffle.api.frame.Frame) call}. The return value will be
* evaluating that in the context of a PromiseEvalFrame and the frame we need to return to is that * delivered via a {@link ReturnException}, which is subsequently caught in the
* given by the PromiseEvalFrame. * {@link FunctionDefinitionNode}.
*/ */
@RBuiltin(name = "return", kind = PRIMITIVE, parameterNames = {"value"}, nonEvalArgs = {0}, behavior = COMPLEX) @RBuiltin(name = "return", kind = PRIMITIVE, parameterNames = {"value"}, behavior = COMPLEX)
public abstract class Return extends RBuiltinNode { public abstract class Return extends RBuiltinNode {
private final BranchProfile isPromiseEvalProfile = BranchProfile.create(); private final BranchProfile isPromiseEvalProfile = BranchProfile.create();
@Child private PromiseHelperNode promiseHelper;
private PromiseHelperNode initPromiseHelper() {
if (promiseHelper == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
promiseHelper = insert(new PromiseHelperNode());
}
return promiseHelper;
}
@Override @Override
public Object[] getDefaultParameterValues() { public Object[] getDefaultParameterValues() {
return new Object[]{RNull.instance}; return new Object[]{RNull.instance};
} }
@Specialization @Specialization
protected Object returnFunction(VirtualFrame frame, @SuppressWarnings("unused") RMissing arg) { protected Object returnFunction(VirtualFrame frame, Object value) {
throw new ReturnException(RNull.instance, RArguments.getCall(frame));
}
@Specialization
protected Object returnFunction(VirtualFrame frame, RNull arg) {
throw new ReturnException(arg, RArguments.getCall(frame));
}
@Specialization
protected Object returnFunction(VirtualFrame frame, RPromise expr) {
// Evaluate the result
Object value = initPromiseHelper().evaluate(frame, expr);
RCaller call = RArguments.getCall(frame); RCaller call = RArguments.getCall(frame);
while (call.isPromise()) { while (call.isPromise()) {
isPromiseEvalProfile.enter(); isPromiseEvalProfile.enter();
......
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