mirror of
https://github.com/neovim/neovim.git
synced 2025-10-13 13:26:06 +00:00
Merge pull request #20100 from bfredl/luafunc
refactor(typval): change FC_CFUNC abstraction into FC_LUAREF
This commit is contained in:
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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));
|
||||
|
@@ -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.
|
||||
|
@@ -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); \
|
||||
} \
|
||||
|
@@ -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
|
||||
|
@@ -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));
|
||||
|
Reference in New Issue
Block a user