18 #include "ruby/config.h" 35 threadptr_stack_overflow(
rb_thread_t *th,
int setup)
50 vm_stackoverflow(
void)
64 #ifdef USE_SIGALTSTACK 65 threadptr_stack_overflow(th,
TRUE);
67 threadptr_stack_overflow(th,
FALSE);
74 callable_class_p(
VALUE klass)
76 #if VM_CHECK_MODE >= 2 77 if (!klass)
return FALSE;
108 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)
121 rb_bug(
"vm_push_frame: specval (%p) should be a block_ptr on %x frame", (
void *)specval, magic);
123 if (!req_block && (type & VM_ENV_FLAG_LOCAL) != 0) {
124 rb_bug(
"vm_push_frame: specval (%p) should not be a block_ptr on %x frame", (
void *)specval, magic);
129 rb_bug(
"vm_push_frame: (%s) should be method entry on %x frame",
rb_obj_info(cref_or_me), magic);
133 if (req_cref && cref_or_me_type !=
imemo_cref) {
134 rb_bug(
"vm_push_frame: (%s) should be CREF on %x frame",
rb_obj_info(cref_or_me), magic);
142 rb_bug(
"vm_push_frame: (%s) should be false or cref on %x frame",
rb_obj_info(cref_or_me), magic);
151 if (!callable_method_entry_p(me)) {
152 rb_bug(
"vm_push_frame: ment (%s) should be callable on %x frame.",
rb_obj_info(cref_or_me), magic);
158 RUBY_VM_NORMAL_ISEQ_P(iseq) );
161 VM_ASSERT(is_cframe == !RUBY_VM_NORMAL_ISEQ_P(iseq));
174 #define CHECK(magic, req_block, req_me, req_cref, is_cframe) \ 176 vm_check_frame_detail(type, req_block, req_me, req_cref, \ 177 specval, cref_or_me, is_cframe, iseq); \ 179 switch (given_magic) {
191 rb_bug(
"vm_push_frame: unknown type (%x)", (
unsigned int)given_magic);
196 #define vm_check_frame(a, b, c, d) 231 for (i=0; i < local_size; i++) {
246 #if VM_DEBUG_BP_CHECK 247 cfp->bp_check = sp + 1;
269 return vm_push_frame_(&th->
ec, iseq, type,
self, specval, cref_or_me, pc, sp, local_size, stack_max);
284 return vm_push_frame_(ec, iseq, type,
self, specval, cref_or_me, pc, sp, local_size, stack_max);
309 rb_arity_error_new(
int argc,
int min,
int max)
313 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d)",
argc, min);
316 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d+)",
argc, min);
319 err_mess =
rb_sprintf(
"wrong number of arguments (given %d, expected %d..%d)",
argc, min, max);
335 vm_env_write_slowpath(
const VALUE *ep,
int index,
VALUE v)
339 VM_FORCE_WRITE(&ep[index], v);
345 vm_env_write(
const VALUE *ep,
int index,
VALUE v)
349 VM_STACK_ENV_WRITE(ep, index, v);
352 vm_env_write_slowpath(ep, index, v);
359 vm_env_write(ep, index, v);
365 #if VM_CHECK_MODE > 0 367 vm_svar_valid_p(
VALUE svar)
417 const struct vm_svar *svar = lep_svar(th, lep);
423 return svar->lastline;
425 return svar->backref;
427 const VALUE ary = svar->others;
448 struct vm_svar *svar = lep_svar(th, lep);
451 lep_svar_write(th, lep, svar = svar_new((
VALUE)svar));
462 VALUE ary = svar->others;
478 val = lep_svar_get(th, lep,
key);
498 rb_bug(
"unexpected back-ref");
510 check_method_entry(
VALUE obj,
int can_be_svar)
514 #if VM_CHECK_MODE > 0 528 #if VM_CHECK_MODE > 0 529 rb_bug(
"check_method_entry: svar should not be there:");
541 while (!VM_ENV_LOCAL_P(ep)) {
543 ep = VM_ENV_PREV_EP(ep);
552 switch (me->
def->type) {
554 return me->
def->body.iseq.cref;
560 #if VM_CHECK_MODE == 0 564 check_cref(
VALUE obj,
int can_be_svar)
568 #if VM_CHECK_MODE > 0 582 #if VM_CHECK_MODE > 0 583 rb_bug(
"check_method_entry: svar should not be there:");
590 vm_env_cref(
const VALUE *ep)
594 while (!VM_ENV_LOCAL_P(ep)) {
596 ep = VM_ENV_PREV_EP(ep);
603 is_cref(
const VALUE v,
int can_be_svar)
619 vm_env_cref_by_cref(
const VALUE *ep)
621 while (!VM_ENV_LOCAL_P(ep)) {
623 ep = VM_ENV_PREV_EP(ep);
629 cref_replace_with_duplicated_cref_each_frame(
const VALUE *vptr,
int can_be_svar,
VALUE parent)
631 const VALUE v = *vptr;
638 new_cref = vm_cref_dup(cref);
643 VM_FORCE_WRITE(vptr, (
VALUE)new_cref);
651 rb_bug(
"cref_replace_with_duplicated_cref_each_frame: unreachable");
660 vm_cref_replace_with_duplicated_cref(
const VALUE *ep)
662 if (vm_env_cref_by_cref(ep)) {
666 while (!VM_ENV_LOCAL_P(ep)) {
667 envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) :
Qfalse;
671 ep = VM_ENV_PREV_EP(ep);
673 envval = VM_ENV_ESCAPED_P(ep) ? VM_ENV_ENVVAL(ep) :
Qfalse;
677 rb_bug(
"vm_cref_dup: unreachable");
683 rb_vm_get_cref(
const VALUE *ep)
691 rb_bug(
"rb_vm_get_cref: unreachable");
696 vm_get_const_key_cref(
const VALUE *ep)
698 const rb_cref_t *cref = rb_vm_get_cref(ep);
705 cref = CREF_NEXT(cref);
718 if (CREF_CLASS(cref) == old_klass) {
720 *new_cref_ptr = new_cref;
724 cref = CREF_NEXT(cref);
725 *new_cref_ptr = new_cref;
728 *new_cref_ptr =
NULL;
737 prev_cref = vm_env_cref(ep);
743 prev_cref = vm_env_cref(cfp->
ep);
751 vm_get_cbase(
const VALUE *ep)
753 const rb_cref_t *cref = rb_vm_get_cref(ep);
757 if ((klass = CREF_CLASS(cref)) != 0) {
760 cref = CREF_NEXT(cref);
767 vm_get_const_base(
const VALUE *ep)
769 const rb_cref_t *cref = rb_vm_get_cref(ep);
773 if (!CREF_PUSHED_BY_EVAL(cref) &&
774 (klass = CREF_CLASS(cref)) != 0) {
777 cref = CREF_NEXT(cref);
784 vm_check_if_namespace(
VALUE klass)
792 vm_ensure_not_refinement_module(
VALUE self)
795 rb_warn(
"not defined at the refinement, but at the outer class/module");
811 if (orig_klass ==
Qnil) {
817 while (root_cref && CREF_PUSHED_BY_EVAL(root_cref)) {
818 root_cref = CREF_NEXT(root_cref);
821 while (cref && CREF_NEXT(cref)) {
822 if (CREF_PUSHED_BY_EVAL(cref)) {
826 klass = CREF_CLASS(cref);
828 cref = CREF_NEXT(cref);
838 if (am == klass)
break;
840 if (is_defined)
return 1;
843 goto search_continue;
858 if (root_cref && !
NIL_P(CREF_CLASS(root_cref))) {
859 klass = vm_get_iclass(th->
ec.
cfp, CREF_CLASS(root_cref));
873 vm_check_if_namespace(orig_klass);
889 rb_bug(
"vm_get_cvar_base: no cref");
892 while (CREF_NEXT(cref) &&
894 CREF_PUSHED_BY_EVAL(cref))) {
895 cref = CREF_NEXT(cref);
897 if (!CREF_NEXT(cref)) {
898 rb_warn(
"class variable access from toplevel");
901 klass = vm_get_iclass(cfp, CREF_CLASS(cref));
910 vm_search_const_defined_class(
const VALUE cbase,
ID id)
923 #ifndef USE_IC_FOR_IVAR 924 #define USE_IC_FOR_IVAR 1 956 if (
st_lookup(iv_index_tbl,
id, &index)) {
1013 else if (index >= INT_MAX) {
1032 vm_getinstancevariable(
VALUE obj,
ID id,
IC ic)
1034 return vm_getivar(obj,
id, ic, 0, 0);
1040 vm_setivar(obj,
id, val, ic, 0, 0);
1077 escape_cfp = reg_cfp;
1079 while (base_iseq->
body->
type != ISEQ_TYPE_BLOCK) {
1082 ep = escape_cfp->
ep;
1083 base_iseq = escape_cfp->
iseq;
1086 ep = VM_ENV_PREV_EP(ep);
1088 escape_cfp = rb_vm_search_cf_from_ep(th, escape_cfp, ep);
1093 if (VM_FRAME_LAMBDA_P(escape_cfp)) {
1099 ep = VM_ENV_PREV_EP(ep);
1101 while (escape_cfp < eocfp) {
1102 if (escape_cfp->
ep == ep) {
1109 for (i=0; i < ct->size; i++) {
1113 entry->
iseq == base_iseq &&
1114 entry->
start < epc && entry->
end >= epc) {
1115 if (entry->
cont == epc) {
1136 for (i = 0; i <
level; i++) {
1137 ep = VM_ENV_PREV_EP(ep);
1140 escape_cfp = rb_vm_search_cf_from_ep(th, reg_cfp, ep);
1144 const VALUE *target_lep = VM_EP_LEP(current_ep);
1145 int in_class_frame = 0;
1147 escape_cfp = reg_cfp;
1149 while (escape_cfp < eocfp) {
1150 const VALUE *lep = VM_CF_LEP(escape_cfp);
1156 if (lep == target_lep &&
1157 VM_FRAME_RUBYFRAME_P(escape_cfp) &&
1163 if (lep == target_lep) {
1164 if (VM_FRAME_LAMBDA_P(escape_cfp)) {
1166 if (in_class_frame) {
1171 const VALUE *tep = current_ep;
1173 while (target_lep != tep) {
1174 if (escape_cfp->
ep == tep) {
1178 tep = VM_ENV_PREV_EP(tep);
1182 else if (VM_FRAME_RUBYFRAME_P(escape_cfp)) {
1185 case ISEQ_TYPE_MAIN:
1186 if (toplevel)
goto valid_return;
1188 case ISEQ_TYPE_EVAL:
1189 case ISEQ_TYPE_CLASS:
1198 if (escape_cfp->
ep == target_lep && escape_cfp->
iseq->
body->
type == ISEQ_TYPE_METHOD) {
1210 rb_bug(
"isns(throw): unsupport throw type");
1214 return (
VALUE)THROW_DATA_NEW(throwobj, escape_cfp, state);
1226 return vm_throw_start(th, reg_cfp, state, flag, level, throwobj);
1229 return vm_throw_continue(th, throwobj);
1236 int is_splat = flag & 0x01;
1237 rb_num_t space_size = num + is_splat;
1246 cfp->
sp += space_size;
1256 for (i=0; i<num-
len; i++) {
1260 for (j=0; i<num; i++, j++) {
1261 VALUE v = ptr[len - j - 1];
1271 VALUE *bptr = &base[space_size - 1];
1273 for (i=0; i<num; i++) {
1275 for (; i<num; i++) {
1301 #if OPT_INLINE_METHOD_CACHE 1315 cc->
call = vm_call_general;
1316 #if OPT_INLINE_METHOD_CACHE 1326 me->
def->body.cfunc.func == func) {
1338 vm_search_method(ci, cc, recv);
1339 return check_cfunc(cc->
me, func);
1345 if (vm_method_cfunc_is(ci, cc, recv, rb_obj_equal)) {
1352 #define BUILTIN_CLASS_P(x, k) (!SPECIAL_CONST_P(x) && RBASIC_CLASS(x) == k) 1353 #define EQ_UNREDEFINED_P(t) BASIC_OP_UNREDEFINED_P(BOP_EQ, t##_REDEFINED_OP_FLAG) 1357 comparable_by_identity(
VALUE recv,
VALUE obj)
1372 #ifndef NO_BIG_INLINE 1378 switch (comparable_by_identity(recv, obj)) {
1398 return opt_equal_fallback(recv, obj, ci, cc);
1402 #ifndef NO_BIG_INLINE 1408 switch (comparable_by_identity(recv, obj)) {
1428 return opt_equal_fallback(recv, obj, ci, cc);
1430 #undef BUILTIN_CLASS_P 1431 #undef EQ_UNREDEFINED_P 1443 return opt_eq_func(obj1, obj2, &ci, &cc);
1456 return opt_eql_func(obj1, obj2, &ci, &cc);
1484 rb_bug(
"check_match: unreachable");
1489 #if defined(_MSC_VER) && _MSC_VER < 1300 1490 #define CHECK_CMP_NAN(a, b) if (isnan(a) || isnan(b)) return Qfalse; 1492 #define CHECK_CMP_NAN(a, b) 1496 double_cmp_lt(
double a,
double b)
1503 double_cmp_le(
double a,
double b)
1510 double_cmp_gt(
double a,
double b)
1517 double_cmp_ge(
double a,
double b)
1528 if (cfp->
iseq && VM_FRAME_RUBYFRAME_P(cfp)) {
1534 #if VM_DEBUG_BP_CHECK 1535 if (bp != cfp->bp_check) {
1536 fprintf(stderr,
"bp_check: %ld, bp: %ld\n",
1537 (
long)(cfp->bp_check -
GET_THREAD()->ec.vm_stack),
1539 rb_bug(
"vm_base_ptr: unreachable");
1570 #if VM_CHECK_MODE > 0 1573 return rb_iseq_check(def->body.iseq.iseqptr);
1579 return vm_call_iseq_setup_tailcall(th, cfp, calling, ci, cc, 0);
1588 return vm_call_iseq_setup_normal(th, cfp, calling, ci, cc, 0, param, local);
1615 CI_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size),
1621 return setup_parameters_complex(th, iseq, calling, ci, argv,
arg_setup_method);
1631 const int opt_pc = vm_callee_setup_arg(th, calling, ci, cc, def_iseq_ptr(cc->
me->
def), cfp->
sp - calling->
argc, param_size, local_size);
1632 return vm_call_iseq_setup_2(th, cfp, calling, ci, cc, opt_pc, param_size, local_size);
1637 int opt_pc,
int param_size,
int local_size)
1640 return vm_call_iseq_setup_normal(th, cfp, calling, ci, cc, opt_pc, param_size, local_size);
1643 return vm_call_iseq_setup_tailcall(th, cfp, calling, ci, cc, opt_pc);
1649 int opt_pc,
int param_size,
int local_size)
1654 VALUE *sp = argv + param_size;
1655 cfp->
sp = argv - 1 ;
1660 local_size - param_size,
1674 VALUE *sp_orig, *sp;
1682 calling->
block_handler = VM_BH_FROM_ISEQ_BLOCK(dst_captured);
1685 calling->
block_handler = VM_BH_FROM_IFUNC_BLOCK(dst_captured);
1689 vm_pop_frame(th, cfp, cfp->
ep);
1692 sp_orig = sp = cfp->
sp;
1695 sp[0] = calling->
recv;
1700 *sp++ = src_argv[i];
1730 return (*func)(recv);
1736 return (*func)(recv, argv[0]);
1742 return (*func)(recv, argv[0], argv[1]);
1748 return (*func)(recv, argv[0], argv[1], argv[2]);
1754 return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
1760 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
1766 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
1772 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
1778 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
1784 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
1790 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
1796 return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
1802 return (*func)(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]);
1808 return (*func)(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]);
1814 return (*func)(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]);
1820 return (*func)(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]);
1824 #define VM_PROFILE 0 1829 VM_PROFILE_R2C_CALL,
1830 VM_PROFILE_R2C_POPF,
1831 VM_PROFILE_C2C_CALL,
1832 VM_PROFILE_C2C_POPF,
1835 static int vm_profile_counter[VM_PROFILE_COUNT];
1836 #define VM_PROFILE_UP(x) (vm_profile_counter[VM_PROFILE_##x]++) 1837 #define VM_PROFILE_ATEXIT() atexit(vm_profile_show_result) 1839 vm_profile_show_result(
void)
1841 fprintf(stderr,
"VM Profile results: \n");
1842 fprintf(stderr,
"r->c call: %d\n", vm_profile_counter[VM_PROFILE_R2C_CALL]);
1843 fprintf(stderr,
"r->c popf: %d\n", vm_profile_counter[VM_PROFILE_R2C_POPF]);
1844 fprintf(stderr,
"c->c call: %d\n", vm_profile_counter[VM_PROFILE_C2C_CALL]);
1845 fprintf(stderr,
"c->c popf: %d\n", vm_profile_counter[VM_PROFILE_C2C_POPF]);
1848 #define VM_PROFILE_UP(x) 1849 #define VM_PROFILE_ATEXIT() 1864 #define CHECK_CFP_CONSISTENCY(func) \ 1865 (LIKELY(vm_cfp_consistent_p(th, reg_cfp)) ? (void)0 : \ 1866 rb_bug(func ": cfp consistency error (%p, %p)", reg_cfp, th->ec.cfp+1)) 1872 #if VM_DEBUG_VERIFY_METHOD_CACHE 1873 switch (me->
def->type) {
1877 # define METHOD_BUG(t) case VM_METHOD_TYPE_##t: rb_bug("wrong method type: " #t) 1879 METHOD_BUG(ATTRSET);
1881 METHOD_BUG(BMETHOD);
1884 METHOD_BUG(OPTIMIZED);
1885 METHOD_BUG(MISSING);
1886 METHOD_BUG(REFINED);
1890 rb_bug(
"wrong method type: %d", me->
def->type);
1893 return &me->
def->body.cfunc;
1902 int len = cfunc->
argc;
1906 int argc = calling->
argc;
1912 block_handler, (
VALUE)me,
1917 reg_cfp->
sp -= argc + 1;
1919 val = (*cfunc->
invoker)(cfunc->
func, recv, argc, reg_cfp->
sp + 1);
1935 return vm_call_cfunc_with_frame(th, reg_cfp, calling, ci, cc);
1942 return vm_getivar(calling->
recv, cc->
me->
def->body.attr.id,
NULL, cc, 1);
1950 return vm_setivar(calling->
recv, cc->
me->
def->body.attr.id, val,
NULL, cc, 1);
1974 argc = calling->
argc;
1977 cfp->
sp += - argc - 1;
1979 return vm_call_bmethod_body(th, calling, ci, cc, argv);
2003 i = calling->
argc - 1;
2005 if (calling->
argc == 0) {
2016 ci_entry.
ci = *orig_ci;
2021 cc_entry = *orig_cc;
2034 ci->
mid = idMethodMissing;
2048 return vm_call_method(th, reg_cfp, calling, ci, cc);
2060 argc = calling->
argc;
2064 cfp->
sp -= argc + 1;
2079 argc = calling->
argc+1;
2082 ci_entry.
mid = idMethodMissing;
2086 cc_entry = *orig_cc;
2089 idMethodMissing,
NULL);
2103 return vm_call_method(th, reg_cfp, calling, ci, cc);
2114 return vm_call_method_nome(th, cfp, calling, ci, cc);
2117 cc->
me->
def->body.refined.orig_me) {
2118 cc->
me = refined_method_callable_without_refinement(cc->
me);
2120 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2124 find_refinement(
VALUE refinements,
VALUE klass)
2126 if (
NIL_P(refinements)) {
2147 }
while (cfp->
iseq != local_iseq);
2153 find_defined_class_by_owner(
VALUE current_class,
VALUE target_owner)
2155 VALUE klass = current_class;
2160 while (
RTEST(klass)) {
2162 if (owner == target_owner) {
2168 return current_class;
2182 if (me->
def->alias_count + me->
def->complemented_count == 0) {
2195 VM_ASSERT(callable_method_entry_p(cme));
2213 VM_ASSERT(callable_method_entry_p(cme));
2225 switch (cc->
me->
def->type) {
2228 return vm_call_iseq_setup(th, cfp, calling, ci, cc);
2233 return vm_call_cfunc(th, cfp, calling, ci, cc);
2240 return vm_call_attrset(th, cfp, calling, ci, cc);
2247 return vm_call_ivar(th, cfp, calling, ci, cc);
2252 return vm_call_method_missing(th, cfp, calling, ci, cc);
2256 return vm_call_bmethod(th, cfp, calling, ci, cc);
2259 cc->
me = aliased_callable_method_entry(cc->
me);
2261 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2264 switch (cc->
me->
def->body.optimize_type) {
2267 return vm_call_opt_send(th, cfp, calling, ci, cc);
2270 return vm_call_opt_call(th, cfp, calling, ci, cc);
2272 rb_bug(
"vm_call_method: unsupported optimized method type (%d)",
2273 cc->
me->
def->body.optimize_type);
2284 VALUE refinements = cref ? CREF_REFINEMENTS(cref) :
Qnil;
2288 refinement = find_refinement(refinements, cc->
me->
owner);
2290 if (
NIL_P(refinement)) {
2291 goto no_refinement_dispatch;
2296 if (cc->
call == vm_call_super_method) {
2299 if (top_me && rb_method_definition_eq(ref_me->
def, top_me->
def)) {
2300 goto no_refinement_dispatch;
2305 return vm_call_method(th, cfp, calling, ci, cc);
2310 return vm_call_method_nome(th, cfp, calling, ci, cc);
2313 no_refinement_dispatch:
2314 if (cc->
me->
def->body.refined.orig_me) {
2315 cc->
me = refined_method_callable_without_refinement(cc->
me);
2321 return vm_call_method(th, cfp, calling, ci, cc);
2325 rb_bug(
"vm_call_method: unsupported method type (%d)", cc->
me->
def->type);
2332 const int stat = ci_missing_reason(ci);
2334 if (ci->
mid == idMethodMissing) {
2342 return vm_call_method_missing(th, cfp, calling, ci, cc);
2354 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2363 return vm_call_method_missing(th, cfp, calling, ci, cc);
2365 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2371 return vm_call_method_missing(th, cfp, calling, ci, cc);
2380 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2383 return vm_call_method_each_type(th, cfp, calling, ci, cc);
2390 return vm_call_method_nome(th, cfp, calling, ci, cc);
2397 return vm_call_method(th, reg_cfp, calling, ci, cc);
2404 if (cc->
call != vm_call_super_method)
rb_bug(
"bug");
2405 return vm_call_method(th, reg_cfp, calling, ci, cc);
2411 vm_search_normal_superclass(
VALUE klass)
2415 klass =
RBASIC(klass)->klass;
2422 vm_super_outside(
void)
2431 VALUE current_defined_class, klass;
2450 RBASIC(current_defined_class)->klass : current_defined_class;
2453 "self has wrong type to call super in this context: " 2460 "implicit argument passing of super from method defined" 2461 " by define_method() is not supported." 2462 " Specify all arguments explicitly.");
2465 ci->
mid = me->
def->original_id;
2483 block_proc_is_lambda(
const VALUE procval)
2502 switch (vm_block_handler_type(block_handler)) {
2504 blockarg = block_handler;
2524 int is_lambda =
FALSE;
2533 else if (argc == 0) {
2540 blockarg = vm_block_handler_to_proc(th, block_handler);
2548 val = (*ifunc->
func)(arg, ifunc->
data, argc, argv, blockarg);
2576 vm_callee_setup_block_arg_arg0_check(
VALUE *argv)
2578 VALUE ary, arg0 = argv[0];
2591 if (simple_iseq_p(iseq)) {
2598 calling->
argc == 1 &&
2601 !
NIL_P(arg0 = vm_callee_setup_block_arg_arg0_check(argv))) {
2602 calling->
argc = vm_callee_setup_block_arg_arg0_splat(cfp, iseq, argv, arg0);
2610 for (i=calling->
argc; i<iseq->body->param.lead_num; i++) argv[i] =
Qnil;
2625 return setup_parameters_complex(th, iseq, calling, ci, argv, arg_setup_type);
2630 vm_yield_setup_args(
rb_thread_t *th,
const rb_iseq_t *iseq,
const int argc,
VALUE *argv,
VALUE block_handler,
enum arg_setup_type arg_setup_type)
2635 calling = &calling_entry;
2642 return vm_callee_setup_block_arg(th, calling, ci, iseq, argv, arg_setup_type);
2659 vm_push_frame(th, iseq,
2678 argc = calling->
argc;
2692 argc = calling->
argc;
2699 vm_proc_to_block_handler(
VALUE procval)
2701 const struct rb_block *block = vm_proc_block(procval);
2703 switch (vm_block_type(block)) {
2705 return VM_BH_FROM_ISEQ_BLOCK(&block->
as.
captured);
2707 return VM_BH_FROM_IFUNC_BLOCK(&block->
as.
captured);
2709 return VM_BH_FROM_SYMBOL(block->
as.
symbol);
2711 return VM_BH_FROM_PROC(block->
as.
proc);
2720 VALUE block_handler = VM_CF_BLOCK_HANDLER(reg_cfp);
2722 int is_lambda =
FALSE;
2724 if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) ||
2730 switch (vm_block_handler_type(block_handler)) {
2734 return vm_invoke_iseq_block(th, reg_cfp, calling, ci, is_lambda, captured);
2739 return vm_invoke_ifunc_block(th, reg_cfp, calling, ci, captured);
2742 is_lambda = block_proc_is_lambda(VM_BH_TO_PROC(block_handler));
2743 block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
2746 return vm_invoke_symbol_block(th, reg_cfp, calling, ci, VM_BH_TO_SYMBOL(block_handler));
2753 vm_make_proc_with_iseq(
const rb_iseq_t *blockiseq)
2760 rb_bug(
"vm_make_proc_with_iseq: unreachable");
2763 captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
2770 vm_once_exec(
VALUE iseq)
2777 vm_once_clear(
VALUE data)
2806 args[0] = obj; args[1] =
Qfalse;
2830 klass = vm_get_cbase(
GET_EP());
2839 klass = vm_get_cvar_base(cref,
GET_CFP());
2847 if (vm_get_ev_const(th, klass,
SYM2ID(obj), 1)) {
2857 expr_type = check_respond_to_missing(obj, v);
2880 expr_type = check_respond_to_missing(obj, v);
2895 ID id = me->
def->original_id;
2910 rb_bug(
"unimplemented defined? type (VM)");
2914 if (expr_type != 0) {
2927 static const VALUE *
2931 const VALUE *ep = reg_ep;
2932 for (i = 0; i < lv; i++) {
2939 vm_get_special_object(
const VALUE *
const reg_ep,
2946 return vm_get_cbase(reg_ep);
2948 return vm_get_const_base(reg_ep);
2950 rb_bug(
"putspecialobject insn: unknown value_type %d", type);
2957 if (!
NIL_P(debug)) {
2966 const VALUE ary2 = ary2st;
2991 else if (
RTEST(flag)) {
3008 for (i = 0; i < n; i++) {
3010 VALUE c = check_match(v, target, type);
3019 return check_match(pattern, target, type);
3026 const VALUE kw_bits = *(ep - bits);
3068 if ((ns = vm_search_const_defined_class(cbase,
id)) == 0) {
3090 "superclass mismatch for class %"PRIsVALUE"",
3127 vm_declare_module(
ID id,
VALUE cbase)
3143 "superclass must be a Class (%"PRIsVALUE" given)",
3147 vm_check_if_namespace(cbase);
3151 if ((klass = vm_const_get_under(
id, flags, cbase)) != 0) {
3152 return vm_check_if_class(
id, flags, super, klass);
3155 return vm_declare_class(
id, flags, cbase, super);
3164 vm_check_if_namespace(cbase);
3165 if ((mod = vm_const_get_under(
id, flags, cbase)) != 0) {
3166 return vm_check_if_module(
id, mod);
3169 return vm_declare_module(
id, cbase);
3174 vm_find_or_create_class_by_id(
ID id,
3184 return vm_define_class(
id, flags, cbase, super);
3192 return vm_define_module(
id, flags, cbase);
3195 rb_bug(
"unknown defineclass type: %d", (
int)type);
3200 #define id_cmp idCmp 3215 const VALUE v = ptr[i];
3242 const VALUE v = ptr[i];
3259 vm_ic_hit_p(
IC ic,
const VALUE *reg_ep)
3276 ic->
ic_cref = vm_get_const_key_cref(reg_ep);
3295 is->once.running_thread = RUNNING_THREAD_ONCE_DONE;
3301 return vm_once_exec((
VALUE)iseq);
3331 if (!
isinf(kval) && modf(kval, &kval) == 0.0) {
3356 const ptrdiff_t nbp =
VM_SP_CNT(th, bp);
3357 static const char stack_consistency_error[] =
3359 #if defined RUBY_DEVEL 3365 rb_bug(stack_consistency_error, nsp, nbp);
3403 switch (vm_opt_binop_dispatch(recv, obj,
BOP_PLUS)) {
3406 case bot_fixnum:
return rb_fix_plus_fix(recv, obj);
3429 switch (vm_opt_binop_dispatch(recv, obj,
BOP_MINUS)) {
3432 case bot_fixnum:
return rb_fix_minus_fix(recv, obj);
3440 switch (vm_opt_binop_dispatch(recv, obj,
BOP_MULT)) {
3443 case bot_fixnum:
return rb_fix_mul_fix(recv, obj);
3451 switch (vm_opt_binop_dispatch(recv, obj,
BOP_DIV)) {
3456 return (
FIX2LONG(obj) == 0) ?
Qundef : rb_fix_div_fix(recv, obj);
3465 switch (vm_opt_binop_dispatch(recv, obj,
BOP_MOD)) {
3470 return (
FIX2LONG(obj) == 0) ?
Qundef : rb_fix_mod_fix(recv, obj);
3482 VALUE val = opt_eq_func(recv, obj, ci_eq, cc_eq);
3495 switch (vm_opt_binop_dispatch(recv, obj,
BOP_LT)) {
3512 switch (vm_opt_binop_dispatch(recv, obj,
BOP_LT)) {
3529 switch (vm_opt_binop_dispatch(recv, obj,
BOP_LT)) {
3546 switch (vm_opt_binop_dispatch(recv, obj,
BOP_LT)) {
3649 vm_opt_length(
VALUE recv,
int bop)
3677 vm_opt_empty_p(
VALUE recv)
3687 vm_opt_succ(
VALUE recv)
3714 if (vm_method_cfunc_is(ci, cc, recv, rb_obj_not)) {
RUBY_EXTERN VALUE rb_cString
double ruby_float_mod(double x, double y)
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
void rb_thread_schedule(void)
wrapper for method_missing(id)
#define UNDEFINED_METHOD_ENTRY_P(me)
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
#define RUBY_VM_CHECK_INTS(th)
VALUE rb_reg_match_last(VALUE)
void rb_warn(const char *fmt,...)
void rb_bug(const char *fmt,...)
VALUE rb_str_length(VALUE)
VALUE rb_ary_entry(VALUE ary, long offset)
RUBY_EXTERN VALUE rb_cFloat
#define RUBY_EVENT_C_RETURN
VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE)
VALUE rb_str_equal(VALUE str1, VALUE str2)
VALUE ruby_vm_const_missing_count
#define RUBY_DTRACE_METHOD_RETURN_HOOK(th, klass, id)
#define RUBY_EVENT_RETURN
const rb_callable_method_entry_t * me
#define RB_DEBUG_COUNTER_INC_UNLESS(type, cond)
VALUE rb_threadptr_backtrace_object(rb_thread_t *th)
#define VM_DEFINECLASS_TYPE(x)
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
#define GetProcPtr(obj, ptr)
const VALUE cref_or_me
class reference or rb_method_entry_t
#define vm_check_frame(a, b, c, d)
void rb_raise(VALUE exc, const char *fmt,...)
#define VM_DEFINECLASS_SCOPED_P(x)
enum method_missing_reason method_missing_reason
struct rb_method_definition_struct rb_method_definition_t
struct rb_method_definition_struct *const def
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
#define CHECK_CFP_CONSISTENCY(func)
#define RUBY_DTRACE_CMETHOD_RETURN_ENABLED()
VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2)
call-seq: obj != other -> true or false
struct rb_iseq_constant_body::@135::@136 flags
#define TH_JUMP_TAG(th, st)
#define HASH_REDEFINED_OP_FLAG
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, int argc, const VALUE *argv, VALUE passed_block_handler)
VALUE rb_reg_match(VALUE, VALUE)
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
VALUE rb_ary_push(VALUE ary, VALUE item)
#define VM_BLOCK_HANDLER_NONE
#define GET_BLOCK_HANDLER()
VALUE rb_str_concat(VALUE, VALUE)
VALUE rb_str_plus(VALUE, VALUE)
VALUE rb_iseq_defined_string(enum defined_type type)
struct rb_iseq_constant_body * body
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define ROBJECT_IV_INDEX_TBL(o)
VALUE rb_ivar_get(VALUE, ID)
#define OPTIMIZED_CMP(a, b, data)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
int rb_const_defined(VALUE, ID)
#define VM_CALL_ARGS_SPLAT
void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)
#define STACK_ADDR_FROM_TOP(n)
NORETURN(static void threadptr_stack_overflow(rb_thread_t *, int))
#define GET_GLOBAL_METHOD_STATE()
const rb_callable_method_entry_t * rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class)
VALUE rb_reg_match_post(VALUE)
RUBY_EXTERN VALUE rb_cProc
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause.
VALUE rb_ivar_defined(VALUE, ID)
PUREFUNC(static rb_callable_method_entry_t *check_method_entry(VALUE obj, int can_be_svar))
VALUE rb_reg_last_match(VALUE)
#define FALSE_REDEFINED_OP_FLAG
#define IS_ARGS_KEYWORD(ci)
#define RUBY_DTRACE_METHOD_ENTRY_HOOK(th, klass, id)
#define VM_ENV_DATA_INDEX_ME_CREF
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, klass, id)
#define THROW_DATA_P(err)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
VALUE rb_vm_make_proc(rb_thread_t *th, const struct rb_captured_block *captured, VALUE klass)
enum iseq_catch_table_entry::catch_type type
const VALUE * iseq_encoded
const rb_callable_method_entry_t * rb_vm_frame_method_entry(const rb_control_frame_t *cfp)
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
VALUE rb_float_equal(VALUE x, VALUE y)
#define RB_TYPE_P(obj, type)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
#define BASIC_OP_UNREDEFINED_P(op, klass)
VALUE rb_cvar_defined(VALUE, ID)
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
struct rb_cref_struct *const next
#define RUBY_DTRACE_METHOD_ENTRY_ENABLED()
#define IS_ARGS_SPLAT(ci)
VALUE rb_dbl2big(double d)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
enum method_missing_reason method_missing_reason
VALUE(* vm_call_handler)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
unsigned int local_table_size
VALUE rb_gvar_defined(struct rb_global_entry *)
const rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class)
RUBY_EXTERN VALUE rb_cObject
#define CALLER_SETUP_ARG(cfp, calling, ci)
RUBY_EXTERN VALUE rb_cBasicObject
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc)
#define CHECK_CMP_NAN(a, b)
ALWAYS_INLINE(static VALUE vm_getivar(VALUE, ID, IC, struct rb_call_cache *, int))
#define TRUE_REDEFINED_OP_FLAG
struct rb_method_definition_struct *const def
#define OBJ_BUILTIN_TYPE(obj)
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_define_module_id(ID id)
int rb_public_const_defined_from(VALUE klass, ID id)
void rb_notimplement(void)
VALUE rb_str_eql(VALUE str1, VALUE str2)
VALUE rb_hash_has_key(VALUE hash, VALUE key)
const VALUE special_exceptions[ruby_special_error_count]
#define ALLOCA_N(type, n)
const VALUE defined_class
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, klass, id)
union rb_captured_block::@141 code
VALUE rb_float_eql(VALUE x, VALUE y)
#define VM_GUARDED_PREV_EP(ep)
RUBY_EXTERN VALUE rb_cModule
#define MEMCPY(p1, p2, type, n)
RUBY_EXTERN int isinf(double)
void rb_obj_copy_ivar(VALUE dest, VALUE obj)
#define RUBY_EVENT_C_CALL
VALUE rb_struct_aset(VALUE, VALUE, VALUE)
#define VM_DEFINECLASS_HAS_SUPERCLASS_P(x)
struct iseq_inline_storage_entry::@133 once
void rb_vm_pop_frame(rb_thread_t *th)
#define VM_ENV_DATA_INDEX_SPECVAL
#define VM_SP_CNT(th, sp)
void rb_threadptr_stack_overflow(rb_thread_t *th, int crit)
#define RCLASS_REFINED_CLASS(c)
VALUE rb_const_get(VALUE, ID)
VALUE rb_ary_to_ary(VALUE obj)
attr_writer or attr_accessor
#define STRING_REDEFINED_OP_FLAG
union rb_call_cache::@134 aux
#define RARRAY_CONST_PTR(a)
#define CI_SET_FASTPATH(cc, func, enabled)
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
struct rb_iseq_constant_body::@135 param
parameter information
VALUE rb_sprintf(const char *format,...)
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
#define RICLASS_IS_ORIGIN
#define RUBY_DTRACE_CMETHOD_ENTRY_ENABLED()
const rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status)
#define VM_CHECKMATCH_TYPE_MASK
#define MEMMOVE(p1, p2, type, n)
#define VMDEBUG
VM Debug Level.
VALUE rb_ivar_set(VALUE, ID, VALUE)
void rb_const_set(VALUE, ID, VALUE)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aref(rb_thread_t *th, rb_control_frame_t *reg_cfp)
VALUE rb_sym_to_proc(VALUE sym)
IFUNC (Internal FUNCtion)
#define METHOD_ENTRY_VISI(me)
int rb_autoloading_value(VALUE mod, ID id, VALUE *value)
#define EXEC_EVENT_HOOK(th_, flag_, self_, id_, called_id_, klass_, data_)
const VALUE defined_class
#define REGEXP_REDEFINED_OP_FLAG
VALUE ruby_vm_special_exception_copy(VALUE exc)
#define VM_CHECKMATCH_ARRAY
#define VM_ENV_DATA_INDEX_FLAGS
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
const struct vm_ifunc * ifunc
void rb_const_warn_if_deprecated(const rb_const_entry_t *ce, VALUE klass, ID id)
VALUE rb_equal_opt(VALUE obj1, VALUE obj2)
enum rb_iseq_constant_body::iseq_type type
union iseq_inline_cache_entry::@132 ic_value
#define RUBY_VM_END_CONTROL_FRAME(th)
#define RB_FLOAT_TYPE_P(obj)
Kernel::send, Proc::call, etc.
const rb_callable_method_entry_t * passed_bmethod_me
struct rb_captured_block captured
register unsigned int len
VALUE rb_str_freeze(VALUE)
VALUE rb_mRubyVMFrozenCore
void rb_vm_rewrite_cref(rb_cref_t *cref, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr)
#define SYMBOL_REDEFINED_OP_FLAG
#define RB_OBJ_WRITE(a, slot, b)
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
const rb_cref_t * ic_cref
int rb_const_defined_at(VALUE, ID)
rb_const_entry_t * rb_const_lookup(VALUE klass, ID id)
#define UNLIMITED_ARGUMENTS
VALUE rb_hash_compare_by_id_p(VALUE hash)
const struct iseq_catch_table * catch_table
const rb_callable_method_entry_t * rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
#define RARRAY_AREF(a, i)
VALUE rb_ary_plus(VALUE x, VALUE y)
#define RBASIC_CLASS(obj)
#define rb_thread_raised_reset(th, f)
#define FLOAT_REDEFINED_OP_FLAG
VALUE rb_check_array_type(VALUE ary)
VALUE rb_struct_aref(VALUE, VALUE)
VALUE rb_hash_aref(VALUE hash, VALUE key)
void rb_error_arity(int argc, int min, int max)
struct rb_iseq_struct * local_iseq
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj)
void rb_warning(const char *fmt,...)
int rb_method_basic_definition_p(VALUE, ID)
VALUE rb_str_cat_cstr(VALUE, const char *)
#define RB_BUILTIN_TYPE(x)
struct rb_thread_struct * running_thread
#define INTEGER_REDEFINED_OP_FLAG
#define VM_UNREACHABLE(func)
const char * rb_obj_info(VALUE obj)
VALUE rb_ary_dup(VALUE ary)
VALUE rb_public_const_get_at(VALUE klass, ID id)
VALUE rb_ary_concat(VALUE x, VALUE y)
#define rb_thread_raised_p(th, f)
void rb_gc_writebarrier_remember(VALUE obj)
#define ARRAY_REDEFINED_OP_FLAG
const struct rb_iseq_struct * parent_iseq
#define RB_DEBUG_COUNTER_INC(type)
#define EQ_UNREDEFINED_P(t)
VALUE rb_const_get_at(VALUE, ID)
VALUE rb_reg_match_pre(VALUE)
rb_execution_context_t ec
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
VALUE rb_define_class_id(ID id, VALUE super)
Defines a new class.
NOINLINE(static void vm_env_write_slowpath(const VALUE *ep, int index, VALUE v))
#define RUBY_DTRACE_METHOD_RETURN_ENABLED()
#define NIL_REDEFINED_OP_FLAG
#define rb_check_frozen(obj)
void rb_vm_env_write(const VALUE *ep, int index, VALUE v)
VALUE rb_str_intern(VALUE)
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aset(rb_thread_t *th, rb_control_frame_t *reg_cfp)
#define SPECIAL_CONST_P(x)
VALUE rb_public_const_get_from(VALUE klass, ID id)
#define CHECK_VM_STACK_OVERFLOW(cfp, margin)
int rb_method_boundp(VALUE, ID, int)
#define GET_GLOBAL_CONSTANT_STATE()
struct rb_global_entry * rb_global_entry(ID)
VALUE rb_class_real(VALUE cl)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
attr_reader or attr_accessor
#define BUILTIN_CLASS_P(x, k)
void rb_gc_verify_internal_consistency(void)
VALUE rb_str_append(VALUE, VALUE)
#define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
VALUE rb_autoload_load(VALUE, ID)
void rb_set_class_path_string(VALUE, VALUE, VALUE)
VALUE rb_reg_nth_match(int, VALUE)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_eql_opt(VALUE obj1, VALUE obj2)
rb_control_frame_t * rb_vm_push_frame(rb_execution_context_t *ec, const rb_iseq_t *iseq, VALUE type, VALUE self, VALUE specval, VALUE cref_or_me, const VALUE *pc, VALUE *sp, int local_size, int stack_max)