lix/src/libexpr/eval-inline.hh

96 lines
2.1 KiB
C++
Raw Normal View History

#pragma once
#include "eval.hh"
#define LocalNoInline(f) static f __attribute__((noinline)); f
#define LocalNoInlineNoReturn(f) static f __attribute__((noinline, noreturn)); f
namespace nix {
2015-07-31 18:28:25 +00:00
LocalNoInlineNoReturn(void throwEvalError(const char * s, const Pos & pos))
{
throw EvalError(s, pos);
}
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
{
throw TypeError(s, showType(v));
}
2014-04-04 17:05:36 +00:00
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, const Pos & pos))
{
throw TypeError(s, showType(v), pos);
2014-04-04 17:05:36 +00:00
}
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)
2015-07-31 18:28:25 +00:00
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);
}
2014-04-04 17:11:40 +00:00
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);
}
2014-04-04 17:05:36 +00:00
inline void EvalState::forceList(Value & v, const Pos & pos)
{
forceValue(v);
if (!v.isList())
2014-04-04 17:05:36 +00:00
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;
}
}