diff options
-rw-r--r-- | doc/manual/command-ref/conf-file.xml | 2 | ||||
-rw-r--r-- | src/libexpr/eval.cc | 8 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 2 | ||||
-rw-r--r-- | src/libexpr/primops.hh | 3 | ||||
-rw-r--r-- | tests/plugins.sh | 2 | ||||
-rw-r--r-- | tests/plugins/plugintest.cc | 4 |
6 files changed, 15 insertions, 6 deletions
diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml index cede6db3cea7..5c4561f66d86 100644 --- a/doc/manual/command-ref/conf-file.xml +++ b/doc/manual/command-ref/conf-file.xml @@ -750,7 +750,7 @@ builtins.fetchurl { files will be dlopened by Nix, allowing them to affect execution through static initialization. In particular, these plugins may construct static instances of RegisterPrimOp to - add new primops to the expression language, + add new primops or constants to the expression language, RegisterStoreImplementation to add new store implementations, and RegisterCommand to add new subcommands to the <literal>nix</literal> command. See the constructors for those diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0b0a0f7b1790..1f3bbc0a53bd 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -404,7 +404,7 @@ Path EvalState::toRealPath(const Path & path, const PathSet & context) }; -void EvalState::addConstant(const string & name, Value & v) +Value * EvalState::addConstant(const string & name, Value & v) { Value * v2 = allocValue(); *v2 = v; @@ -412,12 +412,18 @@ void EvalState::addConstant(const string & name, Value & v) 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)); + return v2; } Value * EvalState::addPrimOp(const string & name, unsigned int arity, PrimOpFun primOp) { + if (arity == 0) { + Value v; + primOp(*this, noPos, nullptr, v); + return addConstant(name, v); + } Value * v = allocValue(); string name2 = string(name, 0, 2) == "__" ? string(name, 2) : name; Symbol sym = symbols.create(name2); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 9e3d30d95f49..51905d7e1c62 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -210,7 +210,7 @@ private: void createBaseEnv(); - void addConstant(const string & name, Value & v); + Value * addConstant(const string & name, Value & v); Value * addPrimOp(const string & name, unsigned int arity, PrimOpFun primOp); diff --git a/src/libexpr/primops.hh b/src/libexpr/primops.hh index 39d23b04a5ce..31bf3f84f6c7 100644 --- a/src/libexpr/primops.hh +++ b/src/libexpr/primops.hh @@ -9,6 +9,9 @@ struct RegisterPrimOp { typedef std::vector<std::tuple<std::string, size_t, PrimOpFun>> PrimOps; static PrimOps * primOps; + /* You can register a constant by passing an arity of 0. fun + will get called during EvalState initialization, so there + may be primops not yet added and builtins is not yet sorted. */ RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun); }; diff --git a/tests/plugins.sh b/tests/plugins.sh index 6d18d1da0d18..23caf04f3380 100644 --- a/tests/plugins.sh +++ b/tests/plugins.sh @@ -2,6 +2,6 @@ source common.sh set -o pipefail -res=$(nix eval '(builtins.constNull true)' --option plugin-files $PWD/plugins/plugintest.so) +res=$(nix eval '(builtins.anotherNull)' --option plugin-files $PWD/plugins/plugintest.so) [ "$res"x = "nullx" ] diff --git a/tests/plugins/plugintest.cc b/tests/plugins/plugintest.cc index f788c4814322..6b5e6d7cde21 100644 --- a/tests/plugins/plugintest.cc +++ b/tests/plugins/plugintest.cc @@ -2,9 +2,9 @@ using namespace nix; -static void prim_constNull (EvalState & state, const Pos & pos, Value ** args, Value & v) +static void prim_anotherNull (EvalState & state, const Pos & pos, Value ** args, Value & v) { mkNull(v); } -static RegisterPrimOp r("constNull", 1, prim_constNull); +static RegisterPrimOp r("anotherNull", 0, prim_anotherNull); |