# HG changeset patch # User Bram Moolenaar # Date 1618055105 -7200 # Node ID a2a7d2d6e72475110fc4bb3d9a07e0177f32af70 # Parent 1df57caa70c0c615d35173de1813c2e2e4df16af patch 8.2.2742: Vim9: when compiling a function fails it is cleared Commit: https://github.com/vim/vim/commit/701cc6ca9e940665a9424541f989bb38c853a498 Author: Bram Moolenaar Date: Sat Apr 10 13:33:48 2021 +0200 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) diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1583,10 +1583,11 @@ typedef struct funccall_S funccall_T; // values used for "uf_def_status" typedef enum { - UF_NOT_COMPILED, - UF_TO_BE_COMPILED, - UF_COMPILING, - UF_COMPILED + UF_NOT_COMPILED, // executed with interpreter + UF_TO_BE_COMPILED, // to be compiled before execution + UF_COMPILING, // in compile_def_function() + UF_COMPILED, // successfully compiled + UF_COMPILE_ERROR // compilation error, cannot execute } def_status_T; /* diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1498,7 +1498,7 @@ def Test_redef_failure() so Xdef delete('Xdef') - g:Func0()->assert_equal(0) + assert_fails('g:Func0()', 'E1091:') g:Func1()->assert_equal('Func1') g:Func2()->assert_equal('Func2') @@ -2591,6 +2591,20 @@ def Test_check_func_arg_types() CheckScriptFailure(lines + ['echo H(G(F2))'], 'E1013:') 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 diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 2742, +/**/ 2741, /**/ 2740, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1791,8 +1791,9 @@ func_needs_compiling(ufunc_T *ufunc, int { switch (ufunc->uf_def_status) { - case UF_NOT_COMPILED: break; - case UF_TO_BE_COMPILED: return TRUE; + case UF_TO_BE_COMPILED: + return TRUE; + case UF_COMPILED: { #ifdef FEAT_PROFILE @@ -1805,7 +1806,11 @@ func_needs_compiling(ufunc_T *ufunc, int break; #endif } - case UF_COMPILING: break; + + case UF_NOT_COMPILED: + case UF_COMPILE_ERROR: + case UF_COMPILING: + break; } return FALSE; } @@ -1834,7 +1839,8 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu 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; @@ -9007,14 +9013,11 @@ erret: --def_functions.ga_len; ufunc->uf_dfunc_idx = 0; } - ufunc->uf_def_status = UF_NOT_COMPILED; + ufunc->uf_def_status = UF_COMPILE_ERROR; while (cctx.ctx_scope != NULL) drop_scope(&cctx); - // Don't execute this function body. - ga_clear_strings(&ufunc->uf_lines); - if (errormsg != NULL) emsg(errormsg); else if (did_emsg == did_emsg_before) diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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) if (ufunc->uf_def_status == UF_NOT_COMPILED + || ufunc->uf_def_status == UF_COMPILE_ERROR || (func_needs_compiling(ufunc, PROFILING(ufunc)) && compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL) == FAIL))