Skip to content
Snippets Groups Projects
Commit 5f42e5fb authored by Mick Jordan's avatar Mick Jordan
Browse files

suppress debugging across R calls used internally

parent c5517936
Branches
No related tags found
No related merge requests found
......@@ -83,6 +83,12 @@ public class DebugHandling {
*/
private static final WeakHashMap<FunctionUID, FunctionStatementsEventReceiver> receiverMap = new WeakHashMap<>();
/**
* This flag is used to (temporarily) disable all debugging across calls that are used
* internally in the implementation.
*/
private static boolean globalDisable;
/**
* Attach the DebugHandling instrument to the FunctionStatementsNode and all syntactic nodes.
*/
......@@ -113,6 +119,19 @@ public class DebugHandling {
return fser != null && !fser.disabled();
}
/**
* Disables/enables debugging globally. Intended to be used for short period, typically while
* executing functions used internally by the implementation.
*
* @param disable {@code true} to disable, {@code false} to enable.
* @return the current value (default {@code false}.
*/
public static boolean globalDisable(boolean disable) {
boolean current = globalDisable;
globalDisable = disable;
return current;
}
private static Probe findStartMethodProbe(FunctionDefinitionNode fdn) {
return RInstrument.findSingleProbe(fdn.getUID(), StandardSyntaxTag.START_METHOD);
}
......@@ -189,7 +208,7 @@ public class DebugHandling {
}
boolean disabled() {
return disabled;
return disabled || globalDisable;
}
void disable() {
......@@ -496,11 +515,13 @@ public class DebugHandling {
@Override
public void tagTrappedAt(Node node, MaterializedFrame frame) {
FunctionBodyNode functionBodyNode = (FunctionBodyNode) node;
FunctionDefinitionNode fdn = (FunctionDefinitionNode) functionBodyNode.getRootNode();
ensureSingleStep(fdn);
clearTrap();
// next stop will be the START_METHOD node
if (!globalDisable) {
FunctionBodyNode functionBodyNode = (FunctionBodyNode) node;
FunctionDefinitionNode fdn = (FunctionDefinitionNode) functionBodyNode.getRootNode();
ensureSingleStep(fdn);
clearTrap();
// next stop will be the START_METHOD node
}
}
static void setTrap() {
......
......@@ -32,6 +32,7 @@ import com.oracle.truffle.r.nodes.access.variables.*;
import com.oracle.truffle.r.nodes.control.*;
import com.oracle.truffle.r.nodes.function.*;
import com.oracle.truffle.r.nodes.function.PromiseNode.VarArgsPromiseNode;
import com.oracle.truffle.r.nodes.instrument.debug.*;
import com.oracle.truffle.r.runtime.*;
import com.oracle.truffle.r.runtime.RContext.Engine.*;
import com.oracle.truffle.r.runtime.RDeparse.State;
......@@ -267,26 +268,40 @@ public class RASTHelperImpl implements RASTHelper {
// most unexpected
throw RInternalError.shouldNotReachHere();
}
}
/**
* TODO replace with more efficient implementation.
*/
private static Object callOut(RCallNode callNode, int depth, Object... args) {
RNode[] argNodes = new RNode[args.length];
for (int i = 0; i < args.length; i++) {
argNodes[i] = ConstantNode.create(args[i]);
}
RCallNode call = RCallNode.createCloneReplacingArgs(callNode, argNodes);
/*
* It's important to disable/enable debugging across this call as it isn't really part of
* the user execution.
*/
boolean gd = DebugHandling.globalDisable(true);
try {
return RContext.getEngine().eval(RDataFactory.createLanguage(call), REnvironment.globalEnv(), depth + 1);
} catch (PutException ex) {
throw RInternalError.shouldNotReachHere("callOut");
} finally {
DebugHandling.globalDisable(gd);
}
}
private static final Source GET_NAMESPACE_SOURCE = Source.asPseudoFile("..getNamespace(name)", "<..getNamespace>");
private static RCallNode getNamespaceCall;
/**
* A rather obscure piece of code used in package loading for lazy loading.
*/
@Override
public REnvironment findNamespace(RStringVector name, int depth) {
if (getNamespaceCall == null) {
getNamespaceCall = getCallNode(GET_NAMESPACE_SOURCE);
}
RCallNode call = RCallNode.createCloneReplacingArgs(getNamespaceCall, ConstantNode.create(name));
try {
return (REnvironment) RContext.getEngine().eval(RDataFactory.createLanguage(call), REnvironment.globalEnv(), depth + 1);
} catch (PutException ex) {
throw RInternalError.shouldNotReachHere("findNamespace");
}
return (REnvironment) callOut(getNamespaceCall, depth, name);
}
private static final Source HANDLE_SIMPLE_ERROR_SOURCE = Source.asPseudoFile(".handleSimpleError(h, msg, call)", "<.handleSimpleError>");
......@@ -297,12 +312,7 @@ public class RASTHelperImpl implements RASTHelper {
if (handleSimpleErrorCall == null) {
handleSimpleErrorCall = getCallNode(HANDLE_SIMPLE_ERROR_SOURCE);
}
RCallNode callNode = RCallNode.createCloneReplacingArgs(handleSimpleErrorCall, ConstantNode.create(f), ConstantNode.create(msg), ConstantNode.create(call));
try {
RContext.getEngine().eval(RDataFactory.createLanguage(callNode), REnvironment.globalEnv(), depth + 1);
} catch (PutException ex) {
throw RInternalError.shouldNotReachHere("handleSimpleError");
}
callOut(handleSimpleErrorCall, depth, f, msg, call);
}
private static final Source SIGNAL_SIMPLE_WARNING_SOURCE = Source.asPseudoFile(".signalSimpleWarning(call, msg)", "<.signalSimpleWarning>");
......@@ -312,13 +322,7 @@ public class RASTHelperImpl implements RASTHelper {
if (signalSimpleWarningCall == null) {
signalSimpleWarningCall = getCallNode(SIGNAL_SIMPLE_WARNING_SOURCE);
}
RCallNode callNode = RCallNode.createCloneReplacingArgs(signalSimpleWarningCall, ConstantNode.create(msg), ConstantNode.create(call));
try {
RContext.getEngine().eval(RDataFactory.createLanguage(callNode), REnvironment.globalEnv(), depth + 1);
} catch (PutException ex) {
throw RInternalError.shouldNotReachHere("signalSimpleWarning");
}
callOut(signalSimpleWarningCall, depth, msg, call);
}
}
......@@ -68,7 +68,7 @@ public interface RASTHelper {
void handleSimpleError(RFunction f, RStringVector msg, Object call, int depth);
/**
* Call out to T to .signalSimpleWarning.
* Call out to R to .signalSimpleWarning.
*/
void signalSimpleWarning(RStringVector msg, Object call, int depth);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment