diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java index 7bd403ca3263119f4d7bf6c49f089da2d93b4ca8..d2407dfe625f4cda14649e91c61417c594371646 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java @@ -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.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; 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.RCaller; import com.oracle.truffle.r.runtime.ReturnException; 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.RPromise; /** - * In the normal case, we are returning from the currently executing function, but in the case where - * "return" was passed as an argument (promise) (e.g. in tryCatch) to a function, we will be - * evaluating that in the context of a PromiseEvalFrame and the frame we need to return to is that - * given by the PromiseEvalFrame. + * Return a value from the currently executing function, which is identified by the + * {@link RArguments#getCall(com.oracle.truffle.api.frame.Frame) call}. The return value will be + * delivered via a {@link ReturnException}, which is subsequently caught in the + * {@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 { 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 public Object[] getDefaultParameterValues() { return new Object[]{RNull.instance}; } @Specialization - protected Object returnFunction(VirtualFrame frame, @SuppressWarnings("unused") RMissing arg) { - 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); + protected Object returnFunction(VirtualFrame frame, Object value) { RCaller call = RArguments.getCall(frame); while (call.isPromise()) { isPromiseEvalProfile.enter();