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

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

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

* commit '1c36352f':
  remove use of RPromise in Return
parents 75791d68 1c36352f
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