fx.reflection: function: implementing pre-binding argument values to functions

This commit is contained in:
2026-05-04 22:53:45 +01:00
parent 3d1600ece6
commit b8e270b962
2 changed files with 67 additions and 14 deletions
+66 -13
View File
@@ -15,14 +15,46 @@ struct fx_function_p {
* variable number of arguments, which may be handled differently by the * variable number of arguments, which may be handled differently by the
* ABI */ * ABI */
size_t func_nr_args; size_t func_nr_args;
fx_value *func_bound_args;
size_t func_nr_bound_args, func_max_bound_args;
}; };
/*** PRIVATE FUNCTIONS ********************************************************/ /*** PRIVATE FUNCTIONS ********************************************************/
extern intptr_t fx_function_invoke_i( static fx_status function_bind(
fx_function_impl impl, struct fx_function_p *func,
const fx_value *args, fx_value *args,
size_t nr_args); size_t nr_args)
{
if (func->func_nr_bound_args) {
fx_value_unset_array(
func->func_bound_args,
func->func_nr_bound_args);
}
if (!args || !nr_args) {
func->func_nr_bound_args = 0;
return FX_SUCCESS;
}
if (nr_args > func->func_max_bound_args) {
fx_value *buf = realloc(
func->func_bound_args,
nr_args * sizeof *buf);
if (!buf) {
return FX_ERR_NO_MEMORY;
}
func->func_bound_args = buf;
func->func_max_bound_args = nr_args;
}
fx_value_copy_array(func->func_bound_args, args, nr_args);
func->func_nr_bound_args = nr_args;
return FX_SUCCESS;
}
static fx_status function_invoke( static fx_status function_invoke(
const struct fx_function_p *func, const struct fx_function_p *func,
@@ -30,34 +62,44 @@ static fx_status function_invoke(
size_t nr_args, size_t nr_args,
fx_value *return_value) fx_value *return_value)
{ {
if (nr_args < func->func_nr_args) { size_t total_args = nr_args + func->func_nr_bound_args;
if (total_args < func->func_nr_args) {
return FX_ERR_INVALID_ARGUMENT; return FX_ERR_INVALID_ARGUMENT;
} }
if (nr_args > func->func_nr_args if (total_args > func->func_nr_args
&& !(func->func_flags & FX_FUNCTION_F_VARARG)) { && !(func->func_flags & FX_FUNCTION_F_VARARG)) {
return FX_ERR_INVALID_ARGUMENT; return FX_ERR_INVALID_ARGUMENT;
} }
size_t nr_fixed_args = func->func_nr_args; size_t nr_fixed_args = func->func_nr_args;
size_t nr_var_args = nr_args - nr_fixed_args; size_t nr_var_args = total_args - nr_fixed_args;
struct callvm vm = {0}; struct callvm vm = {0};
callvm_reset(&vm, nr_fixed_args); callvm_reset(&vm, nr_fixed_args);
for (size_t i = 0; i < func->func_nr_bound_args; i++) {
const fx_value *arg = &func->func_bound_args[i];
callvm_push(&vm, arg);
}
for (size_t i = 0; i < nr_args; i++) { for (size_t i = 0; i < nr_args; i++) {
const fx_value *arg = &args[i]; const fx_value *arg = &args[i];
callvm_push(&vm, arg); callvm_push(&vm, arg);
} }
*return_value *return_value = callvm_invoke(
= callvm_invoke(&vm, func->func_impl, func->func_return_type); &vm,
func->func_impl,
func->func_return_type);
callvm_reset(&vm, 0); callvm_reset(&vm, 0);
return FX_SUCCESS; return FX_SUCCESS;
} }
/*** PUBLIC FUNCTIONS *********************************************************/ /*** PUBLIC FUNCTIONS
* *********************************************************/
FX_API fx_function *fx_function_create( FX_API fx_function *fx_function_create(
const char *name, const char *name,
@@ -72,8 +114,9 @@ FX_API fx_function *fx_function_create(
return NULL; return NULL;
} }
struct fx_function_p *p struct fx_function_p *p = fx_object_get_private(
= fx_object_get_private(func, FX_REFLECTION_TYPE_FUNCTION); func,
FX_REFLECTION_TYPE_FUNCTION);
p->func_name = fx_strdup(name); p->func_name = fx_strdup(name);
p->func_flags = flags; p->func_flags = flags;
@@ -88,7 +131,17 @@ FX_API fx_function *fx_function_create(
return func; return func;
} }
FX_API fx_status fx_function_invoke( fx_status fx_function_bind(fx_function *func, fx_value *args, size_t nr_args)
{
FX_CLASS_DISPATCH_STATIC(
FX_REFLECTION_TYPE_FUNCTION,
function_bind,
func,
args,
nr_args);
}
fx_status fx_function_invoke(
const fx_function *func, const fx_function *func,
const fx_value *args, const fx_value *args,
size_t nr_args, size_t nr_args,
@@ -67,7 +67,7 @@ FX_API fx_function *fx_function_create(
size_t nr_args, size_t nr_args,
fx_value_type return_type); fx_value_type return_type);
FX_API fx_status FX_API fx_status
fx_function_bind(const fx_function *func, const fx_value *args, size_t nr_args); fx_function_bind(fx_function *func, fx_value *args, size_t nr_args);
FX_API fx_status fx_function_invoke( FX_API fx_status fx_function_invoke(
const fx_function *func, const fx_function *func,
const fx_value *args, const fx_value *args,