changeset 22655:eabe2c1444ea v8.2.1876

patch 8.2.1876: Vim9: argument types are not checked at compile time Commit: https://github.com/vim/vim/commit/94738d8fab09c5563e1512f1695e047c715ad274 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Oct 21 14:25:07 2020 +0200 patch 8.2.1876: Vim9: argument types are not checked at compile time Problem: Vim9: argument types for builtin functions are not checked at compile time. Solution: Add an argument type checking mechanism. Implement type checks for one function.
author Bram Moolenaar <Bram@vim.org>
date Wed, 21 Oct 2020 14:30:04 +0200
parents ce95914cd5f2
children 0fcb95ef709d
files src/evalfunc.c src/proto/evalfunc.pro src/testdir/Make_all.mak src/testdir/test_vim9_builtin.vim src/testdir/test_vim9_func.vim src/version.c src/vim9compile.c
diffstat 7 files changed, 1644 insertions(+), 1051 deletions(-) [+]
line wrap: on
line diff
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -259,6 +259,39 @@ static void f_wordcount(typval_T *argvar
 static void f_xor(typval_T *argvars, typval_T *rettv);
 
 
+/*
+ * Functions that check the argument type of a builtin function.
+ * Each function returns FAIL and gives an error message if the type is wrong.
+ */
+
+// Context passed to an arg_ function.
+typedef struct {
+    int		arg_count;  // actual argument count
+    int		arg_idx;    // current argument index (first arg is zero)
+} argcontext_T;
+
+// A function to check one argument type.  The first argument is the type to
+// check.  If needed, other argument types can be obtained with the context.
+// E.g. if "arg_idx" is 1, then (type - 1) is the first argument type.
+typedef int (*argcheck_T)(type_T *, argcontext_T *);
+
+    static int
+arg_float_or_nr(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_FLOAT || type->tt_type == VAR_NUMBER)
+	return OK;
+    arg_type_mismatch(&t_number, type, context->arg_idx + 1);
+    return FAIL;
+}
+
+/*
+ * Lists of functions that check the argument types of a builtin function.
+ */
+argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
+
+/*
+ * Functions that return the return type of a builtin function.
+ */
     static type_T *
 ret_void(int argcount UNUSED, type_T **argtypes UNUSED)
 {
@@ -432,6 +465,7 @@ typedef struct
     char	f_min_argc;	// minimal number of arguments
     char	f_max_argc;	// maximal number of arguments
     char	f_argtype;	// for method: FEARG_ values
+    argcheck_T	*f_argcheck;	// list of functions to check argument types
     type_T	*(*f_retfunc)(int argcount, type_T **argtypes);
 				// return type function
     void	(*f_func)(typval_T *args, typval_T *rvar);
@@ -488,621 +522,1128 @@ typedef struct
 
 static funcentry_T global_functions[] =
 {
-    {"abs",		1, 1, FEARG_1,	  ret_any,	FLOAT_FUNC(f_abs)},
-    {"acos",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_acos)},
-    {"add",		2, 2, FEARG_1,	  ret_first_arg, f_add},
-    {"and",		2, 2, FEARG_1,	  ret_number,	f_and},
-    {"append",		2, 2, FEARG_2,	  ret_number,	f_append},
-    {"appendbufline",	3, 3, FEARG_3,	  ret_number,	f_appendbufline},
-    {"argc",		0, 1, 0,	  ret_number,	f_argc},
-    {"argidx",		0, 0, 0,	  ret_number,	f_argidx},
-    {"arglistid",	0, 2, 0,	  ret_number,	f_arglistid},
-    {"argv",		0, 2, 0,	  ret_argv,	f_argv},
-    {"asin",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_asin)},
-    {"assert_beeps",	1, 2, FEARG_1,	  ret_number,	f_assert_beeps},
-    {"assert_equal",	2, 3, FEARG_2,	  ret_number,	f_assert_equal},
-    {"assert_equalfile", 2, 3, FEARG_1,	  ret_number,	f_assert_equalfile},
-    {"assert_exception", 1, 2, 0,	  ret_number,	f_assert_exception},
-    {"assert_fails",	1, 5, FEARG_1,	  ret_number,	f_assert_fails},
-    {"assert_false",	1, 2, FEARG_1,	  ret_number,	f_assert_false},
-    {"assert_inrange",	3, 4, FEARG_3,	  ret_number,	f_assert_inrange},
-    {"assert_match",	2, 3, FEARG_2,	  ret_number,	f_assert_match},
-    {"assert_notequal",	2, 3, FEARG_2,	  ret_number,	f_assert_notequal},
-    {"assert_notmatch",	2, 3, FEARG_2,	  ret_number,	f_assert_notmatch},
-    {"assert_report",	1, 1, FEARG_1,	  ret_number,	f_assert_report},
-    {"assert_true",	1, 2, FEARG_1,	  ret_number,	f_assert_true},
-    {"atan",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_atan)},
-    {"atan2",		2, 2, FEARG_1,	  ret_float,	FLOAT_FUNC(f_atan2)},
-    {"balloon_gettext",	0, 0, 0,	  ret_string,
+    {"abs",		1, 1, FEARG_1,	    arg1_float_or_nr,
+			ret_any,	    FLOAT_FUNC(f_abs)},
+    {"acos",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_acos)},
+    {"add",		2, 2, FEARG_1,	    NULL,
+			ret_first_arg,	    f_add},
+    {"and",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_and},
+    {"append",		2, 2, FEARG_2,	    NULL,
+			ret_number,	    f_append},
+    {"appendbufline",	3, 3, FEARG_3,	    NULL,
+			ret_number,	    f_appendbufline},
+    {"argc",		0, 1, 0,	    NULL,
+			ret_number,	    f_argc},
+    {"argidx",		0, 0, 0,	    NULL,
+			ret_number,	    f_argidx},
+    {"arglistid",	0, 2, 0,	    NULL,
+			ret_number,	    f_arglistid},
+    {"argv",		0, 2, 0,	    NULL,
+			ret_argv,	    f_argv},
+    {"asin",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_asin)},
+    {"assert_beeps",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_assert_beeps},
+    {"assert_equal",	2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_assert_equal},
+    {"assert_equalfile", 2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_assert_equalfile},
+    {"assert_exception", 1, 2, 0,	    NULL,
+			ret_number,	    f_assert_exception},
+    {"assert_fails",	1, 5, FEARG_1,	    NULL,
+			ret_number,	    f_assert_fails},
+    {"assert_false",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_assert_false},
+    {"assert_inrange",	3, 4, FEARG_3,	    NULL,
+			ret_number,	    f_assert_inrange},
+    {"assert_match",	2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_assert_match},
+    {"assert_notequal",	2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_assert_notequal},
+    {"assert_notmatch",	2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_assert_notmatch},
+    {"assert_report",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_assert_report},
+    {"assert_true",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_assert_true},
+    {"atan",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_atan)},
+    {"atan2",		2, 2, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_atan2)},
+    {"balloon_gettext",	0, 0, 0,	    NULL,
+			ret_string,
 #ifdef FEAT_BEVAL
 	    f_balloon_gettext
 #else
 	    NULL
 #endif
 			},
-    {"balloon_show",	1, 1, FEARG_1,	  ret_void,
+    {"balloon_show",	1, 1, FEARG_1,	    NULL,
+			ret_void,
 #ifdef FEAT_BEVAL
 	    f_balloon_show
 #else
 	    NULL
 #endif
 			},
-    {"balloon_split",	1, 1, FEARG_1,	  ret_list_string,
+    {"balloon_split",	1, 1, FEARG_1,	    NULL,
+			ret_list_string,
 #if defined(FEAT_BEVAL_TERM)
 	    f_balloon_split
 #else
 	    NULL
 #endif
 			},
-    {"browse",		4, 4, 0,	  ret_string,	f_browse},
-    {"browsedir",	2, 2, 0,	  ret_string,	f_browsedir},
-    {"bufadd",		1, 1, FEARG_1,	  ret_number,	f_bufadd},
-    {"bufexists",	1, 1, FEARG_1,	  ret_number,	f_bufexists},
-    {"buffer_exists",	1, 1, FEARG_1,	  ret_number,	f_bufexists},	// obsolete
-    {"buffer_name",	0, 1, FEARG_1,	  ret_string,	f_bufname},	// obsolete
-    {"buffer_number",	0, 1, FEARG_1,	  ret_number,	f_bufnr},	// obsolete
-    {"buflisted",	1, 1, FEARG_1,	  ret_number,	f_buflisted},
-    {"bufload",		1, 1, FEARG_1,	  ret_void,	f_bufload},
-    {"bufloaded",	1, 1, FEARG_1,	  ret_number,	f_bufloaded},
-    {"bufname",		0, 1, FEARG_1,	  ret_string,	f_bufname},
-    {"bufnr",		0, 2, FEARG_1,	  ret_number,	f_bufnr},
-    {"bufwinid",	1, 1, FEARG_1,	  ret_number,	f_bufwinid},
-    {"bufwinnr",	1, 1, FEARG_1,	  ret_number,	f_bufwinnr},
-    {"byte2line",	1, 1, FEARG_1,	  ret_number,	f_byte2line},
-    {"byteidx",		2, 2, FEARG_1,	  ret_number,	f_byteidx},
-    {"byteidxcomp",	2, 2, FEARG_1,	  ret_number,	f_byteidxcomp},
-    {"call",		2, 3, FEARG_1,	  ret_any,	f_call},
-    {"ceil",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_ceil)},
-    {"ch_canread",	1, 1, FEARG_1,	  ret_number,	JOB_FUNC(f_ch_canread)},
-    {"ch_close",	1, 1, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_close)},
-    {"ch_close_in",	1, 1, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_close_in)},
-    {"ch_evalexpr",	2, 3, FEARG_1,	  ret_any,	JOB_FUNC(f_ch_evalexpr)},
-    {"ch_evalraw",	2, 3, FEARG_1,	  ret_any,	JOB_FUNC(f_ch_evalraw)},
-    {"ch_getbufnr",	2, 2, FEARG_1,	  ret_number,	JOB_FUNC(f_ch_getbufnr)},
-    {"ch_getjob",	1, 1, FEARG_1,	  ret_job,	JOB_FUNC(f_ch_getjob)},
-    {"ch_info",		1, 1, FEARG_1,	  ret_dict_any,	JOB_FUNC(f_ch_info)},
-    {"ch_log",		1, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_log)},
-    {"ch_logfile",	1, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_logfile)},
-    {"ch_open",		1, 2, FEARG_1,	  ret_channel,	JOB_FUNC(f_ch_open)},
-    {"ch_read",		1, 2, FEARG_1,	  ret_string,	JOB_FUNC(f_ch_read)},
-    {"ch_readblob",	1, 2, FEARG_1,	  ret_blob,	JOB_FUNC(f_ch_readblob)},
-    {"ch_readraw",	1, 2, FEARG_1,	  ret_string,	JOB_FUNC(f_ch_readraw)},
-    {"ch_sendexpr",	2, 3, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_sendexpr)},
-    {"ch_sendraw",	2, 3, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_sendraw)},
-    {"ch_setoptions",	2, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_ch_setoptions)},
-    {"ch_status",	1, 2, FEARG_1,	  ret_string,	JOB_FUNC(f_ch_status)},
-    {"changenr",	0, 0, 0,	  ret_number,	f_changenr},
-    {"char2nr",		1, 2, FEARG_1,	  ret_number,	f_char2nr},
-    {"charclass",	1, 1, FEARG_1,	  ret_number,	f_charclass},
-    {"chdir",		1, 1, FEARG_1,	  ret_string,	f_chdir},
-    {"cindent",		1, 1, FEARG_1,	  ret_number,	f_cindent},
-    {"clearmatches",	0, 1, FEARG_1,	  ret_void,	f_clearmatches},
-    {"col",		1, 1, FEARG_1,	  ret_number,	f_col},
-    {"complete",	2, 2, FEARG_2,	  ret_void,	f_complete},
-    {"complete_add",	1, 1, FEARG_1,	  ret_number,	f_complete_add},
-    {"complete_check",	0, 0, 0,	  ret_number,	f_complete_check},
-    {"complete_info",	0, 1, FEARG_1,	  ret_dict_any,	f_complete_info},
-    {"confirm",		1, 4, FEARG_1,	  ret_number,	f_confirm},
-    {"copy",		1, 1, FEARG_1,	  ret_first_arg, f_copy},
-    {"cos",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_cos)},
-    {"cosh",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_cosh)},
-    {"count",		2, 4, FEARG_1,	  ret_number,	f_count},
-    {"cscope_connection",0,3, 0,	  ret_number,	f_cscope_connection},
-    {"cursor",		1, 3, FEARG_1,	  ret_number,	f_cursor},
-    {"debugbreak",	1, 1, FEARG_1,	  ret_number,
+    {"browse",		4, 4, 0,	    NULL,
+			ret_string,	    f_browse},
+    {"browsedir",	2, 2, 0,	    NULL,
+			ret_string,	    f_browsedir},
+    {"bufadd",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufadd},
+    {"bufexists",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufexists},
+    {"buffer_exists",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufexists},	// obsolete
+    {"buffer_name",	0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_bufname},	// obsolete
+    {"buffer_number",	0, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufnr},	// obsolete
+    {"buflisted",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_buflisted},
+    {"bufload",		1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_bufload},
+    {"bufloaded",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufloaded},
+    {"bufname",		0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_bufname},
+    {"bufnr",		0, 2, FEARG_1,	    NULL,
+			ret_number,	    f_bufnr},
+    {"bufwinid",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufwinid},
+    {"bufwinnr",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_bufwinnr},
+    {"byte2line",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_byte2line},
+    {"byteidx",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_byteidx},
+    {"byteidxcomp",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_byteidxcomp},
+    {"call",		2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_call},
+    {"ceil",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_ceil)},
+    {"ch_canread",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    JOB_FUNC(f_ch_canread)},
+    {"ch_close",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_close)},
+    {"ch_close_in",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_close_in)},
+    {"ch_evalexpr",	2, 3, FEARG_1,	    NULL,
+			ret_any,	    JOB_FUNC(f_ch_evalexpr)},
+    {"ch_evalraw",	2, 3, FEARG_1,	    NULL,
+			ret_any,	    JOB_FUNC(f_ch_evalraw)},
+    {"ch_getbufnr",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    JOB_FUNC(f_ch_getbufnr)},
+    {"ch_getjob",	1, 1, FEARG_1,	    NULL,
+			ret_job,	    JOB_FUNC(f_ch_getjob)},
+    {"ch_info",		1, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    JOB_FUNC(f_ch_info)},
+    {"ch_log",		1, 2, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_log)},
+    {"ch_logfile",	1, 2, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_logfile)},
+    {"ch_open",		1, 2, FEARG_1,	    NULL,
+			ret_channel,	    JOB_FUNC(f_ch_open)},
+    {"ch_read",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    JOB_FUNC(f_ch_read)},
+    {"ch_readblob",	1, 2, FEARG_1,	    NULL,
+			ret_blob,	    JOB_FUNC(f_ch_readblob)},
+    {"ch_readraw",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    JOB_FUNC(f_ch_readraw)},
+    {"ch_sendexpr",	2, 3, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_sendexpr)},
+    {"ch_sendraw",	2, 3, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_sendraw)},
+    {"ch_setoptions",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_ch_setoptions)},
+    {"ch_status",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    JOB_FUNC(f_ch_status)},
+    {"changenr",	0, 0, 0,	    NULL,
+			ret_number,	    f_changenr},
+    {"char2nr",		1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_char2nr},
+    {"charclass",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_charclass},
+    {"chdir",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_chdir},
+    {"cindent",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_cindent},
+    {"clearmatches",	0, 1, FEARG_1,	    NULL,
+			ret_void,	    f_clearmatches},
+    {"col",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_col},
+    {"complete",	2, 2, FEARG_2,	    NULL,
+			ret_void,	    f_complete},
+    {"complete_add",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_complete_add},
+    {"complete_check",	0, 0, 0,	    NULL,
+			ret_number,	    f_complete_check},
+    {"complete_info",	0, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    f_complete_info},
+    {"confirm",		1, 4, FEARG_1,	    NULL,
+			ret_number,	    f_confirm},
+    {"copy",		1, 1, FEARG_1,	    NULL,
+			ret_first_arg,	    f_copy},
+    {"cos",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_cos)},
+    {"cosh",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_cosh)},
+    {"count",		2, 4, FEARG_1,	    NULL,
+			ret_number,	    f_count},
+    {"cscope_connection",0,3, 0,	    NULL,
+			ret_number,	    f_cscope_connection},
+    {"cursor",		1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_cursor},
+    {"debugbreak",	1, 1, FEARG_1,	    NULL,
+			ret_number,
 #ifdef MSWIN
 	    f_debugbreak
 #else
 	    NULL
 #endif
 			},
