To: vim_dev@googlegroups.com Subject: Patch 8.2.3893 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3893 Problem: Vim9: many local variables are initialized with an instruction. Solution: Initialize local variables to zero to avoid the instructions. Files: src/vim9execute.c, src/vim9compile.c, src/vim9instr.c, src/proto/vim9instr.pro, src/vim9cmds.c, src/testdir/test_vim9_disassemble.vim *** ../vim-8.2.3892/src/vim9execute.c 2021-12-23 21:14:34.364204913 +0000 --- src/vim9execute.c 2021-12-25 18:11:06.611657964 +0000 *************** *** 397,403 **** // Initialize local variables for (idx = 0; idx < dfunc->df_varcount; ++idx) ! STACK_TV_BOT(STACK_FRAME_SIZE + idx)->v_type = VAR_UNKNOWN; if (dfunc->df_has_closure) { typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + dfunc->df_varcount); --- 397,408 ---- // Initialize local variables for (idx = 0; idx < dfunc->df_varcount; ++idx) ! { ! typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + idx); ! ! tv->v_type = VAR_NUMBER; ! tv->vval.v_number = 0; ! } if (dfunc->df_has_closure) { typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + dfunc->df_varcount); *************** *** 5002,5009 **** dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; for (idx = 0; idx < dfunc->df_varcount; ++idx) ! STACK_TV_VAR(idx)->v_type = VAR_UNKNOWN; ectx.ec_stack.ga_len += dfunc->df_varcount; if (dfunc->df_has_closure) { --- 5007,5019 ---- dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; + // Initialize variables to zero. That avoids having to generate + // initializing instructions for "var nr: number", "var x: any", etc. for (idx = 0; idx < dfunc->df_varcount; ++idx) ! { ! STACK_TV_VAR(idx)->v_type = VAR_NUMBER; ! STACK_TV_VAR(idx)->vval.v_number = 0; ! } ectx.ec_stack.ga_len += dfunc->df_varcount; if (dfunc->df_has_closure) { *** ../vim-8.2.3892/src/vim9compile.c 2021-12-22 13:18:36.145009230 +0000 --- src/vim9compile.c 2021-12-25 17:38:52.197501290 +0000 *************** *** 1963,1968 **** --- 1963,1969 ---- { int instr_count = -1; int save_lnum; + int skip_store = FALSE; if (var_start[0] == '_' && !eval_isnamec(var_start[1])) { *************** *** 2186,2192 **** case VAR_VOID: case VAR_INSTR: case VAR_SPECIAL: // cannot happen ! generate_PUSHNR(cctx, 0); break; } } --- 2187,2198 ---- case VAR_VOID: case VAR_INSTR: case VAR_SPECIAL: // cannot happen ! // This is skipped for local variables, they are ! // always initialized to zero. ! if (lhs.lhs_dest == dest_local) ! skip_store = TRUE; ! else ! generate_PUSHNR(cctx, 0); break; } } *************** *** 2278,2284 **** // type of "val" is used. generate_SETTYPE(cctx, lhs.lhs_type); ! if (generate_store_lhs(cctx, &lhs, instr_count) == FAIL) { cctx->ctx_lnum = save_lnum; goto theend; --- 2284,2291 ---- // type of "val" is used. generate_SETTYPE(cctx, lhs.lhs_type); ! if (!skip_store && generate_store_lhs(cctx, &lhs, ! instr_count, is_decl) == FAIL) { cctx->ctx_lnum = save_lnum; goto theend; *** ../vim-8.2.3892/src/vim9instr.c 2021-12-24 21:36:08.428028943 +0000 --- src/vim9instr.c 2021-12-25 17:39:07.037475293 +0000 *************** *** 1886,1892 **** } int ! generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count) { if (lhs->lhs_dest != dest_local) return generate_store_var(cctx, lhs->lhs_dest, --- 1886,1892 ---- } int ! generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl) { if (lhs->lhs_dest != dest_local) return generate_store_var(cctx, lhs->lhs_dest, *************** *** 1899,1906 **** garray_T *instr = &cctx->ctx_instr; isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1; ! // optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into ! // ISN_STORENR if (lhs->lhs_lvar->lv_from_outer == 0 && instr->ga_len == instr_count + 1 && isn->isn_type == ISN_PUSHNR) --- 1899,1907 ---- garray_T *instr = &cctx->ctx_instr; isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1; ! // Optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into ! // ISN_STORENR. ! // And "var = 0" does not need any instruction. if (lhs->lhs_lvar->lv_from_outer == 0 && instr->ga_len == instr_count + 1 && isn->isn_type == ISN_PUSHNR) *************** *** 1908,1916 **** varnumber_T val = isn->isn_arg.number; garray_T *stack = &cctx->ctx_type_stack; ! isn->isn_type = ISN_STORENR; ! isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx; ! isn->isn_arg.storenr.stnr_val = val; if (stack->ga_len > 0) --stack->ga_len; } --- 1909,1924 ---- varnumber_T val = isn->isn_arg.number; garray_T *stack = &cctx->ctx_type_stack; ! if (val == 0 && is_decl) ! { ! --instr->ga_len; ! } ! else ! { ! isn->isn_type = ISN_STORENR; ! isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx; ! isn->isn_arg.storenr.stnr_val = val; ! } if (stack->ga_len > 0) --stack->ga_len; } *** ../vim-8.2.3892/src/proto/vim9instr.pro 2021-12-20 15:03:23.247346527 +0000 --- src/proto/vim9instr.pro 2021-12-25 17:39:19.941480565 +0000 *************** *** 65,71 **** int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod); int generate_undo_cmdmods(cctx_T *cctx); int generate_store_var(cctx_T *cctx, assign_dest_T dest, int opt_flags, int vimvaridx, int scriptvar_idx, int scriptvar_sid, type_T *type, char_u *name); ! int generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count); void may_generate_prof_end(cctx_T *cctx, int prof_lnum); void delete_instr(isn_T *isn); void clear_instr_ga(garray_T *gap); --- 65,71 ---- int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod); int generate_undo_cmdmods(cctx_T *cctx); int generate_store_var(cctx_T *cctx, assign_dest_T dest, int opt_flags, int vimvaridx, int scriptvar_idx, int scriptvar_sid, type_T *type, char_u *name); ! int generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl); void may_generate_prof_end(cctx_T *cctx, int prof_lnum); void delete_instr(isn_T *isn); void clear_instr_ga(garray_T *gap); *** ../vim-8.2.3892/src/vim9cmds.c 2021-12-21 12:32:13.296529989 +0000 --- src/vim9cmds.c 2021-12-25 17:38:07.901578887 +0000 *************** *** 2092,2098 **** &t_string, cctx) == FAIL) return NULL; } ! else if (generate_store_lhs(cctx, lhs, -1) == FAIL) return NULL; VIM_CLEAR(lhs->lhs_name); --- 2092,2098 ---- &t_string, cctx) == FAIL) return NULL; } ! else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL) return NULL; VIM_CLEAR(lhs->lhs_name); *** ../vim-8.2.3892/src/testdir/test_vim9_disassemble.vim 2021-12-21 13:30:38.732749872 +0000 --- src/testdir/test_vim9_disassemble.vim 2021-12-25 17:22:57.003181906 +0000 *************** *** 1773,1778 **** --- 1773,1779 ---- def ReturnBool(): bool var one = 1 var zero = 0 + var none: number var name: bool = one && zero || one return name enddef *************** *** 1783,1801 **** 'var one = 1\_s*' .. '0 STORE 1 in $0\_s*' .. 'var zero = 0\_s*' .. ! '1 STORE 0 in $1\_s*' .. 'var name: bool = one && zero || one\_s*' .. ! '2 LOAD $0\_s*' .. ! '3 COND2BOOL\_s*' .. ! '4 JUMP_IF_COND_FALSE -> 7\_s*' .. ! '5 LOAD $1\_s*' .. ! '6 COND2BOOL\_s*' .. ! '7 JUMP_IF_COND_TRUE -> 10\_s*' .. ! '8 LOAD $0\_s*' .. ! '9 COND2BOOL\_s*' .. ! '10 STORE $2\_s*' .. 'return name\_s*' .. ! '\d\+ LOAD $2\_s*' .. '\d\+ RETURN', instr) assert_equal(true, InvertBool()) --- 1784,1802 ---- 'var one = 1\_s*' .. '0 STORE 1 in $0\_s*' .. 'var zero = 0\_s*' .. ! 'var none: number\_s*' .. 'var name: bool = one && zero || one\_s*' .. ! '1 LOAD $0\_s*' .. ! '2 COND2BOOL\_s*' .. ! '3 JUMP_IF_COND_FALSE -> 6\_s*' .. ! '4 LOAD $1\_s*' .. ! '5 COND2BOOL\_s*' .. ! '6 JUMP_IF_COND_TRUE -> 9\_s*' .. ! '7 LOAD $0\_s*' .. ! '8 COND2BOOL\_s*' .. ! '9 STORE $3\_s*' .. 'return name\_s*' .. ! '\d\+ LOAD $3\_s*' .. '\d\+ RETURN', instr) assert_equal(true, InvertBool()) *** ../vim-8.2.3892/src/version.c 2021-12-25 15:13:13.036442971 +0000 --- src/version.c 2021-12-25 17:00:42.385616042 +0000 *************** *** 751,752 **** --- 751,754 ---- { /* Add new patch number below this line */ + /**/ + 3893, /**/ -- A meeting is an event at which the minutes are kept and the hours are lost. /// 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 ///