Skip to content

Commit

Permalink
shared_ptr for StaticEnv
Browse files Browse the repository at this point in the history
  • Loading branch information
bburdette committed Sep 14, 2021
1 parent 1769111 commit 21071bf
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 69 deletions.
16 changes: 0 additions & 16 deletions doc/manual/src/expressions/builtins.md.tmp

This file was deleted.

11 changes: 6 additions & 5 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ struct NixRepl
Strings loadedFiles;

const static int envSize = 32768;
StaticEnv staticEnv;
std::shared_ptr<StaticEnv> staticEnv;
// StaticEnv staticEnv;
Env * env;
int displ;
StringSet varNames;
Expand Down Expand Up @@ -92,7 +93,7 @@ string removeWhitespace(string s)

NixRepl::NixRepl(ref<EvalState> state)
: state(state)
, staticEnv(false, &state->staticBaseEnv)
, staticEnv(new StaticEnv(false, state->staticBaseEnv.get()))
, historyFile(getDataDir() + "/nix/repl-history")
{
curDir = absPath(".");
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> 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";

Expand Down Expand Up @@ -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));
Expand All @@ -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;
Expand All @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum RepairFlag : bool;

typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v);

extern std::function<void(const Error & error, const Env & env)> debuggerHook;

struct PrimOp
{
Expand Down Expand Up @@ -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> & 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> & staticEnv);
Expr * parseExprFromString(std::string_view s, const Path & basePath);

Expr * parseStdin();
Expand Down Expand Up @@ -238,7 +239,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:

Expand Down Expand Up @@ -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> & staticEnv);

public:

Expand Down
64 changes: 32 additions & 32 deletions src/libexpr/nixexpr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,35 +237,35 @@ Pos noPos;

/* Computing levels/displacements for variables. */

void Expr::bindVars(const StaticEnv & env)
void Expr::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
abort();
}

void ExprInt::bindVars(const StaticEnv & env)
void ExprInt::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
}

void ExprFloat::bindVars(const StaticEnv & env)
void ExprFloat::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
}

void ExprString::bindVars(const StaticEnv & env)
void ExprString::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
}

void ExprPath::bindVars(const StaticEnv & env)
void ExprPath::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
}

void ExprVar::bindVars(const StaticEnv & env)
void ExprVar::bindVars(const std::shared_ptr<const StaticEnv> &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 {
Expand All @@ -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<const StaticEnv> &env)
{
e->bindVars(env);
if (def) def->bindVars(env);
Expand All @@ -300,25 +300,25 @@ void ExprSelect::bindVars(const StaticEnv & env)
i.expr->bindVars(env);
}

void ExprOpHasAttr::bindVars(const StaticEnv & env)
void ExprOpHasAttr::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
e->bindVars(env);
for (auto & i : attrPath)
if (!i.symbol.set())
i.expr->bindVars(env);
}

void ExprAttrs::bindVars(const StaticEnv & env)
void ExprAttrs::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
const StaticEnv * dynamicEnv = &env;
StaticEnv newEnv(false, &env);
const StaticEnv * dynamicEnv = env.get();
auto newEnv = std::shared_ptr<StaticEnv>(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);
Expand All @@ -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<const StaticEnv> &env)
{
for (auto & i : elems)
i->bindVars(env);
}

void ExprLambda::bindVars(const StaticEnv & env)
void ExprLambda::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
StaticEnv newEnv(false, &env);
auto newEnv = std::shared_ptr<StaticEnv>(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);
Expand All @@ -359,64 +359,64 @@ void ExprLambda::bindVars(const StaticEnv & env)
body->bindVars(newEnv);
}

void ExprLet::bindVars(const StaticEnv & env)
void ExprLet::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
StaticEnv newEnv(false, &env);
auto newEnv = std::shared_ptr<StaticEnv>(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);

body->bindVars(newEnv);
}

void ExprWith::bindVars(const StaticEnv & env)
void ExprWith::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
/* Does this `with' have an enclosing `with'? If so, record its
level so that `lookupVar' can look up variables in the previous
`with' if this one doesn't contain the desired attribute. */
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<StaticEnv>(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<const StaticEnv> &env)
{
cond->bindVars(env);
then->bindVars(env);
else_->bindVars(env);
}

void ExprAssert::bindVars(const StaticEnv & env)
void ExprAssert::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
cond->bindVars(env);
body->bindVars(env);
}

void ExprOpNot::bindVars(const StaticEnv & env)
void ExprOpNot::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
e->bindVars(env);
}

void ExprConcatStrings::bindVars(const StaticEnv & env)
void ExprConcatStrings::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
for (auto & i : *es)
i->bindVars(env);
}

void ExprPos::bindVars(const StaticEnv & env)
void ExprPos::bindVars(const std::shared_ptr<const StaticEnv> &env)
{
}

Expand Down
8 changes: 5 additions & 3 deletions src/libexpr/nixexpr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,20 @@ struct Expr
{
virtual ~Expr() { };
virtual void show(std::ostream & str) const;
virtual void bindVars(const StaticEnv & env);
virtual void bindVars(const std::shared_ptr<const StaticEnv> & 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> staticenv;
};

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<const StaticEnv> & env);

struct ExprInt : Expr
{
Expand Down Expand Up @@ -301,7 +303,7 @@ struct ExprOpNot : Expr
{ \
str << "(" << *e1 << " " s " " << *e2 << ")"; \
} \
void bindVars(const StaticEnv & env) \
void bindVars(const std::shared_ptr<const StaticEnv> & env) \
{ \
e1->bindVars(env); e2->bindVars(env); \
} \
Expand Down
6 changes: 3 additions & 3 deletions src/libexpr/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -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> & staticEnv)
{
yyscan_t scanner;
ParseData data(*this);
Expand Down Expand Up @@ -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> & 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> & staticEnv)
{
return parse(s.data(), foString, "", basePath, staticEnv);
}
Expand Down
4 changes: 2 additions & 2 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<StaticEnv>(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;
}

Expand Down

0 comments on commit 21071bf

Please sign in to comment.