-    {"deepcopy",	1, 2, FEARG_1,	  ret_first_arg, f_deepcopy},
-    {"delete",		1, 2, FEARG_1,	  ret_number,	f_delete},
-    {"deletebufline",	2, 3, FEARG_1,	  ret_number,	f_deletebufline},
-    {"did_filetype",	0, 0, 0,	  ret_number,	f_did_filetype},
-    {"diff_filler",	1, 1, FEARG_1,	  ret_number,	f_diff_filler},
-    {"diff_hlID",	2, 2, FEARG_1,	  ret_number,	f_diff_hlID},
-    {"echoraw",		1, 1, FEARG_1,	  ret_number,	f_echoraw},
-    {"empty",		1, 1, FEARG_1,	  ret_number,	f_empty},
-    {"environ",		0, 0, 0,	  ret_dict_string, f_environ},
-    {"escape",		2, 2, FEARG_1,	  ret_string,	f_escape},
-    {"eval",		1, 1, FEARG_1,	  ret_any,	f_eval},
-    {"eventhandler",	0, 0, 0,	  ret_number,	f_eventhandler},
-    {"executable",	1, 1, FEARG_1,	  ret_number,	f_executable},
-    {"execute",		1, 2, FEARG_1,	  ret_string,	f_execute},
-    {"exepath",		1, 1, FEARG_1,	  ret_string,	f_exepath},
-    {"exists",		1, 1, FEARG_1,	  ret_number,	f_exists},
-    {"exp",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_exp)},
-    {"expand",		1, 3, FEARG_1,	  ret_any,	f_expand},
-    {"expandcmd",	1, 1, FEARG_1,	  ret_string,	f_expandcmd},
-    {"extend",		2, 3, FEARG_1,	  ret_first_arg, f_extend},
-    {"feedkeys",	1, 2, FEARG_1,	  ret_void,	f_feedkeys},
-    {"file_readable",	1, 1, FEARG_1,	  ret_number,	f_filereadable}, // obsolete
-    {"filereadable",	1, 1, FEARG_1,	  ret_number,	f_filereadable},
-    {"filewritable",	1, 1, FEARG_1,	  ret_number,	f_filewritable},
-    {"filter",		2, 2, FEARG_1,	  ret_first_arg, f_filter},
-    {"finddir",		1, 3, FEARG_1,	  ret_string,	f_finddir},
-    {"findfile",	1, 3, FEARG_1,	  ret_string,	f_findfile},
-    {"flatten",		1, 2, FEARG_1,	  ret_list_any,	f_flatten},
-    {"float2nr",	1, 1, FEARG_1,	  ret_number,	FLOAT_FUNC(f_float2nr)},
-    {"floor",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_floor)},
-    {"fmod",		2, 2, FEARG_1,	  ret_float,	FLOAT_FUNC(f_fmod)},
-    {"fnameescape",	1, 1, FEARG_1,	  ret_string,	f_fnameescape},
-    {"fnamemodify",	2, 2, FEARG_1,	  ret_string,	f_fnamemodify},
-    {"foldclosed",	1, 1, FEARG_1,	  ret_number,	f_foldclosed},
-    {"foldclosedend",	1, 1, FEARG_1,	  ret_number,	f_foldclosedend},
-    {"foldlevel",	1, 1, FEARG_1,	  ret_number,	f_foldlevel},
-    {"foldtext",	0, 0, 0,	  ret_string,	f_foldtext},
-    {"foldtextresult",	1, 1, FEARG_1,	  ret_string,	f_foldtextresult},
-    {"foreground",	0, 0, 0,	  ret_void,	f_foreground},
-    {"funcref",		1, 3, FEARG_1,	  ret_func_any, f_funcref},
-    {"function",	1, 3, FEARG_1,	  ret_f_function, f_function},
-    {"garbagecollect",	0, 1, 0,	  ret_void,	f_garbagecollect},
-    {"get",		2, 3, FEARG_1,	  ret_any,	f_get},
-    {"getbufinfo",	0, 1, FEARG_1,	  ret_list_dict_any, f_getbufinfo},
-    {"getbufline",	2, 3, FEARG_1,	  ret_list_string, f_getbufline},
-    {"getbufvar",	2, 3, FEARG_1,	  ret_any,	f_getbufvar},
-    {"getchangelist",	0, 1, FEARG_1,	  ret_list_any,	f_getchangelist},
-    {"getchar",		0, 1, 0,	  ret_number,	f_getchar},
-    {"getcharmod",	0, 0, 0,	  ret_number,	f_getcharmod},
-    {"getcharsearch",	0, 0, 0,	  ret_dict_any,	f_getcharsearch},
-    {"getcmdline",	0, 0, 0,	  ret_string,	f_getcmdline},
-    {"getcmdpos",	0, 0, 0,	  ret_number,	f_getcmdpos},
-    {"getcmdtype",	0, 0, 0,	  ret_string,	f_getcmdtype},
-    {"getcmdwintype",	0, 0, 0,	  ret_string,	f_getcmdwintype},
-    {"getcompletion",	2, 3, FEARG_1,	  ret_list_string, f_getcompletion},
-    {"getcurpos",	0, 1, FEARG_1,	  ret_list_number, f_getcurpos},
-    {"getcwd",		0, 2, FEARG_1,	  ret_string,	f_getcwd},
-    {"getenv",		1, 1, FEARG_1,	  ret_string,	f_getenv},
-    {"getfontname",	0, 1, 0,	  ret_string,	f_getfontname},
-    {"getfperm",	1, 1, FEARG_1,	  ret_string,	f_getfperm},
-    {"getfsize",	1, 1, FEARG_1,	  ret_number,	f_getfsize},
-    {"getftime",	1, 1, FEARG_1,	  ret_number,	f_getftime},
-    {"getftype",	1, 1, FEARG_1,	  ret_string,	f_getftype},
-    {"getimstatus",	0, 0, 0,	  ret_number,	f_getimstatus},
-    {"getjumplist",	0, 2, FEARG_1,	  ret_list_any,	f_getjumplist},
-    {"getline",		1, 2, FEARG_1,	  ret_f_getline, f_getline},
-    {"getloclist",	1, 2, 0,	  ret_list_or_dict_1, f_getloclist},
-    {"getmarklist",	0, 1, FEARG_1,	  ret_list_dict_any,  f_getmarklist},
-    {"getmatches",	0, 1, 0,	  ret_list_dict_any, f_getmatches},
-    {"getmousepos",	0, 0, 0,	  ret_dict_number, f_getmousepos},
-    {"getpid",		0, 0, 0,	  ret_number,	f_getpid},
-    {"getpos",		1, 1, FEARG_1,	  ret_list_number,	f_getpos},
-    {"getqflist",	0, 1, 0,	  ret_list_or_dict_0,	f_getqflist},
-    {"getreg",		0, 3, FEARG_1,	  ret_getreg,	f_getreg},
-    {"getreginfo",	0, 1, FEARG_1,	  ret_dict_any,	f_getreginfo},
-    {"getregtype",	0, 1, FEARG_1,	  ret_string,	f_getregtype},
-    {"gettabinfo",	0, 1, FEARG_1,	  ret_list_dict_any,	f_gettabinfo},
-    {"gettabvar",	2, 3, FEARG_1,	  ret_any,	f_gettabvar},
-    {"gettabwinvar",	3, 4, FEARG_1,	  ret_any,	f_gettabwinvar},
-    {"gettagstack",	0, 1, FEARG_1,	  ret_dict_any,	f_gettagstack},
-    {"gettext",		1, 1, FEARG_1,	  ret_string,	f_gettext},
-    {"getwininfo",	0, 1, FEARG_1,	  ret_list_dict_any,	f_getwininfo},
-    {"getwinpos",	0, 1, FEARG_1,	  ret_list_number,	f_getwinpos},
-    {"getwinposx",	0, 0, 0,	  ret_number,	f_getwinposx},
-    {"getwinposy",	0, 0, 0,	  ret_number,	f_getwinposy},
-    {"getwinvar",	2, 3, FEARG_1,	  ret_any,	f_getwinvar},
-    {"glob",		1, 4, FEARG_1,	  ret_any,	f_glob},
-    {"glob2regpat",	1, 1, FEARG_1,	  ret_string,	f_glob2regpat},
-    {"globpath",	2, 5, FEARG_2,	  ret_any,	f_globpath},
-    {"has",		1, 2, 0,	  ret_number,	f_has},
-    {"has_key",		2, 2, FEARG_1,	  ret_number,	f_has_key},
-    {"haslocaldir",	0, 2, FEARG_1,	  ret_number,	f_haslocaldir},
-    {"hasmapto",	1, 3, FEARG_1,	  ret_number,	f_hasmapto},
-    {"highlightID",	1, 1, FEARG_1,	  ret_number,	f_hlID},	// obsolete
-    {"highlight_exists",1, 1, FEARG_1,	  ret_number,	f_hlexists},	// obsolete
-    {"histadd",		2, 2, FEARG_2,	  ret_number,	f_histadd},
-    {"histdel",		1, 2, FEARG_1,	  ret_number,	f_histdel},
-    {"histget",		1, 2, FEARG_1,	  ret_string,	f_histget},
-    {"histnr",		1, 1, FEARG_1,	  ret_number,	f_histnr},
-    {"hlID",		1, 1, FEARG_1,	  ret_number,	f_hlID},
-    {"hlexists",	1, 1, FEARG_1,	  ret_number,	f_hlexists},
-    {"hostname",	0, 0, 0,	  ret_string,	f_hostname},
-    {"iconv",		3, 3, FEARG_1,	  ret_string,	f_iconv},
-    {"indent",		1, 1, FEARG_1,	  ret_number,	f_indent},
-    {"index",		2, 4, FEARG_1,	  ret_number,	f_index},
-    {"input",		1, 3, FEARG_1,	  ret_string,	f_input},
-    {"inputdialog",	1, 3, FEARG_1,	  ret_string,	f_inputdialog},
-    {"inputlist",	1, 1, FEARG_1,	  ret_number,	f_inputlist},
-    {"inputrestore",	0, 0, 0,	  ret_number,	f_inputrestore},
-    {"inputsave",	0, 0, 0,	  ret_number,	f_inputsave},
-    {"inputsecret",	1, 2, FEARG_1,	  ret_string,	f_inputsecret},
-    {"insert",		2, 3, FEARG_1,	  ret_first_arg, f_insert},
-    {"interrupt",	0, 0, 0,	  ret_void,	f_interrupt},
-    {"invert",		1, 1, FEARG_1,	  ret_number,	f_invert},
-    {"isdirectory",	1, 1, FEARG_1,	  ret_number,	f_isdirectory},
-    {"isinf",		1, 1, FEARG_1,	  ret_number,	MATH_FUNC(f_isinf)},
-    {"islocked",	1, 1, FEARG_1,	  ret_number,	f_islocked},
-    {"isnan",		1, 1, FEARG_1,	  ret_number,	MATH_FUNC(f_isnan)},
-    {"items",		1, 1, FEARG_1,	  ret_list_any,	f_items},
-    {"job_getchannel",	1, 1, FEARG_1,	  ret_channel,	JOB_FUNC(f_job_getchannel)},
-    {"job_info",	0, 1, FEARG_1,	  ret_dict_any,	JOB_FUNC(f_job_info)},
-    {"job_setoptions",	2, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_job_setoptions)},
-    {"job_start",	1, 2, FEARG_1,	  ret_job,	JOB_FUNC(f_job_start)},
-    {"job_status",	1, 1, FEARG_1,	  ret_string,	JOB_FUNC(f_job_status)},
-    {"job_stop",	1, 2, FEARG_1,	  ret_number,	JOB_FUNC(f_job_stop)},
-    {"join",		1, 2, FEARG_1,	  ret_string,	f_join},
-    {"js_decode",	1, 1, FEARG_1,	  ret_any,	f_js_decode},
-    {"js_encode",	1, 1, FEARG_1,	  ret_string,	f_js_encode},
-    {"json_decode",	1, 1, FEARG_1,	  ret_any,	f_json_decode},
-    {"json_encode",	1, 1, FEARG_1,	  ret_string,	f_json_encode},
-    {"keys",		1, 1, FEARG_1,	  ret_list_string, f_keys},
-    {"last_buffer_nr",	0, 0, 0,	  ret_number,	f_last_buffer_nr}, // obsolete
-    {"len",		1, 1, FEARG_1,	  ret_number,	f_len},
-    {"libcall",		3, 3, FEARG_3,	  ret_string,	f_libcall},
-    {"libcallnr",	3, 3, FEARG_3,	  ret_number,	f_libcallnr},
-    {"line",		1, 2, FEARG_1,	  ret_number,	f_line},
-    {"line2byte",	1, 1, FEARG_1,	  ret_number,	f_line2byte},
-    {"lispindent",	1, 1, FEARG_1,	  ret_number,	f_lispindent},
-    {"list2str",	1, 2, FEARG_1,	  ret_string,	f_list2str},
-    {"listener_add",	1, 2, FEARG_2,	  ret_number,	f_listener_add},
-    {"listener_flush",	0, 1, FEARG_1,	  ret_void,	f_listener_flush},
-    {"listener_remove",	1, 1, FEARG_1,	  ret_number,	f_listener_remove},
-    {"localtime",	0, 0, 0,	  ret_number,	f_localtime},
-    {"log",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_log)},
-    {"log10",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_log10)},
-    {"luaeval",		1, 2, FEARG_1,	  ret_any,
+    {"deepcopy",	1, 2, FEARG_1,	    NULL,
+			ret_first_arg,	    f_deepcopy},
+    {"delete",		1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_delete},
+    {"deletebufline",	2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_deletebufline},
+    {"did_filetype",	0, 0, 0,	    NULL,
+			ret_number,	    f_did_filetype},
+    {"diff_filler",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_diff_filler},
+    {"diff_hlID",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_diff_hlID},
+    {"echoraw",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_echoraw},
+    {"empty",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_empty},
+    {"environ",		0, 0, 0,	    NULL,
+			ret_dict_string,    f_environ},
+    {"escape",		2, 2, FEARG_1,	    NULL,
+			ret_string,	    f_escape},
+    {"eval",		1, 1, FEARG_1,	    NULL,
+			ret_any,	    f_eval},
+    {"eventhandler",	0, 0, 0,	    NULL,
+			ret_number,	    f_eventhandler},
+    {"executable",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_executable},
+    {"execute",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_execute},
+    {"exepath",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_exepath},
+    {"exists",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_exists},
+    {"exp",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_exp)},
+    {"expand",		1, 3, FEARG_1,	    NULL,
+			ret_any,	    f_expand},
+    {"expandcmd",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_expandcmd},
+    {"extend",		2, 3, FEARG_1,	    NULL,
+			ret_first_arg,	    f_extend},
+    {"feedkeys",	1, 2, FEARG_1,	    NULL,
+			ret_void,	    f_feedkeys},
+    {"file_readable",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_filereadable}, // obsolete
+    {"filereadable",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_filereadable},
+    {"filewritable",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_filewritable},
+    {"filter",		2, 2, FEARG_1,	    NULL,
+			ret_first_arg,	    f_filter},
+    {"finddir",		1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_finddir},
+    {"findfile",	1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_findfile},
+    {"flatten",		1, 2, FEARG_1,	    NULL,
+			ret_list_any,	    f_flatten},
+    {"float2nr",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    FLOAT_FUNC(f_float2nr)},
+    {"floor",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_floor)},
+    {"fmod",		2, 2, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_fmod)},
+    {"fnameescape",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_fnameescape},
+    {"fnamemodify",	2, 2, FEARG_1,	    NULL,
+			ret_string,	    f_fnamemodify},
+    {"foldclosed",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_foldclosed},
+    {"foldclosedend",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_foldclosedend},
+    {"foldlevel",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_foldlevel},
+    {"foldtext",	0, 0, 0,	    NULL,
+			ret_string,	    f_foldtext},
+    {"foldtextresult",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_foldtextresult},
+    {"foreground",	0, 0, 0,	    NULL,
+			ret_void,	    f_foreground},
+    {"funcref",		1, 3, FEARG_1,	    NULL,
+			ret_func_any,	    f_funcref},
+    {"function",	1, 3, FEARG_1,	    NULL,
+			ret_f_function,	    f_function},
+    {"garbagecollect",	0, 1, 0,	    NULL,
+			ret_void,	    f_garbagecollect},
+    {"get",		2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_get},
+    {"getbufinfo",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_getbufinfo},
+    {"getbufline",	2, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_getbufline},
+    {"getbufvar",	2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_getbufvar},
+    {"getchangelist",	0, 1, FEARG_1,	    NULL,
+			ret_list_any,	    f_getchangelist},
+    {"getchar",		0, 1, 0,	    NULL,
+			ret_number,	    f_getchar},
+    {"getcharmod",	0, 0, 0,	    NULL,
+			ret_number,	    f_getcharmod},
+    {"getcharsearch",	0, 0, 0,	    NULL,
+			ret_dict_any,	    f_getcharsearch},
+    {"getcmdline",	0, 0, 0,	    NULL,
+			ret_string,	    f_getcmdline},
+    {"getcmdpos",	0, 0, 0,	    NULL,
+			ret_number,	    f_getcmdpos},
+    {"getcmdtype",	0, 0, 0,	    NULL,
+			ret_string,	    f_getcmdtype},
+    {"getcmdwintype",	0, 0, 0,	    NULL,
+			ret_string,	    f_getcmdwintype},
+    {"getcompletion",	2, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_getcompletion},
+    {"getcurpos",	0, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_getcurpos},
+    {"getcwd",		0, 2, FEARG_1,	    NULL,
+			ret_string,	    f_getcwd},
+    {"getenv",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_getenv},
+    {"getfontname",	0, 1, 0,	    NULL,
+			ret_string,	    f_getfontname},
+    {"getfperm",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_getfperm},
+    {"getfsize",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_getfsize},
+    {"getftime",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_getftime},
+    {"getftype",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_getftype},
+    {"getimstatus",	0, 0, 0,	    NULL,
+			ret_number,	    f_getimstatus},
+    {"getjumplist",	0, 2, FEARG_1,	    NULL,
+			ret_list_any,	    f_getjumplist},
+    {"getline",		1, 2, FEARG_1,	    NULL,
+			ret_f_getline,	    f_getline},
+    {"getloclist",	1, 2, 0,	    NULL,
+			ret_list_or_dict_1, f_getloclist},
+    {"getmarklist",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_getmarklist},
+    {"getmatches",	0, 1, 0,	    NULL,
+			ret_list_dict_any,  f_getmatches},
+    {"getmousepos",	0, 0, 0,	    NULL,
+			ret_dict_number,    f_getmousepos},
+    {"getpid",		0, 0, 0,	    NULL,
+			ret_number,	    f_getpid},
+    {"getpos",		1, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_getpos},
+    {"getqflist",	0, 1, 0,	    NULL,
+			ret_list_or_dict_0, f_getqflist},
+    {"getreg",		0, 3, FEARG_1,	    NULL,
+			ret_getreg,	    f_getreg},
+    {"getreginfo",	0, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    f_getreginfo},
+    {"getregtype",	0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_getregtype},
+    {"gettabinfo",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_gettabinfo},
+    {"gettabvar",	2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_gettabvar},
+    {"gettabwinvar",	3, 4, FEARG_1,	    NULL,
+			ret_any,	    f_gettabwinvar},
+    {"gettagstack",	0, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    f_gettagstack},
+    {"gettext",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_gettext},
+    {"getwininfo",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_getwininfo},
+    {"getwinpos",	0, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_getwinpos},
+    {"getwinposx",	0, 0, 0,	    NULL,
+			ret_number,	    f_getwinposx},
+    {"getwinposy",	0, 0, 0,	    NULL,
+			ret_number,	    f_getwinposy},
+    {"getwinvar",	2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_getwinvar},
+    {"glob",		1, 4, FEARG_1,	    NULL,
+			ret_any,	    f_glob},
+    {"glob2regpat",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_glob2regpat},
+    {"globpath",	2, 5, FEARG_2,	    NULL,
+			ret_any,	    f_globpath},
+    {"has",		1, 2, 0,	    NULL,
+			ret_number,	    f_has},
+    {"has_key",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_has_key},
+    {"haslocaldir",	0, 2, FEARG_1,	    NULL,
+			ret_number,	    f_haslocaldir},
+    {"hasmapto",	1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_hasmapto},
+    {"highlightID",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_hlID},	// obsolete
+    {"highlight_exists",1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_hlexists},	// obsolete
+    {"histadd",		2, 2, FEARG_2,	    NULL,
+			ret_number,	    f_histadd},
+    {"histdel",		1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_histdel},
+    {"histget",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_histget},
+    {"histnr",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_histnr},
+    {"hlID",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_hlID},
+    {"hlexists",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_hlexists},
+    {"hostname",	0, 0, 0,	    NULL,
+			ret_string,	    f_hostname},
+    {"iconv",		3, 3, FEARG_1,	    NULL,
+			ret_string,	    f_iconv},
+    {"indent",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_indent},
+    {"index",		2, 4, FEARG_1,	    NULL,
+			ret_number,	    f_index},
+    {"input",		1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_input},
+    {"inputdialog",	1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_inputdialog},
+    {"inputlist",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_inputlist},
+    {"inputrestore",	0, 0, 0,	    NULL,
+			ret_number,	    f_inputrestore},
+    {"inputsave",	0, 0, 0,	    NULL,
+			ret_number,	    f_inputsave},
+    {"inputsecret",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_inputsecret},
+    {"insert",		2, 3, FEARG_1,	    NULL,
+			ret_first_arg,	    f_insert},
+    {"interrupt",	0, 0, 0,	    NULL,
+			ret_void,	    f_interrupt},
+    {"invert",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_invert},
+    {"isdirectory",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_isdirectory},
+    {"isinf",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    MATH_FUNC(f_isinf)},
+    {"islocked",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_islocked},
+    {"isnan",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    MATH_FUNC(f_isnan)},
+    {"items",		1, 1, FEARG_1,	    NULL,
+			ret_list_any,	    f_items},
+    {"job_getchannel",	1, 1, FEARG_1,	    NULL,
+			ret_channel,	    JOB_FUNC(f_job_getchannel)},
+    {"job_info",	0, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    JOB_FUNC(f_job_info)},
+    {"job_setoptions",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_job_setoptions)},
+    {"job_start",	1, 2, FEARG_1,	    NULL,
+			ret_job,	    JOB_FUNC(f_job_start)},
+    {"job_status",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    JOB_FUNC(f_job_status)},
+    {"job_stop",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    JOB_FUNC(f_job_stop)},
+    {"join",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_join},
+    {"js_decode",	1, 1, FEARG_1,	    NULL,
+			ret_any,	    f_js_decode},
+    {"js_encode",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_js_encode},
+    {"json_decode",	1, 1, FEARG_1,	    NULL,
+			ret_any,	    f_json_decode},
+    {"json_encode",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_json_encode},
+    {"keys",		1, 1, FEARG_1,	    NULL,
+			ret_list_string,    f_keys},
+    {"last_buffer_nr",	0, 0, 0,	    NULL,
+			ret_number,	    f_last_buffer_nr}, // obsolete
+    {"len",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_len},
+    {"libcall",		3, 3, FEARG_3,	    NULL,
+			ret_string,	    f_libcall},
+    {"libcallnr",	3, 3, FEARG_3,	    NULL,
+			ret_number,	    f_libcallnr},
+    {"line",		1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_line},
+    {"line2byte",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_line2byte},
+    {"lispindent",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_lispindent},
+    {"list2str",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_list2str},
+    {"listener_add",	1, 2, FEARG_2,	    NULL,
+			ret_number,	    f_listener_add},
+    {"listener_flush",	0, 1, FEARG_1,	    NULL,
+			ret_void,	    f_listener_flush},
+    {"listener_remove",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_listener_remove},
+    {"localtime",	0, 0, 0,	    NULL,
+			ret_number,	    f_localtime},
+    {"log",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_log)},
+    {"log10",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_log10)},
+    {"luaeval",		1, 2, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_LUA
 		f_luaeval
 #else
 		NULL
 #endif
 			},
-    {"map",		2, 2, FEARG_1,	  ret_any,	f_map},
-    {"maparg",		1, 4, FEARG_1,	  ret_maparg,	f_maparg},
-    {"mapcheck",	1, 3, FEARG_1,	  ret_string,	f_mapcheck},
-    {"mapset",		3, 3, FEARG_1,	  ret_void,	f_mapset},
-    {"match",		2, 4, FEARG_1,	  ret_any,	f_match},
-    {"matchadd",	2, 5, FEARG_1,	  ret_number,	f_matchadd},
-    {"matchaddpos",	2, 5, FEARG_1,	  ret_number,	f_matchaddpos},
-    {"matcharg",	1, 1, FEARG_1,	  ret_list_string, f_matcharg},
-    {"matchdelete",	1, 2, FEARG_1,	  ret_number,	f_matchdelete},
-    {"matchend",	2, 4, FEARG_1,	  ret_number,	f_matchend},
-    {"matchfuzzy",	2, 3, FEARG_1,	  ret_list_string,	f_matchfuzzy},
-    {"matchfuzzypos",	2, 3, FEARG_1,	  ret_list_any,	f_matchfuzzypos},
-    {"matchlist",	2, 4, FEARG_1,	  ret_list_string, f_matchlist},
-    {"matchstr",	2, 4, FEARG_1,	  ret_string,	f_matchstr},
-    {"matchstrpos",	2, 4, FEARG_1,	  ret_list_any,	f_matchstrpos},
-    {"max",		1, 1, FEARG_1,	  ret_any,	f_max},
-    {"menu_info",	1, 2, FEARG_1,	  ret_dict_any,
+    {"map",		2, 2, FEARG_1,	    NULL,
+			ret_any,	    f_map},
+    {"maparg",		1, 4, FEARG_1,	    NULL,
+			ret_maparg,	    f_maparg},
+    {"mapcheck",	1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_mapcheck},
+    {"mapset",		3, 3, FEARG_1,	    NULL,
+			ret_void,	    f_mapset},
+    {"match",		2, 4, FEARG_1,	    NULL,
+			ret_any,	    f_match},
+    {"matchadd",	2, 5, FEARG_1,	    NULL,
+			ret_number,	    f_matchadd},
+    {"matchaddpos",	2, 5, FEARG_1,	    NULL,
+			ret_number,	    f_matchaddpos},
+    {"matcharg",	1, 1, FEARG_1,	    NULL,
+			ret_list_string,    f_matcharg},
+    {"matchdelete",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_matchdelete},
+    {"matchend",	2, 4, FEARG_1,	    NULL,
+			ret_number,	    f_matchend},
+    {"matchfuzzy",	2, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_matchfuzzy},
+    {"matchfuzzypos",	2, 3, FEARG_1,	    NULL,
+			ret_list_any,	    f_matchfuzzypos},
+    {"matchlist",	2, 4, FEARG_1,	    NULL,
+			ret_list_string,    f_matchlist},
+    {"matchstr",	2, 4, FEARG_1,	    NULL,
+			ret_string,	    f_matchstr},
+    {"matchstrpos",	2, 4, FEARG_1,	    NULL,
+			ret_list_any,	    f_matchstrpos},
+    {"max",		1, 1, FEARG_1,	    NULL,
+			ret_any,	    f_max},
+    {"menu_info",	1, 2, FEARG_1,	    NULL,
+			ret_dict_any,
 #ifdef FEAT_MENU
 	    f_menu_info
 #else
 	    NULL
 #endif
 			},
-    {"min",		1, 1, FEARG_1,	  ret_any,	f_min},
-    {"mkdir",		1, 3, FEARG_1,	  ret_number,	f_mkdir},
-    {"mode",		0, 1, FEARG_1,	  ret_string,	f_mode},
-    {"mzeval",		1, 1, FEARG_1,	  ret_any,
+    {"min",		1, 1, FEARG_1,	    NULL,
+			ret_any,	    f_min},
+    {"mkdir",		1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_mkdir},
+    {"mode",		0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_mode},
+    {"mzeval",		1, 1, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_MZSCHEME
 	    f_mzeval
 #else
 	    NULL
 #endif
 			},
-    {"nextnonblank",	1, 1, FEARG_1,	  ret_number,	f_nextnonblank},
-    {"nr2char",		1, 2, FEARG_1,	  ret_string,	f_nr2char},
-    {"or",		2, 2, FEARG_1,	  ret_number,	f_or},
-    {"pathshorten",	1, 2, FEARG_1,	  ret_string,	f_pathshorten},
-    {"perleval",	1, 1, FEARG_1,	  ret_any,
+    {"nextnonblank",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_nextnonblank},
+    {"nr2char",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_nr2char},
+    {"or",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_or},
+    {"pathshorten",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_pathshorten},
+    {"perleval",	1, 1, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_PERL
 	    f_perleval
 #else
 	    NULL
 #endif
 			},
-    {"popup_atcursor",	2, 2, FEARG_1,	  ret_number,	PROP_FUNC(f_popup_atcursor)},
-    {"popup_beval",	2, 2, FEARG_1,	  ret_number,	PROP_FUNC(f_popup_beval)},
-    {"popup_clear",	0, 1, 0,	  ret_void,	PROP_FUNC(f_popup_clear)},
-    {"popup_close",	1, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_close)},
-    {"popup_create",	2, 2, FEARG_1,	  ret_number,	PROP_FUNC(f_popup_create)},
-    {"popup_dialog",	2, 2, FEARG_1,	  ret_number,	PROP_FUNC(f_popup_dialog)},
-    {"popup_filter_menu", 2, 2, 0,	  ret_bool,	PROP_FUNC(f_popup_filter_menu)},
-    {"popup_filter_yesno", 2, 2, 0,	  ret_bool,	PROP_FUNC(f_popup_filter_yesno)},
-    {"popup_findinfo",	0, 0, 0,	  ret_number,	PROP_FUNC(f_popup_findinfo)},
-    {"popup_findpreview", 0, 0, 0,	  ret_number,	PROP_FUNC(f_popup_findpreview)},
-    {"popup_getoptions", 1, 1, FEARG_1,	  ret_dict_any,	PROP_FUNC(f_popup_getoptions)},
-    {"popup_getpos",	1, 1, FEARG_1,	  ret_dict_any,	PROP_FUNC(f_popup_getpos)},
-    {"popup_hide",	1, 1, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_hide)},
-    {"popup_list",	0, 0, 0,	  ret_list_number, PROP_FUNC(f_popup_list)},
-    {"popup_locate",	2, 2, 0,	  ret_number,	PROP_FUNC(f_popup_locate)},
-    {"popup_menu",	2, 2, FEARG_1,	  ret_number,	PROP_FUNC(f_popup_menu)},
-    {"popup_move",	2, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_move)},
-    {"popup_notification", 2, 2, FEARG_1, ret_number,	PROP_FUNC(f_popup_notification)},
-    {"popup_setoptions", 2, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_setoptions)},
-    {"popup_settext",	2, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_settext)},
-    {"popup_show",	1, 1, FEARG_1,	  ret_void,	PROP_FUNC(f_popup_show)},
-    {"pow",		2, 2, FEARG_1,	  ret_float,	FLOAT_FUNC(f_pow)},
-    {"prevnonblank",	1, 1, FEARG_1,	  ret_number,	f_prevnonblank},
-    {"printf",		1, 19, FEARG_2,	  ret_string,	f_printf},
-    {"prompt_getprompt", 1, 1, FEARG_1,	  ret_string,	JOB_FUNC(f_prompt_getprompt)},
-    {"prompt_setcallback", 2, 2, FEARG_1, ret_void,	JOB_FUNC(f_prompt_setcallback)},
-    {"prompt_setinterrupt", 2, 2, FEARG_1,ret_void,	JOB_FUNC(f_prompt_setinterrupt)},
-    {"prompt_setprompt", 2, 2, FEARG_1,	  ret_void,	JOB_FUNC(f_prompt_setprompt)},
-    {"prop_add",	3, 3, FEARG_1,	  ret_void,	PROP_FUNC(f_prop_add)},
-    {"prop_clear",	1, 3, FEARG_1,	  ret_void,	PROP_FUNC(f_prop_clear)},
-    {"prop_find",	1, 2, FEARG_1,	  ret_dict_any,	PROP_FUNC(f_prop_find)},
-    {"prop_list",	1, 2, FEARG_1,	  ret_list_dict_any, PROP_FUNC(f_prop_list)},
-    {"prop_remove",	1, 3, FEARG_1,	  ret_number,	PROP_FUNC(f_prop_remove)},
-    {"prop_type_add",	2, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_prop_type_add)},
-    {"prop_type_change", 2, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_prop_type_change)},
-    {"prop_type_delete", 1, 2, FEARG_1,	  ret_void,	PROP_FUNC(f_prop_type_delete)},
-    {"prop_type_get",	1, 2, FEARG_1,	  ret_dict_any,	PROP_FUNC(f_prop_type_get)},
-    {"prop_type_list",	0, 1, FEARG_1,	  ret_list_string, PROP_FUNC(f_prop_type_list)},
-    {"pum_getpos",	0, 0, 0,	  ret_dict_number, f_pum_getpos},
-    {"pumvisible",	0, 0, 0,	  ret_number,	f_pumvisible},
-    {"py3eval",		1, 1, FEARG_1,	  ret_any,
+    {"popup_atcursor",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_atcursor)},
+    {"popup_beval",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_beval)},
+    {"popup_clear",	0, 1, 0,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_clear)},
+    {"popup_close",	1, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_close)},
+    {"popup_create",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_create)},
+    {"popup_dialog",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_dialog)},
+    {"popup_filter_menu", 2, 2, 0,	    NULL,
+			ret_bool,	    PROP_FUNC(f_popup_filter_menu)},
+    {"popup_filter_yesno", 2, 2, 0,	    NULL,
+			ret_bool,	    PROP_FUNC(f_popup_filter_yesno)},
+    {"popup_findinfo",	0, 0, 0,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_findinfo)},
+    {"popup_findpreview", 0, 0, 0,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_findpreview)},
+    {"popup_getoptions", 1, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    PROP_FUNC(f_popup_getoptions)},
+    {"popup_getpos",	1, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    PROP_FUNC(f_popup_getpos)},
+    {"popup_hide",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_hide)},
+    {"popup_list",	0, 0, 0,	    NULL,
+			ret_list_number,    PROP_FUNC(f_popup_list)},
+    {"popup_locate",	2, 2, 0,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_locate)},
+    {"popup_menu",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_popup_menu)},
+    {"popup_move",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_move)},
+    {"popup_notification", 2, 2, FEARG_1,   NULL,
+			ret_number,	    PROP_FUNC(f_popup_notification)},
+    {"popup_setoptions", 2, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_setoptions)},
+    {"popup_settext",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_settext)},
+    {"popup_show",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_popup_show)},
+    {"pow",		2, 2, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_pow)},
+    {"prevnonblank",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_prevnonblank},
+    {"printf",		1, 19, FEARG_2,	    NULL,
+			ret_string,	    f_printf},
+    {"prompt_getprompt", 1, 1, FEARG_1,	    NULL,
+			ret_string,	    JOB_FUNC(f_prompt_getprompt)},
+    {"prompt_setcallback", 2, 2, FEARG_1,   NULL,
+			ret_void,	    JOB_FUNC(f_prompt_setcallback)},
+    {"prompt_setinterrupt", 2, 2, FEARG_1,  NULL,
+			ret_void,	    JOB_FUNC(f_prompt_setinterrupt)},
+    {"prompt_setprompt", 2, 2, FEARG_1,	    NULL,
+			ret_void,	    JOB_FUNC(f_prompt_setprompt)},
+    {"prop_add",	3, 3, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_prop_add)},
+    {"prop_clear",	1, 3, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_prop_clear)},
+    {"prop_find",	1, 2, FEARG_1,	    NULL,
+			ret_dict_any,	    PROP_FUNC(f_prop_find)},
+    {"prop_list",	1, 2, FEARG_1,	    NULL,
+			ret_list_dict_any,  PROP_FUNC(f_prop_list)},
+    {"prop_remove",	1, 3, FEARG_1,	    NULL,
+			ret_number,	    PROP_FUNC(f_prop_remove)},
+    {"prop_type_add",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_prop_type_add)},
+    {"prop_type_change", 2, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_prop_type_change)},
+    {"prop_type_delete", 1, 2, FEARG_1,	    NULL,
+			ret_void,	    PROP_FUNC(f_prop_type_delete)},
+    {"prop_type_get",	1, 2, FEARG_1,	    NULL,
+			ret_dict_any,	    PROP_FUNC(f_prop_type_get)},
+    {"prop_type_list",	0, 1, FEARG_1,	    NULL,
+			ret_list_string,    PROP_FUNC(f_prop_type_list)},
+    {"pum_getpos",	0, 0, 0,	    NULL,
+			ret_dict_number,    f_pum_getpos},
+    {"pumvisible",	0, 0, 0,	    NULL,
+			ret_number,	    f_pumvisible},
+    {"py3eval",		1, 1, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_PYTHON3
 	    f_py3eval
 #else
 	    NULL
 #endif
 	    },
