Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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