mirror of
https://github.com/NixOS/nix
synced 2025-06-26 07:31:15 +02:00
WIP: broken merge but need a git checkpoint
This commit is contained in:
commit
eb460a9529
241 changed files with 7587 additions and 2694 deletions
|
@ -13,7 +13,6 @@
|
|||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
||||
|
@ -25,7 +24,6 @@ enum RepairFlag : bool;
|
|||
|
||||
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
|
||||
|
||||
|
||||
struct PrimOp
|
||||
{
|
||||
PrimOpFun fun;
|
||||
|
@ -35,6 +33,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
|
||||
{
|
||||
|
@ -44,6 +47,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);
|
||||
|
||||
|
@ -55,6 +62,7 @@ typedef std::map<Path, StorePath> SrcToStore;
|
|||
|
||||
std::ostream & printValue(const EvalState & state, std::ostream & str, const Value & v);
|
||||
std::string printValue(const EvalState & state, const Value & v);
|
||||
std::ostream & operator << (std::ostream & os, const ValueType t);
|
||||
|
||||
|
||||
typedef std::pair<std::string, std::string> SearchPathElem;
|
||||
|
@ -69,8 +77,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;
|
||||
|
@ -86,7 +103,8 @@ public:
|
|||
sOutputHash, sOutputHashAlgo, sOutputHashMode,
|
||||
sRecurseForDerivations,
|
||||
sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath,
|
||||
sPrefix;
|
||||
sPrefix,
|
||||
sOutputSpecified;
|
||||
Symbol sDerivationNix;
|
||||
|
||||
/* If set, force copying files to the Nix store even if they
|
||||
|
@ -108,12 +126,56 @@ public:
|
|||
RootValue vCallFlake = nullptr;
|
||||
RootValue vImportedDrvToDerivation = nullptr;
|
||||
|
||||
/* Debugger */
|
||||
void (* debugRepl)(ref<EvalState> es, const ValMap & extraEnv);
|
||||
bool debugStop;
|
||||
bool debugQuit;
|
||||
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 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 std::move(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 std::move(e);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
SrcToStore srcToStore;
|
||||
|
||||
/* A cache from path names to parse trees. */
|
||||
#if HAVE_BOEHMGC
|
||||
typedef std::map<Path, Expr *, std::less<Path>, traceable_allocator<std::pair<const Path, Expr *> > > FileParseCache;
|
||||
typedef std::map<Path, Expr *, std::less<Path>, traceable_allocator<std::pair<const Path, Expr *>>> FileParseCache;
|
||||
#else
|
||||
typedef std::map<Path, Expr *> FileParseCache;
|
||||
#endif
|
||||
|
@ -121,7 +183,7 @@ private:
|
|||
|
||||
/* A cache from path names to values. */
|
||||
#if HAVE_BOEHMGC
|
||||
typedef std::map<Path, Value, std::less<Path>, traceable_allocator<std::pair<const Path, Value> > > FileEvalCache;
|
||||
typedef std::map<Path, Value, std::less<Path>, traceable_allocator<std::pair<const Path, Value>>> FileEvalCache;
|
||||
#else
|
||||
typedef std::map<Path, Value> FileEvalCache;
|
||||
#endif
|
||||
|
@ -184,10 +246,10 @@ public:
|
|||
|
||||
/* Parse a Nix expression from the specified file. */
|
||||
Expr * parseExprFromFile(const Path & path);
|
||||
Expr * parseExprFromFile(const Path & path, StaticEnv & staticEnv);
|
||||
Expr * parseExprFromFile(const Path & path, std::shared_ptr<StaticEnv> & staticEnv);
|
||||
|
||||
/* Parse a Nix expression from the specified string. */
|
||||
Expr * parseExprFromString(std::string s, const Path & basePath, StaticEnv & staticEnv);
|
||||
Expr * parseExprFromString(std::string s, const Path & basePath, std::shared_ptr<StaticEnv> & staticEnv);
|
||||
Expr * parseExprFromString(std::string s, const Path & basePath);
|
||||
|
||||
Expr * parseStdin();
|
||||
|
@ -197,7 +259,7 @@ public:
|
|||
trivial (i.e. doesn't require arbitrary computation). */
|
||||
void evalFile(const Path & path, Value & v, bool mustBeTrivial = false);
|
||||
|
||||
/* Like `cacheFile`, but with an already parsed expression. */
|
||||
/* Like `evalFile`, but with an already parsed expression. */
|
||||
void cacheFile(
|
||||
const Path & path,
|
||||
const Path & resolvedPath,
|
||||
|
@ -253,32 +315,123 @@ public:
|
|||
std::string_view forceString(Value & v, PathSet & context, const PosIdx pos, std::string_view errorCtx);
|
||||
std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx);
|
||||
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2, const std::string_view s3) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const nix::Suggestions&, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const Pos &, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, std::string_view, nix::PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
[[gnu::noinline, gnu::noreturn]] void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
// coerce-strings
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string_view s2, const std::string_view s3) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const char * s, const Value & v) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeErrorWithTrace(const PosIdx, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeErrorWithTrace(const PosIdx, const nix::Suggestions&, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeErrorWithTrace(const char*, std::string_view, const Pos &, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalErrorWithTrace(const char*, std::string_view, std::string_view, nix::PosIdx, std::string_view) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const;
|
||||
|
||||
[[gnu::noinline]] void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
|
||||
[[gnu::noinline]] void addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2) const;
|
||||
// origin/master
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string & s2);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & 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, 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);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
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 char * s, const Value & v);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
void throwTypeError(const PosIdx pos, const char * s,
|
||||
Env & env, Expr & expr);
|
||||
[[gnu::noinline, gnu::noreturn]]
|
||||
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;
|
||||
[[gnu::noinline]]
|
||||
void addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2) const;
|
||||
|
||||
public:
|
||||
/* Return true iff the value `v' denotes a derivation (i.e. a
|
||||
|
@ -314,7 +467,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:
|
||||
|
||||
|
@ -355,7 +508,7 @@ private:
|
|||
friend struct ExprLet;
|
||||
|
||||
Expr * parse(char * text, size_t length, FileOrigin origin, const PathView path,
|
||||
const PathView basePath, StaticEnv & staticEnv);
|
||||
const PathView basePath, std::shared_ptr<StaticEnv> & staticEnv);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -450,6 +603,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);
|
||||
|
@ -534,6 +697,15 @@ struct EvalSettings : Config
|
|||
|
||||
Setting<bool> useEvalCache{this, true, "eval-cache",
|
||||
"Whether to use the flake evaluation cache."};
|
||||
|
||||
Setting<bool> ignoreExceptionsDuringTry{this, false, "ignore-try",
|
||||
R"(
|
||||
If set to true, ignore exceptions inside 'tryEval' calls when evaluating nix expressions in
|
||||
debug mode (using the --debugger flag). By default the debugger will pause on all exceptions.
|
||||
)"};
|
||||
|
||||
Setting<bool> traceVerbose{this, false, "trace-verbose",
|
||||
"Whether `builtins.traceVerbose` should trace its first argument when evaluated."};
|
||||
};
|
||||
|
||||
extern EvalSettings evalSettings;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue