From e5662ba6525c27248d57d8265e9c6c3a46f95c7e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 5 Aug 2020 21:26:17 +0200 Subject: Add a flag to start the REPL on evaluation errors This allows interactively inspecting the state of the evaluator at the point of failure. Example: $ nix eval path:///home/eelco/Dev/nix/flake2#modules.hello-closure._final --start-repl-on-eval-errors error: --- TypeError -------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix at: (20:53) in file: /nix/store/4264z41dxfdiqr95svmpnxxxwhfplhy0-source/flake.nix 19| 20| _final = builtins.foldl' (xs: mod: xs // (mod._module.config { config = _final; })) _defaults _allModules; | ^ 21| }; attempt to call something which is not a function but a set Starting REPL to allow you to inspect the current state of the evaluator. The following extra variables are in scope: arg, fun Welcome to Nix version 2.4. Type :? for help. nix-repl> fun error: --- EvalError -------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix at: (150:28) in file: /nix/store/4264z41dxfdiqr95svmpnxxxwhfplhy0-source/flake.nix 149| 150| tarballClosure = (module { | ^ 151| extends = [ self.modules.derivation ]; attribute 'derivation' missing nix-repl> :t fun a set nix-repl> builtins.attrNames fun [ "tarballClosure" ] nix-repl> --- src/libexpr/eval.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0123070d1..5d71e5466 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1171,6 +1171,8 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos) } } +std::function & env)> debuggerHook; + void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos) { auto trace = evalSettings.traceFunctionCalls ? std::make_unique(pos) : nullptr; @@ -1198,8 +1200,15 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po } } - if (fun.type != tLambda) - throwTypeError(pos, "attempt to call something which is not a function but %1%", fun); + if (fun.type != tLambda) { + auto error = TypeError({ + .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), + .errPos = pos + }); + if (debuggerHook) + debuggerHook(error, {{"fun", &fun}, {"arg", &arg}}); + throw error; + } ExprLambda & lambda(*fun.lambda.fun); -- cgit v1.2.3 From 57c2dd5d8581f37392df369493b00794b619304e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 28 Apr 2021 09:55:08 -0600 Subject: fixes --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index a92adc3c0..37fb6ed18 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1278,7 +1278,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po if (!fun.isLambda()) { auto error = TypeError({ // .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), - .hint = hintfmt("attempt to call something which is not a function but %1%", fun), + .msg = hintfmt("attempt to call something which is not a function but %1%", fun), .errPos = pos }); if (debuggerHook) -- cgit v1.2.3 From 2dd61411af903e374566e0cf5d06257ad240662e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 3 May 2021 14:37:33 -0600 Subject: debugger on autoCallFunction error --- src/libexpr/eval.cc | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 37fb6ed18..51feef923 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1398,12 +1398,28 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') + auto error = MissingArgumentError({ + .msg = hintfmt(R"(cannot evaluate a function that has an argument without a value ('%1%') Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See -https://nixos.org/manual/nix/stable/#ss-functions.)", i.name); +https://nixos.org/manual/nix/stable/#ss-functions.)", i.name), + .errPos = i.pos + }); + +// throwMissingArgumentError(i.pos +// , R"(cannot evaluate a function that has an argument without a value ('%1%') + +// Nix attempted to evaluate a function as a top level expression; in +// this case it must have its arguments supplied either by default +// values, or passed explicitly with '--arg' or '--argstr'. See +// https://nixos.org/manual/nix/stable/#ss-functions.)", i.name); + + if (debuggerHook) + debuggerHook(error, {{"fun", &fun}}); + + throw error; } } -- cgit v1.2.3 From a8fef9a6b10c34e450d4251f7e9808c906e2f488 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 10 May 2021 18:36:57 -0600 Subject: throwTypeError with debugger/env --- src/libexpr/eval.cc | 123 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 38 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 51feef923..a48c38e0d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -35,6 +36,7 @@ namespace nix { +std::function & env)> debuggerHook; static char * dupString(const char * s) { @@ -615,7 +617,6 @@ std::optional EvalState::getDoc(Value & v) return {}; } - /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing @@ -656,22 +657,46 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s)) +// #define valmap(x) std::optional> + +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const std::optional> & env)) { - throw TypeError({ + auto error = TypeError({ .msg = hintfmt(s), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, const std::optional> & env)) { - throw TypeError({ + auto error = TypeError({ + .msg = hintfmt(s, v), + .errPos = pos + }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; +} + +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, const std::optional> & env)) +{ + auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } + + LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1)) { throw AssertionError({ @@ -688,12 +713,16 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, const std::optional> & env)) { - throw MissingArgumentError({ + auto error = MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInline(void addErrorTrace(Error & e, const char * s, const string & s2)) @@ -1246,7 +1275,6 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos) } } -std::function & env)> debuggerHook; void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos) { @@ -1276,14 +1304,20 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po } if (!fun.isLambda()) { - auto error = TypeError({ - // .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), - .msg = hintfmt("attempt to call something which is not a function but %1%", fun), - .errPos = pos - }); - if (debuggerHook) - debuggerHook(error, {{"fun", &fun}, {"arg", &arg}}); - throw error; + throwTypeError( + pos, + "attempt to call something which is not a function but %1%", + fun, + std::optional>({{"fun", &fun}, {"arg", &arg}})); + + // auto error = TypeError({ + // // .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), + // .msg = hintfmt("attempt to call something which is not a function but %1%", fun), + // .errPos = pos + // }); + // if (debuggerHook) + // debuggerHook(error, {{"fun", &fun}, {"arg", &arg}}); + // throw error; } ExprLambda & lambda(*fun.lambda.fun); @@ -1312,8 +1346,13 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { - if (!i.def) throwTypeError(pos, "%1% called without required argument '%2%'", - lambda, i.name); + if (!i.def) + throwTypeError( + pos, + "%1% called without required argument '%2%'", + lambda, + i.name, + std::optional>({{"fun", &fun}, {"arg", &arg}})); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1328,7 +1367,11 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po user. */ for (auto & i : *arg.attrs) if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end()) - throwTypeError(pos, "%1% called with unexpected argument '%2%'", lambda, i.name); + throwTypeError(pos, + "%1% called with unexpected argument '%2%'", + lambda, + i.name, + std::optional>({{"fun", &fun}, {"arg", &arg}})); abort(); // can't happen } } @@ -1398,16 +1441,14 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - auto error = MissingArgumentError({ - .msg = hintfmt(R"(cannot evaluate a function that has an argument without a value ('%1%') + throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See -https://nixos.org/manual/nix/stable/#ss-functions.)", i.name), - .errPos = i.pos - }); - +https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, + std::optional>({{"fun", &fun}})); // todo add bindings. + // throwMissingArgumentError(i.pos // , R"(cannot evaluate a function that has an argument without a value ('%1%') @@ -1416,10 +1457,11 @@ https://nixos.org/manual/nix/stable/#ss-functions.)", i.name), // values, or passed explicitly with '--arg' or '--argstr'. See // https://nixos.org/manual/nix/stable/#ss-functions.)", i.name); - if (debuggerHook) - debuggerHook(error, {{"fun", &fun}}); + // if (debuggerHook) + // // debuggerHook(error, args); + // debuggerHook(error, {{"fun", &fun}}); - throw error; + // throw error; } } @@ -1673,7 +1715,8 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nInt) - throwTypeError(pos, "value is %1% while an integer was expected", v); + throwTypeError(pos, "value is %1% while an integer was expected", v, + std::optional>({{"value", &v}})); return v.integer; } @@ -1684,7 +1727,8 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) if (v.type() == nInt) return v.integer; else if (v.type() != nFloat) - throwTypeError(pos, "value is %1% while a float was expected", v); + throwTypeError(pos, "value is %1% while a float was expected", v, + std::optional>({{"value", &v}})); return v.fpoint; } @@ -1693,7 +1737,8 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v); + throwTypeError(pos, "value is %1% while a Boolean was expected", v, + std::optional>({{"value", &v}})); return v.boolean; } @@ -1708,7 +1753,8 @@ void EvalState::forceFunction(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) - throwTypeError(pos, "value is %1% while a function was expected", v); + throwTypeError(pos, "value is %1% while a function was expected", v, + std::optional>({{"value", &v}})); } @@ -1716,10 +1762,8 @@ string EvalState::forceString(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nString) { - if (pos) - throwTypeError(pos, "value is %1% while a string was expected", v); - else - throwTypeError("value is %1% while a string was expected", v); + throwTypeError(pos, "value is %1% while a string was expected", v, + std::optional>({{"value", &v}})); } return string(v.string.s); } @@ -1826,7 +1870,9 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, return *maybeString; } auto i = v.attrs->find(sOutPath); - if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string"); + if (i == v.attrs->end()) + throwTypeError(pos, "cannot coerce a set to a string", + std::optional>({{"value", &v}})); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -1857,7 +1903,8 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError(pos, "cannot coerce %1% to a string", v); + throwTypeError(pos, "cannot coerce %1% to a string", v, + std::optional>({{"value", &v}})); } -- cgit v1.2.3 From e7847ad7a1268bbe6962a36a29b044ee841f1874 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 11 May 2021 15:38:49 -0600 Subject: map1/2 for stack usage --- src/libexpr/eval.cc | 56 +++++++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 30 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index a48c38e0d..f8391cd77 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -617,6 +616,19 @@ std::optional EvalState::getDoc(Value & v) return {}; } +static std::optional> map1(const char *name, Value *v) __attribute__((noinline)); +std::optional> map1(const char *name, Value *v) +{ + return std::optional>({{name, v}}); +} + + +static std::optional> map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); +std::optional> map2(const char *name1, Value *v1, const char *name2, Value *v2) +{ + return std::optional>({{name1, v1},{name2, v2}}); +} + /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing @@ -657,8 +669,6 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); } -// #define valmap(x) std::optional> - LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const std::optional> & env)) { auto error = TypeError({ @@ -1308,7 +1318,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po pos, "attempt to call something which is not a function but %1%", fun, - std::optional>({{"fun", &fun}, {"arg", &arg}})); + map2("fun", &fun, "arg", &arg)); // auto error = TypeError({ // // .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), @@ -1352,7 +1362,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - std::optional>({{"fun", &fun}, {"arg", &arg}})); + map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1371,7 +1381,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called with unexpected argument '%2%'", lambda, i.name, - std::optional>({{"fun", &fun}, {"arg", &arg}})); + map2("fun", &fun, "arg", &arg)); abort(); // can't happen } } @@ -1446,23 +1456,9 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See -https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - std::optional>({{"fun", &fun}})); // todo add bindings. - -// throwMissingArgumentError(i.pos -// , R"(cannot evaluate a function that has an argument without a value ('%1%') - -// Nix attempted to evaluate a function as a top level expression; in -// this case it must have its arguments supplied either by default -// values, or passed explicitly with '--arg' or '--argstr'. See -// https://nixos.org/manual/nix/stable/#ss-functions.)", i.name); - - // if (debuggerHook) - // // debuggerHook(error, args); - // debuggerHook(error, {{"fun", &fun}}); - - // throw error; - +https://nixos.org/manual/nix/stable/#ss-functions.)", + i.name, + map1("fun", &fun)); // todo add bindings. } } } @@ -1716,7 +1712,7 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nInt) throwTypeError(pos, "value is %1% while an integer was expected", v, - std::optional>({{"value", &v}})); + map1("value", &v)); return v.integer; } @@ -1728,7 +1724,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) return v.integer; else if (v.type() != nFloat) throwTypeError(pos, "value is %1% while a float was expected", v, - std::optional>({{"value", &v}})); + map1("value", &v)); return v.fpoint; } @@ -1738,7 +1734,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nBool) throwTypeError(pos, "value is %1% while a Boolean was expected", v, - std::optional>({{"value", &v}})); + map1("value", &v)); return v.boolean; } @@ -1754,7 +1750,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) throwTypeError(pos, "value is %1% while a function was expected", v, - std::optional>({{"value", &v}})); + map1("value", &v)); } @@ -1763,7 +1759,7 @@ string EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nString) { throwTypeError(pos, "value is %1% while a string was expected", v, - std::optional>({{"value", &v}})); + map1("value", &v)); } return string(v.string.s); } @@ -1872,7 +1868,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string", - std::optional>({{"value", &v}})); + map1("value", &v)); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -1904,7 +1900,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } throwTypeError(pos, "cannot coerce %1% to a string", v, - std::optional>({{"value", &v}})); + map1("value", &v)); } -- cgit v1.2.3 From 0c2265da85bd094376279aea5e282974784218b3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 12 May 2021 09:43:58 -0600 Subject: unique_ptr for valmap --- src/libexpr/eval.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f8391cd77..531e3f752 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -616,17 +616,21 @@ std::optional EvalState::getDoc(Value & v) return {}; } -static std::optional> map1(const char *name, Value *v) __attribute__((noinline)); -std::optional> map1(const char *name, Value *v) +// typedef std::optional> valmap; +typedef const std::map valmap; + +static std::unique_ptr map1(const char *name, Value *v) __attribute__((noinline)); +std::unique_ptr map1(const char *name, Value *v) { - return std::optional>({{name, v}}); + // return new valmap({{name, v}}); + return std::unique_ptr(new valmap({{name, v}})); } -static std::optional> map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); -std::optional> map2(const char *name1, Value *v1, const char *name2, Value *v2) +static std::unique_ptr map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); +std::unique_ptr map2(const char *name1, Value *v1, const char *name2, Value *v2) { - return std::optional>({{name1, v1},{name2, v2}}); + return std::unique_ptr(new valmap({{name1, v1}, {name2, v2}})); } /* Every "format" object (even temporary) takes up a few hundred bytes @@ -669,7 +673,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const std::optional> & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, std::unique_ptr env)) { auto error = TypeError({ .msg = hintfmt(s), @@ -681,7 +685,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, const std::optional> & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, std::unique_ptr env)) { auto error = TypeError({ .msg = hintfmt(s, v), @@ -693,7 +697,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, const std::optional> & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, std::unique_ptr env)) { auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), @@ -723,7 +727,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, const std::optional> & env)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, std::unique_ptr env)) { auto error = MissingArgumentError({ .msg = hintfmt(s, s1), -- cgit v1.2.3 From 459bccc750616f07c9d55d6c12211e07c2369f1a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 12 May 2021 11:33:31 -0600 Subject: plain env pointer --- src/libexpr/eval.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 531e3f752..3f73c24a1 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -619,18 +619,18 @@ std::optional EvalState::getDoc(Value & v) // typedef std::optional> valmap; typedef const std::map valmap; -static std::unique_ptr map1(const char *name, Value *v) __attribute__((noinline)); -std::unique_ptr map1(const char *name, Value *v) +static valmap* map1(const char *name, Value *v) __attribute__((noinline)); +valmap* map1(const char *name, Value *v) { // return new valmap({{name, v}}); - return std::unique_ptr(new valmap({{name, v}})); + return new valmap({{name, v}}); } -static std::unique_ptr map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); -std::unique_ptr map2(const char *name1, Value *v1, const char *name2, Value *v2) +static valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); +valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2) { - return std::unique_ptr(new valmap({{name1, v1}, {name2, v2}})); + return new valmap({{name1, v1}, {name2, v2}}); } /* Every "format" object (even temporary) takes up a few hundred bytes @@ -673,8 +673,9 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, std::unique_ptr env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valmap* env)) { + auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s), .errPos = pos @@ -685,8 +686,9 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, std:: throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, std::unique_ptr env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, valmap* env)) { + auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos @@ -697,8 +699,9 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, std::unique_ptr env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, valmap* env)) { + auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), .errPos = pos @@ -727,7 +730,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, std::unique_ptr env)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, valmap* env)) { auto error = MissingArgumentError({ .msg = hintfmt(s, s1), -- cgit v1.2.3 From ab19d1685dd67a19c91eb3af346b9ac86f34b7d1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 13 May 2021 16:00:48 -0600 Subject: throwEvalError; mapBindings --- src/libexpr/eval.cc | 79 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 22 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 3f73c24a1..29b2721fe 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -617,20 +617,43 @@ std::optional EvalState::getDoc(Value & v) } // typedef std::optional> valmap; -typedef const std::map valmap; +typedef std::map valmap; -static valmap* map1(const char *name, Value *v) __attribute__((noinline)); -valmap* map1(const char *name, Value *v) +static valmap * map0() __attribute__((noinline)); +valmap * map0() { - // return new valmap({{name, v}}); - return new valmap({{name, v}}); + return new valmap(); +} + +static valmap * map1(const char *name, Value *v) __attribute__((noinline)); +valmap * map1(const char *name, Value *v) +{ + // return new valmap({{name, v}}); + return new valmap({{name, v}}); } -static valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); -valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2) +static valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); +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 @@ -638,17 +661,27 @@ valmap* map2(const char *name1, Value *v1, const char *name2, Value *v2) evaluator. So here are some helper functions for throwing 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(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(env); + auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3)) @@ -673,7 +706,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valmap* env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valmap * env)) { auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -686,7 +719,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valma throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, valmap* env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, valmap * env)) { auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -699,7 +732,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, valmap* env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, valmap * env)) { auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -730,7 +763,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, valmap* env)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, valmap * env)) { auto error = MissingArgumentError({ .msg = hintfmt(s, s1), @@ -1198,7 +1231,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); 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; pos2 = j->pos; @@ -1463,7 +1496,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See -https://nixos.org/manual/nix/stable/#ss-functions.)", +https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, map1("fun", &fun)); // todo add bindings. } @@ -1651,14 +1684,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } 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) { if (vTmp.type() == nInt) { nf += vTmp.integer; } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to a float", showType(vTmp)); + throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), map0()); } else 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) { 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; 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); 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; } -- cgit v1.2.3 From 989a4181a8f3fb830bae5018c18a13dc535b395a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 11:06:20 -0600 Subject: throwEvalError form 2 --- src/libexpr/eval.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 29b2721fe..1ae88ea1f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -684,9 +684,14 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const 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, valmap * env)) { - throw EvalError(s, s2, s3); + auto delenv = std::unique_ptr(env); + auto error = EvalError(s, s2, s3); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3)) @@ -1498,7 +1503,7 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - map1("fun", &fun)); // todo add bindings. + map1("fun", &fun)); // todo add bindings + fun } } } @@ -1850,10 +1855,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0]); + v.string.s, v.string.context[0]); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0]); + v.string.s, v.string.context[0], map1("value", &v)); } return s; } @@ -2052,7 +2057,8 @@ bool EvalState::eqValues(Value & v1, Value & v2) return v1.fpoint == v2.fpoint; default: - throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2)); + throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), + map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From ed74eaa07f6f7b5e87a1b96eff94990551ff488e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 11:09:18 -0600 Subject: throwEvalError form 3 --- src/libexpr/eval.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 1ae88ea1f..592f89fdf 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -694,12 +694,17 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, valmap * env)) { - throw EvalError({ + auto delenv = std::unique_ptr(env); + auto error = EvalError({ .msg = hintfmt(s, s2, s3), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2)) @@ -1855,7 +1860,7 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0]); + v.string.s, v.string.context[0], map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], map1("value", &v)); -- cgit v1.2.3 From d041dd874eddef8e56822ecb0806ad53db1fdacc Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 11:15:24 -0600 Subject: throwEvalError form 4 --- src/libexpr/eval.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 592f89fdf..8c96b6ba2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -707,13 +707,18 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, valmap * env)) { // p1 is where the error occurred; p2 is a position mentioned in the message. - throw EvalError({ + auto delenv = std::unique_ptr(env); + auto error = EvalError({ .msg = hintfmt(s, sym, p2), .errPos = p1 }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valmap * env)) @@ -1151,7 +1156,8 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos); + throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, + map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ -- cgit v1.2.3 From 17af7dc3260216aa279a1bb6f506b537aaef7bc3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 11:29:26 -0600 Subject: throwAssertionError, throwUndefinedError -> valmap-ized --- src/libexpr/eval.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8c96b6ba2..671b07dcd 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -760,26 +760,35 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } - - -LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1)) +LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, valmap * env)) { - throw AssertionError({ + auto delenv = std::unique_ptr(env); + auto error = AssertionError({ .msg = hintfmt(s, s1), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } -LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, valmap * env)) { - throw UndefinedVarError({ + auto delenv = std::unique_ptr(env); + auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; } LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, valmap * env)) { + auto delenv = std::unique_ptr(env); auto error = MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = pos @@ -848,7 +857,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, map0()); // TODO: env.attrs? for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -1548,7 +1557,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v) if (!state.evalBool(env, cond, pos)) { std::ostringstream out; cond->show(out); - throwAssertionError(pos, "assertion '%1%' failed", out.str()); + throwAssertionError(pos, "assertion '%1%' failed", out.str(), map0()); } body->eval(state, env, v); } -- cgit v1.2.3 From 644567cf7ea810f86bd8e0328567b39c4757bc14 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 13:40:00 -0600 Subject: clean up w LocalNoInline macro --- src/libexpr/eval.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 671b07dcd..897444360 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -619,28 +619,24 @@ std::optional EvalState::getDoc(Value & v) // typedef std::optional> valmap; typedef std::map valmap; -static valmap * map0() __attribute__((noinline)); -valmap * map0() +LocalNoInline(valmap * map0()) { return new valmap(); } -static valmap * map1(const char *name, Value *v) __attribute__((noinline)); -valmap * map1(const char *name, Value *v) +LocalNoInline(valmap * map1(const char *name, Value *v)) { // return new valmap({{name, v}}); return new valmap({{name, v}}); } -static valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2) __attribute__((noinline)); -valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2) +LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) { return new valmap({{name1, v1}, {name2, v2}}); } -static valmap * mapBindings(Bindings *b) __attribute__((noinline)); -valmap * mapBindings(Bindings *b) +LocalNoInline(valmap * mapBindings(Bindings *b)) { auto map = new valmap(); -- cgit v1.2.3 From 99304334caa833b32712ad02e04f1a0e9c8322fe Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 14 May 2021 18:09:30 -0600 Subject: showType(fun) --- src/libexpr/eval.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 897444360..9bb43f522 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1378,17 +1378,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po throwTypeError( pos, "attempt to call something which is not a function but %1%", - fun, + showType(fun), map2("fun", &fun, "arg", &arg)); - - // auto error = TypeError({ - // // .hint = hintfmt("attempt to call something which is not a function but %1%", showType(fun)), - // .msg = hintfmt("attempt to call something which is not a function but %1%", fun), - // .errPos = pos - // }); - // if (debuggerHook) - // debuggerHook(error, {{"fun", &fun}, {"arg", &arg}}); - // throw error; } ExprLambda & lambda(*fun.lambda.fun); -- cgit v1.2.3 From ff2e72054f741f51c07e737d82c8eff920342488 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 8 Jun 2021 14:44:41 -0600 Subject: another throwTypeError form --- src/libexpr/eval.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 9bb43f522..f296550d0 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -743,6 +743,19 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const char * t, valmap * env)) +{ + auto delenv = std::unique_ptr(env); + auto error = TypeError({ + .msg = hintfmt(s, t), + .errPos = pos + }); + + if (debuggerHook) + debuggerHook(error, *env); + throw error; +} + LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, valmap * env)) { auto delenv = std::unique_ptr(env); @@ -1378,7 +1391,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po throwTypeError( pos, "attempt to call something which is not a function but %1%", - showType(fun), + showType(fun).c_str(), map2("fun", &fun, "arg", &arg)); } -- cgit v1.2.3 From ebf530d31ecc2e01238737be8cf41c9d80962c99 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 8 Jun 2021 18:17:58 -0600 Subject: line endings --- src/libexpr/eval.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f296550d0..cef0f0bc3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -642,9 +642,9 @@ LocalNoInline(valmap * mapBindings(Bindings *b)) // auto v = new Value; - for (auto i = b->begin(); i != b->end(); ++i) + for (auto i = b->begin(); i != b->end(); ++i) { - std::string s = i->name; + std::string s = i->name; (*map)[s] = i->value; // map->insert({std::string("wat"), v}); } @@ -1174,7 +1174,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, + throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); @@ -2077,7 +2077,7 @@ bool EvalState::eqValues(Value & v1, Value & v2) return v1.fpoint == v2.fpoint; default: - throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), + throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From 93ca9381dac7b95cdab005e653f3051c74968d51 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 8 Jun 2021 18:37:28 -0600 Subject: formatting; string arg for throwTypeError --- src/libexpr/eval.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index cef0f0bc3..85bff6ee5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -743,11 +743,11 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const char * t, valmap * env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, valmap * env)) { auto delenv = std::unique_ptr(env); auto error = TypeError({ - .msg = hintfmt(s, t), + .msg = hintfmt(s, s2), .errPos = pos }); @@ -1516,7 +1516,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) if (j != args.end()) { actualArgs->attrs->push_back(*j); } else if (!i.def) { - throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') + throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%') Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default @@ -1965,7 +1965,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } throwTypeError(pos, "cannot coerce %1% to a string", v, - map1("value", &v)); + map1("value", &v)); } @@ -2077,8 +2077,10 @@ bool EvalState::eqValues(Value & v1, Value & v2) return v1.fpoint == v2.fpoint; default: - throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), - map2("value1", &v1, "value2", &v2)); + throwEvalError("cannot compare %1% with %2%", + showType(v1), + showType(v2), + map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From d22de1dd0c060971cb2cbeb9e49cae84c8d395cb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 9 Jun 2021 15:38:08 -0600 Subject: remove dead code --- src/libexpr/eval.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 85bff6ee5..f8fe0f309 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -616,7 +616,6 @@ std::optional EvalState::getDoc(Value & v) return {}; } -// typedef std::optional> valmap; typedef std::map valmap; LocalNoInline(valmap * map0()) @@ -626,7 +625,6 @@ LocalNoInline(valmap * map0()) LocalNoInline(valmap * map1(const char *name, Value *v)) { - // return new valmap({{name, v}}); return new valmap({{name, v}}); } @@ -640,13 +638,10 @@ LocalNoInline(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; @@ -866,7 +861,8 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, map0()); // TODO: env.attrs? + // TODO: env.attrs? + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, map0()); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } -- cgit v1.2.3 From 129dd760e63d1be33e99d847e759d8a1e4c2dee7 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 11 Jun 2021 18:55:15 -0600 Subject: mapEnvBindings --- src/libexpr/eval.cc | 53 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f8fe0f309..6dcdbb2bd 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -618,6 +618,15 @@ std::optional EvalState::getDoc(Value & v) typedef std::map valmap; +/*void addEnv(Value * v, valmap &vmap) +{ + if (v.isThunk()) { + Env * env = v.thunk.env; + + Expr * expr = v.thunk.expr; + +} +*/ LocalNoInline(valmap * map0()) { return new valmap(); @@ -628,17 +637,16 @@ LocalNoInline(valmap * map1(const char *name, Value *v)) return new valmap({{name, v}}); } - LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) { return new valmap({{name1, v1}, {name2, v2}}); } -LocalNoInline(valmap * mapBindings(Bindings *b)) +LocalNoInline(valmap * mapBindings(Bindings &b)) { auto map = new valmap(); - for (auto i = b->begin(); i != b->end(); ++i) + for (auto i = b.begin(); i != b.end(); ++i) { std::string s = i->name; (*map)[s] = i->value; @@ -647,6 +655,15 @@ LocalNoInline(valmap * mapBindings(Bindings *b)) return map; } +LocalNoInline(valmap * mapEnvBindings(Env &env)) +{ + if (env.values[0]->type() == nAttrs) { + return mapBindings(*env.values[0]->attrs); + } else { + return map0(); + } +} + /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing @@ -813,13 +830,11 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con e.addTrace(pos, s, s2); } - void mkString(Value & v, const char * s) { v.mkString(dupString(s)); } - Value & mkString(Value & v, std::string_view s, const PathSet & context) { v.mkString(dupStringWithLen(s.data(), s.size())); @@ -862,7 +877,8 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) } if (!env->prevWith) // TODO: env.attrs? - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, map0()); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, + mapEnvBindings(*env)); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -1171,7 +1187,8 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, - map1("value", &v)); // TODO dynamicAttrs to env? + mapEnvBindings(env)); + // map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ @@ -1261,7 +1278,9 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError(pos, "attribute '%1%' missing", name, mapBindings(vAttrs->attrs)); + throwEvalError(pos, "attribute '%1%' missing", name, + mapEnvBindings(env)); + // mapBindings(*vAttrs->attrs)); } vAttrs = j->value; pos2 = j->pos; @@ -1519,7 +1538,8 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - map1("fun", &fun)); // todo add bindings + fun + mapBindings(args)); + // map1("fun", &fun)); // todo add bindings + fun } } } @@ -1704,15 +1724,20 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) firstType = nFloat; nf = n; nf += vTmp.fpoint; - } else - throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), map0()); + } else { + std::cerr << "envtype: " << showType(env.values[0]->type()) << std::endl; + + throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), + mapEnvBindings(env)); + } } else if (firstType == nFloat) { if (vTmp.type() == nInt) { nf += vTmp.integer; } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), map0()); + throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), + mapEnvBindings(env)); } else s << state.coerceToString(pos, vTmp, context, false, firstType == nString); } @@ -1871,10 +1896,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], map1("value", &v)); + v.string.s, v.string.context[0], map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], map1("value", &v)); + v.string.s, v.string.context[0], map1("value", &v)); } return s; } -- cgit v1.2.3 From 89264d20e63effa8d10f84a5f989d962f5df36f5 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 6 Aug 2021 11:09:27 -0600 Subject: move valmap to hh; add to env --- src/libexpr/eval.cc | 168 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 138 insertions(+), 30 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6dcdbb2bd..48bff8dce 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -78,6 +78,8 @@ void printValue(std::ostream & str, std::set & active, const Valu return; } + str << "internal type: " << v.internalType << std::endl; + switch (v.internalType) { case tInt: str << v.integer; @@ -404,7 +406,7 @@ EvalState::EvalState(const Strings & _searchPath, ref store) assert(gcInitialised); - static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes"); + static_assert(sizeof(Env) <= 16 + sizeof(std::unique_ptr), "environment must be <= 16 bytes"); /* Initialise the Nix expression search path. */ if (!evalSettings.pureEval) { @@ -616,7 +618,7 @@ std::optional EvalState::getDoc(Value & v) return {}; } -typedef std::map valmap; +// typedef std::map valmap; /*void addEnv(Value * v, valmap &vmap) { @@ -655,13 +657,44 @@ LocalNoInline(valmap * mapBindings(Bindings &b)) return map; } +LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) +{ + for (auto i = b.begin(); i != b.end(); ++i) + { + std::string s = prefix; + s += i->name; + valmap[s] = i->value; + } +} + LocalNoInline(valmap * mapEnvBindings(Env &env)) { - if (env.values[0]->type() == nAttrs) { - return mapBindings(*env.values[0]->attrs); - } else { - return map0(); + // NOT going to use this + if (env.staticEnv) { + std::cout << "got static env" << std::endl; } + +// std::cout << "envsize: " << env.values.size() << std::endl; + + // std::cout << "size_t size: " << sizeof(size_t) << std::endl; + // std::cout << "envsize: " << env.size << std::endl; + // std::cout << "envup: " << env.up << std::endl; + + valmap *vm = env.up ? mapEnvBindings(*env.up) : new valmap(); + + /* + size_t i=0; + do { + std::cout << "env: " << i << " value: " << showType(*env.values[i]) << std::endl; + // std::cout << *env.values[i] << std::endl; + ++i; + } while(i < (std::min(env.size, (size_t)100))); + + + if (env.values[0]->type() == nAttrs) + addBindings(std::to_string((int)env.size), *env.values[0]->attrs, *vm); + */ + return vm; } /* Every "format" object (even temporary) takes up a few hundred bytes @@ -876,7 +909,6 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - // TODO: env.attrs? throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, mapEnvBindings(*env)); for (size_t l = env->prevWith; l; --l, env = env->up) ; @@ -902,14 +934,28 @@ Value * EvalState::allocValue() Env & EvalState::allocEnv(size_t size) { + nrEnvs++; nrValuesInEnvs += size; - Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); - env->type = Env::Plain; + // if (debuggerHook) + // { + // Env * env = (Env *) allocBytes(sizeof(DebugEnv) + size * sizeof(Value *)); + // // Env * env = new DebugEnv; + // env->type = Env::Plain; + // /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ + + // return *env; + // } else { + Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); + env->type = Env::Plain; + // env->size = size; - /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ + /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ - return *env; + return *env; + // } + + } @@ -1126,6 +1172,11 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) env2.up = &env; dynamicEnv = &env2; + // TODO; deal with the below overrides or whatever + if (debuggerHook) { + env2.valuemap = mapBindings(attrs); + } + AttrDefs::iterator overrides = attrs.find(state.sOverrides); bool hasOverrides = overrides != attrs.end(); @@ -1207,6 +1258,9 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) Env & env2(state.allocEnv(attrs->attrs.size())); env2.up = &env; + if (debuggerHook) { + env2.valuemap = mapBindings(attrs); + } /* The recursive attributes are evaluated in the new environment, while the inherited attributes are evaluated in the original environment. */ @@ -1420,9 +1474,11 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po size_t displ = 0; - if (!lambda.matchAttrs) + if (!lambda.matchAttrs){ + // TODO: what is this arg? empty argument? + // add empty valmap here? env2.values[displ++] = &arg; - + } else { forceAttrs(arg, pos); @@ -1432,23 +1488,51 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po /* For each formal argument, get the actual argument. If there is no matching actual argument but the formal argument has a default, use the default. */ - size_t attrsUsed = 0; - for (auto & i : lambda.formals->formals) { - Bindings::iterator j = arg.attrs->find(i.name); - if (j == arg.attrs->end()) { - if (!i.def) - throwTypeError( - pos, - "%1% called without required argument '%2%'", - lambda, - i.name, - map2("fun", &fun, "arg", &arg)); - env2.values[displ++] = i.def->maybeThunk(*this, env2); - } else { - attrsUsed++; - env2.values[displ++] = j->value; + if (debuggerHook) { + size_t attrsUsed = 0; + for (auto & i : lambda.formals->formals) { + Bindings::iterator j = arg.attrs->find(i.name); + if (j == arg.attrs->end()) { + if (!i.def) + throwTypeError( + pos, + "%1% called without required argument '%2%'", + lambda, + i.name, + map2("fun", &fun, "arg", &arg)); + env2.values[displ++] = i.def->maybeThunk(*this, env2); + } else { + attrsUsed++; + env2.values[displ++] = j->value; + } } } + else { + auto map = new valmap(); + + size_t attrsUsed = 0; + for (auto & i : lambda.formals->formals) { + Bindings::iterator j = arg.attrs->find(i.name); + if (j == arg.attrs->end()) { + if (!i.def) + throwTypeError( + pos, + "%1% called without required argument '%2%'", + lambda, + i.name, + map2("fun", &fun, "arg", &arg)); + env2.values[displ++] = i.def->maybeThunk(*this, env2); + } else { + attrsUsed++; + env2.values[displ++] = j->value; + + // add to debugger name-value map + std::string s = i->name; + (*map)[s] = i->value; + } + } + env2.valuemap = map; + } /* Check that each actual argument is listed as a formal argument (unless the attribute match specifies a `...'). */ @@ -1558,6 +1642,8 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; + env2.valuemap = mapBindings(attrs) + body->eval(state, env2, v); } @@ -1896,14 +1982,36 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], map1("value", &v)); + v.string.s, v.string.context[0], + // b.has_value() ? mapBindings(*b.get()) : map0()); + map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], map1("value", &v)); + v.string.s, v.string.context[0], + // b.has_value() ? mapBindings(*b.get()) : map0()); + map1("value", &v)); } return s; } +/*string EvalState::forceStringNoCtx(std::optional b, Value & v, const Pos & pos) +{ + string s = forceString(v, pos); + if (v.string.context) { + if (pos) + throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", + v.string.s, v.string.context[0], + b.has_value() ? mapBindings(*b.get()) : map0()); + // map1("value", &v)); + else + throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", + v.string.s, v.string.context[0], + b.has_value() ? mapBindings(*b.get()) : map0()); + // map1("value", &v)); + } + return s; +}*/ + bool EvalState::isDerivation(Value & v) { -- cgit v1.2.3 From 030271184fecbbe9dd871b71d92c61e163254646 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 9 Aug 2021 14:30:47 -0600 Subject: trying env args; but unecessary? --- src/libexpr/eval.cc | 148 +++++++++++++++++++++++++--------------------------- 1 file changed, 72 insertions(+), 76 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 48bff8dce..464022372 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -35,7 +35,8 @@ namespace nix { -std::function & env)> debuggerHook; +// std::function & env)> debuggerHook; +std::function debuggerHook; static char * dupString(const char * s) { @@ -667,189 +668,189 @@ LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) } } -LocalNoInline(valmap * mapEnvBindings(Env &env)) -{ - // NOT going to use this - if (env.staticEnv) { - std::cout << "got static env" << std::endl; - } +// LocalNoInline(valmap * mapEnvBindings(Env &env)) +// { +// // NOT going to use this +// if (env.valuemap) { +// std::cout << "got static env" << std::endl; +// } -// std::cout << "envsize: " << env.values.size() << std::endl; +// // std::cout << "envsize: " << env.values.size() << std::endl; - // std::cout << "size_t size: " << sizeof(size_t) << std::endl; - // std::cout << "envsize: " << env.size << std::endl; - // std::cout << "envup: " << env.up << std::endl; +// // std::cout << "size_t size: " << sizeof(size_t) << std::endl; +// // std::cout << "envsize: " << env.size << std::endl; +// // std::cout << "envup: " << env.up << std::endl; - valmap *vm = env.up ? mapEnvBindings(*env.up) : new valmap(); +// valmap *vm = env.up ? mapEnvBindings(*env.up) : new valmap(); - /* - size_t i=0; - do { - std::cout << "env: " << i << " value: " << showType(*env.values[i]) << std::endl; - // std::cout << *env.values[i] << std::endl; - ++i; - } while(i < (std::min(env.size, (size_t)100))); +// /* +// size_t i=0; +// do { +// std::cout << "env: " << i << " value: " << showType(*env.values[i]) << std::endl; +// // std::cout << *env.values[i] << std::endl; +// ++i; +// } while(i < (std::min(env.size, (size_t)100))); - if (env.values[0]->type() == nAttrs) - addBindings(std::to_string((int)env.size), *env.values[0]->attrs, *vm); - */ - return vm; -} +// if (env.values[0]->type() == nAttrs) +// addBindings(std::to_string((int)env.size), *env.values[0]->attrs, *vm); +// */ +// return vm; +// } /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing exceptions. */ -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, valmap * env)) +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, valmap * env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, valmap * env)) +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2, s3); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, valmap * env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, s2, s3), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, valmap * env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, Env & env)) { // p1 is where the error occurred; p2 is a position mentioned in the message. - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, sym, p2), .errPos = p1 }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, valmap * env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, valmap * env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, valmap * env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, s2), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, valmap * env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, valmap * env)) +LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = AssertionError({ .msg = hintfmt(s, s1), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, valmap * env)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, valmap * env)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env)) { - auto delenv = std::unique_ptr(env); + // auto delenv = std::unique_ptr(env); auto error = MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = pos }); if (debuggerHook) - debuggerHook(error, *env); + debuggerHook(error, env); throw error; } @@ -909,8 +910,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, - mapEnvBindings(*env)); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -1238,7 +1238,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, - mapEnvBindings(env)); + env); // map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); @@ -1332,8 +1332,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError(pos, "attribute '%1%' missing", name, - mapEnvBindings(env)); + throwEvalError(pos, "attribute '%1%' missing", name, env); // mapBindings(*vAttrs->attrs)); } vAttrs = j->value; @@ -1622,7 +1621,8 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - mapBindings(args)); + fun.lambda.env); + // mapBindings(args)); // map1("fun", &fun)); // todo add bindings + fun } } @@ -1642,7 +1642,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; - env2.valuemap = mapBindings(attrs) + env2.valuemap = mapBindings(*attrs) body->eval(state, env2, v); } @@ -1813,8 +1813,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) } else { std::cerr << "envtype: " << showType(env.values[0]->type()) << std::endl; - throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), - mapEnvBindings(env)); + throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), env); } } else if (firstType == nFloat) { if (vTmp.type() == nInt) { @@ -1822,8 +1821,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), - mapEnvBindings(env)); + throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), env); } else s << state.coerceToString(pos, vTmp, context, false, firstType == nString); } @@ -2061,8 +2059,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) - throwTypeError(pos, "cannot coerce a set to a string", - map1("value", &v)); + throwTypeError(pos, "cannot coerce a set to a string", map1("value", &v)); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -2093,12 +2090,11 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError(pos, "cannot coerce %1% to a string", v, - map1("value", &v)); + throwTypeError(pos, "cannot coerce %1% to a string", v, map1("value", &v)); } -string EvalState::copyPathToStore(PathSet & context, const Path & path) +string EvalState::copyPathToStore(Env &env, PathSet & context, const Path & path) { if (nix::isDerivation(path)) throwEvalError("file names are not allowed to end in '%1%'", -- cgit v1.2.3 From b6eb38016b9d16cf206f3f2b0cd4bce4dea40345 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 17 Aug 2021 14:39:50 -0600 Subject: moving towards env in exceptions --- src/libexpr/eval.cc | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 464022372..f799ee7db 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1172,11 +1172,6 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) env2.up = &env; dynamicEnv = &env2; - // TODO; deal with the below overrides or whatever - if (debuggerHook) { - env2.valuemap = mapBindings(attrs); - } - AttrDefs::iterator overrides = attrs.find(state.sOverrides); bool hasOverrides = overrides != attrs.end(); @@ -1195,6 +1190,11 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) v.attrs->push_back(Attr(i.first, vAttr, &i.second.pos)); } + // TODO; deal with the below overrides or whatever + if (debuggerHook) { + env2.valuemap.reset(mapBindings(*v.attrs)); + } + /* If the rec contains an attribute called `__overrides', then evaluate it, and add the attributes in that set to the rec. This allows overriding of recursive attributes, which is @@ -1258,9 +1258,6 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) Env & env2(state.allocEnv(attrs->attrs.size())); env2.up = &env; - if (debuggerHook) { - env2.valuemap = mapBindings(attrs); - } /* The recursive attributes are evaluated in the new environment, while the inherited attributes are evaluated in the original environment. */ @@ -1268,6 +1265,18 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) for (auto & i : attrs->attrs) env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2); + if (debuggerHook) { + auto map = new valmap(); + + displ = 0; + for (auto & i : attrs->attrs) + { + // std::string s = i->name; + (*map)[i.first] = env2.values[displ++]; + } + env2.valuemap.reset(map); + } + body->eval(state, env2, v); } @@ -1460,6 +1469,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po pos, "attempt to call something which is not a function but %1%", showType(fun).c_str(), + // fun.env); map2("fun", &fun, "arg", &arg)); } @@ -1498,7 +1508,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - map2("fun", &fun, "arg", &arg)); + fun.lambda.env); + // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1519,18 +1530,19 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - map2("fun", &fun, "arg", &arg)); + fun.env); + // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; env2.values[displ++] = j->value; // add to debugger name-value map - std::string s = i->name; - (*map)[s] = i->value; + std::string s = i.name; + (*map)[s] = i.value; } } - env2.valuemap = map; + env2.valuemap.reset(map); } /* Check that each actual argument is listed as a formal @@ -1544,7 +1556,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called with unexpected argument '%2%'", lambda, i.name, - map2("fun", &fun, "arg", &arg)); + fun.env); + // map2("fun", &fun, "arg", &arg)); abort(); // can't happen } } @@ -1621,7 +1634,7 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - fun.lambda.env); + *fun.lambda.env); // mapBindings(args)); // map1("fun", &fun)); // todo add bindings + fun } -- cgit v1.2.3 From e82cf13b1e94a27b2d6402ff6850a5a11d18fb92 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 18 Aug 2021 17:53:10 -0600 Subject: switch to fakeenvs --- src/libexpr/eval.cc | 68 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f799ee7db..48546e8ad 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -958,6 +958,16 @@ Env & EvalState::allocEnv(size_t size) } +Env & fakeEnv(size_t size) +{ + // making a fake Env so we'll have one to pass to exception ftns. + // a placeholder until we can pass real envs everywhere they're needed. + Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); + env->type = Env::Plain; + + return *env; +} + void EvalState::mkList(Value & v, size_t size) { @@ -1469,8 +1479,9 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po pos, "attempt to call something which is not a function but %1%", showType(fun).c_str(), + fakeEnv(1)); // fun.env); - map2("fun", &fun, "arg", &arg)); + // map2("fun", &fun, "arg", &arg)); } ExprLambda & lambda(*fun.lambda.fun); @@ -1508,7 +1519,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - fun.lambda.env); + *fun.lambda.env); // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { @@ -1530,7 +1541,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - fun.env); + *fun.lambda.env); // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { @@ -1539,7 +1550,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po // add to debugger name-value map std::string s = i.name; - (*map)[s] = i.value; + (*map)[s] = j->value; } } env2.valuemap.reset(map); @@ -1556,7 +1567,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called with unexpected argument '%2%'", lambda, i.name, - fun.env); + *fun.lambda.env); // map2("fun", &fun, "arg", &arg)); abort(); // can't happen } @@ -1655,7 +1666,11 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; - env2.valuemap = mapBindings(*attrs) + if (debuggerHook) { + forceAttrs(attrs); + env2.valuemap = mapBindings(attrs->attrs); + } + body->eval(state, env2, v); } @@ -1672,7 +1687,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v) if (!state.evalBool(env, cond, pos)) { std::ostringstream out; cond->show(out); - throwAssertionError(pos, "assertion '%1%' failed", out.str(), map0()); + throwAssertionError(pos, "assertion '%1%' failed", out.str(), env); } body->eval(state, env, v); } @@ -1895,7 +1910,8 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nInt) throwTypeError(pos, "value is %1% while an integer was expected", v, - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); return v.integer; } @@ -1907,7 +1923,8 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) return v.integer; else if (v.type() != nFloat) throwTypeError(pos, "value is %1% while a float was expected", v, - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); return v.fpoint; } @@ -1916,8 +1933,9 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v, - map1("value", &v)); + throwTypeError(pos, "value is %1% while a Boolean was expected", v, + fakeEnv(1)); + // map1("value", &v)); return v.boolean; } @@ -1933,7 +1951,8 @@ void EvalState::forceFunction(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) throwTypeError(pos, "value is %1% while a function was expected", v, - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); } @@ -1942,7 +1961,8 @@ string EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nString) { throwTypeError(pos, "value is %1% while a string was expected", v, - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); } return string(v.string.s); } @@ -1995,12 +2015,14 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], // b.has_value() ? mapBindings(*b.get()) : map0()); - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], // b.has_value() ? mapBindings(*b.get()) : map0()); - map1("value", &v)); + fakeEnv(1)); + // map1("value", &v)); } return s; } @@ -2072,7 +2094,9 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) - throwTypeError(pos, "cannot coerce a set to a string", map1("value", &v)); + throwTypeError(pos, "cannot coerce a set to a string", + fakeEnv(1)); + // map1("value", &v)); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -2080,7 +2104,6 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, return v.external->coerceToString(pos, context, coerceMore, copyToStore); if (coerceMore) { - /* Note that `false' is represented as an empty string for shell scripting convenience, just like `null'. */ if (v.type() == nBool && v.boolean) return "1"; @@ -2103,7 +2126,9 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError(pos, "cannot coerce %1% to a string", v, map1("value", &v)); + throwTypeError(pos, "cannot coerce %1% to a string", v, + fakeEnv(1)); + // map1("value", &v)); } @@ -2136,7 +2161,9 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) { string path = coerceToString(pos, v, context, false, false); if (path == "" || path[0] != '/') - throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, map1("value", &v)); + throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, + fakeEnv(1)); + // map1("value", &v)); return path; } @@ -2218,7 +2245,8 @@ bool EvalState::eqValues(Value & v1, Value & v2) throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), - map2("value1", &v1, "value2", &v2)); + fakeEnv(1)); + // map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From 22720215366ada555f077ffb8eb810029ec93a04 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 18 Aug 2021 20:02:23 -0600 Subject: more error fixes --- src/libexpr/eval.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 48546e8ad..eef4974e5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1667,8 +1667,8 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.values[0] = (Value *) attrs; if (debuggerHook) { - forceAttrs(attrs); - env2.valuemap = mapBindings(attrs->attrs); + state.forceAttrs(*env2.values[0]); + env2.valuemap.reset(mapBindings(*env2.values[0]->attrs)); } @@ -2132,12 +2132,13 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } -string EvalState::copyPathToStore(Env &env, PathSet & context, const Path & path) +string EvalState::copyPathToStore(PathSet & context, const Path & path) { if (nix::isDerivation(path)) throwEvalError("file names are not allowed to end in '%1%'", drvExtension, - map0()); + fakeEnv(1)); + // map0()); Path dstPath; auto i = srcToStore.find(path); -- cgit v1.2.3 From 4b5f9b35f06754aaf578a2d4b3d730949964ef05 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 18 Aug 2021 21:25:26 -0600 Subject: env to bindings --- src/libexpr/eval.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index eef4974e5..2e885bb7c 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -668,6 +668,28 @@ LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) } } + + +void mapEnvBindings(const Env &env, valmap & vm) +{ + // add bindings for the next level up first. + if (env.up) { + mapEnvBindings(*env.up, vm); + } + + // merge - and write over - higher level bindings. + vm.merge(*env.valuemap); +} + +valmap * mapEnvBindings(const Env &env) +{ + auto vm = new valmap(); + + mapEnvBindings(env, *vm); + + return vm; +} + // LocalNoInline(valmap * mapEnvBindings(Env &env)) // { // // NOT going to use this @@ -1508,8 +1530,8 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po /* For each formal argument, get the actual argument. If there is no matching actual argument but the formal argument has a default, use the default. */ + size_t attrsUsed = 0; if (debuggerHook) { - size_t attrsUsed = 0; for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { @@ -1531,7 +1553,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po else { auto map = new valmap(); - size_t attrsUsed = 0; for (auto & i : lambda.formals->formals) { Bindings::iterator j = arg.attrs->find(i.name); if (j == arg.attrs->end()) { -- cgit v1.2.3 From bd3b5329f91e6caff387cf361a5c779468f34f88 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 24 Aug 2021 16:32:54 -0600 Subject: print env bindings --- src/libexpr/eval.cc | 74 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 8 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2e885bb7c..7fee1168c 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -669,6 +669,26 @@ LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) } +void printEnvBindings(const Env &env, int lv ) +{ + if (env.values[0]->type() == nAttrs) { + Bindings::iterator j = env.values[0]->attrs->begin(); + + while (j != env.values[0]->attrs->end()) { + std::cout << lv << " env binding: " << j->name << std::endl; + // if (countCalls && j->pos) attrSelects[*j->pos]++; + // return j->value; + j++; + } + + } + + std::cout << "next env : " << env.up << std::endl; + + if (env.up) { + printEnvBindings(*env.up, ++lv); + } +} void mapEnvBindings(const Env &env, valmap & vm) { @@ -678,14 +698,38 @@ void mapEnvBindings(const Env &env, valmap & vm) } // merge - and write over - higher level bindings. - vm.merge(*env.valuemap); + if (env.valuemap) + vm.merge(*env.valuemap); } +// void mapEnvBindings(const Env &env, valmap & vm) +// { +// // add bindings for the next level up first. +// if (env.up) { +// mapEnvBindings(*env.up, vm); +// } + +// // merge - and write over - higher level bindings. +// if (env.valuemap) +// vm.merge(*env.valuemap); +// } + valmap * mapEnvBindings(const Env &env) { auto vm = new valmap(); + // segfault! + std::cout << "before mapenv" << std::endl; + if (env.valuemap) { + std::cout << "valuemap" << std::endl; + std::cout << "mapenv count" << env.valuemap->size() << std::endl; + } else + { + std::cout << "novaluemap" << std::endl; + } + mapEnvBindings(env, *vm); + std::cout << "after mapenv" << std::endl; return vm; } @@ -852,6 +896,8 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env)) { + std::cout << "throwUndefinedVarError" << std::endl; + // auto delenv = std::unique_ptr(env); auto error = UndefinedVarError({ .msg = hintfmt(s, s1), @@ -914,6 +960,8 @@ void mkPath(Value & v, const char * s) inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) { + // std::cout << " EvalState::lookupVar" << std::endl; + for (size_t l = var.level; l; --l, env = env->up) ; if (!var.fromWith) return env->values[var.displ]; @@ -931,8 +979,10 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) if (countCalls && j->pos) attrSelects[*j->pos]++; return j->value; } - if (!env->prevWith) + if (!env->prevWith) { + std::cout << "pre throwUndefinedVarError" << std::endl; throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env); + } for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -1681,16 +1731,24 @@ https://nixos.org/manual/nix/stable/#ss-functions.)", void ExprWith::eval(EvalState & state, Env & env, Value & v) { + // std::cout << "ExprWith::eval" << std::endl; Env & env2(state.allocEnv(1)); env2.up = &env; env2.prevWith = prevWith; env2.type = Env::HasWithExpr; - env2.values[0] = (Value *) attrs; - - if (debuggerHook) { - state.forceAttrs(*env2.values[0]); - env2.valuemap.reset(mapBindings(*env2.values[0]->attrs)); - } + env2.values[0] = (Value *) attrs; // ok DAG nasty. just smoosh this in. + // presumably evaluate later, lazily. + // std::cout << "ExprWith::eval2" << std::endl; + + // can't load the valuemap until they've been evaled, which is not yet. + // if (debuggerHook) { + // std::cout << "ExprWith::eval3.0" << std::endl; + // std::cout << "ExprWith attrs" << *attrs << std::endl; + // state.forceAttrs(*(Value*) attrs); + // std::cout << "ExprWith::eval3.5" << std::endl; + // env2.valuemap.reset(mapBindings(*env2.values[0]->attrs)); + // std::cout << "ExprWith::eval4" << std::endl; + // } body->eval(state, env2, v); -- cgit v1.2.3 From d8a977a22ebd8884124a0a80e6b1523228f70f4b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 Aug 2021 11:19:09 -0600 Subject: adding all the value names from env.values[0] --- src/libexpr/eval.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7fee1168c..6eb7f2cb9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -698,21 +698,19 @@ void mapEnvBindings(const Env &env, valmap & vm) } // merge - and write over - higher level bindings. - if (env.valuemap) - vm.merge(*env.valuemap); + if (env.values[0]->type() == nAttrs) { + auto map = valmap(); + + Bindings::iterator j = env.values[0]->attrs->begin(); + + while (j != env.values[0]->attrs->end()) { + map[j->name] = j->value; + j++; + } + vm.merge(map); + } } -// void mapEnvBindings(const Env &env, valmap & vm) -// { -// // add bindings for the next level up first. -// if (env.up) { -// mapEnvBindings(*env.up, vm); -// } - -// // merge - and write over - higher level bindings. -// if (env.valuemap) -// vm.merge(*env.valuemap); -// } valmap * mapEnvBindings(const Env &env) { -- cgit v1.2.3 From 310c689d317d1eb4bcf50cd11d84165fe2ffd512 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 Aug 2021 13:18:27 -0600 Subject: remove more explicit valmap code --- src/libexpr/eval.cc | 150 +++++++++++++++++----------------------------------- 1 file changed, 48 insertions(+), 102 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6eb7f2cb9..c6fb052f4 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -630,43 +630,43 @@ std::optional EvalState::getDoc(Value & v) } */ -LocalNoInline(valmap * map0()) -{ - return new valmap(); -} +// LocalNoInline(valmap * map0()) +// { +// return new valmap(); +// } -LocalNoInline(valmap * map1(const char *name, Value *v)) -{ - return new valmap({{name, v}}); -} +// LocalNoInline(valmap * map1(const char *name, Value *v)) +// { +// return new valmap({{name, v}}); +// } -LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) -{ - return new valmap({{name1, v1}, {name2, v2}}); -} +// LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) +// { +// return new valmap({{name1, v1}, {name2, v2}}); +// } -LocalNoInline(valmap * mapBindings(Bindings &b)) -{ - auto map = new valmap(); +// LocalNoInline(valmap * mapBindings(Bindings &b)) +// { +// auto map = new valmap(); - for (auto i = b.begin(); i != b.end(); ++i) - { - std::string s = i->name; - (*map)[s] = i->value; - } +// for (auto i = b.begin(); i != b.end(); ++i) +// { +// std::string s = i->name; +// (*map)[s] = i->value; +// } - return map; -} +// return map; +// } -LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) -{ - for (auto i = b.begin(); i != b.end(); ++i) - { - std::string s = prefix; - s += i->name; - valmap[s] = i->value; - } -} +// LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) +// { +// for (auto i = b.begin(); i != b.end(); ++i) +// { +// std::string s = prefix; +// s += i->name; +// valmap[s] = i->value; +// } +// } void printEnvBindings(const Env &env, int lv ) @@ -698,6 +698,7 @@ void mapEnvBindings(const Env &env, valmap & vm) } // merge - and write over - higher level bindings. + // note; skipping HasWithExpr that haven't been evaled yet. if (env.values[0]->type() == nAttrs) { auto map = valmap(); @@ -716,18 +717,7 @@ valmap * mapEnvBindings(const Env &env) { auto vm = new valmap(); - // segfault! - std::cout << "before mapenv" << std::endl; - if (env.valuemap) { - std::cout << "valuemap" << std::endl; - std::cout << "mapenv count" << env.valuemap->size() << std::endl; - } else - { - std::cout << "novaluemap" << std::endl; - } - mapEnvBindings(env, *vm); - std::cout << "after mapenv" << std::endl; return vm; } @@ -1270,11 +1260,6 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) v.attrs->push_back(Attr(i.first, vAttr, &i.second.pos)); } - // TODO; deal with the below overrides or whatever - if (debuggerHook) { - env2.valuemap.reset(mapBindings(*v.attrs)); - } - /* If the rec contains an attribute called `__overrides', then evaluate it, and add the attributes in that set to the rec. This allows overriding of recursive attributes, which is @@ -1345,18 +1330,6 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) for (auto & i : attrs->attrs) env2.values[displ++] = i.second.e->maybeThunk(state, i.second.inherited ? env : env2); - if (debuggerHook) { - auto map = new valmap(); - - displ = 0; - for (auto & i : attrs->attrs) - { - // std::string s = i->name; - (*map)[i.first] = env2.values[displ++]; - } - env2.valuemap.reset(map); - } - body->eval(state, env2, v); } @@ -1579,52 +1552,25 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po there is no matching actual argument but the formal argument has a default, use the default. */ size_t attrsUsed = 0; - if (debuggerHook) { - for (auto & i : lambda.formals->formals) { - Bindings::iterator j = arg.attrs->find(i.name); - if (j == arg.attrs->end()) { - if (!i.def) - throwTypeError( - pos, - "%1% called without required argument '%2%'", - lambda, - i.name, - *fun.lambda.env); - // map2("fun", &fun, "arg", &arg)); - env2.values[displ++] = i.def->maybeThunk(*this, env2); - } else { - attrsUsed++; - env2.values[displ++] = j->value; - } - } - } - else { - auto map = new valmap(); - - for (auto & i : lambda.formals->formals) { - Bindings::iterator j = arg.attrs->find(i.name); - if (j == arg.attrs->end()) { - if (!i.def) - throwTypeError( - pos, - "%1% called without required argument '%2%'", - lambda, - i.name, - *fun.lambda.env); - // map2("fun", &fun, "arg", &arg)); - env2.values[displ++] = i.def->maybeThunk(*this, env2); - } else { - attrsUsed++; - env2.values[displ++] = j->value; - - // add to debugger name-value map - std::string s = i.name; - (*map)[s] = j->value; - } + for (auto & i : lambda.formals->formals) { + Bindings::iterator j = arg.attrs->find(i.name); + if (j == arg.attrs->end()) { + if (!i.def) + throwTypeError( + pos, + "%1% called without required argument '%2%'", + lambda, + i.name, + *fun.lambda.env); + // map2("fun", &fun, "arg", &arg)); + env2.values[displ++] = i.def->maybeThunk(*this, env2); + } else { + attrsUsed++; + env2.values[displ++] = j->value; } - env2.valuemap.reset(map); } + /* Check that each actual argument is listed as a formal argument (unless the attribute match specifies a `...'). */ if (!lambda.formals->ellipsis && attrsUsed != arg.attrs->size()) { -- cgit v1.2.3 From 176911102ce2c0be06bbfed9099f364d71c3c679 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 13 Sep 2021 11:57:25 -0600 Subject: printEnvPosChain --- src/libexpr/eval.cc | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c6fb052f4..19379b876 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -648,13 +648,11 @@ std::optional EvalState::getDoc(Value & v) // LocalNoInline(valmap * mapBindings(Bindings &b)) // { // auto map = new valmap(); - // for (auto i = b.begin(); i != b.end(); ++i) // { // std::string s = i->name; // (*map)[s] = i->value; // } - // return map; // } @@ -668,12 +666,13 @@ std::optional EvalState::getDoc(Value & v) // } // } - void printEnvBindings(const Env &env, int lv ) { + std::cout << "env " << lv << " type: " << env.type << std::endl; if (env.values[0]->type() == nAttrs) { Bindings::iterator j = env.values[0]->attrs->begin(); + while (j != env.values[0]->attrs->end()) { std::cout << lv << " env binding: " << j->name << std::endl; // if (countCalls && j->pos) attrSelects[*j->pos]++; @@ -690,6 +689,33 @@ void printEnvBindings(const Env &env, int lv ) } } +void printEnvPosChain(const Env &env, int lv ) +{ + std::cout << "printEnvPosChain " << lv << std::endl; + + std::cout << "env" << env.values[0] << std::endl; + + if (env.values[0] && env.values[0]->type() == nAttrs) { + std::cout << "im in the loop" << std::endl; + std::cout << "pos " << env.values[0]->attrs->pos << std::endl; + if (env.values[0]->attrs->pos) { + ErrPos ep(*env.values[0]->attrs->pos); + auto loc = getCodeLines(ep); + if (loc) + printCodeLines(std::cout, + std::__cxx11::to_string(lv), + ep, + *loc); + } + } + + std::cout << "next env : " << env.up << std::endl; + + if (env.up) { + printEnvPosChain(*env.up, ++lv); + } +} + void mapEnvBindings(const Env &env, valmap & vm) { // add bindings for the next level up first. @@ -699,7 +725,7 @@ void mapEnvBindings(const Env &env, valmap & vm) // merge - and write over - higher level bindings. // note; skipping HasWithExpr that haven't been evaled yet. - if (env.values[0]->type() == nAttrs) { + if (env.values[0] && env.values[0]->type() == nAttrs) { auto map = valmap(); Bindings::iterator j = env.values[0]->attrs->begin(); -- cgit v1.2.3 From 21071bfdeb0a5bc2b75018c91a4c2f138f233e33 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 14 Sep 2021 10:49:22 -0600 Subject: shared_ptr for StaticEnv --- src/libexpr/eval.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 19379b876..69e3a4107 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -401,7 +401,7 @@ EvalState::EvalState(const Strings & _searchPath, ref store) , store(store) , regexCache(makeRegexCache()) , baseEnv(allocEnv(128)) - , staticBaseEnv(false, 0) + , staticBaseEnv(new StaticEnv(false, 0)) { countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0"; @@ -538,7 +538,7 @@ Value * EvalState::addConstant(const string & name, Value & v) { Value * v2 = allocValue(); *v2 = v; - staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; + staticBaseEnv->vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v2; string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v2)); @@ -564,7 +564,7 @@ Value * EvalState::addPrimOp(const string & name, Value * v = allocValue(); v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = sym }); - staticBaseEnv.vars[symbols.create(name)] = baseEnvDispl; + staticBaseEnv->vars[symbols.create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; baseEnv.values[0]->attrs->push_back(Attr(sym, v)); return v; @@ -590,7 +590,7 @@ Value * EvalState::addPrimOp(PrimOp && primOp) Value * v = allocValue(); v->mkPrimOp(new PrimOp(std::move(primOp))); - staticBaseEnv.vars[envName] = baseEnvDispl; + staticBaseEnv->vars[envName] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v)); return v; -- cgit v1.2.3 From cd8c232b554776031f61cee5f70a8825c60fbfdb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 15 Sep 2021 16:16:53 -0600 Subject: add cout debugging --- src/libexpr/eval.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 69e3a4107..bcef2008f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -918,6 +918,8 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * .errPos = pos }); + std::cout << "pre debuggerHook" << std::endl; + if (debuggerHook) debuggerHook(error, env); throw error; -- cgit v1.2.3 From c07edb1932b0f747b563aceaecc5550f5ce192fb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Sep 2021 18:14:57 -0600 Subject: staticenv should be With --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bcef2008f..53a5c5bd2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -976,7 +976,7 @@ void mkPath(Value & v, const char * s) inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) { - // std::cout << " EvalState::lookupVar" << std::endl; + std::cout << " EvalState::lookupVar" << var << std::endl; for (size_t l = var.level; l; --l, env = env->up) ; -- cgit v1.2.3 From aad27143c67c863bd4886186bdf68f4796ca26c3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 2 Oct 2021 13:47:36 -0600 Subject: storing staticenv bindings --- src/libexpr/eval.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 53a5c5bd2..c2b6e7ea8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -689,6 +689,29 @@ void printEnvBindings(const Env &env, int lv ) } } +void printStaticEnvBindings(const StaticEnv &se, int lvl) +{ + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) + { + std::cout << lvl << i->first << std::endl; + } + + if (se.up) { + printStaticEnvBindings(*se.up, ++lvl); + } + +} + +void printStaticEnvBindings(const Expr &expr) +{ + // just print the names for now + if (expr.staticenv) + { + printStaticEnvBindings(*expr.staticenv.get(), 0); + } + +} + void printEnvPosChain(const Env &env, int lv ) { std::cout << "printEnvPosChain " << lv << std::endl; -- cgit v1.2.3 From 2ee1fa4afd69226f16305e792d5110fd36669c6b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 Oct 2021 14:42:29 -0600 Subject: add nullable Expr argument --- src/libexpr/eval.cc | 129 ++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 59 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c2b6e7ea8..76c038593 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -36,7 +36,7 @@ namespace nix { // std::function & env)> debuggerHook; -std::function debuggerHook; +std::function debuggerHook; static char * dupString(const char * s) { @@ -806,17 +806,17 @@ valmap * mapEnvBindings(const Env &env) evaluator. So here are some helper functions for throwing exceptions. */ -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env & env)) +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = EvalError({ @@ -824,22 +824,24 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, Env & env)) +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2, s3); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, Env & env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = EvalError({ @@ -847,12 +849,13 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, Env & env)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, Env & env, Expr *expr)) { // p1 is where the error occurred; p2 is a position mentioned in the message. // auto delenv = std::unique_ptr(env); @@ -861,12 +864,13 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const .errPos = p1 }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -874,12 +878,13 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -887,12 +892,13 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -900,12 +906,13 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = TypeError({ @@ -913,12 +920,13 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env)) +LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = AssertionError({ @@ -926,12 +934,13 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { std::cout << "throwUndefinedVarError" << std::endl; @@ -943,12 +952,13 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * std::cout << "pre debuggerHook" << std::endl; - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { // auto delenv = std::unique_ptr(env); auto error = MissingArgumentError({ @@ -956,8 +966,9 @@ LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char .errPos = pos }); - if (debuggerHook) - debuggerHook(error, env); + if (debuggerHook && expr) + debuggerHook(error, env, *expr); + throw error; } @@ -1020,7 +1031,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) } if (!env->prevWith) { std::cout << "pre throwUndefinedVarError" << std::endl; - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, 0); } for (size_t l = env->prevWith; l; --l, env = env->up) ; } @@ -1354,7 +1365,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, - env); + env, this); // map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); @@ -1445,7 +1456,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError(pos, "attribute '%1%' missing", name, env); + throwEvalError(pos, "attribute '%1%' missing", name, env, this); // mapBindings(*vAttrs->attrs)); } vAttrs = j->value; @@ -1573,7 +1584,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po pos, "attempt to call something which is not a function but %1%", showType(fun).c_str(), - fakeEnv(1)); + fakeEnv(1), 0); // fun.env); // map2("fun", &fun, "arg", &arg)); } @@ -1612,7 +1623,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called without required argument '%2%'", lambda, i.name, - *fun.lambda.env); + *fun.lambda.env, &lambda); // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { @@ -1633,7 +1644,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "%1% called with unexpected argument '%2%'", lambda, i.name, - *fun.lambda.env); + *fun.lambda.env, &lambda); // map2("fun", &fun, "arg", &arg)); abort(); // can't happen } @@ -1711,7 +1722,7 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - *fun.lambda.env); + *fun.lambda.env, fun.lambda.fun); // mapBindings(args)); // map1("fun", &fun)); // todo add bindings + fun } @@ -1761,7 +1772,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v) if (!state.evalBool(env, cond, pos)) { std::ostringstream out; cond->show(out); - throwAssertionError(pos, "assertion '%1%' failed", out.str(), env); + throwAssertionError(pos, "assertion '%1%' failed", out.str(), env, this); } body->eval(state, env, v); } @@ -1915,7 +1926,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) } else { std::cerr << "envtype: " << showType(env.values[0]->type()) << std::endl; - throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), env); + throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), env, this); } } else if (firstType == nFloat) { if (vTmp.type() == nInt) { @@ -1923,7 +1934,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), env); + throwEvalError(pos, "cannot add %1% to a float", showType(vTmp), env, this); } else s << state.coerceToString(pos, vTmp, context, false, firstType == nString); } @@ -1984,7 +1995,7 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nInt) throwTypeError(pos, "value is %1% while an integer was expected", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); return v.integer; } @@ -1997,7 +2008,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) return v.integer; else if (v.type() != nFloat) throwTypeError(pos, "value is %1% while a float was expected", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); return v.fpoint; } @@ -2008,7 +2019,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nBool) throwTypeError(pos, "value is %1% while a Boolean was expected", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); return v.boolean; } @@ -2025,7 +2036,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) throwTypeError(pos, "value is %1% while a function was expected", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); } @@ -2035,7 +2046,7 @@ string EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nString) { throwTypeError(pos, "value is %1% while a string was expected", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); } return string(v.string.s); @@ -2089,13 +2100,13 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], // b.has_value() ? mapBindings(*b.get()) : map0()); - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], // b.has_value() ? mapBindings(*b.get()) : map0()); - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); } return s; @@ -2169,7 +2180,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string", - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -2201,7 +2212,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } throwTypeError(pos, "cannot coerce %1% to a string", v, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); } @@ -2211,7 +2222,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) if (nix::isDerivation(path)) throwEvalError("file names are not allowed to end in '%1%'", drvExtension, - fakeEnv(1)); + fakeEnv(1), 0); // map0()); Path dstPath; @@ -2237,7 +2248,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) string path = coerceToString(pos, v, context, false, false); if (path == "" || path[0] != '/') throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, - fakeEnv(1)); + fakeEnv(1), 0); // map1("value", &v)); return path; } @@ -2320,7 +2331,7 @@ bool EvalState::eqValues(Value & v1, Value & v2) throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), - fakeEnv(1)); + fakeEnv(1), 0); // map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From 98eb13691a16d9472b822a92f32b439a6ee6e288 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 Oct 2021 16:32:43 -0600 Subject: print staticenv bindings --- src/libexpr/eval.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 76c038593..fba5f5031 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -712,6 +712,34 @@ void printStaticEnvBindings(const Expr &expr) } +void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) +{ + // add bindings for the next level up first. + if (env.up && se.up) { + mapStaticEnvBindings( *se.up, *env.up,vm); + } + + // iterate through staticenv bindings. + + auto map = valmap(); + for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + { + map[iter->first] = env.values[iter->second]; + } + + vm.merge(map); + +} + + +valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) +{ + auto vm = new valmap(); + mapStaticEnvBindings(se, env, *vm); + return vm; +} + + void printEnvPosChain(const Env &env, int lv ) { std::cout << "printEnvPosChain " << lv << std::endl; -- cgit v1.2.3 From 427fb8d1581d7b20b0f5205cc59f3857275860c1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 11 Oct 2021 16:48:10 -0600 Subject: comment out debugs --- src/libexpr/eval.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index fba5f5031..12f7e8979 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -742,13 +742,13 @@ valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) void printEnvPosChain(const Env &env, int lv ) { - std::cout << "printEnvPosChain " << lv << std::endl; + // std::cout << "printEnvPosChain " << lv << std::endl; - std::cout << "env" << env.values[0] << std::endl; + // std::cout << "env" << env.values[0] << std::endl; if (env.values[0] && env.values[0]->type() == nAttrs) { - std::cout << "im in the loop" << std::endl; - std::cout << "pos " << env.values[0]->attrs->pos << std::endl; + // std::cout << "im in the loop" << std::endl; + // std::cout << "pos " << env.values[0]->attrs->pos << std::endl; if (env.values[0]->attrs->pos) { ErrPos ep(*env.values[0]->attrs->pos); auto loc = getCodeLines(ep); @@ -760,7 +760,7 @@ void printEnvPosChain(const Env &env, int lv ) } } - std::cout << "next env : " << env.up << std::endl; + // std::cout << "next env : " << env.up << std::endl; if (env.up) { printEnvPosChain(*env.up, ++lv); @@ -970,7 +970,7 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { - std::cout << "throwUndefinedVarError" << std::endl; + // std::cout << "throwUndefinedVarError" << std::endl; // auto delenv = std::unique_ptr(env); auto error = UndefinedVarError({ @@ -978,7 +978,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * .errPos = pos }); - std::cout << "pre debuggerHook" << std::endl; + // std::cout << "pre debuggerHook" << std::endl; if (debuggerHook && expr) debuggerHook(error, env, *expr); @@ -1038,7 +1038,7 @@ void mkPath(Value & v, const char * s) inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) { - std::cout << " EvalState::lookupVar" << var << std::endl; + // std::cout << " EvalState::lookupVar" << var << std::endl; for (size_t l = var.level; l; --l, env = env->up) ; @@ -1058,7 +1058,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - std::cout << "pre throwUndefinedVarError" << std::endl; + // std::cout << "pre throwUndefinedVarError" << std::endl; throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, 0); } for (size_t l = env->prevWith; l; --l, env = env->up) ; -- cgit v1.2.3 From cbc2f0fe31576a6403e179bdbbaf9aefa113555b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 22 Oct 2021 14:02:47 -0600 Subject: remove dead code --- src/libexpr/eval.cc | 157 ---------------------------------------------------- 1 file changed, 157 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 12f7e8979..f286cbeec 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -619,75 +619,7 @@ std::optional EvalState::getDoc(Value & v) return {}; } -// typedef std::map valmap; - -/*void addEnv(Value * v, valmap &vmap) -{ - if (v.isThunk()) { - Env * env = v.thunk.env; - - Expr * expr = v.thunk.expr; - -} -*/ -// LocalNoInline(valmap * map0()) -// { -// return new valmap(); -// } - -// LocalNoInline(valmap * map1(const char *name, Value *v)) -// { -// return new valmap({{name, v}}); -// } - -// LocalNoInline(valmap * map2(const char *name1, Value *v1, const char *name2, Value *v2)) -// { -// return new valmap({{name1, v1}, {name2, v2}}); -// } - -// LocalNoInline(valmap * mapBindings(Bindings &b)) -// { -// auto map = new valmap(); -// for (auto i = b.begin(); i != b.end(); ++i) -// { -// std::string s = i->name; -// (*map)[s] = i->value; -// } -// return map; -// } - -// LocalNoInline(void addBindings(string prefix, Bindings &b, valmap &valmap)) -// { -// for (auto i = b.begin(); i != b.end(); ++i) -// { -// std::string s = prefix; -// s += i->name; -// valmap[s] = i->value; -// } -// } - -void printEnvBindings(const Env &env, int lv ) -{ - std::cout << "env " << lv << " type: " << env.type << std::endl; - if (env.values[0]->type() == nAttrs) { - Bindings::iterator j = env.values[0]->attrs->begin(); - - - while (j != env.values[0]->attrs->end()) { - std::cout << lv << " env binding: " << j->name << std::endl; - // if (countCalls && j->pos) attrSelects[*j->pos]++; - // return j->value; - j++; - } - - } - std::cout << "next env : " << env.up << std::endl; - - if (env.up) { - printEnvBindings(*env.up, ++lv); - } -} void printStaticEnvBindings(const StaticEnv &se, int lvl) { @@ -740,95 +672,6 @@ valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) } -void printEnvPosChain(const Env &env, int lv ) -{ - // std::cout << "printEnvPosChain " << lv << std::endl; - - // std::cout << "env" << env.values[0] << std::endl; - - if (env.values[0] && env.values[0]->type() == nAttrs) { - // std::cout << "im in the loop" << std::endl; - // std::cout << "pos " << env.values[0]->attrs->pos << std::endl; - if (env.values[0]->attrs->pos) { - ErrPos ep(*env.values[0]->attrs->pos); - auto loc = getCodeLines(ep); - if (loc) - printCodeLines(std::cout, - std::__cxx11::to_string(lv), - ep, - *loc); - } - } - - // std::cout << "next env : " << env.up << std::endl; - - if (env.up) { - printEnvPosChain(*env.up, ++lv); - } -} - -void mapEnvBindings(const Env &env, valmap & vm) -{ - // add bindings for the next level up first. - if (env.up) { - mapEnvBindings(*env.up, vm); - } - - // merge - and write over - higher level bindings. - // note; skipping HasWithExpr that haven't been evaled yet. - if (env.values[0] && env.values[0]->type() == nAttrs) { - auto map = valmap(); - - Bindings::iterator j = env.values[0]->attrs->begin(); - - while (j != env.values[0]->attrs->end()) { - map[j->name] = j->value; - j++; - } - vm.merge(map); - } -} - - -valmap * mapEnvBindings(const Env &env) -{ - auto vm = new valmap(); - - mapEnvBindings(env, *vm); - - return vm; -} - -// LocalNoInline(valmap * mapEnvBindings(Env &env)) -// { -// // NOT going to use this -// if (env.valuemap) { -// std::cout << "got static env" << std::endl; -// } - -// // std::cout << "envsize: " << env.values.size() << std::endl; - -// // std::cout << "size_t size: " << sizeof(size_t) << std::endl; -// // std::cout << "envsize: " << env.size << std::endl; -// // std::cout << "envup: " << env.up << std::endl; - -// valmap *vm = env.up ? mapEnvBindings(*env.up) : new valmap(); - -// /* -// size_t i=0; -// do { -// std::cout << "env: " << i << " value: " << showType(*env.values[i]) << std::endl; -// // std::cout << *env.values[i] << std::endl; -// ++i; -// } while(i < (std::min(env.size, (size_t)100))); - - -// if (env.values[0]->type() == nAttrs) -// addBindings(std::to_string((int)env.size), *env.values[0]->attrs, *vm); -// */ -// return vm; -// } - /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing -- cgit v1.2.3 From e54f17eb46bc487abc38e70dfc2f1c617fb59d32 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 22 Oct 2021 14:27:04 -0600 Subject: remove more debug code --- src/libexpr/eval.cc | 98 +++++------------------------------------------------ 1 file changed, 8 insertions(+), 90 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f286cbeec..73609c3d2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -35,7 +35,6 @@ namespace nix { -// std::function & env)> debuggerHook; std::function debuggerHook; static char * dupString(const char * s) @@ -407,7 +406,8 @@ EvalState::EvalState(const Strings & _searchPath, ref store) assert(gcInitialised); - static_assert(sizeof(Env) <= 16 + sizeof(std::unique_ptr), "environment must be <= 16 bytes"); + // static_assert(sizeof(Env) <= 16 + sizeof(std::unique_ptr), "environment must be <= 16 bytes"); + static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes"); /* Initialise the Nix expression search path. */ if (!evalSettings.pureEval) { @@ -646,13 +646,13 @@ void printStaticEnvBindings(const Expr &expr) void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) { - // add bindings for the next level up first. + // add bindings for the next level up first, so that the bindings for this level + // override the higher levels. if (env.up && se.up) { mapStaticEnvBindings( *se.up, *env.up,vm); } - // iterate through staticenv bindings. - + // iterate through staticenv bindings and add them. auto map = valmap(); for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) { @@ -679,7 +679,6 @@ valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2); if (debuggerHook && expr) @@ -689,7 +688,6 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos @@ -703,7 +701,6 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = EvalError(s, s2, s3); if (debuggerHook && expr) @@ -714,7 +711,6 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, s2, s3), .errPos = pos @@ -729,7 +725,6 @@ 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, Env & env, Expr *expr)) { // p1 is where the error occurred; p2 is a position mentioned in the message. - // auto delenv = std::unique_ptr(env); auto error = EvalError({ .msg = hintfmt(s, sym, p2), .errPos = p1 @@ -743,7 +738,6 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s), .errPos = pos @@ -757,7 +751,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos @@ -771,7 +764,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, s2), .errPos = pos @@ -785,7 +777,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), .errPos = pos @@ -799,7 +790,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = AssertionError({ .msg = hintfmt(s, s1), .errPos = pos @@ -813,16 +803,11 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { - // std::cout << "throwUndefinedVarError" << std::endl; - - // auto delenv = std::unique_ptr(env); auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); - // std::cout << "pre debuggerHook" << std::endl; - if (debuggerHook && expr) debuggerHook(error, env, *expr); @@ -831,7 +816,6 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { - // auto delenv = std::unique_ptr(env); auto error = MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = pos @@ -881,8 +865,6 @@ void mkPath(Value & v, const char * s) inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) { - // std::cout << " EvalState::lookupVar" << var << std::endl; - for (size_t l = var.level; l; --l, env = env->up) ; if (!var.fromWith) return env->values[var.displ]; @@ -901,7 +883,6 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - // std::cout << "pre throwUndefinedVarError" << std::endl; throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, 0); } for (size_t l = env->prevWith; l; --l, env = env->up) ; @@ -930,25 +911,9 @@ Env & EvalState::allocEnv(size_t size) nrEnvs++; nrValuesInEnvs += size; - // if (debuggerHook) - // { - // Env * env = (Env *) allocBytes(sizeof(DebugEnv) + size * sizeof(Value *)); - // // Env * env = new DebugEnv; - // env->type = Env::Plain; - // /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ - - // return *env; - // } else { - Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); - env->type = Env::Plain; - // env->size = size; - - /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ - - return *env; - // } - - + Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); + env->type = Env::Plain; + return *env; } Env & fakeEnv(size_t size) @@ -1237,7 +1202,6 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) if (j != v.attrs->end()) throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, env, this); - // map1("value", &v)); // TODO dynamicAttrs to env? i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ @@ -1594,8 +1558,6 @@ values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, *fun.lambda.env, fun.lambda.fun); - // mapBindings(args)); - // map1("fun", &fun)); // todo add bindings + fun } } } @@ -1608,25 +1570,12 @@ https://nixos.org/manual/nix/stable/#ss-functions.)", void ExprWith::eval(EvalState & state, Env & env, Value & v) { - // std::cout << "ExprWith::eval" << std::endl; Env & env2(state.allocEnv(1)); env2.up = &env; env2.prevWith = prevWith; env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; // ok DAG nasty. just smoosh this in. // presumably evaluate later, lazily. - // std::cout << "ExprWith::eval2" << std::endl; - - // can't load the valuemap until they've been evaled, which is not yet. - // if (debuggerHook) { - // std::cout << "ExprWith::eval3.0" << std::endl; - // std::cout << "ExprWith attrs" << *attrs << std::endl; - // state.forceAttrs(*(Value*) attrs); - // std::cout << "ExprWith::eval3.5" << std::endl; - // env2.valuemap.reset(mapBindings(*env2.values[0]->attrs)); - // std::cout << "ExprWith::eval4" << std::endl; - // } - body->eval(state, env2, v); } @@ -1867,7 +1816,6 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) if (v.type() != nInt) throwTypeError(pos, "value is %1% while an integer was expected", v, fakeEnv(1), 0); - // map1("value", &v)); return v.integer; } @@ -1880,7 +1828,6 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) else if (v.type() != nFloat) throwTypeError(pos, "value is %1% while a float was expected", v, fakeEnv(1), 0); - // map1("value", &v)); return v.fpoint; } @@ -1891,7 +1838,6 @@ bool EvalState::forceBool(Value & v, const Pos & pos) if (v.type() != nBool) throwTypeError(pos, "value is %1% while a Boolean was expected", v, fakeEnv(1), 0); - // map1("value", &v)); return v.boolean; } @@ -1908,7 +1854,6 @@ void EvalState::forceFunction(Value & v, const Pos & pos) if (v.type() != nFunction && !isFunctor(v)) throwTypeError(pos, "value is %1% while a function was expected", v, fakeEnv(1), 0); - // map1("value", &v)); } @@ -1918,7 +1863,6 @@ string EvalState::forceString(Value & v, const Pos & pos) if (v.type() != nString) { throwTypeError(pos, "value is %1% while a string was expected", v, fakeEnv(1), 0); - // map1("value", &v)); } return string(v.string.s); } @@ -1970,37 +1914,15 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], - // b.has_value() ? mapBindings(*b.get()) : map0()); fakeEnv(1), 0); - // map1("value", &v)); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], - // b.has_value() ? mapBindings(*b.get()) : map0()); fakeEnv(1), 0); - // map1("value", &v)); } return s; } -/*string EvalState::forceStringNoCtx(std::optional b, Value & v, const Pos & pos) -{ - string s = forceString(v, pos); - if (v.string.context) { - if (pos) - throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], - b.has_value() ? mapBindings(*b.get()) : map0()); - // map1("value", &v)); - else - throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], - b.has_value() ? mapBindings(*b.get()) : map0()); - // map1("value", &v)); - } - return s; -}*/ - bool EvalState::isDerivation(Value & v) { @@ -2084,7 +2006,6 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, throwTypeError(pos, "cannot coerce %1% to a string", v, fakeEnv(1), 0); - // map1("value", &v)); } @@ -2094,7 +2015,6 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) throwEvalError("file names are not allowed to end in '%1%'", drvExtension, fakeEnv(1), 0); - // map0()); Path dstPath; auto i = srcToStore.find(path); @@ -2120,7 +2040,6 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) if (path == "" || path[0] != '/') throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, fakeEnv(1), 0); - // map1("value", &v)); return path; } @@ -2203,7 +2122,6 @@ bool EvalState::eqValues(Value & v1, Value & v2) showType(v1), showType(v2), fakeEnv(1), 0); - // map2("value1", &v1, "value2", &v2)); } } -- cgit v1.2.3 From 71da988d47433543e70cd52dbdd6c907dd3cabda Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 22 Oct 2021 14:34:50 -0600 Subject: more debug removal --- src/libexpr/eval.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 73609c3d2..719dcc1b4 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -406,7 +406,6 @@ EvalState::EvalState(const Strings & _searchPath, ref store) assert(gcInitialised); - // static_assert(sizeof(Env) <= 16 + sizeof(std::unique_ptr), "environment must be <= 16 bytes"); static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes"); /* Initialise the Nix expression search path. */ @@ -1574,8 +1573,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.up = &env; env2.prevWith = prevWith; env2.type = Env::HasWithExpr; - env2.values[0] = (Value *) attrs; // ok DAG nasty. just smoosh this in. - // presumably evaluate later, lazily. + env2.values[0] = (Value *) attrs; body->eval(state, env2, v); } -- cgit v1.2.3 From fb8377547bcb6d4dc6464ca34c0fe433e1cfda44 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 22 Oct 2021 14:49:58 -0600 Subject: more code cleanup --- src/libexpr/eval.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 719dcc1b4..4dde92c0a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -912,6 +912,9 @@ Env & EvalState::allocEnv(size_t size) nrValuesInEnvs += size; Env * env = (Env *) allocBytes(sizeof(Env) + size * sizeof(Value *)); env->type = Env::Plain; + + /* We assume that env->values has been cleared by the allocator; maybeThunk() and lookupVar fromWith expect this. */ + return *env; } @@ -925,7 +928,6 @@ Env & fakeEnv(size_t size) return *env; } - void EvalState::mkList(Value & v, size_t size) { v.mkList(size); @@ -1291,7 +1293,6 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) throwEvalError(pos, "attribute '%1%' missing", name, env, this); - // mapBindings(*vAttrs->attrs)); } vAttrs = j->value; pos2 = j->pos; @@ -1419,8 +1420,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po "attempt to call something which is not a function but %1%", showType(fun).c_str(), fakeEnv(1), 0); - // fun.env); - // map2("fun", &fun, "arg", &arg)); } ExprLambda & lambda(*fun.lambda.fun); -- cgit v1.2.3 From 885f819922d7c4b3823090ca4c9ee832f5080bde Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 9 Nov 2021 11:20:14 -0700 Subject: remove dead code --- src/libexpr/eval.cc | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 4dde92c0a..32d51ab87 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1433,8 +1433,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po size_t displ = 0; if (!lambda.matchAttrs){ - // TODO: what is this arg? empty argument? - // add empty valmap here? env2.values[displ++] = &arg; } else { @@ -1457,7 +1455,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po lambda, i.name, *fun.lambda.env, &lambda); - // map2("fun", &fun, "arg", &arg)); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1478,7 +1475,6 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & po lambda, i.name, *fun.lambda.env, &lambda); - // map2("fun", &fun, "arg", &arg)); abort(); // can't happen } } @@ -1971,7 +1967,6 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, if (i == v.attrs->end()) throwTypeError(pos, "cannot coerce a set to a string", fakeEnv(1), 0); - // map1("value", &v)); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } -- cgit v1.2.3 From 7e2a3db4eb663aa99aec7ebcc83d75cb948a2cb3 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 9 Nov 2021 13:14:49 -0700 Subject: cleanup --- src/libexpr/eval.cc | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 32d51ab87..8e263334a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -78,8 +78,6 @@ void printValue(std::ostream & str, std::set & active, const Valu return; } - str << "internal type: " << v.internalType << std::endl; - switch (v.internalType) { case tInt: str << v.integer; @@ -1569,7 +1567,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v) env2.prevWith = prevWith; env2.type = Env::HasWithExpr; env2.values[0] = (Value *) attrs; - + body->eval(state, env2, v); } @@ -1737,8 +1735,6 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } else { - std::cerr << "envtype: " << showType(env.values[0]->type()) << std::endl; - throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp), env, this); } } else if (firstType == nFloat) { @@ -1829,7 +1825,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v, + throwTypeError(pos, "value is %1% while a Boolean was expected", v, fakeEnv(1), 0); return v.boolean; } @@ -1906,12 +1902,10 @@ string EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], - fakeEnv(1), 0); + v.string.s, v.string.context[0], fakeEnv(1), 0); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], - fakeEnv(1), 0); + v.string.s, v.string.context[0], fakeEnv(1), 0); } return s; } @@ -1965,7 +1959,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) - throwTypeError(pos, "cannot coerce a set to a string", + throwTypeError(pos, "cannot coerce a set to a string", fakeEnv(1), 0); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -1996,7 +1990,7 @@ string EvalState::coerceToString(const Pos & pos, Value & v, PathSet & context, } } - throwTypeError(pos, "cannot coerce %1% to a string", v, + throwTypeError(pos, "cannot coerce %1% to a string", v, fakeEnv(1), 0); } @@ -2030,7 +2024,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) { string path = coerceToString(pos, v, context, false, false); 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, fakeEnv(1), 0); return path; } -- cgit v1.2.3 From 69e26c5c4ba106bd16f60bfaac88ccf888b4383f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 25 Nov 2021 08:23:07 -0700 Subject: more cleanup --- src/libexpr/eval.cc | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8e263334a..11a61da26 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -620,7 +620,7 @@ std::optional EvalState::getDoc(Value & v) void printStaticEnvBindings(const StaticEnv &se, int lvl) { - for (auto i = se.vars.begin(); i != se.vars.end(); ++i) + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { std::cout << lvl << i->first << std::endl; } @@ -628,22 +628,21 @@ void printStaticEnvBindings(const StaticEnv &se, int lvl) if (se.up) { printStaticEnvBindings(*se.up, ++lvl); } - + } void printStaticEnvBindings(const Expr &expr) { - // just print the names for now - if (expr.staticenv) - { - printStaticEnvBindings(*expr.staticenv.get(), 0); - } - + // just print the names for now + if (expr.staticenv) + { + printStaticEnvBindings(*expr.staticenv.get(), 0); + } } void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) { - // add bindings for the next level up first, so that the bindings for this level + // add bindings for the next level up first, so that the bindings for this level // override the higher levels. if (env.up && se.up) { mapStaticEnvBindings( *se.up, *env.up,vm); @@ -651,13 +650,13 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) // iterate through staticenv bindings and add them. auto map = valmap(); - for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) { - map[iter->first] = env.values[iter->second]; + map[iter->first] = env.values[iter->second]; } vm.merge(map); - + } -- cgit v1.2.3 From e82aec4efcd06cbd60d57f401fb7e93ab595128c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 30 Nov 2021 14:15:02 -0700 Subject: fix merge issues --- src/libexpr/eval.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index a20123f34..8737930b5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -591,7 +591,7 @@ Value * EvalState::addConstant(const string & name, Value & v) void EvalState::addConstant(const string & name, Value * v) { - staticBaseEnv.vars.emplace_back(symbols.create(name), baseEnvDispl); + staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl); baseEnv.values[baseEnvDispl++] = v; string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; baseEnv.values[0]->attrs->push_back(Attr(symbols.create(name2), v)); @@ -1459,7 +1459,8 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & user. */ for (auto & i : *args[0]->attrs) if (lambda.formals->argNames.find(i.name) == lambda.formals->argNames.end()) - throwTypeError(pos, "%1% called with unexpected argument '%2%'", lambda, i.name); + throwTypeError(pos, "%1% called with unexpected argument '%2%'", + lambda, i.name, *fun.lambda.env, &lambda); abort(); // can't happen } } -- cgit v1.2.3 From b4a59a5eec5bdb94ee2bbc8365f024d5787abd60 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Dec 2021 15:38:49 -0700 Subject: DebugStackTracker class in one place --- src/libexpr/eval.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8737930b5..00d2c1643 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -854,13 +855,20 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { + std::cout << "throwUndefinedVarError" << std::endl; + + std::cout << "loggerSettings.showTrace: " << loggerSettings.showTrace << std::endl; + auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); - if (debuggerHook && expr) + if (debuggerHook && expr) { + + std::cout << "throwUndefinedVarError debuggerHook" << std::endl; debuggerHook(error, env, *expr); + } throw error; } @@ -888,6 +896,16 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con e.addTrace(pos, s, s2); } +// LocalNoInline(void makeErrorTrace(Error & e, const char * s, const string & s2)) +// { +// Trace { .pos = e, .hint = hint } +// } + +// LocalNoInline(void makeErrorTrace(Error & e, const Pos & pos, const char * s, const string & s2)) +// { +// return Trace { .pos = e, .hint = hintfmt(s, s2); }; +// } + void mkString(Value & v, const char * s) { v.mkString(dupString(s)); @@ -934,7 +952,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, 0); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, (Expr*)&var); } for (size_t l = env->prevWith; l; --l, env = env->up) ; } @@ -1092,6 +1110,39 @@ void EvalState::resetFileCache() fileParseCache.clear(); } +class DebugTraceStacker { + public: + DebugTraceStacker(EvalState &evalState, Trace t) + :evalState(evalState), trace(t) + { + evalState.debugTraces.push_front(t); + } + ~DebugTraceStacker() { + // assert(evalState.debugTraces.front() == trace); + evalState.debugTraces.pop_front(); + } + + EvalState &evalState; + Trace trace; + +}; + +// class DebugTraceStacker { +// DebugTraceStacker(std::ref evalState, std::ref t) +// :evalState(evalState), trace(t) +// { +// evalState->debugTraces.push_front(t); +// } +// ~DebugTraceStacker() { +// assert(evalState->debugTraces.pop_front() == trace); +// } + +// std::ref evalState; +// std::ref trace; + +// }; + + void EvalState::cacheFile( const Path & path, @@ -1103,6 +1154,15 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { + std::unique_ptr dts = debuggerHook ? + std::unique_ptr(new DebugTraceStacker(*this, + Trace { .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), + .hint = hintfmt("while evaluating the file '%1%':", resolvedPath) + } + )) : std::unique_ptr(); + + // Trace( .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())): + // std::nullopt), hintfmt("while evaluating the file '%1%':", resolvedPath)); // Enforce that 'flake.nix' is a direct attrset, not a // computation. if (mustBeTrivial && @@ -1472,6 +1532,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { lambda.body->eval(*this, env2, vCur); } catch (Error & e) { + std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl; if (loggerSettings.showTrace.get()) { addErrorTrace(e, lambda.pos, "while evaluating %s", (lambda.name.set() -- cgit v1.2.3 From bc20e54e0044e08c68a7af1f1e12d001baba8a74 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 22 Dec 2021 19:40:08 -0700 Subject: stack traces basically working --- src/libexpr/eval.cc | 72 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 17 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 00d2c1643..c46113560 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -38,6 +38,23 @@ namespace nix { std::function debuggerHook; +class DebugTraceStacker { + public: + DebugTraceStacker(EvalState &evalState, Trace t) + :evalState(evalState), trace(t) + { + evalState.debugTraces.push_front(t); + } + ~DebugTraceStacker() { + // assert(evalState.debugTraces.front() == trace); + evalState.debugTraces.pop_front(); + } + + EvalState &evalState; + Trace trace; + +}; + static char * dupString(const char * s) { char * t; @@ -1110,23 +1127,6 @@ void EvalState::resetFileCache() fileParseCache.clear(); } -class DebugTraceStacker { - public: - DebugTraceStacker(EvalState &evalState, Trace t) - :evalState(evalState), trace(t) - { - evalState.debugTraces.push_front(t); - } - ~DebugTraceStacker() { - // assert(evalState.debugTraces.front() == trace); - evalState.debugTraces.pop_front(); - } - - EvalState &evalState; - Trace trace; - -}; - // class DebugTraceStacker { // DebugTraceStacker(std::ref evalState, std::ref t) // :evalState(evalState), trace(t) @@ -1387,6 +1387,17 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { + std::unique_ptr dts = + debuggerHook ? + std::unique_ptr( + new DebugTraceStacker( + state, + Trace { .pos = *pos2, + .hint = hintfmt( + "while evaluating the attribute '%1%'", + showAttrPath(state, env, attrPath)) + })) + : std::unique_ptr(); for (auto & i : attrPath) { state.nrLookups++; @@ -1530,6 +1541,21 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { + std::unique_ptr dts = + debuggerHook ? + std::unique_ptr( + new DebugTraceStacker( + *this, + Trace { .pos = lambda.pos, + .hint = hintfmt( + "while evaluating %s", + (lambda.name.set() + ? "'" + (string) lambda.name + "'" + : "anonymous lambda")) + })) + : std::unique_ptr(); + + lambda.body->eval(*this, env2, vCur); } catch (Error & e) { std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl; @@ -1924,6 +1950,18 @@ void EvalState::forceValueDeep(Value & v) if (v.type() == nAttrs) { for (auto & i : *v.attrs) try { + std::unique_ptr dts = + debuggerHook ? + std::unique_ptr( + new DebugTraceStacker( + *this, + Trace { .pos = *i.pos, + .hint = hintfmt( + "while evaluating the attribute '%1%'", i.name) + })) + : std::unique_ptr(); + + recurse(*i.value); } catch (Error & e) { addErrorTrace(e, *i.pos, "while evaluating the attribute '%1%'", i.name); -- cgit v1.2.3 From 1bda6a01e1cb4d2b22ff2256fcbde044e2f04d24 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Dec 2021 08:14:17 -0700 Subject: indenting --- src/libexpr/eval.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c46113560..15eaef667 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1542,18 +1542,18 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { std::unique_ptr dts = - debuggerHook ? - std::unique_ptr( - new DebugTraceStacker( - *this, - Trace { .pos = lambda.pos, - .hint = hintfmt( - "while evaluating %s", - (lambda.name.set() - ? "'" + (string) lambda.name + "'" - : "anonymous lambda")) - })) - : std::unique_ptr(); + debuggerHook ? + std::unique_ptr( + new DebugTraceStacker( + *this, + Trace {.pos = lambda.pos, + .hint = hintfmt( + "while evaluating %s", + (lambda.name.set() + ? "'" + (string) lambda.name + "'" + : "anonymous lambda")) + })) + : std::unique_ptr(); lambda.body->eval(*this, env2, vCur); -- cgit v1.2.3 From deb1fd66e8c884937827813c079135532913ca86 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Dec 2021 09:08:41 -0700 Subject: makeDebugTraceStacker --- src/libexpr/eval.cc | 93 ++++++++++++++++++----------------------------------- 1 file changed, 31 insertions(+), 62 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 15eaef667..d7deb550e 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -49,10 +49,8 @@ class DebugTraceStacker { // assert(evalState.debugTraces.front() == trace); evalState.debugTraces.pop_front(); } - EvalState &evalState; Trace trace; - }; static char * dupString(const char * s) @@ -882,8 +880,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); if (debuggerHook && expr) { - - std::cout << "throwUndefinedVarError debuggerHook" << std::endl; + std::cout << "throwUndefinedVarError debuggerHook" << std::endl; debuggerHook(error, env, *expr); } @@ -913,15 +910,17 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con e.addTrace(pos, s, s2); } -// LocalNoInline(void makeErrorTrace(Error & e, const char * s, const string & s2)) -// { -// Trace { .pos = e, .hint = hint } -// } +LocalNoInline(std::unique_ptr + makeDebugTraceStacker(EvalState &state, std::optional pos, const char * s, const string & s2)) +{ + return std::unique_ptr( + new DebugTraceStacker( + state, + Trace {.pos = pos, + .hint = hintfmt(s, s2) + })); +} -// LocalNoInline(void makeErrorTrace(Error & e, const Pos & pos, const char * s, const string & s2)) -// { -// return Trace { .pos = e, .hint = hintfmt(s, s2); }; -// } void mkString(Value & v, const char * s) { @@ -1127,20 +1126,6 @@ void EvalState::resetFileCache() fileParseCache.clear(); } -// class DebugTraceStacker { -// DebugTraceStacker(std::ref evalState, std::ref t) -// :evalState(evalState), trace(t) -// { -// evalState->debugTraces.push_front(t); -// } -// ~DebugTraceStacker() { -// assert(evalState->debugTraces.pop_front() == trace); -// } - -// std::ref evalState; -// std::ref trace; - -// }; @@ -1154,15 +1139,14 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { - std::unique_ptr dts = debuggerHook ? - std::unique_ptr(new DebugTraceStacker(*this, - Trace { .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), - .hint = hintfmt("while evaluating the file '%1%':", resolvedPath) - } - )) : std::unique_ptr(); + std::unique_ptr dts = + debuggerHook ? + makeDebugTraceStacker( + *this, + (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), + "while evaluating the file '%1%':", resolvedPath) + : std::unique_ptr(); - // Trace( .pos = (e->getPos() ? std::optional(ErrPos(*e->getPos())): - // std::nullopt), hintfmt("while evaluating the file '%1%':", resolvedPath)); // Enforce that 'flake.nix' is a direct attrset, not a // computation. if (mustBeTrivial && @@ -1387,16 +1371,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { - std::unique_ptr dts = - debuggerHook ? - std::unique_ptr( - new DebugTraceStacker( - state, - Trace { .pos = *pos2, - .hint = hintfmt( - "while evaluating the attribute '%1%'", - showAttrPath(state, env, attrPath)) - })) + std::unique_ptr dts = + debuggerHook ? + makeDebugTraceStacker( + state, + *pos2, + "while evaluating the attribute '%1%'", + showAttrPath(state, env, attrPath)) : std::unique_ptr(); for (auto & i : attrPath) { @@ -1541,21 +1522,15 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - std::unique_ptr dts = - debuggerHook ? - std::unique_ptr( - new DebugTraceStacker( - *this, - Trace {.pos = lambda.pos, - .hint = hintfmt( + std::unique_ptr dts = + debuggerHook ? + makeDebugTraceStacker(*this, lambda.pos, "while evaluating %s", (lambda.name.set() ? "'" + (string) lambda.name + "'" : "anonymous lambda")) - })) : std::unique_ptr(); - lambda.body->eval(*this, env2, vCur); } catch (Error & e) { std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl; @@ -1950,18 +1925,12 @@ void EvalState::forceValueDeep(Value & v) if (v.type() == nAttrs) { for (auto & i : *v.attrs) try { - std::unique_ptr dts = - debuggerHook ? - std::unique_ptr( - new DebugTraceStacker( - *this, - Trace { .pos = *i.pos, - .hint = hintfmt( + std::unique_ptr dts = + debuggerHook ? + makeDebugTraceStacker(*this, *i.pos, "while evaluating the attribute '%1%'", i.name) - })) : std::unique_ptr(); - recurse(*i.value); } catch (Error & e) { addErrorTrace(e, *i.pos, "while evaluating the attribute '%1%'", i.name); -- cgit v1.2.3 From e5eebda19475ab4f25346128e5428c27e526c7ce Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 23 Dec 2021 13:36:39 -0700 Subject: DebugTrace --- src/libexpr/eval.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d7deb550e..b8d060276 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -40,7 +40,7 @@ std::function deb class DebugTraceStacker { public: - DebugTraceStacker(EvalState &evalState, Trace t) + DebugTraceStacker(EvalState &evalState, DebugTrace t) :evalState(evalState), trace(t) { evalState.debugTraces.push_front(t); @@ -50,7 +50,7 @@ class DebugTraceStacker { evalState.debugTraces.pop_front(); } EvalState &evalState; - Trace trace; + DebugTrace trace; }; static char * dupString(const char * s) @@ -911,12 +911,14 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con } LocalNoInline(std::unique_ptr - makeDebugTraceStacker(EvalState &state, std::optional pos, const char * s, const string & s2)) + makeDebugTraceStacker(EvalState &state, Expr &expr, std::optional pos, const char * s, const string & s2)) { return std::unique_ptr( new DebugTraceStacker( state, - Trace {.pos = pos, + DebugTrace + {.pos = pos, + .expr = expr, .hint = hintfmt(s, s2) })); } @@ -1143,6 +1145,7 @@ void EvalState::cacheFile( debuggerHook ? makeDebugTraceStacker( *this, + *e, (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), "while evaluating the file '%1%':", resolvedPath) : std::unique_ptr(); @@ -1375,6 +1378,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) debuggerHook ? makeDebugTraceStacker( state, + *this, *pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath)) @@ -1524,7 +1528,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { std::unique_ptr dts = debuggerHook ? - makeDebugTraceStacker(*this, lambda.pos, + makeDebugTraceStacker(*this, *lambda.body, lambda.pos, "while evaluating %s", (lambda.name.set() ? "'" + (string) lambda.name + "'" @@ -1925,10 +1929,14 @@ void EvalState::forceValueDeep(Value & v) if (v.type() == nAttrs) { for (auto & i : *v.attrs) try { + std::unique_ptr dts = debuggerHook ? - makeDebugTraceStacker(*this, *i.pos, - "while evaluating the attribute '%1%'", i.name) + // if the value is a thunk, we're evaling. otherwise no trace necessary. + (i.value->isThunk() ? + makeDebugTraceStacker(*this, *v.thunk.expr, *i.pos, + "while evaluating the attribute '%1%'", i.name) + : std::unique_ptr()) : std::unique_ptr(); recurse(*i.value); -- cgit v1.2.3 From d0d589044512a77b345b7e576e2c45910c74eb02 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 13:47:35 -0700 Subject: don't add underscore names to extras --- src/libexpr/eval.cc | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index b8d060276..377e1b2f8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -716,18 +716,34 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) // add bindings for the next level up first, so that the bindings for this level // override the higher levels. if (env.up && se.up) { - mapStaticEnvBindings( *se.up, *env.up,vm); - } + mapStaticEnvBindings( *se.up, *env.up,vm); + + // iterate through staticenv bindings and add them. + auto map = valmap(); + for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + { + map[iter->first] = env.values[iter->second]; + } - // iterate through staticenv bindings and add them. - auto map = valmap(); - for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + vm.merge(map); + } + else { - map[iter->first] = env.values[iter->second]; + std::cout << " -------------------- " << std::endl; + // iterate through staticenv bindings and add them, + // except for the __* ones. + auto map = valmap(); + for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + { + std::cout << iter->first << std::endl; + std::string s = iter->first; + if (s.substr(0,2) != "__") { + map[iter->first] = env.values[iter->second]; + } + } + + vm.merge(map); } - - vm.merge(map); - } -- cgit v1.2.3 From ff82ba98b41eb3e4b1ce96ed02504acea03eb29c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 14:06:04 -0700 Subject: don't add builtins to extras, initEnv() in regular repl --- src/libexpr/eval.cc | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 377e1b2f8..d99e73471 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -715,8 +715,9 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) { // add bindings for the next level up first, so that the bindings for this level // override the higher levels. + // The top level bindings (builtins) are skipped since they are added for us by initEnv() if (env.up && se.up) { - mapStaticEnvBindings( *se.up, *env.up,vm); + mapStaticEnvBindings(*se.up, *env.up,vm); // iterate through staticenv bindings and add them. auto map = valmap(); @@ -725,23 +726,6 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) map[iter->first] = env.values[iter->second]; } - vm.merge(map); - } - else - { - std::cout << " -------------------- " << std::endl; - // iterate through staticenv bindings and add them, - // except for the __* ones. - auto map = valmap(); - for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) - { - std::cout << iter->first << std::endl; - std::string s = iter->first; - if (s.substr(0,2) != "__") { - map[iter->first] = env.values[iter->second]; - } - } - vm.merge(map); } } -- cgit v1.2.3 From 6801a423fc9abdfd2cb7307f2970553bcfad089d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 16:28:45 -0700 Subject: :d env --- src/libexpr/eval.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d99e73471..f1e6cfdf2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -691,10 +691,14 @@ std::optional EvalState::getDoc(Value & v) void printStaticEnvBindings(const StaticEnv &se, int lvl) { + std::cout << "Env level " << lvl << std::endl; + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { - std::cout << lvl << i->first << std::endl; + std::cout << i->first << " "; } + std::cout << std::endl; + std::cout << std::endl; if (se.up) { printStaticEnvBindings(*se.up, ++lvl); @@ -730,7 +734,6 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) } } - valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) { auto vm = new valmap(); -- cgit v1.2.3 From 9760fa8661f7562e0b8979338200904053cc4631 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 17:35:27 -0700 Subject: add DebugTrace for the current error --- src/libexpr/eval.cc | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f1e6cfdf2..4bdcc052f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -38,21 +38,6 @@ namespace nix { std::function debuggerHook; -class DebugTraceStacker { - public: - DebugTraceStacker(EvalState &evalState, DebugTrace t) - :evalState(evalState), trace(t) - { - evalState.debugTraces.push_front(t); - } - ~DebugTraceStacker() { - // assert(evalState.debugTraces.front() == trace); - evalState.debugTraces.pop_front(); - } - EvalState &evalState; - DebugTrace trace; -}; - static char * dupString(const char * s) { char * t; @@ -701,7 +686,7 @@ void printStaticEnvBindings(const StaticEnv &se, int lvl) std::cout << std::endl; if (se.up) { - printStaticEnvBindings(*se.up, ++lvl); + printStaticEnvBindings(*se.up, ++lvl); } } -- cgit v1.2.3 From 4610e02d04c9f41ac355d2ca6a27d3a631ffefc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 18:12:46 -0700 Subject: remove debug code --- src/libexpr/eval.cc | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 4bdcc052f..2596fbe3a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -858,17 +858,12 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { - std::cout << "throwUndefinedVarError" << std::endl; - - std::cout << "loggerSettings.showTrace: " << loggerSettings.showTrace << std::endl; - auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); if (debuggerHook && expr) { - std::cout << "throwUndefinedVarError debuggerHook" << std::endl; debuggerHook(error, env, *expr); } @@ -1525,7 +1520,6 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & lambda.body->eval(*this, env2, vCur); } catch (Error & e) { - std::cout << "eval showErrorInfo showTrace: " << loggerSettings.showTrace.get() << std::endl; if (loggerSettings.showTrace.get()) { addErrorTrace(e, lambda.pos, "while evaluating %s", (lambda.name.set() -- cgit v1.2.3 From 5954cbf3e9dca0e3b84e4bf2def74abb3d6f80cd Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 27 Dec 2021 18:29:55 -0700 Subject: more cleanup --- src/libexpr/eval.cc | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2596fbe3a..ac437e69d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -672,8 +672,6 @@ std::optional EvalState::getDoc(Value & v) return {}; } - - void printStaticEnvBindings(const StaticEnv &se, int lvl) { std::cout << "Env level " << lvl << std::endl; @@ -1112,8 +1110,6 @@ void EvalState::resetFileCache() } - - void EvalState::cacheFile( const Path & path, const Path & resolvedPath, -- cgit v1.2.3 From 1b6b33d43d5fa4675848b39121f681ae330b2b86 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 3 Jan 2022 18:29:43 -0700 Subject: filter out underscore names --- src/libexpr/eval.cc | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 851058b3e..86561c6b0 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -680,16 +680,28 @@ void printStaticEnvBindings(const StaticEnv &se, int lvl) { std::cout << "Env level " << lvl << std::endl; - for (auto i = se.vars.begin(); i != se.vars.end(); ++i) - { - std::cout << i->first << " "; - } - std::cout << std::endl; - std::cout << std::endl; - if (se.up) { + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) + { + std::cout << i->first << " "; + } + std::cout << std::endl; + std::cout << std::endl; + printStaticEnvBindings(*se.up, ++lvl); } + else + { + // for the top level, don't print the double underscore ones; they are in builtins. + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) + { + if (((string)i->first).substr(0,2) != "__") + std::cout << i->first << " "; + } + std::cout << std::endl; + std::cout << std::endl; + + } } -- cgit v1.2.3 From a4d8a799b7dd6b5368b7892747d18911f8ff9ba2 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 5 Jan 2022 12:21:18 -0700 Subject: tidy up debugtraces --- src/libexpr/eval.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 86561c6b0..d9c26106e 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1151,14 +1151,14 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { - std::unique_ptr dts = + auto dts = debuggerHook ? makeDebugTraceStacker( *this, *e, (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), "while evaluating the file '%1%':", resolvedPath) - : std::unique_ptr(); + : nullptr; // Enforce that 'flake.nix' is a direct attrset, not a // computation. @@ -1384,7 +1384,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { - std::unique_ptr dts = + auto dts = debuggerHook ? makeDebugTraceStacker( state, @@ -1392,7 +1392,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) *pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath)) - : std::unique_ptr(); + : nullptr; for (auto & i : attrPath) { state.nrLookups++; @@ -1536,14 +1536,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - std::unique_ptr dts = + auto dts = debuggerHook ? makeDebugTraceStacker(*this, *lambda.body, lambda.pos, "while evaluating %s", (lambda.name.set() ? "'" + (string) lambda.name + "'" : "anonymous lambda")) - : std::unique_ptr(); + : nullptr; lambda.body->eval(*this, env2, vCur); } catch (Error & e) { @@ -1939,14 +1939,14 @@ void EvalState::forceValueDeep(Value & v) for (auto & i : *v.attrs) try { - std::unique_ptr dts = + auto dts = debuggerHook ? // if the value is a thunk, we're evaling. otherwise no trace necessary. (i.value->isThunk() ? makeDebugTraceStacker(*this, *v.thunk.expr, *i.pos, "while evaluating the attribute '%1%'", i.name) - : std::unique_ptr()) - : std::unique_ptr(); + : nullptr) + : nullptr; recurse(*i.value); } catch (Error & e) { -- cgit v1.2.3 From bf8a065be0d0cdccf5b6bc1034dc3e1709b21bd5 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 5 Jan 2022 12:28:31 -0700 Subject: add colors; remove headings --- src/libexpr/eval.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d9c26106e..585042b9d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -679,12 +679,15 @@ std::optional EvalState::getDoc(Value & v) void printStaticEnvBindings(const StaticEnv &se, int lvl) { std::cout << "Env level " << lvl << std::endl; - + if (se.up) { + std::cout << ANSI_MAGENTA; for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { std::cout << i->first << " "; } + std::cout << ANSI_NORMAL; + std::cout << std::endl; std::cout << std::endl; @@ -692,12 +695,14 @@ void printStaticEnvBindings(const StaticEnv &se, int lvl) } else { + std::cout << ANSI_MAGENTA; // for the top level, don't print the double underscore ones; they are in builtins. for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { if (((string)i->first).substr(0,2) != "__") std::cout << i->first << " "; } + std::cout << ANSI_NORMAL; std::cout << std::endl; std::cout << std::endl; -- cgit v1.2.3 From c51b527c280ee08b3ce3ca6d229139c4292b3176 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 7 Jan 2022 16:37:44 -0700 Subject: add env to DebugTrace --- src/libexpr/eval.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 585042b9d..e01147169 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -913,7 +913,7 @@ LocalNoInline(void addErrorTrace(Error & e, const Pos & pos, const char * s, con } LocalNoInline(std::unique_ptr - makeDebugTraceStacker(EvalState &state, Expr &expr, std::optional pos, const char * s, const string & s2)) + makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, std::optional pos, const char * s, const string & s2)) { return std::unique_ptr( new DebugTraceStacker( @@ -921,6 +921,7 @@ LocalNoInline(std::unique_ptr DebugTrace {.pos = pos, .expr = expr, + .env = env, .hint = hintfmt(s, s2) })); } @@ -1161,6 +1162,7 @@ void EvalState::cacheFile( makeDebugTraceStacker( *this, *e, + this->baseEnv, (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), "while evaluating the file '%1%':", resolvedPath) : nullptr; @@ -1394,6 +1396,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) makeDebugTraceStacker( state, *this, + env, *pos2, "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath)) @@ -1543,7 +1546,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { auto dts = debuggerHook ? - makeDebugTraceStacker(*this, *lambda.body, lambda.pos, + makeDebugTraceStacker(*this, *lambda.body, env2, lambda.pos, "while evaluating %s", (lambda.name.set() ? "'" + (string) lambda.name + "'" @@ -1948,7 +1951,7 @@ void EvalState::forceValueDeep(Value & v) debuggerHook ? // if the value is a thunk, we're evaling. otherwise no trace necessary. (i.value->isThunk() ? - makeDebugTraceStacker(*this, *v.thunk.expr, *i.pos, + makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, *i.pos, "while evaluating the attribute '%1%'", i.name) : nullptr) : nullptr; -- cgit v1.2.3 From a963674d88f2f1af6181f126ed4288ec65b61fc6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 8 Jan 2022 11:03:48 -0700 Subject: optinoal error; compiles --- src/libexpr/eval.cc | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e01147169..7b3745e52 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -36,7 +36,7 @@ namespace nix { -std::function debuggerHook; +std::function debuggerHook; static char * dupString(const char * s) { @@ -756,7 +756,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env auto error = EvalError(s, s2); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -768,7 +768,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -778,7 +778,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con auto error = EvalError(s, s2, s3); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -791,7 +791,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -805,7 +805,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -818,7 +818,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -831,7 +831,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -844,7 +844,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -857,7 +857,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -870,7 +870,7 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -883,7 +883,7 @@ LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * }); if (debuggerHook && expr) { - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); } throw error; @@ -897,7 +897,7 @@ LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char }); if (debuggerHook && expr) - debuggerHook(error, env, *expr); + debuggerHook(&error, env, *expr); throw error; } @@ -926,6 +926,13 @@ LocalNoInline(std::unique_ptr })); } +DebugTraceStacker::DebugTraceStacker(EvalState &evalState, DebugTrace t) +:evalState(evalState), trace(t) +{ + evalState.debugTraces.push_front(t); + if (debuggerHook) + debuggerHook(0, t.env, t.expr); +} void mkString(Value & v, const char * s) { -- cgit v1.2.3 From 412d58f0bb65104b0065dbf721a92b9e5dcdcdbb Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 3 Feb 2022 13:15:21 -0700 Subject: break() primop; step and go debug commands --- src/libexpr/eval.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7b3745e52..426cff2d3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -417,6 +417,7 @@ EvalState::EvalState( , repair(NoRepair) , store(store) , buildStore(buildStore ? buildStore : store) + , debugStop(true) , regexCache(makeRegexCache()) , baseEnv(allocEnv(128)) , staticBaseEnv(new StaticEnv(false, 0)) @@ -930,7 +931,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState &evalState, DebugTrace t) :evalState(evalState), trace(t) { evalState.debugTraces.push_front(t); - if (debuggerHook) + if (evalState.debugStop && debuggerHook) debuggerHook(0, t.env, t.expr); } -- cgit v1.2.3 From 195db83148d17484809ca8af0932b1be1803a29a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 4 Feb 2022 17:35:56 -0700 Subject: a few merge fixes --- src/libexpr/eval.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 790b00ace..6c89b87b7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -860,18 +860,18 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env, Expr *expr)) -{ - auto error = TypeError({ - .msg = hintfmt(s, s2), - .errPos = pos - }); +// LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env, Expr *expr)) +// { +// auto error = TypeError({ +// .msg = hintfmt(s, s2), +// .errPos = pos +// }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); +// if (debuggerHook && expr) +// debuggerHook(&error, env, *expr); - throw error; -} +// throw error; +// } LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr *expr)) { @@ -1243,7 +1243,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e) Value v; e->eval(*this, env, v); if (v.type() != nBool) - throwTypeError("value is %1% while a Boolean was expected", v); + throwTypeError(noPos, "value is %1% while a Boolean was expected", v); return v.boolean; } @@ -1262,7 +1262,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v) { e->eval(*this, env, v); if (v.type() != nAttrs) - throwTypeError("value is %1% while a set was expected", v); + throwTypeError(noPos, "value is %1% while a set was expected", v); } -- cgit v1.2.3 From bc67cb5ad12b7d042067ba9727b0b8b37c5f3e53 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 10 Feb 2022 15:05:38 -0700 Subject: remove fakeEnv stuff and instead use last context from the stack --- src/libexpr/eval.cc | 112 ++++++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 52 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6c89b87b7..e584efbfb 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -775,31 +775,39 @@ valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) evaluator. So here are some helper functions for throwing exceptions. */ -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, EvalState &evalState)) { auto error = EvalError(s, s2); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } + throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, EvalState &evalState)) { auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } throw error; } -LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr *expr)) { - auto error = EvalError(s, s2, s3); + auto error = EvalError({ + .msg = hintfmt(s, s2), + .errPos = pos + }); if (debuggerHook && expr) debuggerHook(&error, env, *expr); @@ -807,15 +815,32 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, const string & s3, EvalState &evalState)) { auto error = EvalError({ .msg = hintfmt(s, s2, s3), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } + + throw error; +} + +LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, const string & s3, EvalState &evalState)) +{ + auto error = EvalError({ + .msg = hintfmt(s, s2, s3), + .errPos = noPos + }); + + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } throw error; } @@ -834,45 +859,37 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, EvalState &evalState)) { auto error = TypeError({ .msg = hintfmt(s), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr *expr)) + +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, EvalState &evalState)) { auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook && !evalState.debugTraces.empty()) { + DebugTrace &last = evalState.debugTraces.front(); + debuggerHook(&error, last.env, last.expr); + } throw error; } -// LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const string &s2, Env & env, Expr *expr)) -// { -// auto error = TypeError({ -// .msg = hintfmt(s, s2), -// .errPos = pos -// }); - -// if (debuggerHook && expr) -// debuggerHook(&error, env, *expr); - -// throw error; -// } - LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr *expr)) { auto error = TypeError({ @@ -886,13 +903,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -// LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v, Env & env, Expr *expr)) -// { -// auto error = TypeError({ -// .msg = hintfmt(s, showType(v)) -// .errPos = e ; -// } - LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) { auto error = AssertionError({ @@ -2053,8 +2063,8 @@ NixInt EvalState::forceInt(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nInt) - throwTypeError(pos, "value is %1% while an integer was expected", v, - fakeEnv(1), 0); + throwTypeError(pos, "value is %1% while an integer was expected", v, *this); + return v.integer; } @@ -2066,7 +2076,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) return v.integer; else if (v.type() != nFloat) throwTypeError(pos, "value is %1% while a float was expected", v, - fakeEnv(1), 0); + *this); return v.fpoint; } @@ -2076,7 +2086,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nBool) throwTypeError(pos, "value is %1% while a Boolean was expected", v, - fakeEnv(1), 0); + *this); return v.boolean; } @@ -2092,7 +2102,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) throwTypeError(pos, "value is %1% while a function was expected", v, - fakeEnv(1), 0); + *this); } @@ -2101,7 +2111,7 @@ std::string_view EvalState::forceString(Value & v, const Pos & pos) forceValue(v, pos); if (v.type() != nString) { throwTypeError(pos, "value is %1% while a string was expected", v, - fakeEnv(1), 0); + *this); } return v.string.s; } @@ -2152,10 +2162,10 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const Pos & pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], fakeEnv(1), 0); + v.string.s, v.string.context[0], *this); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], fakeEnv(1), 0); + v.string.s, v.string.context[0], *this); } return s; } @@ -2210,8 +2220,7 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet & return std::move(*maybeString); auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) - throwTypeError(pos, "cannot coerce a set to a string", - fakeEnv(1), 0); + throwTypeError(pos, "cannot coerce a set to a string", *this); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -2240,8 +2249,7 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet & } } - throwTypeError(pos, "cannot coerce %1% to a string", v, - fakeEnv(1), 0); + throwTypeError(pos, "cannot coerce %1% to a string", v, *this); } @@ -2250,7 +2258,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) if (nix::isDerivation(path)) throwEvalError("file names are not allowed to end in '%1%'", drvExtension, - fakeEnv(1), 0); + *this); Path dstPath; auto i = srcToStore.find(path); @@ -2276,7 +2284,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) string path = coerceToString(pos, v, context, false, false).toOwned(); if (path == "" || path[0] != '/') throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, - fakeEnv(1), 0); + *this); return path; } @@ -2358,7 +2366,7 @@ bool EvalState::eqValues(Value & v1, Value & v2) throwEvalError("cannot compare %1% with %2%", showType(v1), showType(v2), - fakeEnv(1), 0); + *this); } } -- cgit v1.2.3 From 3ff5ac3586f0e15e231489e5e36ae783e51e9bab Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 10 Feb 2022 16:01:49 -0700 Subject: update the eval-inline throw fns --- src/libexpr/eval.cc | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e584efbfb..79bdaff47 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -787,6 +787,19 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Eva throw error; } +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, Env & env, Expr *expr)) +{ + auto error = EvalError({ + .msg = hintfmt(s), + .errPos = pos + }); + + if (debuggerHook && expr) + debuggerHook(&error, env, *expr); + + throw error; +} + LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, EvalState &evalState)) { auto error = EvalError({ @@ -875,17 +888,15 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, EvalS } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, EvalState &evalState)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr *expr)) { auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos }); - if (debuggerHook && !evalState.debugTraces.empty()) { - DebugTrace &last = evalState.debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + if (debuggerHook && expr) + debuggerHook(&error, env, *expr); throw error; } @@ -1253,7 +1264,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e) Value v; e->eval(*this, env, v); if (v.type() != nBool) - throwTypeError(noPos, "value is %1% while a Boolean was expected", v); + throwTypeError(noPos, "value is %1% while a Boolean was expected", v, env, e); return v.boolean; } @@ -1263,7 +1274,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos) Value v; e->eval(*this, env, v); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v); + throwTypeError(pos, "value is %1% while a Boolean was expected", v, env, e); return v.boolean; } @@ -1272,7 +1283,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v) { e->eval(*this, env, v); if (v.type() != nAttrs) - throwTypeError(noPos, "value is %1% while a set was expected", v); + throwTypeError(noPos, "value is %1% while a set was expected", v, env, e); } @@ -1377,8 +1388,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, - env, this); + throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, env, this); i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ @@ -1697,7 +1707,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & } else - throwTypeError(pos, "attempt to call something which is not a function but %1%", vCur); + throwTypeError(pos, "attempt to call something which is not a function but %1%", vCur, *this); } vRes = vCur; @@ -2005,7 +2015,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) v.mkFloat(nf); else if (firstType == nPath) { if (!context.empty()) - throwEvalError(pos, "a string that refers to a store path cannot be appended to a path"); + throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, this); v.mkPath(canonPath(str())); } else v.mkStringMove(c_str(), context); @@ -2256,9 +2266,7 @@ BackedStringView EvalState::coerceToString(const Pos & pos, Value & v, PathSet & string EvalState::copyPathToStore(PathSet & context, const Path & path) { if (nix::isDerivation(path)) - throwEvalError("file names are not allowed to end in '%1%'", - drvExtension, - *this); + throwEvalError("file names are not allowed to end in '%1%'", drvExtension, *this); Path dstPath; auto i = srcToStore.find(path); @@ -2283,8 +2291,7 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) { string path = coerceToString(pos, v, context, false, false).toOwned(); if (path == "" || path[0] != '/') - throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, - *this); + throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, *this); return path; } -- cgit v1.2.3 From 4cffb130e385bc3f4c5ca0482ad8c4dd22229cfe Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 11 Feb 2022 14:14:25 -0700 Subject: for primops, enter the debugger at the last DebugTrace in the stack --- src/libexpr/eval.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 79bdaff47..71a28bafa 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -437,7 +437,7 @@ EvalState::EvalState( , emptyBindings(0) , store(store) , buildStore(buildStore ? buildStore : store) - , debugStop(true) + , debugStop(false) , regexCache(makeRegexCache()) #if HAVE_BOEHMGC , valueAllocCache(std::allocate_shared(traceable_allocator(), nullptr)) @@ -787,6 +787,17 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, Eva throw error; } +void EvalState::debug_throw(Error e) { + // call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context + // that's in the DebugTrace stack. + + if (debuggerHook && !debugTraces.empty()) { + DebugTrace &last = debugTraces.front(); + debuggerHook(&e, last.env, last.expr); + } + throw e; +} + LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, Env & env, Expr *expr)) { auto error = EvalError({ -- cgit v1.2.3 From c9bc3735f639a4d022ab071feb5dabd451a0d016 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 15 Feb 2022 09:49:25 -0700 Subject: quit repl from step mode --- src/libexpr/eval.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 71a28bafa..3a835adb3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -438,6 +438,7 @@ EvalState::EvalState( , store(store) , buildStore(buildStore ? buildStore : store) , debugStop(false) + , debugQuit(false) , regexCache(makeRegexCache()) #if HAVE_BOEHMGC , valueAllocCache(std::allocate_shared(traceable_allocator(), nullptr)) -- cgit v1.2.3 From 3d94d3ba91d8cde069ca635aae4c070c85a99759 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 15 Feb 2022 15:46:45 -0700 Subject: Expr refs instead of pointers --- src/libexpr/eval.cc | 76 ++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 3a835adb3..f21919598 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -799,15 +799,15 @@ void EvalState::debug_throw(Error e) { throw e; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, Env & env, Expr &expr)) { auto error = EvalError({ .msg = hintfmt(s), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } @@ -827,15 +827,15 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const string & s2, Env & env, Expr &expr)) { auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } @@ -870,7 +870,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const string & s2, con throw error; } -LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const Symbol & sym, const Pos & p2, Env & env, Expr &expr)) { // p1 is where the error occurred; p2 is a position mentioned in the message. auto error = EvalError({ @@ -878,8 +878,8 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & p1, const char * s, const .errPos = p1 }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } @@ -900,68 +900,67 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, EvalS } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const Value & v, Env & env, Expr &expr)) { auto error = TypeError({ .msg = hintfmt(s, v), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } -LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr &expr)) { auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(), s2), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } -LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, const string & s1, Env & env, Expr &expr)) { auto error = AssertionError({ .msg = hintfmt(s, s1), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } -LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr &expr)) { auto error = UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = pos }); - if (debuggerHook && expr) { - debuggerHook(&error, env, *expr); - } + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } -LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env, Expr *expr)) +LocalNoInlineNoReturn(void throwMissingArgumentError(const Pos & pos, const char * s, const string & s1, Env & env, Expr &expr)) { auto error = MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = pos }); - if (debuggerHook && expr) - debuggerHook(&error, env, *expr); + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } @@ -1055,7 +1054,8 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, (Expr*)&var); + // TODO deal with const_cast + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, *const_cast(&var)); } for (size_t l = env->prevWith; l; --l, env = env->up) ; } @@ -1276,7 +1276,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e) Value v; e->eval(*this, env, v); if (v.type() != nBool) - throwTypeError(noPos, "value is %1% while a Boolean was expected", v, env, e); + throwTypeError(noPos, "value is %1% while a Boolean was expected", v, env, *e); return v.boolean; } @@ -1286,7 +1286,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const Pos & pos) Value v; e->eval(*this, env, v); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v, env, e); + throwTypeError(pos, "value is %1% while a Boolean was expected", v, env, *e); return v.boolean; } @@ -1295,7 +1295,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v) { e->eval(*this, env, v); if (v.type() != nAttrs) - throwTypeError(noPos, "value is %1% while a set was expected", v, env, e); + throwTypeError(noPos, "value is %1% while a set was expected", v, env, *e); } @@ -1400,7 +1400,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v) Symbol nameSym = state.symbols.create(nameVal.string.s); Bindings::iterator j = v.attrs->find(nameSym); if (j != v.attrs->end()) - throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, env, this); + throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, *j->pos, env, *this); i.valueExpr->setName(nameSym); /* Keep sorted order so find can catch duplicates */ @@ -1498,7 +1498,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } else { state.forceAttrs(*vAttrs, pos); if ((j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) - throwEvalError(pos, "attribute '%1%' missing", name, env, this); + throwEvalError(pos, "attribute '%1%' missing", name, env, *this); } vAttrs = j->value; pos2 = j->pos; @@ -1599,7 +1599,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & auto j = args[0]->attrs->get(i.name); if (!j) { if (!i.def) throwTypeError(pos, "%1% called without required argument '%2%'", - lambda, i.name, *fun.lambda.env, &lambda); + lambda, i.name, *fun.lambda.env, lambda); env2.values[displ++] = i.def->maybeThunk(*this, env2); } else { attrsUsed++; @@ -1615,7 +1615,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & for (auto & i : *args[0]->attrs) if (!lambda.formals->has(i.name)) throwTypeError(pos, "%1% called with unexpected argument '%2%'", - lambda, i.name, *fun.lambda.env, &lambda); + lambda, i.name, *fun.lambda.env, lambda); abort(); // can't happen } } @@ -1790,7 +1790,7 @@ this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See https://nixos.org/manual/nix/stable/#ss-functions.)", i.name, - *fun.lambda.env, fun.lambda.fun); + *fun.lambda.env, *fun.lambda.fun); } } } @@ -1822,7 +1822,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v) if (!state.evalBool(env, cond, pos)) { std::ostringstream out; cond->show(out); - throwAssertionError(pos, "assertion '%1%' failed", out.str(), env, this); + throwAssertionError(pos, "assertion '%1%' failed", out.str(), env, *this); } body->eval(state, env, v); } @@ -1999,7 +1999,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } else { - throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp), env, this); + throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp), env, *this); } } else if (firstType == nFloat) { if (vTmp.type() == nInt) { @@ -2007,7 +2007,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp), env, this); + throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp), env, *this); } else { if (s.empty()) s.reserve(es->size()); /* skip canonization of first path, which would only be not @@ -2027,7 +2027,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) v.mkFloat(nf); else if (firstType == nPath) { if (!context.empty()) - throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, this); + throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, *this); v.mkPath(canonPath(str())); } else v.mkStringMove(c_str(), context); -- cgit v1.2.3 From 3dfab6e534e0a1cf71c000a4d2a74e050ba576ce Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 14 Mar 2022 11:58:11 -0600 Subject: have only one debuggerHook declaration --- src/libexpr/eval.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f21919598..6758677ca 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -37,8 +37,6 @@ namespace nix { -std::function debuggerHook; - static char * allocString(size_t size) { char * t; -- cgit v1.2.3 From 1bec3fb337b86f87e7600fc6b6072ded1a7d4927 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 25 Mar 2022 18:15:31 -0600 Subject: add DebugTrace for error --- src/libexpr/eval.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6758677ca..f162f3e0b 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -983,7 +983,8 @@ LocalNoInline(std::unique_ptr {.pos = pos, .expr = expr, .env = env, - .hint = hintfmt(s, s2) + .hint = hintfmt(s, s2), + .is_error = false })); } -- cgit v1.2.3 From c0a567e1963faaf9b16f772d6b4e76496a88ed32 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Tue, 29 Mar 2022 16:44:47 -0600 Subject: remove const_cast --- src/libexpr/eval.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f162f3e0b..cc0380d4a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -937,7 +937,7 @@ LocalNoInlineNoReturn(void throwAssertionError(const Pos & pos, const char * s, throw error; } -LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, Expr &expr)) +LocalNoInlineNoReturn(void throwUndefinedVarError(const Pos & pos, const char * s, const string & s1, Env & env, const Expr &expr)) { auto error = UndefinedVarError({ .msg = hintfmt(s, s1), @@ -1053,8 +1053,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) { - // TODO deal with const_cast - throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, *const_cast(&var)); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", var.name, *env, var); } for (size_t l = env->prevWith; l; --l, env = env->up) ; } -- cgit v1.2.3 From 1096d17b65834a7e1ff29d1afdf09536cc9d7a8d Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 31 Mar 2022 09:37:36 -0600 Subject: show 'with' bindings as well as static --- src/libexpr/eval.cc | 70 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 15 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index cc0380d4a..7c67f2ea8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -699,22 +699,46 @@ std::optional EvalState::getDoc(Value & v) return {}; } -void printStaticEnvBindings(const StaticEnv &se, int lvl) + +// just for the current level of StaticEnv, not the whole chain. +void printStaticEnvBindings(const StaticEnv &se) { - std::cout << "Env level " << lvl << std::endl; + std::cout << ANSI_MAGENTA; + for (auto i = se.vars.begin(); i != se.vars.end(); ++i) + { + std::cout << i->first << " "; + } + std::cout << ANSI_NORMAL; + std::cout << std::endl; +} - if (se.up) { +// just for the current level of Env, not the whole chain. +void printWithBindings(const Env &env) +{ + if (env.type == Env::HasWithAttrs) + { + std::cout << "with: "; std::cout << ANSI_MAGENTA; - for (auto i = se.vars.begin(); i != se.vars.end(); ++i) - { - std::cout << i->first << " "; + Bindings::iterator j = env.values[0]->attrs->begin(); + while (j != env.values[0]->attrs->end()) { + std::cout << j->name << " "; + ++j; } std::cout << ANSI_NORMAL; - - std::cout << std::endl; std::cout << std::endl; + } +} + +void printEnvBindings(const StaticEnv &se, const Env &env, int lvl) +{ + std::cout << "Env level " << lvl << std::endl; - printStaticEnvBindings(*se.up, ++lvl); + if (se.up && env.up) { + std::cout << "static: "; + printStaticEnvBindings(se); + printWithBindings(env); + std::cout << std::endl; + printEnvBindings(*se.up, *env.up, ++lvl); } else { @@ -727,18 +751,19 @@ void printStaticEnvBindings(const StaticEnv &se, int lvl) } std::cout << ANSI_NORMAL; std::cout << std::endl; + printWithBindings(env); // probably nothing there for the top level. std::cout << std::endl; } - } -void printStaticEnvBindings(const Expr &expr) +// TODO: add accompanying env for With stuff. +void printEnvBindings(const Expr &expr, const Env &env) { // just print the names for now if (expr.staticenv) { - printStaticEnvBindings(*expr.staticenv.get(), 0); + printEnvBindings(*expr.staticenv.get(), env, 0); } } @@ -750,11 +775,26 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) if (env.up && se.up) { mapStaticEnvBindings(*se.up, *env.up,vm); - // iterate through staticenv bindings and add them. auto map = valmap(); - for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + if (env.type == Env::HasWithAttrs) + { + std::cout << "(env.type == Env::HasWithAttrs)" << std::endl; + Bindings::iterator j = env.values[0]->attrs->begin(); + while (j != env.values[0]->attrs->end()) { + // std::cout << "adding : " << j->name << std::endl; + map[j->name] = j->value; + // if (countCalls) attrSelects[*j->pos]++; + // return j->value; + ++j; + } + } + else { - map[iter->first] = env.values[iter->second]; + // iterate through staticenv bindings and add them. + for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) + { + map[iter->first] = env.values[iter->second]; + } } vm.merge(map); -- cgit v1.2.3 From f41c18b2210ac36743f03ea218860b7941f4264e Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 31 Mar 2022 09:39:18 -0600 Subject: comments --- src/libexpr/eval.cc | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7c67f2ea8..399cf126d 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -781,10 +781,7 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) std::cout << "(env.type == Env::HasWithAttrs)" << std::endl; Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { - // std::cout << "adding : " << j->name << std::endl; map[j->name] = j->value; - // if (countCalls) attrSelects[*j->pos]++; - // return j->value; ++j; } } -- cgit v1.2.3 From 50b52d51109c430fb2ac69ed5337a6a985e4a486 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 7 Apr 2022 12:03:18 -0600 Subject: remove debug code --- src/libexpr/eval.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 399cf126d..4211d72dd 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -778,7 +778,6 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) auto map = valmap(); if (env.type == Env::HasWithAttrs) { - std::cout << "(env.type == Env::HasWithAttrs)" << std::endl; Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { map[j->name] = j->value; -- cgit v1.2.3 From b8b8ec710160cfd343a8fce33ec8734e23c98444 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 12:34:27 -0600 Subject: move throw to preverve Error type; turn off debugger for tryEval --- src/libexpr/eval.cc | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5ad7e546c..7d02222cf 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -833,15 +833,13 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2 throw error; } -void EvalState::debug_throw(Error e) { +void EvalState::debugLastTrace(Error & e) { // call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context // that's in the DebugTrace stack. - if (debuggerHook && !debugTraces.empty()) { DebugTrace &last = debugTraces.front(); debuggerHook(&e, last.env, last.expr); } - throw e; } LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & suggestions, const char * s, const std::string & s2, Env & env, Expr &expr)) @@ -865,10 +863,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook && !evalState.debugTraces.empty()) { - DebugTrace &last = evalState.debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + evalState.debugLastTrace(error); throw error; } @@ -906,10 +901,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const .errPos = pos }); - if (debuggerHook && !evalState.debugTraces.empty()) { - DebugTrace &last = evalState.debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + evalState.debugLastTrace(error); throw error; } @@ -921,10 +913,7 @@ LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2 .errPos = noPos }); - if (debuggerHook && !evalState.debugTraces.empty()) { - DebugTrace &last = evalState.debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + evalState.debugLastTrace(error); throw error; } @@ -950,10 +939,7 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, EvalS .errPos = pos }); - if (debuggerHook && !evalState.debugTraces.empty()) { - DebugTrace &last = evalState.debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + evalState.debugLastTrace(error); throw error; } @@ -972,8 +958,6 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const throw error; } -// LocalNoInlineNoReturn(void throwTypeError(const char * s, const Value & v)); - LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const ExprLambda & fun, const Symbol & s2, Env & env, Expr &expr)) { auto error = TypeError({ -- cgit v1.2.3 From 27d45f9eb3c151afed8a20f1adc1d4dd1a200f09 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 8 Apr 2022 15:46:12 -0600 Subject: minor cleanup --- src/libexpr/eval.cc | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7d02222cf..914739f70 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -789,6 +789,7 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) auto map = valmap(); if (env.type == Env::HasWithAttrs) { + // add 'with' bindings. Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { map[j->name] = j->value; @@ -1485,15 +1486,15 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) try { auto dts = - debuggerHook ? - makeDebugTraceStacker( - state, - *this, - env, - *pos2, - "while evaluating the attribute '%1%'", - showAttrPath(state, env, attrPath)) - : nullptr; + debuggerHook ? + makeDebugTraceStacker( + state, + *this, + env, + *pos2, + "while evaluating the attribute '%1%'", + showAttrPath(state, env, attrPath)) + : nullptr; for (auto & i : attrPath) { state.nrLookups++; @@ -2082,13 +2083,13 @@ void EvalState::forceValueDeep(Value & v) try { auto dts = - debuggerHook ? - // if the value is a thunk, we're evaling. otherwise no trace necessary. - (i.value->isThunk() ? - makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, *i.pos, - "while evaluating the attribute '%1%'", i.name) - : nullptr) - : nullptr; + debuggerHook ? + // if the value is a thunk, we're evaling. otherwise no trace necessary. + (i.value->isThunk() ? + makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, *i.pos, + "while evaluating the attribute '%1%'", i.name) + : nullptr) + : nullptr; recurse(*i.value); } catch (Error & e) { @@ -2123,8 +2124,7 @@ NixFloat EvalState::forceFloat(Value & v, const Pos & pos) if (v.type() == nInt) return v.integer; else if (v.type() != nFloat) - throwTypeError(pos, "value is %1% while a float was expected", v, - *this); + throwTypeError(pos, "value is %1% while a float was expected", v, *this); return v.fpoint; } @@ -2133,8 +2133,7 @@ bool EvalState::forceBool(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v, - *this); + throwTypeError(pos, "value is %1% while a Boolean was expected", v, *this); return v.boolean; } @@ -2149,8 +2148,7 @@ void EvalState::forceFunction(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) - throwTypeError(pos, "value is %1% while a function was expected", v, - *this); + throwTypeError(pos, "value is %1% while a function was expected", v, *this); } @@ -2158,8 +2156,7 @@ std::string_view EvalState::forceString(Value & v, const Pos & pos) { forceValue(v, pos); if (v.type() != nString) { - throwTypeError(pos, "value is %1% while a string was expected", v, - *this); + throwTypeError(pos, "value is %1% while a string was expected", v, *this); } return v.string.s; } -- cgit v1.2.3 From a61841ac41646ad0345cef547facd2c20f1da957 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 9 Apr 2022 07:45:23 -0600 Subject: don't use std::map merge --- src/libexpr/eval.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 914739f70..876bf8f37 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -784,15 +784,14 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) // override the higher levels. // The top level bindings (builtins) are skipped since they are added for us by initEnv() if (env.up && se.up) { - mapStaticEnvBindings(*se.up, *env.up,vm); + mapStaticEnvBindings(*se.up, *env.up, vm); - auto map = valmap(); if (env.type == Env::HasWithAttrs) { // add 'with' bindings. Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { - map[j->name] = j->value; + vm[j->name] = j->value; ++j; } } @@ -801,11 +800,9 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) // iterate through staticenv bindings and add them. for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) { - map[iter->first] = env.values[iter->second]; + vm[iter->first] = env.values[iter->second]; } } - - vm.merge(map); } } -- cgit v1.2.3 From 8b197c492e4e2878eb58bb2994fb8d7f8044bf90 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sat, 9 Apr 2022 21:54:41 -0600 Subject: remove comma --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 876bf8f37..d0e147733 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -845,7 +845,7 @@ LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const Suggestions & s auto error = EvalError({ .msg = hintfmt(s, s2), .errPos = pos, - .suggestions = suggestions, + .suggestions = suggestions }); if (debuggerHook) -- cgit v1.2.3 From 2a5632c70dcb686a7764c23a5f330fcb9a33c8a1 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 29 Apr 2022 10:02:17 -0600 Subject: incorporate PosIdx changes, symbol changes. --- src/libexpr/eval.cc | 199 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 79 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 896242e0c..7058d117f 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -714,19 +714,19 @@ std::optional EvalState::getDoc(Value & v) // just for the current level of StaticEnv, not the whole chain. -void printStaticEnvBindings(const StaticEnv &se) +void printStaticEnvBindings(const SymbolTable &st, const StaticEnv &se) { std::cout << ANSI_MAGENTA; for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { - std::cout << i->first << " "; + std::cout << st[i->first] << " "; } std::cout << ANSI_NORMAL; std::cout << std::endl; } // just for the current level of Env, not the whole chain. -void printWithBindings(const Env &env) +void printWithBindings(const SymbolTable &st, const Env &env) { if (env.type == Env::HasWithAttrs) { @@ -734,7 +734,7 @@ void printWithBindings(const Env &env) std::cout << ANSI_MAGENTA; Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { - std::cout << j->name << " "; + std::cout << st[j->name] << " "; ++j; } std::cout << ANSI_NORMAL; @@ -742,16 +742,16 @@ void printWithBindings(const Env &env) } } -void printEnvBindings(const StaticEnv &se, const Env &env, int lvl) +void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, int lvl) { std::cout << "Env level " << lvl << std::endl; if (se.up && env.up) { std::cout << "static: "; - printStaticEnvBindings(se); - printWithBindings(env); + printStaticEnvBindings(st, se); + printWithBindings(st, env); std::cout << std::endl; - printEnvBindings(*se.up, *env.up, ++lvl); + printEnvBindings(st, *se.up, *env.up, ++lvl); } else { @@ -759,41 +759,41 @@ void printEnvBindings(const StaticEnv &se, const Env &env, int lvl) // for the top level, don't print the double underscore ones; they are in builtins. for (auto i = se.vars.begin(); i != se.vars.end(); ++i) { - if (((std::string)i->first).substr(0,2) != "__") - std::cout << i->first << " "; + if (((std::string)st[i->first]).substr(0,2) != "__") + std::cout << st[i->first] << " "; } std::cout << ANSI_NORMAL; std::cout << std::endl; - printWithBindings(env); // probably nothing there for the top level. + printWithBindings(st, env); // probably nothing there for the top level. std::cout << std::endl; } } // TODO: add accompanying env for With stuff. -void printEnvBindings(const Expr &expr, const Env &env) +void printEnvBindings(const SymbolTable &st, const Expr &expr, const Env &env) { // just print the names for now if (expr.staticenv) { - printEnvBindings(*expr.staticenv.get(), env, 0); + printEnvBindings(st, *expr.staticenv.get(), env, 0); } } -void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) +void mapStaticEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, valmap & vm) { // add bindings for the next level up first, so that the bindings for this level // override the higher levels. // The top level bindings (builtins) are skipped since they are added for us by initEnv() if (env.up && se.up) { - mapStaticEnvBindings(*se.up, *env.up, vm); + mapStaticEnvBindings(st, *se.up, *env.up, vm); if (env.type == Env::HasWithAttrs) { // add 'with' bindings. Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { - vm[j->name] = j->value; + vm[st[j->name]] = j->value; ++j; } } @@ -802,51 +802,54 @@ void mapStaticEnvBindings(const StaticEnv &se, const Env &env, valmap & vm) // iterate through staticenv bindings and add them. for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) { - vm[iter->first] = env.values[iter->second]; + vm[st[iter->first]] = env.values[iter->second]; } } } } -valmap * mapStaticEnvBindings(const StaticEnv &se, const Env &env) +valmap * mapStaticEnvBindings(const SymbolTable &st,const StaticEnv &se, const Env &env) { auto vm = new valmap(); - mapStaticEnvBindings(se, env, *vm); + mapStaticEnvBindings(st, se, env, *vm); return vm; } +void EvalState::debugLastTrace(Error & e) const { + // call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context + // that's in the DebugTrace stack. + if (debuggerHook && !debugTraces.empty()) { + const DebugTrace &last = debugTraces.front(); + debuggerHook(&e, last.env, last.expr); + } +} + /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing exceptions. */ - -void EvalState::throwEvalError(const PosIdx pos, const char * s) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr &expr) const { auto error = EvalError({ .msg = hintfmt(s), .errPos = positions[pos] }); - if (debuggerHook && !debugTraces.empty()) { - DebugTrace &last = debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + if (debuggerHook) + debuggerHook(&error, env, expr); throw error; } -void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) const +void EvalState::throwEvalError(const PosIdx pos, const char * s) const { - auto error = TypeError({ - .msg = hintfmt(s, showType(v)), + auto error = EvalError({ + .msg = hintfmt(s), .errPos = positions[pos] }); - if (debuggerHook && !debugTraces.empty()) { - DebugTrace &last = debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + debugLastTrace(error); throw error; } @@ -855,23 +858,11 @@ void EvalState::throwEvalError(const char * s, const std::string & s2) const { auto error = EvalError(s, s2); - if (debuggerHook && !debugTraces.empty()) { - DebugTrace &last = debugTraces.front(); - debuggerHook(&error, last.env, last.expr); - } + debugLastTrace(error); throw error; } -void EvalState::debugLastTrace(Error & e) { - // call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context - // that's in the DebugTrace stack. - if (debuggerHook && !debugTraces.empty()) { - DebugTrace &last = debugTraces.front(); - debuggerHook(&e, last.env, last.expr); - } -} - void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2, Env & env, Expr &expr) const { @@ -899,16 +890,43 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri throw error; } -void EvalState::throwEvalError(const char * s, const std::string & s2, const std::string & s3, Env & env, Expr &expr) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr &expr) const { auto error = EvalError({ - .msg = hintfmt(s), - .errPos = pos + .msg = hintfmt(s, s2), + .errPos = positions[pos] }); if (debuggerHook) debuggerHook(&error, env, expr); + + throw error; +} + +void EvalState::throwEvalError(const char * s, const std::string & s2, + const std::string & s3) const +{ + auto error = EvalError({ + .msg = hintfmt(s, s2), + .errPos = positions[noPos] + }); + + debugLastTrace(error); + + throw error; +} + +void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, + const std::string & s3) const +{ + auto error = EvalError({ + .msg = hintfmt(s, s2), + .errPos = positions[pos] + }); + + debugLastTrace(error); + throw error; } @@ -917,7 +935,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri { auto error = EvalError({ .msg = hintfmt(s, s2), - .errPos = pos + .errPos = positions[pos] }); if (debuggerHook) @@ -966,6 +984,31 @@ void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym throw error; } +void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) const +{ + auto error = TypeError({ + .msg = hintfmt(s, showType(v)), + .errPos = positions[pos] + }); + + debugLastTrace(error); + + throw error; +} + +void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr &expr) const +{ + auto error = TypeError({ + .msg = hintfmt(s, showType(v)), + .errPos = positions[pos] + }); + + if (debuggerHook) + debuggerHook(&error, env, expr); + + throw error; +} + void EvalState::throwTypeError(const PosIdx pos, const char * s) const { auto error = TypeError({ @@ -973,7 +1016,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s) const .errPos = positions[pos] }); - evalState.debugLastTrace(error); + debugLastTrace(error); throw error; } @@ -1010,9 +1053,8 @@ void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr) const { auto error = TypeError({ - .msg = hintfmt(s, fun.showNamePos(), s2), - .errPos = pos, - .suggestions = suggestions, + .msg = hintfmt(s, showType(v)), + .errPos = positions[expr.getPos()], }); if (debuggerHook) @@ -1070,8 +1112,8 @@ void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const e.addTrace(positions[pos], s, s2); } -LocalNoInline(std::unique_ptr - makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, std::optional pos, const char * s, const std::string & s2)) +std::unique_ptr makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, + std::optional pos, const char * s, const std::string & s2) { return std::unique_ptr( new DebugTraceStacker( @@ -1150,7 +1192,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval) return j->value; } if (!env->prevWith) - throwUndefinedVarError(var.pos, "undefined variable '%1%'", symbols[var.name], *env, var); + throwUndefinedVarError(var.pos, "undefined variable '%1%'", symbols[var.name], *env, const_cast(var)); for (size_t l = env->prevWith; l; --l, env = env->up) ; } } @@ -1293,7 +1335,7 @@ void EvalState::cacheFile( *this, *e, this->baseEnv, - (e->getPos() ? std::optional(ErrPos(*e->getPos())) : std::nullopt), + (e->getPos() ? std::optional(ErrPos(positions[e->getPos()])) : std::nullopt), "while evaluating the file '%1%':", resolvedPath) : nullptr; @@ -1528,7 +1570,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) state, *this, env, - *pos2, + state.positions[pos2], "while evaluating the attribute '%1%'", showAttrPath(state, env, attrPath)) : nullptr; @@ -1694,10 +1736,10 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & try { auto dts = debuggerHook ? - makeDebugTraceStacker(*this, *lambda.body, env2, lambda.pos, + makeDebugTraceStacker(*this, *lambda.body, env2, positions[lambda.pos], "while evaluating %s", - (lambda.name.set() - ? "'" + (std::string) lambda.name + "'" + (lambda.name + ? concatStrings("'", symbols[lambda.name], "'") : "anonymous lambda")) : nullptr; @@ -1786,7 +1828,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & } else - throwTypeError(pos, "attempt to call something which is not a function but %1%", vCur, *this); + throwTypeError(pos, "attempt to call something which is not a function but %1%", vCur); } vRes = vCur; @@ -1855,7 +1897,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res) Nix attempted to evaluate a function as a top level expression; in this case it must have its arguments supplied either by default values, or passed explicitly with '--arg' or '--argstr'. See -https://nixos.org/manual/nix/stable/#ss-functions.)", symbols[i.name],, +https://nixos.org/manual/nix/stable/#ss-functions.)", symbols[i.name], *fun.lambda.env, *fun.lambda.fun); } } @@ -2092,7 +2134,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) v.mkFloat(nf); else if (firstType == nPath) { if (!context.empty()) - state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, *this);); + state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, *this); v.mkPath(canonPath(str())); } else v.mkStringMove(c_str(), context); @@ -2124,8 +2166,8 @@ void EvalState::forceValueDeep(Value & v) debuggerHook ? // if the value is a thunk, we're evaling. otherwise no trace necessary. (i.value->isThunk() ? - makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, *i.pos, - "while evaluating the attribute '%1%'", i.name) + makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos], + "while evaluating the attribute '%1%'", symbols[i.name]) : nullptr) : nullptr; @@ -2150,7 +2192,7 @@ NixInt EvalState::forceInt(Value & v, const PosIdx pos) { forceValue(v, pos); if (v.type() != nInt) - throwTypeError(pos, "value is %1% while an integer was expected", v, *this); + throwTypeError(pos, "value is %1% while an integer was expected", v); return v.integer; } @@ -2162,7 +2204,7 @@ NixFloat EvalState::forceFloat(Value & v, const PosIdx pos) if (v.type() == nInt) return v.integer; else if (v.type() != nFloat) - throwTypeError(pos, "value is %1% while a float was expected", v, *this); + throwTypeError(pos, "value is %1% while a float was expected", v); return v.fpoint; } @@ -2171,7 +2213,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos) { forceValue(v, pos); if (v.type() != nBool) - throwTypeError(pos, "value is %1% while a Boolean was expected", v, *this); + throwTypeError(pos, "value is %1% while a Boolean was expected", v); return v.boolean; } @@ -2186,7 +2228,7 @@ void EvalState::forceFunction(Value & v, const PosIdx pos) { forceValue(v, pos); if (v.type() != nFunction && !isFunctor(v)) - throwTypeError(pos, "value is %1% while a function was expected", v, *this); + throwTypeError(pos, "value is %1% while a function was expected", v); } @@ -2194,7 +2236,7 @@ std::string_view EvalState::forceString(Value & v, const PosIdx pos) { forceValue(v, pos); if (v.type() != nString) { - throwTypeError(pos, "value is %1% while a string was expected", v, *this); + throwTypeError(pos, "value is %1% while a string was expected", v); } return v.string.s; } @@ -2254,10 +2296,10 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos) if (v.string.context) { if (pos) throwEvalError(pos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], *this); + v.string.s, v.string.context[0]); else throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", - v.string.s, v.string.context[0], *this); + v.string.s, v.string.context[0]); } return s; } @@ -2312,7 +2354,7 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet return std::move(*maybeString); auto i = v.attrs->find(sOutPath); if (i == v.attrs->end()) - throwTypeError(pos, "cannot coerce a set to a string", *this); + throwTypeError(pos, "cannot coerce a set to a string"); return coerceToString(pos, *i->value, context, coerceMore, copyToStore); } @@ -2341,14 +2383,14 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet } } - throwTypeError(pos, "cannot coerce %1% to a string", v, *this); + throwTypeError(pos, "cannot coerce %1% to a string", v); } std::string EvalState::copyPathToStore(PathSet & context, const Path & path) { if (nix::isDerivation(path)) - throwEvalError("file names are not allowed to end in '%1%'", drvExtension, *this); + throwEvalError("file names are not allowed to end in '%1%'", drvExtension); Path dstPath; auto i = srcToStore.find(path); @@ -2373,7 +2415,7 @@ Path EvalState::coerceToPath(const PosIdx pos, Value & v, PathSet & context) { auto path = coerceToString(pos, v, context, false, false).toOwned(); if (path == "" || path[0] != '/') - throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path, *this); + throwEvalError(pos, "string '%1%' doesn't represent an absolute path", path); return path; } @@ -2466,8 +2508,7 @@ bool EvalState::eqValues(Value & v1, Value & v2) default: throwEvalError("cannot compare %1% with %2%", showType(v1), - showType(v2), - *this); + showType(v2)); } } -- cgit v1.2.3 From ca6cba8b81502450f8e377112ce11303ccedc760 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 29 Apr 2022 10:51:10 -0600 Subject: fix 'suggestions' error --- src/libexpr/eval.cc | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 7058d117f..294168392 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -866,7 +866,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2) const void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2, Env & env, Expr &expr) const { - auto error = EvalError({ + auto error = EvalError(ErrorInfo{ .msg = hintfmt(s, s2), .errPos = positions[pos], .suggestions = suggestions, @@ -944,32 +944,6 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri throw error; } -/* -LocalNoInlineNoReturn(void throwEvalError(const Pos & pos, const char * s, const std::string & s2, const std::string & s3, EvalState &evalState)) -{ - auto error = EvalError({ - .msg = hintfmt(s, s2, s3), - .errPos = positions[pos] - }); - - evalState.debugLastTrace(error); - - throw error; -} - -LocalNoInlineNoReturn(void throwEvalError(const char * s, const std::string & s2, const std::string & s3, EvalState &evalState)) -{ - auto error = EvalError({ - .msg = hintfmt(s, s2, s3), - .errPos = noPos - }); - - evalState.debugLastTrace(error); - - throw error; -} -*/ - void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr &expr) const { // p1 is where the error occurred; p2 is a position mentioned in the message. -- cgit v1.2.3 From 172a83d22a3c984b6b569b5528d2338059bb748b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 29 Apr 2022 11:24:54 -0600 Subject: line endings --- src/libexpr/eval.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 294168392..10dba69e7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -730,7 +730,7 @@ void printWithBindings(const SymbolTable &st, const Env &env) { if (env.type == Env::HasWithAttrs) { - std::cout << "with: "; + std::cout << "with: "; std::cout << ANSI_MAGENTA; Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { @@ -747,13 +747,13 @@ void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env std::cout << "Env level " << lvl << std::endl; if (se.up && env.up) { - std::cout << "static: "; + std::cout << "static: "; printStaticEnvBindings(st, se); printWithBindings(st, env); std::cout << std::endl; printEnvBindings(st, *se.up, *env.up, ++lvl); } - else + else { std::cout << ANSI_MAGENTA; // for the top level, don't print the double underscore ones; they are in builtins. @@ -784,7 +784,7 @@ void mapStaticEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env { // add bindings for the next level up first, so that the bindings for this level // override the higher levels. - // The top level bindings (builtins) are skipped since they are added for us by initEnv() + // The top level bindings (builtins) are skipped since they are added for us by initEnv() if (env.up && se.up) { mapStaticEnvBindings(st, *se.up, *env.up, vm); @@ -1086,13 +1086,13 @@ void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const e.addTrace(positions[pos], s, s2); } -std::unique_ptr makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, +std::unique_ptr makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, std::optional pos, const char * s, const std::string & s2) { return std::unique_ptr( new DebugTraceStacker( state, - DebugTrace + DebugTrace {.pos = pos, .expr = expr, .env = env, -- cgit v1.2.3 From dd8b91eebc0d31c9f8016609b36d89f58d8c4d19 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 5 May 2022 12:29:14 +0200 Subject: Style fixes In particular, use std::make_shared and enumerate(). Also renamed some fields to fit naming conventions. --- src/libexpr/eval.cc | 219 ++++++++++++++++++++++++---------------------------- 1 file changed, 102 insertions(+), 117 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 10dba69e7..ca0eec6e3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -466,7 +466,7 @@ EvalState::EvalState( , env1AllocCache(std::make_shared(nullptr)) #endif , baseEnv(allocEnv(128)) - , staticBaseEnv(new StaticEnv(false, 0)) + , staticBaseEnv{std::make_shared(false, nullptr)} { countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0"; @@ -524,7 +524,7 @@ void EvalState::allowPath(const StorePath & storePath) allowedPaths->insert(store->toRealPath(storePath)); } -void EvalState::allowAndSetStorePathString(const StorePath &storePath, Value & v) +void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v) { allowPath(storePath); @@ -714,22 +714,19 @@ std::optional EvalState::getDoc(Value & v) // just for the current level of StaticEnv, not the whole chain. -void printStaticEnvBindings(const SymbolTable &st, const StaticEnv &se) +void printStaticEnvBindings(const SymbolTable & st, const StaticEnv & se) { std::cout << ANSI_MAGENTA; - for (auto i = se.vars.begin(); i != se.vars.end(); ++i) - { - std::cout << st[i->first] << " "; - } + for (auto & i : se.vars) + std::cout << st[i.first] << " "; std::cout << ANSI_NORMAL; std::cout << std::endl; } // just for the current level of Env, not the whole chain. -void printWithBindings(const SymbolTable &st, const Env &env) +void printWithBindings(const SymbolTable & st, const Env & env) { - if (env.type == Env::HasWithAttrs) - { + if (env.type == Env::HasWithAttrs) { std::cout << "with: "; std::cout << ANSI_MAGENTA; Bindings::iterator j = env.values[0]->attrs->begin(); @@ -742,7 +739,7 @@ void printWithBindings(const SymbolTable &st, const Env &env) } } -void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, int lvl) +void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, int lvl) { std::cout << "Env level " << lvl << std::endl; @@ -752,16 +749,13 @@ void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env printWithBindings(st, env); std::cout << std::endl; printEnvBindings(st, *se.up, *env.up, ++lvl); - } - else - { + } else { std::cout << ANSI_MAGENTA; - // for the top level, don't print the double underscore ones; they are in builtins. - for (auto i = se.vars.begin(); i != se.vars.end(); ++i) - { - if (((std::string)st[i->first]).substr(0,2) != "__") - std::cout << st[i->first] << " "; - } + // for the top level, don't print the double underscore ones; + // they are in builtins. + for (auto & i : se.vars) + if (!hasPrefix(st[i.first], "__")) + std::cout << st[i.first] << " "; std::cout << ANSI_NORMAL; std::cout << std::endl; printWithBindings(st, env); // probably nothing there for the top level. @@ -771,56 +765,50 @@ void printEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env } // TODO: add accompanying env for With stuff. -void printEnvBindings(const SymbolTable &st, const Expr &expr, const Env &env) +void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env) { // just print the names for now - if (expr.staticenv) - { - printEnvBindings(st, *expr.staticenv.get(), env, 0); + if (expr.staticEnv) + printEnvBindings(st, *expr.staticEnv.get(), env, 0); +} + +void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, valmap & vm) +{ + // add bindings for the next level up first, so that the bindings for this level + // override the higher levels. + // The top level bindings (builtins) are skipped since they are added for us by initEnv() + if (env.up && se.up) { + mapStaticEnvBindings(st, *se.up, *env.up, vm); + + if (env.type == Env::HasWithAttrs) { + // add 'with' bindings. + Bindings::iterator j = env.values[0]->attrs->begin(); + while (j != env.values[0]->attrs->end()) { + vm[st[j->name]] = j->value; + ++j; + } + } else { + // iterate through staticenv bindings and add them. + for (auto & i : se.vars) + vm[st[i.first]] = env.values[i.second]; + } } } -void mapStaticEnvBindings(const SymbolTable &st, const StaticEnv &se, const Env &env, valmap & vm) -{ - // add bindings for the next level up first, so that the bindings for this level - // override the higher levels. - // The top level bindings (builtins) are skipped since they are added for us by initEnv() - if (env.up && se.up) { - mapStaticEnvBindings(st, *se.up, *env.up, vm); - - if (env.type == Env::HasWithAttrs) - { - // add 'with' bindings. - Bindings::iterator j = env.values[0]->attrs->begin(); - while (j != env.values[0]->attrs->end()) { - vm[st[j->name]] = j->value; - ++j; - } - } - else - { - // iterate through staticenv bindings and add them. - for (auto iter = se.vars.begin(); iter != se.vars.end(); ++iter) - { - vm[st[iter->first]] = env.values[iter->second]; - } - } - } -} - -valmap * mapStaticEnvBindings(const SymbolTable &st,const StaticEnv &se, const Env &env) -{ - auto vm = new valmap(); +std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env) +{ + auto vm = std::make_unique(); mapStaticEnvBindings(st, se, env, *vm); return vm; } - -void EvalState::debugLastTrace(Error & e) const { - // call this in the situation where Expr and Env are inaccessible. The debugger will start in the last context - // that's in the DebugTrace stack. +void EvalState::debugLastTrace(Error & e) const +{ + // Call this in the situation where Expr and Env are inaccessible. + // The debugger will start in the last context that's in the + // DebugTrace stack. if (debuggerHook && !debugTraces.empty()) { - const DebugTrace &last = debugTraces.front(); + const DebugTrace & last = debugTraces.front(); debuggerHook(&e, last.env, last.expr); } } @@ -829,7 +817,7 @@ void EvalState::debugLastTrace(Error & e) const { of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing exceptions. */ -void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr &expr) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr) const { auto error = EvalError({ .msg = hintfmt(s), @@ -864,7 +852,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2) const } void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, - const std::string & s2, Env & env, Expr &expr) const + const std::string & s2, Env & env, Expr & expr) const { auto error = EvalError(ErrorInfo{ .msg = hintfmt(s, s2), @@ -890,7 +878,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri throw error; } -void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr &expr) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) const { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -900,7 +888,6 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri if (debuggerHook) debuggerHook(&error, env, expr); - throw error; } @@ -931,7 +918,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, - const std::string & s3, Env & env, Expr &expr) const + const std::string & s3, Env & env, Expr & expr) const { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -944,7 +931,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri throw error; } -void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr &expr) const +void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) const { // p1 is where the error occurred; p2 is a position mentioned in the message. auto error = EvalError({ @@ -970,7 +957,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v throw error; } -void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr &expr) const +void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) const { auto error = TypeError({ .msg = hintfmt(s, showType(v)), @@ -1086,27 +1073,31 @@ void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const e.addTrace(positions[pos], s, s2); } -std::unique_ptr makeDebugTraceStacker(EvalState &state, Expr &expr, Env &env, - std::optional pos, const char * s, const std::string & s2) +static std::unique_ptr makeDebugTraceStacker( + EvalState & state, + Expr & expr, + Env & env, + std::optional pos, + const char * s, + const std::string & s2) { - return std::unique_ptr( - new DebugTraceStacker( - state, - DebugTrace - {.pos = pos, - .expr = expr, - .env = env, - .hint = hintfmt(s, s2), - .is_error = false - })); + return std::make_unique(state, + DebugTrace { + .pos = pos, + .expr = expr, + .env = env, + .hint = hintfmt(s, s2), + .isError = false + }); } -DebugTraceStacker::DebugTraceStacker(EvalState &evalState, DebugTrace t) -:evalState(evalState), trace(t) +DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) + : evalState(evalState) + , trace(std::move(t)) { - evalState.debugTraces.push_front(t); + evalState.debugTraces.push_front(trace); if (evalState.debugStop && debuggerHook) - debuggerHook(0, t.env, t.expr); + debuggerHook(nullptr, trace.env, trace.expr); } void Value::mkString(std::string_view s) @@ -1303,15 +1294,14 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { - auto dts = - debuggerHook ? - makeDebugTraceStacker( - *this, - *e, - this->baseEnv, - (e->getPos() ? std::optional(ErrPos(positions[e->getPos()])) : std::nullopt), - "while evaluating the file '%1%':", resolvedPath) - : nullptr; + auto dts = debuggerHook + ? makeDebugTraceStacker( + *this, + *e, + this->baseEnv, + e->getPos() ? std::optional(ErrPos(positions[e->getPos()])) : std::nullopt, + "while evaluating the file '%1%':", resolvedPath) + : nullptr; // Enforce that 'flake.nix' is a direct attrset, not a // computation. @@ -1538,15 +1528,14 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { - auto dts = - debuggerHook ? - makeDebugTraceStacker( - state, - *this, - env, - state.positions[pos2], - "while evaluating the attribute '%1%'", - showAttrPath(state, env, attrPath)) + auto dts = debuggerHook + ? makeDebugTraceStacker( + state, + *this, + env, + state.positions[pos2], + "while evaluating the attribute '%1%'", + showAttrPath(state, env, attrPath)) : nullptr; for (auto & i : attrPath) { @@ -1708,14 +1697,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - auto dts = - debuggerHook ? - makeDebugTraceStacker(*this, *lambda.body, env2, positions[lambda.pos], - "while evaluating %s", - (lambda.name - ? concatStrings("'", symbols[lambda.name], "'") - : "anonymous lambda")) - : nullptr; + auto dts = debuggerHook + ? makeDebugTraceStacker( + *this, *lambda.body, env2, positions[lambda.pos], + "while evaluating %s", + lambda.name + ? concatStrings("'", symbols[lambda.name], "'") + : "anonymous lambda") + : nullptr; lambda.body->eval(*this, env2, vCur); } catch (Error & e) { @@ -2135,14 +2124,10 @@ void EvalState::forceValueDeep(Value & v) if (v.type() == nAttrs) { for (auto & i : *v.attrs) try { - - auto dts = - debuggerHook ? - // if the value is a thunk, we're evaling. otherwise no trace necessary. - (i.value->isThunk() ? - makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos], - "while evaluating the attribute '%1%'", symbols[i.name]) - : nullptr) + // If the value is a thunk, we're evaling. Otherwise no trace necessary. + auto dts = debuggerHook && i.value->isThunk() + ? makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos], + "while evaluating the attribute '%1%'", symbols[i.name]) : nullptr; recurse(*i.value); -- cgit v1.2.3 From f400c5466d45d342709483799d9b9c2ac24cf967 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 5 May 2022 15:43:23 -0600 Subject: rename valmap --- src/libexpr/eval.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ca0eec6e3..659b97658 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -772,7 +772,7 @@ void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env printEnvBindings(st, *expr.staticEnv.get(), env, 0); } -void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, valmap & vm) +void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm) { // add bindings for the next level up first, so that the bindings for this level // override the higher levels. @@ -795,9 +795,9 @@ void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const En } } -std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env) +std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env) { - auto vm = std::make_unique(); + auto vm = std::make_unique(); mapStaticEnvBindings(st, se, env, *vm); return vm; } -- cgit v1.2.3 From 2c9fafdc9e43f6da39c289888dedbbbf0ea0b208 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 6 May 2022 08:47:21 -0600 Subject: trying debugThrow --- src/libexpr/eval.cc | 103 +++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 70 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 659b97658..54872669a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -802,8 +802,9 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati return vm; } -void EvalState::debugLastTrace(Error & e) const +void EvalState::debugThrowLastTrace(Error & e) const { + std::cout << "debugThrowLastTrace(Error & e) const" << (debuggerHook == nullptr) << std::endl; // Call this in the situation where Expr and Env are inaccessible. // The debugger will start in the last context that's in the // DebugTrace stack. @@ -811,6 +812,18 @@ void EvalState::debugLastTrace(Error & e) const const DebugTrace & last = debugTraces.front(); debuggerHook(&e, last.env, last.expr); } + + throw e; +} + + +void EvalState::debugThrow(const Error &error, const Env & env, const Expr & expr) const +{ + std::cout << "debugThrow" << (debuggerHook == nullptr) << std::endl; + if (debuggerHook) + debuggerHook(&error, env, expr); + + throw error; } /* Every "format" object (even temporary) takes up a few hundred bytes @@ -824,10 +837,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwEvalError(const PosIdx pos, const char * s) const @@ -837,18 +847,14 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s) const .errPos = positions[pos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwEvalError(const char * s, const std::string & s2) const { auto error = EvalError(s, s2); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, @@ -860,10 +866,7 @@ void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions .suggestions = suggestions, }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2) const @@ -873,9 +876,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) const @@ -885,10 +886,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwEvalError(const char * s, const std::string & s2, @@ -899,9 +897,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2, .errPos = positions[noPos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, @@ -912,9 +908,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, @@ -925,10 +919,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) const @@ -939,10 +930,7 @@ void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym .errPos = positions[p1] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) const @@ -952,9 +940,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v .errPos = positions[pos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) const @@ -964,10 +950,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwTypeError(const PosIdx pos, const char * s) const @@ -977,9 +960,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s) const .errPos = positions[pos] }); - debugLastTrace(error); - - throw error; + debugThrowLastTrace(error); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, @@ -990,10 +971,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambd .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, @@ -1005,10 +983,7 @@ void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions .suggestions = suggestions, }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr) const @@ -1018,10 +993,7 @@ void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr .errPos = positions[expr.getPos()], }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const @@ -1031,10 +1003,7 @@ void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std: .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const @@ -1044,10 +1013,7 @@ void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const s .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const @@ -1057,10 +1023,7 @@ void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, cons .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; + debugThrow(error, env, expr); } void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2) const -- cgit v1.2.3 From fc66f48812383dad59ebdbabdd29bec34ed31921 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 6 May 2022 09:09:49 -0600 Subject: debugError() --- src/libexpr/eval.cc | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 659b97658..c5e33a279 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -813,6 +813,13 @@ void EvalState::debugLastTrace(Error & e) const } } +void debugError(Error * e, Env & env, Expr & expr) +{ + if (debuggerHook) + debuggerHook(e, env, expr); +} + + /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing @@ -824,8 +831,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -860,8 +866,7 @@ void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions .suggestions = suggestions, }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -885,8 +890,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -925,8 +929,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -939,8 +942,7 @@ void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym .errPos = positions[p1] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -964,8 +966,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -990,8 +991,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambd .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -1005,8 +1005,7 @@ void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions .suggestions = suggestions, }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -1018,8 +1017,7 @@ void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr .errPos = positions[expr.getPos()], }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -1031,8 +1029,7 @@ void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std: .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -1044,8 +1041,7 @@ void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const s .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } @@ -1057,8 +1053,7 @@ void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, cons .errPos = positions[pos] }); - if (debuggerHook) - debuggerHook(&error, env, expr); + debugError(&error, env, expr); throw error; } -- cgit v1.2.3 From 1ea13084c9aac84e7877f9051f656eb5ea519d8a Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 12 May 2022 13:59:58 -0600 Subject: template-ize debugThrow --- src/libexpr/eval.cc | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 54872669a..8ba3688d8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -802,30 +802,6 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati return vm; } -void EvalState::debugThrowLastTrace(Error & e) const -{ - std::cout << "debugThrowLastTrace(Error & e) const" << (debuggerHook == nullptr) << std::endl; - // Call this in the situation where Expr and Env are inaccessible. - // The debugger will start in the last context that's in the - // DebugTrace stack. - if (debuggerHook && !debugTraces.empty()) { - const DebugTrace & last = debugTraces.front(); - debuggerHook(&e, last.env, last.expr); - } - - throw e; -} - - -void EvalState::debugThrow(const Error &error, const Env & env, const Expr & expr) const -{ - std::cout << "debugThrow" << (debuggerHook == nullptr) << std::endl; - if (debuggerHook) - debuggerHook(&error, env, expr); - - throw error; -} - /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing -- cgit v1.2.3 From 86ba0a702c63b4a8ff79a07f9303318feb330642 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 15 May 2022 12:05:51 -0600 Subject: fix thunk issue --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c36bb59fb..d9ea92cc0 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2073,7 +2073,7 @@ void EvalState::forceValueDeep(Value & v) try { // If the value is a thunk, we're evaling. Otherwise no trace necessary. auto dts = debuggerHook && i.value->isThunk() - ? makeDebugTraceStacker(*this, *v.thunk.expr, *v.thunk.env, positions[i.pos], + ? makeDebugTraceStacker(*this, *i.value->thunk.expr, *i.value->thunk.env, positions[i.pos], "while evaluating the attribute '%1%'", symbols[i.name]) : nullptr; -- cgit v1.2.3 From 667074b5867ffe40e3f1c59bd8e4ebf259f86aaa Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Mon, 16 May 2022 09:20:51 -0600 Subject: first whack at passing evalState as an arg to debuggerHook. --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d9ea92cc0..3c998f7b6 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1044,7 +1044,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) { evalState.debugTraces.push_front(trace); if (evalState.debugStop && debuggerHook) - debuggerHook(nullptr, trace.env, trace.expr); + debuggerHook(evalState, nullptr, trace.env, trace.expr); } void Value::mkString(std::string_view s) -- cgit v1.2.3 From 357fb84dbaad0b056704915c6a43764cda63ee7f Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 10:48:10 -0600 Subject: use an expr->StaticEnv table in evalState --- src/libexpr/eval.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index d9ea92cc0..c9e4a05b7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -772,12 +772,12 @@ void printEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & } } -// TODO: add accompanying env for With stuff. -void printEnvBindings(const SymbolTable & st, const Expr & expr, const Env & env) +void printEnvBindings(const EvalState &es, const Expr & expr, const Env & env) { // just print the names for now - if (expr.staticEnv) - printEnvBindings(st, *expr.staticEnv.get(), env, 0); + auto se = es.getStaticEnv(expr); + if (se) + printEnvBindings(es.symbols, *se, env, 0); } void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm) -- cgit v1.2.3 From 7ddef73d026d79adc0c4f3fd1518d88d1331c38c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 12:44:40 -0600 Subject: de-const evalState exceptions --- src/libexpr/eval.cc | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bd1cbaab5..f95ff4931 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -814,7 +814,7 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing exceptions. */ -void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr) { auto error = EvalError({ .msg = hintfmt(s), @@ -824,7 +824,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr debugThrow(error, env, expr); } -void EvalState::throwEvalError(const PosIdx pos, const char * s) const +void EvalState::throwEvalError(const PosIdx pos, const char * s) { auto error = EvalError({ .msg = hintfmt(s), @@ -834,7 +834,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s) const debugThrowLastTrace(error); } -void EvalState::throwEvalError(const char * s, const std::string & s2) const +void EvalState::throwEvalError(const char * s, const std::string & s2) { auto error = EvalError(s, s2); @@ -842,7 +842,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2) const } void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, - const std::string & s2, Env & env, Expr & expr) const + const std::string & s2, Env & env, Expr & expr) { auto error = EvalError(ErrorInfo{ .msg = hintfmt(s, s2), @@ -853,7 +853,7 @@ void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions debugThrow(error, env, expr); } -void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2) { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -863,7 +863,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri debugThrowLastTrace(error); } -void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) const +void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -874,7 +874,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri } void EvalState::throwEvalError(const char * s, const std::string & s2, - const std::string & s3) const + const std::string & s3) { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -885,7 +885,7 @@ void EvalState::throwEvalError(const char * s, const std::string & s2, } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, - const std::string & s3) const + const std::string & s3) { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -896,7 +896,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, - const std::string & s3, Env & env, Expr & expr) const + const std::string & s3, Env & env, Expr & expr) { auto error = EvalError({ .msg = hintfmt(s, s2), @@ -906,7 +906,7 @@ void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::stri debugThrow(error, env, expr); } -void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) const +void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) { // p1 is where the error occurred; p2 is a position mentioned in the message. auto error = EvalError({ @@ -917,7 +917,7 @@ void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym debugThrow(error, env, expr); } -void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) const +void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) { auto error = TypeError({ .msg = hintfmt(s, showType(v)), @@ -927,7 +927,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v debugThrowLastTrace(error); } -void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) const +void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) { auto error = TypeError({ .msg = hintfmt(s, showType(v)), @@ -937,7 +937,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v debugThrow(error, env, expr); } -void EvalState::throwTypeError(const PosIdx pos, const char * s) const +void EvalState::throwTypeError(const PosIdx pos, const char * s) { auto error = TypeError({ .msg = hintfmt(s), @@ -948,7 +948,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s) const } void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, - const Symbol s2, Env & env, Expr &expr) const + const Symbol s2, Env & env, Expr &expr) { auto error = TypeError({ .msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]), @@ -959,7 +959,7 @@ void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambd } void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, - const ExprLambda & fun, const Symbol s2, Env & env, Expr &expr) const + const ExprLambda & fun, const Symbol s2, Env & env, Expr &expr) { auto error = TypeError(ErrorInfo { .msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]), @@ -970,7 +970,7 @@ void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions debugThrow(error, env, expr); } -void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr) const +void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr) { auto error = TypeError({ .msg = hintfmt(s, showType(v)), @@ -980,7 +980,7 @@ void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr debugThrow(error, env, expr); } -void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const +void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { auto error = AssertionError({ .msg = hintfmt(s, s1), @@ -990,7 +990,7 @@ void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std: debugThrow(error, env, expr); } -void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const +void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { auto error = UndefinedVarError({ .msg = hintfmt(s, s1), @@ -1000,7 +1000,7 @@ void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const s debugThrow(error, env, expr); } -void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) const +void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { auto error = MissingArgumentError({ .msg = hintfmt(s, s1), -- cgit v1.2.3 From 0600df86b8bc59633457f7ceb79e84c8ea3fed17 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Thu, 19 May 2022 17:01:23 -0600 Subject: 'debugMode' --- src/libexpr/eval.cc | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index f95ff4931..1cde4a9ab 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -463,6 +463,7 @@ EvalState::EvalState( , emptyBindings(0) , store(store) , buildStore(buildStore ? buildStore : store) + , debugMode(false) , debugStop(false) , debugQuit(false) , regexCache(makeRegexCache()) @@ -810,6 +811,31 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati return vm; } +void EvalState::debugRepl(const Error * error, const Env & env, const Expr & expr) +{ + auto dts = + error && expr.getPos() + ? std::make_unique( + *this, + DebugTrace { + .pos = error->info().errPos ? *error->info().errPos : positions[expr.getPos()], + .expr = expr, + .env = env, + .hint = error->info().msg, + .isError = true + }) + : nullptr; + + if (error) + printError("%s\n\n" ANSI_BOLD "Starting REPL to allow you to inspect the current state of the evaluator.\n" ANSI_NORMAL, error->what()); + + auto se = getStaticEnv(expr); + if (se) { + auto vm = mapStaticEnvBindings(symbols, *se.get(), env); + runRepl(*this, *vm); + } +} + /* Every "format" object (even temporary) takes up a few hundred bytes of stack space, which is a real killer in the recursive evaluator. So here are some helper functions for throwing @@ -1043,8 +1069,8 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) , trace(std::move(t)) { evalState.debugTraces.push_front(trace); - if (evalState.debugStop && debuggerHook) - debuggerHook(evalState, nullptr, trace.env, trace.expr); + if (evalState.debugStop && evalState.debugMode) + evalState.debugRepl(nullptr, trace.env, trace.expr); } void Value::mkString(std::string_view s) @@ -1241,7 +1267,7 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { - auto dts = debuggerHook + auto dts = debugMode ? makeDebugTraceStacker( *this, *e, @@ -1475,7 +1501,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { - auto dts = debuggerHook + auto dts = state.debugMode ? makeDebugTraceStacker( state, *this, @@ -1644,7 +1670,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - auto dts = debuggerHook + auto dts = debugMode ? makeDebugTraceStacker( *this, *lambda.body, env2, positions[lambda.pos], "while evaluating %s", @@ -2072,7 +2098,7 @@ void EvalState::forceValueDeep(Value & v) for (auto & i : *v.attrs) try { // If the value is a thunk, we're evaling. Otherwise no trace necessary. - auto dts = debuggerHook && i.value->isThunk() + auto dts = debugMode && i.value->isThunk() ? makeDebugTraceStacker(*this, *i.value->thunk.expr, *i.value->thunk.env, positions[i.pos], "while evaluating the attribute '%1%'", symbols[i.name]) : nullptr; -- cgit v1.2.3 From 884d59178735bcb5d5db7db97a05ad62a175493b Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 20 May 2022 10:33:50 -0600 Subject: debugRepl ftn pointer --- src/libexpr/eval.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 1cde4a9ab..5faecdbe3 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -463,7 +463,7 @@ EvalState::EvalState( , emptyBindings(0) , store(store) , buildStore(buildStore ? buildStore : store) - , debugMode(false) + , debugRepl(0) , debugStop(false) , debugQuit(false) , regexCache(makeRegexCache()) @@ -811,8 +811,12 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati return vm; } -void EvalState::debugRepl(const Error * error, const Env & env, const Expr & expr) +void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & expr) { + // double check we've got the debugRepl ftn pointer. + if (!debugRepl) + return; + auto dts = error && expr.getPos() ? std::make_unique( @@ -832,7 +836,7 @@ void EvalState::debugRepl(const Error * error, const Env & env, const Expr & exp auto se = getStaticEnv(expr); if (se) { auto vm = mapStaticEnvBindings(symbols, *se.get(), env); - runRepl(*this, *vm); + (debugRepl)(*this, *vm); } } @@ -1070,7 +1074,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) { evalState.debugTraces.push_front(trace); if (evalState.debugStop && evalState.debugMode) - evalState.debugRepl(nullptr, trace.env, trace.expr); + evalState.runDebugRepl(nullptr, trace.env, trace.expr); } void Value::mkString(std::string_view s) -- cgit v1.2.3 From 13d02af0799f5d2f7a53825936d587e22edcacb6 Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Sun, 22 May 2022 21:45:24 -0600 Subject: remove redundant 'debugMode' flag --- src/libexpr/eval.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5faecdbe3..c457df380 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -813,7 +813,7 @@ std::unique_ptr mapStaticEnvBindings(const SymbolTable & st, const Stati void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & expr) { - // double check we've got the debugRepl ftn pointer. + // double check we've got the debugRepl function pointer. if (!debugRepl) return; @@ -1073,7 +1073,7 @@ DebugTraceStacker::DebugTraceStacker(EvalState & evalState, DebugTrace t) , trace(std::move(t)) { evalState.debugTraces.push_front(trace); - if (evalState.debugStop && evalState.debugMode) + if (evalState.debugStop && evalState.debugRepl) evalState.runDebugRepl(nullptr, trace.env, trace.expr); } @@ -1271,7 +1271,7 @@ void EvalState::cacheFile( fileParseCache[resolvedPath] = e; try { - auto dts = debugMode + auto dts = debugRepl ? makeDebugTraceStacker( *this, *e, @@ -1505,7 +1505,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) e->eval(state, env, vTmp); try { - auto dts = state.debugMode + auto dts = state.debugRepl ? makeDebugTraceStacker( state, *this, @@ -1674,7 +1674,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - auto dts = debugMode + auto dts = debugRepl ? makeDebugTraceStacker( *this, *lambda.body, env2, positions[lambda.pos], "while evaluating %s", @@ -2102,7 +2102,7 @@ void EvalState::forceValueDeep(Value & v) for (auto & i : *v.attrs) try { // If the value is a thunk, we're evaling. Otherwise no trace necessary. - auto dts = debugMode && i.value->isThunk() + auto dts = debugRepl && i.value->isThunk() ? makeDebugTraceStacker(*this, *i.value->thunk.expr, *i.value->thunk.env, positions[i.pos], "while evaluating the attribute '%1%'", symbols[i.name]) : nullptr; -- cgit v1.2.3 From 91b7d5373acdc5d9b3f2c13d16b9850ab5fc9e9d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 25 May 2022 12:32:22 +0200 Subject: Style tweaks --- src/libexpr/eval.cc | 114 ++++++++++++++++++---------------------------------- 1 file changed, 38 insertions(+), 76 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c457df380..6dc7918b1 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -816,7 +816,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & // double check we've got the debugRepl function pointer. if (!debugRepl) return; - + auto dts = error && expr.getPos() ? std::make_unique( @@ -846,198 +846,160 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & exceptions. */ void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr) { - auto error = EvalError({ + debugThrow(EvalError({ .msg = hintfmt(s), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwEvalError(const PosIdx pos, const char * s) { - auto error = EvalError({ + debugThrowLastTrace(EvalError({ .msg = hintfmt(s), .errPos = positions[pos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwEvalError(const char * s, const std::string & s2) { - auto error = EvalError(s, s2); - - debugThrowLastTrace(error); + debugThrowLastTrace(EvalError(s, s2)); } void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2, Env & env, Expr & expr) { - auto error = EvalError(ErrorInfo{ + debugThrow(EvalError(ErrorInfo{ .msg = hintfmt(s, s2), .errPos = positions[pos], .suggestions = suggestions, - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2) { - auto error = EvalError({ + debugThrowLastTrace(EvalError({ .msg = hintfmt(s, s2), .errPos = positions[pos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr) { - auto error = EvalError({ + debugThrow(EvalError({ .msg = hintfmt(s, s2), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwEvalError(const char * s, const std::string & s2, const std::string & s3) { - auto error = EvalError({ + debugThrowLastTrace(EvalError({ .msg = hintfmt(s, s2), .errPos = positions[noPos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) { - auto error = EvalError({ + debugThrowLastTrace(EvalError({ .msg = hintfmt(s, s2), .errPos = positions[pos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3, Env & env, Expr & expr) { - auto error = EvalError({ + debugThrow(EvalError({ .msg = hintfmt(s, s2), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr) { // p1 is where the error occurred; p2 is a position mentioned in the message. - auto error = EvalError({ + debugThrow(EvalError({ .msg = hintfmt(s, symbols[sym], positions[p2]), .errPos = positions[p1] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) { - auto error = TypeError({ + debugThrowLastTrace(TypeError({ .msg = hintfmt(s, showType(v)), .errPos = positions[pos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr) { - auto error = TypeError({ + debugThrow(TypeError({ .msg = hintfmt(s, showType(v)), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwTypeError(const PosIdx pos, const char * s) { - auto error = TypeError({ + debugThrowLastTrace(TypeError({ .msg = hintfmt(s), .errPos = positions[pos] - }); - - debugThrowLastTrace(error); + })); } void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2, Env & env, Expr &expr) { - auto error = TypeError({ + debugThrow(TypeError({ .msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2, Env & env, Expr &expr) { - auto error = TypeError(ErrorInfo { + debugThrow(TypeError(ErrorInfo { .msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]), .errPos = positions[pos], .suggestions = suggestions, - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr) { - auto error = TypeError({ + debugThrow(TypeError({ .msg = hintfmt(s, showType(v)), .errPos = positions[expr.getPos()], - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { - auto error = AssertionError({ + debugThrow(AssertionError({ .msg = hintfmt(s, s1), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { - auto error = UndefinedVarError({ + debugThrow(UndefinedVarError({ .msg = hintfmt(s, s1), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr) { - auto error = MissingArgumentError({ + debugThrow(MissingArgumentError({ .msg = hintfmt(s, s1), .errPos = positions[pos] - }); - - debugThrow(error, env, expr); + }), env, expr); } void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2) const -- cgit v1.2.3 From b4c24a29c62259a068c8270be62cf5a412e1e35c Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Wed, 25 May 2022 10:21:20 -0600 Subject: back to ref in NixRepl --- src/libexpr/eval.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 6dc7918b1..18baf1cb7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -836,7 +836,7 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr & auto se = getStaticEnv(expr); if (se) { auto vm = mapStaticEnvBindings(symbols, *se.get(), env); - (debugRepl)(*this, *vm); + (debugRepl)(ref(shared_from_this()), *vm); } } -- cgit v1.2.3