mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.2.0823: Vim9: script reload test is disabled
Problem: Vim9: script reload test is disabled. Solution: Compile a function in the context of the script where it was defined. Set execution stack for compiled function. Add a test that an error is reported for the right file/function.
This commit is contained in:
@@ -634,8 +634,8 @@ do_cmdline(
|
|||||||
int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
|
int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
|
||||||
struct dbg_stuff debug_saved; // saved things for debug mode
|
struct dbg_stuff debug_saved; // saved things for debug mode
|
||||||
int initial_trylevel;
|
int initial_trylevel;
|
||||||
struct msglist **saved_msg_list = NULL;
|
msglist_T **saved_msg_list = NULL;
|
||||||
struct msglist *private_msg_list;
|
msglist_T *private_msg_list;
|
||||||
|
|
||||||
// "fgetline" and "cookie" passed to do_one_cmd()
|
// "fgetline" and "cookie" passed to do_one_cmd()
|
||||||
char_u *(*cmd_getline)(int, void *, int, int);
|
char_u *(*cmd_getline)(int, void *, int, int);
|
||||||
@@ -1238,7 +1238,7 @@ do_cmdline(
|
|||||||
if (did_throw)
|
if (did_throw)
|
||||||
{
|
{
|
||||||
void *p = NULL;
|
void *p = NULL;
|
||||||
struct msglist *messages = NULL, *next;
|
msglist_T *messages = NULL, *next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the uncaught exception is a user exception, report it as an
|
* If the uncaught exception is a user exception, report it as an
|
||||||
|
@@ -146,8 +146,8 @@ cause_errthrow(
|
|||||||
int severe,
|
int severe,
|
||||||
int *ignore)
|
int *ignore)
|
||||||
{
|
{
|
||||||
struct msglist *elem;
|
msglist_T *elem;
|
||||||
struct msglist **plist;
|
msglist_T **plist;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do nothing when displaying the interrupt message or reporting an
|
* Do nothing when displaying the interrupt message or reporting an
|
||||||
@@ -251,7 +251,7 @@ cause_errthrow(
|
|||||||
while (*plist != NULL)
|
while (*plist != NULL)
|
||||||
plist = &(*plist)->next;
|
plist = &(*plist)->next;
|
||||||
|
|
||||||
elem = ALLOC_ONE(struct msglist);
|
elem = ALLOC_CLEAR_ONE(msglist_T);
|
||||||
if (elem == NULL)
|
if (elem == NULL)
|
||||||
{
|
{
|
||||||
suppress_errthrow = TRUE;
|
suppress_errthrow = TRUE;
|
||||||
@@ -287,6 +287,11 @@ cause_errthrow(
|
|||||||
else
|
else
|
||||||
(*msg_list)->throw_msg = tmsg;
|
(*msg_list)->throw_msg = tmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the source name and lnum now, it may change before
|
||||||
|
// reaching do_errthrow().
|
||||||
|
elem->sfile = estack_sfile();
|
||||||
|
elem->slnum = SOURCING_LNUM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,15 +303,16 @@ cause_errthrow(
|
|||||||
* Free a "msg_list" and the messages it contains.
|
* Free a "msg_list" and the messages it contains.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
free_msglist(struct msglist *l)
|
free_msglist(msglist_T *l)
|
||||||
{
|
{
|
||||||
struct msglist *messages, *next;
|
msglist_T *messages, *next;
|
||||||
|
|
||||||
messages = l;
|
messages = l;
|
||||||
while (messages != NULL)
|
while (messages != NULL)
|
||||||
{
|
{
|
||||||
next = messages->next;
|
next = messages->next;
|
||||||
vim_free(messages->msg);
|
vim_free(messages->msg);
|
||||||
|
vim_free(messages->sfile);
|
||||||
vim_free(messages);
|
vim_free(messages);
|
||||||
messages = next;
|
messages = next;
|
||||||
}
|
}
|
||||||
@@ -428,7 +434,7 @@ get_exception_string(
|
|||||||
if (type == ET_ERROR)
|
if (type == ET_ERROR)
|
||||||
{
|
{
|
||||||
*should_free = TRUE;
|
*should_free = TRUE;
|
||||||
mesg = ((struct msglist *)value)->throw_msg;
|
mesg = ((msglist_T *)value)->throw_msg;
|
||||||
if (cmdname != NULL && *cmdname != NUL)
|
if (cmdname != NULL && *cmdname != NUL)
|
||||||
{
|
{
|
||||||
cmdlen = (int)STRLEN(cmdname);
|
cmdlen = (int)STRLEN(cmdname);
|
||||||
@@ -526,23 +532,34 @@ throw_exception(void *value, except_type_T type, char_u *cmdname)
|
|||||||
if (type == ET_ERROR)
|
if (type == ET_ERROR)
|
||||||
// Store the original message and prefix the exception value with
|
// Store the original message and prefix the exception value with
|
||||||
// "Vim:" or, if a command name is given, "Vim(cmdname):".
|
// "Vim:" or, if a command name is given, "Vim(cmdname):".
|
||||||
excp->messages = (struct msglist *)value;
|
excp->messages = (msglist_T *)value;
|
||||||
|
|
||||||
excp->value = get_exception_string(value, type, cmdname, &should_free);
|
excp->value = get_exception_string(value, type, cmdname, &should_free);
|
||||||
if (excp->value == NULL && should_free)
|
if (excp->value == NULL && should_free)
|
||||||
goto nomem;
|
goto nomem;
|
||||||
|
|
||||||
excp->type = type;
|
excp->type = type;
|
||||||
excp->throw_name = estack_sfile();
|
if (type == ET_ERROR && ((msglist_T *)value)->sfile != NULL)
|
||||||
if (excp->throw_name == NULL)
|
|
||||||
excp->throw_name = vim_strsave((char_u *)"");
|
|
||||||
if (excp->throw_name == NULL)
|
|
||||||
{
|
{
|
||||||
if (should_free)
|
msglist_T *entry = (msglist_T *)value;
|
||||||
vim_free(excp->value);
|
|
||||||
goto nomem;
|
excp->throw_name = entry->sfile;
|
||||||
|
entry->sfile = NULL;
|
||||||
|
excp->throw_lnum = entry->slnum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
excp->throw_name = estack_sfile();
|
||||||
|
if (excp->throw_name == NULL)
|
||||||
|
excp->throw_name = vim_strsave((char_u *)"");
|
||||||
|
if (excp->throw_name == NULL)
|
||||||
|
{
|
||||||
|
if (should_free)
|
||||||
|
vim_free(excp->value);
|
||||||
|
goto nomem;
|
||||||
|
}
|
||||||
|
excp->throw_lnum = SOURCING_LNUM;
|
||||||
}
|
}
|
||||||
excp->throw_lnum = SOURCING_LNUM;
|
|
||||||
|
|
||||||
if (p_verbose >= 13 || debug_break_level > 0)
|
if (p_verbose >= 13 || debug_break_level > 0)
|
||||||
{
|
{
|
||||||
|
@@ -344,7 +344,7 @@ EXTERN int force_abort INIT(= FALSE);
|
|||||||
* field of a later list element, when the "emsg_severe" flag was set when the
|
* field of a later list element, when the "emsg_severe" flag was set when the
|
||||||
* emsg() call was made.
|
* emsg() call was made.
|
||||||
*/
|
*/
|
||||||
EXTERN struct msglist **msg_list INIT(= NULL);
|
EXTERN msglist_T **msg_list INIT(= NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* suppress_errthrow: When TRUE, don't convert an error to an exception. Used
|
* suppress_errthrow: When TRUE, don't convert an error to an exception. Used
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
/* scriptfile.c */
|
/* scriptfile.c */
|
||||||
void estack_init(void);
|
void estack_init(void);
|
||||||
estack_T *estack_push(etype_T type, char_u *name, long lnum);
|
estack_T *estack_push(etype_T type, char_u *name, long lnum);
|
||||||
void estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum);
|
void estack_push_ufunc(ufunc_T *ufunc, long lnum);
|
||||||
|
int estack_top_is_ufunc(ufunc_T *ufunc, long lnum);
|
||||||
void estack_pop(void);
|
void estack_pop(void);
|
||||||
char_u *estack_sfile(void);
|
char_u *estack_sfile(void);
|
||||||
void ex_runtime(exarg_T *eap);
|
void ex_runtime(exarg_T *eap);
|
||||||
|
@@ -69,14 +69,31 @@ estack_push(etype_T type, char_u *name, long lnum)
|
|||||||
* Add a user function to the execution stack.
|
* Add a user function to the execution stack.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum)
|
estack_push_ufunc(ufunc_T *ufunc, long lnum)
|
||||||
{
|
{
|
||||||
estack_T *entry = estack_push(type,
|
estack_T *entry = estack_push(ETYPE_UFUNC,
|
||||||
ufunc->uf_name_exp != NULL
|
ufunc->uf_name_exp != NULL
|
||||||
? ufunc->uf_name_exp : ufunc->uf_name, lnum);
|
? ufunc->uf_name_exp : ufunc->uf_name, lnum);
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
entry->es_info.ufunc = ufunc;
|
entry->es_info.ufunc = ufunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if "ufunc" with "lnum" is already at the top of the exe stack.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
estack_top_is_ufunc(ufunc_T *ufunc, long lnum)
|
||||||
|
{
|
||||||
|
estack_T *entry;
|
||||||
|
|
||||||
|
if (exestack.ga_len == 0)
|
||||||
|
return FALSE;
|
||||||
|
entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
|
||||||
|
return entry->es_type == ETYPE_UFUNC
|
||||||
|
&& STRCMP( entry->es_name, ufunc->uf_name_exp != NULL
|
||||||
|
? ufunc->uf_name_exp : ufunc->uf_name) == 0
|
||||||
|
&& entry->es_lnum == lnum;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -927,13 +927,16 @@ typedef struct {
|
|||||||
* A list of error messages that can be converted to an exception. "throw_msg"
|
* A list of error messages that can be converted to an exception. "throw_msg"
|
||||||
* is only set in the first element of the list. Usually, it points to the
|
* is only set in the first element of the list. Usually, it points to the
|
||||||
* original message stored in that element, but sometimes it points to a later
|
* original message stored in that element, but sometimes it points to a later
|
||||||
* message in the list. See cause_errthrow() below.
|
* message in the list. See cause_errthrow().
|
||||||
*/
|
*/
|
||||||
|
typedef struct msglist msglist_T;
|
||||||
struct msglist
|
struct msglist
|
||||||
{
|
{
|
||||||
char *msg; // original message
|
char *msg; // original message, allocated
|
||||||
char *throw_msg; // msg to throw: usually original one
|
char *throw_msg; // msg to throw: usually original one
|
||||||
struct msglist *next; // next of several messages in a row
|
char_u *sfile; // value from estack_sfile(), allocated
|
||||||
|
long slnum; // line number for "sfile"
|
||||||
|
msglist_T *next; // next of several messages in a row
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1516,6 +1519,7 @@ struct blobvar_S
|
|||||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||||
typedef struct funccall_S funccall_T;
|
typedef struct funccall_S funccall_T;
|
||||||
|
|
||||||
|
// values used for "uf_dfunc_idx"
|
||||||
# define UF_NOT_COMPILED -2
|
# define UF_NOT_COMPILED -2
|
||||||
# define UF_TO_BE_COMPILED -1
|
# define UF_TO_BE_COMPILED -1
|
||||||
|
|
||||||
|
@@ -745,9 +745,6 @@ def Test_vim9script_fails()
|
|||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_vim9script_reload_import()
|
def Test_vim9script_reload_import()
|
||||||
" TODO: make it work to compile when not in the script context anymore
|
|
||||||
return
|
|
||||||
|
|
||||||
let lines =<< trim END
|
let lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
const var = ''
|
const var = ''
|
||||||
@@ -797,9 +794,6 @@ def Test_vim9script_reload_import()
|
|||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_vim9script_reload_delfunc()
|
def Test_vim9script_reload_delfunc()
|
||||||
" TODO: make it work to compile when not in the script context anymore
|
|
||||||
return
|
|
||||||
|
|
||||||
let first_lines =<< trim END
|
let first_lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
def FuncYes(): string
|
def FuncYes(): string
|
||||||
@@ -920,6 +914,37 @@ def Test_import_rtp()
|
|||||||
delete('import', 'rf')
|
delete('import', 'rf')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_import_compile_error()
|
||||||
|
let export_lines = [
|
||||||
|
'vim9script',
|
||||||
|
'export def ExpFunc(): string',
|
||||||
|
' return notDefined',
|
||||||
|
'enddef',
|
||||||
|
]
|
||||||
|
writefile(export_lines, 'Xexported.vim')
|
||||||
|
|
||||||
|
let import_lines = [
|
||||||
|
'vim9script',
|
||||||
|
'import ExpFunc from "./Xexported.vim"',
|
||||||
|
'def ImpFunc()',
|
||||||
|
' echo ExpFunc()',
|
||||||
|
'enddef',
|
||||||
|
'defcompile',
|
||||||
|
]
|
||||||
|
writefile(import_lines, 'Ximport.vim')
|
||||||
|
|
||||||
|
try
|
||||||
|
source Ximport.vim
|
||||||
|
catch /E1001/
|
||||||
|
" Error should be fore the Xexported.vim file.
|
||||||
|
assert_match('E1001: variable not found: notDefined', v:exception)
|
||||||
|
assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
delete('Xexported.vim')
|
||||||
|
delete('Ximport.vim')
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_fixed_size_list()
|
def Test_fixed_size_list()
|
||||||
" will be allocated as one piece of memory, check that changes work
|
" will be allocated as one piece of memory, check that changes work
|
||||||
let l = [1, 2, 3, 4]
|
let l = [1, 2, 3, 4]
|
||||||
|
@@ -1114,11 +1114,11 @@ call_user_func(
|
|||||||
|
|
||||||
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||||
{
|
{
|
||||||
estack_push_ufunc(ETYPE_UFUNC, fp, 1);
|
estack_push_ufunc(fp, 1);
|
||||||
save_current_sctx = current_sctx;
|
save_current_sctx = current_sctx;
|
||||||
current_sctx = fp->uf_script_ctx;
|
current_sctx = fp->uf_script_ctx;
|
||||||
|
|
||||||
// Execute the compiled function.
|
// Execute the function, possibly compiling it first.
|
||||||
call_def_function(fp, argcount, argvars, funcexe->partial, rettv);
|
call_def_function(fp, argcount, argvars, funcexe->partial, rettv);
|
||||||
--depth;
|
--depth;
|
||||||
current_funccal = fc->caller;
|
current_funccal = fc->caller;
|
||||||
@@ -1288,7 +1288,7 @@ call_user_func(
|
|||||||
++sandbox;
|
++sandbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
estack_push_ufunc(ETYPE_UFUNC, fp, 1);
|
estack_push_ufunc(fp, 1);
|
||||||
ESTACK_CHECK_SETUP
|
ESTACK_CHECK_SETUP
|
||||||
if (p_verbose >= 12)
|
if (p_verbose >= 12)
|
||||||
{
|
{
|
||||||
|
@@ -746,6 +746,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
823,
|
||||||
/**/
|
/**/
|
||||||
822,
|
822,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -2323,8 +2323,7 @@ next_line_from_context(cctx_T *cctx)
|
|||||||
}
|
}
|
||||||
line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
|
line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
|
||||||
cctx->ctx_line_start = line;
|
cctx->ctx_line_start = line;
|
||||||
SOURCING_LNUM = cctx->ctx_ufunc->uf_script_ctx.sc_lnum
|
SOURCING_LNUM = cctx->ctx_lnum + 1;
|
||||||
+ cctx->ctx_lnum + 1;
|
|
||||||
} while (line == NULL || *skipwhite(line) == NUL);
|
} while (line == NULL || *skipwhite(line) == NUL);
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
@@ -6349,14 +6348,15 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
|||||||
int called_emsg_before = called_emsg;
|
int called_emsg_before = called_emsg;
|
||||||
int ret = FAIL;
|
int ret = FAIL;
|
||||||
sctx_T save_current_sctx = current_sctx;
|
sctx_T save_current_sctx = current_sctx;
|
||||||
|
int do_estack_push;
|
||||||
int emsg_before = called_emsg;
|
int emsg_before = called_emsg;
|
||||||
|
|
||||||
|
// When using a function that was compiled before: Free old instructions.
|
||||||
|
// Otherwise add a new entry in "def_functions".
|
||||||
if (ufunc->uf_dfunc_idx >= 0)
|
if (ufunc->uf_dfunc_idx >= 0)
|
||||||
{
|
{
|
||||||
// Redefining a function that was compiled before.
|
|
||||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||||
+ ufunc->uf_dfunc_idx;
|
+ ufunc->uf_dfunc_idx;
|
||||||
// Free old instructions.
|
|
||||||
delete_def_function_contents(dfunc);
|
delete_def_function_contents(dfunc);
|
||||||
}
|
}
|
||||||
else if (add_def_function(ufunc) == FAIL)
|
else if (add_def_function(ufunc) == FAIL)
|
||||||
@@ -6373,9 +6373,17 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
|||||||
ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
|
ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
|
||||||
instr = &cctx.ctx_instr;
|
instr = &cctx.ctx_instr;
|
||||||
|
|
||||||
// Most modern script version.
|
// Set the context to the function, it may be compiled when called from
|
||||||
|
// another script. Set the script version to the most modern one.
|
||||||
|
// The line number will be set in next_line_from_context().
|
||||||
|
current_sctx = ufunc->uf_script_ctx;
|
||||||
current_sctx.sc_version = SCRIPT_VERSION_VIM9;
|
current_sctx.sc_version = SCRIPT_VERSION_VIM9;
|
||||||
|
|
||||||
|
// Make sure error messages are OK.
|
||||||
|
do_estack_push = !estack_top_is_ufunc(ufunc, 1);
|
||||||
|
if (do_estack_push)
|
||||||
|
estack_push_ufunc(ufunc, 1);
|
||||||
|
|
||||||
if (ufunc->uf_def_args.ga_len > 0)
|
if (ufunc->uf_def_args.ga_len > 0)
|
||||||
{
|
{
|
||||||
int count = ufunc->uf_def_args.ga_len;
|
int count = ufunc->uf_def_args.ga_len;
|
||||||
@@ -6795,6 +6803,9 @@ erret:
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_sctx = save_current_sctx;
|
current_sctx = save_current_sctx;
|
||||||
|
if (do_estack_push)
|
||||||
|
estack_pop();
|
||||||
|
|
||||||
free_imported(&cctx);
|
free_imported(&cctx);
|
||||||
free_locals(&cctx);
|
free_locals(&cctx);
|
||||||
ga_clear(&cctx.ctx_type_stack);
|
ga_clear(&cctx.ctx_type_stack);
|
||||||
|
@@ -230,7 +230,7 @@ call_dfunc(int cdf_idx, int argcount_arg, ectx_T *ectx)
|
|||||||
// Set execution state to the start of the called function.
|
// Set execution state to the start of the called function.
|
||||||
ectx->ec_dfunc_idx = cdf_idx;
|
ectx->ec_dfunc_idx = cdf_idx;
|
||||||
ectx->ec_instr = dfunc->df_instr;
|
ectx->ec_instr = dfunc->df_instr;
|
||||||
estack_push_ufunc(ETYPE_UFUNC, dfunc->df_ufunc, 1);
|
estack_push_ufunc(dfunc->df_ufunc, 1);
|
||||||
|
|
||||||
// Decide where to start execution, handles optional arguments.
|
// Decide where to start execution, handles optional arguments.
|
||||||
init_instr_idx(ufunc, argcount, ectx);
|
init_instr_idx(ufunc, argcount, ectx);
|
||||||
@@ -656,6 +656,7 @@ call_def_function(
|
|||||||
int defcount = ufunc->uf_args.ga_len - argc;
|
int defcount = ufunc->uf_args.ga_len - argc;
|
||||||
int save_sc_version = current_sctx.sc_version;
|
int save_sc_version = current_sctx.sc_version;
|
||||||
int breakcheck_count = 0;
|
int breakcheck_count = 0;
|
||||||
|
int called_emsg_before = called_emsg;
|
||||||
|
|
||||||
// Get pointer to item in the stack.
|
// Get pointer to item in the stack.
|
||||||
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
|
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
|
||||||
@@ -673,7 +674,13 @@ call_def_function(
|
|||||||
if (ufunc->uf_dfunc_idx == UF_NOT_COMPILED
|
if (ufunc->uf_dfunc_idx == UF_NOT_COMPILED
|
||||||
|| (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
|| (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
||||||
&& compile_def_function(ufunc, FALSE, NULL) == FAIL))
|
&& compile_def_function(ufunc, FALSE, NULL) == FAIL))
|
||||||
|
{
|
||||||
|
if (called_emsg == called_emsg_before)
|
||||||
|
semsg(_("E1091: Function is not compiled: %s"),
|
||||||
|
ufunc->uf_name_exp == NULL
|
||||||
|
? ufunc->uf_name : ufunc->uf_name_exp);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Check the function was really compiled.
|
// Check the function was really compiled.
|
||||||
|
Reference in New Issue
Block a user