diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java index 34a92b26828718e505d2967c5a1c17b2151a093b..2c3f263917181042a3064870a7327750627bba43 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EvalFunctions.java @@ -134,13 +134,13 @@ public class EvalFunctions { try { return RContext.getEngine().eval((RExpression) expr1, envir1, rCaller); } finally { - visibility.executeAfterCall(frame); + visibility.executeAfterCall(frame, rCaller); } } else if (expr1 instanceof RLanguage) { try { return RContext.getEngine().eval((RLanguage) expr1, envir1, rCaller); } finally { - visibility.executeAfterCall(frame); + visibility.executeAfterCall(frame, rCaller); } } else { // just return value diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java index a4f5ca52693fb66098def049f9e8d548f3c5b092..f402cf9e9b67a70256cf38da66b21263de5f693d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RBuiltinRootNode.java @@ -29,18 +29,18 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode; import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.builtins.FastPathFactory; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; public final class RBuiltinRootNode extends RRootNode { @Child private RBuiltinNode builtin; + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); private final RBuiltinFactory factory; @@ -65,24 +65,19 @@ public final class RBuiltinRootNode extends RRootNode { @Override public Object execute(VirtualFrame frame) { verifyEnclosingAssumptions(frame); - Object result = null; try { if (builtin == null) { assert factory.getDispatch() == RDispatch.SPECIAL : "null builtin node only allowed for SPECIAL dispatch"; throw RError.error(RError.SHOW_CALLER, Message.INVALID_USE, factory.getName()); } - result = builtin.execute(frame); + return builtin.execute(frame); } catch (NullPointerException | ArrayIndexOutOfBoundsException | AssertionError e) { CompilerDirectives.transferToInterpreter(); throw new RInternalError(e, "internal error"); + } finally { + visibility.execute(frame, factory.getVisibility()); + visibility.executeEndOfFunction(frame); } - if (factory.getVisibility() == RVisibility.OFF) { - RContext.getInstance().setVisible(false); - } else if (factory.getVisibility() == RVisibility.ON) { - RContext.getInstance().setVisible(true); - } - - return result; } public RBuiltinNode getBuiltinNode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java index 58f248caeb3d1c4aaeb7c70d9492d6b4f16ff260..6cb1c9e2fa8b3bccf305ebb595da5f462c688b14 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/CallMatcherNode.java @@ -252,7 +252,11 @@ public abstract class CallMatcherNode extends RBaseNode { String genFunctionName = functionName == null ? function.getName() : functionName; Supplier<RSyntaxNode> argsSupplier = RCallerHelper.createFromArguments(genFunctionName, preparePermutation, suppliedArguments, suppliedSignature); RCaller caller = genFunctionName == null ? RCaller.createInvalid(frame, parent) : RCaller.create(frame, parent, argsSupplier); - return call.execute(frame, cachedFunction, caller, null, reorderedArgs, matchedArgs.getSignature(), cachedFunction.getEnclosingFrame(), dispatchArgs); + try { + return call.execute(frame, cachedFunction, caller, null, reorderedArgs, matchedArgs.getSignature(), cachedFunction.getEnclosingFrame(), dispatchArgs); + } finally { + visibility.executeAfterCall(frame, caller); + } } else { applyCasts(reorderedArgs); Object result = builtin.execute(frame, reorderedArgs); @@ -327,6 +331,7 @@ public abstract class CallMatcherNode extends RBaseNode { } @Child private CallRFunctionCachedNode call = CallRFunctionCachedNodeGen.create(0); + @Child private SetVisibilityNode visibility = SetVisibilityNode.create(); @Override public Object execute(VirtualFrame frame, ArgumentsSignature suppliedSignature, Object[] suppliedArguments, RFunction function, String functionName, DispatchArgs dispatchArgs) { @@ -338,7 +343,11 @@ public abstract class CallMatcherNode extends RBaseNode { RCaller caller = genFunctionName == null ? RCaller.createInvalid(frame, parent) : RCaller.create(frame, RCallerHelper.createFromArguments(genFunctionName, new RArgsValuesAndNames(reorderedArgs.getArguments(), ArgumentsSignature.empty(reorderedArgs.getLength())))); - return call.execute(frame, function, caller, null, reorderedArgs.getArguments(), reorderedArgs.getSignature(), function.getEnclosingFrame(), dispatchArgs); + try { + return call.execute(frame, function, caller, null, reorderedArgs.getArguments(), reorderedArgs.getSignature(), function.getEnclosingFrame(), dispatchArgs); + } finally { + visibility.executeAfterCall(frame, caller); + } } @Override diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java index 1c8b0fce0bb4616a854b24566febd93c88265a63..bb8e9eb11a7da751329c6c5205821c8ad125a85c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionCachedNode.java @@ -53,28 +53,28 @@ public abstract class CallRFunctionCachedNode extends Node { public final Object execute(VirtualFrame frame, RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, DispatchArgs dispatchArgs) { Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, dispatchArgs); - return execute(frame, function.getTarget(), callArgs); + return execute(frame, function.getTarget(), callArgs, call); } public final Object execute(VirtualFrame frame, RFunction function, RCaller call, MaterializedFrame callerFrame, Object[] evaluatedArgs, ArgumentsSignature suppliedSignature, MaterializedFrame enclosingFrame, DispatchArgs dispatchArgs) { Object[] callArgs = RArguments.create(function, call, callerFrame, evaluatedArgs, suppliedSignature, enclosingFrame, dispatchArgs); - return execute(frame, function.getTarget(), callArgs); + return execute(frame, function.getTarget(), callArgs, call); } - protected abstract Object execute(VirtualFrame frame, CallTarget target, Object[] arguments); + protected abstract Object execute(VirtualFrame frame, CallTarget target, Object[] arguments, RCaller caller); protected static DirectCallNode createDirectCallNode(CallTarget target) { return Truffle.getRuntime().createDirectCallNode(target); } @Specialization(guards = "target == callNode.getCallTarget()", limit = "cacheLimit") - protected Object call(VirtualFrame frame, @SuppressWarnings("unused") CallTarget target, Object[] arguments, + protected Object call(VirtualFrame frame, @SuppressWarnings("unused") CallTarget target, Object[] arguments, RCaller caller, @Cached("createDirectCallNode(target)") DirectCallNode callNode) { try { return callNode.call(frame, arguments); } finally { - visibility.executeAfterCall(frame); + visibility.executeAfterCall(frame, caller); } } @@ -83,12 +83,12 @@ public abstract class CallRFunctionCachedNode extends Node { } @Specialization - protected Object call(VirtualFrame frame, CallTarget target, Object[] arguments, + protected Object call(VirtualFrame frame, CallTarget target, Object[] arguments, RCaller caller, @Cached("createIndirectCallNode()") IndirectCallNode callNode) { try { return callNode.call(frame, target, arguments); } finally { - visibility.executeAfterCall(frame); + visibility.executeAfterCall(frame, caller); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java index 6cdf8d25967db8c12a98fa7d5df2dd0d25f5420c..5a59ddbbf685243ceea25c0650c82c8f0f9d4a9b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/call/CallRFunctionNode.java @@ -57,7 +57,7 @@ public final class CallRFunctionNode extends Node { try { return callNode.call(frame, callArgs); } finally { - visibility.executeAfterCall(frame); + visibility.executeAfterCall(frame, call); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java index e6347e24fff03b405cba20e6da3c414638977aaf..33ec70e1b2d42b00a4159133cc370365a0974c53 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/visibility/SetVisibilityNode.java @@ -33,6 +33,8 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeCost; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RVisibility; import com.oracle.truffle.r.runtime.context.RContext; @@ -45,7 +47,7 @@ public abstract class SetVisibilityNode extends Node { public abstract void execute(VirtualFrame frame, RVisibility visibility); - public abstract void executeAfterCall(VirtualFrame frame); + public abstract void executeAfterCall(VirtualFrame frame, RCaller caller); public abstract void executeEndOfFunction(VirtualFrame frame); @@ -75,7 +77,7 @@ public abstract class SetVisibilityNode extends Node { } @Override - public void executeAfterCall(VirtualFrame frame) { + public void executeAfterCall(VirtualFrame frame, RCaller caller) { // nothing to do } @@ -102,7 +104,7 @@ public abstract class SetVisibilityNode extends Node { } @Override - public void executeAfterCall(VirtualFrame frame) { + public void executeAfterCall(VirtualFrame frame, RCaller caller) { // nothing to do } @@ -119,12 +121,16 @@ public abstract class SetVisibilityNode extends Node { @CompilationFinal private FrameSlot frameSlot; - @Override - public void execute(Frame frame, boolean value) { + private void ensureFrameSlot(Frame frame) { if (frameSlot == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); } + } + + @Override + public void execute(Frame frame, boolean value) { + ensureFrameSlot(frame); frame.setObject(frameSlot, value); } @@ -138,24 +144,18 @@ public abstract class SetVisibilityNode extends Node { } @Override - public void executeAfterCall(VirtualFrame frame) { - if (frameSlot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); - } - frame.setObject(frameSlot, null); + public void executeAfterCall(VirtualFrame frame, RCaller caller) { + ensureFrameSlot(frame); + frame.setObject(frameSlot, caller.getVisibility()); } @Override public void executeEndOfFunction(VirtualFrame frame) { - if (frameSlot == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - frameSlot = frame.getFrameDescriptor().findOrAddFrameSlot(RFrameSlot.Visibility, FrameSlotKind.Object); - } + ensureFrameSlot(frame); try { Object visibility = frame.getObject(frameSlot); if (visibility != null) { - RContext.getInstance().setVisible(visibility == Boolean.TRUE); + RArguments.getCall(frame).setVisibility(visibility == Boolean.TRUE); } } catch (FrameSlotTypeException e) { throw RInternalError.shouldNotReachHere(e); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCaller.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCaller.java index 6de384ca59ac9e204f606368dfef7b05be3b566d..d24866761216019787a11b85552a225121c926c2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCaller.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCaller.java @@ -38,6 +38,7 @@ public final class RCaller { private static final Object PROMISE_MARKER = new Object(); private final int depth; + private boolean visibility; private final RCaller parent; /** * payload can be an RSyntaxNode, a {@link Supplier}, or an PROMISE_MARKER. @@ -116,4 +117,12 @@ public final class RCaller { public static RCaller createForPromise(RCaller original, int newDepth) { return new RCaller(newDepth, original, PROMISE_MARKER); } + + public boolean getVisibility() { + return visibility; + } + + public void setVisibility(boolean visibility) { + this.visibility = visibility; + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java index 05c5cfbc2cd2bf86b593119f905138179d375fd7..dc57b2b69c7cb57f9e09908765a1bbb1328e7d20 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java @@ -66,7 +66,7 @@ public final class RInternalCode { evaluatedEnvironment.setParent(statsPackage); // caller is put into arguments by eval, internal code is assumed to be well-behaved and // not accessing it - context.getThisEngine().eval(parsedCode, evaluatedEnvironment, /* caller: */null); + context.getThisEngine().eval(parsedCode, evaluatedEnvironment, RCaller.createInvalid(null)); return evaluatedEnvironment; } catch (ParseException e) { throw e.throwAsRError();