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