-    {"pyeval",		1, 1, FEARG_1,	  ret_any,
+    {"pyeval",		1, 1, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_PYTHON
 	    f_pyeval
 #else
 	    NULL
 #endif
 			},
-    {"pyxeval",		1, 1, FEARG_1,	  ret_any,
+    {"pyxeval",		1, 1, FEARG_1,	    NULL,
+			ret_any,
 #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
 	    f_pyxeval
 #else
 	    NULL
 #endif
 			},
-    {"rand",		0, 1, FEARG_1,	  ret_number,	f_rand},
-    {"range",		1, 3, FEARG_1,	  ret_list_number, f_range},
-    {"readdir",		1, 3, FEARG_1,	  ret_list_string, f_readdir},
-    {"readdirex",	1, 3, FEARG_1,	  ret_list_dict_any, f_readdirex},
-    {"readfile",	1, 3, FEARG_1,	  ret_any,	f_readfile},
-    {"reduce",		2, 3, FEARG_1,	  ret_any,	f_reduce},
-    {"reg_executing",	0, 0, 0,	  ret_string,	f_reg_executing},
-    {"reg_recording",	0, 0, 0,	  ret_string,	f_reg_recording},
-    {"reltime",		0, 2, FEARG_1,	  ret_list_any,	f_reltime},
-    {"reltimefloat",	1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_reltimefloat)},
-    {"reltimestr",	1, 1, FEARG_1,	  ret_string,	f_reltimestr},
-    {"remote_expr",	2, 4, FEARG_1,	  ret_string,	f_remote_expr},
-    {"remote_foreground", 1, 1, FEARG_1,  ret_string,	f_remote_foreground},
-    {"remote_peek",	1, 2, FEARG_1,	  ret_number,	f_remote_peek},
-    {"remote_read",	1, 2, FEARG_1,	  ret_string,	f_remote_read},
-    {"remote_send",	2, 3, FEARG_1,	  ret_string,	f_remote_send},
-    {"remote_startserver", 1, 1, FEARG_1, ret_void,	f_remote_startserver},
-    {"remove",		2, 3, FEARG_1,	  ret_remove,	f_remove},
-    {"rename",		2, 2, FEARG_1,	  ret_number,	f_rename},
-    {"repeat",		2, 2, FEARG_1,	  ret_first_arg, f_repeat},
-    {"resolve",		1, 1, FEARG_1,	  ret_string,	f_resolve},
-    {"reverse",		1, 1, FEARG_1,	  ret_first_arg, f_reverse},
-    {"round",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_round)},
-    {"rubyeval",	1, 1, FEARG_1,	  ret_any,
+    {"rand",		0, 1, FEARG_1,	    NULL,
+			ret_number,	    f_rand},
+    {"range",		1, 3, FEARG_1,	    NULL,
+			ret_list_number,    f_range},
+    {"readdir",		1, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_readdir},
+    {"readdirex",	1, 3, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_readdirex},
+    {"readfile",	1, 3, FEARG_1,	    NULL,
+			ret_any,	    f_readfile},
+    {"reduce",		2, 3, FEARG_1,	    NULL,
+			ret_any,	    f_reduce},
+    {"reg_executing",	0, 0, 0,	    NULL,
+			ret_string,	    f_reg_executing},
+    {"reg_recording",	0, 0, 0,	    NULL,
+			ret_string,	    f_reg_recording},
+    {"reltime",		0, 2, FEARG_1,	    NULL,
+			ret_list_any,	    f_reltime},
+    {"reltimefloat",	1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_reltimefloat)},
+    {"reltimestr",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_reltimestr},
+    {"remote_expr",	2, 4, FEARG_1,	    NULL,
+			ret_string,	    f_remote_expr},
+    {"remote_foreground", 1, 1, FEARG_1,    NULL,
+			ret_string,	    f_remote_foreground},
+    {"remote_peek",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_remote_peek},
+    {"remote_read",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_remote_read},
+    {"remote_send",	2, 3, FEARG_1,	    NULL,
+			ret_string,	    f_remote_send},
+    {"remote_startserver", 1, 1, FEARG_1,   NULL,
+			ret_void,	    f_remote_startserver},
+    {"remove",		2, 3, FEARG_1,	    NULL,
+			ret_remove,	    f_remove},
+    {"rename",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_rename},
+    {"repeat",		2, 2, FEARG_1,	    NULL,
+			ret_first_arg,	    f_repeat},
+    {"resolve",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_resolve},
+    {"reverse",		1, 1, FEARG_1,	    NULL,
+			ret_first_arg,	    f_reverse},
+    {"round",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_round)},
+    {"rubyeval",	1, 1, FEARG_1,	    NULL,
+			ret_any,
 #ifdef FEAT_RUBY
 	    f_rubyeval
 #else
 	    NULL
 #endif
 			},
