mirror of
https://github.com/vim/vim.git
synced 2025-08-31 20:53:42 -04:00
patch 8.2.3893: Vim9: many local variables are initialized with an instruction
Problem: Vim9: many local variables are initialized with an instruction. Solution: Initialize local variables to zero to avoid the instructions.
This commit is contained in:
parent
35cfd793aa
commit
5cd647935d
@ -65,7 +65,7 @@ int generate_UNPACK(cctx_T *cctx, int var_count, int semicolon);
|
|||||||
int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod);
|
int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod);
|
||||||
int generate_undo_cmdmods(cctx_T *cctx);
|
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_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 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 may_generate_prof_end(cctx_T *cctx, int prof_lnum);
|
||||||
void delete_instr(isn_T *isn);
|
void delete_instr(isn_T *isn);
|
||||||
void clear_instr_ga(garray_T *gap);
|
void clear_instr_ga(garray_T *gap);
|
||||||
|
@ -1773,6 +1773,7 @@ enddef
|
|||||||
def ReturnBool(): bool
|
def ReturnBool(): bool
|
||||||
var one = 1
|
var one = 1
|
||||||
var zero = 0
|
var zero = 0
|
||||||
|
var none: number
|
||||||
var name: bool = one && zero || one
|
var name: bool = one && zero || one
|
||||||
return name
|
return name
|
||||||
enddef
|
enddef
|
||||||
@ -1783,19 +1784,19 @@ def Test_disassemble_return_bool()
|
|||||||
'var one = 1\_s*' ..
|
'var one = 1\_s*' ..
|
||||||
'0 STORE 1 in $0\_s*' ..
|
'0 STORE 1 in $0\_s*' ..
|
||||||
'var zero = 0\_s*' ..
|
'var zero = 0\_s*' ..
|
||||||
'1 STORE 0 in $1\_s*' ..
|
'var none: number\_s*' ..
|
||||||
'var name: bool = one && zero || one\_s*' ..
|
'var name: bool = one && zero || one\_s*' ..
|
||||||
'2 LOAD $0\_s*' ..
|
'1 LOAD $0\_s*' ..
|
||||||
'3 COND2BOOL\_s*' ..
|
'2 COND2BOOL\_s*' ..
|
||||||
'4 JUMP_IF_COND_FALSE -> 7\_s*' ..
|
'3 JUMP_IF_COND_FALSE -> 6\_s*' ..
|
||||||
'5 LOAD $1\_s*' ..
|
'4 LOAD $1\_s*' ..
|
||||||
'6 COND2BOOL\_s*' ..
|
'5 COND2BOOL\_s*' ..
|
||||||
'7 JUMP_IF_COND_TRUE -> 10\_s*' ..
|
'6 JUMP_IF_COND_TRUE -> 9\_s*' ..
|
||||||
'8 LOAD $0\_s*' ..
|
'7 LOAD $0\_s*' ..
|
||||||
'9 COND2BOOL\_s*' ..
|
'8 COND2BOOL\_s*' ..
|
||||||
'10 STORE $2\_s*' ..
|
'9 STORE $3\_s*' ..
|
||||||
'return name\_s*' ..
|
'return name\_s*' ..
|
||||||
'\d\+ LOAD $2\_s*' ..
|
'\d\+ LOAD $3\_s*' ..
|
||||||
'\d\+ RETURN',
|
'\d\+ RETURN',
|
||||||
instr)
|
instr)
|
||||||
assert_equal(true, InvertBool())
|
assert_equal(true, InvertBool())
|
||||||
|
@ -749,6 +749,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 */
|
||||||
|
/**/
|
||||||
|
3893,
|
||||||
/**/
|
/**/
|
||||||
3892,
|
3892,
|
||||||
/**/
|
/**/
|
||||||
|
@ -2092,7 +2092,7 @@ compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx)
|
|||||||
&t_string, cctx) == FAIL)
|
&t_string, cctx) == FAIL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (generate_store_lhs(cctx, lhs, -1) == FAIL)
|
else if (generate_store_lhs(cctx, lhs, -1, FALSE) == FAIL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
VIM_CLEAR(lhs->lhs_name);
|
VIM_CLEAR(lhs->lhs_name);
|
||||||
|
@ -1963,6 +1963,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
{
|
{
|
||||||
int instr_count = -1;
|
int instr_count = -1;
|
||||||
int save_lnum;
|
int save_lnum;
|
||||||
|
int skip_store = FALSE;
|
||||||
|
|
||||||
if (var_start[0] == '_' && !eval_isnamec(var_start[1]))
|
if (var_start[0] == '_' && !eval_isnamec(var_start[1]))
|
||||||
{
|
{
|
||||||
@ -2186,7 +2187,12 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
case VAR_VOID:
|
case VAR_VOID:
|
||||||
case VAR_INSTR:
|
case VAR_INSTR:
|
||||||
case VAR_SPECIAL: // cannot happen
|
case VAR_SPECIAL: // cannot happen
|
||||||
generate_PUSHNR(cctx, 0);
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2278,7 +2284,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
// type of "val" is used.
|
// type of "val" is used.
|
||||||
generate_SETTYPE(cctx, lhs.lhs_type);
|
generate_SETTYPE(cctx, lhs.lhs_type);
|
||||||
|
|
||||||
if (generate_store_lhs(cctx, &lhs, instr_count) == FAIL)
|
if (!skip_store && generate_store_lhs(cctx, &lhs,
|
||||||
|
instr_count, is_decl) == FAIL)
|
||||||
{
|
{
|
||||||
cctx->ctx_lnum = save_lnum;
|
cctx->ctx_lnum = save_lnum;
|
||||||
goto theend;
|
goto theend;
|
||||||
|
@ -397,7 +397,12 @@ call_dfunc(
|
|||||||
|
|
||||||
// Initialize local variables
|
// Initialize local variables
|
||||||
for (idx = 0; idx < dfunc->df_varcount; ++idx)
|
for (idx = 0; idx < dfunc->df_varcount; ++idx)
|
||||||
STACK_TV_BOT(STACK_FRAME_SIZE + idx)->v_type = VAR_UNKNOWN;
|
{
|
||||||
|
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)
|
if (dfunc->df_has_closure)
|
||||||
{
|
{
|
||||||
typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + dfunc->df_varcount);
|
typval_T *tv = STACK_TV_BOT(STACK_FRAME_SIZE + dfunc->df_varcount);
|
||||||
@ -5002,8 +5007,13 @@ call_def_function(
|
|||||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||||
+ ufunc->uf_dfunc_idx;
|
+ 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)
|
for (idx = 0; idx < dfunc->df_varcount; ++idx)
|
||||||
STACK_TV_VAR(idx)->v_type = VAR_UNKNOWN;
|
{
|
||||||
|
STACK_TV_VAR(idx)->v_type = VAR_NUMBER;
|
||||||
|
STACK_TV_VAR(idx)->vval.v_number = 0;
|
||||||
|
}
|
||||||
ectx.ec_stack.ga_len += dfunc->df_varcount;
|
ectx.ec_stack.ga_len += dfunc->df_varcount;
|
||||||
if (dfunc->df_has_closure)
|
if (dfunc->df_has_closure)
|
||||||
{
|
{
|
||||||
|
@ -1886,7 +1886,7 @@ generate_store_var(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count)
|
generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count, int is_decl)
|
||||||
{
|
{
|
||||||
if (lhs->lhs_dest != dest_local)
|
if (lhs->lhs_dest != dest_local)
|
||||||
return generate_store_var(cctx, lhs->lhs_dest,
|
return generate_store_var(cctx, lhs->lhs_dest,
|
||||||
@ -1899,8 +1899,9 @@ generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count)
|
|||||||
garray_T *instr = &cctx->ctx_instr;
|
garray_T *instr = &cctx->ctx_instr;
|
||||||
isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
|
isn_T *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
|
||||||
|
|
||||||
// optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
|
// Optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
|
||||||
// ISN_STORENR
|
// ISN_STORENR.
|
||||||
|
// And "var = 0" does not need any instruction.
|
||||||
if (lhs->lhs_lvar->lv_from_outer == 0
|
if (lhs->lhs_lvar->lv_from_outer == 0
|
||||||
&& instr->ga_len == instr_count + 1
|
&& instr->ga_len == instr_count + 1
|
||||||
&& isn->isn_type == ISN_PUSHNR)
|
&& isn->isn_type == ISN_PUSHNR)
|
||||||
@ -1908,9 +1909,16 @@ generate_store_lhs(cctx_T *cctx, lhs_T *lhs, int instr_count)
|
|||||||
varnumber_T val = isn->isn_arg.number;
|
varnumber_T val = isn->isn_arg.number;
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
|
|
||||||
isn->isn_type = ISN_STORENR;
|
if (val == 0 && is_decl)
|
||||||
isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx;
|
{
|
||||||
isn->isn_arg.storenr.stnr_val = val;
|
--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)
|
if (stack->ga_len > 0)
|
||||||
--stack->ga_len;
|
--stack->ga_len;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user