about summary refs log tree commit diff
path: root/third_party/nix/src/libexpr/eval-inline.hh
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libexpr/eval-inline.hh')
-rw-r--r--third_party/nix/src/libexpr/eval-inline.hh95
1 files changed, 95 insertions, 0 deletions
diff --git a/third_party/nix/src/libexpr/eval-inline.hh b/third_party/nix/src/libexpr/eval-inline.hh
new file mode 100644
index 0000000000..c27116e3b4
--- /dev/null
+++ b/third_party/nix/src/libexpr/eval-inline.hh
@@ -0,0 +1,95 @@
+#pragma once
+
+#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, const Pos & pos))
+{
+    throw EvalError(format(s) % pos);
+}
+
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
+{
+    throw TypeError(format(s) % showType(v));
+}
+
+
+LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
+{
+    throw TypeError(format(s) % showType(v) % pos);
+}
+
+
+void EvalState::forceValue(Value & v, const Pos & pos)
+{
+    if (v.type == tThunk) {
+        Env * env = v.thunk.env;
+        Expr * expr = v.thunk.expr;
+        try {
+            v.type = tBlackhole;
+            //checkInterrupt();
+            expr->eval(*this, *env, v);
+        } catch (...) {
+            v.type = tThunk;
+            v.thunk.env = env;
+            v.thunk.expr = expr;
+            throw;
+        }
+    }
+    else if (v.type == tApp)
+        callFunction(*v.app.left, *v.app.right, v, noPos);
+    else if (v.type == tBlackhole)
+        throwEvalError("infinite recursion encountered, at %1%", pos);
+}
+
+
+inline void EvalState::forceAttrs(Value & v)
+{
+    forceValue(v);
+    if (v.type != tAttrs)
+        throwTypeError("value is %1% while a set was expected", v);
+}
+
+
+inline void EvalState::forceAttrs(Value & v, const Pos & pos)
+{
+    forceValue(v);
+    if (v.type != tAttrs)
+        throwTypeError("value is %1% while a set was expected, at %2%", v, pos);
+}
+
+
+inline void EvalState::forceList(Value & v)
+{
+    forceValue(v);
+    if (!v.isList())
+        throwTypeError("value is %1% while a list was expected", v);
+}
+
+
+inline void EvalState::forceList(Value & v, const Pos & pos)
+{
+    forceValue(v);
+    if (!v.isList())
+        throwTypeError("value is %1% while a list was expected, at %2%", v, pos);
+}
+
+/* Note: Various places expect the allocated memory to be zeroed. */
+inline void * allocBytes(size_t n)
+{
+    void * p;
+#if HAVE_BOEHMGC
+    p = GC_MALLOC(n);
+#else
+    p = calloc(n, 1);
+#endif
+    if (!p) throw std::bad_alloc();
+    return p;
+}
+
+
+}