Move attribute set data structures into their own header file.
This modification moves Attr and Bindings structures into their own header file which is dedicated to the attribute set representation. The goal of to isolate pieces of code which are related to the attribute set representation. Thus future modifications of the attribute set representation will only have to modify these files, and not every other file across the evaluator.
This commit is contained in:
		
							parent
							
								
									467977f203
								
							
						
					
					
						commit
						db21cfa688
					
				
					 4 changed files with 142 additions and 94 deletions
				
			
		
							
								
								
									
										59
									
								
								src/libexpr/attr-set.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/libexpr/attr-set.cc
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										82
									
								
								src/libexpr/attr-set.hh
									
										
									
									
									
										Normal 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; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -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) | ||||
| { | ||||
|     if (active.find(&v) != active.end()) { | ||||
|  | @ -503,20 +497,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 length) | ||||
| { | ||||
|     clearValue(v); | ||||
|  | @ -527,16 +507,6 @@ void EvalState::mkList(Value & v, unsigned int length) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| 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) | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue