Merge branch 'attr-set-hh' of https://github.com/nbp/nix

Conflicts:
	src/libexpr/eval.cc
This commit is contained in:
Eelco Dolstra 2015-07-23 22:16:01 +02:00
commit 19eddecc0f
4 changed files with 142 additions and 94 deletions

59
src/libexpr/attr-set.cc Normal file
View file

@ -0,0 +1,59 @@
#include "attr-set.hh"
#include "eval.hh"
#include <algorithm>
namespace nix {
static void * allocBytes(size_t n)
{
void * p;
#if HAVE_BOEHMGC
p = GC_malloc(n);
#else
p = malloc(n);
#endif
if (!p) throw std::bad_alloc();
return p;
}
/* Allocate a new array of attributes for an attribute set with a specific
capacity. The space is implicitly reserved after the Bindings
structure. */
Bindings * EvalState::allocBindings(Bindings::size_t capacity)
{
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings(capacity);
}
void EvalState::mkAttrs(Value & v, unsigned int expected)
{
clearValue(v);
v.type = tAttrs;
v.attrs = allocBindings(expected);
nrAttrsets++;
nrAttrsInAttrsets += expected;
}
/* Create a new attribute named 'name' on an existing attribute set stored
in 'vAttrs' and return the newly allocated Value which is associated with
this attribute. */
Value * EvalState::allocAttr(Value & vAttrs, const Symbol & name)
{
Value * v = allocValue();
vAttrs.attrs->push_back(Attr(name, v));
return v;
}
void Bindings::sort()
{
std::sort(begin(), end());
}
}

82
src/libexpr/attr-set.hh Normal file
View file

@ -0,0 +1,82 @@
#pragma once
#include "nixexpr.hh"
#include "symbol-table.hh"
#include <algorithm>
namespace nix {
class EvalState;
struct Value;
/* Map one attribute name to its value. */
struct Attr
{
Symbol name;
Value * value;
Pos * pos;
Attr(Symbol name, Value * value, Pos * pos = &noPos)
: name(name), value(value), pos(pos) { };
Attr() : pos(&noPos) { };
bool operator < (const Attr & a) const
{
return name < a.name;
}
};
/* Bindings contains all the attributes of an attribute set. It is defined
by its size and its capacity, the capacity being the number of Attr
elements allocated after this structure, while the size corresponds to
the number of elements already inserted in this structure. */
class Bindings
{
public:
typedef uint32_t size_t;
private:
size_t size_, capacity_;
Attr attrs[0];
Bindings(size_t capacity) : size_(0), capacity_(capacity) { }
Bindings(const Bindings & bindings) = delete;
public:
size_t size() const { return size_; }
bool empty() const { return !size_; }
typedef Attr * iterator;
void push_back(const Attr & attr)
{
assert(size_ < capacity_);
attrs[size_++] = attr;
}
iterator find(const Symbol & name)
{
Attr key(name, 0);
iterator i = std::lower_bound(begin(), end(), key);
if (i != end() && i->name == name) return i;
return end();
}
iterator begin() { return &attrs[0]; }
iterator end() { return &attrs[size_]; }
Attr & operator[](size_t pos)
{
return attrs[pos];
}
void sort();
size_t capacity() { return capacity_; }
friend class EvalState;
};
}

View file

@ -55,12 +55,6 @@ static void * allocBytes(size_t n)
}
void Bindings::sort()
{
std::sort(begin(), end());
}
static void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v)
{
checkInterrupt();
@ -507,20 +501,6 @@ Env & EvalState::allocEnv(unsigned int size)
}
Value * EvalState::allocAttr(Value & vAttrs, const Symbol & name)
{
Value * v = allocValue();
vAttrs.attrs->push_back(Attr(name, v));
return v;
}
Bindings * EvalState::allocBindings(Bindings::size_t capacity)
{
return new (allocBytes(sizeof(Bindings) + sizeof(Attr) * capacity)) Bindings(capacity);
}
void EvalState::mkList(Value & v, unsigned int size)
{
clearValue(v);
@ -537,16 +517,6 @@ void EvalState::mkList(Value & v, unsigned int size)
}
void EvalState::mkAttrs(Value & v, unsigned int expected)
{
clearValue(v);
v.type = tAttrs;
v.attrs = allocBindings(expected);
nrAttrsets++;
nrAttrsInAttrsets += expected;
}
unsigned long nrThunks = 0;
static inline void mkThunk(Value & v, Env & env, Expr * expr)

View file

@ -1,5 +1,6 @@
#pragma once
#include "attr-set.hh"
#include "value.hh"
#include "nixexpr.hh"
#include "symbol-table.hh"
@ -18,70 +19,6 @@ namespace nix {
class EvalState;
struct Attr
{
Symbol name;
Value * value;
Pos * pos;
Attr(Symbol name, Value * value, Pos * pos = &noPos)
: name(name), value(value), pos(pos) { };
Attr() : pos(&noPos) { };
bool operator < (const Attr & a) const
{
return name < a.name;
}
};
class Bindings
{
public:
typedef uint32_t size_t;
private:
size_t size_, capacity_;
Attr attrs[0];
Bindings(size_t capacity) : size_(0), capacity_(capacity) { }
Bindings(const Bindings & bindings) = delete;
public:
size_t size() const { return size_; }
bool empty() const { return !size_; }
typedef Attr * iterator;
void push_back(const Attr & attr)
{
assert(size_ < capacity_);
attrs[size_++] = attr;
}
iterator find(const Symbol & name)
{
Attr key(name, 0);
iterator i = std::lower_bound(begin(), end(), key);
if (i != end() && i->name == name) return i;
return end();
}
iterator begin() { return &attrs[0]; }
iterator end() { return &attrs[size_]; }
Attr & operator[](size_t pos)
{
return attrs[pos];
}
void sort();
size_t capacity() { return capacity_; }
friend class EvalState;
};
typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v);