Skip to content

Commit 4d00b83

Browse files
erraelchrisbra
authored andcommitted
patch 9.0.1895: Vim9: finding object method/member is inefficient
Problem: Vim9: finding method/member is inefficient Solution: Use lookups closes: #13073 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Ernie Rael <[email protected]>
1 parent f787ee8 commit 4d00b83

4 files changed

Lines changed: 103 additions & 65 deletions

File tree

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ static char *(features[]) =
699699

700700
static int included_patches[] =
701701
{ /* Add new patch number below this line */
702+
/**/
703+
1895,
702704
/**/
703705
1894,
704706
/**/

src/vim9class.c

Lines changed: 98 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,9 +1883,8 @@ class_object_index(
18831883
if (*name_end == '(')
18841884
{
18851885
ufunc_T *fp;
1886-
int m_idx;
18871886

1888-
fp = method_lookup(cl, rettv->v_type, name, len, &m_idx);
1887+
fp = method_lookup(cl, rettv->v_type, name, len, NULL);
18891888
if (fp == NULL)
18901889
{
18911890
semsg(_(e_method_not_found_on_class_str_str), cl->class_name,
@@ -2022,8 +2021,7 @@ find_class_func(char_u **arg)
20222021
goto fail_after_eval;
20232022
len = fname_end - fname;
20242023

2025-
int m_idx;
2026-
fp = method_lookup(cl, tv.v_type, fname, len, &m_idx);
2024+
fp = method_lookup(cl, tv.v_type, fname, len, NULL);
20272025

20282026
fail_after_eval:
20292027
clear_tv(&tv);
@@ -2038,20 +2036,9 @@ find_class_func(char_u **arg)
20382036
int
20392037
class_member_idx(class_T *cl, char_u *name, size_t namelen)
20402038
{
2041-
for (int i = 0; i < cl->class_class_member_count; ++i)
2042-
{
2043-
ocmember_T *m = &cl->class_class_members[i];
2044-
if (namelen)
2045-
{
2046-
if (STRNCMP(name, m->ocm_name, namelen) == 0
2047-
&& m->ocm_name[namelen] == NUL)
2048-
return i;
2049-
}
2050-
else if (STRCMP(name, m->ocm_name) == 0)
2051-
return i;
2052-
}
2053-
2054-
return -1;
2039+
int idx;
2040+
class_member_lookup(cl, name, namelen, &idx);
2041+
return idx;
20552042
}
20562043

20572044
/*
@@ -2062,8 +2049,31 @@ class_member_idx(class_T *cl, char_u *name, size_t namelen)
20622049
ocmember_T *
20632050
class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
20642051
{
2065-
*idx = class_member_idx(cl, name, namelen);
2066-
return *idx >= 0 ? &cl->class_class_members[*idx] : NULL;
2052+
ocmember_T *ret_m = NULL;
2053+
int ret_idx = -1;
2054+
for (int i = 0; i < cl->class_class_member_count; ++i)
2055+
{
2056+
ocmember_T *m = &cl->class_class_members[i];
2057+
if (namelen)
2058+
{
2059+
if (STRNCMP(name, m->ocm_name, namelen) == 0
2060+
&& m->ocm_name[namelen] == NUL)
2061+
{
2062+
ret_m = m;
2063+
ret_idx = i;
2064+
break;
2065+
}
2066+
}
2067+
else if (STRCMP(name, m->ocm_name) == 0)
2068+
{
2069+
ret_m = m;
2070+
ret_idx = i;
2071+
break;
2072+
}
2073+
}
2074+
if (idx != NULL)
2075+
*idx = ret_idx;
2076+
return ret_m;
20672077
}
20682078

20692079
/*
@@ -2073,15 +2083,9 @@ class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
20732083
int
20742084
class_method_idx(class_T *cl, char_u *name, size_t namelen)
20752085
{
2076-
for (int i = 0; i < cl->class_class_function_count; ++i)
2077-
{
2078-
ufunc_T *fp = cl->class_class_functions[i];
2079-
char_u *ufname = (char_u *)fp->uf_name;
2080-
if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
2081-
return i;
2082-
}
2083-
2084-
return -1;
2086+
int idx;
2087+
class_method_lookup(cl, name, namelen, &idx);
2088+
return idx;
20852089
}
20862090

20872091
/*
@@ -2092,8 +2096,22 @@ class_method_idx(class_T *cl, char_u *name, size_t namelen)
20922096
ufunc_T *
20932097
class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
20942098
{
2095-
*idx = class_method_idx(cl, name, namelen);
2096-
return *idx >= 0 ? cl->class_class_functions[*idx] : NULL;
2099+
ufunc_T *ret_fp = NULL;
2100+
int ret_idx = -1;
2101+
for (int i = 0; i < cl->class_class_function_count; ++i)
2102+
{
2103+
ufunc_T *fp = cl->class_class_functions[i];
2104+
char_u *ufname = (char_u *)fp->uf_name;
2105+
if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
2106+
{
2107+
ret_fp = fp;
2108+
ret_idx = i;
2109+
break;
2110+
}
2111+
}
2112+
if (idx != NULL)
2113+
*idx = ret_idx;
2114+
return ret_fp;
20972115
}
20982116

20992117
/*
@@ -2104,20 +2122,9 @@ class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
21042122
int
21052123
object_member_idx(class_T *cl, char_u *name, size_t namelen)
21062124
{
2107-
for (int i = 0; i < cl->class_obj_member_count; ++i)
2108-
{
2109-
ocmember_T *m = &cl->class_obj_members[i];
2110-
if (namelen)
2111-
{
2112-
if (STRNCMP(name, m->ocm_name, namelen) == 0
2113-
&& m->ocm_name[namelen] == NUL)
2114-
return i;
2115-
}
2116-
else if (STRCMP(name, m->ocm_name) == 0)
2117-
return i;
2118-
}
2119-
2120-
return -1;
2125+
int idx;
2126+
object_member_lookup(cl, name, namelen, &idx);
2127+
return idx;
21212128
}
21222129

21232130
/*
@@ -2128,8 +2135,31 @@ object_member_idx(class_T *cl, char_u *name, size_t namelen)
21282135
ocmember_T *
21292136
object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
21302137
{
2131-
*idx = object_member_idx(cl, name, namelen);
2132-
return *idx >= 0 ? &cl->class_obj_members[*idx] : NULL;
2138+
ocmember_T *ret_m = NULL;
2139+
int ret_idx = -1;
2140+
for (int i = 0; i < cl->class_obj_member_count; ++i)
2141+
{
2142+
ocmember_T *m = &cl->class_obj_members[i];
2143+
if (namelen)
2144+
{
2145+
if (STRNCMP(name, m->ocm_name, namelen) == 0
2146+
&& m->ocm_name[namelen] == NUL)
2147+
{
2148+
ret_m = m;
2149+
ret_idx = i;
2150+
break;
2151+
}
2152+
}
2153+
else if (STRCMP(name, m->ocm_name) == 0)
2154+
{
2155+
ret_m = m;
2156+
ret_idx = i;
2157+
break;
2158+
}
2159+
}
2160+
if (idx != NULL)
2161+
*idx = ret_idx;
2162+
return ret_m;
21332163
}
21342164

21352165
/*
@@ -2139,17 +2169,9 @@ object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
21392169
int
21402170
object_method_idx(class_T *cl, char_u *name, size_t namelen)
21412171
{
2142-
for (int i = 0; i < cl->class_obj_method_count; ++i)
2143-
{
2144-
ufunc_T *fp = cl->class_obj_methods[i];
2145-
// Use a separate pointer to avoid that ASAN complains about
2146-
// uf_name[] only being 4 characters.
2147-
char_u *ufname = (char_u *)fp->uf_name;
2148-
if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
2149-
return i;
2150-
}
2151-
2152-
return -1;
2172+
int idx;
2173+
object_method_lookup(cl, name, namelen, &idx);
2174+
return idx;
21532175
}
21542176

21552177
/*
@@ -2160,8 +2182,24 @@ object_method_idx(class_T *cl, char_u *name, size_t namelen)
21602182
ufunc_T *
21612183
object_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
21622184
{
2163-
*idx = object_method_idx(cl, name, namelen);
2164-
return *idx >= 0 ? cl->class_obj_methods[*idx] : NULL;
2185+
ufunc_T *ret_fp = NULL;
2186+
int ret_idx = -1;
2187+
for (int i = 0; i < cl->class_obj_method_count; ++i)
2188+
{
2189+
ufunc_T *fp = cl->class_obj_methods[i];
2190+
// Use a separate pointer to avoid that ASAN complains about
2191+
// uf_name[] only being 4 characters.
2192+
char_u *ufname = (char_u *)fp->uf_name;
2193+
if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
2194+
{
2195+
ret_fp = fp;
2196+
ret_idx = i;
2197+
break;
2198+
}
2199+
}
2200+
if (idx != NULL)
2201+
*idx = ret_idx;
2202+
return ret_fp;
21652203
}
21662204

21672205
/*

src/vim9expr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,10 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
394394

395395
if (type->tt_type == VAR_OBJECT)
396396
{
397-
int m_idx = object_member_idx(cl, name, len);
397+
int m_idx;
398+
ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
398399
if (m_idx >= 0)
399400
{
400-
ocmember_T *m = &cl->class_obj_members[m_idx];
401401
if (*name == '_' && !inside_class(cctx, cl))
402402
{
403403
semsg(_(e_cannot_access_private_member_str), m->ocm_name);

src/vim9instr.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,9 +1838,7 @@ generate_CALL(
18381838
{
18391839
class_T *clp = mtype->tt_class;
18401840
char_u *aname = ((char_u **)ufunc->uf_args.ga_data)[i];
1841-
int m_idx;
1842-
ocmember_T *m = object_member_lookup(clp, aname, 0,
1843-
&m_idx);
1841+
ocmember_T *m = object_member_lookup(clp, aname, 0, NULL);
18441842
if (m != NULL)
18451843
expected = m->ocm_type;
18461844
}

0 commit comments

Comments
 (0)