about summary refs log tree commit diff
path: root/third_party/nix/src/libexpr/eval-inline.hh
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2020-05-17T14·52+0100
committerVincent Ambo <tazjin@google.com>2020-05-17T14·52+0100
commit7994fd1d545cc5c876d6f21db7ddf9185d23dad6 (patch)
tree32dd695785378c5b9c8be97fc583e9dfc62cb105 /third_party/nix/src/libexpr/eval-inline.hh
parentcf8cd640c1adf74a3706efbcb0ea4625da106fb2 (diff)
parent90b3b31dc27f31e9b11653a636025d29ddb087a3 (diff)
Add 'third_party/nix/' from commit 'be66c7a6b24e3c3c6157fd37b86c7203d14acf10' r/724
git-subtree-dir: third_party/nix
git-subtree-mainline: cf8cd640c1adf74a3706efbcb0ea4625da106fb2
git-subtree-split: be66c7a6b24e3c3c6157fd37b86c7203d14acf10
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 000000000000..c27116e3b448
--- /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;
+}
+
+
+}