throwEvalError; mapBindings

This commit is contained in:
Ben Burdette 2021-05-13 16:00:48 -06:00
parent 459bccc750
commit ab19d1685d

View file

@ -617,7 +617,13 @@ std::optional<EvalState::Doc> EvalState::getDoc(Value & v)
} }
// typedef std::optional<const std::map<std::string, Value *>> valmap; // typedef std::optional<const std::map<std::string, Value *>> valmap;
typedef const std::map<std::string, Value *> valmap; typedef std::map<std::string, Value *> valmap;
static valmap * map0() __attribute__((noinline));
valmap * map0()
{
return new valmap();
}
static valmap * map1(const char *name, Value *v) __attribute__((noinline)); static valmap * map1(const char *name, Value *v) __attribute__((noinline));
valmap * map1(const char *name, Value *v) valmap * map1(const char *name, Value *v)
@ -633,22 +639,49 @@ valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2)
return new valmap({{name1, v1}, {name2, v2}}); return new valmap({{name1, v1}, {name2, v2}});
} }
static valmap * mapBindings(Bindings *b) __attribute__((noinline));
valmap * mapBindings(Bindings *b)
{
auto map = new valmap();
// auto v = new Value;
for (auto i = b->begin(); i != b->end(); ++i)
{
std::string s = i->name;
(*map)[s] = i->value;
// map->insert({std::string("wat"), v});
}
return map;
}
/* Every "format" object (even temporary) takes up a few hundred bytes /* Every "format" object (even temporary) takes up a few hundred bytes
of stack space, which is a real killer in the recursive of stack space, which is a real killer in the recursive
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 string & s2)) LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, valmap * env))
{ {
throw EvalError(s, s2); auto delenv = std::unique_ptr<valmap>(env);
auto error = EvalError(s, s2);
if (debuggerHook)
debuggerHook(error, *env);
throw error;
} }
LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2)) LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, valmap * env))
{ {
throw EvalError({ auto delenv = std::unique_ptr<valmap>(env);
auto error = EvalError({
.msg = hintfmt(s, s2), .msg = hintfmt(s, s2),
.errPos = pos .errPos = pos
}); });
if (debuggerHook)
debuggerHook(error, *env);
throw error;
} }
LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3)) LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3))
@ -1198,7 +1231,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
} else { } else {
state.forceAttrs(*vAttrs, pos); state.forceAttrs(*vAttrs, pos);
if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end())
throwEvalError(pos, "attribute '%1%' missing", name); throwEvalError(pos, "attribute '%1%' missing", name, mapBindings(vAttrs->attrs));
} }
vAttrs = j->value; vAttrs = j->value;
pos2 = j->pos; pos2 = j->pos;
@ -1651,14 +1684,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
nf = n; nf = n;
nf += vTmp.fpoint; nf += vTmp.fpoint;
} else } else
throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp)); throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), map0());
} 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(pos, "cannot add %1% to a float", showType(vTmp)); throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), map0());
} else } else
s << state.coerceToString(pos, vTmp, context, false, firstType == nString); s << state.coerceToString(pos, vTmp, context, false, firstType == nString);
} }
@ -1914,7 +1947,9 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context,
string EvalState::copyPathToStore(PathSet & context, const Path & path) string EvalState::copyPathToStore(PathSet & context, const Path & path)
{ {
if (nix::isDerivation(path)) if (nix::isDerivation(path))
throwEvalError("file names are not allowed to end in '%1%'", drvExtension); throwEvalError("file names are not allowed to end in '%1%'",
drvExtension,
map0());
Path dstPath; Path dstPath;
auto i = srcToStore.find(path); auto i = srcToStore.find(path);
@ -1938,7 +1973,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
{ {
string path = coerceToString(pos, v, context, false, false); string path = coerceToString(pos, v, context, false, false);
if (path == "" || path[0] != '/') if (path == "" || path[0] != '/')
throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path); throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, map1("value", &v));
return path; return path;
} }