mirror of
https://github.com/NixOS/nix
synced 2025-07-06 21:41:48 +02:00
nix_api_expr: always force values before giving them to the user
This commit is contained in:
parent
c48b9b8a83
commit
9cccb8bae0
4 changed files with 13 additions and 3 deletions
|
@ -49,6 +49,7 @@ nix_err nix_expr_eval_from_string(nix_c_context *context, State *state,
|
||||||
nix::Expr *parsedExpr = state->state.parseExprFromString(
|
nix::Expr *parsedExpr = state->state.parseExprFromString(
|
||||||
expr, state->state.rootPath(nix::CanonPath(path)));
|
expr, state->state.rootPath(nix::CanonPath(path)));
|
||||||
state->state.eval(parsedExpr, *(nix::Value *)value);
|
state->state.eval(parsedExpr, *(nix::Value *)value);
|
||||||
|
state->state.forceValue(*(nix::Value *)value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
@ -60,6 +61,7 @@ nix_err nix_value_call(nix_c_context *context, State *state, Value *fn,
|
||||||
try {
|
try {
|
||||||
state->state.callFunction(*(nix::Value *)fn, *(nix::Value *)arg,
|
state->state.callFunction(*(nix::Value *)fn, *(nix::Value *)arg,
|
||||||
*(nix::Value *)value, nix::noPos);
|
*(nix::Value *)value, nix::noPos);
|
||||||
|
state->state.forceValue(*(nix::Value *)value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,11 @@ nix_err nix_value_call(nix_c_context *context, State *state, Value *fn,
|
||||||
* The Nix interpreter is lazy, and not-yet-evaluated Values can be
|
* The Nix interpreter is lazy, and not-yet-evaluated Values can be
|
||||||
* of type NIX_TYPE_THUNK instead of their actual value.
|
* of type NIX_TYPE_THUNK instead of their actual value.
|
||||||
*
|
*
|
||||||
* This function converts Values into their final type.
|
* This function converts these Values into their final type.
|
||||||
|
*
|
||||||
|
* @note You don't need this function for basic API usage, since all functions
|
||||||
|
* that return a value call it for you. The only place you will see a
|
||||||
|
* NIX_TYPE_THUNK is in the primop callback.
|
||||||
*
|
*
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] state The state of the evaluation.
|
* @param[in] state The state of the evaluation.
|
||||||
|
|
|
@ -201,7 +201,7 @@ ExternalValue *nix_get_external(nix_c_context *context, Value *value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
|
Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
|
||||||
unsigned int ix) {
|
State *state, unsigned int ix) {
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
|
@ -209,6 +209,7 @@ Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
|
||||||
assert(v.type() == nix::nList);
|
assert(v.type() == nix::nList);
|
||||||
auto *p = v.listElems()[ix];
|
auto *p = v.listElems()[ix];
|
||||||
nix_gc_incref(nullptr, p);
|
nix_gc_incref(nullptr, p);
|
||||||
|
state->state.forceValue(*p, nix::noPos);
|
||||||
return (Value *)p;
|
return (Value *)p;
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
|
@ -225,6 +226,7 @@ Value *nix_get_attr_byname(nix_c_context *context, const Value *value,
|
||||||
auto attr = v.attrs->get(s);
|
auto attr = v.attrs->get(s);
|
||||||
if (attr) {
|
if (attr) {
|
||||||
nix_gc_incref(nullptr, attr->value);
|
nix_gc_incref(nullptr, attr->value);
|
||||||
|
state->state.forceValue(*attr->value, nix::noPos);
|
||||||
return attr->value;
|
return attr->value;
|
||||||
}
|
}
|
||||||
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
||||||
|
@ -258,6 +260,7 @@ Value *nix_get_attr_byidx(nix_c_context *context, const Value *value,
|
||||||
const nix::Attr &a = (*v.attrs)[i];
|
const nix::Attr &a = (*v.attrs)[i];
|
||||||
*name = ((const std::string &)(state->state.symbols[a.name])).c_str();
|
*name = ((const std::string &)(state->state.symbols[a.name])).c_str();
|
||||||
nix_gc_incref(nullptr, a.value);
|
nix_gc_incref(nullptr, a.value);
|
||||||
|
state->state.forceValue(*a.value, nix::noPos);
|
||||||
return a.value;
|
return a.value;
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
|
|
|
@ -178,11 +178,12 @@ ExternalValue *nix_get_external(nix_c_context *context, Value *);
|
||||||
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
|
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
|
* @param[in] state nix evaluator state
|
||||||
* @param[in] ix list element to get
|
* @param[in] ix list element to get
|
||||||
* @return value, NULL in case of errors
|
* @return value, NULL in case of errors
|
||||||
*/
|
*/
|
||||||
Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
|
Value *nix_get_list_byidx(nix_c_context *context, const Value *value,
|
||||||
unsigned int ix);
|
State *state, unsigned int ix);
|
||||||
/** @brief Get an attr by name
|
/** @brief Get an attr by name
|
||||||
*
|
*
|
||||||
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
|
* Owned by the GC. Use nix_gc_decref when you're done with the pointer
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue