forked from lix-project/lix
StaticEnv: Use std::vector instead of std::map
This commit is contained in:
parent
c4bd6a15c2
commit
ab35cbd675
|
@ -583,7 +583,7 @@ Value * EvalState::addConstant(const string & name, Value & v)
|
||||||
{
|
{
|
||||||
Value * v2 = allocValue();
|
Value * v2 = allocValue();
|
||||||
*v2 = v;
|
*v2 = v;
|
||||||
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
staticBaseEnv.vars.emplace_back(symbols.create(name), baseEnvDispl);
|
||||||
baseEnv.values[baseEnvDispl++] = v2;
|
baseEnv.values[baseEnvDispl++] = v2;
|
||||||
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name;
|
||||||
baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2));
|
baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2));
|
||||||
|
@ -609,7 +609,7 @@ Value * EvalState::addPrimOp(const string & name,
|
||||||
|
|
||||||
Value * v = allocValue();
|
Value * v = allocValue();
|
||||||
v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = sym });
|
v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = sym });
|
||||||
staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl;
|
staticBaseEnv.vars.emplace_back(symbols.create(name), baseEnvDispl);
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = v;
|
||||||
baseEnv.values[0]->attrs->push_back(Attr(sym, v));
|
baseEnv.values[0]->attrs->push_back(Attr(sym, v));
|
||||||
return v;
|
return v;
|
||||||
|
@ -635,7 +635,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
|
||||||
|
|
||||||
Value * v = allocValue();
|
Value * v = allocValue();
|
||||||
v->mkPrimOp(new PrimOp(std::move(primOp)));
|
v->mkPrimOp(new PrimOp(std::move(primOp)));
|
||||||
staticBaseEnv.vars[envName] = baseEnvDispl;
|
staticBaseEnv.vars.emplace_back(envName, baseEnvDispl);
|
||||||
baseEnv.values[baseEnvDispl++] = v;
|
baseEnv.values[baseEnvDispl++] = v;
|
||||||
baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v));
|
baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v));
|
||||||
return v;
|
return v;
|
||||||
|
|
|
@ -269,7 +269,7 @@ void ExprVar::bindVars(const StaticEnv & env)
|
||||||
if (curEnv->isWith) {
|
if (curEnv->isWith) {
|
||||||
if (withLevel == -1) withLevel = level;
|
if (withLevel == -1) withLevel = level;
|
||||||
} else {
|
} else {
|
||||||
StaticEnv::Vars::const_iterator i = curEnv->vars.find(name);
|
auto i = curEnv->find(name);
|
||||||
if (i != curEnv->vars.end()) {
|
if (i != curEnv->vars.end()) {
|
||||||
fromWith = false;
|
fromWith = false;
|
||||||
this->level = level;
|
this->level = level;
|
||||||
|
@ -311,14 +311,16 @@ void ExprOpHasAttr::bindVars(const StaticEnv & env)
|
||||||
void ExprAttrs::bindVars(const StaticEnv & env)
|
void ExprAttrs::bindVars(const StaticEnv & env)
|
||||||
{
|
{
|
||||||
const StaticEnv * dynamicEnv = &env;
|
const StaticEnv * dynamicEnv = &env;
|
||||||
StaticEnv newEnv(false, &env);
|
StaticEnv newEnv(false, &env, recursive ? attrs.size() : 0);
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
dynamicEnv = &newEnv;
|
dynamicEnv = &newEnv;
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
newEnv.vars[i.first] = i.second.displ = displ++;
|
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
|
||||||
|
// No need to sort newEnv since attrs is in sorted order.
|
||||||
|
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
i.second.e->bindVars(i.second.inherited ? env : newEnv);
|
i.second.e->bindVars(i.second.inherited ? env : newEnv);
|
||||||
|
@ -342,15 +344,20 @@ void ExprList::bindVars(const StaticEnv & env)
|
||||||
|
|
||||||
void ExprLambda::bindVars(const StaticEnv & env)
|
void ExprLambda::bindVars(const StaticEnv & env)
|
||||||
{
|
{
|
||||||
StaticEnv newEnv(false, &env);
|
StaticEnv newEnv(
|
||||||
|
false, &env,
|
||||||
|
(hasFormals() ? formals->formals.size() : 0) +
|
||||||
|
(arg.empty() ? 0 : 1));
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
|
|
||||||
if (!arg.empty()) newEnv.vars[arg] = displ++;
|
if (!arg.empty()) newEnv.vars.emplace_back(arg, displ++);
|
||||||
|
|
||||||
if (hasFormals()) {
|
if (hasFormals()) {
|
||||||
for (auto & i : formals->formals)
|
for (auto & i : formals->formals)
|
||||||
newEnv.vars[i.name] = displ++;
|
newEnv.vars.emplace_back(i.name, displ++);
|
||||||
|
|
||||||
|
newEnv.sort();
|
||||||
|
|
||||||
for (auto & i : formals->formals)
|
for (auto & i : formals->formals)
|
||||||
if (i.def) i.def->bindVars(newEnv);
|
if (i.def) i.def->bindVars(newEnv);
|
||||||
|
@ -361,11 +368,13 @@ void ExprLambda::bindVars(const StaticEnv & env)
|
||||||
|
|
||||||
void ExprLet::bindVars(const StaticEnv & env)
|
void ExprLet::bindVars(const StaticEnv & env)
|
||||||
{
|
{
|
||||||
StaticEnv newEnv(false, &env);
|
StaticEnv newEnv(false, &env, attrs->attrs.size());
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
newEnv.vars[i.first] = i.second.displ = displ++;
|
newEnv.vars.emplace_back(i.first, i.second.displ = displ++);
|
||||||
|
|
||||||
|
// No need to sort newEnv since attrs->attrs is in sorted order.
|
||||||
|
|
||||||
for (auto & i : attrs->attrs)
|
for (auto & i : attrs->attrs)
|
||||||
i.second.e->bindVars(i.second.inherited ? env : newEnv);
|
i.second.e->bindVars(i.second.inherited ? env : newEnv);
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include "symbol-table.hh"
|
#include "symbol-table.hh"
|
||||||
#include "error.hh"
|
#include "error.hh"
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -342,9 +340,28 @@ struct StaticEnv
|
||||||
{
|
{
|
||||||
bool isWith;
|
bool isWith;
|
||||||
const StaticEnv * up;
|
const StaticEnv * up;
|
||||||
typedef std::map<Symbol, unsigned int> Vars;
|
|
||||||
|
// Note: these must be in sorted order.
|
||||||
|
typedef std::vector<std::pair<Symbol, unsigned int>> Vars;
|
||||||
Vars vars;
|
Vars vars;
|
||||||
StaticEnv(bool isWith, const StaticEnv * up) : isWith(isWith), up(up) { };
|
|
||||||
|
StaticEnv(bool isWith, const StaticEnv * up, size_t expectedSize = 0) : isWith(isWith), up(up) {
|
||||||
|
vars.reserve(expectedSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
void sort()
|
||||||
|
{
|
||||||
|
std::sort(vars.begin(), vars.end(),
|
||||||
|
[](const Vars::value_type & a, const Vars::value_type & b) { return a.first < b.first; });
|
||||||
|
}
|
||||||
|
|
||||||
|
Vars::const_iterator find(const Symbol & name) const
|
||||||
|
{
|
||||||
|
Vars::value_type key(name, 0);
|
||||||
|
auto i = std::lower_bound(vars.begin(), vars.end(), key);
|
||||||
|
if (i != vars.end() && i->first == name) return i;
|
||||||
|
return vars.end();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -126,14 +126,14 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
|
||||||
auto j2 = jAttrs->attrs.find(ad.first);
|
auto j2 = jAttrs->attrs.find(ad.first);
|
||||||
if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error.
|
if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error.
|
||||||
dupAttr(ad.first, j2->second.pos, ad.second.pos);
|
dupAttr(ad.first, j2->second.pos, ad.second.pos);
|
||||||
jAttrs->attrs[ad.first] = ad.second;
|
jAttrs->attrs.emplace(ad.first, ad.second);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dupAttr(attrPath, pos, j->second.pos);
|
dupAttr(attrPath, pos, j->second.pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This attr path is not defined. Let's create it.
|
// This attr path is not defined. Let's create it.
|
||||||
attrs->attrs[i->symbol] = ExprAttrs::AttrDef(e, pos);
|
attrs->attrs.emplace(i->symbol, ExprAttrs::AttrDef(e, pos));
|
||||||
e->setName(i->symbol);
|
e->setName(i->symbol);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -483,7 +483,7 @@ binds
|
||||||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||||
dupAttr(i.symbol, makeCurPos(@3, data), $$->attrs[i.symbol].pos);
|
dupAttr(i.symbol, makeCurPos(@3, data), $$->attrs[i.symbol].pos);
|
||||||
Pos pos = makeCurPos(@3, data);
|
Pos pos = makeCurPos(@3, data);
|
||||||
$$->attrs[i.symbol] = ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true);
|
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| binds INHERIT '(' expr ')' attrs ';'
|
| binds INHERIT '(' expr ')' attrs ';'
|
||||||
|
@ -492,7 +492,7 @@ binds
|
||||||
for (auto & i : *$6) {
|
for (auto & i : *$6) {
|
||||||
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
if ($$->attrs.find(i.symbol) != $$->attrs.end())
|
||||||
dupAttr(i.symbol, makeCurPos(@6, data), $$->attrs[i.symbol].pos);
|
dupAttr(i.symbol, makeCurPos(@6, data), $$->attrs[i.symbol].pos);
|
||||||
$$->attrs[i.symbol] = ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), makeCurPos(@6, data));
|
$$->attrs.emplace(i.symbol, ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), makeCurPos(@6, data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| { $$ = new ExprAttrs(makeCurPos(@0, data)); }
|
| { $$ = new ExprAttrs(makeCurPos(@0, data)); }
|
||||||
|
|
|
@ -184,14 +184,17 @@ static void import(EvalState & state, const Pos & pos, Value & vPath, Value * vS
|
||||||
Env * env = &state.allocEnv(vScope->attrs->size());
|
Env * env = &state.allocEnv(vScope->attrs->size());
|
||||||
env->up = &state.baseEnv;
|
env->up = &state.baseEnv;
|
||||||
|
|
||||||
StaticEnv staticEnv(false, &state.staticBaseEnv);
|
StaticEnv staticEnv(false, &state.staticBaseEnv, vScope->attrs->size());
|
||||||
|
|
||||||
unsigned int displ = 0;
|
unsigned int displ = 0;
|
||||||
for (auto & attr : *vScope->attrs) {
|
for (auto & attr : *vScope->attrs) {
|
||||||
staticEnv.vars[attr.name] = displ;
|
staticEnv.vars.emplace_back(attr.name, displ);
|
||||||
env->values[displ++] = attr.value;
|
env->values[displ++] = attr.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No need to call staticEnv.sort(), because
|
||||||
|
// args[0]->attrs is already sorted.
|
||||||
|
|
||||||
printTalkative("evaluating file '%1%'", realPath);
|
printTalkative("evaluating file '%1%'", realPath);
|
||||||
Expr * e = state.parseExprFromFile(resolveExprPath(realPath), staticEnv);
|
Expr * e = state.parseExprFromFile(resolveExprPath(realPath), staticEnv);
|
||||||
|
|
||||||
|
@ -3726,6 +3729,7 @@ void EvalState::createBaseEnv()
|
||||||
|
|
||||||
/* Add a wrapper around the derivation primop that computes the
|
/* Add a wrapper around the derivation primop that computes the
|
||||||
`drvPath' and `outPath' attributes lazily. */
|
`drvPath' and `outPath' attributes lazily. */
|
||||||
|
staticBaseEnv.sort();
|
||||||
sDerivationNix = symbols.create("//builtin/derivation.nix");
|
sDerivationNix = symbols.create("//builtin/derivation.nix");
|
||||||
eval(parse(
|
eval(parse(
|
||||||
#include "primops/derivation.nix.gen.hh"
|
#include "primops/derivation.nix.gen.hh"
|
||||||
|
@ -3735,6 +3739,8 @@ void EvalState::createBaseEnv()
|
||||||
/* Now that we've added all primops, sort the `builtins' set,
|
/* Now that we've added all primops, sort the `builtins' set,
|
||||||
because attribute lookups expect it to be sorted. */
|
because attribute lookups expect it to be sorted. */
|
||||||
baseEnv.values[0]->attrs->sort();
|
baseEnv.values[0]->attrs->sort();
|
||||||
|
|
||||||
|
staticBaseEnv.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -644,7 +644,8 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v)
|
||||||
{
|
{
|
||||||
if (displ >= envSize)
|
if (displ >= envSize)
|
||||||
throw Error("environment full; cannot add more variables");
|
throw Error("environment full; cannot add more variables");
|
||||||
staticEnv.vars[name] = displ;
|
staticEnv.vars.emplace_back(name, displ);
|
||||||
|
staticEnv.sort();
|
||||||
env->values[displ++] = &v;
|
env->values[displ++] = &v;
|
||||||
varNames.insert((string) name);
|
varNames.insert((string) name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue