@@ -5274,14 +5274,13 @@ vm_invoke_iseq_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
52745274 return Qundef ;
52755275}
52765276
5277- static VALUE
5278- vm_invoke_iseq_block_cc_param_1_local_1 (rb_execution_context_t * ec , rb_control_frame_t * reg_cfp ,
5279- struct rb_calling_info * calling ) {
5277+ static inline VALUE
5278+ vm_invoke_iseq_positional_block (rb_execution_context_t * ec , rb_control_frame_t * reg_cfp ,
5279+ struct rb_calling_info * calling , int arg_size , const int param_size , const int local_table_size ) {
52805280 VALUE block_handler = VM_CF_BLOCK_HANDLER (GET_CFP ());
52815281 const struct rb_captured_block * captured = VM_BH_TO_ISEQ_BLOCK (block_handler );
52825282 const rb_iseq_t * iseq = rb_iseq_check (captured -> code .iseq );
5283- const int arg_size = 1 ;
5284- VALUE * const rsp = GET_SP () - 1 ;
5283+ VALUE * const rsp = GET_SP () - arg_size ;
52855284
52865285 SET_SP (rsp );
52875286
@@ -5290,32 +5289,32 @@ vm_invoke_iseq_block_cc_param_1_local_1(rb_execution_context_t *ec, rb_control_f
52905289 captured -> self ,
52915290 VM_GUARDED_PREV_EP (captured -> ep ), 0 ,
52925291 ISEQ_BODY (iseq )-> iseq_encoded ,
5293- rsp + arg_size ,
5294- 1 - arg_size , ISEQ_BODY (iseq )-> stack_max );
5292+ rsp + param_size ,
5293+ local_table_size - param_size , ISEQ_BODY (iseq )-> stack_max );
52955294
52965295 return Qundef ;
52975296}
52985297
5298+ static VALUE
5299+ vm_invoke_iseq_block_cc_arg1_param1_local1 (rb_execution_context_t * ec , rb_control_frame_t * reg_cfp ,
5300+ struct rb_calling_info * calling ) {
5301+ return vm_invoke_iseq_positional_block (ec , reg_cfp , calling , 1 , 1 , 1 );
5302+ }
5303+
52995304static VALUE
53005305vm_invoke_iseq_block_cc (rb_execution_context_t * ec , rb_control_frame_t * reg_cfp ,
53015306 struct rb_calling_info * calling ) {
5307+
53025308 VALUE block_handler = VM_CF_BLOCK_HANDLER (GET_CFP ());
53035309 const struct rb_captured_block * captured = VM_BH_TO_ISEQ_BLOCK (block_handler );
53045310 const rb_iseq_t * iseq = rb_iseq_check (captured -> code .iseq );
5305- const int arg_size = ISEQ_BODY (iseq )-> param .size ;
5306- VALUE * const rsp = GET_SP () - calling -> argc ;
53075311
5308- SET_SP (rsp );
5309-
5310- vm_push_frame (ec , iseq ,
5311- VM_FRAME_MAGIC_BLOCK ,
5312- captured -> self ,
5313- VM_GUARDED_PREV_EP (captured -> ep ), 0 ,
5314- ISEQ_BODY (iseq )-> iseq_encoded ,
5315- rsp + arg_size ,
5316- ISEQ_BODY (iseq )-> local_table_size - arg_size , ISEQ_BODY (iseq )-> stack_max );
5317-
5318- return Qundef ;
5312+ return vm_invoke_iseq_positional_block (ec ,
5313+ reg_cfp ,
5314+ calling ,
5315+ calling -> argc ,
5316+ ISEQ_BODY (iseq )-> param .size ,
5317+ ISEQ_BODY (iseq )-> local_table_size );
53195318}
53205319
53215320static VALUE
@@ -6019,36 +6018,70 @@ vm_invokeblock_fastpath(struct rb_execution_context_struct *ec,
60196018 ret = cd -> cc ;
60206019 }
60216020 else {
6022- if (rb_simple_iseq_p (callee_iseq ) &&
6023- (vm_ci_flag (ci ) & VM_CALL_ARGS_SIMPLE ) &&
6024- vm_ci_argc (ci ) == (unsigned int )ISEQ_BODY (callee_iseq )-> param .size &&
6025- ISEQ_BODY (callee_iseq )-> param .flags .ambiguous_param0 ) {
6021+ if (rb_simple_iseq_p (callee_iseq )) {
6022+ if (vm_ci_flag (ci ) & VM_CALL_ARGS_SIMPLE ) {
6023+ if ((unsigned int )ISEQ_BODY (callee_iseq )-> param .size == 0 && vm_ci_argc (ci ) > 0 ) {
6024+ fprintf (stderr , "ignored params %d %d\n" , vm_ci_argc (ci ), ISEQ_BODY (callee_iseq )-> local_table_size );
6025+ }
60266026
6027- if (!ISEQ_BODY (callee_iseq )-> block_ccs ) {
6028- ISEQ_BODY (callee_iseq )-> block_ccs = ZALLOC (struct rb_class_cc_entries );
6029- }
6027+ if (vm_ci_argc (ci ) == (unsigned int )ISEQ_BODY (callee_iseq )-> param .size &&
6028+ ISEQ_BODY (callee_iseq )-> param .flags .ambiguous_param0 ) {
6029+
6030+ if (!ISEQ_BODY (callee_iseq )-> block_ccs ) {
6031+ ISEQ_BODY (callee_iseq )-> block_ccs = ZALLOC (struct rb_class_cc_entries );
6032+ }
60306033
6031- struct rb_class_cc_entries * ccs = ISEQ_BODY (callee_iseq )-> block_ccs ;
6032- unsigned int argc = vm_ci_argc (ci );
6033- unsigned int flag = vm_ci_flag (ci );
6034+ struct rb_class_cc_entries * ccs = ISEQ_BODY (callee_iseq )-> block_ccs ;
6035+ unsigned int argc = vm_ci_argc (ci );
6036+ unsigned int flag = vm_ci_flag (ci );
60346037
6035- for (int i = 0 ; i < ccs -> len ; i ++ ) {
6036- if (ccs -> entries [i ].argc == argc && ccs -> entries [i ].flag == flag ) {
6037- return ccs -> entries [i ].cc ;
6038- }
6039- }
6038+ for (int i = 0 ; i < ccs -> len ; i ++ ) {
6039+ if (ccs -> entries [i ].argc == argc && ccs -> entries [i ].flag == flag ) {
6040+ return ccs -> entries [i ].cc ;
6041+ }
6042+ }
6043+
6044+ if (argc == 1 && ISEQ_BODY (callee_iseq )-> local_table_size == 1 ) {
6045+ ret = vm_cc_new ((VALUE )callee_iseq , NULL , vm_invoke_iseq_block_cc_arg1_param1_local1 , cc_type_block );
6046+ }
6047+ else {
6048+ ret = vm_cc_new ((VALUE )callee_iseq , NULL , vm_invoke_iseq_block_cc , cc_type_block );
6049+ }
60406050
6041- if (argc == 1 && ISEQ_BODY (callee_iseq )-> local_table_size == 1 ) {
6042- ret = vm_cc_new ((VALUE )callee_iseq , NULL , vm_invoke_iseq_block_cc_param_1_local_1 , cc_type_block );
6051+ cd -> cc = ret ;
6052+ RB_OBJ_WRITTEN (reg_cfp -> iseq , Qundef , ret );
6053+ vm_ccs_push ((VALUE )callee_iseq , ISEQ_BODY (callee_iseq )-> block_ccs , ci , ret );
6054+ RUBY_ASSERT (ret -> klass == (VALUE )callee_iseq );
6055+ }
6056+ else {
6057+ /*
6058+ if (vm_ci_argc(ci) != (unsigned int)ISEQ_BODY(callee_iseq)->param.size) {
6059+ fprintf(stderr, "args don't match argc %d param size %d\n",
6060+ vm_ci_argc(ci),
6061+ ISEQ_BODY(callee_iseq)->param.size);
6062+ }
6063+ */
6064+ }
60436065 }
60446066 else {
6045- ret = vm_cc_new ((VALUE )callee_iseq , NULL , vm_invoke_iseq_block_cc , cc_type_block );
6067+ /*
6068+ if (!(vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)) {
6069+ fprintf(stderr, "callsite not simple\n");
6070+ }
6071+ if (!ISEQ_BODY(callee_iseq)->param.flags.ambiguous_param0) {
6072+ rb_obj_info_dump((VALUE)reg_cfp->iseq);
6073+ rb_obj_info_dump((VALUE)callee_iseq);
6074+ fprintf(stderr, "not ambiguous param?\n");
6075+ }
6076+ */
60466077 }
6047-
6048- cd -> cc = ret ;
6049- RB_OBJ_WRITTEN (reg_cfp -> iseq , Qundef , ret );
6050- vm_ccs_push ((VALUE )callee_iseq , ISEQ_BODY (callee_iseq )-> block_ccs , ci , ret );
6051- RUBY_ASSERT (ret -> klass == (VALUE )callee_iseq );
6078+ }
6079+ else {
6080+ /*
6081+ if (!rb_simple_iseq_p(callee_iseq)) {
6082+ fprintf(stderr, "iseq not simple\n");
6083+ }
6084+ */
60526085 }
60536086 }
60546087 }
0 commit comments