@@ -1871,6 +1871,30 @@ vm_call_iseq_setup_normal_opt_start(rb_execution_context_t *ec, rb_control_frame
1871
1871
return vm_call_iseq_setup_normal (ec , cfp , calling , cc -> me , opt_pc , param - delta , local );
1872
1872
}
1873
1873
1874
+ static VALUE
1875
+ vm_call_iseq_setup_tailcall_opt_start (rb_execution_context_t * ec , rb_control_frame_t * cfp ,
1876
+ struct rb_calling_info * calling ,
1877
+ const struct rb_call_info * ci , struct rb_call_cache * cc )
1878
+ {
1879
+ const rb_iseq_t * iseq = def_iseq_ptr (cc -> me -> def );
1880
+ const int lead_num = iseq -> body -> param .lead_num ;
1881
+ const int opt = calling -> argc - lead_num ;
1882
+ const int opt_pc = (int )iseq -> body -> param .opt_table [opt ];
1883
+
1884
+ RB_DEBUG_COUNTER_INC (ccf_iseq_opt );
1885
+
1886
+ #if USE_OPT_HIST
1887
+ if (opt_pc < OPT_HIST_MAX ) {
1888
+ opt_hist [opt ]++ ;
1889
+ }
1890
+ else {
1891
+ opt_hist [OPT_HIST_MAX ]++ ;
1892
+ }
1893
+ #endif
1894
+
1895
+ return vm_call_iseq_setup_tailcall (ec , cfp , calling , ci , cc , opt_pc );
1896
+ }
1897
+
1874
1898
static void
1875
1899
args_setup_kw_parameters (rb_execution_context_t * const ec , const rb_iseq_t * const iseq ,
1876
1900
VALUE * const passed_values , const int passed_keyword_len , const VALUE * const passed_keywords ,
@@ -1957,9 +1981,16 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
1957
1981
argument_arity_error (ec , iseq , argc , lead_num , lead_num + opt_num );
1958
1982
}
1959
1983
1960
- CC_SET_FASTPATH (cc , vm_call_iseq_setup_normal_opt_start ,
1961
- !IS_ARGS_SPLAT (ci ) && !IS_ARGS_KEYWORD (ci ) &&
1962
- !(METHOD_ENTRY_VISI (cc -> me ) == METHOD_VISI_PROTECTED ));
1984
+ if (LIKELY (!(ci -> flag & VM_CALL_TAILCALL ))) {
1985
+ CC_SET_FASTPATH (cc , vm_call_iseq_setup_normal_opt_start ,
1986
+ !IS_ARGS_SPLAT (ci ) && !IS_ARGS_KEYWORD (ci ) &&
1987
+ !(METHOD_ENTRY_VISI (cc -> me ) == METHOD_VISI_PROTECTED ));
1988
+ }
1989
+ else {
1990
+ CC_SET_FASTPATH (cc , vm_call_iseq_setup_tailcall_opt_start ,
1991
+ !IS_ARGS_SPLAT (ci ) && !IS_ARGS_KEYWORD (ci ) &&
1992
+ !(METHOD_ENTRY_VISI (cc -> me ) == METHOD_VISI_PROTECTED ));
1993
+ }
1963
1994
1964
1995
/* initialize opt vars for self-references */
1965
1996
VM_ASSERT ((int )iseq -> body -> param .size == lead_num + opt_num );
0 commit comments