mirror of
https://github.com/NixOS/nix
synced 2025-07-05 08:11:47 +02:00
C API: add user_data argument to nix_alloc_primop
Also add a helper function for primops, that converts to C argument types (and eventually handles errors)
This commit is contained in:
parent
48aa57549d
commit
3d79f38709
2 changed files with 38 additions and 8 deletions
|
@ -34,18 +34,39 @@ static nix::Value & check_value_not_null(Value * value)
|
||||||
return *((nix::Value *) value);
|
return *((nix::Value *) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to convert calls from nix into C API.
|
||||||
|
*
|
||||||
|
* Deals with errors and converts arguments from C++ into C types.
|
||||||
|
*/
|
||||||
|
static void nix_c_primop_wrapper(
|
||||||
|
PrimOpFun f, void * userdata, nix::EvalState & state, const nix::PosIdx pos, nix::Value ** args, nix::Value & v)
|
||||||
|
{
|
||||||
|
f(userdata, (State *) &state, *reinterpret_cast<const int *>(&pos), (Value **) args, (Value *) &v);
|
||||||
|
}
|
||||||
|
|
||||||
PrimOp * nix_alloc_primop(
|
PrimOp * nix_alloc_primop(
|
||||||
nix_c_context * context, PrimOpFun fun, int arity, const char * name, const char ** args, const char * doc)
|
nix_c_context * context,
|
||||||
|
PrimOpFun fun,
|
||||||
|
int arity,
|
||||||
|
const char * name,
|
||||||
|
const char ** args,
|
||||||
|
const char * doc,
|
||||||
|
void * user_data)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
auto fun2 = (nix::PrimOpFun) fun;
|
|
||||||
auto p = new
|
auto p = new
|
||||||
#ifdef HAVE_BOEHMGC
|
#ifdef HAVE_BOEHMGC
|
||||||
(GC)
|
(GC)
|
||||||
#endif
|
#endif
|
||||||
nix::PrimOp{.name = name, .args = {}, .arity = (size_t) arity, .doc = doc, .fun = fun2};
|
nix::PrimOp{
|
||||||
|
.name = name,
|
||||||
|
.args = {},
|
||||||
|
.arity = (size_t) arity,
|
||||||
|
.doc = doc,
|
||||||
|
.fun = std::bind_front(nix_c_primop_wrapper, fun, user_data)};
|
||||||
if (args)
|
if (args)
|
||||||
for (size_t i = 0; args[i]; i++)
|
for (size_t i = 0; args[i]; i++)
|
||||||
p->args.emplace_back(*args);
|
p->args.emplace_back(*args);
|
||||||
|
|
|
@ -65,6 +65,7 @@ typedef struct ExternalValue ExternalValue;
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** @brief Function pointer for primops
|
/** @brief Function pointer for primops
|
||||||
|
* @param[in] user_data Arbitrary data, passed to nix_alloc_primop and stored.
|
||||||
* @param[in] state Evaluator state
|
* @param[in] state Evaluator state
|
||||||
* @param[in] pos Call position, opaque index into the state's position table.
|
* @param[in] pos Call position, opaque index into the state's position table.
|
||||||
* @param[in] args list of arguments. Note that these can be thunks and should be forced using nix_value_force before
|
* @param[in] args list of arguments. Note that these can be thunks and should be forced using nix_value_force before
|
||||||
|
@ -72,7 +73,7 @@ typedef struct ExternalValue ExternalValue;
|
||||||
* @param[out] ret return value
|
* @param[out] ret return value
|
||||||
* @see nix_alloc_primop, nix_set_primop
|
* @see nix_alloc_primop, nix_set_primop
|
||||||
*/
|
*/
|
||||||
typedef void (*PrimOpFun)(State * state, int pos, Value ** args, Value * ret);
|
typedef void (*PrimOpFun)(void * user_data, State * state, int pos, Value ** args, Value * ret);
|
||||||
|
|
||||||
/** @brief Allocate a PrimOp
|
/** @brief Allocate a PrimOp
|
||||||
*
|
*
|
||||||
|
@ -85,19 +86,27 @@ typedef void (*PrimOpFun)(State * state, int pos, Value ** args, Value * ret);
|
||||||
* @param[in] name function name
|
* @param[in] name function name
|
||||||
* @param[in] args array of argument names, NULL-terminated
|
* @param[in] args array of argument names, NULL-terminated
|
||||||
* @param[in] doc optional, documentation for this primop
|
* @param[in] doc optional, documentation for this primop
|
||||||
|
* @param[in] user_data optional, arbitrary data, passed to the function when it's called
|
||||||
* @return primop, or null in case of errors
|
* @return primop, or null in case of errors
|
||||||
* @see nix_set_primop
|
* @see nix_set_primop
|
||||||
*/
|
*/
|
||||||
PrimOp * nix_alloc_primop(
|
PrimOp * nix_alloc_primop(
|
||||||
nix_c_context * context, PrimOpFun fun, int arity, const char * name, const char ** args, const char * doc);
|
nix_c_context * context,
|
||||||
|
PrimOpFun fun,
|
||||||
|
int arity,
|
||||||
|
const char * name,
|
||||||
|
const char ** args,
|
||||||
|
const char * doc,
|
||||||
|
void * user_data);
|
||||||
|
|
||||||
/** @brief add a primop to the `builtins` attribute set
|
/** @brief add a primop to the `builtins` attribute set
|
||||||
*
|
*
|
||||||
* Only applies to States created after this call.
|
* Only applies to States created after this call.
|
||||||
*
|
*
|
||||||
* Moves your PrimOp into the global evaluator
|
* Moves your PrimOp content into the global evaluator
|
||||||
* registry, meaning your input PrimOp pointer is no longer usable
|
* registry, meaning your input PrimOp pointer is no longer usable.
|
||||||
* (but still possibly subject to garbage collection).
|
* You are free to remove your references to it,
|
||||||
|
* after which it will be garbage collected.
|
||||||
*
|
*
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @return primop, or null in case of errors
|
* @return primop, or null in case of errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue