mirror of
https://github.com/NixOS/nix
synced 2025-06-30 07:33:16 +02:00
Merge remote-tracking branch 'origin/master' into lazy-trees
This commit is contained in:
commit
dfbb9a997f
46 changed files with 1339 additions and 391 deletions
|
@ -14,7 +14,6 @@
|
|||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
|
@ -27,7 +26,6 @@ enum RepairFlag : bool;
|
|||
|
||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||
|
||||
|
||||
struct PrimOp
|
||||
{
|
||||
PrimOpFun fun;
|
||||
|
@ -37,6 +35,11 @@ struct PrimOp
|
|||
const char * doc = nullptr;
|
||||
};
|
||||
|
||||
#if HAVE_BOEHMGC
|
||||
typedef std::map<std::string, Value *, std::less<std::string>, traceable_allocator<std::pair<const std::string, Value *> > > ValMap;
|
||||
#else
|
||||
typedef std::map<std::string, Value *> ValMap;
|
||||
#endif
|
||||
|
||||
struct Env
|
||||
{
|
||||
|
@ -46,6 +49,10 @@ struct Env
|
|||
Value * values[0];
|
||||
};
|
||||
|
||||
void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env);
|
||||
void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl = 0);
|
||||
|
||||
std::unique_ptr<ValMap> mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env);
|
||||
|
||||
void copyContext(const Value & v, PathSet & context);
|
||||
|
||||
|
@ -68,8 +75,17 @@ struct RegexCache;
|
|||
|
||||
std::shared_ptr<RegexCache> makeRegexCache();
|
||||
|
||||
struct DebugTrace {
|
||||
std::optional<ErrPos> pos;
|
||||
const Expr & expr;
|
||||
const Env & env;
|
||||
hintformat hint;
|
||||
bool isError;
|
||||
};
|
||||
|
||||
class EvalState
|
||||
void debugError(Error * e, Env & env, Expr & expr);
|
||||
|
||||
class EvalState : public std::enable_shared_from_this<EvalState>
|
||||
{
|
||||
public:
|
||||
SymbolTable symbols;
|
||||
|
@ -108,6 +124,49 @@ public:
|
|||
RootValue vCallFlake = nullptr;
|
||||
RootValue vImportedDrvToDerivation = nullptr;
|
||||
|
||||
/* Debugger */
|
||||
void (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv);
|
||||
bool debugStop;
|
||||
bool debugQuit;
|
||||
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 Error * error, const Env & env, const Expr & expr);
|
||||
|
||||
template<class E>
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void debugThrow(E && error, const Env & env, const Expr & expr)
|
||||
{
|
||||
if (debugRepl)
|
||||
runDebugRepl(&error, env, expr);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
template<class E>
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void debugThrowLastTrace(E && e)
|
||||
{
|
||||
// Call this in the situation where Expr and Env are inaccessible.
|
||||
// The debugger will start in the last context that's in the
|
||||
// DebugTrace stack.
|
||||
if (debugRepl && !debugTraces.empty()) {
|
||||
const DebugTrace & last = debugTraces.front();
|
||||
runDebugRepl(&e, last.env, last.expr);
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/* Cache for calls to addToStore(); maps source paths to the store
|
||||
|
@ -124,7 +183,7 @@ private:
|
|||
|
||||
/* A cache from path names to values. */
|
||||
#if HAVE_BOEHMGC
|
||||
typedef std::map<SourcePath, Value, std::less<SourcePath>, traceable_allocator<std::pair<const SourcePath, Value> >> FileEvalCache;
|
||||
typedef std::map<SourcePath, Value, std::less<SourcePath>, traceable_allocator<std::pair<const SourcePath, Value>>> FileEvalCache;
|
||||
#else
|
||||
typedef std::map<SourcePath, Value> FileEvalCache;
|
||||
#endif
|
||||
|
@ -184,10 +243,10 @@ public:
|
|||
|
||||
/* Parse a Nix expression from the specified file. */
|
||||
Expr * parseExprFromFile(const SourcePath & path);
|
||||
Expr * parseExprFromFile(const SourcePath & path, StaticEnv & staticEnv);
|
||||
Expr * parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv);
|
||||
|
||||
/* Parse a Nix expression from the specified string. */
|
||||
Expr * parseExprFromString(std::string s, const SourcePath & basePath, StaticEnv & staticEnv);
|
||||
Expr * parseExprFromString(std::string s, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv);
|
||||
Expr * parseExprFromString(std::string s, const SourcePath & basePath);
|
||||
|
||||
Expr * parseStdin();
|
||||
|
@ -248,35 +307,70 @@ public:
|
|||
std::string_view forceStringNoCtx(Value & v, const PosIdx pos = noPos);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s) const;
|
||||
void throwEvalError(const PosIdx pos, const char * s);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v) const;
|
||||
void throwEvalError(const PosIdx pos, const char * s,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
||||
const std::string & s2) const;
|
||||
void throwEvalError(const char * s, const std::string & s2);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, std::string_view s2);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string & s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3) const;
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const;
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const;
|
||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s) const;
|
||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2,
|
||||
Env & env, Expr & expr);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
||||
const ExprLambda & fun, const Symbol s2) const;
|
||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const char * s, const Value & v) const;
|
||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
void throwTypeError(const PosIdx pos, const char * s);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
void throwTypeError(const PosIdx pos, const char * s,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const char * s, const Value & v,
|
||||
Env & env, Expr & expr);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1,
|
||||
Env & env, Expr & expr);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1,
|
||||
Env & env, Expr & expr);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1,
|
||||
Env & env, Expr & expr);
|
||||
|
||||
[[gnu::noinline]]
|
||||
void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
|
||||
|
@ -315,7 +409,7 @@ public:
|
|||
Env & baseEnv;
|
||||
|
||||
/* The same, but used during parsing to resolve variables. */
|
||||
StaticEnv staticBaseEnv; // !!! should be private
|
||||
std::shared_ptr<StaticEnv> staticBaseEnv; // !!! should be private
|
||||
|
||||
private:
|
||||
|
||||
|
@ -361,7 +455,7 @@ private:
|
|||
FileOrigin origin,
|
||||
const PathView path,
|
||||
const SourcePath & basePath,
|
||||
StaticEnv & staticEnv);
|
||||
std::shared_ptr<StaticEnv> & staticEnv);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -456,6 +550,16 @@ private:
|
|||
friend struct Value;
|
||||
};
|
||||
|
||||
struct DebugTraceStacker {
|
||||
DebugTraceStacker(EvalState & evalState, DebugTrace t);
|
||||
~DebugTraceStacker()
|
||||
{
|
||||
// assert(evalState.debugTraces.front() == trace);
|
||||
evalState.debugTraces.pop_front();
|
||||
}
|
||||
EvalState & evalState;
|
||||
DebugTrace trace;
|
||||
};
|
||||
|
||||
/* Return a string representing the type of the value `v'. */
|
||||
std::string_view showType(ValueType type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue