0
0
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:
Bram Moolenaar
2021-04-10 13:33:48 +02:00
parent 1088b69451
commit 701cc6ca9e
5 changed files with 34 additions and 13 deletions

View File

@@ -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;
/* /*

View File

@@ -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

View File

@@ -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,
/**/ /**/

View File

@@ -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)

View File

@@ -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))