14 #include "insns_info.inc"
19 #include "ruby/config.h"
60 vm_stackoverflow(
void)
74 #ifdef USE_SIGALTSTACK
75 ec_stack_overflow(ec,
TRUE);
77 ec_stack_overflow(ec,
FALSE);
84 callable_class_p(
VALUE klass)
86 #if VM_CHECK_MODE >= 2
87 if (!klass)
return FALSE;
118 vm_check_frame_detail(
VALUE type,
int req_block,
int req_me,
int req_cref,
VALUE specval,
VALUE cref_or_me,
int is_cframe,
const rb_iseq_t *iseq)
131 rb_bug(
"vm_push_frame: specval (%p) should be a block_ptr on %x frame", (
void *)specval, magic);
134 rb_bug(
"vm_push_frame: specval (%p) should not be a block_ptr on %x frame", (
void *)specval, magic);
139 rb_bug(
"vm_push_frame: (%s) should be method entry on %x frame",
rb_obj_info(cref_or_me), magic);
143 if (req_cref && cref_or_me_type !=
imemo_cref) {
144 rb_bug(
"vm_push_frame: (%s) should be CREF on %x frame",
rb_obj_info(cref_or_me), magic);
152 rb_bug(
"vm_push_frame: (%s) should be false or cref on %x frame",
rb_obj_info(cref_or_me), magic);
161 if (!callable_method_entry_p(me)) {
162 rb_bug(
"vm_push_frame: ment (%s) should be callable on %x frame.",
rb_obj_info(cref_or_me), magic);
168 RUBY_VM_NORMAL_ISEQ_P(iseq) );
171 VM_ASSERT(is_cframe == !RUBY_VM_NORMAL_ISEQ_P(iseq));
184 #define CHECK(magic, req_block, req_me, req_cref, is_cframe) \
186 vm_check_frame_detail(type, req_block, req_me, req_cref, \
187 specval, cref_or_me, is_cframe, iseq); \
189 switch (given_magic) {
201 rb_bug(
"vm_push_frame: unknown type (%x)", (
unsigned int)given_magic);
206 static VALUE vm_stack_canary;
207 static bool vm_stack_canary_was_born =
false;
215 if (!
LIKELY(vm_stack_canary_was_born)) {
225 else if (
LIKELY(sp[0] != vm_stack_canary)) {
236 const ptrdiff_t pos =
GET_PC() - encoded;
237 const enum ruby_vminsn_type insn = (
enum ruby_vminsn_type)orig[pos];
238 const char *
name = insn_name(insn);
249 "We are killing the stack canary set by %s, "
251 "watch out the C stack trace.\n"
253 name, stri, pos, strd);
257 #define vm_check_canary(ec, sp)
258 #define vm_check_frame(a, b, c, d)
293 for (
int i=0; i < local_size; i++) {
309 #if VM_DEBUG_BP_CHECK
310 cfp->bp_check = sp + 1;
317 #if USE_DEBUG_COUNTER
329 default:
rb_bug(
"unreachable");
333 if (RUBY_VM_END_CONTROL_FRAME(ec) != prev_cfp) {
334 int cur_ruby_frame = VM_FRAME_RUBYFRAME_P(cfp);
335 int pre_ruby_frame = VM_FRAME_RUBYFRAME_P(prev_cfp);
366 vm_pop_frame(ec, ec->
cfp, ec->
cfp->
ep);
371 rb_arity_error_new(
int argc,
int min,
int max)
375 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d)",
argc, min);
378 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d+)",
argc, min);
381 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d..%d)",
argc, min, max);
401 VM_FORCE_WRITE(&ep[
index], v);
411 VM_STACK_ENV_WRITE(ep,
index, v);
414 vm_env_write_slowpath(ep,
index, v);
425 switch (vm_block_handler_type(block_handler)) {
428 return rb_vm_make_proc(ec, VM_BH_TO_CAPT_BLOCK(block_handler),
rb_cProc);
432 return VM_BH_TO_PROC(block_handler);
441 #if VM_CHECK_MODE > 0
443 vm_svar_valid_p(
VALUE svar)
493 const struct vm_svar *svar = lep_svar(ec, lep);
499 return svar->lastline;
501 return svar->backref;
503 const VALUE ary = svar->others;
524 struct vm_svar *svar = lep_svar(ec, lep);
527 lep_svar_write(ec, lep, svar = svar_new((
VALUE)svar));
538 VALUE ary = svar->others;
554 val = lep_svar_get(ec, lep,
key);
574 rb_bug(
"unexpected back-ref");
586 check_method_entry(
VALUE obj,
int can_be_svar)
590 #if VM_CHECK_MODE > 0
604 #if VM_CHECK_MODE > 0
605 rb_bug(
"check_method_entry: svar should not be there:");
617 while (!VM_ENV_LOCAL_P(ep)) {
619 ep = VM_ENV_PREV_EP(ep);
628 switch (me->
def->type) {
636 #if VM_CHECK_MODE == 0
640 check_cref(
VALUE obj,
int can_be_svar)
644 #if VM_CHECK_MODE > 0
658 #if VM_CHECK_MODE > 0
659 rb_bug(
"check_method_entry: svar should not be there:");
666 vm_env_cref(
const VALUE *ep)
670 while (!VM_ENV_LOCAL_P(ep)) {
672 ep = VM_ENV_PREV_EP(ep);
679 is_cref(
const VALUE v,
int can_be_svar)
695 vm_env_cref_by_cref(
const VALUE *ep)
697 while (!VM_ENV_LOCAL_P(ep)) {
699 ep = VM_ENV_PREV_EP(ep);
705 cref_replace_with_duplicated_cref_each_frame(
const VALUE *vptr,
int can_be_svar,
VALUE parent)
707 const VALUE v = *vptr;
714 new_cref = vm_cref_dup(cref);
719 VM_FORCE_WRITE(vptr, (
VALUE)new_cref);
728 rb_bug(
"cref_replace_with_duplicated_cref_each_frame: unreachable");
737 vm_cref_replace_with_duplicated_cref(
const VALUE *ep)
739 if (vm_env_cref_by_cref(ep)) {
743 while (!VM_ENV_LOCAL_P(ep)) {
744 envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) :
Qfalse;
748 ep = VM_ENV_PREV_EP(ep);
750 envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) :
Qfalse;
754 rb_bug(
"vm_cref_dup: unreachable");
759 vm_get_cref(
const VALUE *ep)
767 rb_bug(
"vm_get_cref: unreachable");
779 return vm_get_cref(cfp->
ep);
783 vm_get_const_key_cref(
const VALUE *ep)
793 cref = CREF_NEXT(cref);
806 if (CREF_CLASS(cref) == old_klass) {
808 *new_cref_ptr = new_cref;
812 cref = CREF_NEXT(cref);
813 *new_cref_ptr = new_cref;
816 *new_cref_ptr =
NULL;
825 prev_cref = vm_env_cref(ep);
831 prev_cref = vm_env_cref(cfp->
ep);
839 vm_get_cbase(
const VALUE *ep)
845 if ((klass = CREF_CLASS(cref)) != 0) {
848 cref = CREF_NEXT(cref);
855 vm_get_const_base(
const VALUE *ep)
861 if (!CREF_PUSHED_BY_EVAL(cref) &&
862 (klass = CREF_CLASS(cref)) != 0) {
865 cref = CREF_NEXT(cref);
872 vm_check_if_namespace(
VALUE klass)
880 vm_ensure_not_refinement_module(
VALUE self)
883 rb_warn(
"not defined at the refinement, but at the outer class/module");
899 if (orig_klass ==
Qnil && allow_nil) {
905 while (root_cref && CREF_PUSHED_BY_EVAL(root_cref)) {
906 root_cref = CREF_NEXT(root_cref);
909 while (cref && CREF_NEXT(cref)) {
910 if (CREF_PUSHED_BY_EVAL(cref)) {
914 klass = CREF_CLASS(cref);
916 cref = CREF_NEXT(cref);
926 if (am == klass)
break;
928 if (is_defined)
return 1;
931 goto search_continue;
946 if (root_cref && !
NIL_P(CREF_CLASS(root_cref))) {
947 klass = vm_get_iclass(ec->
cfp, CREF_CLASS(root_cref));
961 vm_check_if_namespace(orig_klass);
977 rb_bug(
"vm_get_cvar_base: no cref");
980 while (CREF_NEXT(cref) &&
982 CREF_PUSHED_BY_EVAL(cref))) {
983 cref = CREF_NEXT(cref);
985 if (!CREF_NEXT(cref)) {
986 rb_warn(
"class variable access from toplevel");
989 klass = vm_get_iclass(cfp, CREF_CLASS(cref));
998 vm_search_const_defined_class(
const VALUE cbase,
ID id)
1021 else if (
LIKELY(is_attr ?
1038 val = ivtbl->
ivptr[index];
1057 if (
st_lookup(iv_index_tbl,
id, &index)) {
1066 if (index < numiv) {
1076 numiv = ivtbl->numiv;
1077 ivptr = ivtbl->ivptr;
1140 else if (index >= INT_MAX) {
1159 vm_getinstancevariable(
VALUE obj,
ID id,
IVC ic)
1161 return vm_getivar(obj,
id, ic,
NULL,
FALSE);
1167 vm_setivar(obj,
id, val, ic, 0, 0);
1192 const int flag,
const VALUE throwobj)
1204 escape_cfp = reg_cfp;
1206 while (base_iseq->
body->
type != ISEQ_TYPE_BLOCK) {
1209 ep = escape_cfp->
ep;
1210 base_iseq = escape_cfp->
iseq;
1213 ep = VM_ENV_PREV_EP(ep);
1215 escape_cfp = rb_vm_search_cf_from_ep(ec, escape_cfp, ep);
1220 if (VM_FRAME_LAMBDA_P(escape_cfp)) {
1226 ep = VM_ENV_PREV_EP(ep);
1228 while (escape_cfp < eocfp) {
1229 if (escape_cfp->
ep == ep) {
1236 for (i=0; i < ct->size; i++) {
1241 entry->
iseq == base_iseq &&
1242 entry->
start < epc && entry->
end >= epc) {
1243 if (entry->
cont == epc) {
1263 escape_cfp = rb_vm_search_cf_from_ep(ec, reg_cfp, ep);
1267 const VALUE *target_lep = VM_EP_LEP(current_ep);
1268 int in_class_frame = 0;
1270 escape_cfp = reg_cfp;
1272 while (escape_cfp < eocfp) {
1273 const VALUE *lep = VM_CF_LEP(escape_cfp);
1279 if (lep == target_lep &&
1280 VM_FRAME_RUBYFRAME_P(escape_cfp) &&
1286 if (lep == target_lep) {
1287 if (VM_FRAME_LAMBDA_P(escape_cfp)) {
1289 if (in_class_frame) {
1294 const VALUE *tep = current_ep;
1296 while (target_lep != tep) {
1297 if (escape_cfp->
ep == tep) {
1301 tep = VM_ENV_PREV_EP(tep);
1305 else if (VM_FRAME_RUBYFRAME_P(escape_cfp)) {
1308 case ISEQ_TYPE_MAIN:
1310 if (in_class_frame)
goto unexpected_return;
1314 case ISEQ_TYPE_EVAL:
1315 case ISEQ_TYPE_CLASS:
1324 if (escape_cfp->
ep == target_lep && escape_cfp->
iseq->
body->
type == ISEQ_TYPE_METHOD) {
1337 rb_bug(
"isns(throw): unsupported throw type");
1341 return (
VALUE)THROW_DATA_NEW(throwobj, escape_cfp, state);
1352 return vm_throw_start(ec, reg_cfp, state, flag, throwobj);
1355 return vm_throw_continue(ec, throwobj);
1362 int is_splat = flag & 0x01;
1363 rb_num_t space_size = num + is_splat;
1367 const VALUE obj = ary;
1379 if (space_size == 0) {
1382 else if (flag & 0x02) {
1387 for (i=0; i<num-
len; i++) {
1391 for (j=0; i<num; i++, j++) {
1402 VALUE *bptr = &base[space_size - 1];
1404 for (i=0; i<num; i++) {
1406 for (; i<num; i++) {
1427 #ifdef __has_attribute
1428 #if __has_attribute(artificial)
1440 return vm_call_general;
1444 return vm_call_general;
1448 return vm_call_general;
1457 return vm_call_general;
1481 if (
call != vm_call_general) {
1596 for (; i > 0; i--) {
1610 #if OPT_INLINE_METHOD_CACHE
1613 vm_cache_check_for_class_serial(cc,
RCLASS_SERIAL(klass)))) {
1631 vm_search_method_fastpath(cd, klass);
1649 vm_search_method(cd, recv);
1650 return check_cfunc(cd->
cc.
me, func);
1656 if (vm_method_cfunc_is(cd, recv, rb_obj_equal)) {
1663 #define BUILTIN_CLASS_P(x, k) (!SPECIAL_CONST_P(x) && RBASIC_CLASS(x) == k)
1664 #define EQ_UNREDEFINED_P(t) BASIC_OP_UNREDEFINED_P(BOP_EQ, t##_REDEFINED_OP_FLAG)
1697 comparable_by_identity(
VALUE recv,
VALUE obj)
1699 if (FIXNUM_2_P(recv, obj)) {
1702 if (FLONUM_2_P(recv, obj)) {
1712 #ifndef NO_BIG_INLINE
1718 switch (comparable_by_identity(recv, obj)) {
1732 if (recv == obj)
return Qtrue;
1734 return rb_str_eql_internal(recv, obj);
1739 return opt_equal_fallback(recv, obj, cd);
1743 #ifndef NO_BIG_INLINE
1749 switch (comparable_by_identity(recv, obj)) {
1769 return opt_equal_fallback(recv, obj, cd);
1771 #undef BUILTIN_CLASS_P
1772 #undef EQ_UNREDEFINED_P
1779 return opt_eq_func(obj1, obj2, &cd);
1787 return opt_eql_func(obj1, obj2, &cd);
1815 rb_bug(
"check_match: unreachable");
1820 #if defined(_MSC_VER) && _MSC_VER < 1300
1821 #define CHECK_CMP_NAN(a, b) if (isnan(a) || isnan(b)) return Qfalse;
1823 #define CHECK_CMP_NAN(a, b)
1827 double_cmp_lt(
double a,
double b)
1834 double_cmp_le(
double a,
double b)
1841 double_cmp_gt(
double a,
double b)
1848 double_cmp_ge(
double a,
double b)
1854 static inline VALUE *
1857 #if 0 // we may optimize and use this once we confirm it does not spoil performance on JIT.
1860 if (cfp->
iseq && VM_FRAME_RUBYFRAME_P(cfp)) {
1866 #if VM_DEBUG_BP_CHECK
1867 if (
bp != cfp->bp_check) {
1868 fprintf(stderr,
"bp_check: %ld, bp: %ld\n",
1869 (
long)(cfp->bp_check -
GET_EC()->vm_stack),
1871 rb_bug(
"vm_base_ptr: unreachable");
1903 return vm_call_iseq_setup_tailcall(ec, cfp, calling, cd, 0);
1915 return vm_call_iseq_setup_normal(ec, cfp, calling, cc->
me, 0, param, local);
1931 rb_iseq_only_optparam_p(
const rb_iseq_t *iseq)
1943 rb_iseq_only_kwparam_p(
const rb_iseq_t *iseq)
1964 vm_caller_setup_arg_splat(cfp, calling);
1966 calling->argc > 0 &&
1970 calling->kw_splat = 1;
1978 vm_caller_setup_arg_kw(cfp, calling, ci);
1999 calling->kw_splat = 0;
2004 #define USE_OPT_HIST 0
2007 #define OPT_HIST_MAX 64
2008 static int opt_hist[OPT_HIST_MAX+1];
2012 opt_hist_show_results_at_exit(
void)
2014 for (
int i=0; i<OPT_HIST_MAX; i++) {
2015 fprintf(stderr,
"opt_hist\t%d\t%d\n", i, opt_hist[i]);
2028 const int opt = calling->
argc - lead_num;
2033 const int delta = opt_num - opt;
2038 if (opt_pc < OPT_HIST_MAX) {
2042 opt_hist[OPT_HIST_MAX]++;
2046 return vm_call_iseq_setup_normal(ec, cfp, calling, cc->
me, opt_pc, param - delta, local);
2057 const int opt = calling->
argc - lead_num;
2063 if (opt_pc < OPT_HIST_MAX) {
2067 opt_hist[OPT_HIST_MAX]++;
2071 return vm_call_iseq_setup_tailcall(ec, cfp, calling, cd, opt_pc);
2076 VALUE *
const passed_values,
const int passed_keyword_len,
const VALUE *
const passed_keywords,
2077 VALUE *
const locals);
2097 VALUE *
const klocals =
argv + kw_param->bits_start - kw_param->num;
2101 args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals);
2105 return vm_call_iseq_setup_normal(ec, cfp, calling, cc->
me, 0, param, local);
2122 VALUE *
const klocals =
argv + kw_param->bits_start - kw_param->num;
2125 for (i=0; i<kw_param->num; i++) {
2126 klocals[i] = kw_param->default_values[i];
2135 return vm_call_iseq_setup_normal(ec, cfp, calling, cc->
me, 0, param, local);
2148 CALLER_SETUP_ARG(cfp, calling, ci);
2149 CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
2155 CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size), vm_call_iseq_optimizable_p(&cd->
ci, &cd->
cc));
2158 else if (rb_iseq_only_optparam_p(iseq)) {
2160 CALLER_SETUP_ARG(cfp, calling, ci);
2161 CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
2166 const int opt =
argc - lead_num;
2168 if (opt < 0 || opt > opt_num) {
2169 argument_arity_error(ec, iseq,
argc, lead_num, lead_num + opt_num);
2173 CC_SET_FASTPATH(cc, vm_call_iseq_setup_normal_opt_start,
2178 CC_SET_FASTPATH(cc, vm_call_iseq_setup_tailcall_opt_start,
2185 for (
int i=
argc; i<lead_num + opt_num; i++) {
2190 else if (rb_iseq_only_kwparam_p(iseq) && !
IS_ARGS_SPLAT(ci)) {
2204 VALUE *
const klocals =
argv + kw_param->bits_start - kw_param->num;
2205 args_setup_kw_parameters(ec, iseq, ci_kws, ci_kw_len, ci_keywords, klocals);
2207 CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_kwarg,
2213 else if (
argc == lead_num) {
2215 VALUE *
const klocals =
argv + kw_param->bits_start - kw_param->num;
2216 args_setup_kw_parameters(ec, iseq,
NULL, 0,
NULL, klocals);
2218 if (klocals[kw_param->num] ==
INT2FIX(0)) {
2220 CC_SET_FASTPATH(cc, vm_call_iseq_setup_kwparm_nokwarg,
2241 const int opt_pc = vm_callee_setup_arg(ec, calling, cd, def_iseq_ptr(cc->
me->
def), cfp->
sp - calling->
argc, param_size, local_size);
2242 return vm_call_iseq_setup_2(ec, cfp, calling, cd, opt_pc, param_size, local_size);
2247 int opt_pc,
int param_size,
int local_size)
2253 return vm_call_iseq_setup_normal(ec, cfp, calling, cc->
me, opt_pc, param_size, local_size);
2256 return vm_call_iseq_setup_tailcall(ec, cfp, calling, cd, opt_pc);
2262 int opt_pc,
int param_size,
int local_size)
2272 local_size - param_size,
2287 VALUE *sp_orig, *sp;
2295 calling->
block_handler = VM_BH_FROM_ISEQ_BLOCK(dst_captured);
2298 calling->
block_handler = VM_BH_FROM_IFUNC_BLOCK(dst_captured);
2302 vm_pop_frame(ec, cfp, cfp->
ep);
2305 sp_orig = sp = cfp->
sp;
2308 sp[0] = calling->
recv;
2313 *sp++ = src_argv[i];
2349 return (*
f)(recv,
argv[0]);
2372 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2378 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2384 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2390 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2396 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2402 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2403 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9]);
2408 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2409 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10]);
2414 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2415 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11]);
2420 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2421 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12]);
2426 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2427 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12],
argv[13]);
2432 VALUE(*
f)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE) = (
VALUE(*)(
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE,
VALUE))func;
2433 return (*
f)(recv,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12],
argv[13],
argv[14]);
2448 #define CHECK_CFP_CONSISTENCY(func) \
2449 (LIKELY(vm_cfp_consistent_p(ec, reg_cfp)) ? (void)0 : \
2450 rb_bug(func ": cfp consistency error (%p, %p)", (void *)reg_cfp, (void *)(ec->cfp+1)))
2456 #if VM_DEBUG_VERIFY_METHOD_CACHE
2457 switch (me->
def->type) {
2461 # define METHOD_BUG(t) case VM_METHOD_TYPE_##t: rb_bug("wrong method type: " #t)
2463 METHOD_BUG(ATTRSET);
2465 METHOD_BUG(BMETHOD);
2468 METHOD_BUG(OPTIMIZED);
2469 METHOD_BUG(MISSING);
2470 METHOD_BUG(REFINED);
2474 rb_bug(
"wrong method type: %d", me->
def->type);
2495 int orig_argc =
argc;
2500 else if (
UNLIKELY(empty_kw_splat)) {
2507 vm_push_frame(ec,
NULL, frame_type, recv,
2509 0, ec->
cfp->
sp, 0, 0);
2513 reg_cfp->
sp -= orig_argc + 1;
2533 CALLER_SETUP_ARG(reg_cfp, calling, ci);
2534 empty_kw_splat = calling->
kw_splat;
2535 CALLER_REMOVE_EMPTY_KW_SPLAT(reg_cfp, calling, ci);
2536 if (empty_kw_splat && calling->
kw_splat) {
2539 return vm_call_cfunc_with_frame(ec, reg_cfp, calling, cd, empty_kw_splat);
2584 CALLER_SETUP_ARG(cfp, calling, ci);
2590 return vm_call_bmethod_body(ec, calling, cd,
argv);
2616 CALLER_SETUP_ARG(reg_cfp, calling, orig_ci);
2618 i = calling->
argc - 1;
2620 if (calling->
argc == 0) {
2630 cd.ci_kw.
ci = *orig_ci;
2647 ci->
mid = idMethodMissing;
2661 return vm_call_method(ec, reg_cfp, calling, (
CALL_DATA)&cd);
2680 return vm_invoke_block(ec, reg_cfp, calling, ci, block_handler);
2690 return vm_invoke_block_opt_call(ec, reg_cfp, calling, ci, VM_BH_FROM_PROC(procval));
2697 VALUE block_handler = VM_ENV_BLOCK_HANDLER(VM_CF_LEP(reg_cfp));
2701 return vm_invoke_block_opt_call(ec, reg_cfp, calling, ci, block_handler);
2705 vm_search_method(cd, calling->
recv);
2706 return vm_call_general(ec, reg_cfp, calling, cd);
2721 CALLER_SETUP_ARG(reg_cfp, calling, orig_ci);
2725 cd.
ci.
mid = idMethodMissing;
2730 idMethodMissing,
NULL);
2744 return vm_call_method(ec, reg_cfp, calling, &cd);
2759 return vm_call_method_nome(ec, cfp, calling, cd);
2763 CC_SET_ME(cc, refined_method_callable_without_refinement(cc->
me));
2765 return vm_call_method_each_type(ec, cfp, calling, cd);
2769 find_refinement(
VALUE refinements,
VALUE klass)
2771 if (
NIL_P(refinements)) {
2788 if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec, cfp)) {
2792 }
while (cfp->
iseq != local_iseq);
2798 find_defined_class_by_owner(
VALUE current_class,
VALUE target_owner)
2800 VALUE klass = current_class;
2805 while (
RTEST(klass)) {
2807 if (owner == target_owner) {
2813 return current_class;
2840 VM_ASSERT(callable_method_entry_p(cme));
2858 VM_ASSERT(callable_method_entry_p(cme));
2872 for (; cref; cref = CREF_NEXT(cref)) {
2873 const VALUE refinement = find_refinement(CREF_REFINEMENTS(cref), cc->
me->
owner);
2874 if (
NIL_P(refinement))
continue;
2880 if (cc->
call == vm_call_super_method) {
2889 CC_SET_ME(cc, ref_me);
2896 CC_SET_ME(cc,
NULL);
2902 CC_SET_ME(cc, refined_method_callable_without_refinement(cc->
me));
2917 switch (cc->
me->
def->type) {
2919 CC_SET_FASTPATH(cc, vm_call_iseq_setup,
TRUE);
2920 return vm_call_iseq_setup(ec, cfp, calling, cd);
2924 CC_SET_FASTPATH(cc, vm_call_cfunc,
TRUE);
2925 return vm_call_cfunc(ec, cfp, calling, cd);
2928 CALLER_SETUP_ARG(cfp, calling, ci);
2930 rb_warn_keyword_to_last_hash(ec, calling, ci,
NULL);
2933 CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
2939 return vm_call_attrset(ec, cfp, calling, cd);
2942 CALLER_SETUP_ARG(cfp, calling, ci);
2943 CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
2947 return vm_call_ivar(ec, cfp, calling, cd);
2951 CC_SET_FASTPATH(cc, vm_call_method_missing,
TRUE);
2952 return vm_call_method_missing(ec, cfp, calling, cd);
2955 CC_SET_FASTPATH(cc, vm_call_bmethod,
TRUE);
2956 return vm_call_bmethod(ec, cfp, calling, cd);
2959 CC_SET_ME(cc, aliased_callable_method_entry(cc->
me));
2961 return vm_call_method_each_type(ec, cfp, calling, cd);
2966 CC_SET_FASTPATH(cc, vm_call_opt_send,
TRUE);
2967 return vm_call_opt_send(ec, cfp, calling, cd);
2969 CC_SET_FASTPATH(cc, vm_call_opt_call,
TRUE);
2970 return vm_call_opt_call(ec, cfp, calling, cd);
2972 CC_SET_FASTPATH(cc, vm_call_opt_block_call,
TRUE);
2973 return vm_call_opt_block_call(ec, cfp, calling, cd);
2975 rb_bug(
"vm_call_method: unsupported optimized method type (%d)",
2986 if (search_refined_method(ec, cfp, ci->
mid, cc))
2987 return vm_call_method(ec, cfp, calling, cd);
2989 return vm_call_method_nome(ec, cfp, calling, cd);
2992 rb_bug(
"vm_call_method: unsupported method type (%d)", cc->
me->
def->type);
3003 const int stat = ci_missing_reason(ci);
3005 if (ci->
mid == idMethodMissing) {
3012 CC_SET_FASTPATH(cc, vm_call_method_missing,
TRUE);
3013 return vm_call_method_missing(ec, cfp, calling, cd);
3028 return vm_call_method_each_type(ec, cfp, calling, cd);
3036 CC_SET_FASTPATH(cc, vm_call_method_missing,
TRUE);
3037 return vm_call_method_missing(ec, cfp, calling, cd);
3039 return vm_call_method_each_type(ec, cfp, calling, cd);
3045 return vm_call_method_missing(ec, cfp, calling, cd);
3053 return vm_call_method_each_type(ec, cfp, calling, (
void *)&cd_entry);
3057 return vm_call_method_each_type(ec, cfp, calling, &cd_entry);
3061 return vm_call_method_each_type(ec, cfp, calling, cd);
3068 return vm_call_method_nome(ec, cfp, calling, cd);
3076 return vm_call_method(ec, reg_cfp, calling, cd);
3086 if (cc->
call != vm_call_super_method)
rb_bug(
"bug");
3087 return vm_call_method(ec, reg_cfp, calling, cd);
3093 vm_search_normal_superclass(
VALUE klass)
3097 klass =
RBASIC(klass)->klass;
3103 NORETURN(
static void vm_super_outside(
void));
3106 vm_super_outside(
void)
3114 VALUE current_defined_class, klass;
3137 "self has wrong type to call super in this context: "
3145 "implicit argument passing of super from method defined"
3146 " by define_method() is not supported."
3147 " Specify all arguments explicitly.");
3156 CC_SET_FASTPATH(cc, vm_call_method_missing,
TRUE);
3161 CC_SET_FASTPATH(cc, vm_call_super_method,
TRUE);
3168 block_proc_is_lambda(
const VALUE procval)
3187 int is_lambda =
FALSE;
3188 VALUE val, arg, blockarg;
3195 else if (
argc == 0) {
3219 0, ec->
cfp->
sp, 0, 0);
3248 vm_callee_setup_block_arg_arg0_check(
VALUE *
argv)
3267 CALLER_SETUP_ARG(cfp, calling, ci);
3269 rb_warn_keyword_to_last_hash(ec, calling, ci, iseq);
3272 CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
3276 calling->
argc == 1 &&
3279 !
NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(
argv))) {
3280 calling->
argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq,
argv, arg0);
3288 for (i=calling->
argc; i<iseq->body->param.lead_num; i++)
argv[i] =
Qnil;
3313 calling = &calling_entry;
3339 vm_push_frame(ec, iseq,
3357 CALLER_SETUP_ARG(ec->
cfp, calling, ci);
3372 CALLER_SETUP_ARG(ec->
cfp, calling, ci);
3373 CALLER_REMOVE_EMPTY_KW_SPLAT(ec->
cfp, calling, ci);
3374 if (kw_splat && !calling->
kw_splat) {
3387 vm_proc_to_block_handler(
VALUE procval)
3389 const struct rb_block *block = vm_proc_block(procval);
3391 switch (vm_block_type(block)) {
3393 return VM_BH_FROM_ISEQ_BLOCK(&block->
as.
captured);
3395 return VM_BH_FROM_IFUNC_BLOCK(&block->
as.
captured);
3397 return VM_BH_FROM_SYMBOL(block->
as.
symbol);
3399 return VM_BH_FROM_PROC(block->
as.
proc);
3409 int is_lambda =
FALSE;
3412 switch (vm_block_handler_type(block_handler)) {
3416 return vm_invoke_iseq_block(ec, reg_cfp, calling, ci, is_lambda, captured);
3421 return vm_invoke_ifunc_block(ec, reg_cfp, calling, ci, captured);
3424 is_lambda = block_proc_is_lambda(VM_BH_TO_PROC(block_handler));
3425 block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
3428 return vm_invoke_symbol_block(ec, reg_cfp, calling, ci, VM_BH_TO_SYMBOL(block_handler));
3435 vm_make_proc_with_iseq(
const rb_iseq_t *blockiseq)
3442 rb_bug(
"vm_make_proc_with_iseq: unreachable");
3445 captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
3448 return rb_vm_make_proc(ec, captured,
rb_cProc);
3459 vm_once_clear(
VALUE data)
3488 args[0] = obj; args[1] =
Qfalse;
3512 klass = vm_get_cbase(
GET_EP());
3521 klass = vm_get_cvar_base(cref,
GET_CFP());
3531 if (vm_get_ev_const(ec, klass,
SYM2ID(obj), allow_nil,
true)) {
3542 expr_type = check_respond_to_missing(obj, v);
3565 expr_type = check_respond_to_missing(obj, v);
3595 rb_bug(
"unimplemented defined? type (VM)");
3599 if (expr_type != 0) {
3612 static const VALUE *
3616 const VALUE *ep = reg_ep;
3617 for (i = 0; i < lv; i++) {
3624 vm_get_special_object(
const VALUE *
const reg_ep,
3631 return vm_get_cbase(reg_ep);
3633 return vm_get_const_base(reg_ep);
3635 rb_bug(
"putspecialobject insn: unknown value_type %d",
type);
3651 const VALUE ary2 = ary2st;
3676 else if (
RTEST(flag)) {
3693 for (i = 0; i < n; i++) {
3695 VALUE c = check_match(ec, v, target,
type);
3704 return check_match(ec, pattern, target,
type);
3711 const VALUE kw_bits = *(ep - bits);
3714 unsigned int b = (
unsigned int)
FIX2ULONG(kw_bits);
3728 if (RUBY_DTRACE_METHOD_ENTRY_ENABLED() ||
3729 RUBY_DTRACE_METHOD_RETURN_ENABLED() ||
3730 RUBY_DTRACE_CMETHOD_ENTRY_ENABLED() ||
3731 RUBY_DTRACE_CMETHOD_RETURN_ENABLED()) {
3755 if ((ns = vm_search_const_defined_class(cbase,
id)) == 0) {
3777 "superclass mismatch for class %"PRIsVALUE"",
3819 vm_declare_module(
ID id,
VALUE cbase)
3833 if (!
NIL_P(location)) {
3835 " previous definition of %"PRIsVALUE" was here",
3848 "superclass must be a Class (%"PRIsVALUE" given)",
3852 vm_check_if_namespace(cbase);
3856 if ((klass = vm_const_get_under(
id, flags, cbase)) != 0) {
3857 if (!vm_check_if_class(
id, flags, super, klass))
3858 unmatched_redefinition(
"class", cbase,
id, klass);
3862 return vm_declare_class(
id, flags, cbase, super);
3871 vm_check_if_namespace(cbase);
3872 if ((
mod = vm_const_get_under(
id, flags, cbase)) != 0) {
3873 if (!vm_check_if_module(
id,
mod))
3874 unmatched_redefinition(
"module", cbase,
id,
mod);
3878 return vm_declare_module(
id, cbase);
3883 vm_find_or_create_class_by_id(
ID id,
3893 return vm_define_class(
id, flags, cbase, super);
3901 return vm_define_module(
id, flags, cbase);
3904 rb_bug(
"unknown defineclass type: %d", (
int)
type);
3913 if (!vm_env_cref_by_cref(cfp->
ep)) {
3917 return CREF_SCOPE_VISI(vm_ec_cref(ec))->method_visi;
3926 if (!vm_env_cref_by_cref(cfp->
ep)) {
3930 return CREF_SCOPE_VISI(vm_ec_cref(ec))->module_func;
3941 if (!is_singleton) {
3942 klass = CREF_CLASS(cref);
3943 visi = vm_scope_visibility_get(ec);
3956 if (!is_singleton && vm_scope_module_func_check(ec)) {
3963 vm_search_method_wrap(
3968 vm_search_method(cd, recv);
3972 vm_search_invokeblock(
3994 return vm_invoke_block(ec,
GET_CFP(), calling, ci, block_handler);
4003 VALUE block_handler,
4004 void (*method_explorer)(
4039 if (
GET_ISEQ()->body->catch_except_p) {
4043 else if ((val = mjit_exec(ec)) ==
Qundef) {
4054 return mjit_exec(ec);
4070 #define id_cmp idCmp
4127 vm_ic_hit_p(
IC ic,
const VALUE *reg_ep)
4131 ic->
ic_cref == vm_get_cref(reg_ep));
4142 ic->
ic_cref = vm_get_const_key_cref(reg_ep);
4167 return vm_once_exec((
VALUE)iseq);
4197 if (!
isinf(kval) && modf(kval, &kval) == 0.0) {
4223 static const char stack_consistency_error[] =
4225 #if defined RUBY_DEVEL
4231 rb_bug(stack_consistency_error, nsp, nbp);
4238 if (FIXNUM_2_P(recv, obj) &&
4240 return rb_fix_plus_fix(recv, obj);
4242 else if (FLONUM_2_P(recv, obj) &&
4272 if (FIXNUM_2_P(recv, obj) &&
4274 return rb_fix_minus_fix(recv, obj);
4276 else if (FLONUM_2_P(recv, obj) &&
4296 if (FIXNUM_2_P(recv, obj) &&
4298 return rb_fix_mul_fix(recv, obj);
4300 else if (FLONUM_2_P(recv, obj) &&
4320 if (FIXNUM_2_P(recv, obj) &&
4322 return (
FIX2LONG(obj) == 0) ?
Qundef : rb_fix_div_fix(recv, obj);
4324 else if (FLONUM_2_P(recv, obj) &&
4344 if (FIXNUM_2_P(recv, obj) &&
4346 return (
FIX2LONG(obj) == 0) ?
Qundef : rb_fix_mod_fix(recv, obj);
4348 else if (FLONUM_2_P(recv, obj) &&
4369 VALUE val = opt_eq_func(recv, obj, cd_eq);
4382 if (FIXNUM_2_P(recv, obj) &&
4386 else if (FLONUM_2_P(recv, obj) &&
4407 if (FIXNUM_2_P(recv, obj) &&
4411 else if (FLONUM_2_P(recv, obj) &&
4432 if (FIXNUM_2_P(recv, obj) &&
4436 else if (FLONUM_2_P(recv, obj) &&
4457 if (FIXNUM_2_P(recv, obj) &&
4461 else if (FLONUM_2_P(recv, obj) &&
4502 if (FIXNUM_2_P(recv, obj) &&
4504 return (recv & obj) | 1;
4514 if (FIXNUM_2_P(recv, obj) &&
4527 if (FIXNUM_2_P(recv, obj) &&
4536 return rb_ary_entry_internal(recv,
FIX2LONG(obj));
4600 vm_opt_length(
VALUE recv,
int bop)
4628 vm_opt_empty_p(
VALUE recv)
4646 else if (vm_method_cfunc_is(cd, recv,
rb_false)) {
4662 case RSHIFT(~0UL, 1):
4683 vm_opt_succ(
VALUE recv)
4687 return fix_succ(recv);
4704 if (vm_method_cfunc_is(cd, recv, rb_obj_not)) {
4746 if (event & global_hooks->
events) {
4749 vm_dtrace(event, ec);
4750 rb_exec_event_hook_orig(ec, global_hooks, event,
self, 0, 0, 0 , val, 0);
4754 if (local_hooks !=
NULL) {
4755 if (event & local_hooks->
events) {
4758 rb_exec_event_hook_orig(ec, local_hooks, event,
self, 0, 0, 0 , val, 0);
4764 #define VM_TRACE_HOOK(target_event, val) do { \
4765 if ((pc_events & (target_event)) & enabled_flags) { \
4766 vm_trace_hook(ec, reg_cfp, pc, pc_events, (target_event), global_hooks, local_hooks, (val)); \
4784 enabled_flags |= local_hook_events;
4788 if ((pc_events & enabled_flags) == 0) {
4808 fprintf(stderr,
"vm_trace>>%4d (%4x) - %s:%d %s\n",
4829 #if VM_CHECK_MODE > 0
4831 void vm_canary_is_found_dead(
enum ruby_vminsn_type i,
VALUE c)));
4839 vm_stack_canary_was_born =
true;
4844 vm_canary_is_found_dead(
enum ruby_vminsn_type i,
VALUE c)
4852 rb_bug(
"dead canary found at %s: %s", insn,
str);
4888 return (*(rb_invoke_funcptr0_t)funcptr)(ec,
self);
4895 return (*(rb_invoke_funcptr1_t)funcptr)(ec,
self,
argv[0]);
4902 return (*(rb_invoke_funcptr2_t)funcptr)(ec,
self,
argv[0],
argv[1]);
4909 return (*(rb_invoke_funcptr3_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2]);
4916 return (*(rb_invoke_funcptr4_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3]);
4923 return (*(rb_invoke_funcptr5_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4]);
4950 typedef VALUE (*rb_invoke_funcptr9_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9);
4951 return (*(rb_invoke_funcptr9_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8]);
4957 typedef VALUE (*rb_invoke_funcptr10_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10);
4958 return (*(rb_invoke_funcptr10_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9]);
4964 typedef VALUE (*rb_invoke_funcptr11_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10,
VALUE v11);
4965 return (*(rb_invoke_funcptr11_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10]);
4971 typedef VALUE (*rb_invoke_funcptr12_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10,
VALUE v11,
VALUE v12);
4972 return (*(rb_invoke_funcptr12_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11]);
4978 typedef VALUE (*rb_invoke_funcptr13_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10,
VALUE v11,
VALUE v12,
VALUE v13);
4979 return (*(rb_invoke_funcptr13_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12]);
4985 typedef VALUE (*rb_invoke_funcptr14_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10,
VALUE v11,
VALUE v12,
VALUE v13,
VALUE v14);
4986 return (*(rb_invoke_funcptr14_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12],
argv[13]);
4992 typedef VALUE (*rb_invoke_funcptr15_t)(
rb_execution_context_t *ec,
VALUE self,
VALUE v1,
VALUE v2,
VALUE v3,
VALUE v4,
VALUE v5,
VALUE v6,
VALUE v7,
VALUE v8,
VALUE v9,
VALUE v10,
VALUE v11,
VALUE v12,
VALUE v13,
VALUE v14,
VALUE v15);
4993 return (*(rb_invoke_funcptr15_t)funcptr)(ec,
self,
argv[0],
argv[1],
argv[2],
argv[3],
argv[4],
argv[5],
argv[6],
argv[7],
argv[8],
argv[9],
argv[10],
argv[11],
argv[12],
argv[13],
argv[14]);
4999 lookup_builtin_invoker(
int argc)
5020 return invokers[
argc];
5033 return invoke_bf(ec, cfp, bf,
argv);
5040 fprintf(stderr,
"vm_invoke_builtin_delegate: passing -> ");
5041 for (
int i=0; i<bf->
argc; i++) {
5044 fprintf(stderr,
"\n");
5045 fprintf(stderr,
"%s %s(%d):%p\n", RUBY_FUNCTION_NAME_STRING, bf->
name, bf->
argc, bf->
func_ptr);
5048 if (bf->
argc == 0) {
5049 return invoke_bf(ec, cfp, bf,
NULL);
5053 return invoke_bf(ec, cfp, bf,
argv);
5063 return cfp->
ep[index];