forked from lix-project/lix
Remove EvalState::mkAttrs()
This commit is contained in:
parent
17daec0b83
commit
2b4c944823
|
@ -7,6 +7,7 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocate a new array of attributes for an attribute set with a specific
|
/* Allocate a new array of attributes for an attribute set with a specific
|
||||||
capacity. The space is implicitly reserved after the Bindings
|
capacity. The space is implicitly reserved after the Bindings
|
||||||
structure. */
|
structure. */
|
||||||
|
@ -16,15 +17,9 @@ Bindings * EvalState::allocBindings(size_t capacity)
|
||||||
return &emptyBindings;
|
return &emptyBindings;
|
||||||
if (capacity > std::numeric_limits<Bindings::size_t>::max())
|
if (capacity > std::numeric_limits<Bindings::size_t>::max())
|
||||||
throw Error("attribute set of size %d is too big", capacity);
|
throw Error("attribute set of size %d is too big", capacity);
|
||||||
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings((Bindings::size_t) capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void EvalState::mkAttrs(Value & v, size_t capacity)
|
|
||||||
{
|
|
||||||
v.mkAttrs(allocBindings(capacity));
|
|
||||||
nrAttrsets++;
|
nrAttrsets++;
|
||||||
nrAttrsInAttrsets += capacity;
|
nrAttrsInAttrsets += capacity;
|
||||||
|
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings((Bindings::size_t) capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,9 +62,7 @@ void Bindings::sort()
|
||||||
|
|
||||||
Value & Value::mkAttrs(BindingsBuilder & bindings)
|
Value & Value::mkAttrs(BindingsBuilder & bindings)
|
||||||
{
|
{
|
||||||
clearValue();
|
mkAttrs(bindings.finish());
|
||||||
internalType = tAttrs;
|
|
||||||
attrs = bindings.finish();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,13 +118,14 @@ public:
|
||||||
call finish(), which sorts the bindings. */
|
call finish(), which sorts the bindings. */
|
||||||
class BindingsBuilder
|
class BindingsBuilder
|
||||||
{
|
{
|
||||||
EvalState & state;
|
|
||||||
Bindings * bindings;
|
Bindings * bindings;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
EvalState & state;
|
||||||
|
|
||||||
BindingsBuilder(EvalState & state, Bindings * bindings)
|
BindingsBuilder(EvalState & state, Bindings * bindings)
|
||||||
: state(state), bindings(bindings)
|
: bindings(bindings), state(state)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void insert(Symbol name, Value * value, ptr<Pos> pos = ptr(&noPos))
|
void insert(Symbol name, Value * value, ptr<Pos> pos = ptr(&noPos))
|
||||||
|
@ -146,6 +147,11 @@ public:
|
||||||
bindings->sort();
|
bindings->sort();
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bindings * alreadySorted()
|
||||||
|
{
|
||||||
|
return bindings;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ void printValue(std::ostream & str, std::set<const Value *> & active, const Valu
|
||||||
str << v.fpoint;
|
str << v.fpoint;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Error("invalid value");
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
active.erase(&v);
|
active.erase(&v);
|
||||||
|
@ -1065,8 +1065,8 @@ void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
state.mkAttrs(v, attrs.size() + dynamicAttrs.size());
|
v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish());
|
||||||
Env *dynamicEnv = &env;
|
auto dynamicEnv = &env;
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
/* Create a new environment that contains the attributes in
|
/* Create a new environment that contains the attributes in
|
||||||
|
@ -1592,7 +1592,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
if (v1.attrs->size() == 0) { v = v2; return; }
|
if (v1.attrs->size() == 0) { v = v2; return; }
|
||||||
if (v2.attrs->size() == 0) { v = v1; return; }
|
if (v2.attrs->size() == 0) { v = v1; return; }
|
||||||
|
|
||||||
state.mkAttrs(v, v1.attrs->size() + v2.attrs->size());
|
auto attrs = state.buildBindings(v1.attrs->size() + v2.attrs->size());
|
||||||
|
|
||||||
/* Merge the sets, preferring values from the second set. Make
|
/* Merge the sets, preferring values from the second set. Make
|
||||||
sure to keep the resulting vector in sorted order. */
|
sure to keep the resulting vector in sorted order. */
|
||||||
|
@ -1601,17 +1601,19 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
while (i != v1.attrs->end() && j != v2.attrs->end()) {
|
while (i != v1.attrs->end() && j != v2.attrs->end()) {
|
||||||
if (i->name == j->name) {
|
if (i->name == j->name) {
|
||||||
v.attrs->push_back(*j);
|
attrs.insert(*j);
|
||||||
++i; ++j;
|
++i; ++j;
|
||||||
}
|
}
|
||||||
else if (i->name < j->name)
|
else if (i->name < j->name)
|
||||||
v.attrs->push_back(*i++);
|
attrs.insert(*i++);
|
||||||
else
|
else
|
||||||
v.attrs->push_back(*j++);
|
attrs.insert(*j++);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i != v1.attrs->end()) v.attrs->push_back(*i++);
|
while (i != v1.attrs->end()) attrs.insert(*i++);
|
||||||
while (j != v2.attrs->end()) v.attrs->push_back(*j++);
|
while (j != v2.attrs->end()) attrs.insert(*j++);
|
||||||
|
|
||||||
|
v.mkAttrs(attrs.alreadySorted());
|
||||||
|
|
||||||
state.nrOpUpdateValuesCopied += v.attrs->size();
|
state.nrOpUpdateValuesCopied += v.attrs->size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void mkList(Value & v, size_t length);
|
void mkList(Value & v, size_t length);
|
||||||
void mkAttrs(Value & v, size_t capacity);
|
|
||||||
void mkThunk_(Value & v, Expr * expr);
|
void mkThunk_(Value & v, Expr * expr);
|
||||||
void mkPos(Value & v, ptr<Pos> pos);
|
void mkPos(Value & v, ptr<Pos> pos);
|
||||||
|
|
||||||
|
@ -400,6 +399,8 @@ private:
|
||||||
friend struct ExprSelect;
|
friend struct ExprSelect;
|
||||||
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
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_match(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||||
|
|
||||||
|
friend struct Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,10 @@ class JSONSax : nlohmann::json_sax<json> {
|
||||||
ValueMap attrs;
|
ValueMap attrs;
|
||||||
std::unique_ptr<JSONState> resolve(EvalState & state) override
|
std::unique_ptr<JSONState> resolve(EvalState & state) override
|
||||||
{
|
{
|
||||||
Value & v = parent->value(state);
|
auto attrs2 = state.buildBindings(attrs.size());
|
||||||
state.mkAttrs(v, attrs.size());
|
|
||||||
for (auto & i : attrs)
|
for (auto & i : attrs)
|
||||||
v.attrs->push_back(Attr(i.first, i.second));
|
attrs2.insert(i.first, i.second);
|
||||||
|
parent->value(state).mkAttrs(attrs2.alreadySorted());
|
||||||
return std::move(parent);
|
return std::move(parent);
|
||||||
}
|
}
|
||||||
void add() override { v = nullptr; }
|
void add() override { v = nullptr; }
|
||||||
|
|
|
@ -2274,11 +2274,12 @@ static void prim_removeAttrs(EvalState & state, const Pos & pos, Value * * args,
|
||||||
/* Copy all attributes not in that set. Note that we don't need
|
/* Copy all attributes not in that set. Note that we don't need
|
||||||
to sort v.attrs because it's a subset of an already sorted
|
to sort v.attrs because it's a subset of an already sorted
|
||||||
vector. */
|
vector. */
|
||||||
state.mkAttrs(v, args[0]->attrs->size());
|
auto attrs = state.buildBindings(args[0]->attrs->size());
|
||||||
for (auto & i : *args[0]->attrs) {
|
for (auto & i : *args[0]->attrs) {
|
||||||
if (!names.count(i.name))
|
if (!names.count(i.name))
|
||||||
v.attrs->push_back(i);
|
attrs.insert(i);
|
||||||
}
|
}
|
||||||
|
v.mkAttrs(attrs.alreadySorted());
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_removeAttrs({
|
static RegisterPrimOp primop_removeAttrs({
|
||||||
|
@ -2369,13 +2370,15 @@ static void prim_intersectAttrs(EvalState & state, const Pos & pos, Value * * ar
|
||||||
state.forceAttrs(*args[0], pos);
|
state.forceAttrs(*args[0], pos);
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
|
|
||||||
state.mkAttrs(v, std::min(args[0]->attrs->size(), args[1]->attrs->size()));
|
auto attrs = state.buildBindings(std::min(args[0]->attrs->size(), args[1]->attrs->size()));
|
||||||
|
|
||||||
for (auto & i : *args[0]->attrs) {
|
for (auto & i : *args[0]->attrs) {
|
||||||
Bindings::iterator j = args[1]->attrs->find(i.name);
|
Bindings::iterator j = args[1]->attrs->find(i.name);
|
||||||
if (j != args[1]->attrs->end())
|
if (j != args[1]->attrs->end())
|
||||||
v.attrs->push_back(*j);
|
attrs.insert(*j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.mkAttrs(attrs.alreadySorted());
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_intersectAttrs({
|
static RegisterPrimOp primop_intersectAttrs({
|
||||||
|
@ -2429,7 +2432,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
|
||||||
{
|
{
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) {
|
if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) {
|
||||||
state.mkAttrs(v, 0);
|
v.mkAttrs(&state.emptyBindings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!args[0]->isLambda())
|
if (!args[0]->isLambda())
|
||||||
|
@ -2439,7 +2442,7 @@ static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!args[0]->lambda.fun->hasFormals()) {
|
if (!args[0]->lambda.fun->hasFormals()) {
|
||||||
state.mkAttrs(v, 0);
|
v.mkAttrs(&state.emptyBindings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2472,15 +2475,17 @@ static void prim_mapAttrs(EvalState & state, const Pos & pos, Value * * args, Va
|
||||||
{
|
{
|
||||||
state.forceAttrs(*args[1], pos);
|
state.forceAttrs(*args[1], pos);
|
||||||
|
|
||||||
state.mkAttrs(v, args[1]->attrs->size());
|
auto attrs = state.buildBindings(args[1]->attrs->size());
|
||||||
|
|
||||||
for (auto & i : *args[1]->attrs) {
|
for (auto & i : *args[1]->attrs) {
|
||||||
Value * vName = state.allocValue();
|
Value * vName = state.allocValue();
|
||||||
Value * vFun2 = state.allocValue();
|
Value * vFun2 = state.allocValue();
|
||||||
vName->mkString(i.name);
|
vName->mkString(i.name);
|
||||||
vFun2->mkApp(args[0], vName);
|
vFun2->mkApp(args[0], vName);
|
||||||
state.allocAttr(v, i.name)->mkApp(vFun2, i.value);
|
attrs.alloc(i.name).mkApp(vFun2, i.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.mkAttrs(attrs.alreadySorted());
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_mapAttrs({
|
static RegisterPrimOp primop_mapAttrs({
|
||||||
|
@ -2526,12 +2531,13 @@ static void prim_zipAttrsWith(EvalState & state, const Pos & pos, Value * * args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.mkAttrs(v, attrsSeen.size());
|
auto attrs = state.buildBindings(attrsSeen.size());
|
||||||
for (auto & [sym, elem] : attrsSeen) {
|
for (auto & [sym, elem] : attrsSeen) {
|
||||||
Value * list = state.allocAttr(v, sym);
|
auto & list = attrs.alloc(sym);
|
||||||
state.mkList(*list, elem.first);
|
state.mkList(list, elem.first);
|
||||||
elem.second = list->listElems();
|
elem.second = list.listElems();
|
||||||
}
|
}
|
||||||
|
v.mkAttrs(attrs.alreadySorted());
|
||||||
|
|
||||||
for (unsigned int n = 0; n < listSize; ++n) {
|
for (unsigned int n = 0; n < listSize; ++n) {
|
||||||
Value * vElem = listElems[n];
|
Value * vElem = listElems[n];
|
||||||
|
@ -3054,14 +3060,16 @@ static void prim_groupBy(EvalState & state, const Pos & pos, Value * * args, Val
|
||||||
vector->second.push_back(vElem);
|
vector->second.push_back(vElem);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.mkAttrs(v, attrs.size());
|
auto attrs2 = state.buildBindings(attrs.size());
|
||||||
|
|
||||||
for (auto & i : attrs) {
|
for (auto & i : attrs) {
|
||||||
Value * list = state.allocAttr(v, i.first);
|
auto & list = attrs2.alloc(i.first);
|
||||||
auto size = i.second.size();
|
auto size = i.second.size();
|
||||||
state.mkList(*list, size);
|
state.mkList(list, size);
|
||||||
memcpy(list->listElems(), i.second.data(), sizeof(Value *) * size);
|
memcpy(list.listElems(), i.second.data(), sizeof(Value *) * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.mkAttrs(attrs2.alreadySorted());
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterPrimOp primop_groupBy({
|
static RegisterPrimOp primop_groupBy({
|
||||||
|
@ -3829,7 +3837,7 @@ void EvalState::createBaseEnv()
|
||||||
Value v;
|
Value v;
|
||||||
|
|
||||||
/* `builtins' must be first! */
|
/* `builtins' must be first! */
|
||||||
mkAttrs(v, 128);
|
v.mkAttrs(buildBindings(128).finish());
|
||||||
addConstant("builtins", v);
|
addConstant("builtins", v);
|
||||||
|
|
||||||
v.mkBool(true);
|
v.mkBool(true);
|
||||||
|
|
Loading…
Reference in a new issue