Mercurial > vim
changeset 24404:a2a7d2d6e724 v8.2.2742
patch 8.2.2742: Vim9: when compiling a function fails it is cleared
Commit: https://github.com/vim/vim/commit/701cc6ca9e940665a9424541f989bb38c853a498
Author: Bram Moolenaar <Bram@vim.org>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 10 Apr 2021 13:45:05 +0200 |
parents | 1df57caa70c0 |
children | 2831ce589a7d |
files | src/structs.h src/testdir/test_vim9_func.vim src/version.c src/vim9compile.c src/vim9execute.c |
diffstat | 5 files changed, 34 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- 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; /*
--- 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
--- 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,
--- 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)
--- 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))