34 if ((
void *)(sp + local_size) >= (
void *)cfp) {
41 for (i=0; i < local_size; i++) {
67 #define COLLECT_PROFILE 0
69 cfp->prof_time_self = clock();
70 cfp->prof_time_chld = 0;
87 VALUE current_time = clock();
89 cfp->prof_time_self = current_time - cfp->prof_time_self;
90 (cfp+1)->prof_time_chld += cfp->prof_time_self;
92 cfp->
iseq->profile.count++;
93 cfp->
iseq->profile.time_cumu = cfp->prof_time_self;
94 cfp->
iseq->profile.time_self = cfp->prof_time_self - cfp->prof_time_chld;
113 VALUE mesg =
rb_sprintf(
"wrong number of arguments (%d for %d)", miss_argc, correct_argc);
135 #define VM_CALLEE_SETUP_ARG(ret, th, iseq, orig_argc, orig_argv, block) \
136 if (LIKELY((iseq)->arg_simple & 0x01)) { \
138 if ((orig_argc) != (iseq)->argc) { \
139 argument_error((iseq), (orig_argc), (iseq)->argc); \
144 (ret) = vm_callee_setup_arg_complex((th), (iseq), (orig_argc), (orig_argv), (block)); \
149 int orig_argc,
VALUE * orig_argv,
152 const int m = iseq->
argc;
153 int argc = orig_argc;
169 if (!(orig_argc < iseq->arg_post_start)) {
183 if (iseq->
arg_rest == -1 && argc > opts) {
194 for (i = argc; i<
opts; i++) {
195 orig_argv[i +
m] =
Qnil;
219 if (blockptr->
proc == 0) {
223 *block = &proc->
block;
226 blockval = blockptr->
proc;
255 "wrong argument type %s (expected Proc)",
261 blockptr = &po->
block;
266 else if (blockiseq) {
268 blockptr->
iseq = blockiseq;
291 for (i = 0; i <
len; i++) {
307 if (len >= 0 && argc != len) {
320 return (*
func) (recv);
323 return (*
func) (recv, argv[0]);
326 return (*
func) (recv, argv[0], argv[1]);
329 return (*
func) (recv, argv[0], argv[1], argv[2]);
332 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3]);
335 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
338 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
342 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
346 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
347 argv[5], argv[6], argv[7]);
350 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
351 argv[5], argv[6], argv[7], argv[8]);
354 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
355 argv[5], argv[6], argv[7], argv[8], argv[9]);
358 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
359 argv[5], argv[6], argv[7], argv[8], argv[9],
363 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
364 argv[5], argv[6], argv[7], argv[8], argv[9],
368 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
369 argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
373 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
374 argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
375 argv[11], argv[12], argv[13]);
378 return (*
func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
379 argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
380 argv[11], argv[12], argv[13], argv[14]);
400 recv, (
VALUE) blockptr, 0, reg_cfp->
sp, 0, 1);
402 reg_cfp->
sp -= num + 1;
406 if (reg_cfp != th->
cfp + 1) {
407 rb_bug(
"cfp consistency error - send");
454 return rb_funcall2(recv, idMethodMissing, num + 1, argv);
474 if (0) printf(
"local_size: %d, arg_size: %d\n",
494 for (i=0; i < (sp - rsp); i++) {
518 start_method_dispatch:
521 if ((me->
flag == 0)) {
522 normal_method_dispatch:
553 cfp->
sp += - num - 1;
561 cfp->
sp += - num - 1;
570 goto normal_method_dispatch;
573 goto start_method_dispatch;
578 case OPTIMIZED_METHOD_TYPE_SEND: {
598 goto start_method_dispatch;
600 case OPTIMIZED_METHOD_TYPE_CALL: {
612 rb_bug(
"eval_invoke_method: unsupported optimized method type (%d)",
618 rb_bug(
"eval_invoke_method: unsupported method type (%d)", me->
def->
type);
639 defined_class =
RBASIC(defined_class)->klass;
646 goto normal_method_dispatch;
654 goto normal_method_dispatch;
667 if (
id == idMethodMissing) {
709 else if (argc == 0) {
717 if (blockargptr->
proc) {
718 blockarg = blockargptr->
proc;
735 val = (*ifunc->nd_cfnc) (
arg, ifunc->nd_tval, argc, argv, blockarg);
752 const int m = iseq->
argc;
756 int rsize = argc > m ? argc - m : 0;
757 int psize = rsize > len ? len : rsize;
778 printf(
" argc: %d\n", argc);
779 printf(
" len: %d\n", len);
780 printf(
"start: %d\n", start);
781 printf(
"rsize: %d\n", rsize);
792 MEMMOVE(&argv[start], &argv[m+rsize+osize],
VALUE, psize);
796 for (i=psize; i<
len; i++) {
797 argv[start +
i] =
Qnil;
809 int argc = orig_argc;
810 const int m = iseq->
argc;
835 for (i=argc; i<
m; i++) {
840 const int arg_size = iseq->
arg_size;
841 if (arg_size < argc) {
861 for (i=argc; i<
r; i++) {
879 if (blockptr->
proc == 0) {
883 procval = blockptr->
proc;
900 printf(
" argc: %d\n", argc);
901 printf(
"iseq argc: %d\n", iseq->
argc);
902 printf(
"iseq opts: %d\n", iseq->
arg_opts);
903 printf(
"iseq rest: %d\n", iseq->
arg_rest);
905 printf(
"iseq blck: %d\n", iseq->
arg_block);
907 printf(
" lambda: %s\n", lambda ?
"true" :
"false");
929 if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) {
938 const int arg_size = iseq->
arg_size;
976 return (
NODE *)*svar;
1037 switch (type >> 1) {
1051 rb_bug(
"unexpected back-ref");
1069 else if (dfp[-1] !=
Qnil) {
1070 return (
NODE *)dfp[-1];
1082 rb_bug(
"vm_get_cref: unreachable");
1092 cref->nd_visi = noex;
1111 if ((klass = cref->nd_clss) != 0) {
1114 cref = cref->nd_next;
1128 (klass = cref->nd_clss) != 0) {
1131 cref = cref->nd_next;
1141 switch (
TYPE(klass)) {
1154 VALUE orig_klass,
ID id,
int is_defined)
1158 if (orig_klass ==
Qnil) {
1165 root_cref = root_cref->nd_next;
1168 while (cref && cref->nd_next) {
1173 klass = cref->nd_clss;
1175 cref = cref->nd_next;
1177 if (!
NIL_P(klass)) {
1185 if (am == klass)
break;
1187 if (is_defined)
return 1;
1189 goto search_continue;
1204 if (root_cref && !
NIL_P(root_cref->nd_clss)) {
1205 klass = root_cref->nd_clss;
1234 while (cref && cref->nd_next &&
1237 cref = cref->nd_next;
1239 if (!cref->nd_next) {
1240 rb_warn(
"class variable access from toplevel");
1244 klass = cref->nd_clss;
1266 #ifndef USE_IC_FOR_IVAR
1267 #define USE_IC_FOR_IVAR 1
1295 if (
st_lookup(iv_index_tbl,
id, &index)) {
1296 if ((
long)index < len) {
1365 #if OPT_INLINE_METHOD_CACHE
1399 rb_bug(
"vm_search_normal_superclass: should not be reach here");
1411 while (iseq && !iseq->
klass) {
1427 rb_raise(
rb_eRuntimeError,
"implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.");
1430 while (lcfp->
iseq != iseq) {
1437 "super called outside of method");
1439 if (lcfp->
dfp == tdfp) {
1465 int state = (
int)(throw_state & 0xff);
1466 int flag = (
int)(throw_state & 0x8000);
1482 if (cfp->
iseq->
type != ISEQ_TYPE_BLOCK) {
1483 if (cfp->
iseq->
type == ISEQ_TYPE_CLASS) {
1492 if (cfp->
dfp == dfp) {
1497 rb_bug(
"VM (throw): can't find break base.");
1510 if (cfp->
dfp == dfp) {
1519 entry->
start < epc && entry->
end >= epc) {
1520 if (entry->
cont == epc) {
1546 for (i = 0; i <
level; i++) {
1554 int in_class_frame = 0;
1561 if (cfp->
dfp == lfp && cfp->
iseq->
type == ISEQ_TYPE_CLASS) {
1566 if (cfp->
lfp == lfp) {
1570 if (in_class_frame) {
1576 while (lfp != tdfp) {
1577 if (cfp->
dfp == tdfp) {
1587 if (cfp->
dfp == lfp && cfp->
iseq->
type == ISEQ_TYPE_METHOD) {
1601 rb_bug(
"isns(throw): unsupport throw type");
1631 int is_splat = flag & 0x01;
1632 rb_num_t space_size = num + is_splat;
1634 volatile VALUE tmp_ary;
1641 cfp->
sp += space_size;
1652 for (i=0; i<num-
len; i++) {
1656 for (j=0; i<num; i++, j++) {
1667 VALUE *bptr = &base[space_size - 1];
1669 for (i=0; i<num; i++) {
1671 for (; i<num; i++) {
1702 #ifndef NO_BIG_INLINE
RUBY_EXTERN VALUE rb_cString
const rb_block_t * passed_block
#define VM_FRAME_MAGIC_BLOCK
#define VM_CALL_ARGS_SPLAT_BIT
#define DEFAULT_SPECIAL_VAR_COUNT
VALUE rb_reg_match_last(VALUE)
#define VM_CALL_ARGS_BLOCKARG_BIT
int register char * block
static VALUE vm_search_normal_superclass(VALUE klass, VALUE recv)
VALUE rb_ary_new4(long n, const VALUE *elts)
VALUE rb_ary_entry(VALUE ary, long offset)
RUBY_EXTERN VALUE rb_cFloat
static void lfp_svar_set(rb_thread_t *th, VALUE *lfp, rb_num_t key, VALUE val)
#define RUBY_EVENT_C_RETURN
void rb_bug(const char *fmt,...)
#define VM_CALL_SUPER_BIT
VALUE rb_str_equal(VALUE str1, VALUE str2)
static int caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, VALUE flag, int argc, rb_iseq_t *blockiseq, rb_block_t **block)
#define RUBY_EVENT_RETURN
#define VM_CALLEE_SETUP_ARG(ret, th, iseq, orig_argc, orig_argv, block)
static int vm_yield_setup_block_args(rb_thread_t *th, const rb_iseq_t *iseq, int orig_argc, VALUE *argv, const rb_block_t *blockptr)
#define VM_FRAME_MAGIC_CFUNC
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
#define GetProcPtr(obj, ptr)
const rb_method_entry_t * passed_me
#define RUBY_VM_NORMAL_ISEQ_P(ptr)
union rb_method_definition_struct::@42 body
static VALUE vm_method_missing(rb_thread_t *th, ID id, VALUE recv, int num, const rb_block_t *blockptr, int opt)
SSL_METHOD *(* func)(void)
#define RFLOAT_VALUE(val)
static int block_proc_is_lambda(const VALUE procval)
static void vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag)
#define VMDEBUG
VM Debug Level.
static const rb_method_entry_t * vm_method_search(VALUE id, VALUE klass, IC ic)
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
#define ROBJECT_IV_INDEX_TBL(o)
#define RSTRING_PTR(string)
#define VM_FRAME_MAGIC_METHOD
struct rb_iseq_struct * local_iseq
void rb_raise(VALUE exc, const char *fmt,...)
#define VM_FRAME_TYPE(cfp)
VALUE rb_ivar_get(VALUE, ID)
#define GET_PREV_DFP(dfp)
#define VM_FRAME_MAGIC_IFUNC
VALUE rb_obj_is_kind_of(VALUE, VALUE)
int rb_const_defined(VALUE, ID)
#define RARRAY_LEN(ARRAY)
#define GET_VM_STATE_VERSION()
void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)
#define STACK_ADDR_FROM_TOP(n)
VALUE rb_reg_match_post(VALUE)
RUBY_EXTERN VALUE rb_cProc
static void vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE recv, VALUE sigval, ID *idp, VALUE *klassp)
static int vm_yield_setup_args(rb_thread_t *const th, const rb_iseq_t *iseq, int argc, VALUE *argv, const rb_block_t *blockptr, int lambda)
static VALUE vm_search_const_defined_class(const VALUE cbase, ID id)
#define CHECK_STACK_OVERFLOW(cfp, margin)
static VALUE vm_getspecial(rb_thread_t *th, VALUE *lfp, rb_num_t key, rb_num_t type)
VALUE rb_reg_last_match(VALUE)
const rb_method_entry_t * me
static VALUE vm_get_cbase(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
const char * rb_obj_classname(VALUE)
static VALUE vm_getivar(VALUE obj, ID id, IC ic)
static void vm_check_if_namespace(VALUE klass)
static rb_control_frame_t * vm_push_frame(rb_thread_t *th, const rb_iseq_t *iseq, VALUE type, VALUE self, VALUE specval, const VALUE *pc, VALUE *sp, VALUE *lfp, int local_size)
static int vm_callee_setup_arg_complex(rb_thread_t *th, const rb_iseq_t *iseq, int orig_argc, VALUE *orig_argv, const rb_block_t **block)
enum iseq_catch_table_entry::catch_type type
void rb_exc_raise(VALUE mesg)
static NODE * lfp_svar_place(rb_thread_t *th, VALUE *lfp)
#define RB_TYPE_P(obj, type)
enum rb_iseq_struct::iseq_type type
static NODE * vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
#define RUBY_VM_CHECK_INTS()
static VALUE vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, int num, const rb_block_t *blockptr, VALUE flag, ID id, const rb_method_entry_t *me, VALUE recv)
#define HEAP_CLASS_OF(obj)
#define VM_CALL_FCALL_BIT
static VALUE lfp_svar_get(rb_thread_t *th, VALUE *lfp, rb_num_t key)
static void vm_setup_method(rb_thread_t *th, rb_control_frame_t *cfp, VALUE recv, int argc, const rb_block_t *blockptr, VALUE flag, const rb_method_entry_t *me)
void rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv, VALUE obj, int call_status)
RUBY_EXTERN VALUE rb_cObject
#define VM_CALL_OPT_SEND_BIT
static int vm_yield_setup_block_args_complex(rb_thread_t *th, const rb_iseq_t *iseq, int argc, VALUE *argv)
int argc
argument information
static VALUE vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj)
void rb_ary_store(VALUE ary, long idx, VALUE val)
int rb_public_const_defined_from(VALUE klass, ID id)
static NODE * vm_get_cref(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
static VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag)
#define ALLOCA_N(type, n)
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr)
#define MEMCPY(p1, p2, type, n)
static int check_cfunc(const rb_method_entry_t *me, VALUE(*func)())
#define RUBY_EVENT_C_CALL
static VALUE call_cfunc(VALUE(*func)(), VALUE recv, int len, int argc, const VALUE *argv)
union iseq_inline_cache_entry::@74 ic_value
VALUE rb_make_backtrace(void)
#define GC_GUARDED_PTR(p)
static NODE * vm_get_cref0(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
VALUE rb_const_get(VALUE, ID)
VALUE rb_ary_to_ary(VALUE obj)
rb_method_entry_t * method
#define VM_CALL_VCALL_BIT
VALUE rb_obj_is_proc(VALUE)
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
VALUE rb_sprintf(const char *format,...)
#define MEMMOVE(p1, p2, type, n)
static VALUE vm_get_const_base(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp)
struct rb_iseq_struct * parent_iseq
static void vm_method_missing_args(rb_thread_t *th, VALUE *argv, int num, const rb_block_t *blockptr, int opt)
static VALUE vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, int num, volatile VALUE recv, const rb_block_t *blockptr, const rb_method_entry_t *me)
static VALUE vm_get_cvar_base(NODE *cref)
static VALUE vm_call_bmethod(rb_thread_t *th, VALUE recv, int argc, const VALUE *argv, const rb_block_t *blockptr, const rb_method_entry_t *me)
static void vm_pop_frame(rb_thread_t *th)
static void argument_error(const rb_iseq_t *iseq, int miss_argc, int correct_argc)
register unsigned int len
#define RARRAY_LENINT(ary)
rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
#define NEW_THROW_OBJECT(val, pt, st)
#define RCLASS_CONST_TBL(c)
VALUE rb_obj_equal(VALUE obj1, VALUE obj2)
#define EXEC_EVENT_HOOK(th, flag, self, id, klass)
int rb_const_defined_at(VALUE, ID)
#define VM_FRAME_MAGIC_LAMBDA
VALUE rb_exc_new3(VALUE etype, VALUE str)
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
rb_method_definition_t * def
VALUE rb_check_array_type(VALUE ary)
rb_ivar_set(einfo, ID_at_interp, interp)
struct iseq_catch_table_entry * catch_table
enum rb_method_definition_struct::@42::method_optimized_type optimize_type
VALUE rb_reg_match_pre(VALUE)
const char * rb_id2name(ID id)
#define VM_CALL_TAILCALL_BIT
return rb_funcall(q->proc, ID_call, 0)
#define StringValuePtr(v)
static void vm_setivar(VALUE obj, ID id, VALUE val, IC ic)
void rb_warning(const char *fmt,...)
#define rb_check_frozen(obj)
#define GC_GUARDED_PTR_REF(p)
static rb_control_frame_t * vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
static VALUE vm_get_ev_const(rb_thread_t *th, const rb_iseq_t *iseq, VALUE orig_klass, ID id, int is_defined)
#define SPECIAL_CONST_P(x)
VALUE rb_public_const_get_from(VALUE klass, ID id)
struct iseq_insn_info_entry * insn_info_table
#define NODE_FL_CREF_PUSHED_BY_EVAL
int method_missing_reason
#define GET_THROWOBJ_STATE(obj)
void rb_warn(const char *fmt,...)
VALUE rb_autoload_load(VALUE, ID)
VALUE rb_reg_nth_match(int, VALUE)
VALUE rb_attr_get(VALUE, ID)
#define BASIC_OP_UNREDEFINED_P(op)
static VALUE vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, VALUE self, int argc, const VALUE *argv, const rb_block_t *blockargptr)
static VALUE opt_eq_func(VALUE recv, VALUE obj, IC ic)