14#include "insns_info.inc"
19#include "ruby/config.h"
75 ec_stack_overflow(ec,
TRUE);
77 ec_stack_overflow(ec,
FALSE);
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) );
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);
206static VALUE vm_stack_canary;
207static bool vm_stack_canary_was_born =
false;
215 if (!
LIKELY(vm_stack_canary_was_born)) {
225 else if (
LIKELY(sp[0] != vm_stack_canary)) {
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)
310 cfp->bp_check = sp + 1;
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);
371rb_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);
443vm_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");
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);
636#if VM_CHECK_MODE == 0
659 rb_bug(
"check_method_entry: svar should not be there:");
666vm_env_cref(
const VALUE *ep)
670 while (!VM_ENV_LOCAL_P(ep)) {
672 ep = VM_ENV_PREV_EP(ep);
695vm_env_cref_by_cref(
const VALUE *ep)
697 while (!VM_ENV_LOCAL_P(ep)) {
699 ep = VM_ENV_PREV_EP(ep);
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");
737vm_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");
759vm_get_cref(
const VALUE *ep)
767 rb_bug(
"vm_get_cref: unreachable");
779 return vm_get_cref(
cfp->
ep);
783vm_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);
839vm_get_cbase(
const VALUE *ep)
845 if ((
klass = CREF_CLASS(cref)) != 0) {
848 cref = CREF_NEXT(cref);
855vm_get_const_base(
const VALUE *ep)
861 if (!CREF_PUSHED_BY_EVAL(cref) &&
862 (
klass = CREF_CLASS(cref)) != 0) {
865 cref = CREF_NEXT(cref);
880vm_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));
1021 else if (
LIKELY(is_attr ?
1066 if (
index < numiv) {
1076 numiv = ivtbl->numiv;
1077 ivptr = ivtbl->ivptr;
1167 vm_setivar(
obj,
id, val, ic, 0, 0);
1192 const int flag,
const VALUE throwobj)
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;
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;
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
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)
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)) {
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)
1827double_cmp_lt(
double a,
double b)
1834double_cmp_le(
double a,
double b)
1841double_cmp_gt(
double a,
double b)
1848double_cmp_ge(
double a,
double b)
1854static inline VALUE *
1860 if (
cfp->
iseq && VM_FRAME_RUBYFRAME_P(
cfp)) {
1866#if VM_DEBUG_BP_CHECK
1867 if (
bp !=
cfp->bp_check) {
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);
2004#define USE_OPT_HIST 0
2007#define OPT_HIST_MAX 64
2008static int opt_hist[OPT_HIST_MAX+1];
2012opt_hist_show_results_at_exit(
void)
2014 for (
int i=0;
i<OPT_HIST_MAX;
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]++;
2057 const int opt =
calling->argc - lead_num;
2063 if (
opt_pc < OPT_HIST_MAX) {
2067 opt_hist[OPT_HIST_MAX]++;
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);
2158 else if (rb_iseq_only_optparam_p(
iseq)) {
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++) {
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,
2287 VALUE *sp_orig, *sp;
2290 if (VM_BH_FROM_CFP_P(
calling->block_handler,
cfp)) {
2294 if (VM_BH_ISEQ_BLOCK_P(
calling->block_handler)) {
2295 calling->block_handler = VM_BH_FROM_ISEQ_BLOCK(dst_captured);
2298 calling->block_handler = VM_BH_FROM_IFUNC_BLOCK(dst_captured);
2305 sp_orig = sp =
cfp->
sp;
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
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);
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);
2534 empty_kw_splat =
calling->kw_splat;
2536 if (empty_kw_splat &&
calling->kw_splat) {
2539 return vm_call_cfunc_with_frame(ec,
reg_cfp,
calling, cd, empty_kw_splat);
2590 return vm_call_bmethod_body(ec,
calling, cd,
argv);
2630 cd.ci_kw.
ci = *orig_ci;
2690 return vm_invoke_block_opt_call(ec,
reg_cfp,
calling,
ci, VM_BH_FROM_PROC(procval));
2705 vm_search_method(cd,
calling->recv);
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);
2771 if (
NIL_P(refinements)) {
2788 if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(ec,
cfp)) {
2792 }
while (
cfp->
iseq != local_iseq);
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);
2902 CC_SET_ME(
cc, refined_method_callable_without_refinement(
cc->
me));
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);
2939 return vm_call_attrset(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))
2989 return vm_call_method_nome(ec,
cfp,
calling, cd);
3003 const int stat = ci_missing_reason(
ci);
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);
3103NORETURN(
static void vm_super_outside(
void));
3106vm_super_outside(
void)
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);
3168block_proc_is_lambda(
const VALUE procval)
3187 int is_lambda =
FALSE;
3195 else if (
argc == 0) {
3219 0, ec->
cfp->
sp, 0, 0);
3248vm_callee_setup_block_arg_arg0_check(
VALUE *
argv)
3279 !
NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(
argv))) {
3339 vm_push_frame(ec,
iseq,
3371 int kw_splat =
calling->kw_splat;
3374 if (kw_splat && !
calling->kw_splat) {
3387vm_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;
3416 return vm_invoke_iseq_block(ec,
reg_cfp,
calling,
ci, is_lambda, captured);
3424 is_lambda = block_proc_is_lambda(VM_BH_TO_PROC(
block_handler));
3435vm_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);
3459vm_once_clear(
VALUE data)
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) {
3616 const VALUE *ep = reg_ep;
3617 for (
i = 0;
i < lv;
i++) {
3624vm_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++) {
3704 return check_match(ec, pattern, target,
type);
3711 const VALUE kw_bits = *(ep - bits);
3755 if ((ns = vm_search_const_defined_class(
cbase,
id)) == 0) {
3777 "superclass mismatch for class %"PRIsVALUE"",
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);
3883vm_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)) {
3963vm_search_method_wrap(
3968 vm_search_method(cd, recv);
3972vm_search_invokeblock(
4004 void (*method_explorer)(
4012 int argc =
ci->orig_argc;
4039 if (
GET_ISEQ()->body->catch_except_p) {
4043 else if ((val = mjit_exec(ec)) ==
Qundef) {
4054 return mjit_exec(ec);
4127vm_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);
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) &&
4324 else if (FLONUM_2_P(recv,
obj) &&
4344 if (FIXNUM_2_P(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));
4600vm_opt_length(
VALUE recv,
int bop)
4628vm_opt_empty_p(
VALUE recv)
4646 else if (vm_method_cfunc_is(cd, recv,
rb_false)) {
4683vm_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) {
4829#if VM_CHECK_MODE > 0
4839 vm_stack_canary_was_born =
true;
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]);
4999lookup_builtin_invoker(
int argc)
5020 return invokers[
argc];
5033 return invoke_bf(ec,
cfp, bf,
argv);
5041 for (
int i=0;
i<bf->
argc;
i++) {
5048 if (bf->
argc == 0) {
5049 return invoke_bf(ec,
cfp, bf,
NULL);
5053 return invoke_bf(ec,
cfp, bf,
argv);
VALUE rb_uint2big(uintptr_t n)
char str[HTML_ESCAPE_MAX_LEN+1]
VALUE rb_singleton_class(VALUE)
Returns the singleton class of obj.
VALUE rb_class_inherited(VALUE, VALUE)
Calls Class::inherited.
VALUE rb_define_module_id(ID)
VALUE rb_define_class_id(ID, VALUE)
Defines a new class.
VALUE rb_cClass
Class class.
VALUE rb_cBasicObject
BasicObject class.
VALUE rb_cObject
Object class.
VALUE rb_cModule
Module class.
@ RMODULE_INCLUDED_INTO_REFINEMENT
void rb_notimplement(void)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_bug(const char *fmt,...)
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
void rb_warn(const char *fmt,...)
VALUE rb_exc_new_str(VALUE, VALUE)
VALUE rb_ensure(VALUE(*)(VALUE), VALUE, VALUE(*)(VALUE), VALUE)
An equivalent to ensure clause.
VALUE rb_false(VALUE obj)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
void rb_obj_copy_ivar(VALUE dest, VALUE obj)
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_class_real(VALUE cl)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2)
VALUE type(ANYARGS)
ANYARGS-ed function type.
unsigned char buf[MIME_BUF_SIZE]
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
enum iseq_catch_table_entry::catch_type type
const rb_cref_t * ic_cref
struct rb_captured_block captured
const void *const func_ptr
enum method_missing_reason method_missing_reason
const struct rb_callable_method_entry_struct * me
rb_serial_t class_serial[(64 - sizeof(rb_serial_t) - sizeof(struct rb_callable_method_entry_struct *) - sizeof(uintptr_t) - sizeof(enum method_missing_reason) - sizeof(VALUE(*)(struct rb_execution_context_struct *e, struct rb_control_frame_struct *, struct rb_calling_info *, const struct rb_call_data *)))/sizeof(rb_serial_t)]
union rb_call_cache::@37 aux
VALUE(* call)(struct rb_execution_context_struct *ec, struct rb_control_frame_struct *cfp, struct rb_calling_info *calling, struct rb_call_data *cd)
struct rb_call_info_kw_arg * kw_arg
struct rb_method_definition_struct *const def
const VALUE defined_class
const struct vm_ifunc * ifunc
union rb_captured_block::@53 code
struct rb_cref_struct * next
enum method_missing_reason method_missing_reason
struct rb_trace_arg_struct * trace_arg
unsigned int ambiguous_param0
enum rb_iseq_constant_body::iseq_type type
struct rb_iseq_constant_body::@45 param
unsigned int local_table_size
const struct rb_iseq_constant_body::@45::rb_iseq_param_keyword * keyword
struct rb_iseq_constant_body::@45::@47 flags
unsigned int accepts_no_kwarg
struct iseq_catch_table * catch_table
const struct rb_iseq_struct * parent_iseq
struct rb_iseq_struct * local_iseq
struct rb_hook_list_struct * local_hooks
struct rb_iseq_constant_body * body
union rb_iseq_struct::@48 aux
struct rb_iseq_struct::@48::@50 exec
struct rb_call_info_with_kwarg ci_kw
struct rb_method_entry_struct * original_me
VALUE(* invoker)(VALUE recv, int argc, const VALUE *argv, VALUE(*func)())
rb_method_bmethod_t bmethod
enum method_optimized_type optimize_type
union rb_method_definition_struct::@41 body
rb_method_refined_t refined
rb_cref_t * cref
class reference, should be marked
struct rb_method_entry_struct * orig_me
IFUNC (Internal FUNCtion)
rb_block_call_func_t func
const VALUE cref_or_me
class reference or rb_method_entry_t
struct iseq_inline_storage_entry::@44 once
struct rb_thread_struct * running_thread
MJIT_FUNC_EXPORTED void rb_const_warn_if_deprecated(const rb_const_entry_t *ce, VALUE klass, ID id)
MJIT_FUNC_EXPORTED void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_execution_context_t *, rb_control_frame_t *)
VALUE(* builtin_invoker)(rb_execution_context_t *ec, VALUE self, const VALUE *argv, rb_insn_func_t funcptr)
#define EQ_UNREDEFINED_P(t)
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aset(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)
MJIT_FUNC_EXPORTED VALUE rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner)
int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
#define CHECK_CFP_CONSISTENCY(func)
MJIT_STATIC void rb_ec_stack_overflow(rb_execution_context_t *ec, int crit)
NOINLINE(static void vm_env_write_slowpath(const VALUE *ep, int index, VALUE v))
ALWAYS_INLINE(static VALUE vm_getivar(VALUE, ID, IVC, struct rb_call_cache *, int))
NORETURN(static void ec_stack_overflow(rb_execution_context_t *ec, int))
MJIT_STATIC void rb_vm_pop_frame(rb_execution_context_t *ec)
#define BUILTIN_CLASS_P(x, k)
VALUE rb_vm_call0(rb_execution_context_t *ec, VALUE, ID, int, const VALUE *, const rb_callable_method_entry_t *, int kw_splat)
MJIT_STATIC VALUE rb_vm_bh_to_procval(const rb_execution_context_t *ec, VALUE block_handler)
void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
MJIT_STATIC const rb_callable_method_entry_t * rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
VALUE rb_eql_opt(VALUE obj1, VALUE obj2)
MJIT_STATIC void rb_error_arity(int argc, int min, int max)
VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj, int argc, const VALUE *argv, int priv)
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aref(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)
PUREFUNC(static rb_callable_method_entry_t *check_method_entry(VALUE obj, int can_be_svar))
VALUE rb_equal_opt(VALUE obj1, VALUE obj2)
#define vm_check_frame(a, b, c, d)
#define CHECK_CMP_NAN(a, b)
void rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
void Init_vm_stack_canary(void)
#define VM_TRACE_HOOK(target_event, val)
#define vm_check_canary(ec, sp)
rb_event_flag_t rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos)
MJIT_STATIC bool rb_simple_iseq_p(const rb_iseq_t *iseq)
MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE exc)
MJIT_FUNC_EXPORTED void rb_vm_search_method_slowpath(struct rb_call_data *cd, VALUE klass)
rb_method_definition_t * rb_method_definition_create(rb_method_type_t type, ID mid)
VALUE rb_vm_lvar_exposed(rb_execution_context_t *ec, int index)