Ruby 2.0.0p353(2013-11-22revision43784)

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