aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/attr-set.cc59
-rw-r--r--src/libexpr/attr-set.hh82
-rw-r--r--src/libexpr/eval.cc30
-rw-r--r--src/libexpr/eval.hh65
4 files changed, 142 insertions, 94 deletions
diff --git a/src/libexpr/attr-set.cc b/src/libexpr/attr-set.cc
new file mode 100644
index 000000000..9ac5e6031
--- /dev/null
+++ b/src/libexpr/attr-set.cc
@@ -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());
+}
+
+
+}
diff --git a/src/libexpr/attr-set.hh b/src/libexpr/attr-set.hh
new file mode 100644
index 000000000..7cf6a9c58
--- /dev/null
+++ b/src/libexpr/attr-set.hh
@@ -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;
+};
+
+
+}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2dc7b17f6..044256112 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -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)
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 627fae3ff..1b546f89c 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -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);