forked from lix-project/lix
make throw*Error member functions of EvalState
when we introduce position and symbol tables we'll need to do lookups to turn indices into those tables into actual positions/symbols. having the error functions as members of EvalState will avoid a lot of churn for adding lookups into the tables for each caller.
This commit is contained in:
parent
39df15fb8e
commit
34b72775cf
|
@ -2,27 +2,8 @@
|
||||||
|
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
|
|
||||||
#define LocalNoInline(f) static f __attribute__((noinline)); f
|
|
||||||
#define LocalNoInlineNoReturn(f) static f __attribute__((noinline, noreturn)); f
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s))
|
|
||||||
{
|
|
||||||
throw EvalError({
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v))
|
|
||||||
{
|
|
||||||
throw TypeError({
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = pos
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Note: Various places expect the allocated memory to be zeroed. */
|
/* Note: Various places expect the allocated memory to be zeroed. */
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
|
|
|
@ -714,12 +714,30 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
|
||||||
evaluator. So here are some helper functions for throwing
|
evaluator. So here are some helper functions for throwing
|
||||||
exceptions. */
|
exceptions. */
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2))
|
void EvalState::throwEvalError(const Pos & pos, const char * s) const
|
||||||
|
{
|
||||||
|
throw EvalError({
|
||||||
|
.msg = hintfmt(s),
|
||||||
|
.errPos = pos
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvalState::throwTypeError(const Pos & pos, const char * s, const Value & v) const
|
||||||
|
{
|
||||||
|
throw TypeError({
|
||||||
|
.msg = hintfmt(s, showType(v)),
|
||||||
|
.errPos = pos
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EvalState::throwEvalError(const char * s, const std::string & s2) const
|
||||||
{
|
{
|
||||||
throw EvalError(s, s2);
|
throw EvalError(s, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s, const std::string & s2))
|
void EvalState::throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s,
|
||||||
|
const std::string & s2) const
|
||||||
{
|
{
|
||||||
throw EvalError(ErrorInfo {
|
throw EvalError(ErrorInfo {
|
||||||
.msg = hintfmt(s, s2),
|
.msg = hintfmt(s, s2),
|
||||||
|
@ -728,7 +746,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & s
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const std::string & s2))
|
void EvalState::throwEvalError(const Pos & pos, const char * s, const std::string & s2) const
|
||||||
{
|
{
|
||||||
throw EvalError(ErrorInfo {
|
throw EvalError(ErrorInfo {
|
||||||
.msg = hintfmt(s, s2),
|
.msg = hintfmt(s, s2),
|
||||||
|
@ -736,12 +754,13 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2, const std::string & s3))
|
void EvalState::throwEvalError(const char * s, const std::string & s2, const std::string & s3) const
|
||||||
{
|
{
|
||||||
throw EvalError(s, s2, s3);
|
throw EvalError(s, s2, s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const std::string & s2, const std::string & s3))
|
void EvalState::throwEvalError(const Pos & pos, const char * s, const std::string & s2,
|
||||||
|
const std::string & s3) const
|
||||||
{
|
{
|
||||||
throw EvalError({
|
throw EvalError({
|
||||||
.msg = hintfmt(s, s2, s3),
|
.msg = hintfmt(s, s2, s3),
|
||||||
|
@ -749,7 +768,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2))
|
void EvalState::throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2) const
|
||||||
{
|
{
|
||||||
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
||||||
throw EvalError({
|
throw EvalError({
|
||||||
|
@ -758,7 +777,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s))
|
void EvalState::throwTypeError(const Pos & pos, const char * s) const
|
||||||
{
|
{
|
||||||
throw TypeError({
|
throw TypeError({
|
||||||
.msg = hintfmt(s),
|
.msg = hintfmt(s),
|
||||||
|
@ -766,7 +785,8 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2))
|
void EvalState::throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun,
|
||||||
|
const Symbol & s2) const
|
||||||
{
|
{
|
||||||
throw TypeError({
|
throw TypeError({
|
||||||
.msg = hintfmt(s, fun.showNamePos(), s2),
|
.msg = hintfmt(s, fun.showNamePos(), s2),
|
||||||
|
@ -774,7 +794,8 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol & s2))
|
void EvalState::throwTypeError(const Pos & pos, const Suggestions & suggestions, const char * s,
|
||||||
|
const ExprLambda & fun, const Symbol & s2) const
|
||||||
{
|
{
|
||||||
throw TypeError(ErrorInfo {
|
throw TypeError(ErrorInfo {
|
||||||
.msg = hintfmt(s, fun.showNamePos(), s2),
|
.msg = hintfmt(s, fun.showNamePos(), s2),
|
||||||
|
@ -784,12 +805,12 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const Suggestions & s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v))
|
void EvalState::throwTypeError(const char * s, const Value & v) const
|
||||||
{
|
{
|
||||||
throw TypeError(s, showType(v));
|
throw TypeError(s, showType(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const std::string & s1))
|
void EvalState::throwAssertionError(const Pos & pos, const char * s, const std::string & s1) const
|
||||||
{
|
{
|
||||||
throw AssertionError({
|
throw AssertionError({
|
||||||
.msg = hintfmt(s, s1),
|
.msg = hintfmt(s, s1),
|
||||||
|
@ -797,7 +818,7 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const std::string & s1))
|
void EvalState::throwUndefinedVarError(const Pos & pos, const char * s, const std::string & s1) const
|
||||||
{
|
{
|
||||||
throw UndefinedVarError({
|
throw UndefinedVarError({
|
||||||
.msg = hintfmt(s, s1),
|
.msg = hintfmt(s, s1),
|
||||||
|
@ -805,7 +826,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char *
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const std::string & s1))
|
void EvalState::throwMissingArgumentError(const Pos & pos, const char * s, const std::string & s1) const
|
||||||
{
|
{
|
||||||
throw MissingArgumentError({
|
throw MissingArgumentError({
|
||||||
.msg = hintfmt(s, s1),
|
.msg = hintfmt(s, s1),
|
||||||
|
@ -813,12 +834,12 @@ LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInline(void addErrorTrace(Error & e, const char * s, const std::string & s2))
|
void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2) const
|
||||||
{
|
{
|
||||||
e.addTrace(std::nullopt, s, s2);
|
e.addTrace(std::nullopt, s, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, const std::string & s2))
|
void EvalState::addErrorTrace(Error & e, const Pos & pos, const char * s, const std::string & s2) const
|
||||||
{
|
{
|
||||||
e.addTrace(pos, s, s2);
|
e.addTrace(pos, s, s2);
|
||||||
}
|
}
|
||||||
|
@ -1169,7 +1190,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
Symbol nameSym = state.symbols.create(nameVal.string.s);
|
||||||
Bindings::iterator j = v.attrs->find(nameSym);
|
Bindings::iterator j = v.attrs->find(nameSym);
|
||||||
if (j != v.attrs->end())
|
if (j != v.attrs->end())
|
||||||
throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos);
|
state.throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos);
|
||||||
|
|
||||||
i.valueExpr->setName(nameSym);
|
i.valueExpr->setName(nameSym);
|
||||||
/* Keep sorted order so find can catch duplicates */
|
/* Keep sorted order so find can catch duplicates */
|
||||||
|
@ -1260,7 +1281,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
std::set<std::string> allAttrNames;
|
std::set<std::string> allAttrNames;
|
||||||
for (auto & attr : *vAttrs->attrs)
|
for (auto & attr : *vAttrs->attrs)
|
||||||
allAttrNames.insert(attr.name);
|
allAttrNames.insert(attr.name);
|
||||||
throwEvalError(
|
state.throwEvalError(
|
||||||
pos,
|
pos,
|
||||||
Suggestions::bestMatches(allAttrNames, name),
|
Suggestions::bestMatches(allAttrNames, name),
|
||||||
"attribute '%1%' missing", name);
|
"attribute '%1%' missing", name);
|
||||||
|
@ -1275,7 +1296,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
if (*pos2 != noPos && pos2->file != state.sDerivationNix)
|
if (*pos2 != noPos && pos2->file != state.sDerivationNix)
|
||||||
addErrorTrace(e, *pos2, "while evaluating the attribute '%1%'",
|
state.addErrorTrace(e, *pos2, "while evaluating the attribute '%1%'",
|
||||||
showAttrPath(state, env, attrPath));
|
showAttrPath(state, env, attrPath));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -1587,7 +1608,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||||
if (!state.evalBool(env, cond, pos)) {
|
if (!state.evalBool(env, cond, pos)) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
cond->show(out);
|
cond->show(out);
|
||||||
throwAssertionError(pos, "assertion '%1%' failed", out.str());
|
state.throwAssertionError(pos, "assertion '%1%' failed", out.str());
|
||||||
}
|
}
|
||||||
body->eval(state, env, v);
|
body->eval(state, env, v);
|
||||||
}
|
}
|
||||||
|
@ -1764,14 +1785,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
nf = n;
|
nf = n;
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp));
|
state.throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp));
|
||||||
} else if (firstType == nFloat) {
|
} else if (firstType == nFloat) {
|
||||||
if (vTmp.type() == nInt) {
|
if (vTmp.type() == nInt) {
|
||||||
nf += vTmp.integer;
|
nf += vTmp.integer;
|
||||||
} else if (vTmp.type() == nFloat) {
|
} else if (vTmp.type() == nFloat) {
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp));
|
state.throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp));
|
||||||
} else {
|
} else {
|
||||||
if (s.empty()) s.reserve(es->size());
|
if (s.empty()) s.reserve(es->size());
|
||||||
/* skip canonization of first path, which would only be not
|
/* skip canonization of first path, which would only be not
|
||||||
|
@ -1791,7 +1812,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
v.mkFloat(nf);
|
v.mkFloat(nf);
|
||||||
else if (firstType == nPath) {
|
else if (firstType == nPath) {
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path");
|
||||||
v.mkPath(canonPath(str()));
|
v.mkPath(canonPath(str()));
|
||||||
} else
|
} else
|
||||||
v.mkStringMove(c_str(), context);
|
v.mkStringMove(c_str(), context);
|
||||||
|
|
|
@ -249,6 +249,45 @@ public:
|
||||||
std::string_view forceString(Value & v, PathSet & context, const Pos & pos = noPos);
|
std::string_view forceString(Value & v, PathSet & context, const Pos & pos = noPos);
|
||||||
std::string_view forceStringNoCtx(Value & v, const Pos & pos = noPos);
|
std::string_view forceStringNoCtx(Value & v, const Pos & pos = noPos);
|
||||||
|
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const Pos & pos, const char * s) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwTypeError(const Pos & pos, const char * s, const Value & v) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const char * s, const std::string & s2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s,
|
||||||
|
const std::string & s2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const Pos & pos, const char * s, const std::string & s2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const char * s, const std::string & s2, const std::string & s3) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const Pos & pos, const char * s, const std::string & s2, const std::string & s3) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwTypeError(const Pos & pos, const char * s) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwTypeError(const Pos & pos, const Suggestions & suggestions, const char * s,
|
||||||
|
const ExprLambda & fun, const Symbol & s2) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwTypeError(const char * s, const Value & v) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwAssertionError(const Pos & pos, const char * s, const std::string & s1) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwUndefinedVarError(const Pos & pos, const char * s, const std::string & s1) const;
|
||||||
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
|
void throwMissingArgumentError(const Pos & pos, const char * s, const std::string & s1) const;
|
||||||
|
|
||||||
|
[[gnu::noinline]]
|
||||||
|
void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
|
||||||
|
[[gnu::noinline]]
|
||||||
|
void addErrorTrace(Error & e, const Pos & pos, const char * s, const std::string & s2) const;
|
||||||
|
|
||||||
|
public:
|
||||||
/* Return true iff the value `v' denotes a derivation (i.e. a
|
/* Return true iff the value `v' denotes a derivation (i.e. a
|
||||||
set with attribute `type = "derivation"'). */
|
set with attribute `type = "derivation"'). */
|
||||||
bool isDerivation(Value & v);
|
bool isDerivation(Value & v);
|
||||||
|
|
Loading…
Reference in a new issue