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