aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/eval.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/eval.hh')
-rw-r--r--src/libexpr/eval.hh107
1 files changed, 75 insertions, 32 deletions
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index b29feb134..1f0e97b2e 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(
@@ -140,10 +144,25 @@ public:
std::shared_ptr<Store> buildStore = nullptr);
~EvalState();
- void addToSearchPath(const string & s);
+ void requireExperimentalFeatureOnEvaluation(
+ const ExperimentalFeature &,
+ const std::string_view fName,
+ const Pos & pos
+ );
+
+ 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);
+
+ /* 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);
@@ -162,8 +181,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();
@@ -183,8 +202,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);
@@ -203,7 +222,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. */
@@ -213,31 +235,34 @@ 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
@@ -259,16 +284,18 @@ private:
void createBaseEnv();
- Value * addConstant(const string & name, Value & v);
+ Value * addConstant(const std::string & name, Value & v);
+
+ void addConstant(const std::string & name, Value * v);
- Value * addPrimOp(const string & name,
+ 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
{
@@ -289,8 +316,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:
@@ -300,8 +327,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. */
@@ -312,12 +345,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);
@@ -326,7 +363,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:
@@ -367,16 +407,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);