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