Make Env self-describing
If the Env denotes a 'with', then values[0] may be an Expr* cast to a Value*. For code that generically traverses Values/Envs, it's useful to know this.
This commit is contained in:
		
							parent
							
								
									9fd7cf98db
								
							
						
					
					
						commit
						4bb8741b98
					
				
					 2 changed files with 12 additions and 8 deletions
				
			
		|  | @ -307,6 +307,8 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store) | ||||||
| 
 | 
 | ||||||
|     assert(gcInitialised); |     assert(gcInitialised); | ||||||
| 
 | 
 | ||||||
|  |     static_assert(sizeof(Env) == 16); | ||||||
|  | 
 | ||||||
|     /* Initialise the Nix expression search path. */ |     /* Initialise the Nix expression search path. */ | ||||||
|     if (!settings.pureEval) { |     if (!settings.pureEval) { | ||||||
|         Strings paths = parseNixPath(getEnv("NIX_PATH", "")); |         Strings paths = parseNixPath(getEnv("NIX_PATH", "")); | ||||||
|  | @ -568,12 +570,12 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) | ||||||
|     if (!var.fromWith) return env->values[var.displ]; |     if (!var.fromWith) return env->values[var.displ]; | ||||||
| 
 | 
 | ||||||
|     while (1) { |     while (1) { | ||||||
|         if (!env->haveWithAttrs) { |         if (env->type == Env::HasWithExpr) { | ||||||
|             if (noEval) return 0; |             if (noEval) return 0; | ||||||
|             Value * v = allocValue(); |             Value * v = allocValue(); | ||||||
|             evalAttrs(*env->up, (Expr *) env->values[0], *v); |             evalAttrs(*env->up, (Expr *) env->values[0], *v); | ||||||
|             env->values[0] = v; |             env->values[0] = v; | ||||||
|             env->haveWithAttrs = true; |             env->type = Env::HasWithAttrs; | ||||||
|         } |         } | ||||||
|         Bindings::iterator j = env->values[0]->attrs->find(var.name); |         Bindings::iterator j = env->values[0]->attrs->find(var.name); | ||||||
|         if (j != env->values[0]->attrs->end()) { |         if (j != env->values[0]->attrs->end()) { | ||||||
|  | @ -603,6 +605,7 @@ Env & EvalState::allocEnv(size_t size) | ||||||
|     nrValuesInEnvs += size; |     nrValuesInEnvs += size; | ||||||
|     Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); |     Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); | ||||||
|     env->size = (decltype(Env::size)) size; |     env->size = (decltype(Env::size)) size; | ||||||
|  |     env->type = Env::Plain; | ||||||
| 
 | 
 | ||||||
|     /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ |     /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ | ||||||
| 
 | 
 | ||||||
|  | @ -1205,7 +1208,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) | ||||||
|     Env & env2(state.allocEnv(1)); |     Env & env2(state.allocEnv(1)); | ||||||
|     env2.up = &env; |     env2.up = &env; | ||||||
|     env2.prevWith = prevWith; |     env2.prevWith = prevWith; | ||||||
|     env2.haveWithAttrs = false; |     env2.type = Env::HasWithExpr; | ||||||
|     env2.values[0] = (Value *) attrs; |     env2.values[0] = (Value *) attrs; | ||||||
| 
 | 
 | ||||||
|     body->eval(state, env2, v); |     body->eval(state, env2, v); | ||||||
|  | @ -1863,6 +1866,7 @@ size_t valueSize(Value & v) | ||||||
| 
 | 
 | ||||||
|         size_t sz = sizeof(Env) + sizeof(Value *) * env.size; |         size_t sz = sizeof(Env) + sizeof(Value *) * env.size; | ||||||
| 
 | 
 | ||||||
|  |         if (env.type != Env::HasWithExpr) | ||||||
|             for (size_t i = 0; i < env.size; ++i) |             for (size_t i = 0; i < env.size; ++i) | ||||||
|                 if (env.values[i]) |                 if (env.values[i]) | ||||||
|                     sz += doValue(*env.values[i]); |                     sz += doValue(*env.values[i]); | ||||||
|  |  | ||||||
|  | @ -35,8 +35,8 @@ struct Env | ||||||
| { | { | ||||||
|     Env * up; |     Env * up; | ||||||
|     unsigned short size; // used by ‘valueSize’
 |     unsigned short size; // used by ‘valueSize’
 | ||||||
|     unsigned short prevWith:15; // nr of levels up to next `with' environment
 |     unsigned short prevWith:14; // nr of levels up to next `with' environment
 | ||||||
|     unsigned short haveWithAttrs:1; |     enum { Plain = 0, HasWithExpr, HasWithAttrs } type:2; | ||||||
|     Value * values[0]; |     Value * values[0]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue