From 9fe24c5a0d1e694c6338d584a101034cfbff10bf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 7 Jan 2012 17:26:33 +0000 Subject: * Don't create thunks for simple constants (integers, strings, paths) and allocate them only once. * Move Value and related functions into value.hh. --- src/libexpr/value.hh | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/libexpr/value.hh (limited to 'src/libexpr/value.hh') diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh new file mode 100644 index 000000000000..41512d40b1e0 --- /dev/null +++ b/src/libexpr/value.hh @@ -0,0 +1,155 @@ +#ifndef __VALUE_H +#define __VALUE_H + +#include "symbol-table.hh" + +namespace nix { + + +typedef enum { + tInt = 1, + tBool, + tString, + tPath, + tNull, + tAttrs, + tList, + tThunk, + tApp, + tLambda, + tBlackhole, + tPrimOp, + tPrimOpApp, +} ValueType; + + +struct Bindings; +struct Env; +struct Expr; +struct ExprLambda; +struct PrimOp; +struct PrimOp; +struct Symbol; + + +struct Value +{ + ValueType type; + union + { + int integer; + bool boolean; + + /* Strings in the evaluator carry a so-called `context' (the + ATermList) which is a list of strings representing store + paths. This is to allow users to write things like + + "--with-freetype2-library=" + freetype + "/lib" + + where `freetype' is a derivation (or a source to be copied + to the store). If we just concatenated the strings without + keeping track of the referenced store paths, then if the + string is used as a derivation attribute, the derivation + will not have the correct dependencies in its inputDrvs and + inputSrcs. + + The semantics of the context is as follows: when a string + with context C is used as a derivation attribute, then the + derivations in C will be added to the inputDrvs of the + derivation, and the other store paths in C will be added to + the inputSrcs of the derivations. + + For canonicity, the store paths should be in sorted order. */ + struct { + const char * s; + const char * * context; // must be in sorted order + } string; + + const char * path; + Bindings * attrs; + struct { + unsigned int length; + Value * * elems; + } list; + struct { + Env * env; + Expr * expr; + } thunk; + struct { + Value * left, * right; + } app; + struct { + Env * env; + ExprLambda * fun; + } lambda; + PrimOp * primOp; + struct { + Value * left, * right; + } primOpApp; + }; +}; + + +/* After overwriting an app node, be sure to clear pointers in the + Value to ensure that the target isn't kept alive unnecessarily. */ +static inline void clearValue(Value & v) +{ + v.app.right = 0; +} + + +static inline void mkInt(Value & v, int n) +{ + clearValue(v); + v.type = tInt; + v.integer = n; +} + + +static inline void mkBool(Value & v, bool b) +{ + clearValue(v); + v.type = tBool; + v.boolean = b; +} + + +static inline void mkApp(Value & v, Value & left, Value & right) +{ + v.type = tApp; + v.app.left = &left; + v.app.right = &right; +} + + +static inline void mkStringNoCopy(Value & v, const char * s) +{ + v.type = tString; + v.string.s = s; + v.string.context = 0; +} + + +static inline void mkString(Value & v, const Symbol & s) +{ + mkStringNoCopy(v, ((string) s).c_str()); +} + + +void mkString(Value & v, const char * s); + + +static inline void mkPathNoCopy(Value & v, const char * s) +{ + clearValue(v); + v.type = tPath; + v.path = s; +} + + +void mkPath(Value & v, const char * s); + + +} + +#endif /* !__VALUE_H */ -- cgit 1.4.1