Merge pull request #20100 from bfredl/luafunc

refactor(typval): change FC_CFUNC abstraction into FC_LUAREF
This commit is contained in:
bfredl
2022-09-07 09:08:05 +02:00
committed by GitHub
7 changed files with 36 additions and 85 deletions

View File

@@ -65,8 +65,8 @@ typedef struct {
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
do { \
ufunc_T *fp = find_func(fun); \
if (fp != NULL && fp->uf_cb == nlua_CFunction_func_call) { \
LuaRef ref = api_new_luaref(((LuaCFunctionState *)fp->uf_cb_state)->lua_callable.func_ref); \
if (fp != NULL && (fp->uf_flags & FC_LUAREF)) { \
LuaRef ref = api_new_luaref(fp->uf_luaref); \
kvi_push(edata->stack, LUAREF_OBJ(ref)); \
} else { \
TYPVAL_ENCODE_CONV_NIL(tv); \
@@ -351,10 +351,7 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
}
case kObjectTypeLuaRef: {
LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
state->lua_callable.func_ref = api_new_luaref(obj.data.luaref);
char *name =
(char *)register_cfunc(&nlua_CFunction_func_call, &nlua_CFunction_func_free, state);
char *name = (char *)register_luafunc(api_new_luaref(obj.data.luaref));
tv->v_type = VAR_FUNC;
tv->vval.v_string = xstrdup(name);
break;

View File

@@ -286,12 +286,6 @@ typedef struct {
/// Number of fixed variables used for arguments
#define FIXVAR_CNT 12
/// Callback interface for C function reference>
/// Used for managing functions that were registered with |register_cfunc|
typedef int (*cfunc_T)(int argcount, typval_T *argvars, typval_T *rettv, void *state); // NOLINT
/// Callback to clear cfunc_T and any associated state.
typedef void (*cfunc_free_T)(void *state);
// Structure to hold info for a function that is currently being executed.
typedef struct funccall_S funccall_T;
@@ -330,10 +324,7 @@ struct ufunc {
garray_T uf_lines; ///< function lines
int uf_profiling; ///< true when func is being profiled
int uf_prof_initialized;
// Managing cfuncs
cfunc_T uf_cb; ///< C function extension callback
cfunc_free_T uf_cb_free; ///< C function extension free callback
void *uf_cb_state; ///< State of C function extension.
LuaRef uf_luaref; ///< lua callback, used if (uf_flags & FC_LUAREF)
// Profiling the function as a whole.
int uf_tm_count; ///< nr of calls
proftime_T uf_tm_total; ///< time spent in function + children

View File

@@ -28,20 +28,6 @@
#include "nvim/ui.h"
#include "nvim/vim.h"
// flags used in uf_flags
#define FC_ABORT 0x01 // abort function on error
#define FC_RANGE 0x02 // function accepts range
#define FC_DICT 0x04 // Dict function, uses "self"
#define FC_CLOSURE 0x08 // closure, uses outer scope variables
#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
#define FC_SANDBOX 0x40 // function defined in the sandbox
#define FC_DEAD 0x80 // function kept only for reference to dfunc
#define FC_EXPORT 0x100 // "export def Func()"
#define FC_NOARGS 0x200 // no a: variables in lambda
#define FC_VIM9 0x400 // defined in vim9 script file
#define FC_CFUNC 0x800 // C function extension
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/userfunc.c.generated.h"
#endif
@@ -758,9 +744,9 @@ static void func_clear_items(ufunc_T *fp)
ga_clear_strings(&(fp->uf_lines));
XFREE_CLEAR(fp->uf_name_exp);
if (fp->uf_cb_free != NULL) {
fp->uf_cb_free(fp->uf_cb_state);
fp->uf_cb_free = NULL;
if (fp->uf_flags & FC_LUAREF) {
api_free_luaref(fp->uf_luaref);
fp->uf_luaref = LUA_NOREF;
}
XFREE_CLEAR(fp->uf_tml_count);
@@ -1538,9 +1524,8 @@ int call_func(const char *funcname, int len, typval_T *rettv, int argcount_in, t
if (fp != NULL && (fp->uf_flags & FC_DELETED)) {
error = ERROR_DELETED;
} else if (fp != NULL && (fp->uf_flags & FC_CFUNC)) {
cfunc_T cb = fp->uf_cb;
error = (*cb)(argcount, argvars, rettv, fp->uf_cb_state);
} else if (fp != NULL && (fp->uf_flags & FC_LUAREF)) {
error = typval_exec_lua_callable(fp->uf_luaref, argcount, argvars, rettv);
} else if (fp != NULL) {
if (funcexe->argv_func != NULL) {
// postponed filling in the arguments, do it now
@@ -3552,20 +3537,18 @@ bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
return abort;
}
/// Registers a C extension user function.
char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
/// Registers a luaref as a lambda.
char_u *register_luafunc(LuaRef ref)
{
char_u *name = get_lambda_name();
ufunc_T *fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
fp->uf_refcount = 1;
fp->uf_varargs = true;
fp->uf_flags = FC_CFUNC;
fp->uf_flags = FC_LUAREF;
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
fp->uf_cb = cb;
fp->uf_cb_free = cb_free;
fp->uf_cb_state = state;
fp->uf_luaref = ref;
STRCPY(fp->uf_name, name);
hash_add(&func_hashtab, UF2HIKEY(fp));

View File

@@ -9,6 +9,20 @@
#define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name)))
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
// flags used in uf_flags
#define FC_ABORT 0x01 // abort function on error
#define FC_RANGE 0x02 // function accepts range
#define FC_DICT 0x04 // Dict function, uses "self"
#define FC_CLOSURE 0x08 // closure, uses outer scope variables
#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
#define FC_SANDBOX 0x40 // function defined in the sandbox
#define FC_DEAD 0x80 // function kept only for reference to dfunc
#define FC_EXPORT 0x100 // "export def Func()"
#define FC_NOARGS 0x200 // no a: variables in lambda
#define FC_VIM9 0x400 // defined in vim9 script file
#define FC_LUAREF 0x800 // luaref callback
///< Structure used by trans_function_name()
typedef struct {
dict_T *fd_dict; ///< Dictionary used.

View File

@@ -385,12 +385,9 @@ nlua_pop_typval_table_processing_end:
break;
}
case LUA_TFUNCTION: {
LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
state->lua_callable.func_ref = nlua_ref_global(lstate, -1);
LuaRef func = nlua_ref_global(lstate, -1);
char *name = (char *)register_cfunc(&nlua_CFunction_func_call,
&nlua_CFunction_func_free,
state);
char *name = (char *)register_luafunc(func);
cur.tv->v_type = VAR_FUNC;
cur.tv->vval.v_string = xstrdup(name);
@@ -476,8 +473,8 @@ static bool typval_conv_special = false;
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
do { \
ufunc_T *fp = find_func(fun); \
if (fp != NULL && fp->uf_cb == nlua_CFunction_func_call) { \
nlua_pushref(lstate, ((LuaCFunctionState *)fp->uf_cb_state)->lua_callable.func_ref); \
if (fp != NULL && fp->uf_flags & FC_LUAREF) { \
nlua_pushref(lstate, fp->uf_luaref); \
} else { \
TYPVAL_ENCODE_CONV_NIL(tv); \
} \

View File

@@ -9,14 +9,6 @@
#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
typedef struct {
LuaRef func_ref;
} LuaCallable;
typedef struct {
LuaCallable lua_callable;
} LuaCFunctionState;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "lua/converter.h.generated.h"
#endif

View File

@@ -1425,12 +1425,11 @@ int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
/// @param[in] argcount Count of typval arguments
/// @param[in] argvars Typval Arguments
/// @param[out] rettv The return value from the called function.
int typval_exec_lua_callable(lua_State *lstate, LuaCallable lua_cb, int argcount, typval_T *argvars,
typval_T *rettv)
int typval_exec_lua_callable(LuaRef lua_cb, int argcount, typval_T *argvars, typval_T *rettv)
{
LuaRef cb = lua_cb.func_ref;
lua_State *lstate = global_lstate;
nlua_pushref(lstate, cb);
nlua_pushref(lstate, lua_cb);
PUSH_ALL_TYPVALS(lstate, argvars, argcount, false);
@@ -1833,26 +1832,6 @@ static int nlua_is_thread(lua_State *lstate)
return 1;
}
// Required functions for lua c functions as VimL callbacks
int nlua_CFunction_func_call(int argcount, typval_T *argvars, typval_T *rettv, void *state)
{
lua_State *const lstate = global_lstate;
LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
return typval_exec_lua_callable(lstate, funcstate->lua_callable,
argcount, argvars, rettv);
}
void nlua_CFunction_func_free(void *state)
{
lua_State *const lstate = global_lstate;
LuaCFunctionState *funcstate = (LuaCFunctionState *)state;
nlua_unref_global(lstate, funcstate->lua_callable.func_ref);
xfree(funcstate);
}
bool nlua_is_table_from_lua(typval_T *const arg)
{
if (arg->v_type == VAR_DICT) {
@@ -1898,11 +1877,9 @@ char_u *nlua_register_table_as_callable(typval_T *const arg)
}
lua_pop(lstate, 2); // [table]
LuaCFunctionState *state = xmalloc(sizeof(LuaCFunctionState));
state->lua_callable.func_ref = nlua_ref_global(lstate, -1);
LuaRef func = nlua_ref_global(lstate, -1);
char_u *name = register_cfunc(&nlua_CFunction_func_call,
&nlua_CFunction_func_free, state);
char_u *name = register_luafunc(func);
lua_pop(lstate, 1); // []
assert(top == lua_gettop(lstate));