about summary refs log tree commit diff
path: root/src/libexpr/eval-inline.hh
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-02-04T13·50+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-02-04T13·50+0000
commitf491ae97d472bfd6305a8f3e8c58fac1fdc443a4 (patch)
treee78fed9caf2450915214144f20dd976202d7d1a3 /src/libexpr/eval-inline.hh
parent2bda12ef3b2b1d9a0fc59324d723e3fa883ab223 (diff)
* Inline some functions and get rid of the indirection through
  EvalState::eval().  This gives a 12% speedup on ‘nix-instantiate
  /etc/nixos/nixos/ -A system --readonly-mode’ (from 1.01s to 0.89s).

Diffstat (limited to 'src/libexpr/eval-inline.hh')
-rw-r--r--src/libexpr/eval-inline.hh61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh
new file mode 100644
index 0000000000..6026a7d110
--- /dev/null
+++ b/src/libexpr/eval-inline.hh
@@ -0,0 +1,61 @@
+#ifndef __EVAL_INLINE_H
+#define __EVAL_INLINE_H
+
+#include "eval.hh"
+
+#define LocalNoInline(f) static f __attribute__((noinline)); f
+#define LocalNoInlineNoReturn(f) static f __attribute__((noinline, noreturn)); f
+
+namespace nix {
+
+
+LocalNoInlineNoReturn(void throwEvalError(const char * s))
+{
+    throw EvalError(s);
+}
+
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const string & s2))
+{
+    throw TypeError(format(s) % s2);
+}
+
+
+void EvalState::forceValue(Value & v)
+{
+    if (v.type == tThunk) {
+        ValueType saved = v.type;
+        try {
+            v.type = tBlackhole;
+            //checkInterrupt();
+            v.thunk.expr->eval(*this, *v.thunk.env, v);
+        } catch (Error & e) {
+            v.type = saved;
+            throw;
+        }
+    }
+    else if (v.type == tApp)
+        callFunction(*v.app.left, *v.app.right, v);
+    else if (v.type == tBlackhole)
+        throwEvalError("infinite recursion encountered");
+}
+
+
+inline void EvalState::forceAttrs(Value & v)
+{
+    forceValue(v);
+    if (v.type != tAttrs)
+        throwTypeError("value is %1% while an attribute set was expected", showType(v));
+}
+
+
+inline void EvalState::forceList(Value & v)
+{
+    forceValue(v);
+    if (v.type != tList)
+        throwTypeError("value is %1% while a list was expected", showType(v));
+}
+
+
+}
+
+#endif /* !__EVAL_INLINE_H */