diff options
author | Ernie Rael <errael@raelity.com> | 2023-09-11 19:54:42 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-09-11 19:57:52 +0200 |
commit | 4d00b835c49ffc5c416b65ca466d6ad695cbd3d2 (patch) | |
tree | a3974d821ce403d6d5d28cd5cc151b16ef9f50fb /src | |
parent | f787ee8451a1f24de4ef3de48b78d5aa77d09829 (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>
Diffstat (limited to 'src')
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9class.c | 158 | ||||
-rw-r--r-- | src/vim9expr.c | 4 | ||||
-rw-r--r-- | src/vim9instr.c | 4 |
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; } |