summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErnie Rael <errael@raelity.com>2023-09-11 19:54:42 +0200
committerChristian Brabandt <cb@256bit.org>2023-09-11 19:57:52 +0200
commit4d00b835c49ffc5c416b65ca466d6ad695cbd3d2 (patch)
treea3974d821ce403d6d5d28cd5cc151b16ef9f50fb
parentf787ee8451a1f24de4ef3de48b78d5aa77d09829 (diff)
patch 9.0.1895: Vim9: finding object method/member is inefficientv9.0.1895
Problem: Vim9: finding method/member is inefficient Solution: Use lookups closes: #13073 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
-rw-r--r--src/version.c2
-rw-r--r--src/vim9class.c158
-rw-r--r--src/vim9expr.c4
-rw-r--r--src/vim9instr.c4
4 files changed, 103 insertions, 65 deletions
diff --git a/src/version.c b/src/version.c
index d37d147210..c56ef4ceac 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1895,
+/**/
1894,
/**/
1893,
diff --git a/src/vim9class.c b/src/vim9class.c
index 15d2b09137..ccc3818385 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -1883,9 +1883,8 @@ class_object_index(
if (*name_end == '(')
{
ufunc_T *fp;
- int m_idx;
- fp = method_lookup(cl, rettv->v_type, name, len, &m_idx);
+ fp = method_lookup(cl, rettv->v_type, name, len, NULL);
if (fp == NULL)
{
semsg(_(e_method_not_found_on_class_str_str), cl->class_name,
@@ -2022,8 +2021,7 @@ find_class_func(char_u **arg)
goto fail_after_eval;
len = fname_end - fname;
- int m_idx;
- fp = method_lookup(cl, tv.v_type, fname, len, &m_idx);
+ fp = method_lookup(cl, tv.v_type, fname, len, NULL);
fail_after_eval:
clear_tv(&tv);
@@ -2038,20 +2036,9 @@ fail_after_eval:
int
class_member_idx(class_T *cl, char_u *name, size_t namelen)
{
- for (int i = 0; i < cl->class_class_member_count; ++i)
- {
- ocmember_T *m = &cl->class_class_members[i];
- if (namelen)
- {
- if (STRNCMP(name, m->ocm_name, namelen) == 0
- && m->ocm_name[namelen] == NUL)
- return i;
- }
- else if (STRCMP(name, m->ocm_name) == 0)
- return i;
- }
-
- return -1;
+ int idx;
+ class_member_lookup(cl, name, namelen, &idx);
+ return idx;
}
/*
@@ -2062,8 +2049,31 @@ class_member_idx(class_T *cl, char_u *name, size_t namelen)
ocmember_T *
class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
{
- *idx = class_member_idx(cl, name, namelen);
- return *idx >= 0 ? &cl->class_class_members[*idx] : NULL;
+ ocmember_T *ret_m = NULL;
+ int ret_idx = -1;
+ for (int i = 0; i < cl->class_class_member_count; ++i)
+ {
+ ocmember_T *m = &cl->class_class_members[i];
+ if (namelen)
+ {
+ if (STRNCMP(name, m->ocm_name, namelen) == 0
+ && m->ocm_name[namelen] == NUL)
+ {
+ ret_m = m;
+ ret_idx = i;
+ break;
+ }
+ }
+ else if (STRCMP(name, m->ocm_name) == 0)
+ {
+ ret_m = m;
+ ret_idx = i;
+ break;
+ }
+ }
+ if (idx != NULL)
+ *idx = ret_idx;
+ return ret_m;
}
/*
@@ -2073,15 +2083,9 @@ class_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
int
class_method_idx(class_T *cl, char_u *name, size_t namelen)
{
- for (int i = 0; i < cl->class_class_function_count; ++i)
- {
- ufunc_T *fp = cl->class_class_functions[i];
- char_u *ufname = (char_u *)fp->uf_name;
- if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
- return i;
- }
-
- return -1;
+ int idx;
+ class_method_lookup(cl, name, namelen, &idx);
+ return idx;
}
/*
@@ -2092,8 +2096,22 @@ class_method_idx(class_T *cl, char_u *name, size_t namelen)
ufunc_T *
class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
{
- *idx = class_method_idx(cl, name, namelen);
- return *idx >= 0 ? cl->class_class_functions[*idx] : NULL;
+ ufunc_T *ret_fp = NULL;
+ int ret_idx = -1;
+ for (int i = 0; i < cl->class_class_function_count; ++i)
+ {
+ ufunc_T *fp = cl->class_class_functions[i];
+ char_u *ufname = (char_u *)fp->uf_name;
+ if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
+ {
+ ret_fp = fp;
+ ret_idx = i;
+ break;
+ }
+ }
+ if (idx != NULL)
+ *idx = ret_idx;
+ return ret_fp;
}
/*
@@ -2104,20 +2122,9 @@ class_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
int
object_member_idx(class_T *cl, char_u *name, size_t namelen)
{
- for (int i = 0; i < cl->class_obj_member_count; ++i)
- {
- ocmember_T *m = &cl->class_obj_members[i];
- if (namelen)
- {
- if (STRNCMP(name, m->ocm_name, namelen) == 0
- && m->ocm_name[namelen] == NUL)
- return i;
- }
- else if (STRCMP(name, m->ocm_name) == 0)
- return i;
- }
-
- return -1;
+ int idx;
+ object_member_lookup(cl, name, namelen, &idx);
+ return idx;
}
/*
@@ -2128,8 +2135,31 @@ object_member_idx(class_T *cl, char_u *name, size_t namelen)
ocmember_T *
object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
{
- *idx = object_member_idx(cl, name, namelen);
- return *idx >= 0 ? &cl->class_obj_members[*idx] : NULL;
+ ocmember_T *ret_m = NULL;
+ int ret_idx = -1;
+ for (int i = 0; i < cl->class_obj_member_count; ++i)
+ {
+ ocmember_T *m = &cl->class_obj_members[i];
+ if (namelen)
+ {
+ if (STRNCMP(name, m->ocm_name, namelen) == 0
+ && m->ocm_name[namelen] == NUL)
+ {
+ ret_m = m;
+ ret_idx = i;
+ break;
+ }
+ }
+ else if (STRCMP(name, m->ocm_name) == 0)
+ {
+ ret_m = m;
+ ret_idx = i;
+ break;
+ }
+ }
+ if (idx != NULL)
+ *idx = ret_idx;
+ return ret_m;
}
/*
@@ -2139,17 +2169,9 @@ object_member_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
int
object_method_idx(class_T *cl, char_u *name, size_t namelen)
{
- for (int i = 0; i < cl->class_obj_method_count; ++i)
- {
- ufunc_T *fp = cl->class_obj_methods[i];
- // Use a separate pointer to avoid that ASAN complains about
- // uf_name[] only being 4 characters.
- char_u *ufname = (char_u *)fp->uf_name;
- if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
- return i;
- }
-
- return -1;
+ int idx;
+ object_method_lookup(cl, name, namelen, &idx);
+ return idx;
}
/*
@@ -2160,8 +2182,24 @@ object_method_idx(class_T *cl, char_u *name, size_t namelen)
ufunc_T *
object_method_lookup(class_T *cl, char_u *name, size_t namelen, int *idx)
{
- *idx = object_method_idx(cl, name, namelen);
- return *idx >= 0 ? cl->class_obj_methods[*idx] : NULL;
+ ufunc_T *ret_fp = NULL;
+ int ret_idx = -1;
+ for (int i = 0; i < cl->class_obj_method_count; ++i)
+ {
+ ufunc_T *fp = cl->class_obj_methods[i];
+ // Use a separate pointer to avoid that ASAN complains about
+ // uf_name[] only being 4 characters.
+ char_u *ufname = (char_u *)fp->uf_name;
+ if (STRNCMP(name, ufname, namelen) == 0 && ufname[namelen] == NUL)
+ {
+ ret_fp = fp;
+ ret_idx = i;
+ break;
+ }
+ }
+ if (idx != NULL)
+ *idx = ret_idx;
+ return ret_fp;
}
/*
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 0315f4f7bb..120a606277 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -394,10 +394,10 @@ compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
if (type->tt_type == VAR_OBJECT)
{
- int m_idx = object_member_idx(cl, name, len);
+ int m_idx;
+ ocmember_T *m = object_member_lookup(cl, name, len, &m_idx);
if (m_idx >= 0)
{
- ocmember_T *m = &cl->class_obj_members[m_idx];
if (*name == '_' && !inside_class(cctx, cl))
{
semsg(_(e_cannot_access_private_member_str), m->ocm_name);
diff --git a/src/vim9instr.c b/src/vim9instr.c
index dcbe897cda..ccec0bcc38 100644
--- a/src/vim9instr.c
+++ b/src/vim9instr.c
@@ -1838,9 +1838,7 @@ generate_CALL(
{
class_T *clp = mtype->tt_class;
char_u *aname = ((char_u **)ufunc->uf_args.ga_data)[i];
- int m_idx;
- ocmember_T *m = object_member_lookup(clp, aname, 0,
- &m_idx);
+ ocmember_T *m = object_member_lookup(clp, aname, 0, NULL);
if (m != NULL)
expected = m->ocm_type;
}