-    {"screenattr",	2, 2, FEARG_1,	  ret_number,	f_screenattr},
-    {"screenchar",	2, 2, FEARG_1,	  ret_number,	f_screenchar},
-    {"screenchars",	2, 2, FEARG_1,	  ret_list_number, f_screenchars},
-    {"screencol",	0, 0, 0,	  ret_number,	f_screencol},
-    {"screenpos",	3, 3, FEARG_1,	  ret_dict_number, f_screenpos},
-    {"screenrow",	0, 0, 0,	  ret_number,	f_screenrow},
-    {"screenstring",	2, 2, FEARG_1,	  ret_string,	f_screenstring},
-    {"search",		1, 5, FEARG_1,	  ret_number,	f_search},
-    {"searchcount",	0, 1, FEARG_1,	  ret_dict_any,	f_searchcount},
-    {"searchdecl",	1, 3, FEARG_1,	  ret_number,	f_searchdecl},
-    {"searchpair",	3, 7, 0,	  ret_number,	f_searchpair},
-    {"searchpairpos",	3, 7, 0,	  ret_list_number, f_searchpairpos},
-    {"searchpos",	1, 5, FEARG_1,	  ret_list_number, f_searchpos},
-    {"server2client",	2, 2, FEARG_1,	  ret_number,	f_server2client},
-    {"serverlist",	0, 0, 0,	  ret_string,	f_serverlist},
-    {"setbufline",	3, 3, FEARG_3,	  ret_number,	f_setbufline},
-    {"setbufvar",	3, 3, FEARG_3,	  ret_void,	f_setbufvar},
-    {"setcellwidths",	1, 1, FEARG_1,	  ret_void,	f_setcellwidths},
-    {"setcharsearch",	1, 1, FEARG_1,	  ret_void,	f_setcharsearch},
-    {"setcmdpos",	1, 1, FEARG_1,	  ret_number,	f_setcmdpos},
-    {"setenv",		2, 2, FEARG_2,	  ret_void,	f_setenv},
-    {"setfperm",	2, 2, FEARG_1,	  ret_number,	f_setfperm},
-    {"setline",		2, 2, FEARG_2,	  ret_number,	f_setline},
-    {"setloclist",	2, 4, FEARG_2,	  ret_number,	f_setloclist},
-    {"setmatches",	1, 2, FEARG_1,	  ret_number,	f_setmatches},
-    {"setpos",		2, 2, FEARG_2,	  ret_number,	f_setpos},
-    {"setqflist",	1, 3, FEARG_1,	  ret_number,	f_setqflist},
-    {"setreg",		2, 3, FEARG_2,	  ret_number,	f_setreg},
-    {"settabvar",	3, 3, FEARG_3,	  ret_void,	f_settabvar},
-    {"settabwinvar",	4, 4, FEARG_4,	  ret_void,	f_settabwinvar},
-    {"settagstack",	2, 3, FEARG_2,	  ret_number,	f_settagstack},
-    {"setwinvar",	3, 3, FEARG_3,	  ret_void,	f_setwinvar},
-    {"sha256",		1, 1, FEARG_1,	  ret_string,
+    {"screenattr",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_screenattr},
+    {"screenchar",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_screenchar},
+    {"screenchars",	2, 2, FEARG_1,	    NULL,
+			ret_list_number,    f_screenchars},
+    {"screencol",	0, 0, 0,	    NULL,
+			ret_number,	    f_screencol},
+    {"screenpos",	3, 3, FEARG_1,	    NULL,
+			ret_dict_number,    f_screenpos},
+    {"screenrow",	0, 0, 0,	    NULL,
+			ret_number,	    f_screenrow},
+    {"screenstring",	2, 2, FEARG_1,	    NULL,
+			ret_string,	    f_screenstring},
+    {"search",		1, 5, FEARG_1,	    NULL,
+			ret_number,	    f_search},
+    {"searchcount",	0, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    f_searchcount},
+    {"searchdecl",	1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_searchdecl},
+    {"searchpair",	3, 7, 0,	    NULL,
+			ret_number,	    f_searchpair},
+    {"searchpairpos",	3, 7, 0,	    NULL,
+			ret_list_number,    f_searchpairpos},
+    {"searchpos",	1, 5, FEARG_1,	    NULL,
+			ret_list_number,    f_searchpos},
+    {"server2client",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_server2client},
+    {"serverlist",	0, 0, 0,	    NULL,
+			ret_string,	    f_serverlist},
+    {"setbufline",	3, 3, FEARG_3,	    NULL,
+			ret_number,	    f_setbufline},
+    {"setbufvar",	3, 3, FEARG_3,	    NULL,
+			ret_void,	    f_setbufvar},
+    {"setcellwidths",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_setcellwidths},
+    {"setcharsearch",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_setcharsearch},
+    {"setcmdpos",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_setcmdpos},
+    {"setenv",		2, 2, FEARG_2,	    NULL,
+			ret_void,	    f_setenv},
+    {"setfperm",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_setfperm},
+    {"setline",		2, 2, FEARG_2,	    NULL,
+			ret_number,	    f_setline},
+    {"setloclist",	2, 4, FEARG_2,	    NULL,
+			ret_number,	    f_setloclist},
+    {"setmatches",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_setmatches},
+    {"setpos",		2, 2, FEARG_2,	    NULL,
+			ret_number,	    f_setpos},
+    {"setqflist",	1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_setqflist},
+    {"setreg",		2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_setreg},
+    {"settabvar",	3, 3, FEARG_3,	    NULL,
+			ret_void,	    f_settabvar},
+    {"settabwinvar",	4, 4, FEARG_4,	    NULL,
+			ret_void,	    f_settabwinvar},
+    {"settagstack",	2, 3, FEARG_2,	    NULL,
+			ret_number,	    f_settagstack},
+    {"setwinvar",	3, 3, FEARG_3,	    NULL,
+			ret_void,	    f_setwinvar},
+    {"sha256",		1, 1, FEARG_1,	    NULL,
+			ret_string,
 #ifdef FEAT_CRYPT
 	    f_sha256
 #else
 	    NULL
 #endif
 			},
-    {"shellescape",	1, 2, FEARG_1,	  ret_string,	f_shellescape},
-    {"shiftwidth",	0, 1, FEARG_1,	  ret_number,	f_shiftwidth},
-    {"sign_define",	1, 2, FEARG_1,	  ret_any,	SIGN_FUNC(f_sign_define)},
-    {"sign_getdefined",	0, 1, FEARG_1,	  ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)},
-    {"sign_getplaced",	0, 2, FEARG_1,	  ret_list_dict_any, SIGN_FUNC(f_sign_getplaced)},
-    {"sign_jump",	3, 3, FEARG_1,	  ret_number,	SIGN_FUNC(f_sign_jump)},
-    {"sign_place",	4, 5, FEARG_1,	  ret_number,	SIGN_FUNC(f_sign_place)},
-    {"sign_placelist",	1, 1, FEARG_1,	  ret_list_number, SIGN_FUNC(f_sign_placelist)},
-    {"sign_undefine",	0, 1, FEARG_1,	  ret_number,	SIGN_FUNC(f_sign_undefine)},
-    {"sign_unplace",	1, 2, FEARG_1,	  ret_number,	SIGN_FUNC(f_sign_unplace)},
-    {"sign_unplacelist", 1, 2, FEARG_1,	  ret_list_number, SIGN_FUNC(f_sign_unplacelist)},
-    {"simplify",	1, 1, FEARG_1,	  ret_string,	f_simplify},
-    {"sin",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_sin)},
-    {"sinh",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_sinh)},
-    {"sort",		1, 3, FEARG_1,	  ret_first_arg, f_sort},
-    {"sound_clear",	0, 0, 0,	  ret_void,	SOUND_FUNC(f_sound_clear)},
-    {"sound_playevent",	1, 2, FEARG_1,	  ret_number,	SOUND_FUNC(f_sound_playevent)},
-    {"sound_playfile",	1, 2, FEARG_1,	  ret_number,	SOUND_FUNC(f_sound_playfile)},
-    {"sound_stop",	1, 1, FEARG_1,	  ret_void,	SOUND_FUNC(f_sound_stop)},
-    {"soundfold",	1, 1, FEARG_1,	  ret_string,	f_soundfold},
-    {"spellbadword",	0, 1, FEARG_1,	  ret_list_string, f_spellbadword},
-    {"spellsuggest",	1, 3, FEARG_1,	  ret_list_string, f_spellsuggest},
-    {"split",		1, 3, FEARG_1,	  ret_list_string, f_split},
-    {"sqrt",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_sqrt)},
-    {"srand",		0, 1, FEARG_1,	  ret_list_number, f_srand},
-    {"state",		0, 1, FEARG_1,	  ret_string,	f_state},
-    {"str2float",	1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_str2float)},
-    {"str2list",	1, 2, FEARG_1,	  ret_list_number, f_str2list},
-    {"str2nr",		1, 3, FEARG_1,	  ret_number,	f_str2nr},
-    {"strcharpart",	2, 3, FEARG_1,	  ret_string,	f_strcharpart},
-    {"strchars",	1, 2, FEARG_1,	  ret_number,	f_strchars},
-    {"strdisplaywidth",	1, 2, FEARG_1,	  ret_number,	f_strdisplaywidth},
-    {"strftime",	1, 2, FEARG_1,	  ret_string,
+    {"shellescape",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_shellescape},
+    {"shiftwidth",	0, 1, FEARG_1,	    NULL,
+			ret_number,	    f_shiftwidth},
+    {"sign_define",	1, 2, FEARG_1,	    NULL,
+			ret_any,	    SIGN_FUNC(f_sign_define)},
+    {"sign_getdefined",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  SIGN_FUNC(f_sign_getdefined)},
+    {"sign_getplaced",	0, 2, FEARG_1,	    NULL,
+			ret_list_dict_any,  SIGN_FUNC(f_sign_getplaced)},
+    {"sign_jump",	3, 3, FEARG_1,	    NULL,
+			ret_number,	    SIGN_FUNC(f_sign_jump)},
+    {"sign_place",	4, 5, FEARG_1,	    NULL,
+			ret_number,	    SIGN_FUNC(f_sign_place)},
+    {"sign_placelist",	1, 1, FEARG_1,	    NULL,
+			ret_list_number,    SIGN_FUNC(f_sign_placelist)},
+    {"sign_undefine",	0, 1, FEARG_1,	    NULL,
+			ret_number,	    SIGN_FUNC(f_sign_undefine)},
+    {"sign_unplace",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    SIGN_FUNC(f_sign_unplace)},
+    {"sign_unplacelist", 1, 2, FEARG_1,	    NULL,
+			ret_list_number,    SIGN_FUNC(f_sign_unplacelist)},
+    {"simplify",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_simplify},
+    {"sin",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_sin)},
+    {"sinh",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_sinh)},
+    {"sort",		1, 3, FEARG_1,	    NULL,
+			ret_first_arg,	    f_sort},
+    {"sound_clear",	0, 0, 0,	    NULL,
+			ret_void,	    SOUND_FUNC(f_sound_clear)},
+    {"sound_playevent",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    SOUND_FUNC(f_sound_playevent)},
+    {"sound_playfile",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    SOUND_FUNC(f_sound_playfile)},
+    {"sound_stop",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    SOUND_FUNC(f_sound_stop)},
+    {"soundfold",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_soundfold},
+    {"spellbadword",	0, 1, FEARG_1,	    NULL,
+			ret_list_string,    f_spellbadword},
+    {"spellsuggest",	1, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_spellsuggest},
+    {"split",		1, 3, FEARG_1,	    NULL,
+			ret_list_string,    f_split},
+    {"sqrt",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_sqrt)},
+    {"srand",		0, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_srand},
+    {"state",		0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_state},
+    {"str2float",	1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_str2float)},
+    {"str2list",	1, 2, FEARG_1,	    NULL,
+			ret_list_number,    f_str2list},
+    {"str2nr",		1, 3, FEARG_1,	    NULL,
+			ret_number,	    f_str2nr},
+    {"strcharpart",	2, 3, FEARG_1,	    NULL,
+			ret_string,	    f_strcharpart},
+    {"strchars",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_strchars},
+    {"strdisplaywidth",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_strdisplaywidth},
+    {"strftime",	1, 2, FEARG_1,	    NULL,
+			ret_string,
 #ifdef HAVE_STRFTIME
 	    f_strftime
 #else
 	    NULL
 #endif
 			},
-    {"strgetchar",	2, 2, FEARG_1,	  ret_number,	f_strgetchar},
-    {"stridx",		2, 3, FEARG_1,	  ret_number,	f_stridx},
-    {"string",		1, 1, FEARG_1,	  ret_string,	f_string},
-    {"strlen",		1, 1, FEARG_1,	  ret_number,	f_strlen},
-    {"strpart",		2, 4, FEARG_1,	  ret_string,	f_strpart},
-    {"strptime",	2, 2, FEARG_1,	  ret_number,
+    {"strgetchar",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_strgetchar},
+    {"stridx",		2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_stridx},
+    {"string",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_string},
+    {"strlen",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_strlen},
+    {"strpart",		2, 4, FEARG_1,	    NULL,
+			ret_string,	    f_strpart},
+    {"strptime",	2, 2, FEARG_1,	    NULL,
+			ret_number,
 #ifdef HAVE_STRPTIME
 	    f_strptime
 #else
 	    NULL
 #endif
 			},
-    {"strridx",		2, 3, FEARG_1,	  ret_number,	f_strridx},
-    {"strtrans",	1, 1, FEARG_1,	  ret_string,	f_strtrans},
-    {"strwidth",	1, 1, FEARG_1,	  ret_number,	f_strwidth},
-    {"submatch",	1, 2, FEARG_1,	  ret_string,	f_submatch},
-    {"substitute",	4, 4, FEARG_1,	  ret_string,	f_substitute},
-    {"swapinfo",	1, 1, FEARG_1,	  ret_dict_any,	f_swapinfo},
-    {"swapname",	1, 1, FEARG_1,	  ret_string,	f_swapname},
-    {"synID",		3, 3, 0,	  ret_number,	f_synID},
-    {"synIDattr",	2, 3, FEARG_1,	  ret_string,	f_synIDattr},
-    {"synIDtrans",	1, 1, FEARG_1,	  ret_number,	f_synIDtrans},
-    {"synconcealed",	2, 2, 0,	  ret_list_any,	f_synconcealed},
-    {"synstack",	2, 2, 0,	  ret_list_number, f_synstack},
-    {"system",		1, 2, FEARG_1,	  ret_string,	f_system},
-    {"systemlist",	1, 2, FEARG_1,	  ret_list_string, f_systemlist},
-    {"tabpagebuflist",	0, 1, FEARG_1,	  ret_list_number, f_tabpagebuflist},
-    {"tabpagenr",	0, 1, 0,	  ret_number,	f_tabpagenr},
-    {"tabpagewinnr",	1, 2, FEARG_1,	  ret_number,	f_tabpagewinnr},
-    {"tagfiles",	0, 0, 0,	  ret_list_string, f_tagfiles},
-    {"taglist",		1, 2, FEARG_1,	  ret_list_dict_any, f_taglist},
-    {"tan",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_tan)},
-    {"tanh",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_tanh)},
-    {"tempname",	0, 0, 0,	  ret_string,	f_tempname},
-    {"term_dumpdiff",	2, 3, FEARG_1,	  ret_number,	TERM_FUNC(f_term_dumpdiff)},
-    {"term_dumpload",	1, 2, FEARG_1,	  ret_number,	TERM_FUNC(f_term_dumpload)},
-    {"term_dumpwrite",	2, 3, FEARG_2,	  ret_void,	TERM_FUNC(f_term_dumpwrite)},
-    {"term_getaltscreen", 1, 1, FEARG_1,  ret_number,	TERM_FUNC(f_term_getaltscreen)},
-    {"term_getansicolors", 1, 1, FEARG_1, ret_list_string,
+    {"strridx",		2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_strridx},
+    {"strtrans",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_strtrans},
+    {"strwidth",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_strwidth},
+    {"submatch",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_submatch},
+    {"substitute",	4, 4, FEARG_1,	    NULL,
+			ret_string,	    f_substitute},
+    {"swapinfo",	1, 1, FEARG_1,	    NULL,
+			ret_dict_any,	    f_swapinfo},
+    {"swapname",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_swapname},
+    {"synID",		3, 3, 0,	    NULL,
+			ret_number,	    f_synID},
+    {"synIDattr",	2, 3, FEARG_1,	    NULL,
+			ret_string,	    f_synIDattr},
+    {"synIDtrans",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_synIDtrans},
+    {"synconcealed",	2, 2, 0,	    NULL,
+			ret_list_any,	    f_synconcealed},
+    {"synstack",	2, 2, 0,	    NULL,
+			ret_list_number,    f_synstack},
+    {"system",		1, 2, FEARG_1,	    NULL,
+			ret_string,	    f_system},
+    {"systemlist",	1, 2, FEARG_1,	    NULL,
+			ret_list_string,    f_systemlist},
+    {"tabpagebuflist",	0, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_tabpagebuflist},
+    {"tabpagenr",	0, 1, 0,	    NULL,
+			ret_number,	    f_tabpagenr},
+    {"tabpagewinnr",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    f_tabpagewinnr},
+    {"tagfiles",	0, 0, 0,	    NULL,
+			ret_list_string,    f_tagfiles},
+    {"taglist",		1, 2, FEARG_1,	    NULL,
+			ret_list_dict_any,  f_taglist},
+    {"tan",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_tan)},
+    {"tanh",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_tanh)},
+    {"tempname",	0, 0, 0,	    NULL,
+			ret_string,	    f_tempname},
+    {"term_dumpdiff",	2, 3, FEARG_1,	    NULL,
+			ret_number,	    TERM_FUNC(f_term_dumpdiff)},
+    {"term_dumpload",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    TERM_FUNC(f_term_dumpload)},
+    {"term_dumpwrite",	2, 3, FEARG_2,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_dumpwrite)},
+    {"term_getaltscreen", 1, 1, FEARG_1,    NULL,
+			ret_number,	    TERM_FUNC(f_term_getaltscreen)},
+    {"term_getansicolors", 1, 1, FEARG_1,   NULL,
+			ret_list_string,
 #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
 	    f_term_getansicolors
 #else
 	    NULL
 #endif
 			},
-    {"term_getattr",	2, 2, FEARG_1,	  ret_number,	TERM_FUNC(f_term_getattr)},
-    {"term_getcursor",	1, 1, FEARG_1,	  ret_list_any,	TERM_FUNC(f_term_getcursor)},
-    {"term_getjob",	1, 1, FEARG_1,	  ret_job,	TERM_FUNC(f_term_getjob)},
-    {"term_getline",	2, 2, FEARG_1,	  ret_string,	TERM_FUNC(f_term_getline)},
-    {"term_getscrolled", 1, 1, FEARG_1,	  ret_number,	TERM_FUNC(f_term_getscrolled)},
-    {"term_getsize",	1, 1, FEARG_1,	  ret_list_number, TERM_FUNC(f_term_getsize)},
-    {"term_getstatus",	1, 1, FEARG_1,	  ret_string,	TERM_FUNC(f_term_getstatus)},
-    {"term_gettitle",	1, 1, FEARG_1,	  ret_string,	TERM_FUNC(f_term_gettitle)},
-    {"term_gettty",	1, 2, FEARG_1,	  ret_string,	TERM_FUNC(f_term_gettty)},
-    {"term_list",	0, 0, 0,	  ret_list_number, TERM_FUNC(f_term_list)},
-    {"term_scrape",	2, 2, FEARG_1,	  ret_list_dict_any, TERM_FUNC(f_term_scrape)},
-    {"term_sendkeys",	2, 2, FEARG_1,	  ret_void,	TERM_FUNC(f_term_sendkeys)},
-    {"term_setansicolors", 2, 2, FEARG_1, ret_void,
+    {"term_getattr",	2, 2, FEARG_1,	    NULL,
+			ret_number,	    TERM_FUNC(f_term_getattr)},
+    {"term_getcursor",	1, 1, FEARG_1,	    NULL,
+			ret_list_any,	    TERM_FUNC(f_term_getcursor)},
+    {"term_getjob",	1, 1, FEARG_1,	    NULL,
+			ret_job,	    TERM_FUNC(f_term_getjob)},
+    {"term_getline",	2, 2, FEARG_1,	    NULL,
+			ret_string,	    TERM_FUNC(f_term_getline)},
+    {"term_getscrolled", 1, 1, FEARG_1,	    NULL,
+			ret_number,	    TERM_FUNC(f_term_getscrolled)},
+    {"term_getsize",	1, 1, FEARG_1,	    NULL,
+			ret_list_number,    TERM_FUNC(f_term_getsize)},
+    {"term_getstatus",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    TERM_FUNC(f_term_getstatus)},
+    {"term_gettitle",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    TERM_FUNC(f_term_gettitle)},
+    {"term_gettty",	1, 2, FEARG_1,	    NULL,
+			ret_string,	    TERM_FUNC(f_term_gettty)},
+    {"term_list",	0, 0, 0,	    NULL,
+			ret_list_number,    TERM_FUNC(f_term_list)},
+    {"term_scrape",	2, 2, FEARG_1,	    NULL,
+			ret_list_dict_any,  TERM_FUNC(f_term_scrape)},
+    {"term_sendkeys",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_sendkeys)},
+    {"term_setansicolors", 2, 2, FEARG_1,   NULL,
+			ret_void,
 #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
 	    f_term_setansicolors
 #else
 	    NULL
 #endif
 			},
