mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.2742: Vim9: when compiling a function fails it is cleared
Problem: Vim9: when compiling a function fails it is cleared. Solution: Keep the function lines, prevent execution with a different status. (closes #8093)
This commit is contained in:
@@ -1583,10 +1583,11 @@ typedef struct funccall_S funccall_T;
|
|||||||
|
|
||||||
// values used for "uf_def_status"
|
// values used for "uf_def_status"
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UF_NOT_COMPILED,
|
UF_NOT_COMPILED, // executed with interpreter
|
||||||
UF_TO_BE_COMPILED,
|
UF_TO_BE_COMPILED, // to be compiled before execution
|
||||||
UF_COMPILING,
|
UF_COMPILING, // in compile_def_function()
|
||||||
UF_COMPILED
|
UF_COMPILED, // successfully compiled
|
||||||
|
UF_COMPILE_ERROR // compilation error, cannot execute
|
||||||
} def_status_T;
|
} def_status_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1498,7 +1498,7 @@ def Test_redef_failure()
|
|||||||
so Xdef
|
so Xdef
|
||||||
delete('Xdef')
|
delete('Xdef')
|
||||||
|
|
||||||
g:Func0()->assert_equal(0)
|
assert_fails('g:Func0()', 'E1091:')
|
||||||
g:Func1()->assert_equal('Func1')
|
g:Func1()->assert_equal('Func1')
|
||||||
g:Func2()->assert_equal('Func2')
|
g:Func2()->assert_equal('Func2')
|
||||||
|
|
||||||
@@ -2591,6 +2591,20 @@ def Test_check_func_arg_types()
|
|||||||
CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
|
CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def Test_compile_error()
|
||||||
|
var lines =<< trim END
|
||||||
|
def g:Broken()
|
||||||
|
echo 'a' + {}
|
||||||
|
enddef
|
||||||
|
call g:Broken()
|
||||||
|
END
|
||||||
|
# First call: compilation error
|
||||||
|
CheckScriptFailure(lines, 'E1051: Wrong argument type for +')
|
||||||
|
|
||||||
|
# Second call won't try compiling again
|
||||||
|
assert_fails('call g:Broken()', 'E1091: Function is not compiled: Broken')
|
||||||
|
enddef
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||||
|
@@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
2742,
|
||||||
/**/
|
/**/
|
||||||
2741,
|
2741,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -1791,8 +1791,9 @@ func_needs_compiling(ufunc_T *ufunc, int profile UNUSED)
|
|||||||
{
|
{
|
||||||
switch (ufunc->uf_def_status)
|
switch (ufunc->uf_def_status)
|
||||||
{
|
{
|
||||||
case UF_NOT_COMPILED: break;
|
case UF_TO_BE_COMPILED:
|
||||||
case UF_TO_BE_COMPILED: return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case UF_COMPILED:
|
case UF_COMPILED:
|
||||||
{
|
{
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
@@ -1805,7 +1806,11 @@ func_needs_compiling(ufunc_T *ufunc, int profile UNUSED)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
case UF_COMPILING: break;
|
|
||||||
|
case UF_NOT_COMPILED:
|
||||||
|
case UF_COMPILE_ERROR:
|
||||||
|
case UF_COMPILING:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1834,7 +1839,8 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ufunc->uf_def_status != UF_NOT_COMPILED)
|
if (ufunc->uf_def_status != UF_NOT_COMPILED
|
||||||
|
&& ufunc->uf_def_status != UF_COMPILE_ERROR)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -9007,14 +9013,11 @@ erret:
|
|||||||
--def_functions.ga_len;
|
--def_functions.ga_len;
|
||||||
ufunc->uf_dfunc_idx = 0;
|
ufunc->uf_dfunc_idx = 0;
|
||||||
}
|
}
|
||||||
ufunc->uf_def_status = UF_NOT_COMPILED;
|
ufunc->uf_def_status = UF_COMPILE_ERROR;
|
||||||
|
|
||||||
while (cctx.ctx_scope != NULL)
|
while (cctx.ctx_scope != NULL)
|
||||||
drop_scope(&cctx);
|
drop_scope(&cctx);
|
||||||
|
|
||||||
// Don't execute this function body.
|
|
||||||
ga_clear_strings(&ufunc->uf_lines);
|
|
||||||
|
|
||||||
if (errormsg != NULL)
|
if (errormsg != NULL)
|
||||||
emsg(errormsg);
|
emsg(errormsg);
|
||||||
else if (did_emsg == did_emsg_before)
|
else if (did_emsg == did_emsg_before)
|
||||||
|
@@ -1297,6 +1297,7 @@ call_def_function(
|
|||||||
#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
|
#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
|
||||||
|
|
||||||
if (ufunc->uf_def_status == UF_NOT_COMPILED
|
if (ufunc->uf_def_status == UF_NOT_COMPILED
|
||||||
|
|| ufunc->uf_def_status == UF_COMPILE_ERROR
|
||||||
|| (func_needs_compiling(ufunc, PROFILING(ufunc))
|
|| (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||||
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
|
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
|
||||||
== FAIL))
|
== FAIL))
|
||||||
|
Reference in New Issue
Block a user