libexpr: move debug repl state into own struct
just to keep debug-related state closer together. eventually this will
also allow us to not allocate debugger state altogether unless needed.
Change-Id: Id83fea75d96d0ecbe21683cb1b57dd5b11b13535
This commit is contained in:
parent
e635db77e3
commit
003883306d
|
@ -118,7 +118,7 @@ ref<EvalState> EvalCommand::getEvalState()
|
|||
evalState->repair = repair;
|
||||
|
||||
if (startReplOnEvalErrors) {
|
||||
evalState->debugRepl = &AbstractNixRepl::runSimple;
|
||||
evalState->debug.repl = &AbstractNixRepl::runSimple;
|
||||
};
|
||||
}
|
||||
return ref<EvalState>(evalState);
|
||||
|
|
|
@ -285,7 +285,7 @@ ReplExitStatus NixRepl::mainLoop()
|
|||
{
|
||||
if (isFirstRepl) {
|
||||
std::string_view debuggerNotice = "";
|
||||
if (state.debugRepl) {
|
||||
if (state.debug.repl) {
|
||||
debuggerNotice = " debugger";
|
||||
}
|
||||
notice("Lix %1%%2%\nType :? for help.", nixVersion, debuggerNotice);
|
||||
|
@ -310,7 +310,7 @@ ReplExitStatus NixRepl::mainLoop()
|
|||
// number of chars as the prompt.
|
||||
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
|
||||
// Ctrl-D should exit the debugger.
|
||||
state.debugStop = false;
|
||||
state.debug.stop = false;
|
||||
logger->cout("");
|
||||
// TODO: Should Ctrl-D exit just the current debugger session or
|
||||
// the entire program?
|
||||
|
@ -366,7 +366,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
|
|||
}
|
||||
}
|
||||
|
||||
if (state.debugRepl) {
|
||||
if (state.debug.repl) {
|
||||
for (auto const & colonCmd : this->DEBUG_COMMANDS) {
|
||||
if (colonCmd.starts_with(prefix)) {
|
||||
completions.insert(std::string(colonCmd));
|
||||
|
@ -416,9 +416,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
|
|||
}
|
||||
} else {
|
||||
/* Temporarily disable the debugger, to avoid re-entering readline. */
|
||||
auto debug_repl = state.debugRepl;
|
||||
state.debugRepl = nullptr;
|
||||
Finally restoreDebug([&]() { state.debugRepl = debug_repl; });
|
||||
auto debug_repl = state.debug.repl;
|
||||
state.debug.repl = nullptr;
|
||||
Finally restoreDebug([&]() { state.debug.repl = debug_repl; });
|
||||
try {
|
||||
/* This is an expression that should evaluate to an
|
||||
attribute set. Evaluate it to get the names of the
|
||||
|
@ -485,7 +485,7 @@ void NixRepl::loadDebugTraceEnv(DebugTrace & dt)
|
|||
{
|
||||
initEnv();
|
||||
|
||||
auto se = state.getStaticEnv(dt.expr);
|
||||
auto se = state.debug.staticEnvFor(dt.expr);
|
||||
if (se) {
|
||||
auto vm = mapStaticEnvBindings(state.symbols, *se.get(), dt.env);
|
||||
|
||||
|
@ -541,7 +541,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
<< " errors\n"
|
||||
<< " :?, :help Brings up this help menu\n"
|
||||
;
|
||||
if (state.debugRepl) {
|
||||
if (state.debug.repl) {
|
||||
std::cout
|
||||
<< "\n"
|
||||
<< " Debug mode commands\n"
|
||||
|
@ -556,15 +556,15 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
|
||||
}
|
||||
|
||||
else if (state.debugRepl && (command == ":bt" || command == ":backtrace")) {
|
||||
for (const auto & [idx, i] : enumerate(state.debugTraces)) {
|
||||
else if (state.debug.repl && (command == ":bt" || command == ":backtrace")) {
|
||||
for (const auto & [idx, i] : enumerate(state.debug.traces)) {
|
||||
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
||||
showDebugTrace(std::cout, state.positions, i);
|
||||
}
|
||||
}
|
||||
|
||||
else if (state.debugRepl && (command == ":env")) {
|
||||
for (const auto & [idx, i] : enumerate(state.debugTraces)) {
|
||||
else if (state.debug.repl && (command == ":env")) {
|
||||
for (const auto & [idx, i] : enumerate(state.debug.traces)) {
|
||||
if (idx == debugTraceIndex) {
|
||||
printEnvBindings(state, i.expr, i.env);
|
||||
break;
|
||||
|
@ -572,13 +572,13 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
}
|
||||
}
|
||||
|
||||
else if (state.debugRepl && (command == ":st")) {
|
||||
else if (state.debug.repl && (command == ":st")) {
|
||||
try {
|
||||
// change the DebugTrace index.
|
||||
debugTraceIndex = stoi(arg);
|
||||
} catch (...) { }
|
||||
|
||||
for (const auto & [idx, i] : enumerate(state.debugTraces)) {
|
||||
for (const auto & [idx, i] : enumerate(state.debug.traces)) {
|
||||
if (idx == debugTraceIndex) {
|
||||
std::cout << "\n" << ANSI_BLUE << idx << ANSI_NORMAL << ": ";
|
||||
showDebugTrace(std::cout, state.positions, i);
|
||||
|
@ -590,15 +590,15 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
}
|
||||
}
|
||||
|
||||
else if (state.debugRepl && (command == ":s" || command == ":step")) {
|
||||
else if (state.debug.repl && (command == ":s" || command == ":step")) {
|
||||
// set flag to stop at next DebugTrace; exit repl.
|
||||
state.debugStop = true;
|
||||
state.debug.stop = true;
|
||||
return ProcessLineResult::Continue;
|
||||
}
|
||||
|
||||
else if (state.debugRepl && (command == ":c" || command == ":continue")) {
|
||||
else if (state.debug.repl && (command == ":c" || command == ":continue")) {
|
||||
// set flag to run to next breakpoint or end of program; exit repl.
|
||||
state.debugStop = false;
|
||||
state.debug.stop = false;
|
||||
return ProcessLineResult::Continue;
|
||||
}
|
||||
|
||||
|
@ -771,7 +771,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
|||
}
|
||||
|
||||
else if (command == ":q" || command == ":quit") {
|
||||
state.debugStop = false;
|
||||
state.debug.stop = false;
|
||||
return ProcessLineResult::Quit;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ EvalErrorBuilder<T> & EvalErrorBuilder<T>::withFrame(const Env & env, const Expr
|
|||
// NOTE: This is abusing side-effects.
|
||||
// TODO: check compatibility with nested debugger calls.
|
||||
// TODO: What side-effects??
|
||||
error.state.debugTraces.push_front(DebugTrace{
|
||||
error.state.debug.traces.push_front(DebugTrace{
|
||||
.pos = error.state.positions[expr.getPos()],
|
||||
.expr = expr,
|
||||
.env = env,
|
||||
|
@ -74,11 +74,11 @@ EvalErrorBuilder<T>::addTrace(PosIdx pos, std::string_view formatString, const A
|
|||
template<class T>
|
||||
void EvalErrorBuilder<T>::debugThrow()
|
||||
{
|
||||
if (error.state.debugRepl && !error.state.debugTraces.empty()) {
|
||||
const DebugTrace & last = error.state.debugTraces.front();
|
||||
if (error.state.debug.repl && !error.state.debug.traces.empty()) {
|
||||
const DebugTrace & last = error.state.debug.traces.front();
|
||||
const Env * env = &last.env;
|
||||
const Expr * expr = &last.expr;
|
||||
error.state.runDebugRepl(&error, *env, *expr);
|
||||
error.state.debug.runDebugRepl(error.state, &error, *env, *expr);
|
||||
}
|
||||
|
||||
// `EvalState` is the only class that can construct an `EvalErrorBuilder`,
|
||||
|
|
|
@ -262,9 +262,6 @@ EvalState::EvalState(
|
|||
, derivationInternal(rootPath(CanonPath("/builtin/derivation.nix")))
|
||||
, store(store)
|
||||
, buildStore(buildStore ? buildStore : store)
|
||||
, debugRepl(nullptr)
|
||||
, debugStop(false)
|
||||
, trylevel(0)
|
||||
, regexCache(makeRegexCache())
|
||||
#if HAVE_BOEHMGC
|
||||
, valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
|
||||
|
@ -590,7 +587,7 @@ void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env &
|
|||
void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env)
|
||||
{
|
||||
// just print the names for now
|
||||
auto se = es.getStaticEnv(expr);
|
||||
auto se = es.debug.staticEnvFor(expr);
|
||||
if (se)
|
||||
printEnvBindings(es.symbols, *se, env, 0);
|
||||
}
|
||||
|
@ -639,18 +636,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void EvalState::runDebugRepl(const EvalError * error, const Env & env, const Expr & expr)
|
||||
void DebugState::runDebugRepl(
|
||||
EvalState & evalState, const EvalError * error, const Env & env, const Expr & expr
|
||||
)
|
||||
{
|
||||
// Make sure we have a debugger to run and we're not already in a debugger.
|
||||
if (!debugRepl || inDebugger)
|
||||
if (!repl || inDebugger)
|
||||
return;
|
||||
|
||||
auto dts =
|
||||
error && expr.getPos()
|
||||
? std::make_unique<DebugTraceStacker>(
|
||||
*this,
|
||||
evalState,
|
||||
DebugTrace {
|
||||
.pos = error->info().pos ? error->info().pos : positions[expr.getPos()],
|
||||
.pos = error->info().pos ? error->info().pos : evalState.positions[expr.getPos()],
|
||||
.expr = expr,
|
||||
.env = env,
|
||||
.hint = error->info().msg,
|
||||
|
@ -666,11 +665,11 @@ void EvalState::runDebugRepl(const EvalError * error, const Env & env, const Exp
|
|||
printError("This exception occurred in a 'tryEval' call. Use " ANSI_GREEN "--ignore-try" ANSI_NORMAL " to skip these.\n");
|
||||
}
|
||||
|
||||
auto se = getStaticEnv(expr);
|
||||
auto se = staticEnvFor(expr);
|
||||
if (se) {
|
||||
auto vm = mapStaticEnvBindings(symbols, *se.get(), env);
|
||||
auto vm = mapStaticEnvBindings(evalState.symbols, *se.get(), env);
|
||||
DebuggerGuard _guard(inDebugger);
|
||||
auto exitStatus = (debugRepl)(*this, *vm);
|
||||
auto exitStatus = repl(evalState, *vm);
|
||||
switch (exitStatus) {
|
||||
case ReplExitStatus::QuitAll:
|
||||
if (error)
|
||||
|
@ -718,9 +717,9 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t)
|
|||
: evalState(evalState)
|
||||
, trace(std::move(t))
|
||||
{
|
||||
evalState.debugTraces.push_front(trace);
|
||||
if (evalState.debugStop && evalState.debugRepl)
|
||||
evalState.runDebugRepl(nullptr, trace.env, trace.expr);
|
||||
evalState.debug.traces.push_front(trace);
|
||||
if (evalState.debug.stop && evalState.debug.repl)
|
||||
evalState.debug.runDebugRepl(evalState, nullptr, trace.env, trace.expr);
|
||||
}
|
||||
|
||||
inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||
|
@ -955,7 +954,7 @@ void EvalState::cacheFile(
|
|||
fileParseCache[resolvedPath] = e;
|
||||
|
||||
try {
|
||||
auto dts = debugRepl
|
||||
auto dts = debug.repl
|
||||
? makeDebugTraceStacker(
|
||||
*this,
|
||||
*e,
|
||||
|
@ -1173,7 +1172,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
|||
*i.second.chooseByKind(&env2, &env, inheritEnv));
|
||||
}
|
||||
|
||||
auto dts = state.debugRepl
|
||||
auto dts = state.debug.repl
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -1258,7 +1257,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
|||
}
|
||||
|
||||
try {
|
||||
auto dts = state.debugRepl
|
||||
auto dts = state.debug.repl
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -1576,7 +1575,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
|
||||
/* Evaluate the body. */
|
||||
try {
|
||||
auto dts = debugRepl
|
||||
auto dts = debug.repl
|
||||
? makeDebugTraceStacker(
|
||||
*this, *lambda.body, env2, positions[lambda.pos],
|
||||
"while calling %s",
|
||||
|
@ -1715,7 +1714,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
|
||||
void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||
{
|
||||
auto dts = state.debugRepl
|
||||
auto dts = state.debug.repl
|
||||
? makeDebugTraceStacker(
|
||||
state,
|
||||
*this,
|
||||
|
@ -2088,7 +2087,7 @@ void EvalState::forceValueDeep(Value & v)
|
|||
for (auto & i : *v.attrs)
|
||||
try {
|
||||
// If the value is a thunk, we're evaling. Otherwise no trace necessary.
|
||||
auto dts = debugRepl && i.value->isThunk()
|
||||
auto dts = debug.repl && i.value->isThunk()
|
||||
? makeDebugTraceStacker(*this, *i.value->thunk.expr, *i.value->thunk.env, positions[i.pos],
|
||||
"while evaluating the attribute '%1%'", symbols[i.name])
|
||||
: nullptr;
|
||||
|
|
|
@ -152,6 +152,28 @@ struct DebugTrace {
|
|||
bool isError;
|
||||
};
|
||||
|
||||
struct DebugState
|
||||
{
|
||||
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> repl;
|
||||
bool stop = false;
|
||||
bool inDebugger = false;
|
||||
std::list<DebugTrace> traces;
|
||||
std::map<const Expr *, const std::shared_ptr<const StaticEnv>> exprEnvs;
|
||||
int trylevel = 0;
|
||||
|
||||
void runDebugRepl(
|
||||
EvalState & evalState, const EvalError * error, const Env & env, const Expr & expr
|
||||
);
|
||||
|
||||
const std::shared_ptr<const StaticEnv> staticEnvFor(const Expr & expr) const
|
||||
{
|
||||
if (auto i = exprEnvs.find(&expr); i != exprEnvs.end()) {
|
||||
return i->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct StaticSymbols
|
||||
{
|
||||
|
@ -202,25 +224,7 @@ public:
|
|||
RootValue vCallFlake = nullptr;
|
||||
RootValue vImportedDrvToDerivation = nullptr;
|
||||
|
||||
/**
|
||||
* Debugger
|
||||
*/
|
||||
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> debugRepl;
|
||||
bool debugStop;
|
||||
bool inDebugger = false;
|
||||
int trylevel;
|
||||
std::list<DebugTrace> debugTraces;
|
||||
std::map<const Expr*, const std::shared_ptr<const StaticEnv>> exprEnvs;
|
||||
const std::shared_ptr<const StaticEnv> getStaticEnv(const Expr & expr) const
|
||||
{
|
||||
auto i = exprEnvs.find(&expr);
|
||||
if (i != exprEnvs.end())
|
||||
return i->second;
|
||||
else
|
||||
return std::shared_ptr<const StaticEnv>();;
|
||||
}
|
||||
|
||||
void runDebugRepl(const EvalError * error, const Env & env, const Expr & expr);
|
||||
DebugState debug;
|
||||
|
||||
template<class T, typename... Args>
|
||||
[[nodiscard, gnu::noinline]]
|
||||
|
@ -760,7 +764,7 @@ struct DebugTraceStacker {
|
|||
DebugTraceStacker(EvalState & evalState, DebugTrace t);
|
||||
~DebugTraceStacker()
|
||||
{
|
||||
evalState.debugTraces.pop_front();
|
||||
evalState.debug.traces.pop_front();
|
||||
}
|
||||
EvalState & evalState;
|
||||
DebugTrace trace;
|
||||
|
|
|
@ -302,32 +302,32 @@ void Expr::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env
|
|||
|
||||
void ExprInt::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
void ExprFloat::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
void ExprString::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
void ExprPath::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
void ExprVar::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
fromWith = nullptr;
|
||||
|
||||
|
@ -364,14 +364,14 @@ void ExprVar::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
|||
|
||||
void ExprInheritFrom::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
void ExprSelect::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
e->bindVars(es, env);
|
||||
if (def) def->bindVars(es, env);
|
||||
|
@ -382,8 +382,8 @@ void ExprSelect::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
|||
|
||||
void ExprOpHasAttr::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
e->bindVars(es, env);
|
||||
for (auto & i : attrPath)
|
||||
|
@ -414,8 +414,8 @@ std::shared_ptr<const StaticEnv> ExprAttrs::bindInheritSources(
|
|||
|
||||
void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
if (recursive) {
|
||||
auto newEnv = [&] () -> std::shared_ptr<const StaticEnv> {
|
||||
|
@ -453,8 +453,8 @@ void ExprAttrs::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
|||
|
||||
void ExprList::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
for (auto & i : elems)
|
||||
i->bindVars(es, env);
|
||||
|
@ -462,8 +462,8 @@ void ExprList::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
|||
|
||||
void ExprLambda::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
auto newEnv = std::make_shared<StaticEnv>(
|
||||
nullptr, env.get(),
|
||||
|
@ -489,8 +489,8 @@ void ExprLambda::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
|||
|
||||
void ExprCall::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
fun->bindVars(es, env);
|
||||
for (auto & e : args)
|
||||
|
@ -514,16 +514,16 @@ void ExprLet::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
|||
for (auto & i : attrs->attrs)
|
||||
i.second.e->bindVars(es, i.second.chooseByKind(newEnv, env, inheritFromEnv));
|
||||
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
body->bindVars(es, newEnv);
|
||||
}
|
||||
|
||||
void ExprWith::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
parentWith = nullptr;
|
||||
for (auto * e = env.get(); e && !parentWith; e = e->up)
|
||||
|
@ -548,8 +548,8 @@ void ExprWith::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> &
|
|||
|
||||
void ExprIf::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
cond->bindVars(es, env);
|
||||
then->bindVars(es, env);
|
||||
|
@ -558,8 +558,8 @@ void ExprIf::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & e
|
|||
|
||||
void ExprAssert::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
cond->bindVars(es, env);
|
||||
body->bindVars(es, env);
|
||||
|
@ -567,16 +567,16 @@ void ExprAssert::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
|
|||
|
||||
void ExprOpNot::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
e->bindVars(es, env);
|
||||
}
|
||||
|
||||
void ExprConcatStrings::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
|
||||
for (auto & i : this->es)
|
||||
i.second->bindVars(es, env);
|
||||
|
@ -584,8 +584,8 @@ void ExprConcatStrings::bindVars(EvalState & es, const std::shared_ptr<const Sta
|
|||
|
||||
void ExprPos::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env)
|
||||
{
|
||||
if (es.debugRepl)
|
||||
es.exprEnvs.insert(std::make_pair(this, env));
|
||||
if (es.debug.repl)
|
||||
es.debug.exprEnvs.insert(std::make_pair(this, env));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -566,15 +566,15 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
|
|||
|
||||
static void prim_break(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||
{
|
||||
if (state.debugRepl && !state.debugTraces.empty()) {
|
||||
if (state.debug.repl && !state.debug.traces.empty()) {
|
||||
auto error = EvalError(state, ErrorInfo {
|
||||
.level = lvlInfo,
|
||||
.msg = HintFmt("breakpoint reached"),
|
||||
.pos = state.positions[pos],
|
||||
});
|
||||
|
||||
auto & dt = state.debugTraces.front();
|
||||
state.runDebugRepl(&error, dt.env, dt.expr);
|
||||
auto & dt = state.debug.traces.front();
|
||||
state.debug.runDebugRepl(state, &error, dt.env, dt.expr);
|
||||
}
|
||||
|
||||
// Return the value we were passed.
|
||||
|
@ -638,14 +638,14 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
|||
auto attrs = state.buildBindings(2);
|
||||
|
||||
/* increment state.trylevel, and decrement it when this function returns. */
|
||||
MaintainCount trylevel(state.trylevel);
|
||||
MaintainCount trylevel(state.debug.trylevel);
|
||||
|
||||
std::function<ReplExitStatus(EvalState & es, ValMap const & extraEnv)> savedDebugRepl;
|
||||
if (state.debugRepl && evalSettings.ignoreExceptionsDuringTry)
|
||||
if (state.debug.repl && evalSettings.ignoreExceptionsDuringTry)
|
||||
{
|
||||
/* to prevent starting the repl from exceptions withing a tryEval, null it. */
|
||||
savedDebugRepl = state.debugRepl;
|
||||
state.debugRepl = nullptr;
|
||||
savedDebugRepl = state.debug.repl;
|
||||
state.debug.repl = nullptr;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -659,7 +659,7 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
|
|||
|
||||
// restore the debugRepl pointer if we saved it earlier.
|
||||
if (savedDebugRepl)
|
||||
state.debugRepl = savedDebugRepl;
|
||||
state.debug.repl = savedDebugRepl;
|
||||
|
||||
v.mkAttrs(attrs);
|
||||
}
|
||||
|
@ -697,9 +697,9 @@ static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Valu
|
|||
printError("trace: %1%", args[0]->string.s);
|
||||
else
|
||||
printError("trace: %1%", ValuePrinter(state, *args[0]));
|
||||
if (evalSettings.builtinsTraceDebugger && state.debugRepl && !state.debugTraces.empty()) {
|
||||
const DebugTrace & last = state.debugTraces.front();
|
||||
state.runDebugRepl(nullptr, last.env, last.expr);
|
||||
if (evalSettings.builtinsTraceDebugger && state.debug.repl && !state.debug.traces.empty()) {
|
||||
const DebugTrace & last = state.debug.traces.front();
|
||||
state.debug.runDebugRepl(state, nullptr, last.env, last.expr);
|
||||
}
|
||||
state.forceValue(*args[1], pos);
|
||||
v = *args[1];
|
||||
|
|
Loading…
Reference in a new issue