mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
patch 8.2.4669: in compiled code len('string') is not inlined
Problem: In compiled code len('string') is not inlined. Solution: Compute the length at compile time if possible. (closes #10065)
This commit is contained in:
parent
0dac1ab579
commit
58f331a05f
@ -90,7 +90,6 @@ static void f_interrupt(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_invert(typval_T *argvars, typval_T *rettv);
|
static void f_invert(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_islocked(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_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_libcall(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_libcallnr(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);
|
static void f_line(typval_T *argvars, typval_T *rettv);
|
||||||
@ -7019,7 +7018,7 @@ f_last_buffer_nr(typval_T *argvars UNUSED, typval_T *rettv)
|
|||||||
/*
|
/*
|
||||||
* "len()" function
|
* "len()" function
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
f_len(typval_T *argvars, typval_T *rettv)
|
f_len(typval_T *argvars, typval_T *rettv)
|
||||||
{
|
{
|
||||||
switch (argvars[0].v_type)
|
switch (argvars[0].v_type)
|
||||||
|
@ -20,6 +20,7 @@ void execute_cmds_from_string(char_u *str);
|
|||||||
void execute_common(typval_T *argvars, typval_T *rettv, int arg_off);
|
void execute_common(typval_T *argvars, typval_T *rettv, int arg_off);
|
||||||
void f_exists(typval_T *argvars, typval_T *rettv);
|
void f_exists(typval_T *argvars, typval_T *rettv);
|
||||||
void f_has(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);
|
int dynamic_feature(char_u *feature);
|
||||||
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
|
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
|
||||||
void range_list_materialize(list_T *list);
|
void range_list_materialize(list_T *list);
|
||||||
|
@ -1015,9 +1015,20 @@ def s:HasGuiRunning()
|
|||||||
endif
|
endif
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
|
def s:LenConstant(): number
|
||||||
|
return len("foo") + len("fighters")
|
||||||
|
enddef
|
||||||
|
|
||||||
def Test_disassemble_const_expr()
|
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()'))
|
assert_equal("\nyes", execute('HasEval()'))
|
||||||
var instr = execute('disassemble HasEval')
|
instr = execute('disassemble HasEval')
|
||||||
assert_match('HasEval\_s*' ..
|
assert_match('HasEval\_s*' ..
|
||||||
'if has("eval")\_s*' ..
|
'if has("eval")\_s*' ..
|
||||||
'echo "yes"\_s*' ..
|
'echo "yes"\_s*' ..
|
||||||
|
@ -750,6 +750,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 */
|
||||||
|
/**/
|
||||||
|
4669,
|
||||||
/**/
|
/**/
|
||||||
4668,
|
4668,
|
||||||
/**/
|
/**/
|
||||||
|
@ -724,13 +724,16 @@ compile_call(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We can evaluate "has('name')" at compile time.
|
// We can evaluate "has('name')" at compile time.
|
||||||
|
// We can evaluate "len('string')" at compile time.
|
||||||
// We always evaluate "exists_compiled()" at compile time.
|
// We always evaluate "exists_compiled()" at compile time.
|
||||||
if ((varlen == 3 && STRNCMP(*arg, "has", 3) == 0)
|
if ((varlen == 3
|
||||||
|
&& (STRNCMP(*arg, "has", 3) == 0 || STRNCMP(*arg, "len", 3) == 0))
|
||||||
|| (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0))
|
|| (varlen == 15 && STRNCMP(*arg, "exists_compiled", 6) == 0))
|
||||||
{
|
{
|
||||||
char_u *s = skipwhite(*arg + varlen + 1);
|
char_u *s = skipwhite(*arg + varlen + 1);
|
||||||
typval_T argvars[2];
|
typval_T argvars[2];
|
||||||
int is_has = **arg == 'h';
|
int is_has = **arg == 'h';
|
||||||
|
int is_len = **arg == 'l';
|
||||||
|
|
||||||
argvars[0].v_type = VAR_UNKNOWN;
|
argvars[0].v_type = VAR_UNKNOWN;
|
||||||
if (*s == '"')
|
if (*s == '"')
|
||||||
@ -750,6 +753,8 @@ compile_call(
|
|||||||
tv->vval.v_number = 0;
|
tv->vval.v_number = 0;
|
||||||
if (is_has)
|
if (is_has)
|
||||||
f_has(argvars, tv);
|
f_has(argvars, tv);
|
||||||
|
else if (is_len)
|
||||||
|
f_len(argvars, tv);
|
||||||
else
|
else
|
||||||
f_exists(argvars, tv);
|
f_exists(argvars, tv);
|
||||||
clear_tv(&argvars[0]);
|
clear_tv(&argvars[0]);
|
||||||
@ -757,7 +762,7 @@ compile_call(
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
clear_tv(&argvars[0]);
|
clear_tv(&argvars[0]);
|
||||||
if (!is_has)
|
if (!is_has && !is_len)
|
||||||
{
|
{
|
||||||
emsg(_(e_argument_of_exists_compiled_must_be_literal_string));
|
emsg(_(e_argument_of_exists_compiled_must_be_literal_string));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user