comparison src/vim9execute.c @ 31920:f1a5e67e9a1b v9.0.1292

patch 9.0.1292: :defer may call the wrong method for an object Commit: https://github.com/vim/vim/commit/313e4724c3b4f6d7454b45b89da08f83a2a0c77e Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 8 20:55:27 2023 +0000 patch 9.0.1292: :defer may call the wrong method for an object Problem: :defer may call the wrong method for an object. (Ernie Rael) Solution: When en object is from a class that extends or implements, figure out the method to call at runtime. (closes #11910)
author Bram Moolenaar <Bram@vim.org>
date Wed, 08 Feb 2023 22:00:06 +0100
parents ffa11e2757e7
children 7b1cbb43506c
comparison
equal deleted inserted replaced
31919:b1b8848f5bb3 31920:f1a5e67e9a1b
4289 if (GA_GROW_FAILS(&ectx->ec_stack, 1)) 4289 if (GA_GROW_FAILS(&ectx->ec_stack, 1))
4290 { 4290 {
4291 vim_free(pt); 4291 vim_free(pt);
4292 goto theend; 4292 goto theend;
4293 } 4293 }
4294 if (extra == NULL || extra->fre_func_name == NULL) 4294 if (extra != NULL && extra->fre_class != NULL)
4295 {
4296 tv = STACK_TV_BOT(-1);
4297 if (tv->v_type != VAR_OBJECT)
4298 {
4299 object_required_error(tv);
4300 vim_free(pt);
4301 goto on_error;
4302 }
4303 object_T *obj = tv->vval.v_object;
4304 class_T *cl = obj->obj_class;
4305
4306 // convert the interface index to the object index
4307 int idx = object_index_from_itf_index(extra->fre_class,
4308 TRUE, extra->fre_method_idx, cl);
4309 ufunc = cl->class_obj_methods[idx];
4310 }
4311 else if (extra == NULL || extra->fre_func_name == NULL)
4295 { 4312 {
4296 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data) 4313 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data)
4297 + funcref->fr_dfunc_idx; 4314 + funcref->fr_dfunc_idx;
4298 4315
4299 ufunc = pt_dfunc->df_ufunc; 4316 ufunc = pt_dfunc->df_ufunc;
4300 } 4317 }
4301 else 4318 else
4319 {
4302 ufunc = find_func(extra->fre_func_name, FALSE); 4320 ufunc = find_func(extra->fre_func_name, FALSE);
4321 }
4303 if (ufunc == NULL) 4322 if (ufunc == NULL)
4304 { 4323 {
4305 SOURCING_LNUM = iptr->isn_lnum; 4324 SOURCING_LNUM = iptr->isn_lnum;
4306 iemsg("ufunc unexpectedly NULL for FUNCREF"); 4325 iemsg("ufunc unexpectedly NULL for FUNCREF");
4307 goto theend; 4326 goto theend;
6725 + funcref->fr_dfunc_idx; 6744 + funcref->fr_dfunc_idx;
6726 name = df->df_ufunc->uf_name; 6745 name = df->df_ufunc->uf_name;
6727 } 6746 }
6728 else 6747 else
6729 name = extra->fre_func_name; 6748 name = extra->fre_func_name;
6730 if (extra == NULL || extra->fre_loopvar_info.lvi_depth == 0) 6749 if (extra != NULL && extra->fre_class != NULL)
6750 {
6751 smsg("%s%4d FUNCREF %s.%s", pfx, current,
6752 extra->fre_class->class_name, name);
6753 }
6754 else if (extra == NULL
6755 || extra->fre_loopvar_info.lvi_depth == 0)
6756 {
6731 smsg("%s%4d FUNCREF %s", pfx, current, name); 6757 smsg("%s%4d FUNCREF %s", pfx, current, name);
6758 }
6732 else 6759 else
6733 { 6760 {
6734 char_u *info = printable_loopvarinfo( 6761 char_u *info = printable_loopvarinfo(
6735 &extra->fre_loopvar_info); 6762 &extra->fre_loopvar_info);
6736 6763