To: vim_dev@googlegroups.com Subject: Patch 8.2.4669 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4669 Problem: In compiled code len('string') is not inlined. Solution: Compute the length at compile time if possible. (closes #10065) Files: src/evalfunc.c, src/proto/evalfunc.pro, src/vim9expr.c, src/testdir/test_vim9_disassemble.vim *** ../vim-8.2.4668/src/evalfunc.c 2022-04-02 21:12:11.006733246 +0100 --- src/evalfunc.c 2022-04-02 21:53:07.901786916 +0100 *************** *** 90,96 **** static void f_invert(typval_T *argvars, typval_T *rettv); static void f_islocked(typval_T *argvars, typval_T *rettv); static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv); - static void f_len(typval_T *argvars, typval_T *rettv); static void f_libcall(typval_T *argvars, typval_T *rettv); static void f_libcallnr(typval_T *argvars, typval_T *rettv); static void f_line(typval_T *argvars, typval_T *rettv); --- 90,95 ---- *************** *** 7019,7025 **** /* * "len()" function */ ! static void f_len(typval_T *argvars, typval_T *rettv) { switch (argvars[0].v_type) --- 7018,7024 ---- /* * "len()" function */ ! void f_len(typval_T *argvars, typval_T *rettv) { switch (argvars[0].v_type) *** ../vim-8.2.4668/src/proto/evalfunc.pro 2022-02-01 12:11:53.443042004 +0000 --- src/proto/evalfunc.pro 2022-04-02 21:53:07.901786916 +0100 *************** *** 20,25 **** --- 20,26 ---- void execute_common(typval_T *argvars, typval_T *rettv, int arg_off); void f_exists(typval_T *argvars, typval_T *rettv); void f_has(typval_T *argvars, typval_T *rettv); + void f_len(typval_T *argvars, typval_T *rettv); int dynamic_feature(char_u *feature); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); void range_list_materialize(list_T *list); *** ../vim-8.2.4668/src/vim9expr.c 2022-04-01 13:23:42.960558879 +0100 --- src/vim9expr.c 2022-04-02 21:57:19.073737668 +0100 *************** *** 724,736 **** } // We can evaluate "has('name')" at compile time. // We always evaluate "exists_compiled()" at compile time. ! if ((varlen == 3 && STRNCMP(*arg, "has", 3) == 0) || (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0)) { char_u *s = skipwhite(*arg + varlen + 1); typval_T argvars[2]; int is_has = **arg == 'h'; argvars[0].v_type = VAR_UNKNOWN; if (*s == '"') --- 724,739 ---- } // We can evaluate "has('name')" at compile time. + // We can evaluate "len('string')" at compile time. // We always evaluate "exists_compiled()" at compile time. ! if ((varlen == 3 ! && (STRNCMP(*arg, "has", 3) == 0 || STRNCMP(*arg, "len", 3) == 0)) || (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0)) { char_u *s = skipwhite(*arg + varlen + 1); typval_T argvars[2]; int is_has = **arg == 'h'; + int is_len = **arg == 'l'; argvars[0].v_type = VAR_UNKNOWN; if (*s == '"') *************** *** 750,755 **** --- 753,760 ---- tv->vval.v_number = 0; if (is_has) f_has(argvars, tv); + else if (is_len) + f_len(argvars, tv); else f_exists(argvars, tv); clear_tv(&argvars[0]); *************** *** 757,763 **** return OK; } clear_tv(&argvars[0]); ! if (!is_has) { emsg(_(e_argument_of_exists_compiled_must_be_literal_string)); return FAIL; --- 762,768 ---- return OK; } clear_tv(&argvars[0]); ! if (!is_has && !is_len) { emsg(_(e_argument_of_exists_compiled_must_be_literal_string)); return FAIL; *** ../vim-8.2.4668/src/testdir/test_vim9_disassemble.vim 2022-03-30 21:57:46.896372724 +0100 --- src/testdir/test_vim9_disassemble.vim 2022-04-02 21:53:07.901786916 +0100 *************** *** 1015,1023 **** endif enddef def Test_disassemble_const_expr() assert_equal("\nyes", execute('HasEval()')) ! var instr = execute('disassemble HasEval') assert_match('HasEval\_s*' .. 'if has("eval")\_s*' .. 'echo "yes"\_s*' .. --- 1015,1034 ---- endif enddef + def s:LenConstant(): number + return len("foo") + len("fighters") + enddef + def Test_disassemble_const_expr() + var instr = execute('disassemble LenConstant') + assert_match('LenConstant\_s*' .. + 'return len("foo") + len("fighters")\_s*' .. + '\d PUSHNR 11\_s*', + instr) + assert_notmatch('BCALL len', instr) + assert_equal("\nyes", execute('HasEval()')) ! instr = execute('disassemble HasEval') assert_match('HasEval\_s*' .. 'if has("eval")\_s*' .. 'echo "yes"\_s*' .. *** ../vim-8.2.4668/src/version.c 2022-04-02 21:46:14.989612828 +0100 --- src/version.c 2022-04-02 21:55:06.429773629 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4669, /**/ -- "When I die, I want a tombstone that says "GAME OVER" - Ton Richters /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///