aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt9
-rw-r--r--src/nvim/api/private/dispatch.h10
-rw-r--r--src/nvim/eval.c52
-rw-r--r--src/nvim/eval.lua2
4 files changed, 47 insertions, 26 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 71d48a5df1..8d0be4190c 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -14,6 +14,7 @@ set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendispatch.lua)
file(GLOB API_HEADERS api/*.h)
file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
+set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch.c)
@@ -192,8 +193,8 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
${EASTASIANWIDTH_FILE}
)
-add_custom_command(OUTPUT ${GENERATED_API_DISPATCH}
- COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${GENERATED_API_DISPATCH}
+add_custom_command(OUTPUT ${GENERATED_API_DISPATCH} ${API_METADATA}
+ COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${GENERATED_API_DISPATCH} ${API_METADATA}
DEPENDS
${API_HEADERS}
${MSGPACK_RPC_HEADERS}
@@ -220,10 +221,10 @@ add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
add_custom_command(OUTPUT ${GENERATED_FUNCS}
COMMAND ${LUA_PRG} ${FUNCS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_DIR}
+ ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_DIR} ${API_METADATA}
COMMAND $<TARGET_FILE:genhash>
${GENERATED_FUNCS_HASH_INPUT} ${GENERATED_FUNCS} functions functions VimLFuncDef "NOFUNC"
- DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} genhash
+ DEPENDS ${FUNCS_GENERATOR} ${EVAL_DEFS_FILE} ${API_METADATA} genhash
)
add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h
index 9047752026..d91456c306 100644
--- a/src/nvim/api/private/dispatch.h
+++ b/src/nvim/api/private/dispatch.h
@@ -3,13 +3,15 @@
#include "nvim/api/private/defs.h"
+typedef Object (*ApiDispatchWrapper)(uint64_t channel_id,
+ uint64_t request_id,
+ Array args,
+ Error *error);
+
/// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
/// functions of this type.
typedef struct {
- Object (*fn)(uint64_t channel_id,
- uint64_t request_id,
- Array args,
- Error *error);
+ ApiDispatchWrapper fn;
bool async; // function is always safe to run immediately instead of being
// put in a request queue for handling when nvim waits for input.
} MsgpackRpcRequestHandler;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index c5b5866f56..f731d2406a 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -445,13 +445,14 @@ typedef struct {
} timer_T;
/// Prototype of C function that implements VimL function
-typedef void (*VimLFunc)(typval_T *args, typval_T *rvar);
+typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, void *data);
/// Structure holding VimL function definition
typedef struct fst {
uint8_t min_argc; ///< Minimal number of arguments.
uint8_t max_argc; ///< Maximal number of arguments.
VimLFunc func; ///< Function implementation.
+ void *data; ///< Userdata for function implementation.
} VimLFuncDef;
KHASH_MAP_INIT_STR(functions, VimLFuncDef)
@@ -6981,7 +6982,7 @@ call_func (
}
} else {
// Find the function name in the table, call its implementation.
- VimLFuncDef *const fdef = find_internal_func((char *) fname);
+ VimLFuncDef *const fdef = find_internal_func((char *)fname);
if (fdef != NULL) {
if (argcount < fdef->min_argc) {
error = ERROR_TOOFEW;
@@ -6989,7 +6990,7 @@ call_func (
error = ERROR_TOOMANY;
} else {
argvars[argcount].v_type = VAR_UNKNOWN;
- fdef->func(argvars, rettv);
+ fdef->func(argvars, rettv, fdef->data);
error = ERROR_NONE;
}
}
@@ -7100,13 +7101,10 @@ static inline int get_float_arg(typval_T *argvars, float_T *f)
// Some versions of glibc on i386 have an optimization that makes it harder to
// call math functions indirectly from inside an inlined function, causing
// compile-time errors. Avoid `inline` in that case. #3072
-#ifndef ARCH_32
-inline
-#endif
-static void float_op_wrapper(typval_T *argvars, typval_T *rettv,
- float_T (*function)(float_T))
+static void float_op_wrapper(typval_T *argvars, typval_T *rettv, void *data)
{
float_T f;
+ float_T (*function)(float_T) = data;
rettv->v_type = VAR_FLOAT;
if (get_float_arg(argvars, &f) == OK) {
@@ -7116,6 +7114,34 @@ static void float_op_wrapper(typval_T *argvars, typval_T *rettv,
}
}
+static void api_wrapper(typval_T *argvars, typval_T *rettv, void *data)
+{
+ ApiDispatchWrapper fn = data;
+
+ Array args = ARRAY_DICT_INIT;
+
+ for (typval_T *tv = argvars; tv->v_type != VAR_UNKNOWN; tv++) {
+ ADD(args, vim_to_object(tv));
+ }
+
+ Error err = ERROR_INIT;
+ Object result = fn(-1, -1, args, &err);
+
+ if (err.set) {
+ vim_report_error(cstr_as_string(err.msg));
+ goto end;
+ }
+
+ if (!object_to_vim(result, rettv, &err)) {
+ EMSG2(_("Error converting the call result: %s"), err.msg);
+ }
+
+end:
+ // All arguments were freed already, but we still need to free the array
+ xfree(args.items);
+ api_free_object(result);
+}
+
/*
* "abs(expr)" function
*/
@@ -7516,14 +7542,6 @@ static void f_asin(typval_T *argvars, typval_T *rettv)
}
/*
- * "atan()" function
- */
-static void f_atan(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &atan);
-}
-
-/*
* "atan2()" function
*/
static void f_atan2(typval_T *argvars, typval_T *rettv)
@@ -20115,7 +20133,7 @@ void free_all_functions(void)
int translated_function_exists(char_u *name)
{
if (builtin_function(name, -1)) {
- return find_internal_func((char *) name) != NULL;
+ return find_internal_func((char *)name) != NULL;
}
return find_func(name) != NULL;
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 627925cd58..bbac27c7db 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -33,7 +33,7 @@ return {
assert_notequal={args={2, 3}},
assert_notmatch={args={2, 3}},
assert_true={args={1, 2}},
- atan={args=1},
+ atan={args=1, func="float_op_wrapper", data="atan"},
atan2={args=2},
browse={args=4},
browsedir={args=2},