diff options
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r-- | src/libexpr/eval.hh | 109 |
1 files changed, 76 insertions, 33 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 9df6150c6..800b00eef 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -1,10 +1,12 @@ #pragma once #include "attr-set.hh" +#include "types.hh" #include "value.hh" #include "nixexpr.hh" #include "symbol-table.hh" #include "config.hh" +#include "experimental-features.hh" #include <map> #include <optional> @@ -43,8 +45,6 @@ struct Env }; -Value & mkString(Value & v, std::string_view s, const PathSet & context = PathSet()); - void copyContext(const Value & v, PathSet & context); @@ -81,7 +81,8 @@ public: sContentAddressed, sOutputHash, sOutputHashAlgo, sOutputHashMode, sRecurseForDerivations, - sDescription, sSelf, sEpsilon; + sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath, + sPrefix; Symbol sDerivationNix; /* If set, force copying files to the Nix store even if they @@ -92,7 +93,7 @@ public: mode. */ std::optional<PathSet> allowedPaths; - Value vEmptySet; + Bindings emptyBindings; /* Store used to materialise .drv files. */ const ref<Store> store; @@ -132,6 +133,9 @@ private: /* Cache used by prim_match(). */ std::shared_ptr<RegexCache> regexCache; + /* Allocation cache for GC'd Value objects. */ + std::shared_ptr<void *> valueAllocCache; + public: EvalState( @@ -141,15 +145,27 @@ public: ~EvalState(); void requireExperimentalFeatureOnEvaluation( - const std::string & feature, + const ExperimentalFeature &, const std::string_view fName, const Pos & pos ); - void addToSearchPath(const string & s); + void addToSearchPath(const std::string & s); SearchPath getSearchPath() { return searchPath; } + /* Allow access to a path. */ + void allowPath(const Path & path); + + /* Allow access to a store path. Note that this gets remapped to + the real store path if `store` is a chroot store. */ + void allowPath(const StorePath & storePath); + + /* Allow access to a store path and return it as a string. */ + void allowAndSetStorePathString(const StorePath & storePath, Value & v); + + /* Check whether access to a path is allowed and throw an error if + not. Otherwise return the canonicalised path. */ Path checkSourcePath(const Path & path); void checkURI(const std::string & uri); @@ -168,8 +184,8 @@ public: Expr * parseExprFromFile(const Path & path, StaticEnv & staticEnv); /* Parse a Nix expression from the specified string. */ - Expr * parseExprFromString(std::string_view s, const Path & basePath, StaticEnv & staticEnv); - Expr * parseExprFromString(std::string_view s, const Path & basePath); + Expr * parseExprFromString(std::string s, const Path & basePath, StaticEnv & staticEnv); + Expr * parseExprFromString(std::string s, const Path & basePath); Expr * parseStdin(); @@ -189,8 +205,8 @@ public: void resetFileCache(); /* Look up a file in the search path. */ - Path findFile(const string & path); - Path findFile(SearchPath & searchPath, const string & path, const Pos & pos = noPos); + Path findFile(const std::string_view path); + Path findFile(SearchPath & searchPath, const std::string_view path, const Pos & pos = noPos); /* If the specified search path element is a URI, download it. */ std::pair<bool, std::string> resolveSearchPathElem(const SearchPathElem & elem); @@ -209,7 +225,10 @@ public: of the evaluation of the thunk. If `v' is a delayed function application, call the function and overwrite `v' with the result. Otherwise, this is a no-op. */ - inline void forceValue(Value & v, const Pos & pos = noPos); + inline void forceValue(Value & v, const Pos & pos); + + template <typename Callable> + inline void forceValue(Value & v, Callable getPos); /* Force a value, then recursively force list elements and attributes. */ @@ -219,37 +238,43 @@ public: NixInt forceInt(Value & v, const Pos & pos); NixFloat forceFloat(Value & v, const Pos & pos); bool forceBool(Value & v, const Pos & pos); - inline void forceAttrs(Value & v); - inline void forceAttrs(Value & v, const Pos & pos); - inline void forceList(Value & v); + + void forceAttrs(Value & v, const Pos & pos); + + template <typename Callable> + inline void forceAttrs(Value & v, Callable getPos); + inline void forceList(Value & v, const Pos & pos); void forceFunction(Value & v, const Pos & pos); // either lambda or primop - string forceString(Value & v, const Pos & pos = noPos); - string forceString(Value & v, PathSet & context, const Pos & pos = noPos); - string forceStringNoCtx(Value & v, const Pos & pos = noPos); + std::string_view forceString(Value & v, const Pos & pos = noPos); + std::string_view forceString(Value & v, PathSet & context, const Pos & pos = noPos); + std::string_view forceStringNoCtx(Value & v, const Pos & pos = noPos); /* Return true iff the value `v' denotes a derivation (i.e. a set with attribute `type = "derivation"'). */ bool isDerivation(Value & v); - std::optional<string> tryAttrsToString(const Pos & pos, Value & v, + std::optional<std::string> tryAttrsToString(const Pos & pos, Value & v, PathSet & context, bool coerceMore = false, bool copyToStore = true); /* String coercion. Converts strings, paths and derivations to a string. If `coerceMore' is set, also converts nulls, integers, booleans and lists to a string. If `copyToStore' is set, referenced paths are copied to the Nix store as a side effect. */ - string coerceToString(const Pos & pos, Value & v, PathSet & context, + BackedStringView coerceToString(const Pos & pos, Value & v, PathSet & context, bool coerceMore = false, bool copyToStore = true, bool canonicalizePath = true); - string copyPathToStore(PathSet & context, const Path & path); + std::string copyPathToStore(PathSet & context, const Path & path); /* Path coercion. Converts strings, paths and derivations to a path. The result is guaranteed to be a canonicalised, absolute path. Nothing is copied to the store. */ Path coerceToPath(const Pos & pos, Value & v, PathSet & context); + /* Like coerceToPath, but the result must be a store path. */ + StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context); + public: /* The base environment, containing the builtin functions and @@ -265,16 +290,18 @@ private: void createBaseEnv(); - Value * addConstant(const string & name, Value & v); + Value * addConstant(const std::string & name, Value & v); - Value * addPrimOp(const string & name, + void addConstant(const std::string & name, Value * v); + + Value * addPrimOp(const std::string & name, size_t arity, PrimOpFun primOp); Value * addPrimOp(PrimOp && primOp); public: - Value & getBuiltin(const string & name); + Value & getBuiltin(const std::string & name); struct Doc { @@ -295,8 +322,8 @@ private: friend struct ExprAttrs; friend struct ExprLet; - Expr * parse(const char * text, FileOrigin origin, const Path & path, - const Path & basePath, StaticEnv & staticEnv); + Expr * parse(char * text, size_t length, FileOrigin origin, const PathView path, + const PathView basePath, StaticEnv & staticEnv); public: @@ -306,8 +333,14 @@ public: bool isFunctor(Value & fun); - void callFunction(Value & fun, Value & arg, Value & v, const Pos & pos); - void callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos); + // FIXME: use std::span + void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const Pos & pos); + + void callFunction(Value & fun, Value & arg, Value & vRes, const Pos & pos) + { + Value * args[] = {&arg}; + callFunction(fun, 1, args, vRes, pos); + } /* Automatically call a function for which each argument has a default value or has a binding in the `args' map. */ @@ -318,12 +351,16 @@ public: Env & allocEnv(size_t size); Value * allocAttr(Value & vAttrs, const Symbol & name); - Value * allocAttr(Value & vAttrs, const std::string & name); + Value * allocAttr(Value & vAttrs, std::string_view name); Bindings * allocBindings(size_t capacity); + BindingsBuilder buildBindings(size_t capacity) + { + return BindingsBuilder(*this, allocBindings(capacity)); + } + void mkList(Value & v, size_t length); - void mkAttrs(Value & v, size_t capacity); void mkThunk_(Value & v, Expr * expr); void mkPos(Value & v, ptr<Pos> pos); @@ -332,7 +369,10 @@ public: /* Print statistics. */ void printStats(); - void realiseContext(const PathSet & context); + /* Realise the given context, and return a mapping from the placeholders + * used to construct the associated value to their final store path + */ + [[nodiscard]] StringMap realiseContext(const PathSet & context); private: @@ -373,16 +413,19 @@ private: friend struct ExprSelect; friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v); friend void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v); + friend void prim_split(EvalState & state, const Pos & pos, Value * * args, Value & v); + + friend struct Value; }; /* Return a string representing the type of the value `v'. */ -string showType(ValueType type); -string showType(const Value & v); +std::string_view showType(ValueType type); +std::string showType(const Value & v); /* Decode a context string ‘!<name>!<path>’ into a pair <path, name>. */ -std::pair<string, string> decodeContext(std::string_view s); +std::pair<std::string, std::string> decodeContext(std::string_view s); /* If `path' refers to a directory, then append "/default.nix". */ Path resolveExprPath(Path path); |