@@ -3069,6 +3069,9 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
3069
3069
const struct rb_callinfo * ci = calling -> cd -> ci ;
3070
3070
const struct rb_callcache * cc = calling -> cc ;
3071
3071
3072
+ VM_ASSERT ((vm_ci_argc (ci ), 1 ));
3073
+ VM_ASSERT (vm_cc_cme (cc ) != NULL );
3074
+
3072
3075
if (UNLIKELY (!ISEQ_BODY (iseq )-> param .flags .use_block &&
3073
3076
calling -> block_handler != VM_BLOCK_HANDLER_NONE &&
3074
3077
!(vm_ci_flag (calling -> cd -> ci ) & VM_CALL_SUPER ))) {
@@ -4235,10 +4238,23 @@ vm_call_symbol(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
4235
4238
}
4236
4239
}
4237
4240
4238
- calling -> cd = & (struct rb_call_data ) {
4239
- .ci = & VM_CI_ON_STACK (mid , flags , argc , vm_ci_kwarg (ci )),
4240
- .cc = NULL ,
4241
+ struct rb_forwarding_call_data new_fcd = {
4242
+ .cd = {
4243
+ .ci = & VM_CI_ON_STACK (mid , flags , argc , vm_ci_kwarg (ci )),
4244
+ .cc = NULL ,
4245
+ },
4246
+ .caller_ci = NULL ,
4241
4247
};
4248
+
4249
+ if (!(vm_ci_flag (ci ) & VM_CALL_FORWARDING )) {
4250
+ calling -> cd = & new_fcd .cd ;
4251
+ }
4252
+ else {
4253
+ const struct rb_callinfo * caller_ci = ((struct rb_forwarding_call_data * )calling -> cd )-> caller_ci ;
4254
+ VM_ASSERT ((vm_ci_argc (caller_ci ), 1 ));
4255
+ new_fcd .caller_ci = caller_ci ;
4256
+ calling -> cd = (struct rb_call_data * )& new_fcd ;
4257
+ }
4242
4258
calling -> cc = & VM_CC_ON_STACK (klass ,
4243
4259
vm_call_general ,
4244
4260
{ .method_missing_reason = missing_reason },
@@ -4381,10 +4397,25 @@ vm_call_method_missing_body(rb_execution_context_t *ec, rb_control_frame_t *reg_
4381
4397
INC_SP (1 );
4382
4398
4383
4399
ec -> method_missing_reason = reason ;
4384
- calling -> cd = & (struct rb_call_data ) {
4385
- .ci = & VM_CI_ON_STACK (idMethodMissing , flag , argc , vm_ci_kwarg (orig_ci )),
4386
- .cc = NULL ,
4400
+
4401
+ struct rb_forwarding_call_data new_fcd = {
4402
+ .cd = {
4403
+ .ci = & VM_CI_ON_STACK (idMethodMissing , flag , argc , vm_ci_kwarg (orig_ci )),
4404
+ .cc = NULL ,
4405
+ },
4406
+ .caller_ci = NULL ,
4387
4407
};
4408
+
4409
+ if (!(flag & VM_CALL_FORWARDING )) {
4410
+ calling -> cd = & new_fcd .cd ;
4411
+ }
4412
+ else {
4413
+ const struct rb_callinfo * caller_ci = ((struct rb_forwarding_call_data * )calling -> cd )-> caller_ci ;
4414
+ VM_ASSERT ((vm_ci_argc (caller_ci ), 1 ));
4415
+ new_fcd .caller_ci = caller_ci ;
4416
+ calling -> cd = (struct rb_call_data * )& new_fcd ;
4417
+ }
4418
+
4388
4419
calling -> cc = & VM_CC_ON_STACK (Qundef , vm_call_general , {{ 0 }},
4389
4420
rb_callable_method_entry_without_refinements (CLASS_OF (calling -> recv ), idMethodMissing , NULL ));
4390
4421
return vm_call_method (ec , reg_cfp , calling );
0 commit comments