]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1895: Vim9: finding object method/member is inefficient v9.0.1895
authorErnie Rael <errael@raelity.com>
Mon, 11 Sep 2023 17:54:42 +0000 (19:54 +0200)
committerChristian Brabandt <cb@256bit.org>
Mon, 11 Sep 2023 17:57:52 +0000 (19:57 +0200)
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>
src/version.c
src/vim9class.c
src/vim9expr.c
src/vim9instr.c

index d37d1472105d72ec3844a15c341a154420b98f82..c56ef4ceac53dabb1de7268e8f88645898bb7740 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1895,
 /**/
     1894,
 /**/
index 15d2b091372dbf7557994e4451ebecc93d301496..ccc38183854456429ceb0c385ed66f6300fa6ee1 100644 (file)
@@ -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;
 }
 
 /*
index 0315f4f7bb13df1fb6be02e314685c5272f3d019..120a60627786a25b6f69b9b98d41fce75ccd9476 100644 (file)
@@ -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);
index dcbe897cdaa5bf660f6c9de4e671a7f04a98d005..ccec0bcc38224fe3e1c90b891d5abba898a08639 100644 (file)
@@ -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;
                }