@@ -2262,7 +2262,8 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
22622262 class_T * itf = iptr -> isn_arg .storeindex .si_class ;
22632263 if (itf != NULL )
22642264 // convert interface member index to class member index
2265- idx = object_index_from_itf_index (itf , idx , obj -> obj_class );
2265+ idx = object_index_from_itf_index (itf , FALSE,
2266+ idx , obj -> obj_class );
22662267
22672268 clear_tv (& otv [idx ]);
22682269 otv [idx ] = * tv ;
@@ -2950,6 +2951,20 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
29502951 return OK ;
29512952}
29522953
2954+
2955+ static void
2956+ object_required_error (typval_T * tv )
2957+ {
2958+ garray_T type_list ;
2959+ ga_init2 (& type_list , sizeof (type_T * ), 10 );
2960+ type_T * type = typval2type (tv , get_copyID (), & type_list , TVTT_DO_MEMBER );
2961+ char * tofree = NULL ;
2962+ char * typename = type_name (type , & tofree );
2963+ semsg (_ (e_object_required_found_str ), typename );
2964+ vim_free (tofree );
2965+ clear_type_list (& type_list );
2966+ }
2967+
29532968/*
29542969 * Execute instructions in execution context "ectx".
29552970 * Return OK or FAIL;
@@ -4125,6 +4140,30 @@ exec_instructions(ectx_T *ectx)
41254140 goto on_error ;
41264141 break ;
41274142
4143+ // call a method on an interface
4144+ case ISN_METHODCALL :
4145+ {
4146+ SOURCING_LNUM = iptr -> isn_lnum ;
4147+ tv = STACK_TV_BOT (-1 );
4148+ if (tv -> v_type != VAR_OBJECT )
4149+ {
4150+ object_required_error (tv );
4151+ goto on_error ;
4152+ }
4153+ object_T * obj = tv -> vval .v_object ;
4154+ class_T * cl = obj -> obj_class ;
4155+
4156+ // convert the interface index to the object index
4157+ cmfunc_T * mfunc = iptr -> isn_arg .mfunc ;
4158+ int idx = object_index_from_itf_index (mfunc -> cmf_itf ,
4159+ TRUE, mfunc -> cmf_idx , cl );
4160+
4161+ if (call_ufunc (cl -> class_obj_methods [idx ], NULL ,
4162+ mfunc -> cmf_argcount , ectx , NULL , NULL ) == FAIL )
4163+ goto on_error ;
4164+ }
4165+ break ;
4166+
41284167 // call a builtin function
41294168 case ISN_BCALL :
41304169 SOURCING_LNUM = iptr -> isn_lnum ;
@@ -5213,15 +5252,7 @@ exec_instructions(ectx_T *ectx)
52135252 if (tv -> v_type != VAR_OBJECT )
52145253 {
52155254 SOURCING_LNUM = iptr -> isn_lnum ;
5216- garray_T type_list ;
5217- ga_init2 (& type_list , sizeof (type_T * ), 10 );
5218- type_T * type = typval2type (tv , get_copyID (),
5219- & type_list , TVTT_DO_MEMBER );
5220- char * tofree = NULL ;
5221- char * typename = type_name (type , & tofree );
5222- semsg (_ (e_object_required_found_str ), typename );
5223- vim_free (tofree );
5224- clear_type_list (& type_list );
5255+ object_required_error (tv );
52255256 goto on_error ;
52265257 }
52275258
@@ -5234,8 +5265,8 @@ exec_instructions(ectx_T *ectx)
52345265 idx = iptr -> isn_arg .classmember .cm_idx ;
52355266 // convert the interface index to the object index
52365267 idx = object_index_from_itf_index (
5237- iptr -> isn_arg .classmember .cm_class ,
5238- idx , obj -> obj_class );
5268+ iptr -> isn_arg .classmember .cm_class ,
5269+ FALSE, idx , obj -> obj_class );
52395270 }
52405271
52415272 // the members are located right after the object struct
@@ -6637,6 +6668,17 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
66376668 cdfunc -> cdf_argcount );
66386669 }
66396670 break ;
6671+ case ISN_METHODCALL :
6672+ {
6673+ cmfunc_T * mfunc = iptr -> isn_arg .mfunc ;
6674+
6675+ smsg ("%s%4d METHODCALL %s.%s(argc %d)" , pfx , current ,
6676+ mfunc -> cmf_itf -> class_name ,
6677+ mfunc -> cmf_itf -> class_obj_methods [
6678+ mfunc -> cmf_idx ]-> uf_name ,
6679+ mfunc -> cmf_argcount );
6680+ }
6681+ break ;
66406682 case ISN_UCALL :
66416683 {
66426684 cufunc_T * cufunc = & iptr -> isn_arg .ufunc ;
0 commit comments