-    {"term_setapi",	2, 2, FEARG_1,	  ret_void,	TERM_FUNC(f_term_setapi)},
-    {"term_setkill",	2, 2, FEARG_1,	  ret_void,	TERM_FUNC(f_term_setkill)},
-    {"term_setrestore",	2, 2, FEARG_1,	  ret_void,	TERM_FUNC(f_term_setrestore)},
-    {"term_setsize",	3, 3, FEARG_1,	  ret_void,	TERM_FUNC(f_term_setsize)},
-    {"term_start",	1, 2, FEARG_1,	  ret_number,	TERM_FUNC(f_term_start)},
-    {"term_wait",	1, 2, FEARG_1,	  ret_void,	TERM_FUNC(f_term_wait)},
-    {"terminalprops",	0, 0, 0,	  ret_dict_string, f_terminalprops},
-    {"test_alloc_fail",	3, 3, FEARG_1,	  ret_void,	f_test_alloc_fail},
-    {"test_autochdir",	0, 0, 0,	  ret_void,	f_test_autochdir},
-    {"test_feedinput",	1, 1, FEARG_1,	  ret_void,	f_test_feedinput},
-    {"test_garbagecollect_now",	0, 0, 0,  ret_void,	f_test_garbagecollect_now},
-    {"test_garbagecollect_soon", 0, 0, 0, ret_void,	f_test_garbagecollect_soon},
-    {"test_getvalue",	1, 1, FEARG_1,	  ret_number,	f_test_getvalue},
-    {"test_ignore_error", 1, 1, FEARG_1,  ret_void,	f_test_ignore_error},
-    {"test_null_blob",	0, 0, 0,	  ret_blob,	f_test_null_blob},
-    {"test_null_channel", 0, 0, 0,	  ret_channel,	JOB_FUNC(f_test_null_channel)},
-    {"test_null_dict",	0, 0, 0,	  ret_dict_any,	f_test_null_dict},
-    {"test_null_function", 0, 0, 0,	  ret_func_any,	f_test_null_function},
-    {"test_null_job",	0, 0, 0,	  ret_job,	JOB_FUNC(f_test_null_job)},
-    {"test_null_list",	0, 0, 0,	  ret_list_any,	f_test_null_list},
-    {"test_null_partial", 0, 0, 0,	  ret_func_any, f_test_null_partial},
-    {"test_null_string", 0, 0, 0,	  ret_string,	f_test_null_string},
-    {"test_option_not_set", 1, 1, FEARG_1,ret_void,	 f_test_option_not_set},
-    {"test_override",	2, 2, FEARG_2,	  ret_void,	f_test_override},
-    {"test_refcount",	1, 1, FEARG_1,	  ret_number,	f_test_refcount},
-    {"test_scrollbar",	3, 3, FEARG_2,	  ret_void,
+    {"term_setapi",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_setapi)},
+    {"term_setkill",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_setkill)},
+    {"term_setrestore",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_setrestore)},
+    {"term_setsize",	3, 3, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_setsize)},
+    {"term_start",	1, 2, FEARG_1,	    NULL,
+			ret_number,	    TERM_FUNC(f_term_start)},
+    {"term_wait",	1, 2, FEARG_1,	    NULL,
+			ret_void,	    TERM_FUNC(f_term_wait)},
+    {"terminalprops",	0, 0, 0,	    NULL,
+			ret_dict_string,    f_terminalprops},
+    {"test_alloc_fail",	3, 3, FEARG_1,	    NULL,
+			ret_void,	    f_test_alloc_fail},
+    {"test_autochdir",	0, 0, 0,	    NULL,
+			ret_void,	    f_test_autochdir},
+    {"test_feedinput",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_test_feedinput},
+    {"test_garbagecollect_now",	0, 0, 0,    NULL,
+			ret_void,	    f_test_garbagecollect_now},
+    {"test_garbagecollect_soon", 0, 0, 0,   NULL,
+			ret_void,	    f_test_garbagecollect_soon},
+    {"test_getvalue",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_test_getvalue},
+    {"test_ignore_error", 1, 1, FEARG_1,    NULL,
+			ret_void,	    f_test_ignore_error},
+    {"test_null_blob",	0, 0, 0,	    NULL,
+			ret_blob,	    f_test_null_blob},
+    {"test_null_channel", 0, 0, 0,	    NULL,
+			ret_channel,	    JOB_FUNC(f_test_null_channel)},
+    {"test_null_dict",	0, 0, 0,	    NULL,
+			ret_dict_any,	    f_test_null_dict},
+    {"test_null_function", 0, 0, 0,	    NULL,
+			ret_func_any,	    f_test_null_function},
+    {"test_null_job",	0, 0, 0,	    NULL,
+			ret_job,	    JOB_FUNC(f_test_null_job)},
+    {"test_null_list",	0, 0, 0,	    NULL,
+			ret_list_any,	    f_test_null_list},
+    {"test_null_partial", 0, 0, 0,	    NULL,
+			ret_func_any,	    f_test_null_partial},
+    {"test_null_string", 0, 0, 0,	    NULL,
+			ret_string,	    f_test_null_string},
+    {"test_option_not_set", 1, 1, FEARG_1,  NULL,
+			ret_void,	    f_test_option_not_set},
+    {"test_override",	2, 2, FEARG_2,	    NULL,
+			ret_void,	    f_test_override},
+    {"test_refcount",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_test_refcount},
+    {"test_scrollbar",	3, 3, FEARG_2,	    NULL,
+			ret_void,
 #ifdef FEAT_GUI
 	f_test_scrollbar
 #else
 	NULL
 #endif
 			},
