mirror of
https://github.com/neovim/neovim.git
synced 2025-09-11 13:58:18 +00:00
perf(api): allow to use an arena for return values
This commit is contained in:
@@ -801,7 +801,7 @@ def extract_from_xml(filename, target, width, fmt_vimhelp):
|
|||||||
|
|
||||||
prefix = '%s(' % name
|
prefix = '%s(' % name
|
||||||
suffix = '%s)' % ', '.join('{%s}' % a[1] for a in params
|
suffix = '%s)' % ', '.join('{%s}' % a[1] for a in params
|
||||||
if a[0] not in ('void', 'Error'))
|
if a[0] not in ('void', 'Error', 'Arena'))
|
||||||
|
|
||||||
if not fmt_vimhelp:
|
if not fmt_vimhelp:
|
||||||
c_decl = '%s %s(%s);' % (return_type, name, ', '.join(c_args))
|
c_decl = '%s %s(%s);' % (return_type, name, ', '.join(c_args))
|
||||||
|
@@ -1021,7 +1021,7 @@ void nvim_buf_del_var(Buffer buffer, String name, Error *err)
|
|||||||
/// @param buffer Buffer handle, or 0 for current buffer
|
/// @param buffer Buffer handle, or 0 for current buffer
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return Buffer name
|
/// @return Buffer name
|
||||||
String nvim_buf_get_name(Buffer buffer, Error *err)
|
String nvim_buf_get_name(Buffer buffer, Arena *arena, Error *err)
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
String rv = STRING_INIT;
|
String rv = STRING_INIT;
|
||||||
@@ -1031,7 +1031,7 @@ String nvim_buf_get_name(Buffer buffer, Error *err)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cstr_to_string((char *)buf->b_ffname);
|
return cstr_as_string((char *)buf->b_ffname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the full file name for a buffer
|
/// Sets the full file name for a buffer
|
||||||
|
@@ -5,18 +5,23 @@
|
|||||||
|
|
||||||
typedef Object (*ApiDispatchWrapper)(uint64_t channel_id,
|
typedef Object (*ApiDispatchWrapper)(uint64_t channel_id,
|
||||||
Array args,
|
Array args,
|
||||||
|
Arena *arena,
|
||||||
Error *error);
|
Error *error);
|
||||||
|
|
||||||
/// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
|
/// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
|
||||||
/// functions of this type.
|
/// functions of this type.
|
||||||
typedef struct {
|
struct MsgpackRpcRequestHandler {
|
||||||
const char *name;
|
const char *name;
|
||||||
ApiDispatchWrapper fn;
|
ApiDispatchWrapper fn;
|
||||||
bool fast; // Function is safe to be executed immediately while running the
|
bool fast; // Function is safe to be executed immediately while running the
|
||||||
// uv loop (the loop is run very frequently due to breakcheck).
|
// uv loop (the loop is run very frequently due to breakcheck).
|
||||||
// If "fast" is false, the function is deferred, i e the call will
|
// If "fast" is false, the function is deferred, i e the call will
|
||||||
// be put in the event queue, for safe handling later.
|
// be put in the event queue, for safe handling later.
|
||||||
} MsgpackRpcRequestHandler;
|
bool arena_return; // return value is allocated in the arena (or statically)
|
||||||
|
// and should not be freed as such.
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const MsgpackRpcRequestHandler method_handlers[];
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "api/private/dispatch.h.generated.h"
|
# include "api/private/dispatch.h.generated.h"
|
||||||
|
@@ -1629,11 +1629,11 @@ Array nvim_list_chans(void)
|
|||||||
/// an error, it is a three-element array with the zero-based index of the call
|
/// an error, it is a three-element array with the zero-based index of the call
|
||||||
/// which resulted in an error, the error type and the error message. If an
|
/// which resulted in an error, the error type and the error message. If an
|
||||||
/// error occurred, the values from all preceding calls will still be returned.
|
/// error occurred, the values from all preceding calls will still be returned.
|
||||||
Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
|
Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *err)
|
||||||
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
|
||||||
{
|
{
|
||||||
Array rv = ARRAY_DICT_INIT;
|
Array rv = arena_array(arena, 2);
|
||||||
Array results = ARRAY_DICT_INIT;
|
Array results = arena_array(arena, calls.size);
|
||||||
Error nested_error = ERROR_INIT;
|
Error nested_error = ERROR_INIT;
|
||||||
|
|
||||||
size_t i; // also used for freeing the variables
|
size_t i; // also used for freeing the variables
|
||||||
@@ -1676,29 +1676,32 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
|
|||||||
if (ERROR_SET(&nested_error)) {
|
if (ERROR_SET(&nested_error)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Object result = handler.fn(channel_id, args, &nested_error);
|
|
||||||
|
Object result = handler.fn(channel_id, args, arena, &nested_error);
|
||||||
if (ERROR_SET(&nested_error)) {
|
if (ERROR_SET(&nested_error)) {
|
||||||
// error handled after loop
|
// error handled after loop
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!handler.arena_return && result.type != kObjectTypeNil) {
|
||||||
|
// TODO: fix to not leak memory as fuck
|
||||||
|
}
|
||||||
|
|
||||||
ADD(results, result);
|
ADD_C(results, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD(rv, ARRAY_OBJ(results));
|
ADD_C(rv, ARRAY_OBJ(results));
|
||||||
if (ERROR_SET(&nested_error)) {
|
if (ERROR_SET(&nested_error)) {
|
||||||
Array errval = ARRAY_DICT_INIT;
|
Array errval = arena_array(arena, 3);
|
||||||
ADD(errval, INTEGER_OBJ((Integer)i));
|
ADD_C(errval, INTEGER_OBJ((Integer)i));
|
||||||
ADD(errval, INTEGER_OBJ(nested_error.type));
|
ADD_C(errval, INTEGER_OBJ(nested_error.type));
|
||||||
ADD(errval, STRING_OBJ(cstr_to_string(nested_error.msg)));
|
ADD_C(errval, STRING_OBJ(cstr_to_string(nested_error.msg))); // TODO
|
||||||
ADD(rv, ARRAY_OBJ(errval));
|
ADD_C(rv, ARRAY_OBJ(errval));
|
||||||
} else {
|
} else {
|
||||||
ADD(rv, NIL);
|
ADD_C(rv, NIL);
|
||||||
}
|
}
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
validation_error:
|
validation_error:
|
||||||
api_free_array(results);
|
|
||||||
theend:
|
theend:
|
||||||
api_clear_error(&nested_error);
|
api_clear_error(&nested_error);
|
||||||
return rv;
|
return rv;
|
||||||
@@ -1803,6 +1806,7 @@ Dictionary nvim__stats(void)
|
|||||||
PUT(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip));
|
PUT(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip));
|
||||||
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
|
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
|
||||||
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
|
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
|
||||||
|
PUT(rv, "arena_alloc_count", INTEGER_OBJ((Integer)arena_alloc_count));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1074,7 +1074,7 @@ char *arg_all(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "argc([window id])" function
|
/// "argc([window id])" function
|
||||||
void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_argc(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (argvars[0].v_type == VAR_UNKNOWN) {
|
if (argvars[0].v_type == VAR_UNKNOWN) {
|
||||||
// use the current window
|
// use the current window
|
||||||
@@ -1095,13 +1095,13 @@ void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "argidx()" function
|
/// "argidx()" function
|
||||||
void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_argidx(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = curwin->w_arg_idx;
|
rettv->vval.v_number = curwin->w_arg_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "arglistid()" function
|
/// "arglistid()" function
|
||||||
void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_arglistid(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = -1;
|
rettv->vval.v_number = -1;
|
||||||
win_T *wp = find_tabwin(&argvars[0], &argvars[1]);
|
win_T *wp = find_tabwin(&argvars[0], &argvars[1]);
|
||||||
@@ -1123,7 +1123,7 @@ static void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rett
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "argv(nr)" function
|
/// "argv(nr)" function
|
||||||
void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_argv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
aentry_T *arglist = NULL;
|
aentry_T *arglist = NULL;
|
||||||
int argcount = -1;
|
int argcount = -1;
|
||||||
|
@@ -2751,7 +2751,7 @@ void wildmenu_cleanup(CmdlineInfo *cclp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "getcompletion()" function
|
/// "getcompletion()" function
|
||||||
void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char_u *pat;
|
char_u *pat;
|
||||||
expand_T xpc;
|
expand_T xpc;
|
||||||
|
@@ -494,7 +494,7 @@ static int del_history_idx(int histype, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "histadd()" function
|
/// "histadd()" function
|
||||||
void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_histadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
HistoryType histype;
|
HistoryType histype;
|
||||||
|
|
||||||
@@ -517,7 +517,7 @@ void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "histdel()" function
|
/// "histdel()" function
|
||||||
void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_histdel(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
|
const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
|
||||||
@@ -540,7 +540,7 @@ void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "histget()" function
|
/// "histget()" function
|
||||||
void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_histget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
HistoryType type;
|
HistoryType type;
|
||||||
int idx;
|
int idx;
|
||||||
@@ -562,7 +562,7 @@ void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "histnr()" function
|
/// "histnr()" function
|
||||||
void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_histnr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *const histname = tv_get_string_chk(&argvars[0]);
|
const char *const histname = tv_get_string_chk(&argvars[0]);
|
||||||
HistoryType i = histname == NULL
|
HistoryType i = histname == NULL
|
||||||
|
@@ -1917,7 +1917,7 @@ static bool digraph_set_common(const typval_T *argchars, const typval_T *argdigr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "digraph_get()" function
|
/// "digraph_get()" function
|
||||||
void f_digraph_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_digraph_get(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL; // Return empty string for failure
|
rettv->vval.v_string = NULL; // Return empty string for failure
|
||||||
@@ -1938,7 +1938,7 @@ void f_digraph_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "digraph_getlist()" function
|
/// "digraph_getlist()" function
|
||||||
void f_digraph_getlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_digraph_getlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
bool flag_list_all;
|
bool flag_list_all;
|
||||||
|
|
||||||
@@ -1957,7 +1957,7 @@ void f_digraph_getlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "digraph_set()" function
|
/// "digraph_set()" function
|
||||||
void f_digraph_set(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_digraph_set(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_BOOL;
|
rettv->v_type = VAR_BOOL;
|
||||||
rettv->vval.v_bool = kBoolVarFalse;
|
rettv->vval.v_bool = kBoolVarFalse;
|
||||||
@@ -1970,7 +1970,7 @@ void f_digraph_set(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "digraph_setlist()" function
|
/// "digraph_setlist()" function
|
||||||
void f_digraph_setlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_digraph_setlist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_BOOL;
|
rettv->v_type = VAR_BOOL;
|
||||||
rettv->vval.v_bool = kBoolVarFalse;
|
rettv->vval.v_bool = kBoolVarFalse;
|
||||||
|
@@ -4968,7 +4968,7 @@ theend:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref, FunPtr fptr)
|
void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
char *name;
|
char *name;
|
||||||
|
@@ -23,7 +23,7 @@ end
|
|||||||
return {
|
return {
|
||||||
funcs={
|
funcs={
|
||||||
abs={args=1, base=1},
|
abs={args=1, base=1},
|
||||||
acos={args=1, base=1, func="float_op_wrapper", data="&acos"}, -- WJMc
|
acos={args=1, base=1, float_func="acos"}, -- WJMc
|
||||||
add={args=2, base=1},
|
add={args=2, base=1},
|
||||||
['and']={args=2, base=1},
|
['and']={args=2, base=1},
|
||||||
api_info={},
|
api_info={},
|
||||||
@@ -33,7 +33,7 @@ return {
|
|||||||
argidx={},
|
argidx={},
|
||||||
arglistid={args={0, 2}},
|
arglistid={args={0, 2}},
|
||||||
argv={args={0, 2}},
|
argv={args={0, 2}},
|
||||||
asin={args=1, base=1, func="float_op_wrapper", data="&asin"}, -- WJMc
|
asin={args=1, base=1, float_func="asin"}, -- WJMc
|
||||||
assert_beeps={args=1, base=1},
|
assert_beeps={args=1, base=1},
|
||||||
assert_equal={args={2, 3}, base=2},
|
assert_equal={args={2, 3}, base=2},
|
||||||
assert_equalfile={args={2, 3}, base=1},
|
assert_equalfile={args={2, 3}, base=1},
|
||||||
@@ -47,7 +47,7 @@ return {
|
|||||||
assert_notmatch={args={2, 3}, base=2},
|
assert_notmatch={args={2, 3}, base=2},
|
||||||
assert_report={args=1, base=1},
|
assert_report={args=1, base=1},
|
||||||
assert_true={args={1, 2}, base=1},
|
assert_true={args={1, 2}, base=1},
|
||||||
atan={args=1, base=1, func="float_op_wrapper", data="&atan"},
|
atan={args=1, base=1, float_func="atan"},
|
||||||
atan2={args=2, base=1},
|
atan2={args=2, base=1},
|
||||||
browse={args=4},
|
browse={args=4},
|
||||||
browsedir={args=2},
|
browsedir={args=2},
|
||||||
@@ -67,7 +67,7 @@ return {
|
|||||||
byteidx={args=2, base=1},
|
byteidx={args=2, base=1},
|
||||||
byteidxcomp={args=2, base=1},
|
byteidxcomp={args=2, base=1},
|
||||||
call={args={2, 3}, base=1},
|
call={args={2, 3}, base=1},
|
||||||
ceil={args=1, base=1, func="float_op_wrapper", data="&ceil"},
|
ceil={args=1, base=1, float_func="ceil"},
|
||||||
changenr={},
|
changenr={},
|
||||||
chanclose={args={1, 2}},
|
chanclose={args={1, 2}},
|
||||||
chansend={args=2},
|
chansend={args=2},
|
||||||
@@ -85,8 +85,8 @@ return {
|
|||||||
complete_info={args={0, 1}, base=1},
|
complete_info={args={0, 1}, base=1},
|
||||||
confirm={args={1, 4}, base=1},
|
confirm={args={1, 4}, base=1},
|
||||||
copy={args=1, base=1},
|
copy={args=1, base=1},
|
||||||
cos={args=1, base=1, func="float_op_wrapper", data="&cos"},
|
cos={args=1, base=1, float_func="cos"},
|
||||||
cosh={args=1, base=1, func="float_op_wrapper", data="&cosh"},
|
cosh={args=1, base=1, float_func="cosh"},
|
||||||
count={args={2, 4}, base=1},
|
count={args={2, 4}, base=1},
|
||||||
cscope_connection={args={0, 3}},
|
cscope_connection={args={0, 3}},
|
||||||
ctxget={args={0, 1}},
|
ctxget={args={0, 1}},
|
||||||
@@ -117,7 +117,7 @@ return {
|
|||||||
execute={args={1, 2}, base=1},
|
execute={args={1, 2}, base=1},
|
||||||
exepath={args=1, base=1},
|
exepath={args=1, base=1},
|
||||||
exists={args=1, base=1},
|
exists={args=1, base=1},
|
||||||
exp={args=1, base=1, func="float_op_wrapper", data="&exp"},
|
exp={args=1, base=1, float_func="exp"},
|
||||||
expand={args={1, 3}, base=1},
|
expand={args={1, 3}, base=1},
|
||||||
expandcmd={args=1, base=1},
|
expandcmd={args=1, base=1},
|
||||||
extend={args={2, 3}, base=1},
|
extend={args={2, 3}, base=1},
|
||||||
@@ -130,7 +130,7 @@ return {
|
|||||||
findfile={args={1, 3}, base=1},
|
findfile={args={1, 3}, base=1},
|
||||||
flatten={args={1, 2}, base=1},
|
flatten={args={1, 2}, base=1},
|
||||||
float2nr={args=1, base=1},
|
float2nr={args=1, base=1},
|
||||||
floor={args=1, base=1, func="float_op_wrapper", data="&floor"},
|
floor={args=1, base=1, float_func="floor"},
|
||||||
fmod={args=2, base=1},
|
fmod={args=2, base=1},
|
||||||
fnameescape={args=1, base=1},
|
fnameescape={args=1, base=1},
|
||||||
fnamemodify={args=2, base=1},
|
fnamemodify={args=2, base=1},
|
||||||
@@ -245,8 +245,8 @@ return {
|
|||||||
lispindent={args=1, base=1},
|
lispindent={args=1, base=1},
|
||||||
list2str={args={1, 2}, base=1},
|
list2str={args={1, 2}, base=1},
|
||||||
localtime={},
|
localtime={},
|
||||||
log={args=1, base=1, func="float_op_wrapper", data="&log"},
|
log={args=1, base=1, float_func="log"},
|
||||||
log10={args=1, base=1, func="float_op_wrapper", data="&log10"},
|
log10={args=1, base=1, float_func="log10"},
|
||||||
luaeval={args={1, 2}, base=1},
|
luaeval={args={1, 2}, base=1},
|
||||||
map={args=2, base=1},
|
map={args=2, base=1},
|
||||||
maparg={args={1, 4}, base=1},
|
maparg={args={1, 4}, base=1},
|
||||||
@@ -304,7 +304,7 @@ return {
|
|||||||
['repeat']={args=2, base=1},
|
['repeat']={args=2, base=1},
|
||||||
resolve={args=1, base=1},
|
resolve={args=1, base=1},
|
||||||
reverse={args=1, base=1},
|
reverse={args=1, base=1},
|
||||||
round={args=1, base=1, func="float_op_wrapper", data="&round"},
|
round={args=1, base=1, float_func="round"},
|
||||||
rpcnotify={args=varargs(2)},
|
rpcnotify={args=varargs(2)},
|
||||||
rpcrequest={args=varargs(2)},
|
rpcrequest={args=varargs(2)},
|
||||||
rpcstart={args={1, 2}},
|
rpcstart={args={1, 2}},
|
||||||
@@ -358,8 +358,8 @@ return {
|
|||||||
sign_unplace={args={1, 2}, base=1},
|
sign_unplace={args={1, 2}, base=1},
|
||||||
sign_unplacelist={args=1, base=1},
|
sign_unplacelist={args=1, base=1},
|
||||||
simplify={args=1, base=1},
|
simplify={args=1, base=1},
|
||||||
sin={args=1, base=1, func="float_op_wrapper", data="&sin"},
|
sin={args=1, base=1, float_func="sin"},
|
||||||
sinh={args=1, base=1, func="float_op_wrapper", data="&sinh"},
|
sinh={args=1, base=1, float_func="sinh"},
|
||||||
sockconnect={args={2,3}},
|
sockconnect={args={2,3}},
|
||||||
sort={args={1, 3}, base=1},
|
sort={args={1, 3}, base=1},
|
||||||
soundfold={args=1, base=1},
|
soundfold={args=1, base=1},
|
||||||
@@ -367,7 +367,7 @@ return {
|
|||||||
spellbadword={args={0, 1}, base=1},
|
spellbadword={args={0, 1}, base=1},
|
||||||
spellsuggest={args={1, 3}, base=1},
|
spellsuggest={args={1, 3}, base=1},
|
||||||
split={args={1, 3}, base=1},
|
split={args={1, 3}, base=1},
|
||||||
sqrt={args=1, base=1, func="float_op_wrapper", data="&sqrt"},
|
sqrt={args=1, base=1, float_func="sqrt"},
|
||||||
srand={args={0, 1}, base=1},
|
srand={args={0, 1}, base=1},
|
||||||
stdpath={args=1},
|
stdpath={args=1},
|
||||||
str2float={args=1, base=1},
|
str2float={args=1, base=1},
|
||||||
@@ -402,8 +402,8 @@ return {
|
|||||||
tabpagewinnr={args={1, 2}, base=1},
|
tabpagewinnr={args={1, 2}, base=1},
|
||||||
tagfiles={},
|
tagfiles={},
|
||||||
taglist={args={1, 2}, base=1},
|
taglist={args={1, 2}, base=1},
|
||||||
tan={args=1, base=1, func="float_op_wrapper", data="&tan"},
|
tan={args=1, base=1, float_func="tan"},
|
||||||
tanh={args=1, base=1, func="float_op_wrapper", data="&tanh"},
|
tanh={args=1, base=1, float_func="tanh"},
|
||||||
tempname={},
|
tempname={},
|
||||||
termopen={args={1, 2}},
|
termopen={args={1, 2}},
|
||||||
test_garbagecollect_now={},
|
test_garbagecollect_now={},
|
||||||
@@ -417,7 +417,7 @@ return {
|
|||||||
toupper={args=1, base=1},
|
toupper={args=1, base=1},
|
||||||
tr={args=3, base=1},
|
tr={args=3, base=1},
|
||||||
trim={args={1, 3}, base=1},
|
trim={args={1, 3}, base=1},
|
||||||
trunc={args=1, base=1, func="float_op_wrapper", data="&trunc"},
|
trunc={args=1, base=1, float_func="trunc"},
|
||||||
type={args=1, base=1},
|
type={args=1, base=1},
|
||||||
undofile={args=1, base=1},
|
undofile={args=1, base=1},
|
||||||
undotree={},
|
undotree={},
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,12 @@
|
|||||||
#ifndef NVIM_EVAL_FUNCS_H
|
#ifndef NVIM_EVAL_FUNCS_H
|
||||||
#define NVIM_EVAL_FUNCS_H
|
#define NVIM_EVAL_FUNCS_H
|
||||||
|
|
||||||
|
#include "nvim/api/private/dispatch.h"
|
||||||
#include "nvim/buffer_defs.h"
|
#include "nvim/buffer_defs.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
|
|
||||||
/// Prototype of C function that implements VimL function
|
/// Prototype of C function that implements VimL function
|
||||||
typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data);
|
typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, EvalFuncData data);
|
||||||
|
|
||||||
/// Special flags for base_arg @see EvalFuncDef
|
/// Special flags for base_arg @see EvalFuncDef
|
||||||
#define BASE_NONE 0 ///< Not a method (no base argument).
|
#define BASE_NONE 0 ///< Not a method (no base argument).
|
||||||
@@ -19,7 +20,7 @@ typedef struct {
|
|||||||
uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST.
|
uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST.
|
||||||
bool fast; ///< Can be run in |api-fast| events
|
bool fast; ///< Can be run in |api-fast| events
|
||||||
VimLFunc func; ///< Function implementation.
|
VimLFunc func; ///< Function implementation.
|
||||||
FunPtr data; ///< Userdata for function implementation.
|
EvalFuncData data; ///< Userdata for function implementation.
|
||||||
} EvalFuncDef;
|
} EvalFuncDef;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
@@ -831,7 +831,7 @@ int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "join()" function
|
/// "join()" function
|
||||||
void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_join(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (argvars[0].v_type != VAR_LIST) {
|
if (argvars[0].v_type != VAR_LIST) {
|
||||||
emsg(_(e_listreq));
|
emsg(_(e_listreq));
|
||||||
@@ -855,7 +855,7 @@ void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "list2str()" function
|
/// "list2str()" function
|
||||||
void f_list2str(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_list2str(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
|
|
||||||
@@ -1267,13 +1267,13 @@ theend:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sort"({list})" function
|
/// "sort"({list})" function
|
||||||
void f_sort(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sort(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
do_sort_uniq(argvars, rettv, true);
|
do_sort_uniq(argvars, rettv, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "uniq({list})" function
|
/// "uniq({list})" function
|
||||||
void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_uniq(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
do_sort_uniq(argvars, rettv, false);
|
do_sort_uniq(argvars, rettv, false);
|
||||||
}
|
}
|
||||||
@@ -2806,25 +2806,25 @@ static void tv_dict_list(typval_T *const tv, typval_T *const rettv, const DictLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "items(dict)" function
|
/// "items(dict)" function
|
||||||
void f_items(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_items(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
tv_dict_list(argvars, rettv, 2);
|
tv_dict_list(argvars, rettv, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "keys()" function
|
/// "keys()" function
|
||||||
void f_keys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_keys(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
tv_dict_list(argvars, rettv, 0);
|
tv_dict_list(argvars, rettv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "values(dict)" function
|
/// "values(dict)" function
|
||||||
void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_values(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
tv_dict_list(argvars, rettv, 1);
|
tv_dict_list(argvars, rettv, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "has_key()" function
|
/// "has_key()" function
|
||||||
void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_has_key(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (argvars[0].v_type != VAR_DICT) {
|
if (argvars[0].v_type != VAR_DICT) {
|
||||||
emsg(_(e_dictreq));
|
emsg(_(e_dictreq));
|
||||||
|
@@ -25,9 +25,6 @@
|
|||||||
typedef int64_t varnumber_T;
|
typedef int64_t varnumber_T;
|
||||||
typedef uint64_t uvarnumber_T;
|
typedef uint64_t uvarnumber_T;
|
||||||
|
|
||||||
/// Type used for VimL VAR_FLOAT values
|
|
||||||
typedef double float_T;
|
|
||||||
|
|
||||||
/// Refcount for dict or list that should not be freed
|
/// Refcount for dict or list that should not be freed
|
||||||
enum { DO_NOT_FREE_CNT = (INT_MAX / 2), };
|
enum { DO_NOT_FREE_CNT = (INT_MAX / 2), };
|
||||||
|
|
||||||
|
@@ -1702,7 +1702,7 @@ bool var_exists(const char *var)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "gettabvar()" function
|
/// "gettabvar()" function
|
||||||
void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_gettabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *const varname = tv_get_string_chk(&argvars[1]);
|
const char *const varname = tv_get_string_chk(&argvars[1]);
|
||||||
tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
|
tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
|
||||||
@@ -1716,19 +1716,19 @@ void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "gettabwinvar()" function
|
/// "gettabwinvar()" function
|
||||||
void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_gettabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
getwinvar(argvars, rettv, 1);
|
getwinvar(argvars, rettv, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "getwinvar()" function
|
/// "getwinvar()" function
|
||||||
void f_getwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
getwinvar(argvars, rettv, 0);
|
getwinvar(argvars, rettv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "getbufvar()" function
|
/// "getbufvar()" function
|
||||||
void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *const varname = tv_get_string_chk(&argvars[1]);
|
const char *const varname = tv_get_string_chk(&argvars[1]);
|
||||||
buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
|
buf_T *const buf = tv_get_buf_from_arg(&argvars[0]);
|
||||||
@@ -1737,7 +1737,7 @@ void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "settabvar()" function
|
/// "settabvar()" function
|
||||||
void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_settabvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = 0;
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
@@ -1768,19 +1768,19 @@ void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "settabwinvar()" function
|
/// "settabwinvar()" function
|
||||||
void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_settabwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
setwinvar(argvars, rettv, 1);
|
setwinvar(argvars, rettv, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "setwinvar()" function
|
/// "setwinvar()" function
|
||||||
void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setwinvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
setwinvar(argvars, rettv, 0);
|
setwinvar(argvars, rettv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "setbufvar()" function
|
/// "setbufvar()" function
|
||||||
void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setbufvar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (check_secure()
|
if (check_secure()
|
||||||
|| !tv_check_str_or_nr(&argvars[0])) {
|
|| !tv_check_str_or_nr(&argvars[0])) {
|
||||||
|
@@ -3047,7 +3047,7 @@ int cmd_exists(const char *const name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "fullcommand" function
|
/// "fullcommand" function
|
||||||
void f_fullcommand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_fullcommand(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char *name = argvars[0].vval.v_string;
|
char *name = argvars[0].vval.v_string;
|
||||||
|
|
||||||
|
@@ -3212,19 +3212,19 @@ static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "foldclosed()" function
|
/// "foldclosed()" function
|
||||||
void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_foldclosed(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
foldclosed_both(argvars, rettv, false);
|
foldclosed_both(argvars, rettv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "foldclosedend()" function
|
/// "foldclosedend()" function
|
||||||
void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_foldclosedend(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
foldclosed_both(argvars, rettv, true);
|
foldclosed_both(argvars, rettv, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "foldlevel()" function
|
/// "foldlevel()" function
|
||||||
void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_foldlevel(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const linenr_T lnum = tv_get_lnum(argvars);
|
const linenr_T lnum = tv_get_lnum(argvars);
|
||||||
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
|
||||||
@@ -3233,7 +3233,7 @@ void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "foldtext()" function
|
/// "foldtext()" function
|
||||||
void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_foldtext(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
@@ -3279,7 +3279,7 @@ void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "foldtextresult(lnum)" function
|
/// "foldtextresult(lnum)" function
|
||||||
void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_foldtextresult(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char_u buf[FOLD_TEXT_LEN];
|
char_u buf[FOLD_TEXT_LEN];
|
||||||
static bool entered = false;
|
static bool entered = false;
|
||||||
|
@@ -26,6 +26,7 @@ local c_id = (
|
|||||||
local c_void = P('void')
|
local c_void = P('void')
|
||||||
local c_param_type = (
|
local c_param_type = (
|
||||||
((P('Error') * fill * P('*') * fill) * Cc('error')) +
|
((P('Error') * fill * P('*') * fill) * Cc('error')) +
|
||||||
|
((P('Arena') * fill * P('*') * fill) * Cc('arena')) +
|
||||||
C((P('const ') ^ -1) * (c_id) * (ws ^ 1) * P('*')) +
|
C((P('const ') ^ -1) * (c_id) * (ws ^ 1) * P('*')) +
|
||||||
(C(c_id) * (ws ^ 1))
|
(C(c_id) * (ws ^ 1))
|
||||||
)
|
)
|
||||||
|
@@ -17,6 +17,7 @@ local nvimdir = arg[1]
|
|||||||
package.path = nvimdir .. '/?.lua;' .. package.path
|
package.path = nvimdir .. '/?.lua;' .. package.path
|
||||||
|
|
||||||
_G.vim = loadfile(nvimdir..'/../../runtime/lua/vim/shared.lua')()
|
_G.vim = loadfile(nvimdir..'/../../runtime/lua/vim/shared.lua')()
|
||||||
|
_G.vim.inspect = loadfile(nvimdir..'/../../runtime/lua/vim/inspect.lua')()
|
||||||
|
|
||||||
local hashy = require'generators.hashy'
|
local hashy = require'generators.hashy'
|
||||||
|
|
||||||
@@ -72,6 +73,11 @@ for i = 6, #arg do
|
|||||||
-- for specifying errors
|
-- for specifying errors
|
||||||
fn.parameters[#fn.parameters] = nil
|
fn.parameters[#fn.parameters] = nil
|
||||||
end
|
end
|
||||||
|
if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then
|
||||||
|
-- return value is allocated in an arena
|
||||||
|
fn.arena_return = true
|
||||||
|
fn.parameters[#fn.parameters] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
input:close()
|
input:close()
|
||||||
@@ -210,7 +216,7 @@ for i = 1, #functions do
|
|||||||
if fn.impl_name == nil and fn.remote then
|
if fn.impl_name == nil and fn.remote then
|
||||||
local args = {}
|
local args = {}
|
||||||
|
|
||||||
output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Error *error)')
|
output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Arena* arena, Error *error)')
|
||||||
output:write('\n{')
|
output:write('\n{')
|
||||||
output:write('\n#if MIN_LOG_LEVEL <= LOGLVL_DBG')
|
output:write('\n#if MIN_LOG_LEVEL <= LOGLVL_DBG')
|
||||||
output:write('\n logmsg(LOGLVL_DBG, "RPC: ", NULL, -1, true, "ch %" PRIu64 ": invoke '
|
output:write('\n logmsg(LOGLVL_DBG, "RPC: ", NULL, -1, true, "ch %" PRIu64 ": invoke '
|
||||||
@@ -319,6 +325,10 @@ for i = 1, #functions do
|
|||||||
output:write(call_args)
|
output:write(call_args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if fn.arena_return then
|
||||||
|
output:write(', arena')
|
||||||
|
end
|
||||||
|
|
||||||
if fn.can_fail then
|
if fn.can_fail then
|
||||||
-- if the function can fail, also pass a pointer to the local error object
|
-- if the function can fail, also pass a pointer to the local error object
|
||||||
if #args > 0 then
|
if #args > 0 then
|
||||||
@@ -355,11 +365,12 @@ local hashorder, hashfun = hashy.hashy_hash("msgpack_rpc_get_handler_for", vim.t
|
|||||||
return "method_handlers["..idx.."].name"
|
return "method_handlers["..idx.."].name"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
output:write("static const MsgpackRpcRequestHandler method_handlers[] = {\n")
|
output:write("const MsgpackRpcRequestHandler method_handlers[] = {\n")
|
||||||
for _, name in ipairs(hashorder) do
|
for n, name in ipairs(hashorder) do
|
||||||
local fn = remote_fns[name]
|
local fn = remote_fns[name]
|
||||||
|
fn.handler_id = n-1
|
||||||
output:write(' { .name = "'..name..'", .fn = handle_'.. (fn.impl_name or fn.name)..
|
output:write(' { .name = "'..name..'", .fn = handle_'.. (fn.impl_name or fn.name)..
|
||||||
', .fast = '..tostring(fn.fast)..'},\n')
|
', .fast = '..tostring(fn.fast)..', .arena_return = '..tostring(not not fn.arena_return)..'},\n')
|
||||||
end
|
end
|
||||||
output:write("};\n\n")
|
output:write("};\n\n")
|
||||||
output:write(hashfun)
|
output:write(hashfun)
|
||||||
@@ -400,6 +411,10 @@ output:write([[
|
|||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
#include "nvim/lua/converter.h"
|
#include "nvim/lua/converter.h"
|
||||||
#include "nvim/lua/executor.h"
|
#include "nvim/lua/executor.h"
|
||||||
|
#include "nvim/memory.h"
|
||||||
|
|
||||||
|
static ArenaMem lua_reuse_blk = { 0 };
|
||||||
|
|
||||||
]])
|
]])
|
||||||
include_headers(output, headers)
|
include_headers(output, headers)
|
||||||
output:write('\n')
|
output:write('\n')
|
||||||
@@ -477,6 +492,14 @@ local function process_function(fn)
|
|||||||
if fn.receives_channel_id then
|
if fn.receives_channel_id then
|
||||||
cparams = 'LUA_INTERNAL_CALL, ' .. cparams
|
cparams = 'LUA_INTERNAL_CALL, ' .. cparams
|
||||||
end
|
end
|
||||||
|
if fn.arena_return then
|
||||||
|
cparams = cparams .. '&arena, '
|
||||||
|
write_shifted_output(output, [[
|
||||||
|
Arena arena = ARENA_EMPTY;
|
||||||
|
arena_start(&arena, &lua_reuse_blk);
|
||||||
|
]])
|
||||||
|
end
|
||||||
|
|
||||||
if fn.can_fail then
|
if fn.can_fail then
|
||||||
cparams = cparams .. '&err'
|
cparams = cparams .. '&err'
|
||||||
else
|
else
|
||||||
@@ -511,15 +534,21 @@ local function process_function(fn)
|
|||||||
else
|
else
|
||||||
return_type = fn.return_type
|
return_type = fn.return_type
|
||||||
end
|
end
|
||||||
|
local free_retval
|
||||||
|
if fn.arena_return then
|
||||||
|
free_retval = "arena_mem_free(arena_finish(&arena), &lua_reuse_blk);"
|
||||||
|
else
|
||||||
|
free_retval = "api_free_"..return_type:lower().."(ret);"
|
||||||
|
end
|
||||||
write_shifted_output(output, string.format([[
|
write_shifted_output(output, string.format([[
|
||||||
const %s ret = %s(%s);
|
const %s ret = %s(%s);
|
||||||
nlua_push_%s(lstate, ret, true);
|
nlua_push_%s(lstate, ret, true);
|
||||||
api_free_%s(ret);
|
%s
|
||||||
%s
|
%s
|
||||||
%s
|
%s
|
||||||
return 1;
|
return 1;
|
||||||
]], fn.return_type, fn.name, cparams, return_type, return_type:lower(),
|
]], fn.return_type, fn.name, cparams, return_type,
|
||||||
free_at_exit_code, err_throw_code))
|
free_retval, free_at_exit_code, err_throw_code))
|
||||||
else
|
else
|
||||||
write_shifted_output(output, string.format([[
|
write_shifted_output(output, string.format([[
|
||||||
%s(%s);
|
%s(%s);
|
||||||
|
@@ -28,13 +28,20 @@ local hashy = require'generators.hashy'
|
|||||||
local hashpipe = io.open(funcsfname, 'wb')
|
local hashpipe = io.open(funcsfname, 'wb')
|
||||||
|
|
||||||
local funcs = require('eval').funcs
|
local funcs = require('eval').funcs
|
||||||
|
for _, func in pairs(funcs) do
|
||||||
|
if func.float_func then
|
||||||
|
func.func = "float_op_wrapper"
|
||||||
|
func.data = "{ .float_func = &"..func.float_func.." }"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local metadata = mpack.unpack(io.open(metadata_file, 'rb'):read("*all"))
|
local metadata = mpack.unpack(io.open(metadata_file, 'rb'):read("*all"))
|
||||||
for _,fun in ipairs(metadata) do
|
for _,fun in ipairs(metadata) do
|
||||||
if fun.eval then
|
if fun.eval then
|
||||||
funcs[fun.name] = {
|
funcs[fun.name] = {
|
||||||
args=#fun.parameters,
|
args=#fun.parameters,
|
||||||
func='api_wrapper',
|
func='api_wrapper',
|
||||||
data='&handle_'..fun.name,
|
data='{ .api_handler = &method_handlers['..fun.handler_id..'] }'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -60,12 +67,12 @@ for _, name in ipairs(neworder) do
|
|||||||
end
|
end
|
||||||
local base = def.base or "BASE_NONE"
|
local base = def.base or "BASE_NONE"
|
||||||
local func = def.func or ('f_' .. name)
|
local func = def.func or ('f_' .. name)
|
||||||
local data = def.data or "NULL"
|
local data = def.data or "{ .nullptr = NULL }"
|
||||||
local fast = def.fast and 'true' or 'false'
|
local fast = def.fast and 'true' or 'false'
|
||||||
hashpipe:write((' { "%s", %s, %s, %s, %s, &%s, (FunPtr)%s },\n')
|
hashpipe:write((' { "%s", %s, %s, %s, %s, &%s, %s },\n')
|
||||||
:format(name, args[1], args[2], base, fast, func, data))
|
:format(name, args[1], args[2], base, fast, func, data))
|
||||||
end
|
end
|
||||||
hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, NULL },\n')
|
hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .nullptr = NULL } },\n')
|
||||||
hashpipe:write("};\n\n")
|
hashpipe:write("};\n\n")
|
||||||
hashpipe:write(hashfun)
|
hashpipe:write(hashfun)
|
||||||
hashpipe:close()
|
hashpipe:close()
|
||||||
|
@@ -1810,13 +1810,13 @@ static void getchar_common(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "getchar()" function
|
/// "getchar()" function
|
||||||
void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getchar(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
getchar_common(argvars, rettv);
|
getchar_common(argvars, rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "getcharstr()" function
|
/// "getcharstr()" function
|
||||||
void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getcharstr(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
getchar_common(argvars, rettv);
|
getchar_common(argvars, rettv);
|
||||||
|
|
||||||
@@ -1836,7 +1836,7 @@ void f_getcharstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "getcharmod()" function
|
/// "getcharmod()" function
|
||||||
void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getcharmod(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = mod_mask;
|
rettv->vval.v_number = mod_mask;
|
||||||
}
|
}
|
||||||
|
@@ -2256,7 +2256,7 @@ static void set_completion(colnr_T startcol, list_T *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "complete()" function
|
/// "complete()" function
|
||||||
void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_complete(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if ((State & MODE_INSERT) == 0) {
|
if ((State & MODE_INSERT) == 0) {
|
||||||
emsg(_("E785: complete() can only be used in Insert mode"));
|
emsg(_("E785: complete() can only be used in Insert mode"));
|
||||||
@@ -2280,13 +2280,13 @@ void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "complete_add()" function
|
/// "complete_add()" function
|
||||||
void f_complete_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_complete_add(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0, false);
|
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "complete_check()" function
|
/// "complete_check()" function
|
||||||
void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_complete_check(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
int saved = RedrawingDisabled;
|
int saved = RedrawingDisabled;
|
||||||
|
|
||||||
@@ -2441,7 +2441,7 @@ static void get_complete_info(list_T *what_list, dict_T *retdict)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "complete_info()" function
|
/// "complete_info()" function
|
||||||
void f_complete_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_complete_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
tv_dict_alloc_ret(rettv);
|
tv_dict_alloc_ret(rettv);
|
||||||
|
|
||||||
|
@@ -1967,7 +1967,7 @@ char_u *check_map(char_u *keys, int mode, int exact, int ign_mod, int abbr, mapb
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "hasmapto()" function
|
/// "hasmapto()" function
|
||||||
void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_hasmapto(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *mode;
|
const char *mode;
|
||||||
const char *const name = tv_get_string(&argvars[0]);
|
const char *const name = tv_get_string(&argvars[0]);
|
||||||
@@ -2127,7 +2127,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "mapset()" function
|
/// "mapset()" function
|
||||||
void f_mapset(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_mapset(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char buf[NUMBUFLEN];
|
char buf[NUMBUFLEN];
|
||||||
const char *which = tv_get_string_buf_chk(&argvars[0], buf);
|
const char *which = tv_get_string_buf_chk(&argvars[0], buf);
|
||||||
@@ -2195,13 +2195,13 @@ void f_mapset(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "maparg()" function
|
/// "maparg()" function
|
||||||
void f_maparg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_maparg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
get_maparg(argvars, rettv, true);
|
get_maparg(argvars, rettv, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "mapcheck()" function
|
/// "mapcheck()" function
|
||||||
void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_mapcheck(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
get_maparg(argvars, rettv, false);
|
get_maparg(argvars, rettv, false);
|
||||||
}
|
}
|
||||||
|
@@ -859,7 +859,7 @@ static int matchadd_dict_arg(typval_T *tv, const char **conceal_char, win_T **wi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "clearmatches()" function
|
/// "clearmatches()" function
|
||||||
void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_clearmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
win_T *win = get_optional_window(argvars, 0);
|
win_T *win = get_optional_window(argvars, 0);
|
||||||
|
|
||||||
@@ -869,7 +869,7 @@ void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "getmatches()" function
|
/// "getmatches()" function
|
||||||
void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
matchitem_T *cur;
|
matchitem_T *cur;
|
||||||
int i;
|
int i;
|
||||||
@@ -924,7 +924,7 @@ void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "setmatches()" function
|
/// "setmatches()" function
|
||||||
void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setmatches(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
dict_T *d;
|
dict_T *d;
|
||||||
list_T *s = NULL;
|
list_T *s = NULL;
|
||||||
@@ -1027,7 +1027,7 @@ void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "matchadd()" function
|
/// "matchadd()" function
|
||||||
void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matchadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char grpbuf[NUMBUFLEN];
|
char grpbuf[NUMBUFLEN];
|
||||||
char patbuf[NUMBUFLEN];
|
char patbuf[NUMBUFLEN];
|
||||||
@@ -1069,7 +1069,7 @@ void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "matchaddpo()" function
|
/// "matchaddpo()" function
|
||||||
void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matchaddpos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = -1;
|
rettv->vval.v_number = -1;
|
||||||
|
|
||||||
@@ -1120,7 +1120,7 @@ void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "matcharg()" function
|
/// "matcharg()" function
|
||||||
void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matcharg(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const int id = (int)tv_get_number(&argvars[0]);
|
const int id = (int)tv_get_number(&argvars[0]);
|
||||||
|
|
||||||
@@ -1143,7 +1143,7 @@ void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "matchdelete()" function
|
/// "matchdelete()" function
|
||||||
void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matchdelete(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
win_T *win = get_optional_window(argvars, 1);
|
win_T *win = get_optional_window(argvars, 1);
|
||||||
if (win == NULL) {
|
if (win == NULL) {
|
||||||
|
@@ -2748,7 +2748,7 @@ static int tv_nr_compare(const void *a1, const void *a2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "setcellwidths()" function
|
/// "setcellwidths()" function
|
||||||
void f_setcellwidths(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setcellwidths(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) {
|
if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) {
|
||||||
emsg(_(e_listreq));
|
emsg(_(e_listreq));
|
||||||
@@ -2860,7 +2860,7 @@ void f_setcellwidths(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
redraw_all_later(NOT_VALID);
|
redraw_all_later(NOT_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void f_charclass(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_charclass(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
if (tv_check_for_string(&argvars[0]) == FAIL
|
if (tv_check_for_string(&argvars[0]) == FAIL
|
||||||
|| argvars[0].vval.v_string == NULL) {
|
|| argvars[0].vval.v_string == NULL) {
|
||||||
|
@@ -534,15 +534,18 @@ void arena_start(Arena *arena, ArenaMem *reuse_blk)
|
|||||||
if (reuse_blk && *reuse_blk) {
|
if (reuse_blk && *reuse_blk) {
|
||||||
arena->cur_blk = (char *)(*reuse_blk);
|
arena->cur_blk = (char *)(*reuse_blk);
|
||||||
*reuse_blk = NULL;
|
*reuse_blk = NULL;
|
||||||
|
arena->size = ARENA_BLOCK_SIZE;
|
||||||
|
arena->pos = 0;
|
||||||
|
|
||||||
|
// address is the same as as (struct consumed_blk *)arena->cur_blk
|
||||||
|
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
||||||
|
assert((char *)blk == (char *)arena->cur_blk);
|
||||||
|
blk->prev = NULL;
|
||||||
} else {
|
} else {
|
||||||
arena->cur_blk = xmalloc(ARENA_BLOCK_SIZE);
|
arena->cur_blk = NULL;
|
||||||
|
arena->size = 0;
|
||||||
|
arena->pos = 0;
|
||||||
}
|
}
|
||||||
arena->pos = 0;
|
|
||||||
arena->size = ARENA_BLOCK_SIZE;
|
|
||||||
// address is the same as as (struct consumed_blk *)arena->cur_blk
|
|
||||||
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
|
||||||
assert((char *)blk == (char *)arena->cur_blk);
|
|
||||||
blk->prev = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finnish the allocations in an arena.
|
/// Finnish the allocations in an arena.
|
||||||
@@ -558,17 +561,35 @@ ArenaMem arena_finish(Arena *arena)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void alloc_block(Arena *arena)
|
||||||
|
{
|
||||||
|
struct consumed_blk *prev_blk = (struct consumed_blk *)arena->cur_blk;
|
||||||
|
arena->cur_blk = xmalloc(ARENA_BLOCK_SIZE);
|
||||||
|
arena->pos = 0;
|
||||||
|
arena->size = ARENA_BLOCK_SIZE;
|
||||||
|
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
||||||
|
blk->prev = prev_blk;
|
||||||
|
arena_alloc_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param size if zero, will still return a non-null pointer, but not a unique one
|
||||||
void *arena_alloc(Arena *arena, size_t size, bool align)
|
void *arena_alloc(Arena *arena, size_t size, bool align)
|
||||||
{
|
{
|
||||||
if (align) {
|
if (align) {
|
||||||
arena->pos = (arena->pos + (ARENA_ALIGN - 1)) & ~(ARENA_ALIGN - 1);
|
arena->pos = (arena->pos + (ARENA_ALIGN - 1)) & ~(ARENA_ALIGN - 1);
|
||||||
}
|
}
|
||||||
if (arena->pos + size > arena->size) {
|
if (arena->pos + size > arena->size || !arena->cur_blk) {
|
||||||
if (size > (arena->size - sizeof(struct consumed_blk)) >> 1) {
|
if (size > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) >> 1) {
|
||||||
// if allocation is too big, allocate a large block with the requested
|
// if allocation is too big, allocate a large block with the requested
|
||||||
// size, but still with block pointer head. We do this even for
|
// size, but still with block pointer head. We do this even for
|
||||||
// arena->size / 2, as there likely is space left for the next
|
// arena->size / 2, as there likely is space left for the next
|
||||||
// small allocation in the current block.
|
// small allocation in the current block.
|
||||||
|
if (!arena->cur_blk) {
|
||||||
|
// to simplify free-list management, arena->cur_blk must
|
||||||
|
// always be a normal, ARENA_BLOCK_SIZE sized, block
|
||||||
|
alloc_block(arena);
|
||||||
|
}
|
||||||
|
arena_alloc_count++;
|
||||||
char *alloc = xmalloc(size + sizeof(struct consumed_blk));
|
char *alloc = xmalloc(size + sizeof(struct consumed_blk));
|
||||||
struct consumed_blk *cur_blk = (struct consumed_blk *)arena->cur_blk;
|
struct consumed_blk *cur_blk = (struct consumed_blk *)arena->cur_blk;
|
||||||
struct consumed_blk *fix_blk = (struct consumed_blk *)alloc;
|
struct consumed_blk *fix_blk = (struct consumed_blk *)alloc;
|
||||||
@@ -576,12 +597,7 @@ void *arena_alloc(Arena *arena, size_t size, bool align)
|
|||||||
cur_blk->prev = fix_blk;
|
cur_blk->prev = fix_blk;
|
||||||
return (alloc + sizeof(struct consumed_blk));
|
return (alloc + sizeof(struct consumed_blk));
|
||||||
} else {
|
} else {
|
||||||
struct consumed_blk *prev_blk = (struct consumed_blk *)arena->cur_blk;
|
alloc_block(arena);
|
||||||
arena->cur_blk = xmalloc(ARENA_BLOCK_SIZE);
|
|
||||||
arena->pos = 0;
|
|
||||||
arena->size = ARENA_BLOCK_SIZE;
|
|
||||||
struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
|
|
||||||
blk->prev = prev_blk;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
#include <stdint.h> // for uint8_t
|
#include <stdint.h> // for uint8_t
|
||||||
#include <time.h> // for time_t
|
#include <time.h> // for time_t
|
||||||
|
|
||||||
|
#include "nvim/macros.h"
|
||||||
|
|
||||||
/// `malloc()` function signature
|
/// `malloc()` function signature
|
||||||
typedef void *(*MemMalloc)(size_t);
|
typedef void *(*MemMalloc)(size_t);
|
||||||
|
|
||||||
@@ -37,6 +39,8 @@ extern MemRealloc mem_realloc;
|
|||||||
extern bool entered_free_all_mem;
|
extern bool entered_free_all_mem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EXTERN size_t arena_alloc_count INIT(=0);
|
||||||
|
|
||||||
typedef struct consumed_blk {
|
typedef struct consumed_blk {
|
||||||
struct consumed_blk *prev;
|
struct consumed_blk *prev;
|
||||||
} *ArenaMem;
|
} *ArenaMem;
|
||||||
|
@@ -1945,7 +1945,7 @@ static void menuitem_getinfo(const char *menu_name, const vimmenu_T *menu, int m
|
|||||||
|
|
||||||
/// "menu_info()" function
|
/// "menu_info()" function
|
||||||
/// Return information about a menu (including all the child menus)
|
/// Return information about a menu (including all the child menus)
|
||||||
void f_menu_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_menu_info(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
tv_dict_alloc_ret(rettv);
|
tv_dict_alloc_ret(rettv);
|
||||||
dict_T *const retdict = rettv->vval.v_dict;
|
dict_T *const retdict = rettv->vval.v_dict;
|
||||||
|
@@ -304,7 +304,8 @@ static void handle_request(Channel *channel, Unpacker *p, Array args)
|
|||||||
evdata->channel = channel;
|
evdata->channel = channel;
|
||||||
evdata->handler = p->handler;
|
evdata->handler = p->handler;
|
||||||
evdata->args = args;
|
evdata->args = args;
|
||||||
evdata->used_mem = arena_finish(&p->arena);
|
evdata->used_mem = p->arena;
|
||||||
|
p->arena = (Arena)ARENA_EMPTY;
|
||||||
evdata->request_id = p->request_id;
|
evdata->request_id = p->request_id;
|
||||||
channel_incref(channel);
|
channel_incref(channel);
|
||||||
if (p->handler.fast) {
|
if (p->handler.fast) {
|
||||||
@@ -344,7 +345,8 @@ static void request_event(void **argv)
|
|||||||
// channel was closed, abort any pending requests
|
// channel was closed, abort any pending requests
|
||||||
goto free_ret;
|
goto free_ret;
|
||||||
}
|
}
|
||||||
Object result = handler.fn(channel->id, e->args, &error);
|
|
||||||
|
Object result = handler.fn(channel->id, e->args, &e->used_mem, &error);
|
||||||
if (e->type == kMessageTypeRequest || ERROR_SET(&error)) {
|
if (e->type == kMessageTypeRequest || ERROR_SET(&error)) {
|
||||||
// Send the response.
|
// Send the response.
|
||||||
msgpack_packer response;
|
msgpack_packer response;
|
||||||
@@ -355,13 +357,14 @@ static void request_event(void **argv)
|
|||||||
&error,
|
&error,
|
||||||
result,
|
result,
|
||||||
&out_buffer));
|
&out_buffer));
|
||||||
} else {
|
}
|
||||||
|
if (!handler.arena_return) {
|
||||||
api_free_object(result);
|
api_free_object(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_ret:
|
free_ret:
|
||||||
// e->args is allocated in an arena
|
// e->args (and possibly result) are allocated in an arena
|
||||||
arena_mem_free(e->used_mem, &channel->rpc.unpacker->reuse_blk);
|
arena_mem_free(arena_finish(&e->used_mem), &channel->rpc.unpacker->reuse_blk);
|
||||||
channel_decref(channel);
|
channel_decref(channel);
|
||||||
xfree(e);
|
xfree(e);
|
||||||
api_clear_error(&error);
|
api_clear_error(&error);
|
||||||
@@ -624,7 +627,6 @@ static WBuffer *serialize_response(uint64_t channel_id, MessageType type, uint32
|
|||||||
1, // responses only go though 1 channel
|
1, // responses only go though 1 channel
|
||||||
xfree);
|
xfree);
|
||||||
msgpack_sbuffer_clear(sbuffer);
|
msgpack_sbuffer_clear(sbuffer);
|
||||||
api_free_object(arg);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ typedef struct {
|
|||||||
MsgpackRpcRequestHandler handler;
|
MsgpackRpcRequestHandler handler;
|
||||||
Array args;
|
Array args;
|
||||||
uint32_t request_id;
|
uint32_t request_id;
|
||||||
ArenaMem used_mem;
|
Arena used_mem;
|
||||||
} RequestEvent;
|
} RequestEvent;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -7169,14 +7169,14 @@ static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "getloclist()" function
|
/// "getloclist()" function
|
||||||
void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getloclist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
win_T *wp = find_win_by_nr_or_id(&argvars[0]);
|
win_T *wp = find_win_by_nr_or_id(&argvars[0]);
|
||||||
get_qf_loc_list(false, wp, &argvars[1], rettv);
|
get_qf_loc_list(false, wp, &argvars[1], rettv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "getqflist()" functions
|
/// "getqflist()" functions
|
||||||
void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_getqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
get_qf_loc_list(true, NULL, &argvars[0], rettv);
|
get_qf_loc_list(true, NULL, &argvars[0], rettv);
|
||||||
}
|
}
|
||||||
@@ -7263,7 +7263,7 @@ skip_args:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "setloclist()" function
|
/// "setloclist()" function
|
||||||
void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setloclist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = -1;
|
rettv->vval.v_number = -1;
|
||||||
|
|
||||||
@@ -7274,7 +7274,7 @@ void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "setqflist()" function
|
/// "setqflist()" function
|
||||||
void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_setqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
set_qf_ll_list(NULL, argvars, rettv);
|
set_qf_ll_list(NULL, argvars, rettv);
|
||||||
}
|
}
|
||||||
|
@@ -4637,7 +4637,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "searchcount()" function
|
// "searchcount()" function
|
||||||
void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
pos_T pos = curwin->w_cursor;
|
pos_T pos = curwin->w_cursor;
|
||||||
char_u *pattern = NULL;
|
char_u *pattern = NULL;
|
||||||
@@ -5287,13 +5287,13 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "matchfuzzy()" function
|
/// "matchfuzzy()" function
|
||||||
void f_matchfuzzy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matchfuzzy(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
do_fuzzymatch(argvars, rettv, false);
|
do_fuzzymatch(argvars, rettv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "matchfuzzypos()" function
|
/// "matchfuzzypos()" function
|
||||||
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_matchfuzzypos(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
do_fuzzymatch(argvars, rettv, true);
|
do_fuzzymatch(argvars, rettv, true);
|
||||||
}
|
}
|
||||||
|
@@ -1964,7 +1964,7 @@ static void sign_define_multiple(list_T *l, list_T *retlist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_define()" function
|
/// "sign_define()" function
|
||||||
void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_define(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
@@ -1995,7 +1995,7 @@ void f_sign_define(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_getdefined()" function
|
/// "sign_getdefined()" function
|
||||||
void f_sign_getdefined(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_getdefined(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
|
||||||
@@ -2009,7 +2009,7 @@ void f_sign_getdefined(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_getplaced()" function
|
/// "sign_getplaced()" function
|
||||||
void f_sign_getplaced(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_getplaced(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
buf_T *buf = NULL;
|
buf_T *buf = NULL;
|
||||||
dict_T *dict;
|
dict_T *dict;
|
||||||
@@ -2067,7 +2067,7 @@ void f_sign_getplaced(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_jump()" function
|
/// "sign_jump()" function
|
||||||
void f_sign_jump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_jump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
int sign_id;
|
int sign_id;
|
||||||
char *sign_group = NULL;
|
char *sign_group = NULL;
|
||||||
@@ -2225,7 +2225,7 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_place()" function
|
/// "sign_place()" function
|
||||||
void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_place(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
dict_T *dict = NULL;
|
dict_T *dict = NULL;
|
||||||
|
|
||||||
@@ -2243,7 +2243,7 @@ void f_sign_place(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_placelist()" function. Place multiple signs.
|
/// "sign_placelist()" function. Place multiple signs.
|
||||||
void f_sign_placelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_placelist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
int sign_id;
|
int sign_id;
|
||||||
|
|
||||||
@@ -2283,7 +2283,7 @@ static void sign_undefine_multiple(list_T *l, list_T *retlist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_undefine()" function
|
/// "sign_undefine()" function
|
||||||
void f_sign_undefine(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_undefine(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
@@ -2373,7 +2373,7 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_unplace()" function
|
/// "sign_unplace()" function
|
||||||
void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_unplace(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
dict_T *dict = NULL;
|
dict_T *dict = NULL;
|
||||||
|
|
||||||
@@ -2396,7 +2396,7 @@ void f_sign_unplace(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "sign_unplacelist()" function
|
/// "sign_unplacelist()" function
|
||||||
void f_sign_unplacelist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_sign_unplacelist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
@@ -326,19 +326,19 @@ static int assert_beeps(typval_T *argvars, bool no_beep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_beeps(cmd [, error])" function
|
/// "assert_beeps(cmd [, error])" function
|
||||||
void f_assert_beeps(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_beeps(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_beeps(argvars, false);
|
rettv->vval.v_number = assert_beeps(argvars, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_nobeep(cmd [, error])" function
|
/// "assert_nobeep(cmd [, error])" function
|
||||||
void f_assert_nobeep(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_nobeep(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_beeps(argvars, true);
|
rettv->vval.v_number = assert_beeps(argvars, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_equal(expected, actual[, msg])" function
|
/// "assert_equal(expected, actual[, msg])" function
|
||||||
void f_assert_equal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_equal(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
|
rettv->vval.v_number = assert_equal_common(argvars, ASSERT_EQUAL);
|
||||||
}
|
}
|
||||||
@@ -433,19 +433,19 @@ static int assert_equalfile(typval_T *argvars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_equalfile(fname-one, fname-two[, msg])" function
|
/// "assert_equalfile(fname-one, fname-two[, msg])" function
|
||||||
void f_assert_equalfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_equalfile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_equalfile(argvars);
|
rettv->vval.v_number = assert_equalfile(argvars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_notequal(expected, actual[, msg])" function
|
/// "assert_notequal(expected, actual[, msg])" function
|
||||||
void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_notequal(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
|
rettv->vval.v_number = assert_equal_common(argvars, ASSERT_NOTEQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_exception(string[, msg])" function
|
/// "assert_exception(string[, msg])" function
|
||||||
void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_exception(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
|
|
||||||
@@ -468,7 +468,7 @@ void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_fails(cmd [, error [, msg]])" function
|
/// "assert_fails(cmd [, error [, msg]])" function
|
||||||
void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_fails(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *const cmd = tv_get_string_chk(&argvars[0]);
|
const char *const cmd = tv_get_string_chk(&argvars[0]);
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
@@ -513,7 +513,7 @@ void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "assert_false(actual[, msg])" function
|
// "assert_false(actual[, msg])" function
|
||||||
void f_assert_false(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_false(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_bool(argvars, false);
|
rettv->vval.v_number = assert_bool(argvars, false);
|
||||||
}
|
}
|
||||||
@@ -574,25 +574,25 @@ static int assert_inrange(typval_T *argvars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_inrange(lower, upper[, msg])" function
|
/// "assert_inrange(lower, upper[, msg])" function
|
||||||
void f_assert_inrange(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_inrange(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_inrange(argvars);
|
rettv->vval.v_number = assert_inrange(argvars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_match(pattern, actual[, msg])" function
|
/// "assert_match(pattern, actual[, msg])" function
|
||||||
void f_assert_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_match(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
|
rettv->vval.v_number = assert_match_common(argvars, ASSERT_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_notmatch(pattern, actual[, msg])" function
|
/// "assert_notmatch(pattern, actual[, msg])" function
|
||||||
void f_assert_notmatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_notmatch(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
|
rettv->vval.v_number = assert_match_common(argvars, ASSERT_NOTMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_report(msg)" function
|
/// "assert_report(msg)" function
|
||||||
void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_report(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
|
|
||||||
@@ -604,13 +604,13 @@ void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "assert_true(actual[, msg])" function
|
/// "assert_true(actual[, msg])" function
|
||||||
void f_assert_true(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_assert_true(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
rettv->vval.v_number = assert_bool(argvars, true);
|
rettv->vval.v_number = assert_bool(argvars, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// "test_garbagecollect_now()" function
|
/// "test_garbagecollect_now()" function
|
||||||
void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
// This is dangerous, any Lists and Dicts used internally may be freed
|
// This is dangerous, any Lists and Dicts used internally may be freed
|
||||||
// while still in use.
|
// while still in use.
|
||||||
@@ -618,7 +618,7 @@ void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// "test_write_list_log()" function
|
/// "test_write_list_log()" function
|
||||||
void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, FunPtr fptr)
|
void f_test_write_list_log(typval_T *const argvars, typval_T *const rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
const char *const fname = tv_get_string_chk(&argvars[0]);
|
const char *const fname = tv_get_string_chk(&argvars[0]);
|
||||||
if (fname == NULL) {
|
if (fname == NULL) {
|
||||||
|
@@ -22,7 +22,17 @@ typedef int handle_T;
|
|||||||
// absent callback etc.
|
// absent callback etc.
|
||||||
typedef int LuaRef;
|
typedef int LuaRef;
|
||||||
|
|
||||||
typedef void (*FunPtr)(void);
|
/// Type used for VimL VAR_FLOAT values
|
||||||
|
typedef double float_T;
|
||||||
|
|
||||||
|
typedef struct MsgpackRpcRequestHandler MsgpackRpcRequestHandler;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
float_T (*float_func)(float_T);
|
||||||
|
const MsgpackRpcRequestHandler *api_handler;
|
||||||
|
void *nullptr;
|
||||||
|
} EvalFuncData;
|
||||||
|
|
||||||
|
|
||||||
typedef handle_T NS;
|
typedef handle_T NS;
|
||||||
|
|
||||||
|
@@ -55,7 +55,7 @@ UIClientHandler ui_client_get_redraw_handler(const char *name, size_t name_len,
|
|||||||
/// async 'redraw' events, which are expected when nvim acts as an ui client.
|
/// async 'redraw' events, which are expected when nvim acts as an ui client.
|
||||||
/// get handled in msgpack_rpc/unpacker.c and directly dispatched to handlers
|
/// get handled in msgpack_rpc/unpacker.c and directly dispatched to handlers
|
||||||
/// of specific ui events, like ui_client_event_grid_resize and so on.
|
/// of specific ui events, like ui_client_event_grid_resize and so on.
|
||||||
Object handle_ui_client_redraw(uint64_t channel_id, Array args, Error *error)
|
Object handle_ui_client_redraw(uint64_t channel_id, Array args, Arena *arena, Error *error)
|
||||||
{
|
{
|
||||||
api_set_error(error, kErrorTypeValidation, "'redraw' cannot be sent as a request");
|
api_set_error(error, kErrorTypeValidation, "'redraw' cannot be sent as a request");
|
||||||
return NIL;
|
return NIL;
|
||||||
|
Reference in New Issue
Block a user