Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
vm_method.c
Go to the documentation of this file.
1 /*
2  * This file is included by vm.c
3  */
4 
5 #include "id_table.h"
6 
7 #define METHOD_DEBUG 0
8 
9 #if OPT_GLOBAL_METHOD_CACHE
10 #ifndef GLOBAL_METHOD_CACHE_SIZE
11 #define GLOBAL_METHOD_CACHE_SIZE 0x800
12 #endif
13 #define LSB_ONLY(x) ((x) & ~((x) - 1))
14 #define POWER_OF_2_P(x) ((x) == LSB_ONLY(x))
15 #if !POWER_OF_2_P(GLOBAL_METHOD_CACHE_SIZE)
16 # error GLOBAL_METHOD_CACHE_SIZE must be power of 2
17 #endif
18 #ifndef GLOBAL_METHOD_CACHE_MASK
19 #define GLOBAL_METHOD_CACHE_MASK (GLOBAL_METHOD_CACHE_SIZE-1)
20 #endif
21 
22 #define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&(global_method_cache.mask))
23 #define GLOBAL_METHOD_CACHE(c,m) (global_method_cache.entries + GLOBAL_METHOD_CACHE_KEY(c,m))
24 #else
25 #define GLOBAL_METHOD_CACHE(c,m) (rb_bug("global method cache disabled improperly"), NULL)
26 #endif
27 
28 static int vm_redefinition_check_flag(VALUE klass);
29 static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass);
30 
31 #define object_id idObject_id
32 #define added idMethod_added
33 #define singleton_added idSingleton_method_added
34 #define removed idMethod_removed
35 #define singleton_removed idSingleton_method_removed
36 #define undefined idMethod_undefined
37 #define singleton_undefined idSingleton_method_undefined
38 #define attached id__attached__
39 
40 struct cache_entry {
46 };
47 
48 #if OPT_GLOBAL_METHOD_CACHE
49 static struct {
50  unsigned int size;
51  unsigned int mask;
52  struct cache_entry *entries;
53 } global_method_cache = {
54  GLOBAL_METHOD_CACHE_SIZE,
55  GLOBAL_METHOD_CACHE_MASK,
56 };
57 #endif
58 
59 #define ruby_running (GET_VM()->running)
60 /* int ruby_running = 0; */
61 
62 static void
63 rb_class_clear_method_cache(VALUE klass, VALUE arg)
64 {
65  VALUE old_serial = *(rb_serial_t *)arg;
66  if (RCLASS_SERIAL(klass) > old_serial) {
67  return;
68  }
69 
72 
73  if (BUILTIN_TYPE(klass) == T_ICLASS) {
74  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(klass);
75  if (table) {
76  rb_id_table_clear(table);
77  }
78  }
79  else {
81  }
82 
83  rb_class_foreach_subclass(klass, rb_class_clear_method_cache, arg);
84 }
85 
86 void
88 {
90 }
91 
92 void
94 {
95  if (klass && klass != Qundef) {
96  int global = klass == rb_cBasicObject || klass == rb_cObject || klass == rb_mKernel;
97 
98  RUBY_DTRACE_HOOK(METHOD_CACHE_CLEAR, (global ? "global" : rb_class2name(klass)));
99 
100  if (global) {
102  }
103  else {
104  rb_serial_t old_serial = PREV_CLASS_SERIAL();
105  rb_class_clear_method_cache(klass, (VALUE)&old_serial);
106  }
107  }
108 
109  if (klass == rb_mKernel) {
110  rb_subclass_entry_t *entry = RCLASS_EXT(klass)->subclasses;
111 
112  for (; entry != NULL; entry = entry->next) {
113  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(entry->klass);
114  if (table)rb_id_table_clear(table);
115  }
116  }
117 }
118 
119 VALUE
121 {
122  rb_notimplement();
123 
125 }
126 
127 static void
128 rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_visibility_t visi)
129 {
130  rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, visi);
131 }
132 
133 void
135 {
136  if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
137  if (func != rb_f_notimplement) {
138  rb_method_cfunc_t opt;
139  opt.func = func;
140  opt.argc = argc;
141  rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, visi);
142  }
143  else {
144  rb_define_notimplement_method_id(klass, mid, visi);
145  }
146 }
147 
148 static void
149 rb_method_definition_release(rb_method_definition_t *def, int complemented)
150 {
151  if (def != NULL) {
152  const int alias_count = def->alias_count;
153  const int complemented_count = def->complemented_count;
154  VM_ASSERT(alias_count >= 0);
155  VM_ASSERT(complemented_count >= 0);
156 
157  if (alias_count + complemented_count == 0) {
158  if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d,%d (remove)\n", (void *)def,
159  rb_id2name(def->original_id), alias_count, complemented_count);
160  VM_ASSERT(def->type == VM_METHOD_TYPE_BMETHOD ? def->body.bmethod.hooks == NULL : TRUE);
161  xfree(def);
162  }
163  else {
164  if (complemented) def->complemented_count--;
165  else if (def->alias_count > 0) def->alias_count--;
166 
167  if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d,%d->%d (dec)\n", (void *)def, rb_id2name(def->original_id),
168  alias_count, def->alias_count, complemented_count, def->complemented_count);
169  }
170  }
171 }
172 
173 void
175 {
176  rb_method_definition_release(me->def, METHOD_ENTRY_COMPLEMENTED(me));
177 }
178 
179 static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr);
181 
182 static inline rb_method_entry_t *
183 lookup_method_table(VALUE klass, ID id)
184 {
185  st_data_t body;
186  struct rb_id_table *m_tbl = RCLASS_M_TBL(klass);
187 
188  if (rb_id_table_lookup(m_tbl, id, &body)) {
189  return (rb_method_entry_t *) body;
190  }
191  else {
192  return 0;
193  }
194 }
195 
196 static VALUE
197 (*call_cfunc_invoker_func(int argc))(VALUE recv, int argc, const VALUE *, VALUE (*func)(ANYARGS))
198 {
199  switch (argc) {
200  case -2: return &call_cfunc_m2;
201  case -1: return &call_cfunc_m1;
202  case 0: return &call_cfunc_0;
203  case 1: return &call_cfunc_1;
204  case 2: return &call_cfunc_2;
205  case 3: return &call_cfunc_3;
206  case 4: return &call_cfunc_4;
207  case 5: return &call_cfunc_5;
208  case 6: return &call_cfunc_6;
209  case 7: return &call_cfunc_7;
210  case 8: return &call_cfunc_8;
211  case 9: return &call_cfunc_9;
212  case 10: return &call_cfunc_10;
213  case 11: return &call_cfunc_11;
214  case 12: return &call_cfunc_12;
215  case 13: return &call_cfunc_13;
216  case 14: return &call_cfunc_14;
217  case 15: return &call_cfunc_15;
218  default:
219  rb_bug("call_cfunc_func: unsupported length: %d", argc);
220  }
221 }
222 
223 static void
224 setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(), int argc)
225 {
226  cfunc->func = func;
227  cfunc->argc = argc;
228  cfunc->invoker = call_cfunc_invoker_func(argc);
229 }
230 
233 {
234  *(rb_method_definition_t **)&me->def = def;
235 
236  if (opts != NULL) {
237  switch (def->type) {
238  case VM_METHOD_TYPE_ISEQ:
239  {
240  rb_method_iseq_t *iseq_body = (rb_method_iseq_t *)opts;
241  rb_cref_t *method_cref, *cref = iseq_body->cref;
242 
243  /* setup iseq first (before invoking GC) */
244  RB_OBJ_WRITE(me, &def->body.iseq.iseqptr, iseq_body->iseqptr);
245 
246  if (0) vm_cref_dump("rb_method_definition_create", cref);
247 
248  if (cref) {
249  method_cref = cref;
250  }
251  else {
252  method_cref = vm_cref_new_toplevel(GET_EC()); /* TODO: can we reuse? */
253  }
254 
255  RB_OBJ_WRITE(me, &def->body.iseq.cref, method_cref);
256  return;
257  }
259  {
260  rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
261  setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), cfunc->func, cfunc->argc);
262  return;
263  }
265  case VM_METHOD_TYPE_IVAR:
266  {
267  const rb_execution_context_t *ec = GET_EC();
269  int line;
270 
271  def->body.attr.id = (ID)(VALUE)opts;
272 
274 
275  if (cfp && (line = rb_vm_get_sourceline(cfp))) {
276  VALUE location = rb_ary_new3(2, rb_iseq_path(cfp->iseq), INT2FIX(line));
277  RB_OBJ_WRITE(me, &def->body.attr.location, rb_ary_freeze(location));
278  }
279  else {
280  VM_ASSERT(def->body.attr.location == 0);
281  }
282  return;
283  }
285  RB_OBJ_WRITE(me, &def->body.bmethod.proc, (VALUE)opts);
286  return;
288  setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
289  return;
291  def->body.optimize_type = (enum method_optimized_type)opts;
292  return;
294  {
295  const rb_method_refined_t *refined = (rb_method_refined_t *)opts;
296  RB_OBJ_WRITE(me, &def->body.refined.orig_me, refined->orig_me);
297  RB_OBJ_WRITE(me, &def->body.refined.owner, refined->owner);
298  return;
299  }
302  return;
306  return;
307  }
308  }
309 }
310 
311 static void
312 method_definition_reset(const rb_method_entry_t *me)
313 {
314  rb_method_definition_t *def = me->def;
315 
316  switch(def->type) {
317  case VM_METHOD_TYPE_ISEQ:
320  break;
322  case VM_METHOD_TYPE_IVAR:
324  break;
327  /* give up to check all in a list */
329  break;
333  break;
336  break;
343  break;
344  }
345 }
346 
349 {
352  def->type = type;
353  def->original_id = mid;
354  static uintptr_t method_serial = 1;
355  def->method_serial = method_serial++;
356  return def;
357 }
358 
359 static rb_method_definition_t *
360 method_definition_addref(rb_method_definition_t *def)
361 {
362  def->alias_count++;
363  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->alias_count);
364  return def;
365 }
366 
367 static rb_method_definition_t *
368 method_definition_addref_complement(rb_method_definition_t *def)
369 {
370  def->complemented_count++;
371  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->complemented_count);
372  return def;
373 }
374 
375 static rb_method_entry_t *
376 rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def)
377 {
378  rb_method_entry_t *me = (rb_method_entry_t *)rb_imemo_new(imemo_ment, (VALUE)def, (VALUE)called_id, owner, defined_class);
379  return me;
380 }
381 
382 static VALUE
383 filter_defined_class(VALUE klass)
384 {
385  switch (BUILTIN_TYPE(klass)) {
386  case T_CLASS:
387  return klass;
388  case T_MODULE:
389  return 0;
390  case T_ICLASS:
391  break;
392  }
393  rb_bug("filter_defined_class: %s", rb_obj_info(klass));
394 }
395 
398 {
399  rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def);
400  METHOD_ENTRY_FLAGS_SET(me, visi, ruby_running ? FALSE : TRUE);
401  if (def != NULL) method_definition_reset(me);
402  return me;
403 }
404 
405 const rb_method_entry_t *
407 {
408  rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class,
409  method_definition_addref(src_me->def));
410  METHOD_ENTRY_FLAGS_COPY(me, src_me);
411  return me;
412 }
413 
415 rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
416 {
417  rb_method_definition_t *def = src_me->def;
419  struct {
420  const struct rb_method_entry_struct *orig_me;
421  VALUE owner;
422  } refined = {0};
423 
424  if (!src_me->defined_class &&
426  def->body.refined.orig_me) {
427  const rb_method_entry_t *orig_me =
429  RB_OBJ_WRITE((VALUE)orig_me, &orig_me->defined_class, defined_class);
430  refined.orig_me = orig_me;
431  refined.owner = orig_me->owner;
432  def = NULL;
433  }
434  else {
435  def = method_definition_addref_complement(def);
436  }
437  me = rb_method_entry_alloc(called_id, src_me->owner, defined_class, def);
438  METHOD_ENTRY_FLAGS_COPY(me, src_me);
440  if (!def) {
442  rb_method_definition_set(me, def, &refined);
443  }
444 
446 
447  return (rb_callable_method_entry_t *)me;
448 }
449 
450 void
452 {
453  *(rb_method_definition_t **)&dst->def = method_definition_addref(src->def);
454  method_definition_reset(dst);
455  dst->called_id = src->called_id;
456  RB_OBJ_WRITE((VALUE)dst, &dst->owner, src->owner);
457  RB_OBJ_WRITE((VALUE)dst, &dst->defined_class, src->defined_class);
458  METHOD_ENTRY_FLAGS_COPY(dst, src);
459 }
460 
461 static void
462 make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
463 {
464  if (me->def->type == VM_METHOD_TYPE_REFINED) {
465  return;
466  }
467  else {
468  struct {
469  struct rb_method_entry_struct *orig_me;
470  VALUE owner;
471  } refined;
473 
474  rb_vm_check_redefinition_opt_method(me, me->owner);
475 
476  refined.orig_me =
477  rb_method_entry_alloc(me->called_id, me->owner,
478  me->defined_class ?
480  method_definition_addref(me->def));
481  METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me);
482  refined.owner = owner;
483 
485  rb_method_definition_set(me, def, (void *)&refined);
486  METHOD_ENTRY_VISI_SET(me, METHOD_VISI_PUBLIC);
487  }
488 }
489 
490 void
492 {
493  rb_method_entry_t *me = lookup_method_table(refined_class, mid);
494 
495  if (me) {
496  make_method_entry_refined(refined_class, me);
497  rb_clear_method_cache_by_class(refined_class);
498  }
499  else {
501  }
502 }
503 
504 static void
505 check_override_opt_method_i(VALUE klass, VALUE arg)
506 {
507  ID mid = (ID)arg;
508  const rb_method_entry_t *me, *newme;
509 
510  if (vm_redefinition_check_flag(klass)) {
511  me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
512  if (me) {
513  newme = rb_method_entry(klass, mid);
514  if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
515  }
516  }
517  rb_class_foreach_subclass(klass, check_override_opt_method_i, (VALUE)mid);
518 }
519 
520 static void
521 check_override_opt_method(VALUE klass, VALUE mid)
522 {
523  if (rb_vm_check_optimizable_mid(mid)) {
524  check_override_opt_method_i(klass, mid);
525  }
526 }
527 
528 /*
529  * klass->method_table[mid] = method_entry(defined_class, visi, def)
530  *
531  * If def is given (!= NULL), then just use it and ignore original_id and otps.
532  * If not given, then make a new def with original_id and opts.
533  */
534 static rb_method_entry_t *
535 rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibility_t visi,
536  rb_method_type_t type, rb_method_definition_t *def, ID original_id, void *opts)
537 {
539  struct rb_id_table *mtbl;
540  st_data_t data;
541  int make_refined = 0;
542 
543  if (NIL_P(klass)) {
544  klass = rb_cObject;
545  }
546  if (!FL_TEST(klass, FL_SINGLETON) &&
549  switch (mid) {
550  case idInitialize:
551  case idInitialize_copy:
552  case idInitialize_clone:
553  case idInitialize_dup:
555  visi = METHOD_VISI_PRIVATE;
556  }
557  }
558 
560 
562  VALUE refined_class = rb_refinement_module_get_refined_class(klass);
563  rb_add_refined_method_entry(refined_class, mid);
564  }
565  if (type == VM_METHOD_TYPE_REFINED) {
566  rb_method_entry_t *old_me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
567  if (old_me) rb_vm_check_redefinition_opt_method(old_me, klass);
568  }
569  else {
571  }
572  mtbl = RCLASS_M_TBL(klass);
573 
574  /* check re-definition */
575  if (rb_id_table_lookup(mtbl, mid, &data)) {
576  rb_method_entry_t *old_me = (rb_method_entry_t *)data;
577  rb_method_definition_t *old_def = old_me->def;
578 
579  if (rb_method_definition_eq(old_def, def)) return old_me;
580  rb_vm_check_redefinition_opt_method(old_me, klass);
581 
582  if (old_def->type == VM_METHOD_TYPE_REFINED) make_refined = 1;
583 
584  if (RTEST(ruby_verbose) &&
586  (old_def->alias_count == 0) &&
587  !make_refined &&
588  old_def->type != VM_METHOD_TYPE_UNDEF &&
589  old_def->type != VM_METHOD_TYPE_ZSUPER &&
590  old_def->type != VM_METHOD_TYPE_ALIAS) {
591  const rb_iseq_t *iseq = 0;
592 
593  rb_warning("method redefined; discarding old %"PRIsVALUE, rb_id2str(mid));
594  switch (old_def->type) {
595  case VM_METHOD_TYPE_ISEQ:
596  iseq = def_iseq_ptr(old_def);
597  break;
599  iseq = rb_proc_get_iseq(old_def->body.bmethod.proc, 0);
600  break;
601  default:
602  break;
603  }
604  if (iseq) {
607  "previous definition of %"PRIsVALUE" was here",
608  rb_id2str(old_def->original_id));
609  }
610  }
611  }
612 
613  /* create method entry */
614  me = rb_method_entry_create(mid, defined_class, visi, NULL);
615  if (def == NULL) def = rb_method_definition_create(type, original_id);
616  rb_method_definition_set(me, def, opts);
617 
619 
620  /* check mid */
621  if (klass == rb_cObject) {
622  switch (mid) {
623  case idInitialize:
625  case idMethodMissing:
626  case idRespond_to:
627  rb_warn("redefining Object#%s may cause infinite loop", rb_id2name(mid));
628  }
629  }
630  /* check mid */
631  if (mid == object_id || mid == id__send__) {
632  if (type == VM_METHOD_TYPE_ISEQ && search_method(klass, mid, 0)) {
633  rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
634  }
635  }
636 
637  if (make_refined) {
638  make_method_entry_refined(klass, me);
639  }
640 
641  rb_id_table_insert(mtbl, mid, (VALUE)me);
643 
644  VM_ASSERT(me->def != NULL);
645 
646  /* check optimized method override by a prepended module */
647  if (RB_TYPE_P(klass, T_MODULE)) {
648  check_override_opt_method(klass, (VALUE)mid);
649  }
650 
651  return me;
652 }
653 
654 #define CALL_METHOD_HOOK(klass, hook, mid) do { \
655  const VALUE arg = ID2SYM(mid); \
656  VALUE recv_class = (klass); \
657  ID hook_id = (hook); \
658  if (FL_TEST((klass), FL_SINGLETON)) { \
659  recv_class = rb_ivar_get((klass), attached); \
660  hook_id = singleton_##hook; \
661  } \
662  rb_funcallv(recv_class, hook_id, 1, &arg); \
663  } while (0)
664 
665 static void
666 method_added(VALUE klass, ID mid)
667 {
668  if (ruby_running) {
670  }
671 }
672 
673 void
675 {
676  rb_method_entry_make(klass, mid, klass, visi, type, NULL, mid, opts);
677 
679  method_added(klass, mid);
680  }
681 }
682 
685 {
686  struct { /* should be same fields with rb_method_iseq_struct */
687  const rb_iseq_t *iseqptr;
688  rb_cref_t *cref;
689  } iseq_body;
690 
691  iseq_body.iseqptr = iseq;
692  iseq_body.cref = cref;
693  rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
694 }
695 
696 static rb_method_entry_t *
697 method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me,
698  rb_method_visibility_t visi, VALUE defined_class)
699 {
700  rb_method_entry_t *newme = rb_method_entry_make(klass, mid, defined_class, visi,
701  me->def->type, method_definition_addref(me->def), 0, NULL);
702  method_added(klass, mid);
703  return newme;
704 }
705 
708 {
709  return method_entry_set(klass, mid, me, visi, klass);
710 }
711 
712 #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1)
713 
714 void
716 {
718  RCLASS_EXT(klass)->allocator = func;
719 }
720 
721 void
723 {
725 }
726 
729 {
731 
732  for (; klass; klass = RCLASS_SUPER(klass)) {
733  rb_alloc_func_t allocator = RCLASS_EXT(klass)->allocator;
734  if (allocator == UNDEF_ALLOC_FUNC) break;
735  if (allocator) return allocator;
736  }
737  return 0;
738 }
739 
740 static inline rb_method_entry_t*
741 search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
742 {
744 
745  for (; klass; klass = RCLASS_SUPER(klass)) {
746  RB_DEBUG_COUNTER_INC(mc_search_super);
747  if ((me = lookup_method_table(klass, id)) != 0) break;
748  }
749 
750  if (defined_class_ptr)
751  *defined_class_ptr = klass;
752  return me;
753 }
754 
755 const rb_method_entry_t *
757 {
758  return lookup_method_table(klass, id);
759 }
760 
761 /*
762  * search method entry without the method cache.
763  *
764  * if you need method entry with method cache (normal case), use
765  * rb_method_entry() simply.
766  */
767 static rb_method_entry_t *
768 method_entry_get_without_cache(VALUE klass, ID id,
769  VALUE *defined_class_ptr)
770 {
771  VALUE defined_class;
772  rb_method_entry_t *me = search_method(klass, id, &defined_class);
773 
774  if (ruby_running) {
776  struct cache_entry *ent;
777  ent = GLOBAL_METHOD_CACHE(klass, id);
781  ent->mid = id;
782 
784  me = ent->me = NULL;
785  }
786  else {
787  ent->me = me;
788  }
789  }
790  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
791  me = NULL;
792  }
793  }
794  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
795  me = NULL;
796  }
797 
798  if (defined_class_ptr)
799  *defined_class_ptr = defined_class;
800  return me;
801 }
802 
803 static void
804 verify_method_cache(VALUE klass, ID id, VALUE defined_class, rb_method_entry_t *me)
805 {
806  if (!VM_DEBUG_VERIFY_METHOD_CACHE) return;
807  VALUE actual_defined_class;
808  rb_method_entry_t *actual_me =
809  method_entry_get_without_cache(klass, id, &actual_defined_class);
810 
811  if (me != actual_me || defined_class != actual_defined_class) {
812  rb_bug("method cache verification failed");
813  }
814 }
815 
816 static rb_method_entry_t *
817 method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
818 {
819  struct cache_entry *ent;
820  if (!OPT_GLOBAL_METHOD_CACHE) goto nocache;
821  ent = GLOBAL_METHOD_CACHE(klass, id);
822  if (ent->method_state == GET_GLOBAL_METHOD_STATE() &&
823  ent->class_serial == RCLASS_SERIAL(klass) &&
824  ent->mid == id) {
825  verify_method_cache(klass, id, ent->defined_class, ent->me);
826  if (defined_class_ptr) *defined_class_ptr = ent->defined_class;
827  RB_DEBUG_COUNTER_INC(mc_global_hit);
828  return ent->me;
829  }
830 
831  nocache:
832  RB_DEBUG_COUNTER_INC(mc_global_miss);
833  return method_entry_get_without_cache(klass, id, defined_class_ptr);
834 }
835 
838 {
839  return method_entry_get(klass, id, NULL);
840 }
841 
842 static const rb_callable_method_entry_t *
843 prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_t *me)
844 {
845  struct rb_id_table *mtbl;
846  const rb_callable_method_entry_t *cme;
847 
848  if (me && me->defined_class == 0) {
849  RB_DEBUG_COUNTER_INC(mc_cme_complement);
850  VM_ASSERT(RB_TYPE_P(defined_class, T_ICLASS) || RB_TYPE_P(defined_class, T_MODULE));
851  VM_ASSERT(me->defined_class == 0);
852 
853  mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
854 
855  if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&me)) {
856  RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
858  VM_ASSERT(callable_method_entry_p(cme));
859  }
860  else {
861  if (!mtbl) {
862  mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
863  }
865  rb_id_table_insert(mtbl, id, (VALUE)cme);
866  VM_ASSERT(callable_method_entry_p(cme));
867  }
868  }
869  else {
870  cme = (const rb_callable_method_entry_t *)me;
871  VM_ASSERT(callable_method_entry_p(cme));
872  }
873 
874  return cme;
875 }
876 
879 {
880  VALUE defined_class;
881  rb_method_entry_t *me = method_entry_get(klass, id, &defined_class);
882  return prepare_callable_method_entry(defined_class, id, me);
883 }
884 
885 static const rb_method_entry_t *resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr);
886 
887 static const rb_method_entry_t *
888 method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *defined_class_ptr)
889 {
890  const rb_method_entry_t *me = method_entry_get(klass, id, defined_class_ptr);
891 
892  if (me) {
893  if (me->def->type == VM_METHOD_TYPE_REFINED) {
894  if (with_refinement) {
895  const rb_cref_t *cref = rb_vm_cref();
896  VALUE refinements = cref ? CREF_REFINEMENTS(cref) : Qnil;
897  me = resolve_refined_method(refinements, me, defined_class_ptr);
898  }
899  else {
900  me = resolve_refined_method(Qnil, me, defined_class_ptr);
901  }
902 
904  }
905  }
906 
907  return me;
908 }
909 
910 const rb_method_entry_t *
912 {
913  return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr);
914 }
915 
918 {
919  VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
920  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, TRUE, dcp);
921  return prepare_callable_method_entry(*dcp, id, me);
922 }
923 
924 const rb_method_entry_t *
926 {
927  return method_entry_resolve_refinement(klass, id, FALSE, defined_class_ptr);
928 }
929 
932 {
933  VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
934  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, FALSE, dcp);
935  return prepare_callable_method_entry(*dcp, id, me);
936 }
937 
938 static const rb_method_entry_t *
939 resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
940 {
941  while (me && me->def->type == VM_METHOD_TYPE_REFINED) {
942  VALUE refinement;
943  const rb_method_entry_t *tmp_me;
944  VALUE super;
945 
946  refinement = find_refinement(refinements, me->owner);
947  if (!NIL_P(refinement)) {
948  tmp_me = method_entry_get(refinement, me->called_id, defined_class_ptr);
949 
950  if (tmp_me && tmp_me->def->type != VM_METHOD_TYPE_REFINED) {
951  return tmp_me;
952  }
953  }
954 
955  tmp_me = me->def->body.refined.orig_me;
956  if (tmp_me) {
957  if (defined_class_ptr) *defined_class_ptr = tmp_me->defined_class;
958  return tmp_me;
959  }
960 
961  super = RCLASS_SUPER(me->owner);
962  if (!super) {
963  return 0;
964  }
965 
966  me = method_entry_get(super, me->called_id, defined_class_ptr);
967  }
968  return me;
969 }
970 
971 const rb_method_entry_t *
973 {
974  return resolve_refined_method(refinements, me, NULL);
975 }
976 
980 {
981  VALUE defined_class = me->defined_class;
982  const rb_method_entry_t *resolved_me = resolve_refined_method(refinements, (const rb_method_entry_t *)me, &defined_class);
983 
984  if (resolved_me && resolved_me->defined_class == 0) {
985  return rb_method_entry_complement_defined_class(resolved_me, me->called_id, defined_class);
986  }
987  else {
988  return (const rb_callable_method_entry_t *)resolved_me;
989  }
990 }
991 
992 static void
993 remove_method(VALUE klass, ID mid)
994 {
995  VALUE data;
996  rb_method_entry_t *me = 0;
997  VALUE self = klass;
998 
1001  if (mid == object_id || mid == id__send__ || mid == idInitialize) {
1002  rb_warn("removing `%s' may cause serious problems", rb_id2name(mid));
1003  }
1004 
1005  if (!rb_id_table_lookup(RCLASS_M_TBL(klass), mid, &data) ||
1006  !(me = (rb_method_entry_t *)data) ||
1007  (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
1009  rb_name_err_raise("method `%1$s' not defined in %2$s",
1010  klass, ID2SYM(mid));
1011  }
1012 
1014 
1015  rb_vm_check_redefinition_opt_method(me, klass);
1017 
1018  if (me->def->type == VM_METHOD_TYPE_REFINED) {
1020  }
1021 
1022  CALL_METHOD_HOOK(self, removed, mid);
1023 }
1024 
1025 void
1027 {
1028  remove_method(klass, mid);
1029 }
1030 
1031 void
1033 {
1034  remove_method(klass, rb_intern(name));
1035 }
1036 
1037 /*
1038  * call-seq:
1039  * remove_method(symbol) -> self
1040  * remove_method(string) -> self
1041  *
1042  * Removes the method identified by _symbol_ from the current
1043  * class. For an example, see Module#undef_method.
1044  * String arguments are converted to symbols.
1045  */
1046 
1047 static VALUE
1048 rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
1049 {
1050  int i;
1051 
1052  for (i = 0; i < argc; i++) {
1053  VALUE v = argv[i];
1054  ID id = rb_check_id(&v);
1055  if (!id) {
1056  rb_name_err_raise("method `%1$s' not defined in %2$s",
1057  mod, v);
1058  }
1059  remove_method(mod, id);
1060  }
1061  return mod;
1062 }
1063 
1064 static void
1065 rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
1066 {
1068  VALUE defined_class;
1069  VALUE origin_class = RCLASS_ORIGIN(klass);
1070 
1071  me = search_method(origin_class, name, &defined_class);
1072  if (!me && RB_TYPE_P(klass, T_MODULE)) {
1073  me = search_method(rb_cObject, name, &defined_class);
1074  }
1075 
1079  }
1080 
1081  if (METHOD_ENTRY_VISI(me) != visi) {
1082  rb_vm_check_redefinition_opt_method(me, klass);
1083 
1084  if (klass == defined_class || origin_class == defined_class) {
1085  METHOD_ENTRY_VISI_SET(me, visi);
1086 
1088  METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
1089  }
1091  }
1092  else {
1094  }
1095  }
1096 }
1097 
1098 #define BOUND_PRIVATE 0x01
1099 #define BOUND_RESPONDS 0x02
1100 
1101 int
1103 {
1104  const rb_method_entry_t *me;
1105 
1106  if (ex & BOUND_RESPONDS) {
1107  me = method_entry_resolve_refinement(klass, id, TRUE, NULL);
1108  }
1109  else {
1111  }
1112 
1113  if (me != 0) {
1114  if ((ex & ~BOUND_RESPONDS) &&
1117  return 0;
1118  }
1119 
1121  if (ex & BOUND_RESPONDS) return 2;
1122  return 0;
1123  }
1124  return 1;
1125  }
1126  return 0;
1127 }
1128 
1129 static void
1130 vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
1131 {
1133  scope_visi->method_visi = method_visi;
1134  scope_visi->module_func = module_func;
1135 }
1136 
1137 void
1139 {
1140  vm_cref_set_visibility(visi, FALSE);
1141 }
1142 
1143 static void
1144 scope_visibility_check(void)
1145 {
1146  /* Check for public/protected/private/module_function called inside a method */
1147  rb_control_frame_t *cfp = rb_current_execution_context()->cfp+1;
1148  if (cfp && cfp->iseq && cfp->iseq->body->type == ISEQ_TYPE_METHOD) {
1149  rb_warn("calling %s without arguments inside a method may not have the intended effect",
1151  }
1152 }
1153 
1154 static void
1155 rb_scope_module_func_set(void)
1156 {
1157  scope_visibility_check();
1158  vm_cref_set_visibility(METHOD_VISI_PRIVATE, TRUE);
1159 }
1160 
1162 void
1163 rb_attr(VALUE klass, ID id, int read, int write, int ex)
1164 {
1165  ID attriv;
1167  const rb_execution_context_t *ec = GET_EC();
1168  const rb_cref_t *cref = rb_vm_cref_in_context(klass, klass);
1169 
1170  if (!ex || !cref) {
1171  visi = METHOD_VISI_PUBLIC;
1172  }
1173  else {
1174  switch (vm_scope_visibility_get(ec)) {
1175  case METHOD_VISI_PRIVATE:
1176  if (vm_scope_module_func_check(ec)) {
1177  rb_warning("attribute accessor as module_function");
1178  }
1179  visi = METHOD_VISI_PRIVATE;
1180  break;
1181  case METHOD_VISI_PROTECTED:
1182  visi = METHOD_VISI_PROTECTED;
1183  break;
1184  default:
1185  visi = METHOD_VISI_PUBLIC;
1186  break;
1187  }
1188  }
1189 
1190  attriv = rb_intern_str(rb_sprintf("@%"PRIsVALUE, rb_id2str(id)));
1191  if (read) {
1192  rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, visi);
1193  }
1194  if (write) {
1195  rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, visi);
1196  }
1197 }
1198 
1199 void
1201 {
1202  const rb_method_entry_t *me;
1203 
1204  if (NIL_P(klass)) {
1205  rb_raise(rb_eTypeError, "no class to undef method");
1206  }
1208  if (id == object_id || id == id__send__ || id == idInitialize) {
1209  rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
1210  }
1211 
1212  me = search_method(klass, id, 0);
1213  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
1215  }
1216 
1220  }
1221 
1223 
1225 }
1226 
1227 /*
1228  * call-seq:
1229  * undef_method(symbol) -> self
1230  * undef_method(string) -> self
1231  *
1232  * Prevents the current class from responding to calls to the named
1233  * method. Contrast this with <code>remove_method</code>, which deletes
1234  * the method from the particular class; Ruby will still search
1235  * superclasses and mixed-in modules for a possible receiver.
1236  * String arguments are converted to symbols.
1237  *
1238  * class Parent
1239  * def hello
1240  * puts "In parent"
1241  * end
1242  * end
1243  * class Child < Parent
1244  * def hello
1245  * puts "In child"
1246  * end
1247  * end
1248  *
1249  *
1250  * c = Child.new
1251  * c.hello
1252  *
1253  *
1254  * class Child
1255  * remove_method :hello # remove from child, still in parent
1256  * end
1257  * c.hello
1258  *
1259  *
1260  * class Child
1261  * undef_method :hello # prevent any calls to 'hello'
1262  * end
1263  * c.hello
1264  *
1265  * <em>produces:</em>
1266  *
1267  * In child
1268  * In parent
1269  * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
1270  */
1271 
1272 static VALUE
1273 rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
1274 {
1275  int i;
1276  for (i = 0; i < argc; i++) {
1277  VALUE v = argv[i];
1278  ID id = rb_check_id(&v);
1279  if (!id) {
1281  }
1282  rb_undef(mod, id);
1283  }
1284  return mod;
1285 }
1286 
1288 check_definition_visibility(VALUE mod, int argc, VALUE *argv)
1289 {
1290  const rb_method_entry_t *me;
1291  VALUE mid, include_super, lookup_mod = mod;
1292  int inc_super;
1293  ID id;
1294 
1295  rb_scan_args(argc, argv, "11", &mid, &include_super);
1296  id = rb_check_id(&mid);
1297  if (!id) return METHOD_VISI_UNDEF;
1298 
1299  if (argc == 1) {
1300  inc_super = 1;
1301  }
1302  else {
1303  inc_super = RTEST(include_super);
1304  if (!inc_super) {
1305  lookup_mod = RCLASS_ORIGIN(mod);
1306  }
1307  }
1308 
1309  me = rb_method_entry_without_refinements(lookup_mod, id, NULL);
1310  if (me) {
1312  if (!inc_super && me->owner != mod) return METHOD_VISI_UNDEF;
1313  return METHOD_ENTRY_VISI(me);
1314  }
1315  return METHOD_VISI_UNDEF;
1316 }
1317 
1318 /*
1319  * call-seq:
1320  * mod.method_defined?(symbol, inherit=true) -> true or false
1321  * mod.method_defined?(string, inherit=true) -> true or false
1322  *
1323  * Returns +true+ if the named method is defined by
1324  * _mod_. If _inherit_ is set, the lookup will also search _mod_'s
1325  * ancestors. Public and protected methods are matched.
1326  * String arguments are converted to symbols.
1327  *
1328  * module A
1329  * def method1() end
1330  * def protected_method1() end
1331  * protected :protected_method1
1332  * end
1333  * class B
1334  * def method2() end
1335  * def private_method2() end
1336  * private :private_method2
1337  * end
1338  * class C < B
1339  * include A
1340  * def method3() end
1341  * end
1342  *
1343  * A.method_defined? :method1 #=> true
1344  * C.method_defined? "method1" #=> true
1345  * C.method_defined? "method2" #=> true
1346  * C.method_defined? "method2", true #=> true
1347  * C.method_defined? "method2", false #=> false
1348  * C.method_defined? "method3" #=> true
1349  * C.method_defined? "protected_method1" #=> true
1350  * C.method_defined? "method4" #=> false
1351  * C.method_defined? "private_method2" #=> false
1352  */
1353 
1354 static VALUE
1355 rb_mod_method_defined(int argc, VALUE *argv, VALUE mod)
1356 {
1357  rb_method_visibility_t visi = check_definition_visibility(mod, argc, argv);
1358  return (visi == METHOD_VISI_PUBLIC || visi == METHOD_VISI_PROTECTED) ? Qtrue : Qfalse;
1359 }
1360 
1361 static VALUE
1362 check_definition(VALUE mod, int argc, VALUE *argv, rb_method_visibility_t visi)
1363 {
1364  return (check_definition_visibility(mod, argc, argv) == visi) ? Qtrue : Qfalse;
1365 }
1366 
1367 /*
1368  * call-seq:
1369  * mod.public_method_defined?(symbol, inherit=true) -> true or false
1370  * mod.public_method_defined?(string, inherit=true) -> true or false
1371  *
1372  * Returns +true+ if the named public method is defined by
1373  * _mod_. If _inherit_ is set, the lookup will also search _mod_'s
1374  * ancestors.
1375  * String arguments are converted to symbols.
1376  *
1377  * module A
1378  * def method1() end
1379  * end
1380  * class B
1381  * protected
1382  * def method2() end
1383  * end
1384  * class C < B
1385  * include A
1386  * def method3() end
1387  * end
1388  *
1389  * A.method_defined? :method1 #=> true
1390  * C.public_method_defined? "method1" #=> true
1391  * C.public_method_defined? "method1", true #=> true
1392  * C.public_method_defined? "method1", false #=> true
1393  * C.public_method_defined? "method2" #=> false
1394  * C.method_defined? "method2" #=> true
1395  */
1396 
1397 static VALUE
1398 rb_mod_public_method_defined(int argc, VALUE *argv, VALUE mod)
1399 {
1400  return check_definition(mod, argc, argv, METHOD_VISI_PUBLIC);
1401 }
1402 
1403 /*
1404  * call-seq:
1405  * mod.private_method_defined?(symbol, inherit=true) -> true or false
1406  * mod.private_method_defined?(string, inherit=true) -> true or false
1407  *
1408  * Returns +true+ if the named private method is defined by
1409  * _mod_. If _inherit_ is set, the lookup will also search _mod_'s
1410  * ancestors.
1411  * String arguments are converted to symbols.
1412  *
1413  * module A
1414  * def method1() end
1415  * end
1416  * class B
1417  * private
1418  * def method2() end
1419  * end
1420  * class C < B
1421  * include A
1422  * def method3() end
1423  * end
1424  *
1425  * A.method_defined? :method1 #=> true
1426  * C.private_method_defined? "method1" #=> false
1427  * C.private_method_defined? "method2" #=> true
1428  * C.private_method_defined? "method2", true #=> true
1429  * C.private_method_defined? "method2", false #=> false
1430  * C.method_defined? "method2" #=> false
1431  */
1432 
1433 static VALUE
1434 rb_mod_private_method_defined(int argc, VALUE *argv, VALUE mod)
1435 {
1436  return check_definition(mod, argc, argv, METHOD_VISI_PRIVATE);
1437 }
1438 
1439 /*
1440  * call-seq:
1441  * mod.protected_method_defined?(symbol, inherit=true) -> true or false
1442  * mod.protected_method_defined?(string, inherit=true) -> true or false
1443  *
1444  * Returns +true+ if the named protected method is defined
1445  * _mod_. If _inherit_ is set, the lookup will also search _mod_'s
1446  * ancestors.
1447  * String arguments are converted to symbols.
1448  *
1449  * module A
1450  * def method1() end
1451  * end
1452  * class B
1453  * protected
1454  * def method2() end
1455  * end
1456  * class C < B
1457  * include A
1458  * def method3() end
1459  * end
1460  *
1461  * A.method_defined? :method1 #=> true
1462  * C.protected_method_defined? "method1" #=> false
1463  * C.protected_method_defined? "method2" #=> true
1464  * C.protected_method_defined? "method2", true #=> true
1465  * C.protected_method_defined? "method2", false #=> false
1466  * C.method_defined? "method2" #=> true
1467  */
1468 
1469 static VALUE
1470 rb_mod_protected_method_defined(int argc, VALUE *argv, VALUE mod)
1471 {
1472  return check_definition(mod, argc, argv, METHOD_VISI_PROTECTED);
1473 }
1474 
1475 int
1477 {
1478  return rb_method_definition_eq(m1->def, m2->def);
1479 }
1480 
1481 static const rb_method_definition_t *
1482 original_method_definition(const rb_method_definition_t *def)
1483 {
1484  again:
1485  if (def) {
1486  switch (def->type) {
1488  if (def->body.refined.orig_me) {
1489  def = def->body.refined.orig_me->def;
1490  goto again;
1491  }
1492  break;
1493  case VM_METHOD_TYPE_ALIAS:
1494  def = def->body.alias.original_me->def;
1495  goto again;
1496  default:
1497  break;
1498  }
1499  }
1500  return def;
1501 }
1502 
1505 {
1506  d1 = original_method_definition(d1);
1507  d2 = original_method_definition(d2);
1508 
1509  if (d1 == d2) return 1;
1510  if (!d1 || !d2) return 0;
1511  if (d1->type != d2->type) return 0;
1512 
1513  switch (d1->type) {
1514  case VM_METHOD_TYPE_ISEQ:
1515  return d1->body.iseq.iseqptr == d2->body.iseq.iseqptr;
1516  case VM_METHOD_TYPE_CFUNC:
1517  return
1518  d1->body.cfunc.func == d2->body.cfunc.func &&
1519  d1->body.cfunc.argc == d2->body.cfunc.argc;
1521  case VM_METHOD_TYPE_IVAR:
1522  return d1->body.attr.id == d2->body.attr.id;
1524  return RTEST(rb_equal(d1->body.bmethod.proc, d2->body.bmethod.proc));
1526  return d1->original_id == d2->original_id;
1527  case VM_METHOD_TYPE_ZSUPER:
1529  case VM_METHOD_TYPE_UNDEF:
1530  return 1;
1532  return d1->body.optimize_type == d2->body.optimize_type;
1534  case VM_METHOD_TYPE_ALIAS:
1535  break;
1536  }
1537  rb_bug("rb_method_definition_eq: unsupported type: %d\n", d1->type);
1538 }
1539 
1540 static st_index_t
1541 rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
1542 {
1543  hash = rb_hash_uint(hash, def->type);
1544  def = original_method_definition(def);
1545 
1546  if (!def) return hash;
1547 
1548  switch (def->type) {
1549  case VM_METHOD_TYPE_ISEQ:
1550  return rb_hash_uint(hash, (st_index_t)def->body.iseq.iseqptr);
1551  case VM_METHOD_TYPE_CFUNC:
1552  hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
1553  return rb_hash_uint(hash, def->body.cfunc.argc);
1555  case VM_METHOD_TYPE_IVAR:
1556  return rb_hash_uint(hash, def->body.attr.id);
1558  return rb_hash_proc(hash, def->body.bmethod.proc);
1560  return rb_hash_uint(hash, def->original_id);
1561  case VM_METHOD_TYPE_ZSUPER:
1563  case VM_METHOD_TYPE_UNDEF:
1564  return hash;
1566  return rb_hash_uint(hash, def->body.optimize_type);
1568  case VM_METHOD_TYPE_ALIAS:
1569  break; /* unreachable */
1570  }
1571  rb_bug("rb_hash_method_definition: unsupported method type (%d)\n", def->type);
1572  }
1573 
1574 st_index_t
1576 {
1577  return rb_hash_method_definition(hash, me->def);
1578 }
1579 
1580 void
1581 rb_alias(VALUE klass, ID alias_name, ID original_name)
1582 {
1583  const VALUE target_klass = klass;
1584  VALUE defined_class;
1585  const rb_method_entry_t *orig_me;
1587 
1588  if (NIL_P(klass)) {
1589  rb_raise(rb_eTypeError, "no class to make alias");
1590  }
1591 
1593 
1594  again:
1595  orig_me = search_method(klass, original_name, &defined_class);
1596  if (orig_me && orig_me->def->type == VM_METHOD_TYPE_REFINED) {
1597  orig_me = rb_resolve_refined_method(Qnil, orig_me);
1598  }
1599 
1600  if (UNDEFINED_METHOD_ENTRY_P(orig_me) ||
1601  UNDEFINED_REFINED_METHOD_P(orig_me->def)) {
1602  if ((!RB_TYPE_P(klass, T_MODULE)) ||
1603  (orig_me = search_method(rb_cObject, original_name, &defined_class),
1604  UNDEFINED_METHOD_ENTRY_P(orig_me))) {
1605  rb_print_undef(klass, original_name, METHOD_VISI_UNDEF);
1606  }
1607  }
1608 
1609  if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {
1611  original_name = orig_me->def->original_id;
1612  visi = METHOD_ENTRY_VISI(orig_me);
1613  goto again;
1614  }
1615 
1616  if (visi == METHOD_VISI_UNDEF) visi = METHOD_ENTRY_VISI(orig_me);
1617 
1618  if (orig_me->defined_class == 0) {
1619  rb_method_entry_make(target_klass, alias_name, target_klass, visi,
1620  VM_METHOD_TYPE_ALIAS, NULL, orig_me->called_id,
1621  (void *)rb_method_entry_clone(orig_me));
1622  method_added(target_klass, alias_name);
1623  }
1624  else {
1625  rb_method_entry_t *alias_me;
1626 
1627  alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner);
1628  RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass);
1629  RB_OBJ_WRITE(alias_me, &alias_me->defined_class, defined_class);
1630  }
1631 }
1632 
1633 /*
1634  * call-seq:
1635  * alias_method(new_name, old_name) -> self
1636  *
1637  * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
1638  * be used to retain access to methods that are overridden.
1639  *
1640  * module Mod
1641  * alias_method :orig_exit, :exit
1642  * def exit(code=0)
1643  * puts "Exiting with code #{code}"
1644  * orig_exit(code)
1645  * end
1646  * end
1647  * include Mod
1648  * exit(99)
1649  *
1650  * <em>produces:</em>
1651  *
1652  * Exiting with code 99
1653  */
1654 
1655 static VALUE
1656 rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
1657 {
1658  ID oldid = rb_check_id(&oldname);
1659  if (!oldid) {
1660  rb_print_undef_str(mod, oldname);
1661  }
1662  rb_alias(mod, rb_to_id(newname), oldid);
1663  return mod;
1664 }
1665 
1666 static void
1667 set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
1668 {
1669  int i;
1670 
1671  rb_check_frozen(self);
1672  if (argc == 0) {
1673  rb_warning("%"PRIsVALUE" with no argument is just ignored",
1675  return;
1676  }
1677 
1678  for (i = 0; i < argc; i++) {
1679  VALUE v = argv[i];
1680  ID id = rb_check_id(&v);
1681  if (!id) {
1682  rb_print_undef_str(self, v);
1683  }
1684  rb_export_method(self, id, visi);
1685  }
1686 }
1687 
1688 static VALUE
1689 set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
1690 {
1691  if (argc == 0) {
1692  scope_visibility_check();
1694  }
1695  else {
1696  set_method_visibility(module, argc, argv, visi);
1697  }
1698  return module;
1699 }
1700 
1701 /*
1702  * call-seq:
1703  * public -> self
1704  * public(symbol, ...) -> self
1705  * public(string, ...) -> self
1706  *
1707  * With no arguments, sets the default visibility for subsequently
1708  * defined methods to public. With arguments, sets the named methods to
1709  * have public visibility.
1710  * String arguments are converted to symbols.
1711  */
1712 
1713 static VALUE
1714 rb_mod_public(int argc, VALUE *argv, VALUE module)
1715 {
1716  return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC);
1717 }
1718 
1719 /*
1720  * call-seq:
1721  * protected -> self
1722  * protected(symbol, ...) -> self
1723  * protected(string, ...) -> self
1724  *
1725  * With no arguments, sets the default visibility for subsequently
1726  * defined methods to protected. With arguments, sets the named methods
1727  * to have protected visibility.
1728  * String arguments are converted to symbols.
1729  *
1730  * If a method has protected visibility, it is callable only where
1731  * <code>self</code> of the context is the same as the method.
1732  * (method definition or instance_eval). This behavior is different from
1733  * Java's protected method. Usually <code>private</code> should be used.
1734  *
1735  * Note that a protected method is slow because it can't use inline cache.
1736  *
1737  * To show a private method on RDoc, use <code>:doc:</code> instead of this.
1738  */
1739 
1740 static VALUE
1741 rb_mod_protected(int argc, VALUE *argv, VALUE module)
1742 {
1743  return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED);
1744 }
1745 
1746 /*
1747  * call-seq:
1748  * private -> self
1749  * private(symbol, ...) -> self
1750  * private(string, ...) -> self
1751  *
1752  * With no arguments, sets the default visibility for subsequently
1753  * defined methods to private. With arguments, sets the named methods
1754  * to have private visibility.
1755  * String arguments are converted to symbols.
1756  *
1757  * module Mod
1758  * def a() end
1759  * def b() end
1760  * private
1761  * def c() end
1762  * private :a
1763  * end
1764  * Mod.private_instance_methods #=> [:a, :c]
1765  *
1766  * Note that to show a private method on RDoc, use <code>:doc:</code>.
1767  */
1768 
1769 static VALUE
1770 rb_mod_private(int argc, VALUE *argv, VALUE module)
1771 {
1772  return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE);
1773 }
1774 
1775 /*
1776  * call-seq:
1777  * ruby2_keywords(method_name, ...) -> self
1778  *
1779  * For the given method names, marks the method as passing keywords through
1780  * a normal argument splat. This should only be called on methods that
1781  * accept an argument splat (<tt>*args</tt>) but not explicit keywords or
1782  * a keyword splat. It marks the method such that if the method is called
1783  * with keyword arguments, the final hash argument is marked with a special
1784  * flag such that if it is the final element of a normal argument splat to
1785  * another method call, and that method call does not include explicit
1786  * keywords or a keyword splat, the final element is interpreted as keywords.
1787  * In other words, keywords will be passed through the method to other
1788  * methods.
1789  *
1790  * This should only be used for methods that delegate keywords to another
1791  * method, and only for backwards compatibility with Ruby versions before
1792  * 2.7.
1793  *
1794  * This method will probably be removed at some point, as it exists only
1795  * for backwards compatibility. As it does not exist in Ruby versions
1796  * before 2.7, check that the module responds to this method before calling
1797  * it. Also, be aware that if this method is removed, the behavior of the
1798  * method will change so that it does not pass through keywords.
1799  *
1800  * module Mod
1801  * def foo(meth, *args, &block)
1802  * send(:"do_#{meth}", *args, &block)
1803  * end
1804  * ruby2_keywords(:foo) if respond_to?(:ruby2_keywords, true)
1805  * end
1806  */
1807 
1808 static VALUE
1809 rb_mod_ruby2_keywords(int argc, VALUE *argv, VALUE module)
1810 {
1811  int i;
1812  VALUE origin_class = RCLASS_ORIGIN(module);
1813 
1814  rb_check_frozen(module);
1815 
1816  for (i = 0; i < argc; i++) {
1817  VALUE v = argv[i];
1818  ID name = rb_check_id(&v);
1820  VALUE defined_class;
1821 
1822  if (!name) {
1823  rb_print_undef_str(module, v);
1824  }
1825 
1826  me = search_method(origin_class, name, &defined_class);
1827  if (!me && RB_TYPE_P(module, T_MODULE)) {
1828  me = search_method(rb_cObject, name, &defined_class);
1829  }
1830 
1834  }
1835 
1836  if (module == defined_class || origin_class == defined_class) {
1837  switch (me->def->type) {
1838  case VM_METHOD_TYPE_ISEQ:
1839  if (me->def->body.iseq.iseqptr->body->param.flags.has_rest &&
1840  !me->def->body.iseq.iseqptr->body->param.flags.has_kw &&
1841  !me->def->body.iseq.iseqptr->body->param.flags.has_kwrest) {
1842  me->def->body.iseq.iseqptr->body->param.flags.ruby2_keywords = 1;
1844  }
1845  else {
1846  rb_warn("Skipping set of ruby2_keywords flag for %s (method accepts keywords or method does not accept argument splat)", rb_id2name(name));
1847  }
1848  break;
1849  case VM_METHOD_TYPE_BMETHOD: {
1850  VALUE procval = me->def->body.bmethod.proc;
1851  if (vm_block_handler_type(procval) == block_handler_type_proc) {
1852  procval = vm_proc_to_block_handler(VM_BH_TO_PROC(procval));
1853  }
1854 
1855  if (vm_block_handler_type(procval) == block_handler_type_iseq) {
1856  const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(procval);
1857  const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
1858  if (iseq->body->param.flags.has_rest &&
1859  !iseq->body->param.flags.has_kw &&
1860  !iseq->body->param.flags.has_kwrest) {
1861  iseq->body->param.flags.ruby2_keywords = 1;
1863  }
1864  else {
1865  rb_warn("Skipping set of ruby2_keywords flag for %s (method accepts keywords or method does not accept argument splat)", rb_id2name(name));
1866  }
1867  return Qnil;
1868  }
1869  }
1870  /* fallthrough */
1871  default:
1872  rb_warn("Skipping set of ruby2_keywords flag for %s (method not defined in Ruby)", rb_id2name(name));
1873  break;
1874  }
1875  }
1876  else {
1877  rb_warn("Skipping set of ruby2_keywords flag for %s (can only set in method defining module)", rb_id2name(name));
1878  }
1879  }
1880  return Qnil;
1881 }
1882 
1883 /*
1884  * call-seq:
1885  * mod.public_class_method(symbol, ...) -> mod
1886  * mod.public_class_method(string, ...) -> mod
1887  *
1888  * Makes a list of existing class methods public.
1889  *
1890  * String arguments are converted to symbols.
1891  */
1892 
1893 static VALUE
1894 rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
1895 {
1896  set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PUBLIC);
1897  return obj;
1898 }
1899 
1900 /*
1901  * call-seq:
1902  * mod.private_class_method(symbol, ...) -> mod
1903  * mod.private_class_method(string, ...) -> mod
1904  *
1905  * Makes existing class methods private. Often used to hide the default
1906  * constructor <code>new</code>.
1907  *
1908  * String arguments are converted to symbols.
1909  *
1910  * class SimpleSingleton # Not thread safe
1911  * private_class_method :new
1912  * def SimpleSingleton.create(*args, &block)
1913  * @me = new(*args, &block) if ! @me
1914  * @me
1915  * end
1916  * end
1917  */
1918 
1919 static VALUE
1920 rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
1921 {
1922  set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PRIVATE);
1923  return obj;
1924 }
1925 
1926 /*
1927  * call-seq:
1928  * public
1929  * public(symbol, ...)
1930  * public(string, ...)
1931  *
1932  * With no arguments, sets the default visibility for subsequently
1933  * defined methods to public. With arguments, sets the named methods to
1934  * have public visibility.
1935  *
1936  * String arguments are converted to symbols.
1937  */
1938 
1939 static VALUE
1940 top_public(int argc, VALUE *argv, VALUE _)
1941 {
1942  return rb_mod_public(argc, argv, rb_cObject);
1943 }
1944 
1945 /*
1946  * call-seq:
1947  * private
1948  * private(symbol, ...)
1949  * private(string, ...)
1950  *
1951  * With no arguments, sets the default visibility for subsequently
1952  * defined methods to private. With arguments, sets the named methods to
1953  * have private visibility.
1954  *
1955  * String arguments are converted to symbols.
1956  */
1957 static VALUE
1958 top_private(int argc, VALUE *argv, VALUE _)
1959 {
1960  return rb_mod_private(argc, argv, rb_cObject);
1961 }
1962 
1963 /*
1964  * call-seq:
1965  * ruby2_keywords(method_name, ...) -> self
1966  *
1967  * For the given method names, marks the method as passing keywords through
1968  * a normal argument splat. See Module#ruby2_keywords in detail.
1969  */
1970 static VALUE
1971 top_ruby2_keywords(int argc, VALUE *argv, VALUE module)
1972 {
1973  return rb_mod_ruby2_keywords(argc, argv, rb_cObject);
1974 }
1975 
1976 /*
1977  * call-seq:
1978  * module_function(symbol, ...) -> self
1979  * module_function(string, ...) -> self
1980  *
1981  * Creates module functions for the named methods. These functions may
1982  * be called with the module as a receiver, and also become available
1983  * as instance methods to classes that mix in the module. Module
1984  * functions are copies of the original, and so may be changed
1985  * independently. The instance-method versions are made private. If
1986  * used with no arguments, subsequently defined methods become module
1987  * functions.
1988  * String arguments are converted to symbols.
1989  *
1990  * module Mod
1991  * def one
1992  * "This is one"
1993  * end
1994  * module_function :one
1995  * end
1996  * class Cls
1997  * include Mod
1998  * def call_one
1999  * one
2000  * end
2001  * end
2002  * Mod.one #=> "This is one"
2003  * c = Cls.new
2004  * c.call_one #=> "This is one"
2005  * module Mod
2006  * def one
2007  * "This is the new one"
2008  * end
2009  * end
2010  * Mod.one #=> "This is one"
2011  * c.call_one #=> "This is the new one"
2012  */
2013 
2014 static VALUE
2015 rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
2016 {
2017  int i;
2018  ID id;
2019  const rb_method_entry_t *me;
2020 
2021  if (!RB_TYPE_P(module, T_MODULE)) {
2022  rb_raise(rb_eTypeError, "module_function must be called for modules");
2023  }
2024 
2025  if (argc == 0) {
2026  rb_scope_module_func_set();
2027  return module;
2028  }
2029 
2030  set_method_visibility(module, argc, argv, METHOD_VISI_PRIVATE);
2031 
2032  for (i = 0; i < argc; i++) {
2033  VALUE m = module;
2034 
2035  id = rb_to_id(argv[i]);
2036  for (;;) {
2037  me = search_method(m, id, 0);
2038  if (me == 0) {
2039  me = search_method(rb_cObject, id, 0);
2040  }
2042  rb_print_undef(module, id, METHOD_VISI_UNDEF);
2043  }
2044  if (me->def->type != VM_METHOD_TYPE_ZSUPER) {
2045  break; /* normal case: need not to follow 'super' link */
2046  }
2047  m = RCLASS_SUPER(m);
2048  if (!m)
2049  break;
2050  }
2052  }
2053  return module;
2054 }
2055 
2056 bool
2058 {
2059  if (cd->ci.mid != mid) {
2060  *cd = (struct rb_call_data) /* reset */ { .ci = { .mid = mid, }, };
2061  }
2062 
2063  vm_search_method_fastpath(cd, klass);
2064  return cd->cc.me && METHOD_ENTRY_BASIC(cd->cc.me);
2065 }
2066 
2067 #ifdef __GNUC__
2068 #pragma push_macro("rb_method_basic_definition_p")
2069 #undef rb_method_basic_definition_p
2070 #endif
2071 int
2073 {
2074  const rb_method_entry_t *me;
2075  if (!klass) return TRUE; /* hidden object cannot be overridden */
2076  me = rb_method_entry(klass, id);
2077  return (me && METHOD_ENTRY_BASIC(me)) ? TRUE : FALSE;
2078 }
2079 #ifdef __GNUC__
2080 #pragma pop_macro("rb_method_basic_definition_p")
2081 #endif
2082 
2083 static VALUE
2084 call_method_entry(rb_execution_context_t *ec, VALUE defined_class, VALUE obj, ID id,
2085  const rb_method_entry_t *me, int argc, const VALUE *argv, int kw_splat)
2086 {
2087  const rb_callable_method_entry_t *cme =
2088  prepare_callable_method_entry(defined_class, id, me);
2089  VALUE passed_block_handler = vm_passed_block_handler(ec);
2090  VALUE result = rb_vm_call_kw(ec, obj, id, argc, argv, cme, kw_splat);
2091  vm_passed_block_handler_set(ec, passed_block_handler);
2092  return result;
2093 }
2094 
2095 static VALUE
2096 basic_obj_respond_to_missing(rb_execution_context_t *ec, VALUE klass, VALUE obj,
2097  VALUE mid, VALUE priv)
2098 {
2099  VALUE defined_class, args[2];
2100  const ID rtmid = idRespond_to_missing;
2101  const rb_method_entry_t *const me =
2102  method_entry_get(klass, rtmid, &defined_class);
2103 
2104  if (!me || METHOD_ENTRY_BASIC(me)) return Qundef;
2105  args[0] = mid;
2106  args[1] = priv;
2107  return call_method_entry(ec, defined_class, obj, rtmid, me, 2, args, RB_NO_KEYWORDS);
2108 }
2109 
2110 static inline int
2111 basic_obj_respond_to(rb_execution_context_t *ec, VALUE obj, ID id, int pub)
2112 {
2113  VALUE klass = CLASS_OF(obj);
2114  VALUE ret;
2115 
2116  switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) {
2117  case 2:
2118  return FALSE;
2119  case 0:
2120  ret = basic_obj_respond_to_missing(ec, klass, obj, ID2SYM(id),
2121  pub ? Qfalse : Qtrue);
2122  return RTEST(ret) && ret != Qundef;
2123  default:
2124  return TRUE;
2125  }
2126 }
2127 
2128 static int
2129 vm_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE obj, ID id, int priv)
2130 {
2131  VALUE defined_class;
2132  const ID resid = idRespond_to;
2133  const rb_method_entry_t *const me =
2134  method_entry_get(klass, resid, &defined_class);
2135 
2136  if (!me) return -1;
2137  if (METHOD_ENTRY_BASIC(me)) {
2138  return -1;
2139  }
2140  else {
2141  int argc = 1;
2142  VALUE args[2];
2143  VALUE result;
2144 
2145  args[0] = ID2SYM(id);
2146  args[1] = Qtrue;
2147  if (priv) {
2149  if (argc > 2) {
2151  "respond_to? must accept 1 or 2 arguments (requires %d)",
2152  argc);
2153  }
2154  if (argc != 1) {
2155  argc = 2;
2156  }
2157  else if (!NIL_P(ruby_verbose)) {
2158  VALUE location = rb_method_entry_location(me);
2159  rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") uses"
2160  " the deprecated method signature, which takes one parameter",
2162  (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
2163  QUOTE_ID(id));
2164  if (!NIL_P(location)) {
2165  VALUE path = RARRAY_AREF(location, 0);
2166  VALUE line = RARRAY_AREF(location, 1);
2167  if (!NIL_P(path)) {
2169  "respond_to? is defined here");
2170  }
2171  }
2172  }
2173  }
2174  result = call_method_entry(ec, defined_class, obj, resid, me, argc, args, RB_NO_KEYWORDS);
2175  return RTEST(result);
2176  }
2177 }
2178 
2179 int
2181 {
2183  VALUE klass = CLASS_OF(obj);
2184  int ret = vm_respond_to(ec, klass, obj, id, priv);
2185  if (ret == -1) ret = basic_obj_respond_to(ec, obj, id, !priv);
2186  return ret;
2187 }
2188 
2189 int
2191 {
2192  return rb_obj_respond_to(obj, id, FALSE);
2193 }
2194 
2195 
2196 /*
2197  * call-seq:
2198  * obj.respond_to?(symbol, include_all=false) -> true or false
2199  * obj.respond_to?(string, include_all=false) -> true or false
2200  *
2201  * Returns +true+ if _obj_ responds to the given method. Private and
2202  * protected methods are included in the search only if the optional
2203  * second parameter evaluates to +true+.
2204  *
2205  * If the method is not implemented,
2206  * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
2207  * false is returned.
2208  *
2209  * If the method is not defined, <code>respond_to_missing?</code>
2210  * method is called and the result is returned.
2211  *
2212  * When the method name parameter is given as a string, the string is
2213  * converted to a symbol.
2214  */
2215 
2216 static VALUE
2217 obj_respond_to(int argc, VALUE *argv, VALUE obj)
2218 {
2219  VALUE mid, priv;
2220  ID id;
2222 
2223  rb_scan_args(argc, argv, "11", &mid, &priv);
2224  if (!(id = rb_check_id(&mid))) {
2225  VALUE ret = basic_obj_respond_to_missing(ec, CLASS_OF(obj), obj,
2226  rb_to_symbol(mid), priv);
2227  if (ret == Qundef) ret = Qfalse;
2228  return ret;
2229  }
2230  if (basic_obj_respond_to(ec, obj, id, !RTEST(priv)))
2231  return Qtrue;
2232  return Qfalse;
2233 }
2234 
2235 /*
2236  * call-seq:
2237  * obj.respond_to_missing?(symbol, include_all) -> true or false
2238  * obj.respond_to_missing?(string, include_all) -> true or false
2239  *
2240  * DO NOT USE THIS DIRECTLY.
2241  *
2242  * Hook method to return whether the _obj_ can respond to _id_ method
2243  * or not.
2244  *
2245  * When the method name parameter is given as a string, the string is
2246  * converted to a symbol.
2247  *
2248  * See #respond_to?, and the example of BasicObject.
2249  */
2250 static VALUE
2251 obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
2252 {
2253  return Qfalse;
2254 }
2255 
2256 void
2258 {
2259  if (!OPT_GLOBAL_METHOD_CACHE) return;
2260  char *ptr = getenv("RUBY_GLOBAL_METHOD_CACHE_SIZE");
2261  int val;
2262 
2263  if (ptr != NULL && (val = atoi(ptr)) > 0) {
2264  if ((val & (val - 1)) == 0) { /* ensure val is a power of 2 */
2265  global_method_cache.size = val;
2266  global_method_cache.mask = val - 1;
2267  }
2268  else {
2269  fprintf(stderr, "RUBY_GLOBAL_METHOD_CACHE_SIZE was set to %d but ignored because the value is not a power of 2.\n", val);
2270  }
2271  }
2272 
2273  global_method_cache.entries = (struct cache_entry *)calloc(global_method_cache.size, sizeof(struct cache_entry));
2274  if (global_method_cache.entries == NULL) {
2275  fprintf(stderr, "[FATAL] failed to allocate memory\n");
2276  exit(EXIT_FAILURE);
2277  }
2278 }
2279 
2280 void
2282 {
2283 #undef rb_intern
2284 #define rb_intern(str) rb_intern_const(str)
2285 
2286  rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
2287  rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
2288 
2289  rb_define_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
2290  rb_define_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
2291  rb_define_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
2292  rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
2293  rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
2294  rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
2295  rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
2296  rb_define_private_method(rb_cModule, "ruby2_keywords", rb_mod_ruby2_keywords, -1);
2297 
2298  rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, -1);
2299  rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, -1);
2300  rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, -1);
2301  rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, -1);
2302  rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
2303  rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
2304 
2306  "public", top_public, -1);
2308  "private", top_private, -1);
2310  "ruby2_keywords", top_ruby2_keywords, -1);
2311 
2312  {
2313 #define REPLICATE_METHOD(klass, id) do { \
2314  const rb_method_entry_t *me = rb_method_entry((klass), (id)); \
2315  rb_method_entry_set((klass), (id), me, METHOD_ENTRY_VISI(me)); \
2316  } while (0)
2317 
2321  }
2322 }
rb_add_method_cfunc
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
Definition: vm_method.c:134
METHOD_VISI_PRIVATE
@ METHOD_VISI_PRIVATE
Definition: method.h:29
REPLICATE_METHOD
#define REPLICATE_METHOD(klass, id)
rb_subclass_entry::next
rb_subclass_entry_t * next
Definition: internal.h:1000
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5425
ID
unsigned long ID
Definition: ruby.h:103
rb_method_entry_arity
int rb_method_entry_arity(const rb_method_entry_t *me)
Definition: proc.c:2543
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5703
rb_id2name
const char * rb_id2name(ID)
Definition: symbol.c:801
rb_method_bmethod_struct::proc
VALUE proc
Definition: method.h:152
rb_method_basic_definition_p
int rb_method_basic_definition_p(VALUE klass, ID id)
Definition: vm_method.c:2072
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:595
rb_add_method
void rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
Definition: vm_method.c:674
TRUE
#define TRUE
Definition: nkf.h:175
rb_callable_method_entry
const MJIT_FUNC_EXPORTED rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
Definition: vm_method.c:878
block_handler_type_iseq
@ block_handler_type_iseq
Definition: vm_core.h:738
rb_check_id
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:919
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13179
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.1.h:5324
rb_class_modify_check
void rb_class_modify_check(VALUE klass)
Asserts that klass is not a frozen class.
Definition: eval.c:438
id
const int id
Definition: nkf.c:209
VM_METHOD_TYPE_REFINED
@ VM_METHOD_TYPE_REFINED
refinement
Definition: method.h:113
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
rb_iseq_struct
Definition: vm_core.h:456
rb_method_definition_struct::method_serial
uintptr_t method_serial
Definition: method.h:180
rb_method_cfunc_struct::invoker
VALUE(* invoker)(VALUE recv, int argc, const VALUE *argv, VALUE(*func)(ANYARGS))
Definition: method.h:133
VM_METHOD_TYPE_OPTIMIZED
@ VM_METHOD_TYPE_OPTIMIZED
Kernel::send, Proc::call, etc.
Definition: method.h:111
PREV_CLASS_SERIAL
#define PREV_CLASS_SERIAL()
Definition: vm_insnhelper.h:187
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
entries
struct iseq_catch_table_entry entries[]
Definition: rb_mjit_min_header-2.7.1.h:10752
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
rb_method_definition_struct::attr
rb_method_attr_t attr
Definition: method.h:171
idRespond_to_missing
@ idRespond_to_missing
Definition: id.h:117
rb_hash_method_entry
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1575
rb_undef
void rb_undef(VALUE klass, ID id)
Definition: vm_method.c:1200
rb_method_iseq_struct::cref
rb_cref_t * cref
class reference, should be marked
Definition: method.h:128
rb_vm_cref_in_context
const rb_cref_t * rb_vm_cref_in_context(VALUE self, VALUE cbase)
Definition: vm.c:1400
rb_vm_check_optimizable_mid
int rb_vm_check_optimizable_mid(VALUE mid)
Definition: vm.c:1581
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
rb_to_symbol
VALUE rb_to_symbol(VALUE name)
Definition: string.c:11156
added
#define added
Definition: vm_method.c:32
rb_print_undef
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:379
rb_call_cache::me
const struct rb_callable_method_entry_struct * me
Definition: internal.h:2378
idInitialize
@ idInitialize
Definition: rb_mjit_min_header-2.7.1.h:8636
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
rb_callable_method_entry_struct::owner
const VALUE owner
Definition: method.h:64
rb_intern
#define rb_intern(str)
rb_method_name_error
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1778
rb_method_attr_struct::id
ID id
Definition: method.h:138
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
GLOBAL_METHOD_CACHE
#define GLOBAL_METHOD_CACHE(c, m)
Definition: vm_method.c:25
cache_entry::class_serial
rb_serial_t class_serial
Definition: vm_method.c:42
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_id_attrset
ID rb_id_attrset(ID)
Definition: symbol.c:98
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
ZALLOC
#define ZALLOC(type)
Definition: ruby.h:1666
rb_scope_visi_struct::method_visi
rb_method_visibility_t method_visi
Definition: rb_mjit_min_header-2.7.1.h:8698
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
rb_callable_method_entry_struct
Definition: method.h:59
rb_cModule
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:2034
block_handler_type_proc
@ block_handler_type_proc
Definition: vm_core.h:741
rb_method_definition_struct::type
rb_method_type_t type
Definition: rb_mjit_min_header-2.7.1.h:8804
rb_method_entry_struct::def
struct rb_method_definition_struct *const def
Definition: method.h:54
rb_iseq_path
VALUE rb_iseq_path(const rb_iseq_t *iseq)
Definition: iseq.c:1027
getenv
#define getenv(name)
Definition: win32.c:73
rb_iseq_constant_body::location
rb_iseq_location_t location
Definition: vm_core.h:399
rb_id_table
Definition: id_table.c:40
rb_id_table_insert
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
Definition: id_table.c:256
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5562
rb_method_definition_struct::optimize_type
enum method_optimized_type optimize_type
Definition: method.h:176
rb_method_definition_struct::refined
rb_method_refined_t refined
Definition: method.h:173
rb_method_iseq_struct
Definition: method.h:126
rb_iseq_location_struct::first_lineno
VALUE first_lineno
Definition: vm_core.h:276
rb_method_visibility_t
rb_method_visibility_t
Definition: method.h:26
iseq
const rb_iseq_t * iseq
Definition: rb_mjit_min_header-2.7.1.h:13426
rb_method_refined_struct::orig_me
struct rb_method_entry_struct * orig_me
Definition: method.h:147
Qundef
#define Qundef
Definition: ruby.h:470
rb_method_definition_eq
int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
Definition: vm_method.c:1504
EXIT_FAILURE
#define EXIT_FAILURE
Definition: eval_intern.h:32
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
GET_EC
#define GET_EC()
Definition: vm_core.h:1766
rb_respond_to
int rb_respond_to(VALUE obj, ID id)
Definition: vm_method.c:2190
ptr
struct RIMemo * ptr
Definition: debug.c:74
me
const rb_callable_method_entry_t * me
Definition: rb_mjit_min_header-2.7.1.h:13151
METHOD_ENTRY_COMPLEMENTED_SET
#define METHOD_ENTRY_COMPLEMENTED_SET(me)
Definition: method.h:70
rb_method_iseq_struct::iseqptr
rb_iseq_t * iseqptr
iseq pointer, should be separated from iseqval
Definition: method.h:127
Qfalse
#define Qfalse
Definition: ruby.h:467
ruby_running
#define ruby_running
Definition: vm_method.c:59
uintptr_t
unsigned int uintptr_t
Definition: win32.h:106
rb_method_entry_struct::owner
VALUE owner
Definition: method.h:56
rb_method_definition_struct::alias_count
int alias_count
Definition: method.h:165
rb_free_method_entry
void rb_free_method_entry(const rb_method_entry_t *me)
Definition: vm_method.c:174
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
INC_GLOBAL_METHOD_STATE
#define INC_GLOBAL_METHOD_STATE()
Definition: vm_insnhelper.h:190
rb_method_entry_with_refinements
const rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:911
rb_callable_method_entry_with_refinements
const MJIT_FUNC_EXPORTED rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:917
rb_ary_new3
#define rb_ary_new3
Definition: intern.h:104
NULL
#define NULL
Definition: _sdbm.c:101
FL_TEST
#define FL_TEST(x, f)
Definition: ruby.h:1353
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
rb_vm_cref
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1384
ID2SYM
#define ID2SYM(x)
Definition: ruby.h:414
rb_method_definition_struct::bmethod
rb_method_bmethod_t bmethod
Definition: method.h:174
VM_METHOD_TYPE_IVAR
@ VM_METHOD_TYPE_IVAR
attr_reader or attr_accessor
Definition: method.h:105
rb_obj_respond_to
int rb_obj_respond_to(VALUE obj, ID id, int priv)
Definition: vm_method.c:2180
rb_resolve_refined_method
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
Definition: vm_method.c:972
VM_ASSERT
#define VM_ASSERT(expr)
Definition: vm_core.h:56
rb_imemo_new
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:2308
VM_METHOD_TYPE_UNDEF
@ VM_METHOD_TYPE_UNDEF
Definition: method.h:109
cache_entry::me
rb_method_entry_t * me
Definition: vm_method.c:44
rb_method_definition_struct::complemented_count
int complemented_count
Definition: method.h:166
cache_entry::mid
ID mid
Definition: vm_method.c:43
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
RCLASS_ORIGIN
#define RCLASS_ORIGIN(c)
Definition: internal.h:1075
rb_method_definition_struct::cfunc
rb_method_cfunc_t cfunc
Definition: method.h:170
rb_notimplement
void rb_notimplement(void)
Definition: error.c:2712
rb_execution_context_struct::cfp
rb_control_frame_t * cfp
Definition: vm_core.h:847
id__send__
@ id__send__
Definition: rb_mjit_min_header-2.7.1.h:8634
rb_callable_method_entry_struct::called_id
ID called_id
Definition: method.h:63
if
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:357
RMODULE_IS_REFINEMENT
@ RMODULE_IS_REFINEMENT
Definition: ruby.h:956
rb_method_definition_struct::body
union rb_method_definition_struct::@118 body
rb_method_entry_location
VALUE rb_method_entry_location(const rb_method_entry_t *me)
Definition: proc.c:2713
rb_undef_alloc_func
void rb_undef_alloc_func(VALUE klass)
Definition: vm_method.c:722
rb_obj_info
const MJIT_FUNC_EXPORTED char * rb_obj_info(VALUE obj)
Definition: gc.c:11674
T_ICLASS
#define T_ICLASS
Definition: ruby.h:525
rb_scope_visi_struct::module_func
unsigned int module_func
Definition: method.h:37
rb_iseq_constant_body::param
struct rb_iseq_constant_body::@178 param
parameter information
rb_method_attr_struct::location
VALUE location
Definition: method.h:139
rb_cref_struct::scope_visi
const rb_scope_visibility_t scope_visi
Definition: method.h:46
undefined
#define undefined
Definition: vm_method.c:36
rb_cBasicObject
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:2009
RCLASS_M_TBL
#define RCLASS_M_TBL(c)
Definition: internal.h:1069
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_callable_method_entry_struct::defined_class
const VALUE defined_class
Definition: method.h:61
rb_method_definition_struct::alias
rb_method_alias_t alias
Definition: method.h:172
rb_method_entry_complement_defined_class
const MJIT_FUNC_EXPORTED rb_callable_method_entry_t * rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
Definition: vm_method.c:415
cfp
rb_control_frame_t * cfp
Definition: rb_mjit_min_header-2.7.1.h:14481
METHOD_ENTRY_VISI
#define METHOD_ENTRY_VISI(me)
Definition: method.h:67
cache_entry
Definition: vm_method.c:40
rb_frame_this_func
ID rb_frame_this_func(void)
The original name of the current method.
Definition: eval.c:1183
cbase
VALUE cbase
Definition: rb_mjit_min_header-2.7.1.h:16070
rb_remove_method_id
void rb_remove_method_id(VALUE klass, ID mid)
Definition: vm_method.c:1026
rb_attr
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
Definition: vm_method.c:1163
rb_serial_t
unsigned long rb_serial_t
Definition: internal.h:1014
rb_vm_top_self
VALUE rb_vm_top_self(void)
Definition: vm.c:3347
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1509
rb_clear_constant_cache
void rb_clear_constant_cache(void)
Definition: vm_method.c:87
Init_eval_method
void Init_eval_method(void)
Definition: vm_method.c:2281
rb_compile_warning
void rb_compile_warning(const char *file, int line, const char *fmt,...)
Definition: error.c:285
mask
enum @11::@13::@14 mask
VM_METHOD_TYPE_CFUNC
@ VM_METHOD_TYPE_CFUNC
C method.
Definition: method.h:103
rb_to_id
ID rb_to_id(VALUE)
Definition: string.c:11146
rb_method_entry_at
const rb_method_entry_t * rb_method_entry_at(VALUE klass, ID id)
Definition: vm_method.c:756
rb_method_entry_without_refinements
const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:925
rb_method_cfunc_struct::func
VALUE(* func)(ANYARGS)
Definition: method.h:132
VM_METHOD_TYPE_NOTIMPLEMENTED
@ VM_METHOD_TYPE_NOTIMPLEMENTED
Definition: method.h:110
rb_cref_struct
CREF (Class REFerence)
Definition: method.h:41
RCLASS_SERIAL
#define RCLASS_SERIAL(c)
Definition: internal.h:1078
st_index_t
st_data_t st_index_t
Definition: st.h:50
METHOD_VISI_UNDEF
@ METHOD_VISI_UNDEF
Definition: method.h:27
VM_METHOD_TYPE_BMETHOD
@ VM_METHOD_TYPE_BMETHOD
Definition: method.h:106
rb_method_entry_create
rb_method_entry_t * rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def)
Definition: vm_method.c:397
METHOD_ENTRY_BASIC
#define METHOD_ENTRY_BASIC(me)
Definition: method.h:68
rb_method_definition_struct::iseq
rb_method_iseq_t iseq
Definition: method.h:169
RCLASS_CALLABLE_M_TBL
#define RCLASS_CALLABLE_M_TBL(c)
Definition: internal.h:1073
rb_iseq_constant_body::type
enum rb_iseq_constant_body::iseq_type type
rb_call_data::cc
struct rb_call_cache cc
Definition: internal.h:2399
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
GET_GLOBAL_METHOD_STATE
#define GET_GLOBAL_METHOD_STATE()
Definition: vm_insnhelper.h:189
idMethodMissing
@ idMethodMissing
Definition: rb_mjit_min_header-2.7.1.h:8619
rb_call_info::mid
ID mid
Definition: internal.h:2394
T_CLASS
#define T_CLASS
Definition: ruby.h:524
rb_method_alias_struct::original_me
struct rb_method_entry_struct * original_me
Definition: method.h:143
METHOD_DEBUG
#define METHOD_DEBUG
Definition: vm_method.c:7
METHOD_VISI_PROTECTED
@ METHOD_VISI_PROTECTED
Definition: method.h:30
mod
#define mod(x, y)
Definition: date_strftime.c:28
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
rb_control_frame_struct
Definition: vm_core.h:760
marker
const VALUE VALUE VALUE marker
Definition: rb_mjit_min_header-2.7.1.h:5703
size
int size
Definition: encoding.c:58
FALSE
#define FALSE
Definition: nkf.h:174
RCLASS_SUPER
#define RCLASS_SUPER(c)
Definition: classext.h:16
write
_ssize_t write(int __fd, const void *__buf, size_t __nbyte)
cache_entry::defined_class
VALUE defined_class
Definition: vm_method.c:45
VM_METHOD_TYPE_ZSUPER
@ VM_METHOD_TYPE_ZSUPER
Definition: method.h:107
METHOD_VISI_PUBLIC
@ METHOD_VISI_PUBLIC
Definition: method.h:28
rb_gc_writebarrier_remember
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6877
rb_iseq_constant_body::flags
struct rb_iseq_constant_body::@178::@180 flags
rb_class2name
const char * rb_class2name(VALUE)
Definition: variable.c:280
rb_method_refined_struct
Definition: method.h:146
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1508
rb_method_entry
const MJIT_FUNC_EXPORTED rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
Definition: vm_method.c:837
OPT_GLOBAL_METHOD_CACHE
#define OPT_GLOBAL_METHOD_CACHE
Definition: vm_opts.h:50
atoi
int atoi(const char *__nptr)
path
VALUE path
Definition: rb_mjit_min_header-2.7.1.h:7300
rb_vm_call_kw
VALUE rb_vm_call_kw(rb_execution_context_t *ec, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me, int kw_splat)
Definition: vm_eval.c:265
RCLASS_EXT
#define RCLASS_EXT(c)
Definition: classext.h:15
rb_frame_callee
ID rb_frame_callee(void)
The name of the current method.
Definition: eval.c:1200
QUOTE_ID
#define QUOTE_ID(id)
Definition: internal.h:2148
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
T_MODULE
#define T_MODULE
Definition: ruby.h:526
rb_define_alloc_func
void rb_define_alloc_func(VALUE klass, VALUE(*func)(VALUE))
Definition: vm_method.c:715
rb_alias
void rb_alias(VALUE klass, ID alias_name, ID original_name)
Definition: vm_method.c:1581
imemo_ment
@ imemo_ment
Definition: internal.h:1139
rb_method_bmethod_struct::hooks
struct rb_hook_list_struct * hooks
Definition: method.h:153
rb_scan_args
#define rb_scan_args(argc, argvp, fmt,...)
Definition: rb_mjit_min_header-2.7.1.h:6333
CALL_METHOD_HOOK
#define CALL_METHOD_HOOK(klass, hook, mid)
Definition: vm_method.c:654
rb_method_type_t
rb_method_type_t
Definition: method.h:101
rb_method_refined_struct::owner
VALUE owner
Definition: method.h:148
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
mjit_remove_class_serial
void mjit_remove_class_serial(rb_serial_t class_serial)
VM_METHOD_TYPE_MISSING
@ VM_METHOD_TYPE_MISSING
wrapper for method_missing(id)
Definition: method.h:112
rb_method_cfunc_struct::argc
int argc
Definition: method.h:134
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
rb_mKernel
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1998
argv
char ** argv
Definition: ruby.c:223
rb_method_basic_definition_p_with_cc
bool rb_method_basic_definition_p_with_cc(struct rb_call_data *cd, VALUE klass, ID mid)
Definition: vm_method.c:2057
idInitialize_clone
@ idInitialize_clone
Definition: rb_mjit_min_header-2.7.1.h:8638
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: intern.h:815
rb_vm_get_ruby_level_next_cfp
MJIT_FUNC_EXPORTED rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
Definition: vm.c:553
VM_METHOD_TYPE_ATTRSET
@ VM_METHOD_TYPE_ATTRSET
attr_writer or attr_accessor
Definition: method.h:104
ANYARGS
#define ANYARGS
Definition: defines.h:201
rb_method_entry_struct::defined_class
VALUE defined_class
Definition: method.h:53
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
rb_next_class_serial
rb_serial_t rb_next_class_serial(void)
Definition: vm.c:358
rb_add_method_iseq
MJIT_FUNC_EXPORTED void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
Definition: vm_method.c:684
rb_captured_block::iseq
const rb_iseq_t * iseq
Definition: vm_core.h:731
rb_subclass_entry::klass
VALUE klass
Definition: internal.h:999
rb_print_undef_str
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:394
rb_class_foreach_subclass
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
Definition: class.c:113
BOUND_RESPONDS
#define BOUND_RESPONDS
Definition: vm_method.c:1099
rb_method_entry_set
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi)
Definition: vm_method.c:707
rb_control_frame_struct::iseq
const rb_iseq_t * iseq
Definition: vm_core.h:763
rb_captured_block::code
union rb_captured_block::@186 code
rb_captured_block
Definition: vm_core.h:727
idInitialize_dup
@ idInitialize_dup
Definition: rb_mjit_min_header-2.7.1.h:8639
read
_ssize_t read(int __fd, void *__buf, size_t __nbyte)
cache_entry::method_state
rb_serial_t method_state
Definition: vm_method.c:41
INC_GLOBAL_CONSTANT_STATE
#define INC_GLOBAL_CONSTANT_STATE()
Definition: vm_insnhelper.h:192
rb_alloc_func_t
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:427
removed
#define removed
Definition: vm_method.c:34
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_id_table_create
struct rb_id_table * rb_id_table_create(size_t capa)
Definition: id_table.c:95
rb_method_entry_struct::called_id
ID called_id
Definition: method.h:55
argc
int argc
Definition: ruby.c:222
VM_METHOD_TYPE_ISEQ
@ VM_METHOD_TYPE_ISEQ
Ruby method.
Definition: method.h:102
rb_singleton_class
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1725
RB_NO_KEYWORDS
#define RB_NO_KEYWORDS
Definition: ruby.h:1977
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
rb_clear_method_cache_by_class
void rb_clear_method_cache_by_class(VALUE klass)
Definition: vm_method.c:93
rb_eException
VALUE rb_eException
Definition: error.c:914
xfree
#define xfree
Definition: defines.h:216
rb_ary_freeze
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:648
rb_method_definition_struct::original_id
ID original_id
Definition: method.h:179
rb_call_data::ci
struct rb_call_info ci
Definition: internal.h:2400
RUBY_DTRACE_HOOK
#define RUBY_DTRACE_HOOK(name, arg)
Definition: internal.h:2591
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12257
rb_proc_get_iseq
const rb_iseq_t * rb_proc_get_iseq(VALUE proc, int *is_proc)
Definition: proc.c:1194
rb_method_definition_struct
Definition: method.h:163
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: defines.h:396
_
#define _(args)
Definition: dln.h:28
rb_compile_warn
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:270
rb_callable_method_entry_struct::def
struct rb_method_definition_struct *const def
Definition: method.h:62
Qtrue
#define Qtrue
Definition: ruby.h:468
Init_Method
void Init_Method(void)
Definition: vm_method.c:2257
rb_scope_visi_struct
Definition: method.h:35
exit
void exit(int __status) __attribute__((__noreturn__))
UNDEF_ALLOC_FUNC
#define UNDEF_ALLOC_FUNC
Definition: vm_method.c:712
RB_DEBUG_COUNTER_INC
#define RB_DEBUG_COUNTER_INC(type)
Definition: debug_counter.h:375
method_optimized_type
method_optimized_type
Definition: method.h:156
rb_method_entry_struct
Definition: method.h:51
rb_iseq_struct::body
struct rb_iseq_constant_body * body
Definition: vm_core.h:460
rb_subclass_entry
Definition: internal.h:998
rb_hash_proc
st_index_t rb_hash_proc(st_index_t hash, VALUE proc)
Definition: proc.c:1302
UNDEFINED_REFINED_METHOD_P
#define UNDEFINED_REFINED_METHOD_P(def)
Definition: method.h:187
rb_intern_str
#define rb_intern_str(string)
Definition: generator.h:16
rb_remove_method
void rb_remove_method(VALUE klass, const char *name)
Definition: vm_method.c:1032
rb_method_definition_create
MJIT_FUNC_EXPORTED rb_method_definition_t * rb_method_definition_create(rb_method_type_t type, ID mid)
Definition: vm_method.c:348
FL_SINGLETON
#define FL_SINGLETON
Definition: ruby.h:1278
idInitialize_copy
@ idInitialize_copy
Definition: rb_mjit_min_header-2.7.1.h:8637
idRespond_to
@ idRespond_to
Definition: id.h:116
stderr
#define stderr
Definition: rb_mjit_min_header-2.7.1.h:1479
rb_method_definition_set
MJIT_FUNC_EXPORTED void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
Definition: vm_method.c:232
rb_callable_method_entry_without_refinements
const MJIT_FUNC_EXPORTED rb_callable_method_entry_t * rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:931
rb_method_entry_eq
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
Definition: vm_method.c:1476
rb_method_cfunc_struct
Definition: method.h:131
rb_get_alloc_func
rb_alloc_func_t rb_get_alloc_func(VALUE klass)
Definition: vm_method.c:728
rb_method_entry_copy
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
Definition: vm_method.c:451
rb_vm_get_sourceline
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
Definition: vm_backtrace.c:68
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
rb_id_table_delete
int rb_id_table_delete(struct rb_id_table *tbl, ID id)
Definition: id_table.c:262
rb_add_refined_method_entry
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
Definition: vm_method.c:491
rb_f_notimplement
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj, VALUE marker)
Definition: vm_method.c:120
rb_id_table_lookup
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
Definition: id_table.c:226
rb_scope_visibility_set
void rb_scope_visibility_set(rb_method_visibility_t visi)
Definition: vm_method.c:1138
rb_name_err_raise
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1576
UNALIGNED_MEMBER_PTR
#define UNALIGNED_MEMBER_PTR(ptr, mem)
Definition: internal.h:2690
UNREACHABLE_RETURN
#define UNREACHABLE_RETURN(val)
Definition: ruby.h:59
rb_call_data
Definition: internal.h:2398
rb_define_private_method
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1569
calloc
void * calloc(size_t, size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1
METHOD_ENTRY_COMPLEMENTED
#define METHOD_ENTRY_COMPLEMENTED(me)
Definition: method.h:69
rb_resolve_refined_method_callable
const MJIT_FUNC_EXPORTED rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
Definition: vm_method.c:979
id_table.h
VM_DEBUG_VERIFY_METHOD_CACHE
#define VM_DEBUG_VERIFY_METHOD_CACHE
Definition: vm_core.h:724
rb_method_entry_clone
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
Definition: vm_method.c:406
RTEST
#define RTEST(v)
Definition: ruby.h:481
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
object_id
#define object_id
Definition: vm_method.c:31
rb_id_table_clear
void rb_id_table_clear(struct rb_id_table *tbl)
Definition: id_table.c:109
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
VM_METHOD_TYPE_ALIAS
@ VM_METHOD_TYPE_ALIAS
Definition: method.h:108
d1
#define d1
UNDEFINED_METHOD_ENTRY_P
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:186
rb_method_boundp
int rb_method_boundp(VALUE klass, ID id, int ex)
Definition: vm_method.c:1102
src
__inline__ const void *__restrict src
Definition: rb_mjit_min_header-2.7.1.h:2804
name
const char * name
Definition: nkf.c:208
rb_execution_context_struct
Definition: vm_core.h:843