-    {"test_setmouse",	2, 2, 0,	  ret_void,	f_test_setmouse},
-    {"test_settime",	1, 1, FEARG_1,	  ret_void,	f_test_settime},
-    {"test_srand_seed",	0, 1, FEARG_1,	  ret_void,	f_test_srand_seed},
-    {"test_unknown",	0, 0, 0,	  ret_any,	f_test_unknown},
-    {"test_void",	0, 0, 0,	  ret_void,	f_test_void},
-    {"timer_info",	0, 1, FEARG_1,	  ret_list_dict_any, TIMER_FUNC(f_timer_info)},
-    {"timer_pause",	2, 2, FEARG_1,	  ret_void,	TIMER_FUNC(f_timer_pause)},
-    {"timer_start",	2, 3, FEARG_1,	  ret_number,	TIMER_FUNC(f_timer_start)},
-    {"timer_stop",	1, 1, FEARG_1,	  ret_void,	TIMER_FUNC(f_timer_stop)},
-    {"timer_stopall",	0, 0, 0,	  ret_void,	TIMER_FUNC(f_timer_stopall)},
-    {"tolower",		1, 1, FEARG_1,	  ret_string,	f_tolower},
-    {"toupper",		1, 1, FEARG_1,	  ret_string,	f_toupper},
-    {"tr",		3, 3, FEARG_1,	  ret_string,	f_tr},
-    {"trim",		1, 3, FEARG_1,	  ret_string,	f_trim},
-    {"trunc",		1, 1, FEARG_1,	  ret_float,	FLOAT_FUNC(f_trunc)},
-    {"type",		1, 1, FEARG_1,	  ret_number,	f_type},
-    {"undofile",	1, 1, FEARG_1,	  ret_string,	f_undofile},
-    {"undotree",	0, 0, 0,	  ret_dict_any,	f_undotree},
-    {"uniq",		1, 3, FEARG_1,	  ret_list_any,	f_uniq},
-    {"values",		1, 1, FEARG_1,	  ret_list_any,	f_values},
-    {"virtcol",		1, 1, FEARG_1,	  ret_number,	f_virtcol},
-    {"visualmode",	0, 1, 0,	  ret_string,	f_visualmode},
-    {"wildmenumode",	0, 0, 0,	  ret_number,	f_wildmenumode},
-    {"win_execute",	2, 3, FEARG_2,	  ret_string,	f_win_execute},
-    {"win_findbuf",	1, 1, FEARG_1,	  ret_list_number, f_win_findbuf},
-    {"win_getid",	0, 2, FEARG_1,	  ret_number,	f_win_getid},
-    {"win_gettype",	0, 1, FEARG_1,    ret_string,	f_win_gettype},
-    {"win_gotoid",	1, 1, FEARG_1,	  ret_number,	f_win_gotoid},
-    {"win_id2tabwin",	1, 1, FEARG_1,	  ret_list_number, f_win_id2tabwin},
-    {"win_id2win",	1, 1, FEARG_1,	  ret_number,	f_win_id2win},
-    {"win_screenpos",	1, 1, FEARG_1,	  ret_list_number, f_win_screenpos},
-    {"win_splitmove",   2, 3, FEARG_1,    ret_number,	f_win_splitmove},
-    {"winbufnr",	1, 1, FEARG_1,	  ret_number,	f_winbufnr},
-    {"wincol",		0, 0, 0,	  ret_number,	f_wincol},
-    {"windowsversion",	0, 0, 0,	  ret_string,	f_windowsversion},
-    {"winheight",	1, 1, FEARG_1,	  ret_number,	f_winheight},
-    {"winlayout",	0, 1, FEARG_1,	  ret_list_any,	f_winlayout},
-    {"winline",		0, 0, 0,	  ret_number,	f_winline},
-    {"winnr",		0, 1, FEARG_1,	  ret_number,	f_winnr},
-    {"winrestcmd",	0, 0, 0,	  ret_string,	f_winrestcmd},
-    {"winrestview",	1, 1, FEARG_1,	  ret_void,	f_winrestview},
-    {"winsaveview",	0, 0, 0,	  ret_dict_any,	f_winsaveview},
-    {"winwidth",	1, 1, FEARG_1,	  ret_number,	f_winwidth},
-    {"wordcount",	0, 0, 0,	  ret_dict_number, f_wordcount},
-    {"writefile",	2, 3, FEARG_1,	  ret_number,	f_writefile},
-    {"xor",		2, 2, FEARG_1,	  ret_number,	f_xor},
+    {"test_setmouse",	2, 2, 0,	    NULL,
+			ret_void,	    f_test_setmouse},
+    {"test_settime",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_test_settime},
+    {"test_srand_seed",	0, 1, FEARG_1,	    NULL,
+			ret_void,	    f_test_srand_seed},
+    {"test_unknown",	0, 0, 0,	    NULL,
+			ret_any,	    f_test_unknown},
+    {"test_void",	0, 0, 0,	    NULL,
+			ret_void,	    f_test_void},
+    {"timer_info",	0, 1, FEARG_1,	    NULL,
+			ret_list_dict_any,  TIMER_FUNC(f_timer_info)},
+    {"timer_pause",	2, 2, FEARG_1,	    NULL,
+			ret_void,	    TIMER_FUNC(f_timer_pause)},
+    {"timer_start",	2, 3, FEARG_1,	    NULL,
+			ret_number,	    TIMER_FUNC(f_timer_start)},
+    {"timer_stop",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    TIMER_FUNC(f_timer_stop)},
+    {"timer_stopall",	0, 0, 0,	    NULL,
+			ret_void,	    TIMER_FUNC(f_timer_stopall)},
+    {"tolower",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_tolower},
+    {"toupper",		1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_toupper},
+    {"tr",		3, 3, FEARG_1,	    NULL,
+			ret_string,	    f_tr},
+    {"trim",		1, 3, FEARG_1,	    NULL,
+			ret_string,	    f_trim},
+    {"trunc",		1, 1, FEARG_1,	    NULL,
+			ret_float,	    FLOAT_FUNC(f_trunc)},
+    {"type",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_type},
+    {"undofile",	1, 1, FEARG_1,	    NULL,
+			ret_string,	    f_undofile},
+    {"undotree",	0, 0, 0,	    NULL,
+			ret_dict_any,	    f_undotree},
+    {"uniq",		1, 3, FEARG_1,	    NULL,
+			ret_list_any,	    f_uniq},
+    {"values",		1, 1, FEARG_1,	    NULL,
+			ret_list_any,	    f_values},
+    {"virtcol",		1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_virtcol},
+    {"visualmode",	0, 1, 0,	    NULL,
+			ret_string,	    f_visualmode},
+    {"wildmenumode",	0, 0, 0,	    NULL,
+			ret_number,	    f_wildmenumode},
+    {"win_execute",	2, 3, FEARG_2,	    NULL,
+			ret_string,	    f_win_execute},
+    {"win_findbuf",	1, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_win_findbuf},
+    {"win_getid",	0, 2, FEARG_1,	    NULL,
+			ret_number,	    f_win_getid},
+    {"win_gettype",	0, 1, FEARG_1,	    NULL,
+			ret_string,	    f_win_gettype},
+    {"win_gotoid",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_win_gotoid},
+    {"win_id2tabwin",	1, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_win_id2tabwin},
+    {"win_id2win",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_win_id2win},
+    {"win_screenpos",	1, 1, FEARG_1,	    NULL,
+			ret_list_number,    f_win_screenpos},
+    {"win_splitmove",   2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_win_splitmove},
+    {"winbufnr",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_winbufnr},
+    {"wincol",		0, 0, 0,	    NULL,
+			ret_number,	    f_wincol},
+    {"windowsversion",	0, 0, 0,	    NULL,
+			ret_string,	    f_windowsversion},
+    {"winheight",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_winheight},
+    {"winlayout",	0, 1, FEARG_1,	    NULL,
+			ret_list_any,	    f_winlayout},
+    {"winline",		0, 0, 0,	    NULL,
+			ret_number,	    f_winline},
+    {"winnr",		0, 1, FEARG_1,	    NULL,
+			ret_number,	    f_winnr},
+    {"winrestcmd",	0, 0, 0,	    NULL,
+			ret_string,	    f_winrestcmd},
+    {"winrestview",	1, 1, FEARG_1,	    NULL,
+			ret_void,	    f_winrestview},
+    {"winsaveview",	0, 0, 0,	    NULL,
+			ret_dict_any,	    f_winsaveview},
+    {"winwidth",	1, 1, FEARG_1,	    NULL,
+			ret_number,	    f_winwidth},
+    {"wordcount",	0, 0, 0,	    NULL,
+			ret_dict_number,    f_wordcount},
+    {"writefile",	2, 3, FEARG_1,	    NULL,
+			ret_number,	    f_writefile},
+    {"xor",		2, 2, FEARG_1,	    NULL,
+			ret_number,	    f_xor},
 };
 
 /*
@@ -1216,6 +1757,33 @@ internal_func_name(int idx)
     return global_functions[idx].f_name;
 }
 
+/*
+ * Check the argument types for builting function "idx".
+ * Uses the list of types on the type stack: "types".
+ * Return FAIL and gives an error message when a type is wrong.
+ */
+    int
+internal_func_check_arg_types(type_T *types, int idx, int argcount)
+{
+    argcheck_T	*argchecks = global_functions[idx].f_argcheck;
+    int		i;
+
+    if (argchecks != NULL)
+    {
+	argcontext_T context;
+
+	context.arg_count = argcount;
+	for (i = 0; i < argcount; ++i)
+	    if (argchecks[i] != NULL)
+	    {
+		context.arg_idx = i;
+		if (argchecks[i](types + i, &context) == FAIL)
+		    return FAIL;
+	    }
+    }
+    return OK;
+}
+
     type_T *
 internal_func_ret_type(int idx, int argcount, type_T **argtypes)
 {
--- a/src/proto/evalfunc.pro
+++ b/src/proto/evalfunc.pro
@@ -4,6 +4,7 @@ char_u *get_expr_name(expand_T *xp, int 
 int find_internal_func(char_u *name);
 int has_internal_func(char_u *name);
 char *internal_func_name(int idx);
+int internal_func_check_arg_types(type_T *types, int idx, int argcount);
 type_T *internal_func_ret_type(int idx, int argcount, type_T **argtypes);
 int check_internal_func(int idx, int argcount);
 int call_internal_func(char_u *name, int argcount, typval_T *argvars, typval_T *rettv);
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -31,6 +31,7 @@ SCRIPTS_TINY_OUT = \
 # Tests for Vim9 script.
 TEST_VIM9 = \
 	test_vim9_assign \
+	test_vim9_builtin \
 	test_vim9_cmd \
 	test_vim9_disassemble \
 	test_vim9_expr \
@@ -40,6 +41,7 @@ TEST_VIM9 = \
 
 TEST_VIM9_RES = \
 	test_vim9_assign.res \
+	test_vim9_builtin.res \
 	test_vim9_cmd.res \
 	test_vim9_disassemble.res \
 	test_vim9_expr.res \
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_vim9_builtin.vim
@@ -0,0 +1,554 @@
+" Test using builtin functions in the Vim9 script language.
+
+source check.vim
+source vim9.vim
+
+" Test for passing too many or too few arguments to builtin functions
+func Test_internalfunc_arg_error()
+  let l =<< trim END
+    def! FArgErr(): float
+      return ceil(1.1, 2)
+    enddef
+    defcompile
+  END
+  call writefile(l, 'Xinvalidarg')
+  call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
+  let l =<< trim END
+    def! FArgErr(): float
+      return ceil()
+    enddef
+    defcompile
+  END
+  call writefile(l, 'Xinvalidarg')
+  call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
+  call delete('Xinvalidarg')
+endfunc
+
+" Test for builtin functions returning different types
+func Test_InternalFuncRetType()
+  let lines =<< trim END
+    def RetFloat(): float
+      return ceil(1.456)
+    enddef
+
+    def RetListAny(): list<any>
+      return items({'k': 'v'})
+    enddef
+
+    def RetListString(): list<string>
+      return split('a:b:c', ':')
+    enddef
+
+    def RetListDictAny(): list<dict<any>>
+      return getbufinfo()
+    enddef
+
+    def RetDictNumber(): dict<number>
+      return wordcount()
+    enddef
+
+    def RetDictString(): dict<string>
+      return environ()
+    enddef
+  END
+  call writefile(lines, 'Xscript')
+  source Xscript
+
+  call RetFloat()->assert_equal(2.0)
+  call RetListAny()->assert_equal([['k', 'v']])
+  call RetListString()->assert_equal(['a', 'b', 'c'])
+  call RetListDictAny()->assert_notequal([])
+  call RetDictNumber()->assert_notequal({})
+  call RetDictString()->assert_notequal({})
+  call delete('Xscript')
+endfunc
+
+def Test_abs()
+  assert_equal(0, abs(0))
+  assert_equal(2, abs(-2))
+  assert_equal(3, abs(3))
+  CheckDefFailure(['abs("text")'], 'E1013: Argument 1: type mismatch, expected number but got string', 1)
+  if has('float')
+    assert_equal(0, abs(0))
+    assert_equal(2.0, abs(-2.0))
+    assert_equal(3.0, abs(3.0))
+  endif
+enddef
+
+def Test_add_list()
+  var l: list<number>  # defaults to empty list
+  add(l, 9)
+  assert_equal([9], l)
+
+  var lines =<< trim END
+      var l: list<number>
+      add(l, "x")
+  END
+  CheckDefFailure(lines, 'E1012:', 2)
+
+  lines =<< trim END
+      var l: list<number> = test_null_list()
+      add(l, 123)
+  END
+  CheckDefExecFailure(lines, 'E1130:', 2)
+enddef
+
+def Test_add_blob()
+  var b1: blob = 0z12
+  add(b1, 0x34)
+  assert_equal(0z1234, b1)
+
+  var b2: blob # defaults to empty blob
+  add(b2, 0x67)
+  assert_equal(0z67, b2)
+
+  var lines =<< trim END
+      var b: blob
+      add(b, "x")
+  END
+  CheckDefFailure(lines, 'E1012:', 2)
+
+  lines =<< trim END
+      var b: blob = test_null_blob()
+      add(b, 123)
+  END
+  CheckDefExecFailure(lines, 'E1131:', 2)
+enddef
+
+def Test_bufname()
+  split SomeFile
+  bufname('%')->assert_equal('SomeFile')
+  edit OtherFile
+  bufname('#')->assert_equal('SomeFile')
+  close
+enddef
+
+def Test_bufnr()
+  var buf = bufnr()
+  bufnr('%')->assert_equal(buf)
+
+  buf = bufnr('Xdummy', true)
+  buf->assert_notequal(-1)
+  exe 'bwipe! ' .. buf
+enddef
+
+def Test_bufwinid()
+  var origwin = win_getid()
+  below split SomeFile
+  var SomeFileID = win_getid()
+  below split OtherFile
+  below split SomeFile
+  bufwinid('SomeFile')->assert_equal(SomeFileID)
+
+  win_gotoid(origwin)
+  only
+  bwipe SomeFile
+  bwipe OtherFile
+enddef
+
+def Test_call_call()
+  var l = [3, 2, 1]
+  call('reverse', [l])
+  l->assert_equal([1, 2, 3])
+enddef
+
+def Test_char2nr()
+  char2nr('あ', true)->assert_equal(12354)
+enddef
+
+def Test_col()
+  new
+  setline(1, 'asdf')
+  col([1, '$'])->assert_equal(5)
+enddef
+
+def Test_copy_return_type()
+  var l = copy([1, 2, 3])
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(6)
+
+  var dl = deepcopy([1, 2, 3])
+  res = 0
+  for n in dl
+    res += n
+  endfor
+  res->assert_equal(6)
+
+  dl = deepcopy([1, 2, 3], true)
+enddef
+
+def Test_count()
+  count('ABC ABC ABC', 'b', true)->assert_equal(3)
+  count('ABC ABC ABC', 'b', false)->assert_equal(0)
+enddef
+
+def Test_expand()
+  split SomeFile
+  expand('%', true, true)->assert_equal(['SomeFile'])
+  close
+enddef
+
+def Test_extend_return_type()
+  var l = extend([1, 2], [3])
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(6)
+enddef
+
+
+def Wrong_dict_key_type(items: list<number>): list<number>
+  return filter(items, {_, val -> get({val: 1}, 'x')})
+enddef
+
+def Test_filter_wrong_dict_key_type()
+  assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
+enddef
+
+def Test_filter_return_type()
+  var l = filter([1, 2, 3], {-> 1})
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(6)
+enddef
+
+
+def Test_garbagecollect()
+  garbagecollect(true)
+enddef
+
+def Test_getbufinfo()
+  var bufinfo = getbufinfo(bufnr())
+  getbufinfo('%')->assert_equal(bufinfo)
+
+  edit Xtestfile1
+  hide edit Xtestfile2
+  hide enew
+  getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
+      ->len()->assert_equal(3)
+  bwipe Xtestfile1 Xtestfile2
+enddef
+
+def Test_getbufline()
+  e SomeFile
+  var buf = bufnr()
+  e #
+  var lines = ['aaa', 'bbb', 'ccc']
+  setbufline(buf, 1, lines)
+  getbufline('#', 1, '$')->assert_equal(lines)
+
+  bwipe!
+enddef
+
+def Test_getchangelist()
+  new
+  setline(1, 'some text')
+  var changelist = bufnr()->getchangelist()
+  getchangelist('%')->assert_equal(changelist)
+  bwipe!
+enddef
+
+def Test_getchar()
+  while getchar(0)
+  endwhile
+  getchar(true)->assert_equal(0)
+enddef
+
+def Test_getcompletion()
+  set wildignore=*.vim,*~
+  var l = getcompletion('run', 'file', true)
+  l->assert_equal([])
+  set wildignore&
+enddef
+
+def Test_getloclist_return_type()
+  var l = getloclist(1)
+  l->assert_equal([])
+
+  var d = getloclist(1, #{items: 0})
+  d->assert_equal(#{items: []})
+enddef
+
+def Test_getqflist_return_type()
+  var l = getqflist()
+  l->assert_equal([])
+
+  var d = getqflist(#{items: 0})
+  d->assert_equal(#{items: []})
+enddef
+
+def Test_getreg()
+  var lines = ['aaa', 'bbb', 'ccc']
+  setreg('a', lines)
+  getreg('a', true, true)->assert_equal(lines)
+enddef
+
+def Test_getreg_return_type()
+  var s1: string = getreg('"')
+  var s2: string = getreg('"', 1)
+  var s3: list<string> = getreg('"', 1, 1)
+enddef
+
+def Test_glob()
+  glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
+enddef
+
+def Test_globpath()
+  globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
+enddef
+
+def Test_has()
+  has('eval', true)->assert_equal(1)
+enddef
+
+def Test_hasmapto()
+  hasmapto('foobar', 'i', true)->assert_equal(0)
+  iabbrev foo foobar
+  hasmapto('foobar', 'i', true)->assert_equal(1)
+  iunabbrev foo
+enddef
+
+def Test_index()
+  index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
+enddef
+
+def Test_insert_return_type()
+  var l = insert([2, 1], 3)
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(6)
+enddef
+
+def Test_keys_return_type()
+  const var: list<string> = #{a: 1, b: 2}->keys()
+  var->assert_equal(['a', 'b'])
+enddef
+
+def Test_list2str_str2list_utf8()
+  var s = "\u3042\u3044"
+  var l = [0x3042, 0x3044]
+  str2list(s, true)->assert_equal(l)
+  list2str(l, true)->assert_equal(s)
+enddef
+
+def SID(): number
+  return expand('<SID>')
+          ->matchstr('<SNR>\zs\d\+\ze_$')
+          ->str2nr()
+enddef
+
+def Test_maparg()
+  var lnum = str2nr(expand('<sflnum>'))
+  map foo bar
+  maparg('foo', '', false, true)->assert_equal(#{
+        lnum: lnum + 1,
+        script: 0,
+        mode: ' ',
+        silent: 0,
+        noremap: 0,
+        lhs: 'foo',
+        lhsraw: 'foo',
+        nowait: 0,
+        expr: 0,
+        sid: SID(),
+        rhs: 'bar',
+        buffer: 0})
+  unmap foo
+enddef
+
+def Test_mapcheck()
+  iabbrev foo foobar
+  mapcheck('foo', 'i', true)->assert_equal('foobar')
+  iunabbrev foo
+enddef
+
+def Test_maparg_mapset()
+  nnoremap <F3> :echo "hit F3"<CR>
+  var mapsave = maparg('<F3>', 'n', false, true)
+  mapset('n', false, mapsave)
+
+  nunmap <F3>
+enddef
+
+def Test_nr2char()
+  nr2char(97, true)->assert_equal('a')
+enddef
+
+def Test_readdir()
+   eval expand('sautest')->readdir({e -> e[0] !=# '.'})
+   eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
+enddef
+
+def Test_remove_return_type()
+  var l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(3)
+enddef
+
+def Test_reverse_return_type()
+  var l = reverse([1, 2, 3])
+  var res = 0
+  for n in l
+    res += n
+  endfor
+  res->assert_equal(6)
+enddef
+
+def Test_search()
+  new
+  setline(1, ['foo', 'bar'])
+  var val = 0
+  # skip expr returns boolean
+  search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
+  :1
+  search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
+  # skip expr returns number, only 0 and 1 are accepted
+  :1
+  search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
+  :1
+  search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
+  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
+  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
+enddef
+
+def Test_searchcount()
+  new
+  setline(1, "foo bar")
+  :/foo
+  searchcount(#{recompute: true})
+      ->assert_equal(#{
+          exact_match: 1,
+          current: 1,
+          total: 1,
+          maxcount: 99,
+          incomplete: 0})
+  bwipe!
+enddef
+
+def Test_searchdecl()
+  searchdecl('blah', true, true)->assert_equal(1)
+enddef
+
+def Test_setbufvar()
+  setbufvar(bufnr('%'), '&syntax', 'vim')
+  &syntax->assert_equal('vim')
+  setbufvar(bufnr('%'), '&ts', 16)
+  &ts->assert_equal(16)
+  settabwinvar(1, 1, '&syntax', 'vam')
+  &syntax->assert_equal('vam')
+  settabwinvar(1, 1, '&ts', 15)
+  &ts->assert_equal(15)
+  setlocal ts=8
+
+  setbufvar('%', 'myvar', 123)
+  getbufvar('%', 'myvar')->assert_equal(123)
+enddef
+
+def Test_setloclist()
+  var items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
+  var what = #{items: items}
+  setqflist([], ' ', what)
+  setloclist(0, [], ' ', what)
+enddef
+
+def Test_setreg()
+  setreg('a', ['aaa', 'bbb', 'ccc'])
+  var reginfo = getreginfo('a')
+  setreg('a', reginfo)
+  getreginfo('a')->assert_equal(reginfo)
+enddef 
+
+def Test_spellsuggest()
+  if !has('spell')
+    MissingFeature 'spell'
+  else
+    spellsuggest('marrch', 1, true)->assert_equal(['March'])
+  endif
+enddef
+
+def Test_sort_return_type()
+  var res: list<number>
+  res = [1, 2, 3]->sort()
+enddef
+
+def Test_sort_argument()
+  var res = ['b', 'a', 'c']->sort('i')
+  res->assert_equal(['a', 'b', 'c'])
+enddef
+
+def Test_split()
+  split('  aa  bb  ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
+enddef
+
+def Test_str2nr()
+  str2nr("1'000'000", 10, true)->assert_equal(1000000)
+enddef
+
+def Test_strchars()
+  strchars("A\u20dd", true)->assert_equal(1)
+enddef
+
+def Test_submatch()
+  var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
+  var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
+  var actual = substitute('A123456789', pat, Rep, '')
+  var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
+  actual->assert_equal(expected)
+enddef
+
+def Test_synID()
+  new
+  setline(1, "text")
+  synID(1, 1, true)->assert_equal(0)
+  bwipe!
+enddef
+
+def Test_term_gettty()
+  if !has('terminal')
+    MissingFeature 'terminal'
+  else
+    var buf = Run_shell_in_terminal({})
+    term_gettty(buf, true)->assert_notequal('')
+    StopShellInTerminal(buf)
+  endif
+enddef
+
+def Test_term_start()
+  if !has('terminal')
+    MissingFeature 'terminal'
+  else
+    botright new
+    var winnr = winnr()
+    term_start(&shell, #{curwin: true})
+    winnr()->assert_equal(winnr)
+    bwipe!
+  endif
+enddef
+
+def Test_timer_paused()
+  var id = timer_start(50, {-> 0})
+  timer_pause(id, true)
+  var info = timer_info(id)
+  info[0]['paused']->assert_equal(1)
+  timer_stop(id)
+enddef
+
+def Test_win_splitmove()
+  split
+  win_splitmove(1, 2, #{vertical: true, rightbelow: true})
+  close
+enddef
+
+
+" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -459,12 +459,6 @@ def Test_call_def_varargs()
   CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
 enddef
 
-def Test_call_call()
-  var l = [3, 2, 1]
-  call('reverse', [l])
-  l->assert_equal([1, 2, 3])
-enddef
-
 let s:value = ''
 
 def FuncOneDefArg(opt = 'text')
@@ -944,66 +938,6 @@ def Test_vim9script_func()
   delete('XVim9Func')
 enddef
 
-" Test for internal functions returning different types
-func Test_InternalFuncRetType()
-  let lines =<< trim END
-    def RetFloat(): float
-      return ceil(1.456)
-    enddef
-
-    def RetListAny(): list<any>
-      return items({'k': 'v'})
-    enddef
-
-    def RetListString(): list<string>
-      return split('a:b:c', ':')
-    enddef
-
-    def RetListDictAny(): list<dict<any>>
-      return getbufinfo()
-    enddef
-
-    def RetDictNumber(): dict<number>
-      return wordcount()
-    enddef
-
-    def RetDictString(): dict<string>
-      return environ()
-    enddef
-  END
-  call writefile(lines, 'Xscript')
-  source Xscript
-
-  call RetFloat()->assert_equal(2.0)
-  call RetListAny()->assert_equal([['k', 'v']])
-  call RetListString()->assert_equal(['a', 'b', 'c'])
-  call RetListDictAny()->assert_notequal([])
-  call RetDictNumber()->assert_notequal({})
-  call RetDictString()->assert_notequal({})
-  call delete('Xscript')
-endfunc
-
-" Test for passing too many or too few arguments to internal functions
-func Test_internalfunc_arg_error()
-  let l =<< trim END
-    def! FArgErr(): float
-      return ceil(1.1, 2)
-    enddef
-    defcompile
-  END
-  call writefile(l, 'Xinvalidarg')
-  call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
-  let l =<< trim END
-    def! FArgErr(): float
-      return ceil()
-    enddef
-    defcompile
-  END
-  call writefile(l, 'Xinvalidarg')
-  call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
-  call delete('Xinvalidarg')
-endfunc
-
 let s:funcResult = 0
 
 def FuncNoArgNoRet()
@@ -1481,137 +1415,6 @@ def Test_nested_lambda()
   CheckScriptSuccess(lines)
 enddef
 
-def Test_sort_return_type()
-  var res: list<number>
-  res = [1, 2, 3]->sort()
-enddef
-
-def Test_sort_argument()
-  var res = ['b', 'a', 'c']->sort('i')
-  res->assert_equal(['a', 'b', 'c'])
-enddef
-
-def Test_getqflist_return_type()
-  var l = getqflist()
-  l->assert_equal([])
-
-  var d = getqflist(#{items: 0})
-  d->assert_equal(#{items: []})
-enddef
-
-def Test_getloclist_return_type()
-  var l = getloclist(1)
-  l->assert_equal([])
-
-  var d = getloclist(1, #{items: 0})
-  d->assert_equal(#{items: []})
-enddef
-
-def Test_copy_return_type()
-  var l = copy([1, 2, 3])
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(6)
-
-  var dl = deepcopy([1, 2, 3])
-  res = 0
-  for n in dl
-    res += n
-  endfor
-  res->assert_equal(6)
-
-  dl = deepcopy([1, 2, 3], true)
-enddef
-
-def Test_extend_return_type()
-  var l = extend([1, 2], [3])
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(6)
-enddef
-
-def Test_garbagecollect()
-  garbagecollect(true)
-enddef
-
-def Test_insert_return_type()
-  var l = insert([2, 1], 3)
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(6)
-enddef
-
-def Test_keys_return_type()
-  const var: list<string> = #{a: 1, b: 2}->keys()
-  var->assert_equal(['a', 'b'])
-enddef
-
-def Test_reverse_return_type()
-  var l = reverse([1, 2, 3])
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(6)
-enddef
-
-def Test_remove_return_type()
-  var l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(3)
-enddef
-
-def Test_filter_return_type()
-  var l = filter([1, 2, 3], {-> 1})
-  var res = 0
-  for n in l
-    res += n
-  endfor
-  res->assert_equal(6)
-enddef
-
-def Test_bufnr()
-  var buf = bufnr()
-  bufnr('%')->assert_equal(buf)
-
-  buf = bufnr('Xdummy', true)
-  buf->assert_notequal(-1)
-  exe 'bwipe! ' .. buf
-enddef
-
-def Test_col()
-  new
-  setline(1, 'asdf')
-  col([1, '$'])->assert_equal(5)
-enddef
-
-def Test_char2nr()
-  char2nr('あ', true)->assert_equal(12354)
-enddef
-
-def Test_getreg_return_type()
-  var s1: string = getreg('"')
-  var s2: string = getreg('"', 1)
-  var s3: list<string> = getreg('"', 1, 1)
-enddef
-
-def Wrong_dict_key_type(items: list<number>): list<number>
-  return filter(items, {_, val -> get({val: 1}, 'x')})
-enddef
-
-def Test_wrong_dict_key_type()
-  assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
-enddef
-
 def Line_continuation_in_def(dir: string = ''): string
   var path: string = empty(dir)
           \ ? 'empty'
@@ -1657,346 +1460,6 @@ func Test_silent_echo()
   call delete('XTest_silent_echo')
 endfunc
 
-""""""" builtin functions that behave differently in Vim9
-
-def Test_bufname()
-  split SomeFile
-  bufname('%')->assert_equal('SomeFile')
-  edit OtherFile
-  bufname('#')->assert_equal('SomeFile')
-  close
-enddef
-
-def Test_bufwinid()
-  var origwin = win_getid()
-  below split SomeFile
-  var SomeFileID = win_getid()
-  below split OtherFile
-  below split SomeFile
-  bufwinid('SomeFile')->assert_equal(SomeFileID)
-
-  win_gotoid(origwin)
-  only
-  bwipe SomeFile
-  bwipe OtherFile
-enddef
-
-def Test_count()
-  count('ABC ABC ABC', 'b', true)->assert_equal(3)
-  count('ABC ABC ABC', 'b', false)->assert_equal(0)
-enddef
-
-def Test_expand()
-  split SomeFile
-  expand('%', true, true)->assert_equal(['SomeFile'])
-  close
-enddef
-
-def Test_getbufinfo()
-  var bufinfo = getbufinfo(bufnr())
-  getbufinfo('%')->assert_equal(bufinfo)
-
-  edit Xtestfile1
-  hide edit Xtestfile2
-  hide enew
-  getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
-      ->len()->assert_equal(3)
-  bwipe Xtestfile1 Xtestfile2
-enddef
-
-def Test_getbufline()
-  e SomeFile
-  var buf = bufnr()
-  e #
-  var lines = ['aaa', 'bbb', 'ccc']
-  setbufline(buf, 1, lines)
-  getbufline('#', 1, '$')->assert_equal(lines)
-
-  bwipe!
-enddef
-
-def Test_getchangelist()
-  new
-  setline(1, 'some text')
-  var changelist = bufnr()->getchangelist()
-  getchangelist('%')->assert_equal(changelist)
-  bwipe!
-enddef
-
-def Test_getchar()
-  while getchar(0)
-  endwhile
-  getchar(true)->assert_equal(0)
-enddef
-
-def Test_getcompletion()
-  set wildignore=*.vim,*~
-  var l = getcompletion('run', 'file', true)
-  l->assert_equal([])
-  set wildignore&
-enddef
-
-def Test_getreg()
-  var lines = ['aaa', 'bbb', 'ccc']
-  setreg('a', lines)
-  getreg('a', true, true)->assert_equal(lines)
-enddef
-
-def Test_glob()
-  glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
-enddef
-
-def Test_globpath()
-  globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
-enddef
-
-def Test_has()
-  has('eval', true)->assert_equal(1)
-enddef
-
-def Test_hasmapto()
-  hasmapto('foobar', 'i', true)->assert_equal(0)
-  iabbrev foo foobar
-  hasmapto('foobar', 'i', true)->assert_equal(1)
-  iunabbrev foo
-enddef
-
-def Test_index()
-  index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
-enddef
-
-def Test_list2str_str2list_utf8()
-  var s = "\u3042\u3044"
-  var l = [0x3042, 0x3044]
-  str2list(s, true)->assert_equal(l)
-  list2str(l, true)->assert_equal(s)
-enddef
-
-def Test_list_add()
-  var l: list<number>  # defaults to empty list
-  add(l, 9)
-  assert_equal([9], l)
-
-  var lines =<< trim END
-      var l: list<number>
-      add(l, "x")
-  END
-  CheckDefFailure(lines, 'E1012:', 2)
-
-  lines =<< trim END
-      var l: list<number> = test_null_list()
-      add(l, 123)
-  END
-  CheckDefExecFailure(lines, 'E1130:', 2)
-enddef
-
-def Test_blob_add()
-  var b1: blob = 0z12
-  add(b1, 0x34)
-  assert_equal(0z1234, b1)
-
-  var b2: blob # defaults to empty blob
-  add(b2, 0x67)
-  assert_equal(0z67, b2)
-
-  var lines =<< trim END
-      var b: blob
-      add(b, "x")
-  END
-  CheckDefFailure(lines, 'E1012:', 2)
-
-  lines =<< trim END
-      var b: blob = test_null_blob()
-      add(b, 123)
-  END
-  CheckDefExecFailure(lines, 'E1131:', 2)
-enddef
-
-def SID(): number
-  return expand('<SID>')
-          ->matchstr('<SNR>\zs\d\+\ze_$')
-          ->str2nr()
-enddef
-
-def Test_maparg()
-  var lnum = str2nr(expand('<sflnum>'))
-  map foo bar
-  maparg('foo', '', false, true)->assert_equal(#{
-        lnum: lnum + 1,
-        script: 0,
-        mode: ' ',
-        silent: 0,
-        noremap: 0,
-        lhs: 'foo',
-        lhsraw: 'foo',
-        nowait: 0,
-        expr: 0,
-        sid: SID(),
-        rhs: 'bar',
-        buffer: 0})
-  unmap foo
-enddef
-
-def Test_mapcheck()
-  iabbrev foo foobar
-  mapcheck('foo', 'i', true)->assert_equal('foobar')
-  iunabbrev foo
-enddef
-
-def Test_maparg_mapset()
-  nnoremap <F3> :echo "hit F3"<CR>
-  var mapsave = maparg('<F3>', 'n', false, true)
-  mapset('n', false, mapsave)
-
-  nunmap <F3>
-enddef
-
-def Test_nr2char()
-  nr2char(97, true)->assert_equal('a')
-enddef
-
-def Test_readdir()
-   eval expand('sautest')->readdir({e -> e[0] !=# '.'})
-   eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
-enddef
-
-def Test_search()
-  new
-  setline(1, ['foo', 'bar'])
-  var val = 0
-  # skip expr returns boolean
-  search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
-  :1
-  search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
-  # skip expr returns number, only 0 and 1 are accepted
-  :1
-  search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
-  :1
-  search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
-  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
-  assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
-enddef
-
-def Test_searchcount()
-  new
-  setline(1, "foo bar")
-  :/foo
-  searchcount(#{recompute: true})
-      ->assert_equal(#{
-          exact_match: 1,
-          current: 1,
-          total: 1,
-          maxcount: 99,
-          incomplete: 0})
-  bwipe!
-enddef
-
-def Test_searchdecl()
-  searchdecl('blah', true, true)->assert_equal(1)
-enddef
-
-def Test_setbufvar()
-  setbufvar(bufnr('%'), '&syntax', 'vim')
-  &syntax->assert_equal('vim')
-  setbufvar(bufnr('%'), '&ts', 16)
-  &ts->assert_equal(16)
-  settabwinvar(1, 1, '&syntax', 'vam')
-  &syntax->assert_equal('vam')
-  settabwinvar(1, 1, '&ts', 15)
-  &ts->assert_equal(15)
-  setlocal ts=8
-
-  setbufvar('%', 'myvar', 123)
-  getbufvar('%', 'myvar')->assert_equal(123)
-enddef
-
-def Test_setloclist()
-  var items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
-  var what = #{items: items}
-  setqflist([], ' ', what)
-  setloclist(0, [], ' ', what)
-enddef
-
-def Test_setreg()
-  setreg('a', ['aaa', 'bbb', 'ccc'])
-  var reginfo = getreginfo('a')
-  setreg('a', reginfo)
-  getreginfo('a')->assert_equal(reginfo)
-enddef 
-
-def Test_spellsuggest()
-  if !has('spell')
-    MissingFeature 'spell'
-  else
-    spellsuggest('marrch', 1, true)->assert_equal(['March'])
-  endif
-enddef
-
-def Test_split()
-  split('  aa  bb  ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
-enddef
-
-def Test_str2nr()
-  str2nr("1'000'000", 10, true)->assert_equal(1000000)
-enddef
-
-def Test_strchars()
-  strchars("A\u20dd", true)->assert_equal(1)
-enddef
-
-def Test_submatch()
-  var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
-  var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
-  var actual = substitute('A123456789', pat, Rep, '')
-  var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
-  actual->assert_equal(expected)
-enddef
-
-def Test_synID()
-  new
-  setline(1, "text")
-  synID(1, 1, true)->assert_equal(0)
-  bwipe!
-enddef
-
-def Test_term_gettty()
-  if !has('terminal')
-    MissingFeature 'terminal'
-  else
-    var buf = Run_shell_in_terminal({})
-    term_gettty(buf, true)->assert_notequal('')
-    StopShellInTerminal(buf)
-  endif
-enddef
-
-def Test_term_start()
-  if !has('terminal')
-    MissingFeature 'terminal'
-  else
-    botright new
-    var winnr = winnr()
-    term_start(&shell, #{curwin: true})
-    winnr()->assert_equal(winnr)
-    bwipe!
-  endif
-enddef
-
-def Test_timer_paused()
-  var id = timer_start(50, {-> 0})
-  timer_pause(id, true)
-  var info = timer_info(id)
-  info[0]['paused']->assert_equal(1)
-  timer_stop(id)
-enddef
-
-def Test_win_splitmove()
-  split
-  win_splitmove(1, 2, #{vertical: true, rightbelow: true})
-  close
-enddef
-
-""""""" end of builtin functions
-
 def Fibonacci(n: number): number
   if n < 2
     return n
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1876,
+/**/
     1875,
 /**/
     1874,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1460,8 +1460,7 @@ generate_BCALL(cctx_T *cctx, int func_id
     isn_T	*isn;
     garray_T	*stack = &cctx->ctx_type_stack;
     int		argoff;
-    type_T	*argtypes[MAX_FUNC_ARGS];
-    int		i;
+    type_T	**argtypes;
 
     RETURN_OK_IF_SKIP(cctx);
     argoff = check_internal_func(func_idx, argcount);
@@ -1476,20 +1475,24 @@ generate_BCALL(cctx_T *cctx, int func_id
 	isn->isn_arg.shuffle.shfl_up = argoff - 1;
     }
 
+    // Check the types of the arguments.
+    argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
+    if (argcount > 0 && internal_func_check_arg_types(
+					*argtypes, func_idx, argcount) == FAIL)
+	    return FAIL;
+
     if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL)
 	return FAIL;
     isn->isn_arg.bfunc.cbf_idx = func_idx;
     isn->isn_arg.bfunc.cbf_argcount = argcount;
 
-    for (i = 0; i < argcount; ++i)
-	argtypes[i] = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
-
-    stack->ga_len -= argcount; // drop the arguments
+    // Drop the argument types and push the return type.
+    stack->ga_len -= argcount;
     if (ga_grow(stack, 1) == FAIL)
 	return FAIL;
     ((type_T **)stack->ga_data)[stack->ga_len] =
 			  internal_func_ret_type(func_idx, argcount, argtypes);
-    ++stack->ga_len;	    // add return value
+    ++stack->ga_len;
 
     return OK;
 }