From 21071bfdeb0a5bc2b75018c91a4c2f138f233e33 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 14 Sep 2021 10:49:22 -0600 Subject: [PATCH] shared_ptr for StaticEnv --- doc/manual/src/expressions/builtins.md.tmp | 16 ------ src/libcmd/repl.cc | 11 ++-- src/libexpr/eval.cc | 8 +-- src/libexpr/eval.hh | 9 +-- src/libexpr/nixexpr.cc | 64 +++++++++++----------- src/libexpr/nixexpr.hh | 8 ++- src/libexpr/parser.y | 6 +- src/libexpr/primops.cc | 4 +- 8 files changed, 57 insertions(+), 69 deletions(-) delete mode 100644 doc/manual/src/expressions/builtins.md.tmp diff --git a/doc/manual/src/expressions/builtins.md.tmp b/doc/manual/src/expressions/builtins.md.tmp deleted file mode 100644 index 95a73709e..000000000 --- a/doc/manual/src/expressions/builtins.md.tmp +++ /dev/null @@ -1,16 +0,0 @@ -# Built-in Functions - -This section lists the functions built into the Nix expression -evaluator. (The built-in function `derivation` is discussed above.) -Some built-ins, such as `derivation`, are always in scope of every Nix -expression; you can just access them right away. But to prevent -polluting the namespace too much, most built-ins are not in -scope. Instead, you can access them through the `builtins` built-in -value, which is a set that contains all built-in functions and values. -For instance, `derivation` is also available as `builtins.derivation`. - - - `derivation` *attrs*; `builtins.derivation` *attrs*\ - - `derivation` is described in [its own section](derivations.md). - -EvalCommand::getEvalState()0 diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 57174bf0e..e1b58cc76 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -53,7 +53,8 @@ struct NixRepl Strings loadedFiles; const static int envSize = 32768; - StaticEnv staticEnv; + std::shared_ptr staticEnv; + // StaticEnv staticEnv; Env * env; int displ; StringSet varNames; @@ -92,7 +93,7 @@ string removeWhitespace(string s) NixRepl::NixRepl(ref state) : state(state) - , staticEnv(false, &state->staticBaseEnv) + , staticEnv(new StaticEnv(false, state->staticBaseEnv.get())) , historyFile(getDataDir() + "/nix/repl-history") { curDir = absPath("."); @@ -567,10 +568,10 @@ void NixRepl::initEnv() env = &state->allocEnv(envSize); env->up = &state->baseEnv; displ = 0; - staticEnv.vars.clear(); + staticEnv->vars.clear(); varNames.clear(); - for (auto & i : state->staticBaseEnv.vars) + for (auto & i : state->staticBaseEnv->vars) varNames.insert(i.first); } @@ -605,7 +606,7 @@ void NixRepl::addVarToScope(const Symbol & name, Value * v) { if (displ >= envSize) throw Error("environment full; cannot add more variables"); - staticEnv.vars[name] = displ; + staticEnv->vars[name] = displ; env->values[displ++] = v; varNames.insert((string) name); } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 19379b876..69e3a4107 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -401,7 +401,7 @@ EvalState::EvalState(const Strings & _searchPath, ref store) , store(store) , regexCache(makeRegexCache()) , baseEnv(allocEnv(128)) - , staticBaseEnv(false, 0) + , staticBaseEnv(new StaticEnv(false, 0)) { countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0"; @@ -538,7 +538,7 @@ Value * EvalState::addConstant(const string & name, Value & v) { Value * v2 = allocValue(); *v2 = v; - staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; + staticBaseEnv->vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v2; string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2)); @@ -564,7 +564,7 @@ Value * EvalState::addPrimOp(const string & name, Value * v = allocValue(); v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = sym }); - staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; + staticBaseEnv->vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; baseEnv.values[0]->attrs->push_back(Attr(sym, v)); return v; @@ -590,7 +590,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp) Value * v = allocValue(); v->mkPrimOp(new PrimOp(std::move(primOp))); - staticBaseEnv.vars[envName] = baseEnvDispl; + staticBaseEnv->vars[envName] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v)); return v; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index c96e2c726..8edc17789 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -23,6 +23,7 @@ enum RepairFlag : bool; typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v); +extern std::function debuggerHook; struct PrimOp { @@ -154,10 +155,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); /* 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, std::shared_ptr & staticEnv); Expr * parseExprFromString(std::string_view s, const Path & basePath); Expr * parseStdin(); @@ -238,7 +239,7 @@ public: Env & baseEnv; /* The same, but used during parsing to resolve variables. */ - StaticEnv staticBaseEnv; // !!! should be private + std::shared_ptr staticBaseEnv; // !!! should be private private: @@ -277,7 +278,7 @@ private: friend struct ExprLet; Expr * parse(const char * text, FileOrigin origin, const Path & path, - const Path & basePath, StaticEnv & staticEnv); + const Path & basePath, std::shared_ptr & staticEnv); public: diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 492b819e7..218e35f33 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -237,35 +237,35 @@ Pos noPos; /* Computing levels/displacements for variables. */ -void Expr::bindVars(const StaticEnv & env) +void Expr::bindVars(const std::shared_ptr &env) { abort(); } -void ExprInt::bindVars(const StaticEnv & env) +void ExprInt::bindVars(const std::shared_ptr &env) { } -void ExprFloat::bindVars(const StaticEnv & env) +void ExprFloat::bindVars(const std::shared_ptr &env) { } -void ExprString::bindVars(const StaticEnv & env) +void ExprString::bindVars(const std::shared_ptr &env) { } -void ExprPath::bindVars(const StaticEnv & env) +void ExprPath::bindVars(const std::shared_ptr &env) { } -void ExprVar::bindVars(const StaticEnv & env) +void ExprVar::bindVars(const std::shared_ptr &env) { /* Check whether the variable appears in the environment. If so, set its level and displacement. */ const StaticEnv * curEnv; unsigned int level; int withLevel = -1; - for (curEnv = &env, level = 0; curEnv; curEnv = curEnv->up, level++) { + for (curEnv = env.get(), level = 0; curEnv; curEnv = curEnv->up, level++) { if (curEnv->isWith) { if (withLevel == -1) withLevel = level; } else { @@ -291,7 +291,7 @@ void ExprVar::bindVars(const StaticEnv & env) this->level = withLevel; } -void ExprSelect::bindVars(const StaticEnv & env) +void ExprSelect::bindVars(const std::shared_ptr &env) { e->bindVars(env); if (def) def->bindVars(env); @@ -300,7 +300,7 @@ void ExprSelect::bindVars(const StaticEnv & env) i.expr->bindVars(env); } -void ExprOpHasAttr::bindVars(const StaticEnv & env) +void ExprOpHasAttr::bindVars(const std::shared_ptr &env) { e->bindVars(env); for (auto & i : attrPath) @@ -308,17 +308,17 @@ void ExprOpHasAttr::bindVars(const StaticEnv & env) i.expr->bindVars(env); } -void ExprAttrs::bindVars(const StaticEnv & env) +void ExprAttrs::bindVars(const std::shared_ptr &env) { - const StaticEnv * dynamicEnv = &env; - StaticEnv newEnv(false, &env); + const StaticEnv * dynamicEnv = env.get(); + auto newEnv = std::shared_ptr(new StaticEnv(false, env.get())); // also make shared_ptr? if (recursive) { - dynamicEnv = &newEnv; + dynamicEnv = newEnv.get(); unsigned int displ = 0; for (auto & i : attrs) - newEnv.vars[i.first] = i.second.displ = displ++; + newEnv->vars[i.first] = i.second.displ = displ++; for (auto & i : attrs) i.second.e->bindVars(i.second.inherited ? env : newEnv); @@ -329,28 +329,28 @@ void ExprAttrs::bindVars(const StaticEnv & env) i.second.e->bindVars(env); for (auto & i : dynamicAttrs) { - i.nameExpr->bindVars(*dynamicEnv); - i.valueExpr->bindVars(*dynamicEnv); + i.nameExpr->bindVars(newEnv); + i.valueExpr->bindVars(newEnv); } } -void ExprList::bindVars(const StaticEnv & env) +void ExprList::bindVars(const std::shared_ptr &env) { for (auto & i : elems) i->bindVars(env); } -void ExprLambda::bindVars(const StaticEnv & env) +void ExprLambda::bindVars(const std::shared_ptr &env) { - StaticEnv newEnv(false, &env); + auto newEnv = std::shared_ptr(new StaticEnv(false, env.get())); // also make shared_ptr? unsigned int displ = 0; - if (!arg.empty()) newEnv.vars[arg] = displ++; + if (!arg.empty()) newEnv->vars[arg] = displ++; if (matchAttrs) { for (auto & i : formals->formals) - newEnv.vars[i.name] = displ++; + newEnv->vars[i.name] = displ++; for (auto & i : formals->formals) if (i.def) i.def->bindVars(newEnv); @@ -359,13 +359,13 @@ void ExprLambda::bindVars(const StaticEnv & env) body->bindVars(newEnv); } -void ExprLet::bindVars(const StaticEnv & env) +void ExprLet::bindVars(const std::shared_ptr &env) { - StaticEnv newEnv(false, &env); + auto newEnv = std::shared_ptr(new StaticEnv(false, env.get())); // also make shared_ptr? unsigned int displ = 0; for (auto & i : attrs->attrs) - newEnv.vars[i.first] = i.second.displ = displ++; + newEnv->vars[i.first] = i.second.displ = displ++; for (auto & i : attrs->attrs) i.second.e->bindVars(i.second.inherited ? env : newEnv); @@ -373,7 +373,7 @@ void ExprLet::bindVars(const StaticEnv & env) body->bindVars(newEnv); } -void ExprWith::bindVars(const StaticEnv & env) +void ExprWith::bindVars(const std::shared_ptr &env) { /* Does this `with' have an enclosing `with'? If so, record its level so that `lookupVar' can look up variables in the previous @@ -381,42 +381,42 @@ void ExprWith::bindVars(const StaticEnv & env) const StaticEnv * curEnv; unsigned int level; prevWith = 0; - for (curEnv = &env, level = 1; curEnv; curEnv = curEnv->up, level++) + for (curEnv = env.get(), level = 1; curEnv; curEnv = curEnv->up, level++) if (curEnv->isWith) { prevWith = level; break; } attrs->bindVars(env); - StaticEnv newEnv(true, &env); + auto newEnv = std::shared_ptr(new StaticEnv(false, env.get())); // also make shared_ptr? body->bindVars(newEnv); } -void ExprIf::bindVars(const StaticEnv & env) +void ExprIf::bindVars(const std::shared_ptr &env) { cond->bindVars(env); then->bindVars(env); else_->bindVars(env); } -void ExprAssert::bindVars(const StaticEnv & env) +void ExprAssert::bindVars(const std::shared_ptr &env) { cond->bindVars(env); body->bindVars(env); } -void ExprOpNot::bindVars(const StaticEnv & env) +void ExprOpNot::bindVars(const std::shared_ptr &env) { e->bindVars(env); } -void ExprConcatStrings::bindVars(const StaticEnv & env) +void ExprConcatStrings::bindVars(const std::shared_ptr &env) { for (auto & i : *es) i->bindVars(env); } -void ExprPos::bindVars(const StaticEnv & env) +void ExprPos::bindVars(const std::shared_ptr &env) { } diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 51a14cd59..4c55cb64b 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -79,10 +79,12 @@ struct Expr { virtual ~Expr() { }; virtual void show(std::ostream & str) const; - virtual void bindVars(const StaticEnv & env); + virtual void bindVars(const std::shared_ptr & env); virtual void eval(EvalState & state, Env & env, Value & v); virtual Value * maybeThunk(EvalState & state, Env & env); virtual void setName(Symbol & name); + + std::shared_ptr staticenv; }; std::ostream & operator << (std::ostream & str, const Expr & e); @@ -90,7 +92,7 @@ std::ostream & operator << (std::ostream & str, const Expr & e); #define COMMON_METHODS \ void show(std::ostream & str) const; \ void eval(EvalState & state, Env & env, Value & v); \ - void bindVars(const StaticEnv & env); + void bindVars(const std::shared_ptr & env); struct ExprInt : Expr { @@ -301,7 +303,7 @@ struct ExprOpNot : Expr { \ str << "(" << *e1 << " " s " " << *e2 << ")"; \ } \ - void bindVars(const StaticEnv & env) \ + void bindVars(const std::shared_ptr & env) \ { \ e1->bindVars(env); e2->bindVars(env); \ } \ diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index f948dde47..d1e898677 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -570,7 +570,7 @@ namespace nix { Expr * EvalState::parse(const char * text, FileOrigin origin, - const Path & path, const Path & basePath, StaticEnv & staticEnv) + const Path & path, const Path & basePath, std::shared_ptr & staticEnv) { yyscan_t scanner; ParseData data(*this); @@ -633,13 +633,13 @@ Expr * EvalState::parseExprFromFile(const Path & path) } -Expr * EvalState::parseExprFromFile(const Path & path, StaticEnv & staticEnv) +Expr * EvalState::parseExprFromFile(const Path & path, std::shared_ptr & staticEnv) { return parse(readFile(path).c_str(), foFile, path, dirOf(path), staticEnv); } -Expr * EvalState::parseExprFromString(std::string_view s, const Path & basePath, StaticEnv & staticEnv) +Expr * EvalState::parseExprFromString(std::string_view s, const Path & basePath, std::shared_ptr & staticEnv) { return parse(s.data(), foString, "", basePath, staticEnv); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index fc4afaab8..0400c8942 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -186,11 +186,11 @@ static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vS Env * env = &state.allocEnv(vScope->attrs->size()); env->up = &state.baseEnv; - StaticEnv staticEnv(false, &state.staticBaseEnv); + auto staticEnv = std::shared_ptr(new StaticEnv(false, state.staticBaseEnv.get())); unsigned int displ = 0; for (auto & attr : *vScope->attrs) { - staticEnv.vars[attr.name] = displ; + staticEnv->vars[attr.name] = displ; env->values[displ++] = attr.value; }