@@ -973,33 +973,36 @@ add_defer_item(int var_idx, int argcount, ectx_T *ectx)
973973 * Returns OK or FAIL.
974974 */
975975 static int
976- defer_command (int var_idx , int argcount , ectx_T * ectx )
976+ defer_command (int var_idx , int has_obj , int argcount , ectx_T * ectx )
977977{
978- list_T * l = add_defer_item (var_idx , argcount , ectx );
978+ int obj_off = has_obj ? 1 : 0 ;
979+ list_T * l = add_defer_item (var_idx , argcount + obj_off , ectx );
979980 int i ;
980981 typval_T * func_tv ;
981982
982983 if (l == NULL )
983984 return FAIL ;
984985
985986 func_tv = STACK_TV_BOT (- argcount - 1 );
986- if (func_tv -> v_type != VAR_FUNC && func_tv -> v_type != VAR_PARTIAL )
987+ if (has_obj ? func_tv -> v_type != VAR_PARTIAL : func_tv -> v_type != VAR_FUNC )
987988 {
988989 semsg (_ (e_expected_str_but_got_str ),
989- "function or partial" ,
990+ has_obj ? " partial" : "function " ,
990991 vartype_name (func_tv -> v_type ));
991992 return FAIL ;
992993 }
993994 list_set_item (l , 0 , func_tv );
995+ if (has_obj )
996+ list_set_item (l , 1 , STACK_TV_BOT (- argcount - 2 ));
994997
995998 for (i = 0 ; i < argcount ; ++ i )
996- list_set_item (l , i + 1 , STACK_TV_BOT (- argcount + i ));
997- ectx -> ec_stack .ga_len -= argcount + 1 ;
999+ list_set_item (l , i + 1 + obj_off , STACK_TV_BOT (- argcount + i ));
1000+ ectx -> ec_stack .ga_len -= argcount + 1 + obj_off ;
9981001 return OK ;
9991002}
10001003
10011004/*
1002- * Add a deferred function "name" with one argument "arg_tv ".
1005+ * Add a deferred call for "name" with arguments "argvars[argcount] ".
10031006 * Consumes "name", also on failure.
10041007 * Only to be called when in_def_function() returns TRUE.
10051008 */
@@ -1056,19 +1059,31 @@ invoke_defer_funcs(ectx_T *ectx)
10561059 typval_T argvars [MAX_FUNC_ARGS ];
10571060 int i ;
10581061 listitem_T * arg_li = l -> lv_first ;
1059- funcexe_T funcexe ;
1062+ typval_T * functv = & l -> lv_first -> li_tv ;
1063+ int obj_off = functv -> v_type == VAR_PARTIAL ? 1 : 0 ;
1064+ int argcount = l -> lv_len - 1 - obj_off ;
10601065
1061- for (i = 0 ; i < l -> lv_len - 1 ; ++ i )
1066+ if (obj_off == 1 )
1067+ arg_li = arg_li -> li_next ; // second list item is the object
1068+ for (i = 0 ; i < argcount ; ++ i )
10621069 {
10631070 arg_li = arg_li -> li_next ;
10641071 argvars [i ] = arg_li -> li_tv ;
10651072 }
10661073
1074+ funcexe_T funcexe ;
10671075 CLEAR_FIELD (funcexe );
10681076 funcexe .fe_evaluate = TRUE;
10691077 rettv .v_type = VAR_UNKNOWN ;
1070- (void )call_func (l -> lv_first -> li_tv .vval .v_string , -1 ,
1071- & rettv , l -> lv_len - 1 , argvars , & funcexe );
1078+ if (functv -> v_type == VAR_PARTIAL )
1079+ {
1080+ funcexe .fe_partial = functv -> vval .v_partial ;
1081+ funcexe .fe_object = l -> lv_first -> li_next -> li_tv .vval .v_object ;
1082+ if (funcexe .fe_object != NULL )
1083+ ++ funcexe .fe_object -> obj_refcount ;
1084+ }
1085+ (void )call_func (functv -> vval .v_string , -1 ,
1086+ & rettv , argcount , argvars , & funcexe );
10721087 clear_tv (& rettv );
10731088 }
10741089}
@@ -4170,7 +4185,9 @@ exec_instructions(ectx_T *ectx)
41704185
41714186 // :defer func(arg)
41724187 case ISN_DEFER :
4188+ case ISN_DEFEROBJ :
41734189 if (defer_command (iptr -> isn_arg .defer .defer_var_idx ,
4190+ iptr -> isn_type == ISN_DEFEROBJ ,
41744191 iptr -> isn_arg .defer .defer_argcount , ectx ) == FAIL )
41754192 goto on_error ;
41764193 break ;
@@ -6640,7 +6657,9 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
66406657 smsg ("%s%4d PCALL end" , pfx , current );
66416658 break ;
66426659 case ISN_DEFER :
6643- smsg ("%s%4d DEFER %d args" , pfx , current ,
6660+ case ISN_DEFEROBJ :
6661+ smsg ("%s%4d %s %d args" , pfx , current ,
6662+ iptr -> isn_type == ISN_DEFER ? "DEFER" : "DEFEROBJ" ,
66446663 (int )iptr -> isn_arg .defer .defer_argcount );
66456664 break ;
66466665 case ISN_RETURN :
0 commit comments