aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc124
-rw-r--r--src/libexpr/eval.hh8
-rw-r--r--src/libexpr/json-to-value.hh2
-rw-r--r--src/libexpr/nixexpr.hh16
-rw-r--r--src/libexpr/parser.y8
-rw-r--r--src/libexpr/primops.cc10
-rw-r--r--src/libexpr/primops/fetchGit.cc14
-rw-r--r--src/libexpr/value.hh10
8 files changed, 56 insertions, 136 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 0b3f75d60..ff7bce45e 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -244,7 +244,7 @@ void initGC()
that GC_expand_hp() causes a lot of virtual, but not physical
(resident) memory to be allocated. This might be a problem on
systems that don't overcommit. */
- if (!getenv("GC_INITIAL_HEAP_SIZE")) {
+ if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
size_t size = 32 * 1024 * 1024;
#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
size_t maxSize = 384 * 1024 * 1024;
@@ -335,7 +335,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
, baseEnv(allocEnv(128))
, staticBaseEnv(false, 0)
{
- countCalls = getEnv("NIX_COUNT_CALLS", "0") != "0";
+ countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
assert(gcInitialised);
@@ -343,9 +343,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
/* Initialise the Nix expression search path. */
if (!evalSettings.pureEval) {
- Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
for (auto & i : _searchPath) addToSearchPath(i);
- for (auto & i : paths) addToSearchPath(i);
+ for (auto & i : evalSettings.nixPath.get()) addToSearchPath(i);
}
addToSearchPath("nix=" + canonPath(settings.nixDataDir + "/nix/corepkgs", true));
@@ -461,7 +460,7 @@ Path EvalState::toRealPath(const Path & path, const PathSet & context)
!context.empty() && store->isInStore(path)
? store->toRealPath(path)
: path;
-};
+}
Value * EvalState::addConstant(const string & name, Value & v)
@@ -651,13 +650,9 @@ Value * EvalState::allocValue()
Env & EvalState::allocEnv(size_t size)
{
- if (size > std::numeric_limits<decltype(Env::size)>::max())
- throw Error("environment size %d is too big", size);
-
nrEnvs++;
nrValuesInEnvs += size;
Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *));
- env->size = (decltype(Env::size)) size;
env->type = Env::Plain;
/* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */
@@ -917,7 +912,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
if (hasOverrides) {
Value * vOverrides = (*v.attrs)[overrides->second.displ].value;
state.forceAttrs(*vOverrides);
- Bindings * newBnds = state.allocBindings(v.attrs->size() + vOverrides->attrs->size());
+ Bindings * newBnds = state.allocBindings(v.attrs->capacity() + vOverrides->attrs->size());
for (auto & i : *v.attrs)
newBnds->push_back(i);
for (auto & i : *vOverrides->attrs) {
@@ -1794,7 +1789,7 @@ bool EvalState::eqValues(Value & v1, Value & v2)
void EvalState::printStats()
{
- bool showStats = getEnv("NIX_SHOW_STATS", "0") != "0";
+ bool showStats = getEnv("NIX_SHOW_STATS").value_or("0") != "0";
struct rusage buf;
getrusage(RUSAGE_SELF, &buf);
@@ -1810,7 +1805,7 @@ void EvalState::printStats()
GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes);
#endif
if (showStats) {
- auto outPath = getEnv("NIX_SHOW_STATS_PATH","-");
+ auto outPath = getEnv("NIX_SHOW_STATS_PATH").value_or("-");
std::fstream fs;
if (outPath != "-")
fs.open(outPath, std::fstream::out);
@@ -1902,7 +1897,7 @@ void EvalState::printStats()
}
}
- if (getEnv("NIX_SHOW_SYMBOLS", "0") != "0") {
+ if (getEnv("NIX_SHOW_SYMBOLS").value_or("0") != "0") {
auto list = topObj.list("symbols");
symbols.dump([&](const std::string & s) { list.elem(s); });
}
@@ -1910,93 +1905,6 @@ void EvalState::printStats()
}
-size_t valueSize(Value & v)
-{
- std::set<const void *> seen;
-
- auto doString = [&](const char * s) -> size_t {
- if (!seen.insert(s).second) return 0;
- return strlen(s) + 1;
- };
-
- std::function<size_t(Value & v)> doValue;
- std::function<size_t(Env & v)> doEnv;
-
- doValue = [&](Value & v) -> size_t {
- if (!seen.insert(&v).second) return 0;
-
- size_t sz = sizeof(Value);
-
- switch (v.type) {
- case tString:
- sz += doString(v.string.s);
- if (v.string.context)
- for (const char * * p = v.string.context; *p; ++p)
- sz += doString(*p);
- break;
- case tPath:
- sz += doString(v.path);
- break;
- case tAttrs:
- if (seen.insert(v.attrs).second) {
- sz += sizeof(Bindings) + sizeof(Attr) * v.attrs->capacity();
- for (auto & i : *v.attrs)
- sz += doValue(*i.value);
- }
- break;
- case tList1:
- case tList2:
- case tListN:
- if (seen.insert(v.listElems()).second) {
- sz += v.listSize() * sizeof(Value *);
- for (size_t n = 0; n < v.listSize(); ++n)
- sz += doValue(*v.listElems()[n]);
- }
- break;
- case tThunk:
- sz += doEnv(*v.thunk.env);
- break;
- case tApp:
- sz += doValue(*v.app.left);
- sz += doValue(*v.app.right);
- break;
- case tLambda:
- sz += doEnv(*v.lambda.env);
- break;
- case tPrimOpApp:
- sz += doValue(*v.primOpApp.left);
- sz += doValue(*v.primOpApp.right);
- break;
- case tExternal:
- if (!seen.insert(v.external).second) break;
- sz += v.external->valueSize(seen);
- break;
- default:
- ;
- }
-
- return sz;
- };
-
- doEnv = [&](Env & env) -> size_t {
- if (!seen.insert(&env).second) return 0;
-
- size_t sz = sizeof(Env) + sizeof(Value *) * env.size;
-
- if (env.type != Env::HasWithExpr)
- for (size_t i = 0; i < env.size; ++i)
- if (env.values[i])
- sz += doValue(*env.values[i]);
-
- if (env.up) sz += doEnv(*env.up);
-
- return sz;
- };
-
- return doValue(v);
-}
-
-
string ExternalValueBase::coerceToString(const Pos & pos, PathSet & context, bool copyMore, bool copyToStore) const
{
throw TypeError(format("cannot coerce %1% to a string, at %2%") %
@@ -2015,6 +1923,22 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
}
+EvalSettings::EvalSettings()
+{
+ auto var = getEnv("NIX_PATH");
+ if (var) nixPath = parseNixPath(*var);
+}
+
+Strings EvalSettings::getDefaultNixPath()
+{
+ Strings res;
+ auto add = [&](const Path & p) { if (pathExists(p)) { res.push_back(p); } };
+ add(getHome() + "/.nix-defexpr/channels");
+ add("nixpkgs=" + settings.nixStateDir + "/nix/profiles/per-user/root/channels/nixpkgs");
+ add(settings.nixStateDir + "/nix/profiles/per-user/root/channels");
+ return res;
+}
+
EvalSettings evalSettings;
static GlobalConfig::Register r1(&evalSettings);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 0ce1cda3c..baca7f03f 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -40,7 +40,6 @@ struct PrimOp
struct Env
{
Env * up;
- unsigned short size; // used by ‘valueSize’
unsigned short prevWith:14; // nr of levels up to next `with' environment
enum { Plain = 0, HasWithExpr, HasWithAttrs } type:2;
Value * values[0];
@@ -363,9 +362,16 @@ struct InvalidPathError : EvalError
struct EvalSettings : Config
{
+ EvalSettings();
+
+ static Strings getDefaultNixPath();
+
Setting<bool> enableNativeCode{this, false, "allow-unsafe-native-code-during-evaluation",
"Whether builtin functions that allow executing native code should be enabled."};
+ Setting<Strings> nixPath{this, getDefaultNixPath(), "nix-path",
+ "List of directories to be searched for <...> file references."};
+
Setting<bool> restrictEval{this, false, "restrict-eval",
"Whether to restrict file system access to paths in $NIX_PATH, "
"and network access to the URI prefixes listed in 'allowed-uris'."};
diff --git a/src/libexpr/json-to-value.hh b/src/libexpr/json-to-value.hh
index 33f35b16c..3b0fdae11 100644
--- a/src/libexpr/json-to-value.hh
+++ b/src/libexpr/json-to-value.hh
@@ -6,7 +6,7 @@
namespace nix {
-MakeError(JSONParseError, EvalError)
+MakeError(JSONParseError, EvalError);
void parseJSON(EvalState & state, const string & s, Value & v);
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 665a42987..f7e9105a4 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -9,14 +9,14 @@
namespace nix {
-MakeError(EvalError, Error)
-MakeError(ParseError, Error)
-MakeError(AssertionError, EvalError)
-MakeError(ThrownError, AssertionError)
-MakeError(Abort, EvalError)
-MakeError(TypeError, EvalError)
-MakeError(UndefinedVarError, Error)
-MakeError(RestrictedPathError, Error)
+MakeError(EvalError, Error);
+MakeError(ParseError, Error);
+MakeError(AssertionError, EvalError);
+MakeError(ThrownError, AssertionError);
+MakeError(Abort, EvalError);
+MakeError(TypeError, EvalError);
+MakeError(UndefinedVarError, Error);
+MakeError(RestrictedPathError, Error);
/* Position objects. */
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 93834bec6..10a057062 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -20,6 +20,7 @@
#include "nixexpr.hh"
#include "eval.hh"
+#include "globals.hh"
namespace nix {
@@ -401,7 +402,12 @@ expr_simple
new ExprVar(data->symbols.create("__nixPath"))),
new ExprString(data->symbols.create(path)));
}
- | URI { $$ = new ExprString(data->symbols.create($1)); }
+ | URI {
+ static bool noURLLiterals = settings.isExperimentalFeatureEnabled("no-url-literals");
+ if (noURLLiterals)
+ throw ParseError("URL literals are disabled, at %s", CUR_POS);
+ $$ = new ExprString(data->symbols.create($1));
+ }
| '(' expr ')' { $$ = $2; }
/* Let expressions `let {..., body = ...}' are just desugared
into `(rec {..., body = ...}).body'. */
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 7c3e5a4da..021204f08 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -469,7 +469,7 @@ static void prim_tryEval(EvalState & state, const Pos & pos, Value * * args, Val
static void prim_getEnv(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
string name = state.forceStringNoCtx(*args[0], pos);
- mkString(v, evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name));
+ mkString(v, evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
}
@@ -506,13 +506,6 @@ static void prim_trace(EvalState & state, const Pos & pos, Value * * args, Value
}
-void prim_valueSize(EvalState & state, const Pos & pos, Value * * args, Value & v)
-{
- /* We're not forcing the argument on purpose. */
- mkInt(v, valueSize(*args[0]));
-}
-
-
/*************************************************************
* Derivations
*************************************************************/
@@ -2206,7 +2199,6 @@ void EvalState::createBaseEnv()
// Debugging
addPrimOp("__trace", 2, prim_trace);
- addPrimOp("__valueSize", 1, prim_valueSize);
// Paths
addPrimOp("__toPath", 1, prim_toPath);
diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc
index 6f67e3d76..a4c4b0943 100644
--- a/src/libexpr/primops/fetchGit.cc
+++ b/src/libexpr/primops/fetchGit.cc
@@ -5,6 +5,7 @@
#include "store-api.hh"
#include "pathlocks.hh"
#include "hash.hh"
+#include "tarfile.hh"
#include <sys/time.h>
@@ -164,7 +165,6 @@ GitInfo exportGit(ref<Store> store, std::string uri,
isLocal = true;
}
- Path cacheDir = getCacheDir() + "/nix/gitv3/" + hashString(htSHA256, uri).to_string(Base32, false);
Path repoDir;
if (isLocal) {
@@ -172,13 +172,11 @@ GitInfo exportGit(ref<Store> store, std::string uri,
if (!rev)
rev = Hash(chomp(runProgram("git", true, { "-C", uri, "rev-parse", *ref })), htSHA1);
- if (!pathExists(cacheDir))
- createDirs(cacheDir);
-
repoDir = uri;
} else {
+ Path cacheDir = getCacheDir() + "/nix/gitv3/" + hashString(htSHA256, uri).to_string(Base32, false);
repoDir = cacheDir;
if (!pathExists(cacheDir)) {
@@ -256,12 +254,16 @@ GitInfo exportGit(ref<Store> store, std::string uri,
// FIXME: should pipe this, or find some better way to extract a
// revision.
- auto tar = runProgram("git", true, { "-C", repoDir, "archive", gitInfo.rev.gitRev() });
+ auto source = sinkToSource([&](Sink & sink) {
+ RunOptions gitOptions("git", { "-C", repoDir, "archive", gitInfo.rev.gitRev() });
+ gitOptions.standardOut = &sink;
+ runProgram2(gitOptions);
+ });
Path tmpDir = createTempDir();
AutoDelete delTmpDir(tmpDir, true);
- runProgram("tar", true, { "x", "-C", tmpDir }, tar);
+ unpackTarfile(*source, tmpDir);
gitInfo.storePath = store->addToStore(name, tmpDir);
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index bdf2cdde1..60de60c67 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -35,7 +35,6 @@ struct Env;
struct Expr;
struct ExprLambda;
struct PrimOp;
-struct PrimOp;
class Symbol;
struct Pos;
class EvalState;
@@ -63,9 +62,6 @@ class ExternalValueBase
/* Return a string to be used in builtins.typeOf */
virtual string typeOf() const = 0;
- /* How much space does this value take up */
- virtual size_t valueSize(std::set<const void *> & seen) const = 0;
-
/* Coerce the value to a string. Defaults to uncoercable, i.e. throws an
* error
*/
@@ -261,12 +257,6 @@ static inline void mkPathNoCopy(Value & v, const char * s)
void mkPath(Value & v, const char * s);
-/* Compute the size in bytes of the given value, including all values
- and environments reachable from it. Static expressions (Exprs) are
- not included. */
-size_t valueSize(Value & v);
-
-
#if HAVE_BOEHMGC
typedef std::vector<Value *, gc_allocator<Value *> > ValueVector;
typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> > > ValueMap;