Ruby  2.1.4p265(2014-10-27revision48166)
vm_insnhelper.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  vm_insnhelper.c - instruction helper functions.
4 
5  $Author: nagachika $
6 
7  Copyright (C) 2007 Koichi Sasada
8 
9 **********************************************************************/
10 
11 /* finish iseq array */
12 #include "insns.inc"
13 #include <math.h>
14 #include "constant.h"
15 #include "internal.h"
16 #include "probes.h"
17 #include "probes_helper.h"
18 
19 /* control stack frame */
20 
21 #ifndef INLINE
22 #define INLINE inline
23 #endif
24 
26 
27 static void
29 {
31 }
32 
33 static inline rb_control_frame_t *
35  const rb_iseq_t *iseq,
36  VALUE type,
37  VALUE self,
38  VALUE klass,
39  VALUE specval,
40  const VALUE *pc,
41  VALUE *sp,
42  int local_size,
43  const rb_method_entry_t *me,
44  size_t stack_max)
45 {
46  rb_control_frame_t *const cfp = th->cfp - 1;
47  int i;
48 
49  /* check stack overflow */
50  CHECK_VM_STACK_OVERFLOW0(cfp, sp, local_size + (int)stack_max);
51 
52  th->cfp = cfp;
53 
54  /* setup vm value stack */
55 
56  /* initialize local variables */
57  for (i=0; i < local_size; i++) {
58  *sp++ = Qnil;
59  }
60 
61  /* set special val */
62  *sp = specval;
63 
64  /* setup vm control frame stack */
65 
66  cfp->pc = (VALUE *)pc;
67  cfp->sp = sp + 1;
68 #if VM_DEBUG_BP_CHECK
69  cfp->bp_check = sp + 1;
70 #endif
71  cfp->ep = sp;
72  cfp->iseq = (rb_iseq_t *) iseq;
73  cfp->flag = type;
74  cfp->self = self;
75  cfp->block_iseq = 0;
76  cfp->proc = 0;
77  cfp->me = me;
78  if (klass) {
79  cfp->klass = klass;
80  }
81  else {
83  if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, prev_cfp)) {
84  cfp->klass = Qnil;
85  }
86  else {
87  cfp->klass = prev_cfp->klass;
88  }
89  }
90 
91  if (VMDEBUG == 2) {
92  SDR();
93  }
94 
95  return cfp;
96 }
97 
98 static inline void
100 {
102 
103  if (VMDEBUG == 2) {
104  SDR();
105  }
106 }
107 
108 /* method dispatch */
109 static inline VALUE
110 rb_arg_error_new(int argc, int min, int max)
111 {
112  VALUE err_mess = 0;
113  if (min == max) {
114  err_mess = rb_sprintf("wrong number of arguments (%d for %d)", argc, min);
115  }
116  else if (max == UNLIMITED_ARGUMENTS) {
117  err_mess = rb_sprintf("wrong number of arguments (%d for %d+)", argc, min);
118  }
119  else {
120  err_mess = rb_sprintf("wrong number of arguments (%d for %d..%d)", argc, min, max);
121  }
122  return rb_exc_new3(rb_eArgError, err_mess);
123 }
124 
125 NORETURN(static void argument_error(const rb_iseq_t *iseq, int miss_argc, int min_argc, int max_argc));
126 static void
127 argument_error(const rb_iseq_t *iseq, int miss_argc, int min_argc, int max_argc)
128 {
129  rb_thread_t *th = GET_THREAD();
130  VALUE exc = rb_arg_error_new(miss_argc, min_argc, max_argc);
131  VALUE at;
132 
133  if (iseq) {
134  vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD, Qnil /* self */, Qnil /* klass */, Qnil /* specval*/,
135  iseq->iseq_encoded, th->cfp->sp, 0 /* local_size */, 0 /* me */, 0 /* stack_max */);
136  at = rb_vm_backtrace_object();
137  vm_pop_frame(th);
138  }
139  else {
140  at = rb_vm_backtrace_object();
141  }
142 
143  rb_iv_set(exc, "bt_locations", at);
144  rb_funcall(exc, rb_intern("set_backtrace"), 1, at);
145  rb_exc_raise(exc);
146 }
147 
148 void
149 rb_error_arity(int argc, int min, int max)
150 {
151  rb_exc_raise(rb_arg_error_new(argc, min, max));
152 }
153 
154 /* svar */
155 
156 static inline NODE *
158 {
159  VALUE *svar;
160 
161  if (lep && th->root_lep != lep) {
162  svar = &lep[-1];
163  }
164  else {
165  svar = &th->root_svar;
166  }
167  if (NIL_P(*svar)) {
168  *svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil);
169  }
170  return (NODE *)*svar;
171 }
172 
173 static VALUE
175 {
176  NODE *svar = lep_svar_place(th, lep);
177 
178  switch (key) {
179  case 0:
180  return svar->u1.value;
181  case 1:
182  return svar->u2.value;
183  default: {
184  const VALUE ary = svar->u3.value;
185 
186  if (NIL_P(ary)) {
187  return Qnil;
188  }
189  else {
190  return rb_ary_entry(ary, key - DEFAULT_SPECIAL_VAR_COUNT);
191  }
192  }
193  }
194 }
195 
196 static void
198 {
199  NODE *svar = lep_svar_place(th, lep);
200 
201  switch (key) {
202  case 0:
203  svar->u1.value = val;
204  return;
205  case 1:
206  svar->u2.value = val;
207  return;
208  default: {
209  VALUE ary = svar->u3.value;
210 
211  if (NIL_P(ary)) {
212  svar->u3.value = ary = rb_ary_new();
213  }
214  rb_ary_store(ary, key - DEFAULT_SPECIAL_VAR_COUNT, val);
215  }
216  }
217 }
218 
219 static inline VALUE
221 {
222  VALUE val;
223 
224  if (type == 0) {
225  val = lep_svar_get(th, lep, key);
226  }
227  else {
228  VALUE backref = lep_svar_get(th, lep, 1);
229 
230  if (type & 0x01) {
231  switch (type >> 1) {
232  case '&':
233  val = rb_reg_last_match(backref);
234  break;
235  case '`':
236  val = rb_reg_match_pre(backref);
237  break;
238  case '\'':
239  val = rb_reg_match_post(backref);
240  break;
241  case '+':
242  val = rb_reg_match_last(backref);
243  break;
244  default:
245  rb_bug("unexpected back-ref");
246  }
247  }
248  else {
249  val = rb_reg_nth_match((int)(type >> 1), backref);
250  }
251  }
252  return val;
253 }
254 
255 static NODE *
256 vm_get_cref0(const rb_iseq_t *iseq, const VALUE *ep)
257 {
258  while (1) {
259  if (VM_EP_LEP_P(ep)) {
260  if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) return NULL;
261  return iseq->cref_stack;
262  }
263  else if (ep[-1] != Qnil) {
264  return (NODE *)ep[-1];
265  }
266  ep = VM_EP_PREV_EP(ep);
267  }
268 }
269 
270 NODE *
271 rb_vm_get_cref(const rb_iseq_t *iseq, const VALUE *ep)
272 {
273  NODE *cref = vm_get_cref0(iseq, ep);
274 
275  if (cref == 0) {
276  rb_bug("rb_vm_get_cref: unreachable");
277  }
278  return cref;
279 }
280 
281 static NODE *
282 vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
283 {
285  NODE *cref = NEW_CREF(klass);
286  cref->nd_refinements = Qnil;
287  cref->nd_visi = noex;
288 
289  if (blockptr) {
290  RB_OBJ_WRITE(cref, &cref->nd_next, vm_get_cref0(blockptr->iseq, blockptr->ep));
291  }
292  else if (cfp) {
293  RB_OBJ_WRITE(cref, &cref->nd_next, vm_get_cref0(cfp->iseq, cfp->ep));
294  }
295  /* TODO: why cref->nd_next is 1? */
296  if (cref->nd_next && cref->nd_next != (void *) 1 &&
297  !NIL_P(cref->nd_next->nd_refinements)) {
298  COPY_CREF_OMOD(cref, cref->nd_next);
299  }
300 
301  return cref;
302 }
303 
304 static inline VALUE
305 vm_get_cbase(const rb_iseq_t *iseq, const VALUE *ep)
306 {
307  NODE *cref = rb_vm_get_cref(iseq, ep);
308  VALUE klass = Qundef;
309 
310  while (cref) {
311  if ((klass = cref->nd_clss) != 0) {
312  break;
313  }
314  cref = cref->nd_next;
315  }
316 
317  return klass;
318 }
319 
320 static inline VALUE
321 vm_get_const_base(const rb_iseq_t *iseq, const VALUE *ep)
322 {
323  NODE *cref = rb_vm_get_cref(iseq, ep);
324  VALUE klass = Qundef;
325 
326  while (cref) {
327  if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) &&
328  (klass = cref->nd_clss) != 0) {
329  break;
330  }
331  cref = cref->nd_next;
332  }
333 
334  return klass;
335 }
336 
337 static inline void
339 {
340  VALUE str;
341  if (!RB_TYPE_P(klass, T_CLASS) && !RB_TYPE_P(klass, T_MODULE)) {
342  str = rb_inspect(klass);
343  rb_raise(rb_eTypeError, "%s is not a class/module",
344  StringValuePtr(str));
345  }
346 }
347 
348 static inline VALUE
350 {
351  if (RB_TYPE_P(klass, T_MODULE) &&
352  FL_TEST(klass, RMODULE_IS_OVERLAID) &&
353  RB_TYPE_P(cfp->klass, T_ICLASS) &&
354  RBASIC(cfp->klass)->klass == klass) {
355  return cfp->klass;
356  }
357  else {
358  return klass;
359  }
360 }
361 
362 static inline VALUE
364  VALUE orig_klass, ID id, int is_defined)
365 {
366  VALUE val;
367 
368  if (orig_klass == Qnil) {
369  /* in current lexical scope */
370  const NODE *root_cref = rb_vm_get_cref(iseq, th->cfp->ep);
371  const NODE *cref;
372  VALUE klass = orig_klass;
373 
374  while (root_cref && root_cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) {
375  root_cref = root_cref->nd_next;
376  }
377  cref = root_cref;
378  while (cref && cref->nd_next) {
379  if (cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) {
380  klass = Qnil;
381  }
382  else {
383  klass = cref->nd_clss;
384  }
385  cref = cref->nd_next;
386 
387  if (!NIL_P(klass)) {
388  VALUE av, am = 0;
389  st_data_t data;
390  search_continue:
391  if (RCLASS_CONST_TBL(klass) &&
392  st_lookup(RCLASS_CONST_TBL(klass), id, &data)) {
393  val = ((rb_const_entry_t*)data)->value;
394  if (val == Qundef) {
395  if (am == klass) break;
396  am = klass;
397  if (is_defined) return 1;
398  if (rb_autoloading_value(klass, id, &av)) return av;
399  rb_autoload_load(klass, id);
400  goto search_continue;
401  }
402  else {
403  if (is_defined) {
404  return 1;
405  }
406  else {
407  return val;
408  }
409  }
410  }
411  }
412  }
413 
414  /* search self */
415  if (root_cref && !NIL_P(root_cref->nd_clss)) {
416  klass = vm_get_iclass(th->cfp, root_cref->nd_clss);
417  }
418  else {
419  klass = CLASS_OF(th->cfp->self);
420  }
421 
422  if (is_defined) {
423  return rb_const_defined(klass, id);
424  }
425  else {
426  return rb_const_get(klass, id);
427  }
428  }
429  else {
430  vm_check_if_namespace(orig_klass);
431  if (is_defined) {
432  return rb_public_const_defined_from(orig_klass, id);
433  }
434  else {
435  return rb_public_const_get_from(orig_klass, id);
436  }
437  }
438 }
439 
440 static inline VALUE
442 {
443  VALUE klass;
444 
445  if (!cref) {
446  rb_bug("vm_get_cvar_base: no cref");
447  }
448 
449  while (cref->nd_next &&
450  (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON) ||
451  (cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL))) {
452  cref = cref->nd_next;
453  }
454  if (!cref->nd_next) {
455  rb_warn("class variable access from toplevel");
456  }
457 
458  klass = vm_get_iclass(cfp, cref->nd_clss);
459 
460  if (NIL_P(klass)) {
461  rb_raise(rb_eTypeError, "no class variables available");
462  }
463  return klass;
464 }
465 
466 static VALUE
468 {
469  if (rb_const_defined_at(cbase, id)) return cbase;
470  if (cbase == rb_cObject) {
471  VALUE tmp = RCLASS_SUPER(cbase);
472  while (tmp) {
473  if (rb_const_defined_at(tmp, id)) return tmp;
474  tmp = RCLASS_SUPER(tmp);
475  }
476  }
477  return 0;
478 }
479 
480 #ifndef USE_IC_FOR_IVAR
481 #define USE_IC_FOR_IVAR 1
482 #endif
483 
484 static inline VALUE
485 vm_getivar(VALUE obj, ID id, IC ic, rb_call_info_t *ci, int is_attr)
486 {
487 #if USE_IC_FOR_IVAR
488  if (RB_TYPE_P(obj, T_OBJECT)) {
489  VALUE val = Qundef;
490  VALUE klass = RBASIC(obj)->klass;
491 
492  if (LIKELY((!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) ||
493  (is_attr && ci->aux.index > 0))) {
494  long index = !is_attr ? (long)ic->ic_value.index : ci->aux.index - 1;
495  long len = ROBJECT_NUMIV(obj);
496  VALUE *ptr = ROBJECT_IVPTR(obj);
497 
498  if (index < len) {
499  val = ptr[index];
500  }
501  }
502  else {
503  st_data_t index;
504  long len = ROBJECT_NUMIV(obj);
505  VALUE *ptr = ROBJECT_IVPTR(obj);
506  struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
507 
508  if (iv_index_tbl) {
509  if (st_lookup(iv_index_tbl, id, &index)) {
510  if ((long)index < len) {
511  val = ptr[index];
512  }
513  if (!is_attr) {
514  ic->ic_value.index = index;
515  ic->ic_serial = RCLASS_SERIAL(klass);
516  }
517  else { /* call_info */
518  ci->aux.index = index + 1;
519  }
520  }
521  }
522  }
523 
524  if (UNLIKELY(val == Qundef)) {
525  if (!is_attr) rb_warning("instance variable %s not initialized", rb_id2name(id));
526  val = Qnil;
527  }
528  return val;
529  }
530 #endif /* USE_IC_FOR_IVAR */
531  if (is_attr)
532  return rb_attr_get(obj, id);
533  return rb_ivar_get(obj, id);
534 }
535 
536 static inline VALUE
537 vm_setivar(VALUE obj, ID id, VALUE val, IC ic, rb_call_info_t *ci, int is_attr)
538 {
539 #if USE_IC_FOR_IVAR
540  rb_check_frozen(obj);
541 
542  if (RB_TYPE_P(obj, T_OBJECT)) {
543  VALUE klass = RBASIC(obj)->klass;
544  st_data_t index;
545 
546  if (LIKELY(
547  (!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) ||
548  (is_attr && ci->aux.index > 0))) {
549  long index = !is_attr ? (long)ic->ic_value.index : ci->aux.index-1;
550  long len = ROBJECT_NUMIV(obj);
551  VALUE *ptr = ROBJECT_IVPTR(obj);
552 
553  if (index < len) {
554  RB_OBJ_WRITE(obj, &ptr[index], val);
555  return val; /* inline cache hit */
556  }
557  }
558  else {
559  struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
560 
561  if (iv_index_tbl && st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
562  if (!is_attr) {
563  ic->ic_value.index = index;
564  ic->ic_serial = RCLASS_SERIAL(klass);
565  }
566  else {
567  ci->aux.index = index + 1;
568  }
569  }
570  /* fall through */
571  }
572  }
573 #endif /* USE_IC_FOR_IVAR */
574  return rb_ivar_set(obj, id, val);
575 }
576 
577 static VALUE
579 {
580  return vm_getivar(obj, id, ic, 0, 0);
581 }
582 
583 static void
585 {
586  vm_setivar(obj, id, val, ic, 0, 0);
587 }
588 
589 static VALUE
591  rb_num_t throw_state, VALUE throwobj)
592 {
593  int state = (int)(throw_state & 0xff);
594  int flag = (int)(throw_state & 0x8000);
595  rb_num_t level = throw_state >> 16;
596 
597  if (state != 0) {
598  VALUE *pt = 0;
599  if (flag != 0) {
600  pt = (void *) 1;
601  }
602  else {
603  if (state == TAG_BREAK) {
604  rb_control_frame_t *cfp = GET_CFP();
605  VALUE *ep = GET_EP();
606  int is_orphan = 1;
607  rb_iseq_t *base_iseq = GET_ISEQ();
608 
609  search_parent:
610  if (cfp->iseq->type != ISEQ_TYPE_BLOCK) {
611  if (cfp->iseq->type == ISEQ_TYPE_CLASS) {
613  ep = cfp->ep;
614  goto search_parent;
615  }
616  ep = VM_EP_PREV_EP(ep);
617  base_iseq = base_iseq->parent_iseq;
618 
619  while ((VALUE *) cfp < th->stack + th->stack_size) {
620  if (cfp->ep == ep) {
621  goto search_parent;
622  }
624  }
625  rb_bug("VM (throw): can't find break base.");
626  }
627 
628  if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
629  /* lambda{... break ...} */
630  is_orphan = 0;
631  pt = cfp->ep;
632  state = TAG_RETURN;
633  }
634  else {
635  ep = VM_EP_PREV_EP(ep);
636 
637  while ((VALUE *)cfp < th->stack + th->stack_size) {
638  if (cfp->ep == ep) {
639  VALUE epc = cfp->pc - cfp->iseq->iseq_encoded;
640  rb_iseq_t *iseq = cfp->iseq;
641  int i;
642 
643  for (i=0; i<iseq->catch_table_size; i++) {
644  struct iseq_catch_table_entry *entry = &iseq->catch_table[i];
645 
646  if (entry->type == CATCH_TYPE_BREAK &&
647  entry->start < epc && entry->end >= epc) {
648  if (entry->cont == epc) {
649  goto found;
650  }
651  else {
652  break;
653  }
654  }
655  }
656  break;
657 
658  found:
659  pt = ep;
660  is_orphan = 0;
661  break;
662  }
664  }
665  }
666 
667  if (is_orphan) {
668  rb_vm_localjump_error("break from proc-closure", throwobj, TAG_BREAK);
669  }
670  }
671  else if (state == TAG_RETRY) {
672  rb_num_t i;
673  pt = VM_EP_PREV_EP(GET_EP());
674  for (i = 0; i < level; i++) {
675  pt = GC_GUARDED_PTR_REF((VALUE *) * pt);
676  }
677  }
678  else if (state == TAG_RETURN) {
679  rb_control_frame_t *cfp = GET_CFP();
680  VALUE *ep = GET_EP();
681  VALUE *target_lep = VM_CF_LEP(cfp);
682  int in_class_frame = 0;
683 
684  /* check orphan and get dfp */
685  while ((VALUE *) cfp < th->stack + th->stack_size) {
686  VALUE *lep = VM_CF_LEP(cfp);
687 
688  if (!target_lep) {
689  target_lep = lep;
690  }
691 
692  if (lep == target_lep && cfp->iseq->type == ISEQ_TYPE_CLASS) {
693  in_class_frame = 1;
694  target_lep = 0;
695  }
696 
697  if (lep == target_lep) {
698  if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
699  VALUE *tep = ep;
700 
701  if (in_class_frame) {
702  /* lambda {class A; ... return ...; end} */
703  ep = cfp->ep;
704  goto valid_return;
705  }
706 
707  while (target_lep != tep) {
708  if (cfp->ep == tep) {
709  /* in lambda */
710  ep = cfp->ep;
711  goto valid_return;
712  }
713  tep = VM_EP_PREV_EP(tep);
714  }
715  }
716  }
717 
718  if (cfp->ep == target_lep && cfp->iseq->type == ISEQ_TYPE_METHOD) {
719  ep = target_lep;
720  goto valid_return;
721  }
722 
724  }
725 
726  rb_vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
727 
728  valid_return:
729  pt = ep;
730  }
731  else {
732  rb_bug("isns(throw): unsupport throw type");
733  }
734  }
735  th->state = state;
736  return (VALUE)NEW_THROW_OBJECT(throwobj, (VALUE) pt, state);
737  }
738  else {
739  /* continue throw */
740  VALUE err = throwobj;
741 
742  if (FIXNUM_P(err)) {
743  th->state = FIX2INT(err);
744  }
745  else if (SYMBOL_P(err)) {
746  th->state = TAG_THROW;
747  }
748  else if (BUILTIN_TYPE(err) == T_NODE) {
749  th->state = GET_THROWOBJ_STATE(err);
750  }
751  else {
752  th->state = TAG_RAISE;
753  /*th->state = FIX2INT(rb_ivar_get(err, idThrowState));*/
754  }
755  return err;
756  }
757 }
758 
759 static inline void
761 {
762  int is_splat = flag & 0x01;
763  rb_num_t space_size = num + is_splat;
764  VALUE *base = cfp->sp;
765  const VALUE *ptr;
766  rb_num_t len;
767 
768  if (!RB_TYPE_P(ary, T_ARRAY)) {
769  ary = rb_ary_to_ary(ary);
770  }
771 
772  cfp->sp += space_size;
773 
774  ptr = RARRAY_CONST_PTR(ary);
775  len = (rb_num_t)RARRAY_LEN(ary);
776 
777  if (flag & 0x02) {
778  /* post: ..., nil ,ary[-1], ..., ary[0..-num] # top */
779  rb_num_t i = 0, j;
780 
781  if (len < num) {
782  for (i=0; i<num-len; i++) {
783  *base++ = Qnil;
784  }
785  }
786  for (j=0; i<num; i++, j++) {
787  VALUE v = ptr[len - j - 1];
788  *base++ = v;
789  }
790  if (is_splat) {
791  *base = rb_ary_new4(len - j, ptr);
792  }
793  }
794  else {
795  /* normal: ary[num..-1], ary[num-2], ary[num-3], ..., ary[0] # top */
796  rb_num_t i;
797  VALUE *bptr = &base[space_size - 1];
798 
799  for (i=0; i<num; i++) {
800  if (len <= i) {
801  for (; i<num; i++) {
802  *bptr-- = Qnil;
803  }
804  break;
805  }
806  *bptr-- = ptr[i];
807  }
808  if (is_splat) {
809  if (num > len) {
810  *bptr = rb_ary_new();
811  }
812  else {
813  *bptr = rb_ary_new4(len - num, ptr + num);
814  }
815  }
816  }
817  RB_GC_GUARD(ary);
818 }
819 
821 
822 static void
824 {
825  VALUE klass = CLASS_OF(recv);
826 
827 #if OPT_INLINE_METHOD_CACHE
828  if (LIKELY(GET_GLOBAL_METHOD_STATE() == ci->method_state && RCLASS_SERIAL(klass) == ci->class_serial)) {
829  /* cache hit! */
830  return;
831  }
832 #endif
833 
834  ci->me = rb_method_entry(klass, ci->mid, &ci->defined_class);
835  ci->klass = klass;
836  ci->call = vm_call_general;
837 #if OPT_INLINE_METHOD_CACHE
839  ci->class_serial = RCLASS_SERIAL(klass);
840 #endif
841 }
842 
843 static inline int
845 {
846  if (me && me->def->type == VM_METHOD_TYPE_CFUNC &&
847  me->def->body.cfunc.func == func) {
848  return 1;
849  }
850  else {
851  return 0;
852  }
853 }
854 
855 static
856 #ifndef NO_BIG_INLINE
857 inline
858 #endif
859 VALUE
861 {
862  if (FIXNUM_2_P(recv, obj) &&
864  return (recv == obj) ? Qtrue : Qfalse;
865  }
866  else if (FLONUM_2_P(recv, obj) &&
868  return (recv == obj) ? Qtrue : Qfalse;
869  }
870  else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
871  if (RBASIC_CLASS(recv) == rb_cFloat &&
872  RBASIC_CLASS(obj) == rb_cFloat &&
874  double a = RFLOAT_VALUE(recv);
875  double b = RFLOAT_VALUE(obj);
876 
877  if (isnan(a) || isnan(b)) {
878  return Qfalse;
879  }
880  return (a == b) ? Qtrue : Qfalse;
881  }
882  else if (RBASIC_CLASS(recv) == rb_cString &&
883  RBASIC_CLASS(obj) == rb_cString &&
885  return rb_str_equal(recv, obj);
886  }
887  }
888 
889  {
890  vm_search_method(ci, recv);
891 
892  if (check_cfunc(ci->me, rb_obj_equal)) {
893  return recv == obj ? Qtrue : Qfalse;
894  }
895  }
896 
897  return Qundef;
898 }
899 
900 VALUE
902 {
903  rb_call_info_t ci;
904  ci.mid = idEq;
905  ci.klass = 0;
906  ci.method_state = 0;
907  ci.me = NULL;
908  ci.defined_class = 0;
909  return opt_eq_func(obj1, obj2, &ci);
910 }
911 
912 static VALUE
913 vm_call0(rb_thread_t*, VALUE, ID, int, const VALUE*, const rb_method_entry_t*, VALUE);
914 
915 static VALUE
917 {
918  switch (type) {
920  return pattern;
922  if (!rb_obj_is_kind_of(pattern, rb_cModule)) {
923  rb_raise(rb_eTypeError, "class or module required for rescue clause");
924  }
925  /* fall through */
927  VALUE defined_class;
928  rb_method_entry_t *me = rb_method_entry_with_refinements(CLASS_OF(pattern), idEqq, &defined_class);
929  if (me) {
930  return vm_call0(GET_THREAD(), pattern, idEqq, 1, &target, me, defined_class);
931  }
932  else {
933  /* fallback to funcall (e.g. method_missing) */
934  return rb_funcall2(pattern, idEqq, 1, &target);
935  }
936  }
937  default:
938  rb_bug("check_match: unreachable");
939  }
940 }
941 
942 
943 #if defined(_MSC_VER) && _MSC_VER < 1300
944 #define CHECK_CMP_NAN(a, b) if (isnan(a) || isnan(b)) return Qfalse;
945 #else
946 #define CHECK_CMP_NAN(a, b) /* do nothing */
947 #endif
948 
949 static inline VALUE
950 double_cmp_lt(double a, double b)
951 {
952  CHECK_CMP_NAN(a, b);
953  return a < b ? Qtrue : Qfalse;
954 }
955 
956 static inline VALUE
957 double_cmp_le(double a, double b)
958 {
959  CHECK_CMP_NAN(a, b);
960  return a <= b ? Qtrue : Qfalse;
961 }
962 
963 static inline VALUE
964 double_cmp_gt(double a, double b)
965 {
966  CHECK_CMP_NAN(a, b);
967  return a > b ? Qtrue : Qfalse;
968 }
969 
970 static inline VALUE
971 double_cmp_ge(double a, double b)
972 {
973  CHECK_CMP_NAN(a, b);
974  return a >= b ? Qtrue : Qfalse;
975 }
976 
977 static VALUE *
979 {
981  VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
982 
983  if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
984  /* adjust `self' */
985  bp += 1;
986  }
987 
988 #if VM_DEBUG_BP_CHECK
989  if (bp != cfp->bp_check) {
990  fprintf(stderr, "bp_check: %ld, bp: %ld\n",
991  (long)(cfp->bp_check - GET_THREAD()->stack),
992  (long)(bp - GET_THREAD()->stack));
993  rb_bug("vm_base_ptr: unreachable");
994  }
995 #endif
996 
997  return bp;
998 }
999 
1000 /* method call processes with call_info */
1001 
1002 static void
1004 {
1005 #define SAVE_RESTORE_CI(expr, ci) do { \
1006  int saved_argc = (ci)->argc; rb_block_t *saved_blockptr = (ci)->blockptr; /* save */ \
1007  expr; \
1008  (ci)->argc = saved_argc; (ci)->blockptr = saved_blockptr; /* restore */ \
1009 } while (0)
1010 
1011  if (UNLIKELY(ci->flag & VM_CALL_ARGS_BLOCKARG)) {
1012  rb_proc_t *po;
1013  VALUE proc;
1014 
1015  proc = *(--cfp->sp);
1016 
1017  if (proc != Qnil) {
1018  if (!rb_obj_is_proc(proc)) {
1019  VALUE b;
1020 
1021  SAVE_RESTORE_CI(b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"), ci);
1022 
1023  if (NIL_P(b) || !rb_obj_is_proc(b)) {
1025  "wrong argument type %s (expected Proc)",
1026  rb_obj_classname(proc));
1027  }
1028  proc = b;
1029  }
1030  GetProcPtr(proc, po);
1031  ci->blockptr = &po->block;
1032  RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)->proc = proc;
1033  }
1034  }
1035  else if (ci->blockiseq != 0) { /* likely */
1037  ci->blockptr->iseq = ci->blockiseq;
1038  ci->blockptr->proc = 0;
1039  }
1040 
1041  /* expand top of stack? */
1042 
1043  if (UNLIKELY(ci->flag & VM_CALL_ARGS_SPLAT)) {
1044  VALUE ary = *(cfp->sp - 1);
1045  const VALUE *ptr;
1046  int i;
1047  VALUE tmp;
1048 
1049  SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);
1050 
1051  if (NIL_P(tmp)) {
1052  /* do nothing */
1053  }
1054  else {
1055  long len = RARRAY_LEN(tmp);
1056  ptr = RARRAY_CONST_PTR(tmp);
1057  cfp->sp -= 1;
1058 
1059  CHECK_VM_STACK_OVERFLOW(cfp, len);
1060 
1061  for (i = 0; i < len; i++) {
1062  *cfp->sp++ = ptr[i];
1063  }
1064  ci->argc += i-1;
1065  }
1066  }
1067 }
1068 
1069 static inline int
1070 vm_callee_setup_keyword_arg(rb_thread_t *th, const rb_iseq_t *iseq, int argc, int m, VALUE *orig_argv, VALUE *kwd)
1071 {
1072  VALUE keyword_hash = 0, orig_hash;
1073  int optional = iseq->arg_keywords - iseq->arg_keyword_required;
1074  VALUE *const sp = th->cfp->sp;
1075  const int mark_stack_len = th->mark_stack_len;
1076 
1077  th->cfp->sp += argc;
1078  th->mark_stack_len -= argc;
1079 
1080  if (argc > m &&
1081  !NIL_P(orig_hash = rb_check_hash_type(orig_argv[argc-1])) &&
1082  (keyword_hash = rb_extract_keywords(&orig_hash)) != 0) {
1083  if (!orig_hash) {
1084  argc--;
1085  }
1086  else {
1087  orig_argv[argc-1] = orig_hash;
1088  }
1089  }
1090  rb_get_kwargs(keyword_hash, iseq->arg_keyword_table, iseq->arg_keyword_required,
1091  (iseq->arg_keyword_check ? optional : -1-optional),
1092  NULL);
1093 
1094  if (!keyword_hash) {
1095  keyword_hash = rb_hash_new();
1096  }
1097 
1098  th->cfp->sp = sp;
1099  th->mark_stack_len = mark_stack_len;
1100 
1101  *kwd = keyword_hash;
1102 
1103  return argc;
1104 }
1105 
1106 static inline int
1108 {
1109  const int m = iseq->argc;
1110  const int opts = iseq->arg_opts - (iseq->arg_opts > 0);
1111  const int min = m + iseq->arg_post_len;
1112  const int max = (iseq->arg_rest == -1) ? m + opts + iseq->arg_post_len : UNLIMITED_ARGUMENTS;
1113  const int orig_argc = ci->argc;
1114  int argc = orig_argc;
1115  VALUE *argv = orig_argv;
1116  VALUE keyword_hash = Qnil;
1117  rb_num_t opt_pc = 0;
1118 
1119  th->mark_stack_len = argc + iseq->arg_size;
1120 
1121  /* keyword argument */
1122  if (iseq->arg_keyword != -1) {
1123  argc = vm_callee_setup_keyword_arg(th, iseq, argc, min, orig_argv, &keyword_hash);
1124  }
1125 
1126  /* mandatory */
1127  if ((argc < min) || (argc > max && max != UNLIMITED_ARGUMENTS)) {
1128  argument_error(iseq, argc, min, max);
1129  }
1130 
1131  argv += m;
1132  argc -= m;
1133 
1134  /* post arguments */
1135  if (iseq->arg_post_len) {
1136  if (!(orig_argc < iseq->arg_post_start)) {
1137  VALUE *new_argv = ALLOCA_N(VALUE, argc);
1138  MEMCPY(new_argv, argv, VALUE, argc);
1139  argv = new_argv;
1140  }
1141 
1142  MEMCPY(&orig_argv[iseq->arg_post_start], &argv[argc -= iseq->arg_post_len],
1143  VALUE, iseq->arg_post_len);
1144  }
1145 
1146  /* opt arguments */
1147  if (iseq->arg_opts) {
1148  if (argc > opts) {
1149  argc -= opts;
1150  argv += opts;
1151  opt_pc = iseq->arg_opt_table[opts]; /* no opt */
1152  }
1153  else {
1154  int i;
1155  for (i = argc; i<opts; i++) {
1156  orig_argv[i + m] = Qnil;
1157  }
1158  opt_pc = iseq->arg_opt_table[argc];
1159  argc = 0;
1160  }
1161  }
1162 
1163  /* rest arguments */
1164  if (iseq->arg_rest != -1) {
1165  orig_argv[iseq->arg_rest] = rb_ary_new4(argc, argv);
1166  argc = 0;
1167  }
1168 
1169  /* keyword argument */
1170  if (iseq->arg_keyword != -1) {
1171  int i;
1172  int arg_keywords_end = iseq->arg_keyword - (iseq->arg_block != -1);
1173  for (i = iseq->arg_keywords; 0 < i; i--) {
1174  orig_argv[arg_keywords_end - i] = Qnil;
1175  }
1176  orig_argv[iseq->arg_keyword] = keyword_hash;
1177  }
1178 
1179  /* block arguments */
1180  if (iseq->arg_block != -1) {
1181  VALUE blockval = Qnil;
1182  const rb_block_t *blockptr = ci->blockptr;
1183 
1184  if (blockptr) {
1185  /* make Proc object */
1186  if (blockptr->proc == 0) {
1187  rb_proc_t *proc;
1188  blockval = rb_vm_make_proc(th, blockptr, rb_cProc);
1189  GetProcPtr(blockval, proc);
1190  ci->blockptr = &proc->block;
1191  }
1192  else {
1193  blockval = blockptr->proc;
1194  }
1195  }
1196 
1197  orig_argv[iseq->arg_block] = blockval; /* Proc or nil */
1198  }
1199 
1200  th->mark_stack_len = 0;
1201  return (int)opt_pc;
1202 }
1203 
1207 
1208 static inline void
1210  VALUE *argv, int is_lambda)
1211 {
1212  if (LIKELY(iseq->arg_simple & 0x01)) {
1213  /* simple check */
1214  if (ci->argc != iseq->argc) {
1215  argument_error(iseq, ci->argc, iseq->argc, iseq->argc);
1216  }
1217  ci->aux.opt_pc = 0;
1218  CI_SET_FASTPATH(ci,
1219  (UNLIKELY(ci->flag & VM_CALL_TAILCALL) ?
1222  (!is_lambda &&
1223  !(ci->flag & VM_CALL_ARGS_SPLAT) && /* argc may differ for each calls */
1224  !(ci->me->flag & NOEX_PROTECTED)));
1225  }
1226  else {
1227  ci->aux.opt_pc = vm_callee_setup_arg_complex(th, ci, iseq, argv);
1228  }
1229 }
1230 
1231 static VALUE
1233 {
1234  vm_callee_setup_arg(th, ci, ci->me->def->body.iseq, cfp->sp - ci->argc, 0);
1235  return vm_call_iseq_setup_2(th, cfp, ci);
1236 }
1237 
1238 static VALUE
1240 {
1241  if (LIKELY(!(ci->flag & VM_CALL_TAILCALL))) {
1242  return vm_call_iseq_setup_normal(th, cfp, ci);
1243  }
1244  else {
1245  return vm_call_iseq_setup_tailcall(th, cfp, ci);
1246  }
1247 }
1248 
1249 static inline VALUE
1251 {
1252  int i, local_size;
1253  VALUE *argv = cfp->sp - ci->argc;
1254  rb_iseq_t *iseq = ci->me->def->body.iseq;
1255  VALUE *sp = argv + iseq->arg_size;
1256 
1257  /* clear local variables (arg_size...local_size) */
1258  for (i = iseq->arg_size, local_size = iseq->local_size; i < local_size; i++) {
1259  *sp++ = Qnil;
1260  }
1261 
1264  iseq->iseq_encoded + ci->aux.opt_pc, sp, 0, ci->me, iseq->stack_max);
1265 
1266  cfp->sp = argv - 1 /* recv */;
1267  return Qundef;
1268 }
1269 
1270 static inline VALUE
1272 {
1273  int i;
1274  VALUE *argv = cfp->sp - ci->argc;
1275  rb_iseq_t *iseq = ci->me->def->body.iseq;
1276  VALUE *src_argv = argv;
1277  VALUE *sp_orig, *sp;
1278  VALUE finish_flag = VM_FRAME_TYPE_FINISH_P(cfp) ? VM_FRAME_FLAG_FINISH : 0;
1279 
1280  cfp = th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); /* pop cf */
1281 
1282  RUBY_VM_CHECK_INTS(th);
1283 
1284  sp_orig = sp = cfp->sp;
1285 
1286  /* push self */
1287  sp[0] = ci->recv;
1288  sp++;
1289 
1290  /* copy arguments */
1291  for (i=0; i < iseq->arg_size; i++) {
1292  *sp++ = src_argv[i];
1293  }
1294 
1295  /* clear local variables */
1296  for (i = 0; i < iseq->local_size - iseq->arg_size; i++) {
1297  *sp++ = Qnil;
1298  }
1299 
1300  vm_push_frame(th, iseq, VM_FRAME_MAGIC_METHOD | finish_flag,
1302  iseq->iseq_encoded + ci->aux.opt_pc, sp, 0, ci->me, iseq->stack_max);
1303 
1304  cfp->sp = sp_orig;
1305  return Qundef;
1306 }
1307 
1308 static VALUE
1310 {
1311  return (*func)(recv, rb_ary_new4(argc, argv));
1312 }
1313 
1314 static VALUE
1316 {
1317  return (*func)(argc, argv, recv);
1318 }
1319 
1320 static VALUE
1322 {
1323  return (*func)(recv);
1324 }
1325 
1326 static VALUE
1328 {
1329  return (*func)(recv, argv[0]);
1330 }
1331 
1332 static VALUE
1334 {
1335  return (*func)(recv, argv[0], argv[1]);
1336 }
1337 
1338 static VALUE
1340 {
1341  return (*func)(recv, argv[0], argv[1], argv[2]);
1342 }
1343 
1344 static VALUE
1346 {
1347  return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
1348 }
1349 
1350 static VALUE
1352 {
1353  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
1354 }
1355 
1356 static VALUE
1358 {
1359  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
1360 }
1361 
1362 static VALUE
1364 {
1365  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
1366 }
1367 
1368 static VALUE
1370 {
1371  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
1372 }
1373 
1374 static VALUE
1376 {
1377  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
1378 }
1379 
1380 static VALUE
1382 {
1383  return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
1384 }
1385 
1386 static VALUE
1388 {
1389  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]);
1390 }
1391 
1392 static VALUE
1394 {
1395  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]);
1396 }
1397 
1398 static VALUE
1400 {
1401  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]);
1402 }
1403 
1404 static VALUE
1406 {
1407  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]);
1408 }
1409 
1410 static VALUE
1412 {
1413  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]);
1414 }
1415 
1416 #ifndef VM_PROFILE
1417 #define VM_PROFILE 0
1418 #endif
1419 
1420 #if VM_PROFILE
1421 static int vm_profile_counter[4];
1422 #define VM_PROFILE_UP(x) (vm_profile_counter[x]++)
1423 #define VM_PROFILE_ATEXIT() atexit(vm_profile_show_result)
1424 static void
1425 vm_profile_show_result(void)
1426 {
1427  fprintf(stderr, "VM Profile results: \n");
1428  fprintf(stderr, "r->c call: %d\n", vm_profile_counter[0]);
1429  fprintf(stderr, "r->c popf: %d\n", vm_profile_counter[1]);
1430  fprintf(stderr, "c->c call: %d\n", vm_profile_counter[2]);
1431  fprintf(stderr, "r->c popf: %d\n", vm_profile_counter[3]);
1432 }
1433 #else
1434 #define VM_PROFILE_UP(x)
1435 #define VM_PROFILE_ATEXIT()
1436 #endif
1437 
1438 static inline
1439 const rb_method_cfunc_t *
1441 {
1442 #if VM_DEBUG_VERIFY_METHOD_CACHE
1443  switch (me->def->type) {
1444  case VM_METHOD_TYPE_CFUNC:
1446  break;
1447 # define METHOD_BUG(t) case VM_METHOD_TYPE_##t: rb_bug("wrong method type: " #t)
1448  METHOD_BUG(ISEQ);
1449  METHOD_BUG(ATTRSET);
1450  METHOD_BUG(IVAR);
1451  METHOD_BUG(BMETHOD);
1452  METHOD_BUG(ZSUPER);
1453  METHOD_BUG(UNDEF);
1454  METHOD_BUG(OPTIMIZED);
1455  METHOD_BUG(MISSING);
1456  METHOD_BUG(REFINED);
1457 # undef METHOD_BUG
1458  default:
1459  rb_bug("wrong method type: %d", me->def->type);
1460  }
1461 #endif
1462  return &me->def->body.cfunc;
1463 }
1464 
1465 static VALUE
1467 {
1468  VALUE val;
1469  const rb_method_entry_t *me = ci->me;
1470  const rb_method_cfunc_t *cfunc = vm_method_cfunc_entry(me);
1471  int len = cfunc->argc;
1472 
1473  /* don't use `ci' after EXEC_EVENT_HOOK because ci can be override */
1474  VALUE recv = ci->recv;
1475  VALUE defined_class = ci->defined_class;
1476  rb_block_t *blockptr = ci->blockptr;
1477  int argc = ci->argc;
1478 
1480  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass, Qundef);
1481 
1482  vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
1483  VM_ENVVAL_BLOCK_PTR(blockptr), 0, th->cfp->sp, 1, me, 0);
1484 
1485  if (len >= 0) rb_check_arity(argc, len, len);
1486 
1487  reg_cfp->sp -= argc + 1;
1488  VM_PROFILE_UP(0);
1489  val = (*cfunc->invoker)(cfunc->func, recv, argc, reg_cfp->sp + 1);
1490 
1491  if (reg_cfp != th->cfp + 1) {
1492  rb_bug("vm_call_cfunc - cfp consistency error");
1493  }
1494 
1495  vm_pop_frame(th);
1496 
1497  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->klass, val);
1499 
1500  return val;
1501 }
1502 
1503 #if OPT_CALL_CFUNC_WITHOUT_FRAME
1504 static VALUE
1505 vm_call_cfunc_latter(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
1506 {
1507  VALUE val;
1508  int argc = ci->argc;
1509  VALUE *argv = STACK_ADDR_FROM_TOP(argc);
1510  const rb_method_cfunc_t *cfunc = vm_method_cfunc_entry(ci->me);
1511 
1512  th->passed_ci = ci;
1513  reg_cfp->sp -= argc + 1;
1514  ci->aux.inc_sp = argc + 1;
1515  VM_PROFILE_UP(0);
1516  val = (*cfunc->invoker)(cfunc->func, ci, argv);
1517 
1518  /* check */
1519  if (reg_cfp == th->cfp) { /* no frame push */
1520  if (UNLIKELY(th->passed_ci != ci)) {
1521  rb_bug("vm_call_cfunc_latter: passed_ci error (ci: %p, passed_ci: %p)", ci, th->passed_ci);
1522  }
1523  th->passed_ci = 0;
1524  }
1525  else {
1526  if (UNLIKELY(reg_cfp != RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp))) {
1527  rb_bug("vm_call_cfunc_latter: cfp consistency error (%p, %p)", reg_cfp, th->cfp+1);
1528  }
1529  vm_pop_frame(th);
1530  VM_PROFILE_UP(1);
1531  }
1532 
1533  return val;
1534 }
1535 
1536 static VALUE
1538 {
1539  VALUE val;
1540  const rb_method_entry_t *me = ci->me;
1541  int len = vm_method_cfunc_entry(me)->argc;
1542  VALUE recv = ci->recv;
1543 
1544  if (len >= 0) rb_check_arity(ci->argc, len, len);
1545 
1547  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass, Qnil);
1548 
1549  if (!(ci->me->flag & NOEX_PROTECTED) &&
1550  !(ci->flag & VM_CALL_ARGS_SPLAT)) {
1551  CI_SET_FASTPATH(ci, vm_call_cfunc_latter, 1);
1552  }
1553  val = vm_call_cfunc_latter(th, reg_cfp, ci);
1554 
1555  EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->klass, val);
1557 
1558  return val;
1559 }
1560 
1561 void
1562 vm_call_cfunc_push_frame(rb_thread_t *th)
1563 {
1564  rb_call_info_t *ci = th->passed_ci;
1565  const rb_method_entry_t *me = ci->me;
1566  th->passed_ci = 0;
1567 
1569  VM_ENVVAL_BLOCK_PTR(ci->blockptr), 0, th->cfp->sp + ci->aux.inc_sp, 1, me);
1570 
1571  if (ci->call != vm_call_general) {
1573  }
1574 }
1575 #else /* OPT_CALL_CFUNC_WITHOUT_FRAME */
1576 static VALUE
1578 {
1579  return vm_call_cfunc_with_frame(th, reg_cfp, ci);
1580 }
1581 #endif
1582 
1583 static VALUE
1585 {
1586  VALUE val = vm_getivar(ci->recv, ci->me->def->body.attr.id, 0, ci, 1);
1587  cfp->sp -= 1;
1588  return val;
1589 }
1590 
1591 static VALUE
1593 {
1594  VALUE val = vm_setivar(ci->recv, ci->me->def->body.attr.id, *(cfp->sp - 1), 0, ci, 1);
1595  cfp->sp -= 2;
1596  return val;
1597 }
1598 
1599 static inline VALUE
1601 {
1602  rb_proc_t *proc;
1603  VALUE val;
1604 
1605  /* control block frame */
1606  th->passed_bmethod_me = ci->me;
1607  GetProcPtr(ci->me->def->body.proc, proc);
1608  val = vm_invoke_proc(th, proc, ci->recv, ci->defined_class, ci->argc, argv, ci->blockptr);
1609 
1610  return val;
1611 }
1612 
1613 static VALUE
1615 {
1616  VALUE *argv = ALLOCA_N(VALUE, ci->argc);
1617  MEMCPY(argv, cfp->sp - ci->argc, VALUE, ci->argc);
1618  cfp->sp += - ci->argc - 1;
1619 
1620  return vm_call_bmethod_body(th, ci, argv);
1621 }
1622 
1623 static
1624 #ifdef _MSC_VER
1625 __forceinline
1626 #else
1627 inline
1628 #endif
1630 
1631 static VALUE
1633 {
1634  int i = ci->argc - 1;
1635  VALUE sym;
1636  rb_call_info_t ci_entry;
1637 
1638  if (ci->argc == 0) {
1639  rb_raise(rb_eArgError, "no method name given");
1640  }
1641 
1642  ci_entry = *ci; /* copy ci entry */
1643  ci = &ci_entry;
1644 
1645  sym = TOPN(i);
1646 
1647  if (SYMBOL_P(sym)) {
1648  ci->mid = SYM2ID(sym);
1649  }
1650  else if (!(ci->mid = rb_check_id(&sym))) {
1651  if (rb_method_basic_definition_p(CLASS_OF(ci->recv), idMethodMissing)) {
1653  rb_exc_raise(exc);
1654  }
1655  ci->mid = rb_to_id(sym);
1656  }
1657 
1658  /* shift arguments */
1659  if (i > 0) {
1660  MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i);
1661  }
1662  ci->me =
1664  ci->mid, &ci->defined_class);
1665  ci->argc -= 1;
1666  DEC_SP(1);
1667 
1669 
1670  return vm_call_method(th, reg_cfp, ci);
1671 }
1672 
1673 static VALUE
1675 {
1676  rb_proc_t *proc;
1677  int argc = ci->argc;
1678  VALUE *argv = ALLOCA_N(VALUE, argc);
1679  GetProcPtr(ci->recv, proc);
1680  MEMCPY(argv, cfp->sp - argc, VALUE, argc);
1681  cfp->sp -= argc + 1;
1682 
1683  return rb_vm_invoke_proc(th, proc, argc, argv, ci->blockptr);
1684 }
1685 
1686 static VALUE
1688 {
1689  VALUE *argv = STACK_ADDR_FROM_TOP(ci->argc);
1690  rb_call_info_t ci_entry;
1691 
1692  ci_entry.flag = VM_CALL_FCALL | VM_CALL_OPT_SEND;
1693  ci_entry.argc = ci->argc+1;
1694  ci_entry.mid = idMethodMissing;
1695  ci_entry.blockptr = ci->blockptr;
1696  ci_entry.recv = ci->recv;
1697  ci_entry.me = rb_method_entry(CLASS_OF(ci_entry.recv), idMethodMissing, &ci_entry.defined_class);
1698 
1699  /* shift arguments: m(a, b, c) #=> method_missing(:m, a, b, c) */
1700  CHECK_VM_STACK_OVERFLOW(reg_cfp, 1);
1701  if (ci->argc > 0) {
1702  MEMMOVE(argv+1, argv, VALUE, ci->argc);
1703  }
1704  argv[0] = ID2SYM(ci->mid);
1705  INC_SP(1);
1706 
1708  return vm_call_method(th, reg_cfp, &ci_entry);
1709 }
1710 
1711 static inline VALUE
1712 find_refinement(VALUE refinements, VALUE klass)
1713 {
1714  if (NIL_P(refinements)) {
1715  return Qnil;
1716  }
1717  return rb_hash_lookup(refinements, klass);
1718 }
1719 
1722 
1723 static rb_control_frame_t *
1725 {
1726  rb_control_frame_t *top_cfp = cfp;
1727 
1728  if (cfp->iseq && cfp->iseq->type == ISEQ_TYPE_BLOCK) {
1729  rb_iseq_t *local_iseq = cfp->iseq->local_iseq;
1730  do {
1731  cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
1733  /* TODO: orphan block */
1734  return top_cfp;
1735  }
1736  } while (cfp->iseq != local_iseq);
1737  }
1738  return cfp;
1739 }
1740 
1741 static
1742 #ifdef _MSC_VER
1743 __forceinline
1744 #else
1745 inline
1746 #endif
1747 VALUE
1749 {
1750  int enable_fastpath = 1;
1751  rb_call_info_t ci_temp;
1752 
1753  start_method_dispatch:
1754  if (ci->me != 0) {
1755  if ((ci->me->flag == 0)) {
1756  VALUE klass;
1757 
1758  normal_method_dispatch:
1759  switch (ci->me->def->type) {
1760  case VM_METHOD_TYPE_ISEQ:{
1761  CI_SET_FASTPATH(ci, vm_call_iseq_setup, enable_fastpath);
1762  return vm_call_iseq_setup(th, cfp, ci);
1763  }
1765  case VM_METHOD_TYPE_CFUNC:
1766  CI_SET_FASTPATH(ci, vm_call_cfunc, enable_fastpath);
1767  return vm_call_cfunc(th, cfp, ci);
1768  case VM_METHOD_TYPE_ATTRSET:{
1769  rb_check_arity(ci->argc, 1, 1);
1770  ci->aux.index = 0;
1771  CI_SET_FASTPATH(ci, vm_call_attrset, enable_fastpath && !(ci->flag & VM_CALL_ARGS_SPLAT));
1772  return vm_call_attrset(th, cfp, ci);
1773  }
1774  case VM_METHOD_TYPE_IVAR:{
1775  rb_check_arity(ci->argc, 0, 0);
1776  ci->aux.index = 0;
1777  CI_SET_FASTPATH(ci, vm_call_ivar, enable_fastpath && !(ci->flag & VM_CALL_ARGS_SPLAT));
1778  return vm_call_ivar(th, cfp, ci);
1779  }
1780  case VM_METHOD_TYPE_MISSING:{
1781  ci->aux.missing_reason = 0;
1782  CI_SET_FASTPATH(ci, vm_call_method_missing, enable_fastpath);
1783  return vm_call_method_missing(th, cfp, ci);
1784  }
1785  case VM_METHOD_TYPE_BMETHOD:{
1786  CI_SET_FASTPATH(ci, vm_call_bmethod, enable_fastpath);
1787  return vm_call_bmethod(th, cfp, ci);
1788  }
1789  case VM_METHOD_TYPE_ZSUPER:{
1790  klass = ci->me->klass;
1791  klass = RCLASS_ORIGIN(klass);
1792  zsuper_method_dispatch:
1793  klass = RCLASS_SUPER(klass);
1794  if (!klass) {
1795  ci->me = 0;
1796  goto start_method_dispatch;
1797  }
1798  ci_temp = *ci;
1799  ci = &ci_temp;
1800 
1801  ci->me = rb_method_entry(klass, ci->mid, &ci->defined_class);
1802 
1803  if (ci->me != 0) {
1804  goto normal_method_dispatch;
1805  }
1806  else {
1807  goto start_method_dispatch;
1808  }
1809  }
1811  switch (ci->me->def->body.optimize_type) {
1812  case OPTIMIZED_METHOD_TYPE_SEND:
1813  CI_SET_FASTPATH(ci, vm_call_opt_send, enable_fastpath);
1814  return vm_call_opt_send(th, cfp, ci);
1815  case OPTIMIZED_METHOD_TYPE_CALL:
1816  CI_SET_FASTPATH(ci, vm_call_opt_call, enable_fastpath);
1817  return vm_call_opt_call(th, cfp, ci);
1818  default:
1819  rb_bug("vm_call_method: unsupported optimized method type (%d)",
1820  ci->me->def->body.optimize_type);
1821  }
1822  break;
1823  }
1824  case VM_METHOD_TYPE_UNDEF:
1825  break;
1826  case VM_METHOD_TYPE_REFINED:{
1827  NODE *cref = rb_vm_get_cref(cfp->iseq, cfp->ep);
1828  VALUE refinements = cref ? cref->nd_refinements : Qnil;
1829  VALUE refinement, defined_class;
1830  rb_method_entry_t *me;
1831 
1832  refinement = find_refinement(refinements,
1833  ci->defined_class);
1834  if (NIL_P(refinement)) {
1835  goto no_refinement_dispatch;
1836  }
1837  me = rb_method_entry(refinement, ci->mid, &defined_class);
1838  if (me) {
1839  if (ci->call == vm_call_super_method) {
1840  rb_control_frame_t *top_cfp = current_method_entry(th, cfp);
1841  if (top_cfp->me &&
1842  rb_method_definition_eq(me->def, top_cfp->me->def)) {
1843  goto no_refinement_dispatch;
1844  }
1845  }
1846  ci->me = me;
1847  ci->defined_class = defined_class;
1848  if (me->def->type != VM_METHOD_TYPE_REFINED) {
1849  goto start_method_dispatch;
1850  }
1851  }
1852 
1853  no_refinement_dispatch:
1854  if (ci->me->def->body.orig_me) {
1855  ci->me = ci->me->def->body.orig_me;
1856  if (UNDEFINED_METHOD_ENTRY_P(ci->me)) {
1857  ci->me = 0;
1858  }
1859  goto start_method_dispatch;
1860  }
1861  else {
1862  klass = ci->me->klass;
1863  goto zsuper_method_dispatch;
1864  }
1865  }
1866  }
1867  rb_bug("vm_call_method: unsupported method type (%d)", ci->me->def->type);
1868  }
1869  else {
1870  int noex_safe;
1871  if (!(ci->flag & VM_CALL_FCALL) && (ci->me->flag & NOEX_MASK) & NOEX_PRIVATE) {
1872  int stat = NOEX_PRIVATE;
1873 
1874  if (ci->flag & VM_CALL_VCALL) {
1875  stat |= NOEX_VCALL;
1876  }
1877  ci->aux.missing_reason = stat;
1879  return vm_call_method_missing(th, cfp, ci);
1880  }
1881  else if (!(ci->flag & VM_CALL_OPT_SEND) && (ci->me->flag & NOEX_MASK) & NOEX_PROTECTED) {
1882  enable_fastpath = 0;
1883  if (!rb_obj_is_kind_of(cfp->self, ci->defined_class)) {
1885  return vm_call_method_missing(th, cfp, ci);
1886  }
1887  else {
1888  goto normal_method_dispatch;
1889  }
1890  }
1891  else if ((noex_safe = NOEX_SAFE(ci->me->flag)) > th->safe_level && (noex_safe > 2)) {
1892  rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(ci->mid));
1893  }
1894  else {
1895  goto normal_method_dispatch;
1896  }
1897  }
1898  }
1899  else {
1900  /* method missing */
1901  int stat = 0;
1902  if (ci->flag & VM_CALL_VCALL) {
1903  stat |= NOEX_VCALL;
1904  }
1905  if (ci->flag & VM_CALL_SUPER) {
1906  stat |= NOEX_SUPER;
1907  }
1908  if (ci->mid == idMethodMissing) {
1909  rb_control_frame_t *reg_cfp = cfp;
1910  VALUE *argv = STACK_ADDR_FROM_TOP(ci->argc);
1911  rb_raise_method_missing(th, ci->argc, argv, ci->recv, stat);
1912  }
1913  else {
1914  ci->aux.missing_reason = stat;
1916  return vm_call_method_missing(th, cfp, ci);
1917  }
1918  }
1919 
1920  rb_bug("vm_call_method: unreachable");
1921 }
1922 
1923 static VALUE
1925 {
1926  return vm_call_method(th, reg_cfp, ci);
1927 }
1928 
1929 static VALUE
1931 {
1932  return vm_call_method(th, reg_cfp, ci);
1933 }
1934 
1935 /* super */
1936 
1937 static inline VALUE
1939 {
1940  if (BUILTIN_TYPE(klass) == T_ICLASS &&
1941  FL_TEST(RBASIC(klass)->klass, RMODULE_IS_REFINEMENT)) {
1942  klass = RBASIC(klass)->klass;
1943  }
1944  klass = RCLASS_ORIGIN(klass);
1945  return RCLASS_SUPER(klass);
1946 }
1947 
1948 static void
1950 {
1951  rb_raise(rb_eNoMethodError, "super called outside of method");
1952 }
1953 
1954 static int
1956 {
1957  while (iseq && !iseq->klass) {
1958  iseq = iseq->parent_iseq;
1959  }
1960 
1961  if (iseq == 0) {
1962  return -1;
1963  }
1964 
1965  ci->mid = iseq->defined_method_id;
1966 
1967  if (iseq != iseq->local_iseq) {
1968  /* defined by Module#define_method() */
1969  rb_control_frame_t *lcfp = GET_CFP();
1970 
1971  if (!sigval) {
1972  /* zsuper */
1973  return -2;
1974  }
1975 
1976  while (lcfp->iseq != iseq) {
1977  rb_thread_t *th = GET_THREAD();
1978  VALUE *tep = VM_EP_PREV_EP(lcfp->ep);
1979  while (1) {
1980  lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp);
1982  return -1;
1983  }
1984  if (lcfp->ep == tep) {
1985  break;
1986  }
1987  }
1988  }
1989 
1990  /* temporary measure for [Bug #2420] [Bug #3136] */
1991  if (!lcfp->me) {
1992  return -1;
1993  }
1994 
1995  ci->mid = lcfp->me->def->original_id;
1997  }
1998  else {
1999  ci->klass = vm_search_normal_superclass(reg_cfp->klass);
2000  }
2001 
2002  return 0;
2003 }
2004 
2005 static void
2007 {
2008  VALUE current_defined_class;
2009  rb_iseq_t *iseq = GET_ISEQ();
2010  VALUE sigval = TOPN(ci->argc);
2011 
2012  current_defined_class = GET_CFP()->klass;
2013  if (NIL_P(current_defined_class)) {
2014  vm_super_outside();
2015  }
2016 
2017  if (!NIL_P(RCLASS_REFINED_CLASS(current_defined_class))) {
2018  current_defined_class = RCLASS_REFINED_CLASS(current_defined_class);
2019  }
2020 
2021  if (BUILTIN_TYPE(current_defined_class) != T_MODULE &&
2022  BUILTIN_TYPE(current_defined_class) != T_ICLASS && /* bound UnboundMethod */
2023  !FL_TEST(current_defined_class, RMODULE_INCLUDED_INTO_REFINEMENT) &&
2024  !rb_obj_is_kind_of(ci->recv, current_defined_class)) {
2025  VALUE m = RB_TYPE_P(current_defined_class, T_ICLASS) ?
2026  RBASIC(current_defined_class)->klass : current_defined_class;
2027 
2029  "self has wrong type to call super in this context: "
2030  "%"PRIsVALUE" (expected %"PRIsVALUE")",
2031  rb_obj_class(ci->recv), m);
2032  }
2033 
2034  switch (vm_search_superclass(GET_CFP(), iseq, sigval, ci)) {
2035  case -1:
2036  vm_super_outside();
2037  case -2:
2039  "implicit argument passing of super from method defined"
2040  " by define_method() is not supported."
2041  " Specify all arguments explicitly.");
2042  }
2043  if (!ci->klass) {
2044  /* bound instance method of module */
2047  return;
2048  }
2049 
2050  /* TODO: use inline cache */
2051  ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class);
2052  ci->call = vm_call_super_method;
2053 
2054  while (iseq && !iseq->klass) {
2055  iseq = iseq->parent_iseq;
2056  }
2057 
2058  if (ci->me && ci->me->def->type == VM_METHOD_TYPE_ISEQ && ci->me->def->body.iseq == iseq) {
2059  ci->klass = RCLASS_SUPER(ci->defined_class);
2060  ci->me = rb_method_entry(ci->klass, ci->mid, &ci->defined_class);
2061  }
2062 }
2063 
2064 /* yield */
2065 
2066 static inline int
2068 {
2069  rb_proc_t *proc;
2070 
2071  if (procval) {
2072  GetProcPtr(procval, proc);
2073  return proc->is_lambda;
2074  }
2075  else {
2076  return 0;
2077  }
2078 }
2079 
2080 static inline VALUE
2082  VALUE self, int argc, const VALUE *argv,
2083  const rb_block_t *blockargptr)
2084 {
2085  NODE *ifunc = (NODE *) block->iseq;
2086  VALUE val, arg, blockarg;
2087  int lambda = block_proc_is_lambda(block->proc);
2088 
2089  if (lambda) {
2090  arg = rb_ary_new4(argc, argv);
2091  }
2092  else if (argc == 0) {
2093  arg = Qnil;
2094  }
2095  else {
2096  arg = argv[0];
2097  }
2098 
2099  if (blockargptr) {
2100  if (blockargptr->proc) {
2101  blockarg = blockargptr->proc;
2102  }
2103  else {
2104  blockarg = rb_vm_make_proc(th, blockargptr, rb_cProc);
2105  }
2106  }
2107  else {
2108  blockarg = Qnil;
2109  }
2110 
2111  vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
2112  0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
2113  th->cfp->sp, 1, 0, 0);
2114 
2115  val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
2116 
2117  th->cfp++;
2118  return val;
2119 }
2120 
2121 
2122 /*--
2123  * @brief on supplied all of optional, rest and post parameters.
2124  * @pre iseq is block style (not lambda style)
2125  */
2126 static inline int
2128  int argc, VALUE *argv)
2129 {
2130  rb_num_t opt_pc = 0;
2131  int i;
2132  const int m = iseq->argc;
2133  const int r = iseq->arg_rest;
2134  int len = iseq->arg_post_len;
2135  int start = iseq->arg_post_start;
2136  int rsize = argc > m ? argc - m : 0; /* # of arguments which did not consumed yet */
2137  int psize = rsize > len ? len : rsize; /* # of post arguments */
2138  int osize = 0; /* # of opt arguments */
2139  VALUE ary;
2140 
2141  /* reserves arguments for post parameters */
2142  rsize -= psize;
2143 
2144  if (iseq->arg_opts) {
2145  const int opts = iseq->arg_opts - 1;
2146  if (rsize > opts) {
2147  osize = opts;
2148  opt_pc = iseq->arg_opt_table[opts];
2149  }
2150  else {
2151  osize = rsize;
2152  opt_pc = iseq->arg_opt_table[rsize];
2153  }
2154  }
2155  rsize -= osize;
2156 
2157  if (0) {
2158  printf(" argc: %d\n", argc);
2159  printf(" len: %d\n", len);
2160  printf("start: %d\n", start);
2161  printf("rsize: %d\n", rsize);
2162  }
2163 
2164  if (r == -1) {
2165  /* copy post argument */
2166  MEMMOVE(&argv[start], &argv[m+osize], VALUE, psize);
2167  }
2168  else {
2169  ary = rb_ary_new4(rsize, &argv[r]);
2170 
2171  /* copy post argument */
2172  MEMMOVE(&argv[start], &argv[m+rsize+osize], VALUE, psize);
2173  argv[r] = ary;
2174  }
2175 
2176  for (i=psize; i<len; i++) {
2177  argv[start + i] = Qnil;
2178  }
2179 
2180  return (int)opt_pc;
2181 }
2182 
2183 static inline int
2185  int orig_argc, VALUE *argv,
2186  const rb_block_t *blockptr)
2187 {
2188  int i;
2189  int argc = orig_argc;
2190  const int m = iseq->argc;
2191  const int min = m + iseq->arg_post_len;
2192  VALUE ary, arg0;
2193  VALUE keyword_hash = Qnil;
2194  int opt_pc = 0;
2195 
2196  th->mark_stack_len = argc;
2197 
2198  /*
2199  * yield [1, 2]
2200  * => {|a|} => a = [1, 2]
2201  * => {|a, b|} => a, b = [1, 2]
2202  */
2203  arg0 = argv[0];
2204  if (!(iseq->arg_simple & 0x02) && /* exclude {|a|} */
2205  (min > 0 || /* positional arguments exist */
2206  iseq->arg_opts > 2 || /* multiple optional arguments exist */
2207  iseq->arg_keyword != -1 || /* any keyword arguments */
2208  0) &&
2209  argc == 1 && !NIL_P(ary = rb_check_array_type(arg0))) { /* rhs is only an array */
2210  th->mark_stack_len = argc = RARRAY_LENINT(ary);
2211 
2212  CHECK_VM_STACK_OVERFLOW(th->cfp, argc);
2213 
2214  MEMCPY(argv, RARRAY_CONST_PTR(ary), VALUE, argc);
2215  }
2216  else {
2217  /* vm_push_frame current argv is at the top of sp because vm_invoke_block
2218  * set sp at the first element of argv.
2219  * Therefore when rb_check_array_type(arg0) called to_ary and called to_ary
2220  * or method_missing run vm_push_frame, it initializes local variables.
2221  * see also https://bugs.ruby-lang.org/issues/8484
2222  */
2223  argv[0] = arg0;
2224  }
2225 
2226  /* keyword argument */
2227  if (iseq->arg_keyword != -1) {
2228  argc = vm_callee_setup_keyword_arg(th, iseq, argc, min, argv, &keyword_hash);
2229  }
2230 
2231  for (i=argc; i<m; i++) {
2232  argv[i] = Qnil;
2233  }
2234 
2235  if (iseq->arg_rest == -1 && iseq->arg_opts == 0) {
2236  const int arg_size = iseq->arg_size;
2237  if (arg_size < argc) {
2238  /*
2239  * yield 1, 2
2240  * => {|a|} # truncate
2241  */
2242  th->mark_stack_len = argc = arg_size;
2243  }
2244  }
2245  else {
2246  int r = iseq->arg_rest;
2247 
2248  if (iseq->arg_post_len ||
2249  iseq->arg_opts) { /* TODO: implement simple version for (iseq->arg_post_len==0 && iseq->arg_opts > 0) */
2250  opt_pc = vm_yield_setup_block_args_complex(th, iseq, argc, argv);
2251  }
2252  else {
2253  if (argc < r) {
2254  /* yield 1
2255  * => {|a, b, *r|}
2256  */
2257  for (i=argc; i<r; i++) {
2258  argv[i] = Qnil;
2259  }
2260  argv[r] = rb_ary_new();
2261  }
2262  else {
2263  argv[r] = rb_ary_new4(argc-r, &argv[r]);
2264  }
2265  }
2266 
2267  th->mark_stack_len = iseq->arg_size;
2268  }
2269 
2270  /* keyword argument */
2271  if (iseq->arg_keyword != -1) {
2272  int arg_keywords_end = iseq->arg_keyword - (iseq->arg_block != -1);
2273  for (i = iseq->arg_keywords; 0 < i; i--) {
2274  argv[arg_keywords_end - i] = Qnil;
2275  }
2276  argv[iseq->arg_keyword] = keyword_hash;
2277  }
2278 
2279  /* {|&b|} */
2280  if (iseq->arg_block != -1) {
2281  VALUE procval = Qnil;
2282 
2283  if (blockptr) {
2284  if (blockptr->proc == 0) {
2285  procval = rb_vm_make_proc(th, blockptr, rb_cProc);
2286  }
2287  else {
2288  procval = blockptr->proc;
2289  }
2290  }
2291 
2292  argv[iseq->arg_block] = procval;
2293  }
2294 
2295  th->mark_stack_len = 0;
2296  return opt_pc;
2297 }
2298 
2299 static inline int
2301  int argc, VALUE *argv, const rb_block_t *blockptr, int lambda)
2302 {
2303  if (0) { /* for debug */
2304  printf(" argc: %d\n", argc);
2305  printf("iseq argc: %d\n", iseq->argc);
2306  printf("iseq opts: %d\n", iseq->arg_opts);
2307  printf("iseq rest: %d\n", iseq->arg_rest);
2308  printf("iseq post: %d\n", iseq->arg_post_len);
2309  printf("iseq blck: %d\n", iseq->arg_block);
2310  printf("iseq smpl: %d\n", iseq->arg_simple);
2311  printf(" lambda: %s\n", lambda ? "true" : "false");
2312  }
2313 
2314  if (lambda) {
2315  /* call as method */
2316  rb_call_info_t ci_entry;
2317  ci_entry.flag = 0;
2318  ci_entry.argc = argc;
2319  ci_entry.blockptr = (rb_block_t *)blockptr;
2320  vm_callee_setup_arg(th, &ci_entry, iseq, argv, 1);
2321  return ci_entry.aux.opt_pc;
2322  }
2323  else {
2324  return vm_yield_setup_block_args(th, iseq, argc, argv, blockptr);
2325  }
2326 }
2327 
2328 static VALUE
2330 {
2331  const rb_block_t *block = VM_CF_BLOCK_PTR(reg_cfp);
2332  rb_iseq_t *iseq;
2333  VALUE type = GET_ISEQ()->local_iseq->type;
2334 
2335  if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) {
2336  rb_vm_localjump_error("no block given (yield)", Qnil, 0);
2337  }
2338  iseq = block->iseq;
2339 
2340  if (UNLIKELY(ci->flag & VM_CALL_ARGS_SPLAT)) {
2341  vm_caller_setup_args(th, GET_CFP(), ci);
2342  }
2343 
2344  if (BUILTIN_TYPE(iseq) != T_NODE) {
2345  int opt_pc;
2346  const int arg_size = iseq->arg_size;
2347  int is_lambda = block_proc_is_lambda(block->proc);
2348  VALUE * const rsp = GET_SP() - ci->argc;
2349  SET_SP(rsp);
2350 
2351  opt_pc = vm_yield_setup_args(th, iseq, ci->argc, rsp, 0, is_lambda);
2352 
2353  vm_push_frame(th, iseq,
2355  block->self,
2356  block->klass,
2357  VM_ENVVAL_PREV_EP_PTR(block->ep),
2358  iseq->iseq_encoded + opt_pc,
2359  rsp + arg_size,
2360  iseq->local_size - arg_size, 0, iseq->stack_max);
2361 
2362  return Qundef;
2363  }
2364  else {
2365  VALUE val = vm_yield_with_cfunc(th, block, block->self, ci->argc, STACK_ADDR_FROM_TOP(ci->argc), 0);
2366  POPN(ci->argc); /* TODO: should put before C/yield? */
2367  return val;
2368  }
2369 }
2370 
2371 static VALUE
2373 {
2374  rb_block_t *blockptr;
2375  rb_thread_t *th = GET_THREAD();
2377 
2378  if (cfp == 0) {
2379  rb_bug("vm_make_proc_with_iseq: unreachable");
2380  }
2381 
2382  blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
2383  blockptr->iseq = blockiseq;
2384  blockptr->proc = 0;
2385 
2386  return rb_vm_make_proc(th, blockptr, rb_cProc);
2387 }
2388 
2389 static VALUE
2391 {
2392  VALUE proc = vm_make_proc_with_iseq(iseq);
2393  return rb_proc_call_with_block(proc, 0, 0, Qnil);
2394 }
2395 
2396 static VALUE
2398 {
2399  union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)data;
2400  is->once.running_thread = NULL;
2401  return Qnil;
2402 }
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:1583
rb_serial_t class_serial
Definition: vm_core.h:164
#define VM_FRAME_MAGIC_BLOCK
Definition: vm_core.h:760
rb_control_frame_t * cfp
Definition: vm_core.h:531
#define VM_CALL_ARGS_BLOCKARG
Definition: vm_core.h:745
#define DEFAULT_SPECIAL_VAR_COUNT
Definition: iseq.h:132
struct rb_block_struct * blockptr
Definition: vm_core.h:173
#define T_OBJECT
Definition: ruby.h:477
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:110
#define RUBY_VM_CHECK_INTS(th)
Definition: vm_core.h:989
int arg_simple
Definition: vm_core.h:275
VALUE rb_reg_match_last(VALUE)
Definition: re.c:1572
static VALUE opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci)
static VALUE vm_call_iseq_setup_2(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
static VALUE call_cfunc_0(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
NODE *const cref_stack
Definition: vm_core.h:315
static void argument_error(const rb_iseq_t *iseq, int miss_argc, int min_argc, int max_argc)
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1171
VALUE rb_vm_backtrace_object(void)
Definition: vm_backtrace.c:536
RUBY_EXTERN VALUE rb_cFloat
Definition: ruby.h:1566
#define RARRAY_LEN(a)
Definition: ruby.h:878
#define RUBY_EVENT_C_RETURN
Definition: ruby.h:1713
VALUE rb_proc_call_with_block(VALUE, int argc, const VALUE *argv, VALUE)
Definition: proc.c:745
void rb_bug(const char *fmt,...)
Definition: error.c:327
rb_method_type_t type
Definition: method.h:79
VALUE * root_lep
Definition: vm_core.h:557
static VALUE vm_get_iclass(rb_control_frame_t *cfp, VALUE klass)
static VALUE vm_call_opt_call(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:2543
rb_method_attr_t attr
Definition: method.h:84
#define rb_hash_lookup
Definition: tcltklib.c:269
static VALUE vm_call_general(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
#define VM_CALL_FCALL
Definition: vm_core.h:746
#define VM_ENVVAL_PREV_EP_PTR(v)
Definition: vm_core.h:815
#define RCLASS_CONST_TBL(c)
Definition: internal.h:293
Definition: constant.h:19
static VALUE vm_call_bmethod(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
Definition: st.h:69
#define VM_FRAME_FLAG_FINISH
Definition: vm_core.h:776
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)
rb_serial_t method_state
Definition: vm_core.h:163
ID * arg_keyword_table
Definition: vm_core.h:287
#define VM_FRAME_TYPE_FINISH_P(cfp)
Definition: vm_core.h:778
unsigned long end
Definition: iseq.h:66
#define TAG_THROW
Definition: eval_intern.h:194
#define VM_FRAME_MAGIC_CFUNC
Definition: vm_core.h:763
static int max(int a, int b)
Definition: strftime.c:141
static VALUE find_refinement(VALUE refinements, VALUE klass)
#define d1
static rb_control_frame_t * vm_push_frame(rb_thread_t *th, const rb_iseq_t *iseq, VALUE type, VALUE self, VALUE klass, VALUE specval, const VALUE *pc, VALUE *sp, int local_size, const rb_method_entry_t *me, size_t stack_max)
Definition: vm_insnhelper.c:34
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:825
#define GetProcPtr(obj, ptr)
Definition: vm_core.h:697
static VALUE vm_get_const_base(const rb_iseq_t *iseq, const VALUE *ep)
rb_method_flag_t flag
Definition: method.h:98
#define RUBY_VM_NORMAL_ISEQ_P(ptr)
Definition: vm_core.h:835
#define FLOAT_REDEFINED_OP_FLAG
#define CLASS_OF(v)
Definition: ruby.h:440
#define T_MODULE
Definition: ruby.h:480
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Definition: class.c:1918
#define Qtrue
Definition: ruby.h:426
static int vm_callee_setup_keyword_arg(rb_thread_t *th, const rb_iseq_t *iseq, int argc, int m, VALUE *orig_argv, VALUE *kwd)
vm_check_match_type
Definition: vm_core.h:735
rb_iseq_t * iseq
Definition: vm_core.h:466
#define TAG_BREAK
Definition: eval_intern.h:189
static int block_proc_is_lambda(const VALUE procval)
static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:701
static VALUE call_cfunc_10(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
struct rb_method_entry_struct * orig_me
Definition: method.h:92
static void vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag)
#define sysstack_error
Definition: vm_core.h:899
VALUE rb_eTypeError
Definition: error.c:548
#define rb_check_arity
Definition: intern.h:296
#define rb_long2int(n)
Definition: ruby.h:317
#define SYM2ID(x)
Definition: ruby.h:356
static VALUE vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
VALUE rb_obj_equal(VALUE obj1, VALUE obj2)
Definition: object.c:142
VALUE(* call)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_call_info_struct *ci)
Definition: vm_core.h:182
#define UNDEF
static const rb_method_cfunc_t * vm_method_cfunc_entry(const rb_method_entry_t *me)
#define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp)
Definition: vm_core.h:838
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:775
#define VM_ENVVAL_BLOCK_PTR(v)
Definition: vm_core.h:813
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
Definition: vm.c:656
VALUE rb_iv_set(VALUE, const char *, VALUE)
Definition: variable.c:2609
#define ROBJECT_IV_INDEX_TBL(o)
Definition: ruby.h:782
static VALUE vm_call_cfunc_with_frame(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
static VALUE vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
#define VM_FRAME_MAGIC_METHOD
Definition: vm_core.h:759
struct rb_iseq_struct * local_iseq
Definition: vm_core.h:297
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1857
#define VM_FRAME_TYPE(cfp)
Definition: vm_core.h:772
static void lep_svar_set(rb_thread_t *th, VALUE *lep, rb_num_t key, VALUE val)
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1115
ID called_id
Definition: method.h:101
#define VM_FRAME_MAGIC_IFUNC
Definition: vm_core.h:765
#define RB_GC_GUARD(v)
Definition: ruby.h:523
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:652
int rb_const_defined(VALUE, ID)
Definition: variable.c:2124
#define VM_PROFILE_UP(x)
#define VM_CALL_ARGS_SPLAT
Definition: vm_core.h:744
const VALUE klass
Definition: vm_core.h:316
#define SET_SP(x)
union rb_method_definition_struct::@126 body
void rb_vm_localjump_error(const char *mesg, VALUE value, int reason)
Definition: vm.c:1094
size_t stack_max
Definition: vm_core.h:289
#define FIXNUM_2_P(a, b)
int arg_keyword
Definition: vm_core.h:283
VALUE rb_eSecurityError
Definition: error.c:557
#define SDR()
Definition: vm_core.h:853
ID defined_method_id
Definition: vm_core.h:319
#define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)
Definition: vm_core.h:831
#define STACK_ADDR_FROM_TOP(n)
Definition: vm_insnhelper.h:86
#define T_ARRAY
Definition: ruby.h:484
#define GET_GLOBAL_METHOD_STATE()
#define TAG_RAISE
Definition: eval_intern.h:193
static VALUE vm_getinstancevariable(VALUE obj, ID id, IC ic)
VALUE rb_reg_match_post(VALUE)
Definition: re.c:1554
static VALUE vm_once_clear(VALUE data)
#define ROBJECT_NUMIV(o)
Definition: ruby.h:774
static VALUE lep_svar_get(rb_thread_t *th, VALUE *lep, rb_num_t key)
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, int argc, const VALUE *argv, const rb_block_t *blockptr)
Definition: vm.c:897
static VALUE * VM_CF_LEP(rb_control_frame_t *cfp)
Definition: vm.c:40
#define DEC_SP(x)
RUBY_EXTERN VALUE rb_cProc
Definition: ruby.h:1576
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_getspecial(rb_thread_t *th, VALUE *lep, rb_num_t key, rb_num_t type)
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
Definition: ripper.c:17324
#define FIXNUM_P(f)
Definition: ruby.h:347
static VALUE vm_search_const_defined_class(const VALUE cbase, ID id)
int arg_post_len
Definition: vm_core.h:279
#define LIKELY(x)
Definition: vm_core.h:108
union iseq_inline_cache_entry::@164 ic_value
union RNode::@131 u3
static VALUE vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
#define VM_CALL_VCALL
Definition: vm_core.h:747
VALUE rb_reg_last_match(VALUE)
Definition: re.c:1509
static VALUE call_cfunc_11(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const char * rb_obj_classname(VALUE)
Definition: variable.c:406
static VALUE vm_call_iseq_setup_normal(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
#define RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, klass, id)
Definition: probes_helper.h:61
struct iseq_inline_storage_entry::@165 once
#define sym(x)
Definition: date_core.c:3695
static void vm_check_if_namespace(VALUE klass)
static void vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:20
Definition: node.h:239
enum iseq_catch_table_entry::catch_type type
void rb_exc_raise(VALUE mesg)
Definition: eval.c:567
static VALUE vm_call_ivar(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
#define FL_SINGLETON
Definition: ruby.h:1133
#define GET_CFP()
VALUE rb_extract_keywords(VALUE *orighash)
Definition: class.c:1903
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1664
enum rb_iseq_struct::iseq_type type
static VALUE vm_make_proc_with_iseq(rb_iseq_t *blockiseq)
int st_lookup(st_table *, st_data_t, st_data_t *)
static NODE * vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr)
rb_method_cfunc_t cfunc
Definition: method.h:83
int arg_keyword_required
Definition: vm_core.h:286
static VALUE call_cfunc_15(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define FL_TEST(x, f)
Definition: ruby.h:1169
static VALUE make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, const VALUE *argv)
Definition: vm_eval.c:636
#define ROBJECT_IVPTR(o)
Definition: ruby.h:778
#define NEW_IF(c, t, e)
Definition: node.h:371
#define SAVE_RESTORE_CI(expr, ci)
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:247
#define val
void rb_raise_method_missing(rb_thread_t *th, int argc, VALUE *argv, VALUE obj, int call_status)
Definition: vm_eval.c:730
rb_iseq_t * block_iseq
Definition: vm_core.h:453
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
VALUE rb_eRuntimeError
Definition: error.c:547
#define POPN(n)
Definition: vm_insnhelper.h:84
#define RMODULE_IS_REFINEMENT
Definition: ruby.h:802
union RNode::@130 u2
VALUE rb_ary_new(void)
Definition: array.c:495
#define FLONUM_2_P(a, b)
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
Definition: vm_core.h:274
#define RCLASS_ORIGIN(c)
Definition: internal.h:297
#define CHECK_CMP_NAN(a, b)
rb_iseq_t * iseq
Definition: vm_core.h:448
int arg_post_start
Definition: vm_core.h:280
#define NIL_P(v)
Definition: ruby.h:438
#define VMDEBUG
Definition: vm_dump.c:19
#define RMODULE_IS_OVERLAID
Definition: ruby.h:801
#define UNLIKELY(x)
Definition: vm_core.h:109
VALUE rb_eNoMethodError
Definition: error.c:556
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)
Definition: array.c:790
VALUE value
Definition: node.h:245
VALUE * arg_opt_table
Definition: vm_core.h:282
enum rb_method_definition_struct::@126::method_optimized_type optimize_type
int arg_keywords
Definition: vm_core.h:285
static VALUE call_cfunc_2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
union RNode::@129 u1
Definition: vm_core.h:141
static VALUE vm_call_attrset(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
int rb_public_const_defined_from(VALUE klass, ID id)
Definition: variable.c:2136
int argc
Definition: ruby.c:131
#define Qfalse
Definition: ruby.h:425
static int vm_search_superclass(rb_control_frame_t *reg_cfp, rb_iseq_t *iseq, VALUE sigval, rb_call_info_t *ci)
#define ALLOCA_N(type, n)
Definition: ruby.h:1337
#define RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, klass, id)
Definition: probes_helper.h:64
Definition: method.h:97
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1572
rb_iseq_t * blockiseq
Definition: vm_core.h:160
if((ID)(DISPID) nameid!=nameid)
Definition: win32ole.c:770
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1352
static VALUE vm_call_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
#define T_NODE
Definition: ruby.h:498
#define rb_ary_new4
Definition: intern.h:92
static int check_cfunc(const rb_method_entry_t *me, VALUE(*func)())
#define RUBY_EVENT_C_CALL
Definition: ruby.h:1712
int err
Definition: win32.c:114
static VALUE call_cfunc_1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_9(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_3(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
rb_method_entry_t * rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr)
Definition: vm_method.c:617
VALUE(* func)(ANYARGS)
Definition: method.h:66
#define TOPN(n)
Definition: vm_insnhelper.h:83
VALUE klass
Definition: method.h:102
union rb_call_info_struct::@166 aux
unsigned long start
Definition: iseq.h:65
unsigned long rb_num_t
Definition: vm_core.h:124
#define RCLASS_REFINED_CLASS(c)
Definition: internal.h:298
#define TAG_RETURN
Definition: eval_intern.h:188
#define VM_CALL_SUPER
Definition: vm_core.h:749
Definition: vm_core.h:133
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1880
VALUE rb_ary_to_ary(VALUE obj)
Definition: array.c:1522
rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:683
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:886
rb_iseq_t *const iseq
Definition: method.h:82
static rb_block_t * VM_CF_BLOCK_PTR(rb_control_frame_t *cfp)
Definition: vm.c:52
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
#define VM_EP_PREV_EP(ep)
Definition: vm_core.h:818
#define T_DATA
Definition: ruby.h:492
static VALUE vm_call0(rb_thread_t *, VALUE, ID, int, const VALUE *, const rb_method_entry_t *, VALUE)
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:94
static VALUE call_cfunc_13(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
#define CI_SET_FASTPATH(ci, func, enabled)
#define MEMMOVE(p1, p2, type, n)
Definition: ruby.h:1353
VALUE rb_hash_new(void)
Definition: hash.c:298
static VALUE vm_call_opt_send(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1133
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:588
struct rb_iseq_struct * parent_iseq
Definition: vm_core.h:296
#define FIXNUM_REDEFINED_OP_FLAG
#define PRIsVALUE
Definition: ruby.h:137
unsigned long ID
Definition: ruby.h:89
#define Qnil
Definition: ruby.h:427
int type
Definition: tcltklib.c:112
#define BUILTIN_TYPE(x)
Definition: ruby.h:502
VALUE * iseq_encoded
Definition: vm_core.h:226
int rb_autoloading_value(VALUE mod, ID id, VALUE *value)
Definition: variable.c:1715
unsigned long VALUE
Definition: ruby.h:88
static VALUE * vm_base_ptr(rb_control_frame_t *cfp)
#define rb_funcall2
Definition: ruby.h:1456
static void vm_pop_frame(rb_thread_t *th)
Definition: vm_insnhelper.c:99
int catch_table_size
Definition: vm_core.h:293
#define RBASIC(obj)
Definition: ruby.h:1116
Definition: iseq.h:55
#define FIX2INT(x)
Definition: ruby.h:632
#define VM_CALL_OPT_SEND
Definition: vm_core.h:750
static NODE * lep_svar_place(rb_thread_t *th, VALUE *lep)
static VALUE check_match(VALUE pattern, VALUE target, enum vm_check_match_type type)
static VALUE call_cfunc_m2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE vm_search_normal_superclass(VALUE klass)
#define isnan(x)
Definition: win32.h:376
Definition: iseq.h:60
static VALUE call_cfunc_12(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE vm_call_bmethod_body(rb_thread_t *th, rb_call_info_t *ci, const VALUE *argv)
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:67
static VALUE call_cfunc_5(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static rb_control_frame_t * current_method_entry(rb_thread_t *th, rb_control_frame_t *cfp)
static VALUE double_cmp_le(double a, double b)
#define RARRAY_LENINT(ary)
Definition: ruby.h:884
VALUE flags
Definition: node.h:240
static VALUE rb_arg_error_new(int argc, int min, int max)
VALUE rb_equal_opt(VALUE obj1, VALUE obj2)
rb_serial_t ic_serial
Definition: vm_core.h:134
static VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
static VALUE double_cmp_gt(double a, double b)
#define NEW_THROW_OBJECT(val, pt, st)
Definition: eval_intern.h:198
static void vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
static VALUE vm_once_exec(rb_iseq_t *iseq)
static VALUE call_cfunc_7(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE double_cmp_ge(double a, double b)
#define rb_exc_new3
Definition: intern.h:248
int rb_const_defined_at(VALUE, ID)
Definition: variable.c:2130
unsigned long sp
Definition: iseq.h:68
#define RFLOAT_VALUE(v)
Definition: ruby.h:814
#define VM_FRAME_MAGIC_LAMBDA
Definition: vm_core.h:767
int is_lambda
Definition: vm_core.h:707
int mark_stack_len
Definition: vm_core.h:631
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
static void vm_setinstancevariable(VALUE obj, ID id, VALUE val, IC ic)
int arg_keyword_check
Definition: vm_core.h:284
#define RCLASS_SUPER(c)
Definition: classext.h:16
static VALUE vm_get_cbase(const rb_iseq_t *iseq, const VALUE *ep)
VALUE root_svar
Definition: vm_core.h:558
rb_block_t block
Definition: vm_core.h:701
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2631
static VALUE call_cfunc_m1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
size_t index
Definition: vm_core.h:136
rb_method_definition_t * def
Definition: method.h:100
#define RBASIC_CLASS(obj)
Definition: ruby.h:759
static VALUE vm_call_method_missing(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci)
#define ANYARGS
Definition: defines.h:98
const rb_method_entry_t * me
Definition: vm_core.h:455
#define INC_SP(x)
static void vm_search_method(rb_call_info_t *ci, VALUE recv)
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:628
void rb_error_arity(int argc, int min, int max)
static VALUE call_cfunc_14(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define STRING_REDEFINED_OP_FLAG
struct iseq_catch_table_entry * catch_table
Definition: vm_core.h:292
#define NEW_CREF(a)
Definition: node.h:452
uint8_t key[16]
Definition: random.c:1250
static int vm_callee_setup_arg_complex(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *orig_argv)
int local_size
Definition: vm_core.h:239
static VALUE vm_get_cvar_base(NODE *cref, rb_control_frame_t *cfp)
int rb_method_basic_definition_p(VALUE, ID)
Definition: vm_method.c:1573
Definition: id.h:85
struct rb_thread_struct * running_thread
Definition: vm_core.h:143
#define GET_EP()
static VALUE call_cfunc_6(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
NODE * rb_vm_get_cref(const rb_iseq_t *iseq, const VALUE *ep)
static VALUE vm_call_iseq_setup(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
#define NOEX_SAFE(n)
Definition: method.h:41
#define VM_CALL_TAILCALL
Definition: vm_core.h:748
static VALUE call_cfunc_4(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define T_CLASS
Definition: ruby.h:478
const rb_method_entry_t * passed_bmethod_me
Definition: vm_core.h:545
VALUE rb_reg_match_pre(VALUE)
Definition: re.c:1527
rb_call_info_t * passed_ci
Definition: vm_core.h:548
#define EXEC_EVENT_HOOK(th_, flag_, self_, id_, klass_, data_)
Definition: vm_core.h:1034
static NODE * vm_get_cref0(const rb_iseq_t *iseq, const VALUE *ep)
NORETURN(static void argument_error(const rb_iseq_t *iseq, int miss_argc, int min_argc, int max_argc))
#define ID2SYM(x)
Definition: ruby.h:355
unsigned long cont
Definition: iseq.h:67
#define RMODULE_INCLUDED_INTO_REFINEMENT
Definition: ruby.h:803
const char * rb_id2name(ID id)
Definition: ripper.c:17230
#define StringValuePtr(v)
Definition: ruby.h:540
size_t stack_size
Definition: vm_core.h:530
#define GET_SP()
VALUE rb_inspect(VALUE)
Definition: object.c:470
VALUE iseq
Definition: iseq.h:64
void rb_warning(const char *fmt,...)
Definition: error.c:236
static void vm_callee_setup_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *argv, int is_lambda)
#define rb_check_frozen(obj)
Definition: intern.h:277
#define GC_GUARDED_PTR_REF(p)
Definition: vm_core.h:800
static void vm_super_outside(void)
#define GET_ISEQ()
static VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class, int argc, const VALUE *argv, const rb_block_t *blockptr)
Definition: vm.c:869
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)
Definition: ruby.h:1165
VALUE rb_public_const_get_from(VALUE klass, ID id)
Definition: variable.c:1892
#define CHECK_VM_STACK_OVERFLOW(cfp, margin)
Definition: vm_core.h:910
#define BASIC_OP_UNREDEFINED_P(op, klass)
static VALUE vm_setivar(VALUE obj, ID id, VALUE val, IC ic, rb_call_info_t *ci, int is_attr)
Definition: id.h:84
#define rb_intern(str)
#define SYMBOL_P(x)
Definition: ruby.h:354
#define stat(path, st)
Definition: win32.h:213
#define NULL
Definition: _sdbm.c:103
#define Qundef
Definition: ruby.h:428
#define T_ICLASS
Definition: ruby.h:479
int method_missing_reason
Definition: vm_core.h:649
#define RCLASS_SERIAL(c)
Definition: internal.h:299
#define GET_THROWOBJ_STATE(obj)
Definition: eval_intern.h:207
#define VM_EP_LEP_P(ep)
Definition: vm_core.h:820
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:927
void rb_warn(const char *fmt,...)
Definition: error.c:223
#define CHECK_VM_STACK_OVERFLOW0(cfp, sp, margin)
Definition: vm_core.h:908
ID rb_to_id(VALUE)
Definition: string.c:8730
#define bp()
Definition: vm_debug.h:25
VALUE rb_eArgError
Definition: error.c:549
VALUE rb_autoload_load(VALUE, ID)
Definition: variable.c:1769
#define COPY_CREF_OMOD(c1, c2)
static VALUE vm_getivar(VALUE obj, ID id, IC ic, rb_call_info_t *ci, int is_attr)
static VALUE call_cfunc_8(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE double_cmp_lt(double a, double b)
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1213
VALUE rb_reg_nth_match(int, VALUE)
Definition: re.c:1483
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1127
static void vm_stackoverflow(void)
Definition: vm_insnhelper.c:28
const rb_method_entry_t * me
Definition: vm_core.h:168
char ** argv
Definition: ruby.c:132
#define TAG_RETRY
Definition: eval_intern.h:191
VALUE * ep
Definition: vm_core.h:465
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)
VALUE rb_obj_class(VALUE)
Definition: object.c:226
#define NODE_FL_CREF_PUSHED_BY_EVAL
Definition: node.h:276