Ruby  2.4.2p198(2017-09-14revision59899)
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
64 {
66 
67  if (RB_TYPE_P(klass, T_ICLASS)) {
68  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(klass);
69  if (table) {
70  rb_id_table_clear(table);
71  }
72  }
73  else {
74  if (RCLASS_CALLABLE_M_TBL(klass) != 0) {
75  rb_obj_info_dump(klass);
76  rb_bug("RCLASS_CALLABLE_M_TBL(klass) != 0");
77  }
78  }
79 
81 }
82 
83 void
85 {
86  ONLY_FOR_INTERNAL_USE("rb_clear_cache()");
87 }
88 
89 void
91 {
93 }
94 
95 void
97 {
98  if (klass && klass != Qundef) {
99  int global = klass == rb_cBasicObject || klass == rb_cObject || klass == rb_mKernel;
100 
101  RUBY_DTRACE_HOOK(METHOD_CACHE_CLEAR, (global ? "global" : rb_class2name(klass)));
102 
103  if (global) {
105  }
106  else {
108  }
109  }
110 
111  if (klass == rb_mKernel) {
112  rb_subclass_entry_t *entry = RCLASS_EXT(klass)->subclasses;
113 
114  for (; entry != NULL; entry = entry->next) {
115  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(entry->klass);
116  if (table)rb_id_table_clear(table);
117  }
118  }
119 }
120 
121 VALUE
123 {
124  rb_notimplement();
125 
126  UNREACHABLE;
127 }
128 
129 static void
131 {
132  rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, visi);
133 }
134 
135 void
137 {
138  if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
139  if (func != rb_f_notimplement) {
140  rb_method_cfunc_t opt;
141  opt.func = func;
142  opt.argc = argc;
143  rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, visi);
144  }
145  else {
146  rb_define_notimplement_method_id(klass, mid, visi);
147  }
148 }
149 
150 static void
152 {
153  if (def != NULL) {
154  const int alias_count = def->alias_count;
155  const int complemented_count = def->complemented_count;
156  VM_ASSERT(alias_count >= 0);
157  VM_ASSERT(complemented_count >= 0);
158 
159  if (alias_count + complemented_count == 0) {
160  if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d,%d (remove)\n", def, rb_id2name(def->original_id), alias_count, complemented_count);
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", def, rb_id2name(def->original_id),
168  alias_count, def->alias_count, complemented_count, def->complemented_count);
169  }
170  }
171 }
172 
173 void
175 {
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 *
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 (*func)(ANYARGS), VALUE recv, int argc, const VALUE *)
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
225 {
226  cfunc->func = func;
227  cfunc->argc = argc;
228  cfunc->invoker = call_cfunc_invoker_func(argc);
229 }
230 
231 static void
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_THREAD()); /* 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(&def->body.cfunc, cfunc->func, cfunc->argc);
262  return;
263  }
265  case VM_METHOD_TYPE_IVAR:
266  {
267  rb_thread_t *th = GET_THREAD();
268  rb_control_frame_t *cfp;
269  int line;
270 
271  def->body.attr.id = (ID)(VALUE)opts;
272 
273  cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
274 
275  if (cfp && (line = rb_vm_get_sourceline(cfp))) {
276  VALUE location = rb_ary_new3(2, cfp->iseq->body->location.path, 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.proc, (VALUE)opts);
286  return;
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
313 {
314  rb_method_definition_t *def = me->def;
315 
316  switch(def->type) {
317  case VM_METHOD_TYPE_ISEQ:
319  RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.cref);
320  break;
322  case VM_METHOD_TYPE_IVAR:
324  break;
326  RB_OBJ_WRITTEN(me, Qundef, def->body.proc);
327  break;
331  break;
334  break;
341  break;
342  }
343 }
344 
345 static rb_method_definition_t *
347 {
350  def->type = type;
351  def->original_id = mid;
352  return def;
353 }
354 
355 static rb_method_definition_t *
357 {
358  def->alias_count++;
359  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", def, rb_id2name(def->original_id), def->alias_count);
360  return def;
361 }
362 
363 static rb_method_definition_t *
365 {
366  def->complemented_count++;
367  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", def, rb_id2name(def->original_id), def->alias_count);
368  return def;
369 }
370 
371 static rb_method_entry_t *
373 {
374  rb_method_entry_t *me = (rb_method_entry_t *)rb_imemo_new(imemo_ment, (VALUE)def, (VALUE)called_id, owner, defined_class);
375  return me;
376 }
377 
378 static VALUE
380 {
381  switch (BUILTIN_TYPE(klass)) {
382  case T_CLASS:
383  return klass;
384  case T_MODULE:
385  return 0;
386  case T_ICLASS:
387  break;
388  }
389  rb_bug("filter_defined_class: %s", rb_obj_info(klass));
390 }
391 
394 {
395  rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def);
397  if (def != NULL) method_definition_reset(me);
398  return me;
399 }
400 
401 const rb_method_entry_t *
403 {
405  method_definition_addref(src_me->def));
406  METHOD_ENTRY_FLAGS_COPY(me, src_me);
407  return me;
408 }
409 
412 {
413  rb_method_entry_t *me = rb_method_entry_alloc(called_id, src_me->owner, defined_class,
415  METHOD_ENTRY_FLAGS_COPY(me, src_me);
417 
419 
420  return (rb_callable_method_entry_t *)me;
421 }
422 
423 void
425 {
428  dst->called_id = src->called_id;
429  RB_OBJ_WRITE((VALUE)dst, &dst->owner, src->owner);
430  RB_OBJ_WRITE((VALUE)dst, &dst->defined_class, src->defined_class);
431  METHOD_ENTRY_FLAGS_COPY(dst, src);
432 }
433 
434 static void
436 {
437  if (me->def->type == VM_METHOD_TYPE_REFINED) {
438  return;
439  }
440  else {
441  struct {
442  struct rb_method_entry_struct *orig_me;
443  VALUE owner;
444  } refined;
445 
447 
448  refined.orig_me =
450  me->defined_class ?
451  me->defined_class : owner,
453  METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me);
454  refined.owner = owner;
455 
458  }
459 }
460 
461 void
463 {
464  rb_method_entry_t *me = lookup_method_table(refined_class, mid);
465 
466  if (me) {
467  make_method_entry_refined(refined_class, me);
468  rb_clear_method_cache_by_class(refined_class);
469  }
470  else {
472  }
473 }
474 
475 static void
477 {
478  ID mid = (ID)arg;
479  const rb_method_entry_t *me, *newme;
480 
481  if (vm_redefinition_check_flag(klass)) {
482  me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
483  if (me) {
484  newme = rb_method_entry(klass, mid);
485  if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
486  }
487  }
489 }
490 
491 /*
492  * klass->method_table[mid] = method_entry(defined_class, visi, def)
493  *
494  * If def is given (!= NULL), then just use it and ignore original_id and otps.
495  * If not given, then make a new def with original_id and opts.
496  */
497 static rb_method_entry_t *
499  rb_method_type_t type, rb_method_definition_t *def, ID original_id, void *opts)
500 {
502  struct rb_id_table *mtbl;
503  st_data_t data;
504  int make_refined = 0;
505 
506  if (NIL_P(klass)) {
507  klass = rb_cObject;
508  }
509  if (!FL_TEST(klass, FL_SINGLETON) &&
511  type != VM_METHOD_TYPE_ZSUPER) {
512  switch (mid) {
513  case idInitialize:
514  case idInitialize_copy:
515  case idInitialize_clone:
516  case idInitialize_dup:
518  visi = METHOD_VISI_PRIVATE;
519  }
520  }
521 
522  rb_frozen_class_p(klass);
523 
524  if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
525  VALUE refined_class = rb_refinement_module_get_refined_class(klass);
526  rb_add_refined_method_entry(refined_class, mid);
527  }
528  if (type == VM_METHOD_TYPE_REFINED) {
529  rb_method_entry_t *old_me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
530  if (old_me) rb_vm_check_redefinition_opt_method(old_me, klass);
531  }
532  else {
533  klass = RCLASS_ORIGIN(klass);
534  }
535  mtbl = RCLASS_M_TBL(klass);
536 
537  /* check re-definition */
538  if (rb_id_table_lookup(mtbl, mid, &data)) {
539  rb_method_entry_t *old_me = (rb_method_entry_t *)data;
540  rb_method_definition_t *old_def = old_me->def;
541 
542  if (rb_method_definition_eq(old_def, def)) return old_me;
544 
545  if (old_def->type == VM_METHOD_TYPE_REFINED) make_refined = 1;
546 
547  if (RTEST(ruby_verbose) &&
548  type != VM_METHOD_TYPE_UNDEF &&
549  (old_def->alias_count == 0) &&
550  !make_refined &&
551  old_def->type != VM_METHOD_TYPE_UNDEF &&
552  old_def->type != VM_METHOD_TYPE_ZSUPER &&
553  old_def->type != VM_METHOD_TYPE_ALIAS) {
554  const rb_iseq_t *iseq = 0;
555 
556  rb_warning("method redefined; discarding old %"PRIsVALUE, rb_id2str(mid));
557  switch (old_def->type) {
558  case VM_METHOD_TYPE_ISEQ:
559  iseq = def_iseq_ptr(old_def);
560  break;
562  iseq = rb_proc_get_iseq(old_def->body.proc, 0);
563  break;
564  default:
565  break;
566  }
567  if (iseq) {
570  "previous definition of %"PRIsVALUE" was here",
571  rb_id2str(old_def->original_id));
572  }
573  }
574  }
575 
576  /* create method entry */
577  me = rb_method_entry_create(mid, defined_class, visi, NULL);
578  if (def == NULL) def = method_definition_create(type, original_id);
579  method_definition_set(me, def, opts);
580 
582 
583  /* check mid */
584  if (klass == rb_cObject && mid == idInitialize) {
585  rb_warn("redefining Object#initialize may cause infinite loop");
586  }
587  /* check mid */
588  if (mid == object_id || mid == id__send__) {
589  if (type == VM_METHOD_TYPE_ISEQ && search_method(klass, mid, 0)) {
590  rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
591  }
592  }
593 
594  if (make_refined) {
595  make_method_entry_refined(klass, me);
596  }
597 
598  rb_id_table_insert(mtbl, mid, (VALUE)me);
599  RB_OBJ_WRITTEN(klass, Qundef, (VALUE)me);
600 
601  VM_ASSERT(me->def != NULL);
602 
603  /* check optimized method override by a prepended module */
604  if (RB_TYPE_P(klass, T_MODULE)) {
605  check_override_opt_method(klass, (VALUE)mid);
606  }
607 
608  return me;
609 }
610 
611 #define CALL_METHOD_HOOK(klass, hook, mid) do { \
612  const VALUE arg = ID2SYM(mid); \
613  VALUE recv_class = (klass); \
614  ID hook_id = (hook); \
615  if (FL_TEST((klass), FL_SINGLETON)) { \
616  recv_class = rb_ivar_get((klass), attached); \
617  hook_id = singleton_##hook; \
618  } \
619  rb_funcallv(recv_class, hook_id, 1, &arg); \
620  } while (0)
621 
622 static void
623 method_added(VALUE klass, ID mid)
624 {
625  if (ruby_running) {
626  CALL_METHOD_HOOK(klass, added, mid);
627  }
628 }
629 
631 rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
632 {
633  rb_method_entry_t *me = rb_method_entry_make(klass, mid, klass, visi, type, NULL, mid, opts);
634 
635  if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
636  method_added(klass, mid);
637  }
638 
639  return me;
640 }
641 
642 void
644 {
645  struct { /* should be same fields with rb_method_iseq_struct */
646  const rb_iseq_t *iseqptr;
647  rb_cref_t *cref;
648  } iseq_body;
649 
650  iseq_body.iseqptr = iseq;
651  iseq_body.cref = cref;
652  rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
653 }
654 
655 static rb_method_entry_t *
658 {
659  rb_method_entry_t *newme = rb_method_entry_make(klass, mid, defined_class, visi,
660  me->def->type, method_definition_addref(me->def), 0, NULL);
661  method_added(klass, mid);
662  return newme;
663 }
664 
667 {
668  return method_entry_set(klass, mid, me, visi, klass);
669 }
670 
671 #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1)
672 
673 void
675 {
676  Check_Type(klass, T_CLASS);
677  RCLASS_EXT(klass)->allocator = func;
678 }
679 
680 void
682 {
684 }
685 
688 {
689  Check_Type(klass, T_CLASS);
690 
691  for (; klass; klass = RCLASS_SUPER(klass)) {
692  rb_alloc_func_t allocator = RCLASS_EXT(klass)->allocator;
693  if (allocator == UNDEF_ALLOC_FUNC) break;
694  if (allocator) return allocator;
695  }
696  return 0;
697 }
698 
699 static inline rb_method_entry_t*
700 search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
701 {
703 
704  for (me = 0; klass; klass = RCLASS_SUPER(klass)) {
705  if ((me = lookup_method_table(klass, id)) != 0) break;
706  }
707 
708  if (defined_class_ptr)
709  *defined_class_ptr = klass;
710  return me;
711 }
712 
713 const rb_method_entry_t *
715 {
716  return lookup_method_table(klass, id);
717 }
718 
719 /*
720  * search method entry without the method cache.
721  *
722  * if you need method entry with method cache (normal case), use
723  * rb_method_entry() simply.
724  */
725 static rb_method_entry_t *
727  VALUE *defined_class_ptr)
728 {
730  rb_method_entry_t *me = search_method(klass, id, &defined_class);
731 
732  if (ruby_running) {
734  struct cache_entry *ent;
735  ent = GLOBAL_METHOD_CACHE(klass, id);
736  ent->class_serial = RCLASS_SERIAL(klass);
739  ent->mid = id;
740 
741  if (UNDEFINED_METHOD_ENTRY_P(me)) {
742  me = ent->me = NULL;
743  }
744  else {
745  ent->me = me;
746  }
747  }
748  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
749  me = NULL;
750  }
751  }
752  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
753  me = NULL;
754  }
755 
756  if (defined_class_ptr)
757  *defined_class_ptr = defined_class;
758  return me;
759 }
760 
761 #if VM_DEBUG_VERIFY_METHOD_CACHE
762 static void
763 verify_method_cache(VALUE klass, ID id, VALUE defined_class, rb_method_entry_t *me)
764 {
765  VALUE actual_defined_class;
766  rb_method_entry_t *actual_me =
767  method_entry_get_without_cache(klass, id, &actual_defined_class);
768 
769  if (me != actual_me || defined_class != actual_defined_class) {
770  rb_bug("method cache verification failed");
771  }
772 }
773 #endif
774 
775 static rb_method_entry_t *
776 method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
777 {
778 #if OPT_GLOBAL_METHOD_CACHE
779  struct cache_entry *ent;
780  ent = GLOBAL_METHOD_CACHE(klass, id);
781  if (ent->method_state == GET_GLOBAL_METHOD_STATE() &&
782  ent->class_serial == RCLASS_SERIAL(klass) &&
783  ent->mid == id) {
784 #if VM_DEBUG_VERIFY_METHOD_CACHE
785  verify_method_cache(klass, id, ent->defined_class, ent->me);
786 #endif
787  if (defined_class_ptr) *defined_class_ptr = ent->defined_class;
788  return ent->me;
789  }
790 #endif
791 
792  return method_entry_get_without_cache(klass, id, defined_class_ptr);
793 }
794 
795 const rb_method_entry_t *
797 {
798  return method_entry_get(klass, id, NULL);
799 }
800 
801 static const rb_callable_method_entry_t *
803 {
804  struct rb_id_table *mtbl;
805  const rb_callable_method_entry_t *cme;
806 
807  if (me && me->defined_class == 0) {
808  VM_ASSERT(RB_TYPE_P(defined_class, T_ICLASS) || RB_TYPE_P(defined_class, T_MODULE));
809  VM_ASSERT(me->defined_class == 0);
810 
811  if ((mtbl = RCLASS_CALLABLE_M_TBL(defined_class)) == NULL) {
812  mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
813  }
814 
815  if (rb_id_table_lookup(mtbl, id, (VALUE *)&me)) {
816  cme = (rb_callable_method_entry_t *)me;
817  VM_ASSERT(callable_method_entry_p(cme));
818  }
819  else {
820  cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
821  rb_id_table_insert(mtbl, id, (VALUE)cme);
822  VM_ASSERT(callable_method_entry_p(cme));
823  }
824  }
825  else {
826  cme = (const rb_callable_method_entry_t *)me;
827  VM_ASSERT(callable_method_entry_p(cme));
828  }
829 
830  return cme;
831 }
832 
835 {
837  rb_method_entry_t *me = method_entry_get(klass, id, &defined_class);
838  return prepare_callable_method_entry(defined_class, id, me);
839 }
840 
841 static const rb_method_entry_t *resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr);
842 
843 static const rb_method_entry_t *
844 method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *defined_class_ptr)
845 {
846  const rb_method_entry_t *me = method_entry_get(klass, id, defined_class_ptr);
847 
848  if (me) {
849  if (me->def->type == VM_METHOD_TYPE_REFINED) {
850  if (with_refinement) {
851  const rb_cref_t *cref = rb_vm_cref();
852  VALUE refinements = cref ? CREF_REFINEMENTS(cref) : Qnil;
853  me = resolve_refined_method(refinements, me, defined_class_ptr);
854  }
855  else {
856  me = resolve_refined_method(Qnil, me, defined_class_ptr);
857  }
858 
859  if (UNDEFINED_METHOD_ENTRY_P(me)) me = NULL;
860  }
861  }
862 
863  return me;
864 }
865 
866 const rb_method_entry_t *
868 {
869  return method_entry_resolve_refinement(klass, id, TRUE, NULL);
870 }
871 
874 {
876  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, TRUE, &defined_class);
877  return prepare_callable_method_entry(defined_class, id, me);
878 }
879 
880 const rb_method_entry_t *
882 {
883  return method_entry_resolve_refinement(klass, id, FALSE, NULL);
884 }
885 
888 {
890  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, FALSE, &defined_class);
891  return prepare_callable_method_entry(defined_class, id, me);
892 }
893 
894 static const rb_method_entry_t *
895 refined_method_original_method_entry(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
896 {
897  VALUE super;
898 
899  if (me->def->body.refined.orig_me) {
900  if (defined_class_ptr) *defined_class_ptr = me->def->body.refined.orig_me->defined_class;
901  return me->def->body.refined.orig_me;
902  }
903  else if (!(super = RCLASS_SUPER(me->owner))) {
904  return 0;
905  }
906  else {
907  rb_method_entry_t *tmp_me;
908  tmp_me = method_entry_get(super, me->called_id, defined_class_ptr);
909  return resolve_refined_method(refinements, tmp_me, defined_class_ptr);
910  }
911 }
912 
913 static const rb_method_entry_t *
914 resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
915 {
916  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
917  VALUE refinement;
918  rb_method_entry_t *tmp_me;
919 
920  refinement = find_refinement(refinements, me->owner);
921  if (NIL_P(refinement)) {
922  return refined_method_original_method_entry(refinements, me, defined_class_ptr);
923  }
924  else {
925  tmp_me = method_entry_get(refinement, me->called_id, defined_class_ptr);
926 
927  if (tmp_me && tmp_me->def->type != VM_METHOD_TYPE_REFINED) {
928  return tmp_me;
929  }
930  else {
931  return refined_method_original_method_entry(refinements, me, defined_class_ptr);
932  }
933  }
934  }
935  else {
936  return me;
937  }
938 }
939 
940 const rb_method_entry_t *
942 {
943  return resolve_refined_method(refinements, me, NULL);
944 }
945 
948 {
949  VALUE defined_class = me->defined_class;
950  const rb_method_entry_t *resolved_me = resolve_refined_method(refinements, (const rb_method_entry_t *)me, &defined_class);
951 
952  if (resolved_me && resolved_me->defined_class == 0) {
953  return rb_method_entry_complement_defined_class(resolved_me, me->called_id, defined_class);
954  }
955  else {
956  return (const rb_callable_method_entry_t *)resolved_me;
957  }
958 }
959 
960 static void
961 remove_method(VALUE klass, ID mid)
962 {
963  VALUE data;
964  rb_method_entry_t *me = 0;
965  VALUE self = klass;
966 
967  klass = RCLASS_ORIGIN(klass);
968  rb_frozen_class_p(klass);
969  if (mid == object_id || mid == id__send__ || mid == idInitialize) {
970  rb_warn("removing `%s' may cause serious problems", rb_id2name(mid));
971  }
972 
973  if (!rb_id_table_lookup(RCLASS_M_TBL(klass), mid, &data) ||
974  !(me = (rb_method_entry_t *)data) ||
975  (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
977  rb_name_err_raise("method `%1$s' not defined in %2$s",
978  klass, ID2SYM(mid));
979  }
980 
981  rb_id_table_delete(RCLASS_M_TBL(klass), mid);
982 
985 
986  if (me->def->type == VM_METHOD_TYPE_REFINED) {
987  rb_add_refined_method_entry(klass, mid);
988  }
989 
990  CALL_METHOD_HOOK(self, removed, mid);
991 }
992 
993 void
995 {
996  remove_method(klass, mid);
997 }
998 
999 void
1000 rb_remove_method(VALUE klass, const char *name)
1001 {
1002  remove_method(klass, rb_intern(name));
1003 }
1004 
1005 /*
1006  * call-seq:
1007  * remove_method(symbol) -> self
1008  * remove_method(string) -> self
1009  *
1010  * Removes the method identified by _symbol_ from the current
1011  * class. For an example, see <code>Module.undef_method</code>.
1012  * String arguments are converted to symbols.
1013  */
1014 
1015 static VALUE
1017 {
1018  int i;
1019 
1020  for (i = 0; i < argc; i++) {
1021  VALUE v = argv[i];
1022  ID id = rb_check_id(&v);
1023  if (!id) {
1024  rb_name_err_raise("method `%1$s' not defined in %2$s",
1025  mod, v);
1026  }
1027  remove_method(mod, id);
1028  }
1029  return mod;
1030 }
1031 
1032 static void
1034 {
1037 
1038  me = search_method(klass, name, &defined_class);
1039  if (!me && RB_TYPE_P(klass, T_MODULE)) {
1040  me = search_method(rb_cObject, name, &defined_class);
1041  }
1042 
1043  if (UNDEFINED_METHOD_ENTRY_P(me) ||
1045  rb_print_undef(klass, name, METHOD_VISI_UNDEF);
1046  }
1047 
1048  if (METHOD_ENTRY_VISI(me) != visi) {
1050 
1051  if (klass == defined_class || RCLASS_ORIGIN(klass) == defined_class) {
1052  METHOD_ENTRY_VISI_SET(me, visi);
1053 
1054  if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
1056  }
1058  }
1059  else {
1060  rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, visi);
1061  }
1062  }
1063 }
1064 
1065 #define BOUND_PRIVATE 0x01
1066 #define BOUND_RESPONDS 0x02
1067 
1068 int
1069 rb_method_boundp(VALUE klass, ID id, int ex)
1070 {
1072 
1073  if (me != 0) {
1074  if ((ex & ~BOUND_RESPONDS) &&
1076  ((ex & BOUND_RESPONDS) && (METHOD_ENTRY_VISI(me) == METHOD_VISI_PROTECTED)))) {
1077  return 0;
1078  }
1079 
1080  if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
1081  if (ex & BOUND_RESPONDS) return 2;
1082  return 0;
1083  }
1084  return 1;
1085  }
1086  return 0;
1087 }
1088 
1091 {
1092  rb_thread_t *th = GET_THREAD();
1094 
1095  if (!vm_env_cref_by_cref(cfp->ep)) {
1096  return METHOD_VISI_PUBLIC;
1097  }
1098  else {
1100  }
1101 }
1102 
1103 static int
1105 {
1106  rb_thread_t *th = GET_THREAD();
1108 
1109  if (!vm_env_cref_by_cref(cfp->ep)) {
1110  return FALSE;
1111  }
1112  else {
1114  }
1115 }
1116 
1117 static void
1118 vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
1119 {
1121  scope_visi->method_visi = method_visi;
1122  scope_visi->module_func = module_func;
1123 }
1124 
1125 void
1127 {
1129 }
1130 
1131 static void
1133 {
1135 }
1136 
1137 void
1138 rb_attr(VALUE klass, ID id, int read, int write, int ex)
1139 {
1140  ID attriv;
1142 
1143  if (!ex) {
1144  visi = METHOD_VISI_PUBLIC;
1145  }
1146  else {
1147  switch (rb_scope_visibility_get()) {
1148  case METHOD_VISI_PRIVATE:
1150  rb_warning("attribute accessor as module_function");
1151  }
1152  visi = METHOD_VISI_PRIVATE;
1153  break;
1154  case METHOD_VISI_PROTECTED:
1155  visi = METHOD_VISI_PROTECTED;
1156  break;
1157  default:
1158  visi = METHOD_VISI_PUBLIC;
1159  break;
1160  }
1161  }
1162 
1163  attriv = rb_intern_str(rb_sprintf("@%"PRIsVALUE, rb_id2str(id)));
1164  if (read) {
1165  rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, visi);
1166  }
1167  if (write) {
1168  rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, visi);
1169  }
1170 }
1171 
1172 void
1173 rb_undef(VALUE klass, ID id)
1174 {
1175  const rb_method_entry_t *me;
1176 
1177  if (NIL_P(klass)) {
1178  rb_raise(rb_eTypeError, "no class to undef method");
1179  }
1180  rb_frozen_class_p(klass);
1181  if (id == object_id || id == id__send__ || id == idInitialize) {
1182  rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
1183  }
1184 
1185  me = search_method(klass, id, 0);
1186  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
1187  me = rb_resolve_refined_method(Qnil, me);
1188  }
1189 
1190  if (UNDEFINED_METHOD_ENTRY_P(me) ||
1192  rb_method_name_error(klass, rb_id2str(id));
1193  }
1194 
1196 
1197  CALL_METHOD_HOOK(klass, undefined, id);
1198 }
1199 
1200 /*
1201  * call-seq:
1202  * undef_method(symbol) -> self
1203  * undef_method(string) -> self
1204  *
1205  * Prevents the current class from responding to calls to the named
1206  * method. Contrast this with <code>remove_method</code>, which deletes
1207  * the method from the particular class; Ruby will still search
1208  * superclasses and mixed-in modules for a possible receiver.
1209  * String arguments are converted to symbols.
1210  *
1211  * class Parent
1212  * def hello
1213  * puts "In parent"
1214  * end
1215  * end
1216  * class Child < Parent
1217  * def hello
1218  * puts "In child"
1219  * end
1220  * end
1221  *
1222  *
1223  * c = Child.new
1224  * c.hello
1225  *
1226  *
1227  * class Child
1228  * remove_method :hello # remove from child, still in parent
1229  * end
1230  * c.hello
1231  *
1232  *
1233  * class Child
1234  * undef_method :hello # prevent any calls to 'hello'
1235  * end
1236  * c.hello
1237  *
1238  * <em>produces:</em>
1239  *
1240  * In child
1241  * In parent
1242  * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
1243  */
1244 
1245 static VALUE
1247 {
1248  int i;
1249  for (i = 0; i < argc; i++) {
1250  VALUE v = argv[i];
1251  ID id = rb_check_id(&v);
1252  if (!id) {
1253  rb_method_name_error(mod, v);
1254  }
1255  rb_undef(mod, id);
1256  }
1257  return mod;
1258 }
1259 
1260 /*
1261  * call-seq:
1262  * mod.method_defined?(symbol) -> true or false
1263  * mod.method_defined?(string) -> true or false
1264  *
1265  * Returns +true+ if the named method is defined by
1266  * _mod_ (or its included modules and, if _mod_ is a class,
1267  * its ancestors). Public and protected methods are matched.
1268  * String arguments are converted to symbols.
1269  *
1270  * module A
1271  * def method1() end
1272  * def protected_method1() end
1273  * protected :protected_method1
1274  * end
1275  * class B
1276  * def method2() end
1277  * def private_method2() end
1278  * private :private_method2
1279  * end
1280  * class C < B
1281  * include A
1282  * def method3() end
1283  * end
1284  *
1285  * A.method_defined? :method1 #=> true
1286  * C.method_defined? "method1" #=> true
1287  * C.method_defined? "method2" #=> true
1288  * C.method_defined? "method3" #=> true
1289  * C.method_defined? "protected_method1" #=> true
1290  * C.method_defined? "method4" #=> false
1291  * C.method_defined? "private_method2" #=> false
1292  */
1293 
1294 static VALUE
1296 {
1297  ID id = rb_check_id(&mid);
1298  if (!id || !rb_method_boundp(mod, id, 1)) {
1299  return Qfalse;
1300  }
1301  return Qtrue;
1302 
1303 }
1304 
1305 static VALUE
1307 {
1308  const rb_method_entry_t *me;
1309  ID id = rb_check_id(&mid);
1310  if (!id) return Qfalse;
1312  if (me) {
1313  if (METHOD_ENTRY_VISI(me) == visi) return Qtrue;
1314  }
1315  return Qfalse;
1316 }
1317 
1318 /*
1319  * call-seq:
1320  * mod.public_method_defined?(symbol) -> true or false
1321  * mod.public_method_defined?(string) -> true or false
1322  *
1323  * Returns +true+ if the named public method is defined by
1324  * _mod_ (or its included modules and, if _mod_ is a class,
1325  * its ancestors).
1326  * String arguments are converted to symbols.
1327  *
1328  * module A
1329  * def method1() end
1330  * end
1331  * class B
1332  * protected
1333  * def method2() end
1334  * end
1335  * class C < B
1336  * include A
1337  * def method3() end
1338  * end
1339  *
1340  * A.method_defined? :method1 #=> true
1341  * C.public_method_defined? "method1" #=> true
1342  * C.public_method_defined? "method2" #=> false
1343  * C.method_defined? "method2" #=> true
1344  */
1345 
1346 static VALUE
1348 {
1349  return check_definition(mod, mid, METHOD_VISI_PUBLIC);
1350 }
1351 
1352 /*
1353  * call-seq:
1354  * mod.private_method_defined?(symbol) -> true or false
1355  * mod.private_method_defined?(string) -> true or false
1356  *
1357  * Returns +true+ if the named private method is defined by
1358  * _ mod_ (or its included modules and, if _mod_ is a class,
1359  * its ancestors).
1360  * String arguments are converted to symbols.
1361  *
1362  * module A
1363  * def method1() end
1364  * end
1365  * class B
1366  * private
1367  * def method2() end
1368  * end
1369  * class C < B
1370  * include A
1371  * def method3() end
1372  * end
1373  *
1374  * A.method_defined? :method1 #=> true
1375  * C.private_method_defined? "method1" #=> false
1376  * C.private_method_defined? "method2" #=> true
1377  * C.method_defined? "method2" #=> false
1378  */
1379 
1380 static VALUE
1382 {
1383  return check_definition(mod, mid, METHOD_VISI_PRIVATE);
1384 }
1385 
1386 /*
1387  * call-seq:
1388  * mod.protected_method_defined?(symbol) -> true or false
1389  * mod.protected_method_defined?(string) -> true or false
1390  *
1391  * Returns +true+ if the named protected method is defined
1392  * by _mod_ (or its included modules and, if _mod_ is a
1393  * class, its ancestors).
1394  * String arguments are converted to symbols.
1395  *
1396  * module A
1397  * def method1() end
1398  * end
1399  * class B
1400  * protected
1401  * def method2() end
1402  * end
1403  * class C < B
1404  * include A
1405  * def method3() end
1406  * end
1407  *
1408  * A.method_defined? :method1 #=> true
1409  * C.protected_method_defined? "method1" #=> false
1410  * C.protected_method_defined? "method2" #=> true
1411  * C.method_defined? "method2" #=> true
1412  */
1413 
1414 static VALUE
1416 {
1417  return check_definition(mod, mid, METHOD_VISI_PROTECTED);
1418 }
1419 
1420 int
1422 {
1423  return rb_method_definition_eq(m1->def, m2->def);
1424 }
1425 
1426 static const rb_method_definition_t *
1428 {
1429  again:
1430  if (def) {
1431  switch (def->type) {
1433  if (def->body.refined.orig_me) {
1434  def = def->body.refined.orig_me->def;
1435  goto again;
1436  }
1437  break;
1438  case VM_METHOD_TYPE_ALIAS:
1439  def = def->body.alias.original_me->def;
1440  goto again;
1441  default:
1442  break;
1443  }
1444  }
1445  return def;
1446 }
1447 
1448 static int
1450 {
1451  d1 = original_method_definition(d1);
1452  d2 = original_method_definition(d2);
1453 
1454  if (d1 == d2) return 1;
1455  if (!d1 || !d2) return 0;
1456  if (d1->type != d2->type) return 0;
1457 
1458  switch (d1->type) {
1459  case VM_METHOD_TYPE_ISEQ:
1460  return d1->body.iseq.iseqptr == d2->body.iseq.iseqptr;
1461  case VM_METHOD_TYPE_CFUNC:
1462  return
1463  d1->body.cfunc.func == d2->body.cfunc.func &&
1464  d1->body.cfunc.argc == d2->body.cfunc.argc;
1466  case VM_METHOD_TYPE_IVAR:
1467  return d1->body.attr.id == d2->body.attr.id;
1469  return RTEST(rb_equal(d1->body.proc, d2->body.proc));
1471  return d1->original_id == d2->original_id;
1472  case VM_METHOD_TYPE_ZSUPER:
1474  case VM_METHOD_TYPE_UNDEF:
1475  return 1;
1477  return d1->body.optimize_type == d2->body.optimize_type;
1479  case VM_METHOD_TYPE_ALIAS:
1480  break;
1481  }
1482  rb_bug("rb_method_definition_eq: unsupported type: %d\n", d1->type);
1483 }
1484 
1485 static st_index_t
1487 {
1488  hash = rb_hash_uint(hash, def->type);
1489  def = original_method_definition(def);
1490 
1491  if (!def) return hash;
1492 
1493  switch (def->type) {
1494  case VM_METHOD_TYPE_ISEQ:
1495  return rb_hash_uint(hash, (st_index_t)def->body.iseq.iseqptr);
1496  case VM_METHOD_TYPE_CFUNC:
1497  hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
1498  return rb_hash_uint(hash, def->body.cfunc.argc);
1500  case VM_METHOD_TYPE_IVAR:
1501  return rb_hash_uint(hash, def->body.attr.id);
1503  return rb_hash_proc(hash, def->body.proc);
1505  return rb_hash_uint(hash, def->original_id);
1506  case VM_METHOD_TYPE_ZSUPER:
1508  case VM_METHOD_TYPE_UNDEF:
1509  return hash;
1511  return rb_hash_uint(hash, def->body.optimize_type);
1513  case VM_METHOD_TYPE_ALIAS:
1514  break; /* unreachable */
1515  }
1516  rb_bug("rb_hash_method_definition: unsupported method type (%d)\n", def->type);
1517  }
1518 
1519 st_index_t
1521 {
1522  return rb_hash_method_definition(hash, me->def);
1523 }
1524 
1525 void
1526 rb_alias(VALUE klass, ID alias_name, ID original_name)
1527 {
1528  const VALUE target_klass = klass;
1530  const rb_method_entry_t *orig_me;
1532 
1533  if (NIL_P(klass)) {
1534  rb_raise(rb_eTypeError, "no class to make alias");
1535  }
1536 
1537  rb_frozen_class_p(klass);
1538 
1539  again:
1540  orig_me = search_method(klass, original_name, &defined_class);
1541  if (orig_me && orig_me->def->type == VM_METHOD_TYPE_REFINED) {
1542  orig_me = rb_resolve_refined_method(Qnil, orig_me);
1543  }
1544 
1545  if (UNDEFINED_METHOD_ENTRY_P(orig_me) ||
1546  UNDEFINED_REFINED_METHOD_P(orig_me->def)) {
1547  if ((!RB_TYPE_P(klass, T_MODULE)) ||
1548  (orig_me = search_method(rb_cObject, original_name, &defined_class),
1549  UNDEFINED_METHOD_ENTRY_P(orig_me))) {
1550  rb_print_undef(klass, original_name, METHOD_VISI_UNDEF);
1551  }
1552  }
1553 
1554  if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {
1555  klass = RCLASS_SUPER(klass);
1556  original_name = orig_me->def->original_id;
1557  visi = METHOD_ENTRY_VISI(orig_me);
1558  goto again;
1559  }
1560 
1561  if (visi == METHOD_VISI_UNDEF) visi = METHOD_ENTRY_VISI(orig_me);
1562 
1563  if (orig_me->defined_class == 0) {
1564  rb_method_entry_make(target_klass, alias_name, target_klass, visi,
1565  VM_METHOD_TYPE_ALIAS, NULL, orig_me->called_id,
1566  (void *)rb_method_entry_clone(orig_me));
1567  method_added(target_klass, alias_name);
1568  }
1569  else {
1570  rb_method_entry_t *alias_me;
1571 
1572  alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner);
1573  RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass);
1574  RB_OBJ_WRITE(alias_me, &alias_me->defined_class, defined_class);
1575  }
1576 }
1577 
1578 /*
1579  * call-seq:
1580  * alias_method(new_name, old_name) -> self
1581  *
1582  * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
1583  * be used to retain access to methods that are overridden.
1584  *
1585  * module Mod
1586  * alias_method :orig_exit, :exit
1587  * def exit(code=0)
1588  * puts "Exiting with code #{code}"
1589  * orig_exit(code)
1590  * end
1591  * end
1592  * include Mod
1593  * exit(99)
1594  *
1595  * <em>produces:</em>
1596  *
1597  * Exiting with code 99
1598  */
1599 
1600 static VALUE
1602 {
1603  ID oldid = rb_check_id(&oldname);
1604  if (!oldid) {
1605  rb_print_undef_str(mod, oldname);
1606  }
1607  rb_alias(mod, rb_to_id(newname), oldid);
1608  return mod;
1609 }
1610 
1611 static void
1613 {
1614  int i;
1615 
1616  rb_check_frozen(self);
1617  if (argc == 0) {
1618  rb_warning("%"PRIsVALUE" with no argument is just ignored",
1620  return;
1621  }
1622 
1623  for (i = 0; i < argc; i++) {
1624  VALUE v = argv[i];
1625  ID id = rb_check_id(&v);
1626  if (!id) {
1627  rb_print_undef_str(self, v);
1628  }
1629  rb_export_method(self, id, visi);
1630  }
1631 }
1632 
1633 static VALUE
1634 set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
1635 {
1636  if (argc == 0) {
1638  }
1639  else {
1640  set_method_visibility(module, argc, argv, visi);
1641  }
1642  return module;
1643 }
1644 
1645 /*
1646  * call-seq:
1647  * public -> self
1648  * public(symbol, ...) -> self
1649  * public(string, ...) -> self
1650  *
1651  * With no arguments, sets the default visibility for subsequently
1652  * defined methods to public. With arguments, sets the named methods to
1653  * have public visibility.
1654  * String arguments are converted to symbols.
1655  */
1656 
1657 static VALUE
1658 rb_mod_public(int argc, VALUE *argv, VALUE module)
1659 {
1660  return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC);
1661 }
1662 
1663 /*
1664  * call-seq:
1665  * protected -> self
1666  * protected(symbol, ...) -> self
1667  * protected(string, ...) -> self
1668  *
1669  * With no arguments, sets the default visibility for subsequently
1670  * defined methods to protected. With arguments, sets the named methods
1671  * to have protected visibility.
1672  * String arguments are converted to symbols.
1673  *
1674  * If a method has protected visibility, it is callable only where
1675  * <code>self</code> of the context is the same as the method.
1676  * (method definition or instance_eval). This behavior is different from
1677  * Java's protected method. Usually <code>private</code> should be used.
1678  *
1679  * Note that a protected method is slow because it can't use inline cache.
1680  *
1681  * To show a private method on RDoc, use <code>:doc:</code> instead of this.
1682  */
1683 
1684 static VALUE
1685 rb_mod_protected(int argc, VALUE *argv, VALUE module)
1686 {
1687  return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED);
1688 }
1689 
1690 /*
1691  * call-seq:
1692  * private -> self
1693  * private(symbol, ...) -> self
1694  * private(string, ...) -> self
1695  *
1696  * With no arguments, sets the default visibility for subsequently
1697  * defined methods to private. With arguments, sets the named methods
1698  * to have private visibility.
1699  * String arguments are converted to symbols.
1700  *
1701  * module Mod
1702  * def a() end
1703  * def b() end
1704  * private
1705  * def c() end
1706  * private :a
1707  * end
1708  * Mod.private_instance_methods #=> [:a, :c]
1709  *
1710  * Note that to show a private method on RDoc, use <code>:doc:</code>.
1711  */
1712 
1713 static VALUE
1714 rb_mod_private(int argc, VALUE *argv, VALUE module)
1715 {
1716  return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE);
1717 }
1718 
1719 /*
1720  * call-seq:
1721  * mod.public_class_method(symbol, ...) -> mod
1722  * mod.public_class_method(string, ...) -> mod
1723  *
1724  * Makes a list of existing class methods public.
1725  *
1726  * String arguments are converted to symbols.
1727  */
1728 
1729 static VALUE
1731 {
1733  return obj;
1734 }
1735 
1736 /*
1737  * call-seq:
1738  * mod.private_class_method(symbol, ...) -> mod
1739  * mod.private_class_method(string, ...) -> mod
1740  *
1741  * Makes existing class methods private. Often used to hide the default
1742  * constructor <code>new</code>.
1743  *
1744  * String arguments are converted to symbols.
1745  *
1746  * class SimpleSingleton # Not thread safe
1747  * private_class_method :new
1748  * def SimpleSingleton.create(*args, &block)
1749  * @me = new(*args, &block) if ! @me
1750  * @me
1751  * end
1752  * end
1753  */
1754 
1755 static VALUE
1757 {
1759  return obj;
1760 }
1761 
1762 /*
1763  * call-seq:
1764  * public
1765  * public(symbol, ...)
1766  * public(string, ...)
1767  *
1768  * With no arguments, sets the default visibility for subsequently
1769  * defined methods to public. With arguments, sets the named methods to
1770  * have public visibility.
1771  *
1772  * String arguments are converted to symbols.
1773  */
1774 
1775 static VALUE
1776 top_public(int argc, VALUE *argv)
1777 {
1778  return rb_mod_public(argc, argv, rb_cObject);
1779 }
1780 
1781 /*
1782  * call-seq:
1783  * private
1784  * private(symbol, ...)
1785  * private(string, ...)
1786  *
1787  * With no arguments, sets the default visibility for subsequently
1788  * defined methods to private. With arguments, sets the named methods to
1789  * have private visibility.
1790  *
1791  * String arguments are converted to symbols.
1792  */
1793 static VALUE
1795 {
1796  return rb_mod_private(argc, argv, rb_cObject);
1797 }
1798 
1799 /*
1800  * call-seq:
1801  * module_function(symbol, ...) -> self
1802  * module_function(string, ...) -> self
1803  *
1804  * Creates module functions for the named methods. These functions may
1805  * be called with the module as a receiver, and also become available
1806  * as instance methods to classes that mix in the module. Module
1807  * functions are copies of the original, and so may be changed
1808  * independently. The instance-method versions are made private. If
1809  * used with no arguments, subsequently defined methods become module
1810  * functions.
1811  * String arguments are converted to symbols.
1812  *
1813  * module Mod
1814  * def one
1815  * "This is one"
1816  * end
1817  * module_function :one
1818  * end
1819  * class Cls
1820  * include Mod
1821  * def call_one
1822  * one
1823  * end
1824  * end
1825  * Mod.one #=> "This is one"
1826  * c = Cls.new
1827  * c.call_one #=> "This is one"
1828  * module Mod
1829  * def one
1830  * "This is the new one"
1831  * end
1832  * end
1833  * Mod.one #=> "This is one"
1834  * c.call_one #=> "This is the new one"
1835  */
1836 
1837 static VALUE
1838 rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
1839 {
1840  int i;
1841  ID id;
1842  const rb_method_entry_t *me;
1843 
1844  if (!RB_TYPE_P(module, T_MODULE)) {
1845  rb_raise(rb_eTypeError, "module_function must be called for modules");
1846  }
1847 
1848  if (argc == 0) {
1850  return module;
1851  }
1852 
1853  set_method_visibility(module, argc, argv, METHOD_VISI_PRIVATE);
1854 
1855  for (i = 0; i < argc; i++) {
1856  VALUE m = module;
1857 
1858  id = rb_to_id(argv[i]);
1859  for (;;) {
1860  me = search_method(m, id, 0);
1861  if (me == 0) {
1862  me = search_method(rb_cObject, id, 0);
1863  }
1864  if (UNDEFINED_METHOD_ENTRY_P(me)) {
1865  rb_print_undef(module, id, METHOD_VISI_UNDEF);
1866  }
1867  if (me->def->type != VM_METHOD_TYPE_ZSUPER) {
1868  break; /* normal case: need not to follow 'super' link */
1869  }
1870  m = RCLASS_SUPER(m);
1871  if (!m)
1872  break;
1873  }
1875  }
1876  return module;
1877 }
1878 
1879 int
1881 {
1882  const rb_method_entry_t *me;
1883  if (!klass) return TRUE; /* hidden object cannot be overridden */
1884  me = rb_method_entry(klass, id);
1885  return (me && METHOD_ENTRY_BASIC(me)) ? TRUE : FALSE;
1886 }
1887 
1888 static VALUE
1889 call_method_entry(rb_thread_t *th, VALUE defined_class, VALUE obj, ID id,
1890  const rb_method_entry_t *me, int argc, const VALUE *argv)
1891 {
1892  const rb_callable_method_entry_t *cme =
1893  prepare_callable_method_entry(defined_class, id, me);
1894  VALUE passed_block_handler = vm_passed_block_handler(th);
1895  VALUE result = vm_call0(th, obj, id, argc, argv, cme);
1896  vm_passed_block_handler_set(th, passed_block_handler);
1897  return result;
1898 }
1899 
1900 static VALUE
1902  VALUE mid, VALUE priv)
1903 {
1904  VALUE defined_class, args[2];
1905  const ID rtmid = idRespond_to_missing;
1906  const rb_method_entry_t *const me =
1907  method_entry_get(klass, rtmid, &defined_class);
1908 
1909  if (!me || METHOD_ENTRY_BASIC(me)) return Qundef;
1910  args[0] = mid;
1911  args[1] = priv;
1912  return call_method_entry(th, defined_class, obj, rtmid, me, 2, args);
1913 }
1914 
1915 static inline int
1917 {
1918  VALUE klass = CLASS_OF(obj);
1919  VALUE ret;
1920 
1921  switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) {
1922  case 2:
1923  return FALSE;
1924  case 0:
1925  ret = basic_obj_respond_to_missing(th, klass, obj, ID2SYM(id),
1926  pub ? Qfalse : Qtrue);
1927  return RTEST(ret) && ret != Qundef;
1928  default:
1929  return TRUE;
1930  }
1931 }
1932 
1933 static int
1934 vm_respond_to(rb_thread_t *th, VALUE klass, VALUE obj, ID id, int priv)
1935 {
1937  const ID resid = idRespond_to;
1938  const rb_method_entry_t *const me =
1939  method_entry_get(klass, resid, &defined_class);
1940 
1941  if (!me) return -1;
1942  if (METHOD_ENTRY_BASIC(me)) {
1943  return -1;
1944  }
1945  else {
1946  int argc = 1;
1947  VALUE args[2];
1948  VALUE result;
1949 
1950  args[0] = ID2SYM(id);
1951  args[1] = Qtrue;
1952  if (priv) {
1953  argc = rb_method_entry_arity(me);
1954  if (argc > 2) {
1956  "respond_to? must accept 1 or 2 arguments (requires %d)",
1957  argc);
1958  }
1959  if (argc != 1) {
1960  argc = 2;
1961  }
1962  else if (!NIL_P(ruby_verbose)) {
1963  VALUE location = rb_method_entry_location(me);
1964  rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") uses"
1965  " the deprecated method signature, which takes one parameter",
1966  (FL_TEST(klass, FL_SINGLETON) ? obj : klass),
1967  (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
1968  QUOTE_ID(id));
1969  if (!NIL_P(location)) {
1970  VALUE path = RARRAY_AREF(location, 0);
1971  VALUE line = RARRAY_AREF(location, 1);
1972  if (!NIL_P(path)) {
1973  rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
1974  "respond_to? is defined here");
1975  }
1976  }
1977  }
1978  }
1979  result = call_method_entry(th, defined_class, obj, resid, me, argc, args);
1980  return RTEST(result);
1981  }
1982 }
1983 
1984 int
1985 rb_obj_respond_to(VALUE obj, ID id, int priv)
1986 {
1987  rb_thread_t *th = GET_THREAD();
1988  VALUE klass = CLASS_OF(obj);
1989  int ret = vm_respond_to(th, klass, obj, id, priv);
1990  if (ret == -1) ret = basic_obj_respond_to(th, obj, id, !priv);
1991  return ret;
1992 }
1993 
1994 int
1996 {
1997  return rb_obj_respond_to(obj, id, FALSE);
1998 }
1999 
2000 
2001 /*
2002  * call-seq:
2003  * obj.respond_to?(symbol, include_all=false) -> true or false
2004  * obj.respond_to?(string, include_all=false) -> true or false
2005  *
2006  * Returns +true+ if _obj_ responds to the given method. Private and
2007  * protected methods are included in the search only if the optional
2008  * second parameter evaluates to +true+.
2009  *
2010  * If the method is not implemented,
2011  * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
2012  * false is returned.
2013  *
2014  * If the method is not defined, <code>respond_to_missing?</code>
2015  * method is called and the result is returned.
2016  *
2017  * When the method name parameter is given as a string, the string is
2018  * converted to a symbol.
2019  */
2020 
2021 static VALUE
2022 obj_respond_to(int argc, VALUE *argv, VALUE obj)
2023 {
2024  VALUE mid, priv;
2025  ID id;
2026  rb_thread_t *th = GET_THREAD();
2027 
2028  rb_scan_args(argc, argv, "11", &mid, &priv);
2029  if (!(id = rb_check_id(&mid))) {
2030  VALUE ret = basic_obj_respond_to_missing(th, CLASS_OF(obj), obj,
2031  rb_to_symbol(mid), priv);
2032  if (ret == Qundef) ret = Qfalse;
2033  return ret;
2034  }
2035  if (basic_obj_respond_to(th, obj, id, !RTEST(priv)))
2036  return Qtrue;
2037  return Qfalse;
2038 }
2039 
2040 /*
2041  * call-seq:
2042  * obj.respond_to_missing?(symbol, include_all) -> true or false
2043  * obj.respond_to_missing?(string, include_all) -> true or false
2044  *
2045  * DO NOT USE THIS DIRECTLY.
2046  *
2047  * Hook method to return whether the _obj_ can respond to _id_ method
2048  * or not.
2049  *
2050  * When the method name parameter is given as a string, the string is
2051  * converted to a symbol.
2052  *
2053  * See #respond_to?, and the example of BasicObject.
2054  */
2055 static VALUE
2057 {
2058  return Qfalse;
2059 }
2060 
2061 void
2063 {
2064 #if OPT_GLOBAL_METHOD_CACHE
2065  char *ptr = getenv("RUBY_GLOBAL_METHOD_CACHE_SIZE");
2066  int val;
2067 
2068  if (ptr != NULL && (val = atoi(ptr)) > 0) {
2069  if ((val & (val - 1)) == 0) { /* ensure val is a power of 2 */
2070  global_method_cache.size = val;
2071  global_method_cache.mask = val - 1;
2072  }
2073  else {
2074  fprintf(stderr, "RUBY_GLOBAL_METHOD_CACHE_SIZE was set to %d but ignored because the value is not a power of 2.\n", val);
2075  }
2076  }
2077 
2078  global_method_cache.entries = (struct cache_entry *)calloc(global_method_cache.size, sizeof(struct cache_entry));
2079  if (global_method_cache.entries == NULL) {
2080  fprintf(stderr, "[FATAL] failed to allocate memory\n");
2081  exit(EXIT_FAILURE);
2082  }
2083 #endif
2084 }
2085 
2086 void
2088 {
2089 #undef rb_intern
2090 #define rb_intern(str) rb_intern_const(str)
2091 
2092  rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
2093  rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
2094 
2101  rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
2102 
2103  rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
2104  rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
2105  rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
2106  rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
2107  rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
2108  rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
2109 
2111  "public", top_public, -1);
2113  "private", top_private, -1);
2114 
2115  {
2116 #define REPLICATE_METHOD(klass, id) do { \
2117  const rb_method_entry_t *me = rb_method_entry((klass), (id)); \
2118  rb_method_entry_set((klass), (id), me, METHOD_ENTRY_VISI(me)); \
2119  } while (0)
2120 
2121  REPLICATE_METHOD(rb_eException, idMethodMissing);
2124  }
2125 }
static rb_method_definition_t * method_definition_addref(rb_method_definition_t *def)
Definition: vm_method.c:356
#define UNDEFINED_REFINED_METHOD_P(def)
Definition: method.h:172
static rb_method_definition_t * method_definition_create(rb_method_type_t type, ID mid)
Definition: vm_method.c:346
int rb_method_boundp(VALUE klass, ID id, int ex)
Definition: vm_method.c:1069
rb_control_frame_t * cfp
Definition: vm_core.h:708
static VALUE basic_obj_respond_to_missing(rb_thread_t *th, VALUE klass, VALUE obj, VALUE mid, VALUE priv)
Definition: vm_method.c:1901
static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
Definition: vm_method.c:1449
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:489
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
Definition: vm_method.c:136
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:171
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:923
const VALUE * ep
Definition: vm_core.h:636
static VALUE rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1730
static VALUE call_cfunc_0(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const VALUE owner
Definition: method.h:144
static void vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
Definition: eval_intern.h:8
void rb_bug(const char *fmt,...)
Definition: error.c:482
rb_method_type_t type
Definition: method.h:148
#define FALSE
Definition: nkf.h:174
rb_method_entry_t * me
Definition: vm_method.c:44
rb_method_attr_t attr
Definition: method.h:155
static VALUE rb_mod_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1295
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:197
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:403
static VALUE rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
Definition: vm_method.c:1601
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
Definition: vm_backtrace.c:38
static int vm_env_cref_by_cref(const VALUE *ep)
#define NUM2INT(x)
Definition: ruby.h:684
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1438
void rb_remove_method(VALUE klass, const char *name)
Definition: vm_method.c:1000
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1520
static unsigned int hash(str, len) register const char *str
static VALUE rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
Definition: vm_method.c:1016
static rb_method_entry_t * method_entry_get_without_cache(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:726
rb_subclass_entry_t * next
Definition: internal.h:640
static VALUE find_refinement(VALUE refinements, VALUE klass)
#define d1
static const rb_iseq_t * def_iseq_ptr(rb_method_definition_t *def)
static rb_method_entry_t * rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def)
Definition: vm_method.c:372
const VALUE location
Definition: method.h:135
#define QUOTE_ID(id)
Definition: internal.h:1473
const rb_iseq_t * rb_proc_get_iseq(VALUE proc, int *is_proc)
Definition: proc.c:1091
#define CLASS_OF(v)
Definition: ruby.h:453
#define T_MODULE
Definition: ruby.h:494
#define RCLASS_EXT(c)
Definition: classext.h:15
rb_cref_t *const cref
Definition: method.h:124
#define Qtrue
Definition: ruby.h:437
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
Definition: vm_method.c:462
static void rb_class_clear_method_cache(VALUE klass, VALUE arg)
Definition: vm_method.c:63
static const rb_method_definition_t * original_method_definition(const rb_method_definition_t *def)
Definition: vm_method.c:1427
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:1971
#define rb_id2str(id)
Definition: vm_backtrace.c:29
static VALUE call_cfunc_10(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const int id
Definition: nkf.c:209
rb_alloc_func_t rb_get_alloc_func(VALUE klass)
Definition: vm_method.c:687
VALUE rb_refinement_module_get_refined_class(VALUE module)
Definition: eval.c:1238
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1527
rb_serial_t method_state
Definition: vm_method.c:41
static void setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE(*func)(), int argc)
Definition: vm_method.c:224
static void make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
Definition: vm_method.c:435
VALUE rb_eTypeError
Definition: error.c:762
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
Definition: vm_method.c:631
#define rb_intern(str)
#define UNREACHABLE
Definition: ruby.h:46
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
Definition: vm_method.c:402
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
Definition: zonetab.h:883
const VALUE owner
Definition: method.h:55
VALUE defined_class
Definition: vm_method.c:45
static const rb_method_entry_t * method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *defined_class_ptr)
Definition: vm_method.c:844
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
Definition: vm_method.c:834
#define ruby_running
Definition: vm_method.c:59
struct rb_iseq_constant_body * body
Definition: vm_core.h:395
static const rb_method_entry_t * refined_method_original_method_entry(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
Definition: vm_method.c:895
static void METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)
Definition: method.h:72
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:212
#define Check_Type(v, t)
Definition: ruby.h:562
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
#define METHOD_ENTRY_COMPLEMENTED(me)
Definition: method.h:68
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:181
ID called_id
Definition: method.h:54
static VALUE set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
Definition: vm_method.c:1634
Definition: vm_method.c:40
static VALUE CREF_REFINEMENTS(const rb_cref_t *cref)
Definition: eval_intern.h:216
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1649
st_data_t st_index_t
Definition: st.h:50
#define GET_GLOBAL_METHOD_STATE()
static void rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
Definition: vm_method.c:1033
static const rb_cref_t * method_cref(VALUE method)
Definition: proc.c:2473
#define RUBY_DTRACE_HOOK(name, arg)
Definition: internal.h:1755
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:9380
static void rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_visibility_t visi)
Definition: vm_method.c:130
int rb_method_basic_definition_p(VALUE klass, ID id)
Definition: vm_method.c:1880
static rb_method_entry_t * lookup_method_table(VALUE klass, ID id)
Definition: vm_method.c:183
static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj)
Definition: vm_method.c:122
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1024
static VALUE call_cfunc_11(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static void METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
Definition: method.h:93
rb_method_iseq_t iseq
Definition: method.h:153
static rb_method_entry_t * search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:700
#define GET_THREAD()
Definition: vm_core.h:1513
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
static void remove_method(VALUE klass, ID mid)
Definition: vm_method.c:961
static st_index_t rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
Definition: vm_method.c:1486
static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
Definition: vm_method.c:232
#define FL_SINGLETON
Definition: ruby.h:1215
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1689
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
Definition: vm_method.c:1138
int rb_obj_respond_to(VALUE obj, ID id, int priv)
Definition: vm_method.c:1985
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
rb_method_cfunc_t cfunc
Definition: method.h:154
const rb_scope_visibility_t scope_visi
Definition: method.h:45
static VALUE call_cfunc_15(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define FL_TEST(x, f)
Definition: ruby.h:1284
const rb_iseq_t * iseq
Definition: vm_core.h:634
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
Definition: vm_method.c:941
#define rb_intern_str(string)
Definition: generator.h:16
#define METHOD_ENTRY_COMPLEMENTED_SET(me)
Definition: method.h:69
Definition: internal.h:638
static void METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsigned int basic)
Definition: method.h:84
#define val
rb_method_alias_t alias
Definition: method.h:156
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
static VALUE vm_call0(rb_thread_t *th, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
Definition: vm_eval.c:46
int rb_respond_to(VALUE obj, ID id)
Definition: vm_method.c:1995
void rb_clear_cache(void)
Definition: vm_method.c:84
void rb_id_table_clear(struct rb_id_table *tbl)
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:1871
static VALUE top_public(int argc, VALUE *argv)
Definition: vm_method.c:1776
const rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
Definition: vm_method.c:947
static VALUE obj_respond_to(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:2022
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:393
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1860
void rb_remove_method_id(VALUE klass, ID mid)
Definition: vm_method.c:994
#define RCLASS_ORIGIN(c)
Definition: internal.h:693
int rb_id_table_delete(struct rb_id_table *tbl, ID id)
#define NIL_P(v)
Definition: ruby.h:451
struct rb_id_table * rb_id_table_create(size_t size)
#define calloc
Definition: ripper.c:118
void rb_undef_alloc_func(VALUE klass)
Definition: vm_method.c:681
rb_method_visibility_t
Definition: method.h:26
struct rb_method_definition_struct *const def
Definition: method.h:53
static VALUE top_private(int argc, VALUE *argv)
Definition: vm_method.c:1794
static rb_method_visibility_t rb_scope_visibility_get(void)
Definition: vm_method.c:1090
#define BOUND_RESPONDS
Definition: vm_method.c:1066
static VALUE call_cfunc_2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define added
Definition: vm_method.c:32
int rb_method_entry_arity(const rb_method_entry_t *me)
Definition: proc.c:2341
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
#define undefined
Definition: vm_method.c:36
const rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
Definition: vm_method.c:796
const VALUE defined_class
Definition: method.h:60
Definition: method.h:50
const 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:411
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1895
static void vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
Definition: vm_method.c:1118
Definition: method.h:58
void rb_clear_constant_cache(void)
Definition: vm_method.c:90
static VALUE call_cfunc_1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define EXIT_FAILURE
Definition: eval_intern.h:33
#define OPT_GLOBAL_METHOD_CACHE
Definition: vm_opts.h:41
VALUE rb_method_entry_location(const rb_method_entry_t *me)
Definition: proc.c:2501
static VALUE call_cfunc_9(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_3(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
rb_method_type_t
Definition: method.h:100
static VALUE filter_defined_class(VALUE klass)
Definition: vm_method.c:379
rb_serial_t class_serial
Definition: vm_method.c:42
void rb_alias(VALUE klass, ID alias_name, ID original_name)
Definition: vm_method.c:1526
static void method_definition_reset(const rb_method_entry_t *me)
Definition: vm_method.c:312
static VALUE rb_mod_private_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1381
#define removed
Definition: vm_method.c:34
#define ZALLOC(type)
Definition: ruby.h:1590
const rb_callable_method_entry_t * rb_callable_method_entry_without_refinements(VALUE klass, ID id)
Definition: vm_method.c:887
static int rb_scope_module_func_check(void)
Definition: vm_method.c:1104
#define RCLASS_M_TBL(c)
Definition: internal.h:690
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:129
union rb_method_definition_struct::@144 body
#define TRUE
Definition: nkf.h:175
static VALUE(*)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *) call_cfunc_invoker_func(int argc)
Definition: vm_method.c:197
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
Definition: class.c:113
static VALUE call_cfunc_13(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1440
unsigned long rb_serial_t
Definition: internal.h:650
static VALUE rb_mod_public(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1658
static int vm_redefinition_check_flag(VALUE klass)
VALUE rb_to_symbol(VALUE name)
Definition: string.c:9989
#define VM_ASSERT(expr)
Definition: vm_core.h:54
VALUE klass
Definition: internal.h:639
VALUE(* func)(ANYARGS)
Definition: method.h:128
static int basic_obj_respond_to(rb_thread_t *th, VALUE obj, ID id, int pub)
Definition: vm_method.c:1916
#define UNDEF_ALLOC_FUNC
Definition: vm_method.c:671
static VALUE rb_mod_protected_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1415
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
#define INC_GLOBAL_METHOD_STATE()
#define INC_GLOBAL_CONSTANT_STATE()
#define METHOD_ENTRY_VISI(me)
Definition: method.h:66
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_vm_top_self(void)
Definition: vm.c:3151
static VALUE rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1838
static VALUE result
Definition: nkf.c:40
static rb_method_entry_t * rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibility_t visi, rb_method_type_t type, rb_method_definition_t *def, ID original_id, void *opts)
Definition: vm_method.c:498
const VALUE defined_class
Definition: method.h:52
const char * rb_class2name(VALUE)
Definition: variable.c:449
static VALUE obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
Definition: vm_method.c:2056
rb_method_visibility_t method_visi
Definition: method.h:36
#define FIX2INT(x)
Definition: ruby.h:686
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:643
const struct rb_method_entry_struct *const original_me
Definition: method.h:139
static void check_override_opt_method(VALUE klass, VALUE arg)
Definition: vm_method.c:476
#define rb_ary_new3
Definition: intern.h:91
static rb_method_entry_t * method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi, VALUE defined_class)
Definition: vm_method.c:656
static VALUE call_cfunc_m2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const char * rb_id2name(ID)
Definition: symbol.c:759
static VALUE call_cfunc_12(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_5(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
Definition: vm_method.c:1246
#define CALL_METHOD_HOOK(klass, hook, mid)
Definition: vm_method.c:611
static void method_added(VALUE klass, ID mid)
Definition: vm_method.c:623
static rb_method_entry_t * method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:776
static VALUE call_cfunc_7(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define getenv(name)
Definition: win32.c:71
#define RSTRING_PTR(str)
Definition: ruby.h:982
static VALUE rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1756
static VALUE call_method_entry(rb_thread_t *th, VALUE defined_class, VALUE obj, ID id, const rb_method_entry_t *me, int argc, const VALUE *argv)
Definition: vm_method.c:1889
#define METHOD_DEBUG
Definition: vm_method.c:7
VALUE rb_equal(VALUE, VALUE)
Definition: object.c:86
int size
Definition: encoding.c:57
#define INT2FIX(i)
Definition: ruby.h:232
static void set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
Definition: vm_method.c:1612
#define RCLASS_SUPER(c)
Definition: classext.h:16
#define RARRAY_AREF(a, i)
Definition: ruby.h:1040
ID rb_frame_callee(void)
Definition: eval.c:985
static VALUE call_cfunc_m1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define METHOD_ENTRY_BASIC(me)
Definition: method.h:67
const rb_method_entry_t * rb_method_entry_at(VALUE klass, ID id)
Definition: vm_method.c:714
#define object_id
Definition: vm_method.c:31
void Init_Method(void)
Definition: vm_method.c:2062
#define ANYARGS
Definition: defines.h:173
const rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id)
Definition: vm_method.c:867
static VALUE call_cfunc_14(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
Definition: vm_method.c:1421
static void rb_scope_module_func_set(void)
Definition: vm_method.c:1132
void rb_compile_warning(const char *file, int line, const char *fmt,...)
Definition: error.c:196
#define RCLASS_CALLABLE_M_TBL(c)
Definition: internal.h:691
#define RTEST(v)
Definition: ruby.h:450
st_index_t rb_hash_uint(st_index_t, st_index_t)
void rb_define_alloc_func(VALUE klass, VALUE(*func)(VALUE))
Definition: vm_method.c:674
#define GLOBAL_METHOD_CACHE(c, m)
Definition: vm_method.c:25
#define ONLY_FOR_INTERNAL_USE(func)
Definition: internal.h:1027
static VALUE rb_mod_protected(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1685
static VALUE call_cfunc_6(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const char * rb_obj_info(VALUE obj)
Definition: gc.c:9369
void rb_notimplement(void)
Definition: error.c:2253
static VALUE call_cfunc_4(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
void Init_eval_method(void)
Definition: vm_method.c:2087
static VALUE rb_mod_public_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1347
#define T_CLASS
Definition: ruby.h:492
static void vm_cref_dump(const char *mesg, const rb_cref_t *cref)
Definition: vm.c:259
static int vm_respond_to(rb_thread_t *th, VALUE klass, VALUE obj, ID id, int priv)
Definition: vm_method.c:1934
static VALUE rb_mod_private(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1714
const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id)
Definition: vm_method.c:881
void rb_frozen_class_p(VALUE klass)
Definition: eval.c:396
const char * name
Definition: nkf.c:208
static VALUE vm_passed_block_handler(rb_thread_t *th)
Definition: vm.c:169
#define ID2SYM(x)
Definition: ruby.h:383
#define REPLICATE_METHOD(klass, id)
void rb_undef(VALUE klass, ID id)
Definition: vm_method.c:1173
static const rb_callable_method_entry_t * prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_t *me)
Definition: vm_method.c:802
rb_serial_t rb_next_class_serial(void)
Definition: vm.c:305
void rb_warning(const char *fmt,...)
Definition: error.c:250
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:666
static const rb_scope_visibility_t * CREF_SCOPE_VISI(const rb_cref_t *cref)
Definition: eval_intern.h:210
#define rb_check_frozen(obj)
Definition: intern.h:276
enum rb_method_definition_struct::@144::method_optimized_type optimize_type
const rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id)
Definition: vm_method.c:873
ID rb_id_attrset(ID)
Definition: symbol.c:100
const rb_iseq_t *const iseqptr
Definition: method.h:123
void void xfree(void *)
st_index_t rb_hash_proc(st_index_t hash, VALUE proc)
Definition: proc.c:1193
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
Definition: vm_method.c:424
#define mod(x, y)
Definition: date_strftime.c:28
const struct rb_method_entry_struct *const orig_me
Definition: method.h:143
static rb_cref_t * vm_cref_new_toplevel(rb_thread_t *th)
Definition: vm.c:241
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:387
static rb_method_definition_t * method_definition_addref_complement(rb_method_definition_t *def)
Definition: vm_method.c:364
#define NULL
Definition: _sdbm.c:102
rb_method_refined_t refined
Definition: method.h:157
static void rb_method_definition_release(rb_method_definition_t *def, int complemented)
Definition: vm_method.c:151
#define Qundef
Definition: ruby.h:439
#define T_ICLASS
Definition: ruby.h:493
void rb_free_method_entry(const rb_method_entry_t *me)
Definition: vm_method.c:174
#define RCLASS_SERIAL(c)
Definition: internal.h:695
void rb_scope_visibility_set(rb_method_visibility_t visi)
Definition: vm_method.c:1126
static const rb_method_entry_t * resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
Definition: vm_method.c:914
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
#define ruby_verbose
Definition: ruby.h:1792
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1299
void rb_warn(const char *fmt,...)
Definition: error.c:221
ID rb_to_id(VALUE)
Definition: string.c:9979
void rb_clear_method_cache_by_class(VALUE klass)
Definition: vm_method.c:96
VALUE rb_eArgError
Definition: error.c:763
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
static VALUE call_cfunc_8(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
unsigned int module_func
Definition: method.h:37
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1437
char ** argv
Definition: ruby.c:184
rb_iseq_location_t location
Definition: vm_core.h:358
VALUE rb_eException
Definition: error.c:755
ID mid
Definition: vm_method.c:43
static VALUE check_definition(VALUE mod, VALUE mid, rb_method_visibility_t visi)
Definition: vm_method.c:1306