Ruby  2.1.3p242(2014-09-19revision47630)
vm_method.c
Go to the documentation of this file.
1 /*
2  * This file is included by vm.c
3  */
4 
5 #ifndef GLOBAL_METHOD_CACHE_SIZE
6 #define GLOBAL_METHOD_CACHE_SIZE 0x800
7 #endif
8 #ifndef GLOBAL_METHOD_CACHE_MASK
9 #define GLOBAL_METHOD_CACHE_MASK 0x7ff
10 #endif
11 
12 #define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&GLOBAL_METHOD_CACHE_MASK)
13 #define GLOBAL_METHOD_CACHE(c,m) (global_method_cache + GLOBAL_METHOD_CACHE_KEY(c,m))
14 #include "method.h"
15 
16 #define NOEX_NOREDEF 0
17 #ifndef NOEX_NOREDEF
18 #define NOEX_NOREDEF NOEX_RESPONDS
19 #endif
20 
21 static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass);
22 
23 #define object_id idObject_id
24 #define added idMethod_added
25 #define singleton_added idSingleton_method_added
26 #define removed idMethod_removed
27 #define singleton_removed idSingleton_method_removed
28 #define undefined idMethod_undefined
29 #define singleton_undefined idSingleton_method_undefined
30 #define attached id__attached__
31 
32 struct cache_entry {
38 };
39 
41 #define ruby_running (GET_VM()->running)
42 /* int ruby_running = 0; */
43 
44 static void
46 {
49 }
50 
51 void
53 {
54  rb_warning("rb_clear_cache() is deprecated.");
57 }
58 
59 void
61 {
63 }
64 
65 void
67 {
68  if (klass && klass != Qundef) {
69  int global = klass == rb_cBasicObject || klass == rb_cObject || klass == rb_mKernel;
70 
73  }
74 
75  if (global) {
77  }
78  else {
80  }
81  }
82 }
83 
84 VALUE
86 {
88 
90 }
91 
92 static void
94 {
96 }
97 
98 void
100 {
101  if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
102  if (func != rb_f_notimplement) {
103  rb_method_cfunc_t opt;
104  opt.func = func;
105  opt.argc = argc;
106  rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, noex);
107  }
108  else {
109  rb_define_notimplement_method_id(klass, mid, noex);
110  }
111 }
112 
113 void
115 {
117  ume->me = me;
118  ume->next = GET_VM()->unlinked_method_entry_list;
119  GET_VM()->unlinked_method_entry_list = ume;
120 }
121 
122 void
124 {
125  rb_vm_t *vm = pvm;
127 
128  while (ume) {
129  if (ume->me->mark) {
130  rb_mark_method_entry(ume->me);
131  }
132  ume = ume->next;
133  }
134 }
135 
136 void
138 {
139  rb_vm_t *vm = pvm;
140  struct unlinked_method_entry_list_entry **prev_ume = &vm->unlinked_method_entry_list, *ume = *prev_ume, *curr_ume;
141 
142  while (ume) {
143  if (ume->me->mark) {
144  ume->me->mark = 0;
145  prev_ume = &ume->next;
146  ume = *prev_ume;
147  }
148  else {
149  rb_free_method_entry(ume->me);
150 
151  curr_ume = ume;
152  ume = ume->next;
153  *prev_ume = ume;
154  xfree(curr_ume);
155  }
156  }
157 }
158 
159 static void
161 {
162  if (def == 0)
163  return;
164  if (def->alias_count == 0) {
165  if (def->type == VM_METHOD_TYPE_REFINED &&
166  def->body.orig_me) {
168  xfree(def->body.orig_me);
169  }
170  xfree(def);
171  }
172  else if (def->alias_count > 0) {
173  def->alias_count--;
174  }
175 }
176 
177 void
179 {
181  xfree(me);
182 }
183 
185 
186 static inline rb_method_entry_t *
188 {
189  st_data_t body;
190  st_table *m_tbl = RCLASS_M_TBL(klass);
191  if (st_lookup(m_tbl, id, &body)) {
192  return (rb_method_entry_t *) body;
193  }
194  else {
195  return 0;
196  }
197 }
198 
199 static void
201 {
202  rb_method_definition_t *new_def;
203 
204  if (me->def && me->def->type == VM_METHOD_TYPE_REFINED)
205  return;
206 
207  new_def = ALLOC(rb_method_definition_t);
208  new_def->type = VM_METHOD_TYPE_REFINED;
209  new_def->original_id = me->called_id;
210  new_def->alias_count = 0;
211  new_def->body.orig_me = ALLOC(rb_method_entry_t);
212  *new_def->body.orig_me = *me;
214  if (me->def) me->def->alias_count++;
216  me->def = new_def;
217 }
218 
219 void
221 {
222  rb_method_entry_t *me = lookup_method_table(refined_class, mid);
223 
224  if (me) {
226  rb_clear_method_cache_by_class(refined_class);
227  }
228  else {
229  rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0,
230  NOEX_PUBLIC);
231  }
232 }
233 
234 static rb_method_entry_t *
237  VALUE defined_class)
238 {
240 #if NOEX_NOREDEF
241  VALUE rklass;
242 #endif
243  st_table *mtbl;
244  st_data_t data;
245  int make_refined = 0;
246 
247  if (NIL_P(klass)) {
248  klass = rb_cObject;
249  }
250  if (!FL_TEST(klass, FL_SINGLETON) &&
252  type != VM_METHOD_TYPE_ZSUPER &&
253  (mid == idInitialize || mid == idInitialize_copy ||
254  mid == idInitialize_clone || mid == idInitialize_dup ||
255  mid == idRespond_to_missing)) {
256  noex = NOEX_PRIVATE | noex;
257  }
258 
259  rb_check_frozen(klass);
260 #if NOEX_NOREDEF
261  rklass = klass;
262 #endif
263  if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
264  VALUE refined_class =
266 
267  rb_add_refined_method_entry(refined_class, mid);
268  }
269  if (type == VM_METHOD_TYPE_REFINED) {
270  rb_method_entry_t *old_me =
271  lookup_method_table(RCLASS_ORIGIN(klass), mid);
272  if (old_me) rb_vm_check_redefinition_opt_method(old_me, klass);
273  }
274  else {
275  klass = RCLASS_ORIGIN(klass);
276  }
277  mtbl = RCLASS_M_TBL(klass);
278 
279  /* check re-definition */
280  if (st_lookup(mtbl, mid, &data)) {
281  rb_method_entry_t *old_me = (rb_method_entry_t *)data;
282  rb_method_definition_t *old_def = old_me->def;
283 
284  if (rb_method_definition_eq(old_def, def)) return old_me;
285 #if NOEX_NOREDEF
286  if (old_me->flag & NOEX_NOREDEF) {
287  rb_raise(rb_eTypeError, "cannot redefine %"PRIsVALUE"#%"PRIsVALUE,
288  rb_class_name(rklass), rb_id2str(mid));
289  }
290 #endif
292  if (old_def->type == VM_METHOD_TYPE_REFINED)
293  make_refined = 1;
294 
295  if (RTEST(ruby_verbose) &&
296  type != VM_METHOD_TYPE_UNDEF &&
297  old_def->alias_count == 0 &&
298  old_def->type != VM_METHOD_TYPE_UNDEF &&
299  old_def->type != VM_METHOD_TYPE_ZSUPER) {
300  rb_iseq_t *iseq = 0;
301 
302  rb_warning("method redefined; discarding old %s", rb_id2name(mid));
303  switch (old_def->type) {
304  case VM_METHOD_TYPE_ISEQ:
305  iseq = old_def->body.iseq;
306  break;
308  iseq = rb_proc_get_iseq(old_def->body.proc, 0);
309  break;
310  default:
311  break;
312  }
313  if (iseq && !NIL_P(iseq->location.path)) {
314  int line = iseq->line_info_table ? FIX2INT(rb_iseq_first_lineno(iseq->self)) : 0;
316  "previous definition of %s was here",
317  rb_id2name(old_def->original_id));
318  }
319  }
320 
321  rb_unlink_method_entry(old_me);
322  }
323 
324  me = ALLOC(rb_method_entry_t);
325 
327 
328  me->flag = NOEX_WITH_SAFE(noex);
329  me->mark = 0;
330  me->called_id = mid;
331  RB_OBJ_WRITE(klass, &me->klass, defined_class);
332  me->def = def;
333 
334  if (def) {
335  def->alias_count++;
336 
337  switch(def->type) {
338  case VM_METHOD_TYPE_ISEQ:
339  RB_OBJ_WRITTEN(klass, Qundef, def->body.iseq->self);
340  break;
341  case VM_METHOD_TYPE_IVAR:
342  RB_OBJ_WRITTEN(klass, Qundef, def->body.attr.location);
343  break;
345  RB_OBJ_WRITTEN(klass, Qundef, def->body.proc);
346  break;
347  default:;
348  /* ignore */
349  }
350  }
351 
352  /* check mid */
353  if (klass == rb_cObject && mid == idInitialize) {
354  rb_warn("redefining Object#initialize may cause infinite loop");
355  }
356  /* check mid */
357  if (mid == object_id || mid == id__send__) {
358  if (type == VM_METHOD_TYPE_ISEQ) {
359  rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
360  }
361  }
362 
363  if (make_refined) {
365  }
366 
367  st_insert(mtbl, mid, (st_data_t) me);
368 
369  return me;
370 }
371 
372 #define CALL_METHOD_HOOK(klass, hook, mid) do { \
373  const VALUE arg = ID2SYM(mid); \
374  VALUE recv_class = (klass); \
375  ID hook_id = (hook); \
376  if (FL_TEST((klass), FL_SINGLETON)) { \
377  recv_class = rb_ivar_get((klass), attached); \
378  hook_id = singleton_##hook; \
379  } \
380  rb_funcall2(recv_class, hook_id, 1, &arg); \
381  } while (0)
382 
383 static void
384 method_added(VALUE klass, ID mid)
385 {
386  if (ruby_running) {
387  CALL_METHOD_HOOK(klass, added, mid);
388  }
389 }
390 
391 static VALUE
392 (*call_cfunc_invoker_func(int argc))(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *)
393 {
394  switch (argc) {
395  case -2: return &call_cfunc_m2;
396  case -1: return &call_cfunc_m1;
397  case 0: return &call_cfunc_0;
398  case 1: return &call_cfunc_1;
399  case 2: return &call_cfunc_2;
400  case 3: return &call_cfunc_3;
401  case 4: return &call_cfunc_4;
402  case 5: return &call_cfunc_5;
403  case 6: return &call_cfunc_6;
404  case 7: return &call_cfunc_7;
405  case 8: return &call_cfunc_8;
406  case 9: return &call_cfunc_9;
407  case 10: return &call_cfunc_10;
408  case 11: return &call_cfunc_11;
409  case 12: return &call_cfunc_12;
410  case 13: return &call_cfunc_13;
411  case 14: return &call_cfunc_14;
412  case 15: return &call_cfunc_15;
413  default:
414  rb_bug("call_cfunc_func: unsupported length: %d", argc);
415  }
416 }
417 
418 static void
420 {
421  cfunc->func = func;
422  cfunc->argc = argc;
423  cfunc->invoker = call_cfunc_invoker_func(argc);
424 }
425 
428 {
429  rb_thread_t *th;
430  rb_control_frame_t *cfp;
431  int line;
432  rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, 0, noex, klass);
434  if (me->def && me->def->type == VM_METHOD_TYPE_REFINED) {
435  me->def->body.orig_me->def = def;
436  }
437  else {
438  me->def = def;
439  }
440  def->type = type;
441  def->original_id = mid;
442  def->alias_count = 0;
443  switch (type) {
444  case VM_METHOD_TYPE_ISEQ: {
445  rb_iseq_t *iseq = (rb_iseq_t *)opts;
446  *(rb_iseq_t **)&def->body.iseq = iseq;
447  RB_OBJ_WRITTEN(klass, Qundef, iseq->self);
448  break;
449  }
451  {
452  rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
453  setup_method_cfunc_struct(&def->body.cfunc, cfunc->func, cfunc->argc);
454  }
455  break;
457  case VM_METHOD_TYPE_IVAR:
458  def->body.attr.id = (ID)opts;
459  RB_OBJ_WRITE(klass, &def->body.attr.location, Qfalse);
460  th = GET_THREAD();
461  cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
462  if (cfp && (line = rb_vm_get_sourceline(cfp))) {
463  VALUE location = rb_ary_new3(2, cfp->iseq->location.path, INT2FIX(line));
464  RB_OBJ_WRITE(klass, &def->body.attr.location, rb_ary_freeze(location));
465  }
466  break;
468  RB_OBJ_WRITE(klass, &def->body.proc, (VALUE)opts);
469  break;
472  break;
474  def->body.optimize_type = (enum method_optimized_type)opts;
475  break;
478  break;
480  def->body.orig_me = (rb_method_entry_t *) opts;
481  break;
482  default:
483  rb_bug("rb_add_method: unsupported method type (%d)\n", type);
484  }
485  if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
486  method_added(klass, mid);
487  }
488  return me;
489 }
490 
491 static rb_method_entry_t *
493  rb_method_flag_t noex, VALUE defined_class)
494 {
496  rb_method_entry_t *newme = rb_method_entry_make(klass, mid, type, me->def, noex,
497  defined_class);
498  method_added(klass, mid);
499  return newme;
500 }
501 
504 {
505  return method_entry_set(klass, mid, me, noex, klass);
506 }
507 
508 #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1)
509 
510 void
512 {
513  Check_Type(klass, T_CLASS);
514  RCLASS_EXT(klass)->allocator = func;
515 }
516 
517 void
519 {
521 }
522 
525 {
526  Check_Type(klass, T_CLASS);
527 
528  for (; klass; klass = RCLASS_SUPER(klass)) {
529  rb_alloc_func_t allocator = RCLASS_EXT(klass)->allocator;
530  if (allocator == UNDEF_ALLOC_FUNC) break;
531  if (allocator) return allocator;
532  }
533  return 0;
534 }
535 
536 static inline rb_method_entry_t*
537 search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
538 {
540 
541  for (me = 0; klass; klass = RCLASS_SUPER(klass)) {
542  if ((me = lookup_method_table(klass, id)) != 0) break;
543  }
544 
545  if (defined_class_ptr)
546  *defined_class_ptr = klass;
547  return me;
548 }
549 
552 {
553  return lookup_method_table(klass, id);
554 }
555 
556 /*
557  * search method entry without the method cache.
558  *
559  * if you need method entry with method cache (normal case), use
560  * rb_method_entry() simply.
561  */
564  VALUE *defined_class_ptr)
565 {
566  VALUE defined_class;
567  rb_method_entry_t *me = search_method(klass, id, &defined_class);
568 
569  if (me && me->klass) {
570  switch (BUILTIN_TYPE(me->klass)) {
571  case T_CLASS:
572  if (RBASIC(klass)->flags & FL_SINGLETON) break;
573  /* fall through */
574  case T_ICLASS:
575  defined_class = me->klass;
576  }
577  }
578 
579  if (ruby_running) {
580  struct cache_entry *ent;
581  ent = GLOBAL_METHOD_CACHE(klass, id);
582  ent->class_serial = RCLASS_EXT(klass)->class_serial;
585  ent->mid = id;
586 
587  if (UNDEFINED_METHOD_ENTRY_P(me)) {
588  ent->me = 0;
589  me = 0;
590  }
591  else {
592  ent->me = me;
593  }
594  }
595 
596  if (defined_class_ptr)
597  *defined_class_ptr = defined_class;
598  return me;
599 }
600 
601 #if VM_DEBUG_VERIFY_METHOD_CACHE
602 static void
603 verify_method_cache(VALUE klass, ID id, VALUE defined_class, rb_method_entry_t *me)
604 {
605  VALUE actual_defined_class;
606  rb_method_entry_t *actual_me =
607  rb_method_entry_get_without_cache(klass, id, &actual_defined_class);
608 
609  if (me != actual_me || defined_class != actual_defined_class) {
610  rb_bug("method cache verification failed");
611  }
612 }
613 #endif
614 
616 rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr)
617 {
618 #if OPT_GLOBAL_METHOD_CACHE
619  struct cache_entry *ent;
620  ent = GLOBAL_METHOD_CACHE(klass, id);
621  if (ent->method_state == GET_GLOBAL_METHOD_STATE() &&
622  ent->class_serial == RCLASS_EXT(klass)->class_serial &&
623  ent->mid == id) {
624  if (defined_class_ptr)
625  *defined_class_ptr = ent->defined_class;
626 #if VM_DEBUG_VERIFY_METHOD_CACHE
627  verify_method_cache(klass, id, ent->defined_class, ent->me);
628 #endif
629  return ent->me;
630  }
631 #endif
632 
633  return rb_method_entry_get_without_cache(klass, id, defined_class_ptr);
634 }
635 
636 static rb_method_entry_t *
638  const rb_method_entry_t *me,
639  VALUE *defined_class_ptr)
640 {
641  if (me->def->body.orig_me) {
642  return me->def->body.orig_me;
643  }
644  else {
645  rb_method_entry_t *tmp_me;
646  tmp_me = rb_method_entry(RCLASS_SUPER(me->klass), me->called_id,
647  defined_class_ptr);
648  return rb_resolve_refined_method(refinements, tmp_me,
649  defined_class_ptr);
650  }
651 }
652 
655  VALUE *defined_class_ptr)
656 {
657  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
658  VALUE refinement;
659  rb_method_entry_t *tmp_me;
660 
661  refinement = find_refinement(refinements, me->klass);
662  if (NIL_P(refinement)) {
663  return get_original_method_entry(refinements, me,
664  defined_class_ptr);
665  }
666  tmp_me = rb_method_entry(refinement, me->called_id,
667  defined_class_ptr);
668  if (tmp_me && tmp_me->def->type != VM_METHOD_TYPE_REFINED) {
669  return tmp_me;
670  }
671  else {
672  return get_original_method_entry(refinements, me,
673  defined_class_ptr);
674  }
675  }
676  else {
677  return (rb_method_entry_t *)me;
678  }
679 }
680 
683  VALUE *defined_class_ptr)
684 {
686  rb_method_entry_t *me = rb_method_entry(klass, id, &defined_class);
687 
688  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
689  NODE *cref = rb_vm_cref();
690  VALUE refinements = cref ? cref->nd_refinements : Qnil;
691 
692  me = rb_resolve_refined_method(refinements, me, &defined_class);
693  }
694  if (defined_class_ptr)
695  *defined_class_ptr = defined_class;
696  return me;
697 }
698 
701  VALUE *defined_class_ptr)
702 {
704  rb_method_entry_t *me = rb_method_entry(klass, id, &defined_class);
705 
706  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
707  me = rb_resolve_refined_method(Qnil, me, &defined_class);
708  }
709  if (defined_class_ptr)
710  *defined_class_ptr = defined_class;
711  if (UNDEFINED_METHOD_ENTRY_P(me)) {
712  return 0;
713  }
714  else {
715  return me;
716  }
717 }
718 
719 static void
720 remove_method(VALUE klass, ID mid)
721 {
722  st_data_t key, data;
723  rb_method_entry_t *me = 0;
724  VALUE self = klass;
725 
726  klass = RCLASS_ORIGIN(klass);
727  rb_check_frozen(klass);
728  if (mid == object_id || mid == id__send__ || mid == idInitialize) {
729  rb_warn("removing `%s' may cause serious problems", rb_id2name(mid));
730  }
731 
732  if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) ||
733  !(me = (rb_method_entry_t *)data) ||
734  (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF)) {
735  rb_name_error(mid, "method `%s' not defined in %s",
736  rb_id2name(mid), rb_class2name(klass));
737  }
738  key = (st_data_t)mid;
739  st_delete(RCLASS_M_TBL(klass), &key, &data);
740 
744 
745  CALL_METHOD_HOOK(self, removed, mid);
746 }
747 
748 void
750 {
751  remove_method(klass, mid);
752 }
753 
754 void
755 rb_remove_method(VALUE klass, const char *name)
756 {
757  remove_method(klass, rb_intern(name));
758 }
759 
760 /*
761  * call-seq:
762  * remove_method(symbol) -> self
763  * remove_method(string) -> self
764  *
765  * Removes the method identified by _symbol_ from the current
766  * class. For an example, see <code>Module.undef_method</code>.
767  * String arguments are converted to symbols.
768  */
769 
770 static VALUE
772 {
773  int i;
774 
775  for (i = 0; i < argc; i++) {
776  VALUE v = argv[i];
777  ID id = rb_check_id(&v);
778  if (!id) {
779  rb_name_error_str(v, "method `%s' not defined in %s",
780  RSTRING_PTR(v), rb_class2name(mod));
781  }
782  remove_method(mod, id);
783  }
784  return mod;
785 }
786 
787 #undef rb_disable_super
788 #undef rb_enable_super
789 
790 void
791 rb_disable_super(VALUE klass, const char *name)
792 {
793  /* obsolete - no use */
794 }
795 
796 void
797 rb_enable_super(VALUE klass, const char *name)
798 {
799  rb_warning("rb_enable_super() is obsolete");
800 }
801 
802 static void
804 {
807 
808  me = search_method(klass, name, &defined_class);
809  if (!me && RB_TYPE_P(klass, T_MODULE)) {
810  me = search_method(rb_cObject, name, &defined_class);
811  }
812 
813  if (UNDEFINED_METHOD_ENTRY_P(me)) {
814  rb_print_undef(klass, name, 0);
815  }
816 
817  if (me->flag != noex) {
819 
820  if (klass == defined_class ||
821  RCLASS_ORIGIN(klass) == defined_class) {
822  me->flag = noex;
823  if (me->def->type == VM_METHOD_TYPE_REFINED) {
824  me->def->body.orig_me->flag = noex;
825  }
827  }
828  else {
829  rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, noex);
830  }
831  }
832 }
833 
834 int
835 rb_method_boundp(VALUE klass, ID id, int ex)
836 {
837  rb_method_entry_t *me =
839 
840  if (me != 0) {
841  if ((ex & ~NOEX_RESPONDS) &&
842  ((me->flag & NOEX_PRIVATE) ||
843  ((ex & NOEX_RESPONDS) && (me->flag & NOEX_PROTECTED)))) {
844  return 0;
845  }
846  if (!me->def) return 0;
847  if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
848  if (ex & NOEX_RESPONDS) return 2;
849  return 0;
850  }
851  return 1;
852  }
853  return 0;
854 }
855 
856 extern ID rb_check_attr_id(ID id);
857 
858 void
859 rb_attr(VALUE klass, ID id, int read, int write, int ex)
860 {
861  ID attriv;
862  VALUE aname;
863  rb_method_flag_t noex;
864 
865  if (!ex) {
866  noex = NOEX_PUBLIC;
867  }
868  else {
869  if (SCOPE_TEST(NOEX_PRIVATE)) {
870  noex = NOEX_PRIVATE;
872  "attribute accessor as module_function" :
873  "private attribute?");
874  }
875  else if (SCOPE_TEST(NOEX_PROTECTED)) {
876  noex = NOEX_PROTECTED;
877  }
878  else {
879  noex = NOEX_PUBLIC;
880  }
881  }
882 
883  aname = rb_id2str(rb_check_attr_id(id));
884  if (NIL_P(aname)) {
885  rb_raise(rb_eArgError, "argument needs to be symbol or string");
886  }
887  attriv = rb_intern_str(rb_sprintf("@%"PRIsVALUE, aname));
888  if (read) {
889  rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, noex);
890  }
891  if (write) {
892  rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, noex);
893  }
894 }
895 
896 void
897 rb_undef(VALUE klass, ID id)
898 {
900 
901  if (NIL_P(klass)) {
902  rb_raise(rb_eTypeError, "no class to undef method");
903  }
904  rb_frozen_class_p(klass);
905  if (id == object_id || id == id__send__ || id == idInitialize) {
906  rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
907  }
908 
909  me = search_method(klass, id, 0);
910 
911  if (UNDEFINED_METHOD_ENTRY_P(me) ||
912  (me->def->type == VM_METHOD_TYPE_REFINED &&
914  const char *s0 = " class";
915  VALUE c = klass;
916 
917  if (FL_TEST(c, FL_SINGLETON)) {
918  VALUE obj = rb_ivar_get(klass, attached);
919 
920  if (RB_TYPE_P(obj, T_MODULE) || RB_TYPE_P(obj, T_CLASS)) {
921  c = obj;
922  s0 = "";
923  }
924  }
925  else if (RB_TYPE_P(c, T_MODULE)) {
926  s0 = " module";
927  }
928  rb_name_error(id, "undefined method `%"PRIsVALUE"' for%s `%"PRIsVALUE"'",
929  QUOTE_ID(id), s0, rb_class_name(c));
930  }
931 
933 
934  CALL_METHOD_HOOK(klass, undefined, id);
935 }
936 
937 /*
938  * call-seq:
939  * undef_method(symbol) -> self
940  * undef_method(string) -> self
941  *
942  * Prevents the current class from responding to calls to the named
943  * method. Contrast this with <code>remove_method</code>, which deletes
944  * the method from the particular class; Ruby will still search
945  * superclasses and mixed-in modules for a possible receiver.
946  * String arguments are converted to symbols.
947  *
948  * class Parent
949  * def hello
950  * puts "In parent"
951  * end
952  * end
953  * class Child < Parent
954  * def hello
955  * puts "In child"
956  * end
957  * end
958  *
959  *
960  * c = Child.new
961  * c.hello
962  *
963  *
964  * class Child
965  * remove_method :hello # remove from child, still in parent
966  * end
967  * c.hello
968  *
969  *
970  * class Child
971  * undef_method :hello # prevent any calls to 'hello'
972  * end
973  * c.hello
974  *
975  * <em>produces:</em>
976  *
977  * In child
978  * In parent
979  * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
980  */
981 
982 static VALUE
984 {
985  int i;
986  for (i = 0; i < argc; i++) {
987  VALUE v = argv[i];
988  ID id = rb_check_id(&v);
989  if (!id) {
990  rb_method_name_error(mod, v);
991  }
992  rb_undef(mod, id);
993  }
994  return mod;
995 }
996 
997 /*
998  * call-seq:
999  * mod.method_defined?(symbol) -> true or false
1000  * mod.method_defined?(string) -> true or false
1001  *
1002  * Returns +true+ if the named method is defined by
1003  * _mod_ (or its included modules and, if _mod_ is a class,
1004  * its ancestors). Public and protected methods are matched.
1005  * String arguments are converted to symbols.
1006  *
1007  * module A
1008  * def method1() end
1009  * end
1010  * class B
1011  * def method2() end
1012  * end
1013  * class C < B
1014  * include A
1015  * def method3() end
1016  * end
1017  *
1018  * A.method_defined? :method1 #=> true
1019  * C.method_defined? "method1" #=> true
1020  * C.method_defined? "method2" #=> true
1021  * C.method_defined? "method3" #=> true
1022  * C.method_defined? "method4" #=> false
1023  */
1024 
1025 static VALUE
1027 {
1028  ID id = rb_check_id(&mid);
1029  if (!id || !rb_method_boundp(mod, id, 1)) {
1030  return Qfalse;
1031  }
1032  return Qtrue;
1033 
1034 }
1035 
1036 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
1037 
1038 static VALUE
1040 {
1041  const rb_method_entry_t *me;
1042  ID id = rb_check_id(&mid);
1043  if (!id) return Qfalse;
1044  me = rb_method_entry(mod, id, 0);
1045  if (me) {
1046  if (VISI_CHECK(me->flag, noex))
1047  return Qtrue;
1048  }
1049  return Qfalse;
1050 }
1051 
1052 /*
1053  * call-seq:
1054  * mod.public_method_defined?(symbol) -> true or false
1055  * mod.public_method_defined?(string) -> true or false
1056  *
1057  * Returns +true+ if the named public method is defined by
1058  * _mod_ (or its included modules and, if _mod_ is a class,
1059  * its ancestors).
1060  * String arguments are converted to symbols.
1061  *
1062  * module A
1063  * def method1() end
1064  * end
1065  * class B
1066  * protected
1067  * def method2() end
1068  * end
1069  * class C < B
1070  * include A
1071  * def method3() end
1072  * end
1073  *
1074  * A.method_defined? :method1 #=> true
1075  * C.public_method_defined? "method1" #=> true
1076  * C.public_method_defined? "method2" #=> false
1077  * C.method_defined? "method2" #=> true
1078  */
1079 
1080 static VALUE
1082 {
1083  return check_definition(mod, mid, NOEX_PUBLIC);
1084 }
1085 
1086 /*
1087  * call-seq:
1088  * mod.private_method_defined?(symbol) -> true or false
1089  * mod.private_method_defined?(string) -> true or false
1090  *
1091  * Returns +true+ if the named private method is defined by
1092  * _ mod_ (or its included modules and, if _mod_ is a class,
1093  * its ancestors).
1094  * String arguments are converted to symbols.
1095  *
1096  * module A
1097  * def method1() end
1098  * end
1099  * class B
1100  * private
1101  * def method2() end
1102  * end
1103  * class C < B
1104  * include A
1105  * def method3() end
1106  * end
1107  *
1108  * A.method_defined? :method1 #=> true
1109  * C.private_method_defined? "method1" #=> false
1110  * C.private_method_defined? "method2" #=> true
1111  * C.method_defined? "method2" #=> false
1112  */
1113 
1114 static VALUE
1116 {
1117  return check_definition(mod, mid, NOEX_PRIVATE);
1118 }
1119 
1120 /*
1121  * call-seq:
1122  * mod.protected_method_defined?(symbol) -> true or false
1123  * mod.protected_method_defined?(string) -> true or false
1124  *
1125  * Returns +true+ if the named protected method is defined
1126  * by _mod_ (or its included modules and, if _mod_ is a
1127  * class, its ancestors).
1128  * String arguments are converted to symbols.
1129  *
1130  * module A
1131  * def method1() end
1132  * end
1133  * class B
1134  * protected
1135  * def method2() end
1136  * end
1137  * class C < B
1138  * include A
1139  * def method3() end
1140  * end
1141  *
1142  * A.method_defined? :method1 #=> true
1143  * C.protected_method_defined? "method1" #=> false
1144  * C.protected_method_defined? "method2" #=> true
1145  * C.method_defined? "method2" #=> true
1146  */
1147 
1148 static VALUE
1150 {
1151  return check_definition(mod, mid, NOEX_PROTECTED);
1152 }
1153 
1154 int
1156 {
1157  return rb_method_definition_eq(m1->def, m2->def);
1158 }
1159 
1160 static int
1162 {
1163  if (d1 && d1->type == VM_METHOD_TYPE_REFINED && d1->body.orig_me)
1164  d1 = d1->body.orig_me->def;
1165  if (d2 && d2->type == VM_METHOD_TYPE_REFINED && d2->body.orig_me)
1166  d2 = d2->body.orig_me->def;
1167  if (d1 == d2) return 1;
1168  if (!d1 || !d2) return 0;
1169  if (d1->type != d2->type) {
1170  return 0;
1171  }
1172  switch (d1->type) {
1173  case VM_METHOD_TYPE_ISEQ:
1174  return d1->body.iseq == d2->body.iseq;
1175  case VM_METHOD_TYPE_CFUNC:
1176  return
1177  d1->body.cfunc.func == d2->body.cfunc.func &&
1178  d1->body.cfunc.argc == d2->body.cfunc.argc;
1180  case VM_METHOD_TYPE_IVAR:
1181  return d1->body.attr.id == d2->body.attr.id;
1183  return RTEST(rb_equal(d1->body.proc, d2->body.proc));
1185  return d1->original_id == d2->original_id;
1186  case VM_METHOD_TYPE_ZSUPER:
1188  case VM_METHOD_TYPE_UNDEF:
1189  return 1;
1191  return d1->body.optimize_type == d2->body.optimize_type;
1192  default:
1193  rb_bug("rb_method_entry_eq: unsupported method type (%d)\n", d1->type);
1194  return 0;
1195  }
1196 }
1197 
1198 static st_index_t
1200 {
1201  again:
1202  hash = rb_hash_uint(hash, def->type);
1203  switch (def->type) {
1204  case VM_METHOD_TYPE_ISEQ:
1205  return rb_hash_uint(hash, (st_index_t)def->body.iseq);
1206  case VM_METHOD_TYPE_CFUNC:
1207  hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
1208  return rb_hash_uint(hash, def->body.cfunc.argc);
1210  case VM_METHOD_TYPE_IVAR:
1211  return rb_hash_uint(hash, def->body.attr.id);
1213  return rb_hash_proc(hash, def->body.proc);
1215  return rb_hash_uint(hash, def->original_id);
1216  case VM_METHOD_TYPE_ZSUPER:
1218  case VM_METHOD_TYPE_UNDEF:
1219  return hash;
1221  return rb_hash_uint(hash, def->body.optimize_type);
1223  if (def->body.orig_me) {
1224  def = def->body.orig_me->def;
1225  goto again;
1226  }
1227  else {
1228  return hash;
1229  }
1230  default:
1231  rb_bug("rb_hash_method_definition: unsupported method type (%d)\n", def->type);
1232  }
1233  return hash;
1234 }
1235 
1236 st_index_t
1238 {
1239  return rb_hash_method_definition(hash, me->def);
1240 }
1241 
1242 void
1243 rb_alias(VALUE klass, ID name, ID def)
1244 {
1245  VALUE target_klass = klass;
1247  rb_method_entry_t *orig_me;
1249 
1250  if (NIL_P(klass)) {
1251  rb_raise(rb_eTypeError, "no class to make alias");
1252  }
1253 
1254  rb_frozen_class_p(klass);
1255 
1256  again:
1257  orig_me = search_method(klass, def, &defined_class);
1258 
1259  if (UNDEFINED_METHOD_ENTRY_P(orig_me)) {
1260  if ((!RB_TYPE_P(klass, T_MODULE)) ||
1261  (orig_me = search_method(rb_cObject, def, 0),
1262  UNDEFINED_METHOD_ENTRY_P(orig_me))) {
1263  rb_print_undef(klass, def, 0);
1264  }
1265  }
1266  if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {
1267  klass = RCLASS_SUPER(klass);
1268  def = orig_me->def->original_id;
1269  flag = orig_me->flag;
1270  goto again;
1271  }
1272  if (RB_TYPE_P(defined_class, T_ICLASS)) {
1273  VALUE real_class = RBASIC_CLASS(defined_class);
1274  if (real_class && RCLASS_ORIGIN(real_class) == defined_class)
1275  defined_class = real_class;
1276  }
1277 
1278  if (flag == NOEX_UNDEF) flag = orig_me->flag;
1279  method_entry_set(target_klass, name, orig_me, flag, defined_class);
1280 }
1281 
1282 /*
1283  * call-seq:
1284  * alias_method(new_name, old_name) -> self
1285  *
1286  * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
1287  * be used to retain access to methods that are overridden.
1288  *
1289  * module Mod
1290  * alias_method :orig_exit, :exit
1291  * def exit(code=0)
1292  * puts "Exiting with code #{code}"
1293  * orig_exit(code)
1294  * end
1295  * end
1296  * include Mod
1297  * exit(99)
1298  *
1299  * <em>produces:</em>
1300  *
1301  * Exiting with code 99
1302  */
1303 
1304 static VALUE
1306 {
1307  ID oldid = rb_check_id(&oldname);
1308  if (!oldid) {
1309  rb_print_undef_str(mod, oldname);
1310  }
1311  rb_alias(mod, rb_to_id(newname), oldid);
1312  return mod;
1313 }
1314 
1315 static void
1317 {
1318  int i;
1319 
1320  if (argc == 0) {
1321  rb_warning("%"PRIsVALUE" with no argument is just ignored",
1323  return;
1324  }
1325 
1326  for (i = 0; i < argc; i++) {
1327  VALUE v = argv[i];
1328  ID id = rb_check_id(&v);
1329  if (!id) {
1330  rb_print_undef_str(self, v);
1331  }
1332  rb_export_method(self, id, ex);
1333  }
1334 }
1335 
1336 static VALUE
1338 {
1339  if (argc == 0) {
1340  SCOPE_SET(ex);
1341  }
1342  else {
1343  set_method_visibility(module, argc, argv, ex);
1344  }
1345  return module;
1346 }
1347 
1348 /*
1349  * call-seq:
1350  * public -> self
1351  * public(symbol, ...) -> self
1352  * public(string, ...) -> self
1353  *
1354  * With no arguments, sets the default visibility for subsequently
1355  * defined methods to public. With arguments, sets the named methods to
1356  * have public visibility.
1357  * String arguments are converted to symbols.
1358  */
1359 
1360 static VALUE
1361 rb_mod_public(int argc, VALUE *argv, VALUE module)
1362 {
1363  return set_visibility(argc, argv, module, NOEX_PUBLIC);
1364 }
1365 
1366 /*
1367  * call-seq:
1368  * protected -> self
1369  * protected(symbol, ...) -> self
1370  * protected(string, ...) -> self
1371  *
1372  * With no arguments, sets the default visibility for subsequently
1373  * defined methods to protected. With arguments, sets the named methods
1374  * to have protected visibility.
1375  * String arguments are converted to symbols.
1376  */
1377 
1378 static VALUE
1379 rb_mod_protected(int argc, VALUE *argv, VALUE module)
1380 {
1381  return set_visibility(argc, argv, module, NOEX_PROTECTED);
1382 }
1383 
1384 /*
1385  * call-seq:
1386  * private -> self
1387  * private(symbol, ...) -> self
1388  * private(string, ...) -> self
1389  *
1390  * With no arguments, sets the default visibility for subsequently
1391  * defined methods to private. With arguments, sets the named methods
1392  * to have private visibility.
1393  * String arguments are converted to symbols.
1394  *
1395  * module Mod
1396  * def a() end
1397  * def b() end
1398  * private
1399  * def c() end
1400  * private :a
1401  * end
1402  * Mod.private_instance_methods #=> [:a, :c]
1403  */
1404 
1405 static VALUE
1406 rb_mod_private(int argc, VALUE *argv, VALUE module)
1407 {
1408  return set_visibility(argc, argv, module, NOEX_PRIVATE);
1409 }
1410 
1411 /*
1412  * call-seq:
1413  * mod.public_class_method(symbol, ...) -> mod
1414  * mod.public_class_method(string, ...) -> mod
1415  *
1416  * Makes a list of existing class methods public.
1417  *
1418  * String arguments are converted to symbols.
1419  */
1420 
1421 static VALUE
1423 {
1425  return obj;
1426 }
1427 
1428 /*
1429  * call-seq:
1430  * mod.private_class_method(symbol, ...) -> mod
1431  * mod.private_class_method(string, ...) -> mod
1432  *
1433  * Makes existing class methods private. Often used to hide the default
1434  * constructor <code>new</code>.
1435  *
1436  * String arguments are converted to symbols.
1437  *
1438  * class SimpleSingleton # Not thread safe
1439  * private_class_method :new
1440  * def SimpleSingleton.create(*args, &block)
1441  * @me = new(*args, &block) if ! @me
1442  * @me
1443  * end
1444  * end
1445  */
1446 
1447 static VALUE
1449 {
1451  return obj;
1452 }
1453 
1454 /*
1455  * call-seq:
1456  * public
1457  * public(symbol, ...)
1458  * public(string, ...)
1459  *
1460  * With no arguments, sets the default visibility for subsequently
1461  * defined methods to public. With arguments, sets the named methods to
1462  * have public visibility.
1463  *
1464  * String arguments are converted to symbols.
1465  */
1466 
1467 static VALUE
1468 top_public(int argc, VALUE *argv)
1469 {
1470  return rb_mod_public(argc, argv, rb_cObject);
1471 }
1472 
1473 /*
1474  * call-seq:
1475  * private
1476  * private(symbol, ...)
1477  * private(string, ...)
1478  *
1479  * With no arguments, sets the default visibility for subsequently
1480  * defined methods to private. With arguments, sets the named methods to
1481  * have private visibility.
1482  *
1483  * String arguments are converted to symbols.
1484  */
1485 static VALUE
1487 {
1488  return rb_mod_private(argc, argv, rb_cObject);
1489 }
1490 
1491 /*
1492  * call-seq:
1493  * module_function(symbol, ...) -> self
1494  * module_function(string, ...) -> self
1495  *
1496  * Creates module functions for the named methods. These functions may
1497  * be called with the module as a receiver, and also become available
1498  * as instance methods to classes that mix in the module. Module
1499  * functions are copies of the original, and so may be changed
1500  * independently. The instance-method versions are made private. If
1501  * used with no arguments, subsequently defined methods become module
1502  * functions.
1503  * String arguments are converted to symbols.
1504  *
1505  * module Mod
1506  * def one
1507  * "This is one"
1508  * end
1509  * module_function :one
1510  * end
1511  * class Cls
1512  * include Mod
1513  * def call_one
1514  * one
1515  * end
1516  * end
1517  * Mod.one #=> "This is one"
1518  * c = Cls.new
1519  * c.call_one #=> "This is one"
1520  * module Mod
1521  * def one
1522  * "This is the new one"
1523  * end
1524  * end
1525  * Mod.one #=> "This is one"
1526  * c.call_one #=> "This is the new one"
1527  */
1528 
1529 static VALUE
1530 rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
1531 {
1532  int i;
1533  ID id;
1534  const rb_method_entry_t *me;
1535 
1536  if (!RB_TYPE_P(module, T_MODULE)) {
1537  rb_raise(rb_eTypeError, "module_function must be called for modules");
1538  }
1539 
1540  if (argc == 0) {
1542  return module;
1543  }
1544 
1545  set_method_visibility(module, argc, argv, NOEX_PRIVATE);
1546 
1547  for (i = 0; i < argc; i++) {
1548  VALUE m = module;
1549 
1550  id = rb_to_id(argv[i]);
1551  for (;;) {
1552  me = search_method(m, id, 0);
1553  if (me == 0) {
1554  me = search_method(rb_cObject, id, 0);
1555  }
1556  if (UNDEFINED_METHOD_ENTRY_P(me)) {
1557  rb_print_undef(module, id, 0);
1558  }
1559  if (me->def->type != VM_METHOD_TYPE_ZSUPER) {
1560  break; /* normal case: need not to follow 'super' link */
1561  }
1562  m = RCLASS_SUPER(m);
1563  if (!m)
1564  break;
1565  }
1567  }
1568  return module;
1569 }
1570 
1571 int
1573 {
1574  const rb_method_entry_t *me = rb_method_entry(klass, id, 0);
1575  if (me && (me->flag & NOEX_BASIC))
1576  return 1;
1577  return 0;
1578 }
1579 
1580 static inline int
1581 basic_obj_respond_to(VALUE obj, ID id, int pub)
1582 {
1583  VALUE klass = CLASS_OF(obj);
1584  VALUE args[2];
1585 
1586  switch (rb_method_boundp(klass, id, pub|NOEX_RESPONDS)) {
1587  case 2:
1588  return FALSE;
1589  case 0:
1590  args[0] = ID2SYM(id);
1591  args[1] = pub ? Qfalse : Qtrue;
1592  return RTEST(rb_funcall2(obj, idRespond_to_missing, 2, args));
1593  default:
1594  return TRUE;
1595  }
1596 }
1597 
1598 int
1599 rb_obj_respond_to(VALUE obj, ID id, int priv)
1600 {
1601  VALUE klass = CLASS_OF(obj);
1602 
1604  return basic_obj_respond_to(obj, id, !RTEST(priv));
1605  }
1606  else {
1607  int argc = 1;
1608  VALUE args[2];
1609  args[0] = ID2SYM(id);
1610  args[1] = Qtrue;
1611  if (priv) {
1612  if (rb_obj_method_arity(obj, idRespond_to) != 1) {
1613  argc = 2;
1614  }
1615  else if (!NIL_P(ruby_verbose)) {
1616  VALUE klass = CLASS_OF(obj);
1617  VALUE location = rb_mod_method_location(klass, idRespond_to);
1618  rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") is"
1619  " old fashion which takes only one parameter",
1620  (FL_TEST(klass, FL_SINGLETON) ? obj : klass),
1621  (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
1622  QUOTE_ID(id));
1623  if (!NIL_P(location)) {
1624  VALUE path = RARRAY_AREF(location, 0);
1625  VALUE line = RARRAY_AREF(location, 1);
1626  if (!NIL_P(path)) {
1627  rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
1628  "respond_to? is defined here");
1629  }
1630  }
1631  }
1632  }
1633  return RTEST(rb_funcall2(obj, idRespond_to, argc, args));
1634  }
1635 }
1636 
1637 int
1639 {
1640  return rb_obj_respond_to(obj, id, FALSE);
1641 }
1642 
1643 
1644 /*
1645  * call-seq:
1646  * obj.respond_to?(symbol, include_all=false) -> true or false
1647  * obj.respond_to?(string, include_all=false) -> true or false
1648  *
1649  * Returns +true+ if _obj_ responds to the given method. Private and
1650  * protected methods are included in the search only if the optional
1651  * second parameter evaluates to +true+.
1652  *
1653  * If the method is not implemented,
1654  * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
1655  * false is returned.
1656  *
1657  * If the method is not defined, <code>respond_to_missing?</code>
1658  * method is called and the result is returned.
1659  *
1660  * When the method name parameter is given as a string, the string is
1661  * converted to a symbol.
1662  */
1663 
1664 static VALUE
1665 obj_respond_to(int argc, VALUE *argv, VALUE obj)
1666 {
1667  VALUE mid, priv;
1668  ID id;
1669 
1670  rb_scan_args(argc, argv, "11", &mid, &priv);
1671  if (!(id = rb_check_id(&mid))) {
1673  VALUE args[2];
1674  args[0] = ID2SYM(rb_to_id(mid));
1675  args[1] = priv;
1676  return rb_funcall2(obj, idRespond_to_missing, 2, args);
1677  }
1678  return Qfalse;
1679  }
1680  if (basic_obj_respond_to(obj, id, !RTEST(priv)))
1681  return Qtrue;
1682  return Qfalse;
1683 }
1684 
1685 /*
1686  * call-seq:
1687  * obj.respond_to_missing?(symbol, include_all) -> true or false
1688  * obj.respond_to_missing?(string, include_all) -> true or false
1689  *
1690  * DO NOT USE THIS DIRECTLY.
1691  *
1692  * Hook method to return whether the _obj_ can respond to _id_ method
1693  * or not.
1694  *
1695  * When the method name parameter is given as a string, the string is
1696  * converted to a symbol.
1697  *
1698  * See #respond_to?, and the example of BasicObject.
1699  */
1700 static VALUE
1702 {
1703  return Qfalse;
1704 }
1705 
1706 void
1708 {
1709 #undef rb_intern
1710 #define rb_intern(str) rb_intern_const(str)
1711 
1712  rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
1713  rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
1714 
1721  rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
1722 
1723  rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
1724  rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
1725  rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
1726  rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
1727  rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
1728  rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
1729 
1731  "public", top_public, -1);
1733  "private", top_private, -1);
1734 
1735  {
1736 #define REPLICATE_METHOD(klass, id, noex) \
1737  rb_method_entry_set((klass), (id), \
1738  rb_method_entry((klass), (id), 0), \
1739  (rb_method_flag_t)(noex | NOEX_BASIC | NOEX_NOREDEF))
1740  REPLICATE_METHOD(rb_eException, idMethodMissing, NOEX_PRIVATE);
1743  }
1744 }
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:374
struct unlinked_method_entry_list_entry * next
Definition: method.h:106
int rb_method_boundp(VALUE klass, ID id, int ex)
Definition: vm_method.c:835
rb_control_frame_t * cfp
Definition: vm_core.h:531
char mark
Definition: method.h:99
static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
Definition: vm_method.c:1161
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:110
static VALUE rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1422
static VALUE call_cfunc_0(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static void rb_class_clear_method_cache(VALUE klass)
Definition: vm_method.c:45
void rb_bug(const char *fmt,...)
Definition: error.c:327
rb_method_type_t type
Definition: method.h:79
rb_method_entry_t * rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:616
#define FALSE
Definition: nkf.h:174
rb_method_entry_t * rb_method_entry_at(VALUE klass, ID id)
Definition: vm_method.c:551
rb_method_entry_t * me
Definition: vm_method.c:36
rb_method_attr_t attr
Definition: method.h:84
static VALUE set_visibility(int argc, VALUE *argv, VALUE module, rb_method_flag_t ex)
Definition: vm_method.c:1337
static VALUE rb_mod_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1026
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:397
static VALUE rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
Definition: vm_method.c:1305
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
Definition: vm_backtrace.c:33
Definition: st.h:69
VALUE rb_id2str(ID id)
Definition: ripper.c:17157
#define NOEX_WITH_SAFE(n)
Definition: method.h:43
#define NUM2INT(x)
Definition: ruby.h:630
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1214
void rb_remove_method(VALUE klass, const char *name)
Definition: vm_method.c:755
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1237
static VALUE rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
Definition: vm_method.c:771
static VALUE find_refinement(VALUE refinements, VALUE klass)
#define d1
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE))
Definition: class.c:117
const VALUE location
Definition: method.h:73
rb_method_flag_t flag
Definition: method.h:98
int rb_obj_method_arity(VALUE, ID)
Definition: proc.c:2128
#define QUOTE_ID(id)
Definition: internal.h:715
#define CLASS_OF(v)
Definition: ruby.h:440
#define VISI_CHECK(x, f)
Definition: vm_method.c:1036
#define T_MODULE
Definition: ruby.h:480
#define RCLASS_EXT(c)
Definition: classext.h:15
static rb_method_entry_t * method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_flag_t noex, VALUE defined_class)
Definition: vm_method.c:492
#define Qtrue
Definition: ruby.h:426
int st_insert(st_table *, st_data_t, st_data_t)
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
Definition: vm_method.c:220
void rb_disable_super(VALUE klass, const char *name)
Definition: vm_method.c:791
VALUE rb_mod_method_location(VALUE mod, ID id)
Definition: proc.c:2180
#define SCOPE_SET(f)
Definition: eval_intern.h:211
static VALUE call_cfunc_10(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
struct rb_method_entry_struct * orig_me
Definition: method.h:92
const int id
Definition: nkf.c:209
rb_alloc_func_t rb_get_alloc_func(VALUE klass)
Definition: vm_method.c:524
VALUE rb_refinement_module_get_refined_class(VALUE module)
Definition: eval.c:1177
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1500
rb_serial_t method_state
Definition: vm_method.c:33
static void setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE(*func)(), int argc)
Definition: vm_method.c:419
VALUE rb_eTypeError
Definition: error.c:548
#define rb_intern(str)
rb_method_flag_t
Definition: method.h:24
#define UNREACHABLE
Definition: ruby.h:42
static rb_method_entry_t * search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:537
VALUE defined_class
Definition: vm_method.c:37
#define ruby_running
Definition: vm_method.c:41
void rb_alias(VALUE klass, ID name, ID def)
Definition: vm_method.c:1243
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:229
#define Check_Type(v, t)
Definition: ruby.h:532
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1854
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1115
NODE * rb_vm_cref(void)
Definition: vm.c:980
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:179
ID called_id
Definition: method.h:101
VALUE rb_iseq_first_lineno(VALUE iseqval)
Definition: iseq.c:958
union rb_method_definition_struct::@126 body
Definition: vm_method.c:32
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1409
st_data_t st_index_t
Definition: st.h:48
#define GET_GLOBAL_METHOD_STATE()
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
Definition: ripper.c:17321
int rb_method_basic_definition_p(VALUE klass, ID id)
Definition: vm_method.c:1572
static rb_method_entry_t * lookup_method_table(VALUE klass, ID id)
Definition: vm_method.c:187
static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
static VALUE call_cfunc_11(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
void rb_mark_method_entry(const rb_method_entry_t *me)
Definition: gc.c:3417
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
Definition: vm_method.c:427
void rb_name_error_str(VALUE str, const char *fmt,...)
Definition: error.c:982
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:20
void rb_name_error(ID id, const char *fmt,...)
Definition: error.c:967
static void remove_method(VALUE klass, ID mid)
Definition: vm_method.c:720
static st_index_t rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
Definition: vm_method.c:1199
static void rb_export_method(VALUE klass, ID name, rb_method_flag_t noex)
Definition: vm_method.c:803
Definition: node.h:239
#define FL_SINGLETON
Definition: ruby.h:1133
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1628
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
Definition: vm_method.c:859
int rb_obj_respond_to(VALUE obj, ID id, int priv)
Definition: vm_method.c:1599
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1664
int st_lookup(st_table *, st_data_t, st_data_t *)
rb_method_cfunc_t cfunc
Definition: method.h:83
static VALUE call_cfunc_15(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define FL_TEST(x, f)
Definition: ruby.h:1169
#define rb_intern_str(string)
Definition: generator.h:17
VALUE rb_class_name(VALUE)
Definition: variable.c:391
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:247
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1553
int rb_respond_to(VALUE obj, ID id)
Definition: vm_method.c:1638
#define RMODULE_IS_REFINEMENT
Definition: ruby.h:802
void rb_clear_cache(void)
Definition: vm_method.c:52
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:1552
static VALUE top_public(int argc, VALUE *argv)
Definition: vm_method.c:1468
static VALUE obj_respond_to(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1665
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1541
void rb_remove_method_id(VALUE klass, ID mid)
Definition: vm_method.c:749
#define RCLASS_ORIGIN(c)
Definition: internal.h:297
rb_iseq_t * iseq
Definition: vm_core.h:448
static struct cache_entry global_method_cache[GLOBAL_METHOD_CACHE_SIZE]
Definition: vm_method.c:40
static rb_method_entry_t * rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_flag_t noex, VALUE defined_class)
Definition: vm_method.c:235
#define NIL_P(v)
Definition: ruby.h:438
static VALUE check_definition(VALUE mod, VALUE mid, rb_method_flag_t noex)
Definition: vm_method.c:1039
void rb_undef_alloc_func(VALUE klass)
Definition: vm_method.c:518
int st_delete(st_table *, st_data_t *, st_data_t *)
#define RUBY_DTRACE_METHOD_CACHE_CLEAR(arg0, arg1, arg2)
Definition: probes.h:80
static VALUE top_private(int argc, VALUE *argv)
Definition: vm_method.c:1486
enum rb_method_definition_struct::@126::method_optimized_type optimize_type
static VALUE call_cfunc_2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define added
Definition: vm_method.c:24
int argc
Definition: ruby.c:131
struct unlinked_method_entry_list_entry * unlinked_method_entry_list
Definition: vm_core.h:402
#define Qfalse
Definition: ruby.h:425
#define undefined
Definition: vm_method.c:28
#define rb_sourcefile()
Definition: tcltklib.c:98
void rb_gc_mark_unlinked_live_method_entries(void *pvm)
Definition: vm_method.c:123
Definition: method.h:97
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1572
void rb_clear_constant_cache(void)
Definition: vm_method.c:60
static int basic_obj_respond_to(VALUE obj, ID id, int pub)
Definition: vm_method.c:1581
static VALUE call_cfunc_1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define GLOBAL_METHOD_CACHE_SIZE
Definition: vm_method.c:6
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)
VALUE rb_vm_top_self()
Definition: vm.c:2791
VALUE(* func)(ANYARGS)
Definition: method.h:66
VALUE klass
Definition: method.h:102
#define ALLOC(type)
Definition: ruby.h:1334
rb_method_type_t
Definition: method.h:47
rb_serial_t class_serial
Definition: vm_method.c:34
static VALUE rb_mod_private_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1115
#define removed
Definition: vm_method.c:26
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_flag_t noex)
Definition: vm_method.c:99
#define RCLASS_M_TBL(c)
Definition: internal.h:295
rb_iseq_t *const iseq
Definition: method.h:82
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
#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:392
static VALUE call_cfunc_13(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1250
unsigned long rb_serial_t
Definition: internal.h:260
static VALUE rb_mod_public(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1361
rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:682
static void release_method_definition(rb_method_definition_t *def)
Definition: vm_method.c:160
#define UNDEF_ALLOC_FUNC
Definition: vm_method.c:508
static VALUE rb_mod_protected_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1149
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1728
#define PRIsVALUE
Definition: ruby.h:137
const VALUE path
Definition: vm_core.h:197
unsigned long ID
Definition: ruby.h:89
rb_iseq_t * rb_proc_get_iseq(VALUE proc, int *is_proc)
Definition: proc.c:904
#define Qnil
Definition: ruby.h:427
#define INC_GLOBAL_METHOD_STATE()
#define INC_GLOBAL_CONSTANT_STATE()
int type
Definition: tcltklib.c:112
#define BUILTIN_TYPE(x)
Definition: ruby.h:502
unsigned long VALUE
Definition: ruby.h:88
static VALUE rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1530
#define rb_funcall2
Definition: ruby.h:1456
#define RBASIC(obj)
Definition: ruby.h:1116
const char * rb_class2name(VALUE)
Definition: variable.c:397
ID rb_id_attrset(ID id)
Definition: ripper.c:15419
static VALUE obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
Definition: vm_method.c:1701
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_flag_t noex)
Definition: vm_method.c:503
#define FIX2INT(x)
Definition: ruby.h:632
rb_iseq_location_t location
Definition: vm_core.h:223
#define rb_ary_new3
Definition: intern.h:91
static VALUE call_cfunc_m2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_12(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:67
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:983
#define CALL_METHOD_HOOK(klass, hook, mid)
Definition: vm_method.c:372
static void method_added(VALUE klass, ID mid)
Definition: vm_method.c:384
static void set_method_visibility(VALUE self, int argc, VALUE *argv, rb_method_flag_t ex)
Definition: vm_method.c:1316
static VALUE call_cfunc_7(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE rb_f_notimplement(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:85
#define RSTRING_PTR(str)
Definition: ruby.h:845
static VALUE rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1448
void rb_enable_super(VALUE klass, const char *name)
Definition: vm_method.c:797
void rb_sweep_method_entry(void *pvm)
Definition: vm_method.c:137
VALUE rb_equal(VALUE, VALUE)
Definition: object.c:89
#define NOEX_NOREDEF
Definition: vm_method.c:16
#define INT2FIX(i)
Definition: ruby.h:231
#define RCLASS_SUPER(c)
Definition: classext.h:16
int rb_sourceline(void)
Definition: vm.c:966
#define RARRAY_AREF(a, i)
Definition: ruby.h:901
ID rb_frame_callee(void)
Definition: eval.c:949
static VALUE call_cfunc_m1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
rb_method_definition_t * def
Definition: method.h:100
#define object_id
Definition: vm_method.c:23
#define RBASIC_CLASS(obj)
Definition: ruby.h:759
#define ANYARGS
Definition: defines.h:98
#define SCOPE_CHECK(f)
Definition: eval_intern.h:210
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:1155
void rb_compile_warning(const char *file, int line, const char *fmt,...)
Definition: error.c:192
uint8_t key[16]
Definition: random.c:1250
#define RTEST(v)
Definition: ruby.h:437
#define attached
Definition: vm_method.c:30
void rb_free_method_entry(rb_method_entry_t *me)
Definition: vm_method.c:178
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:511
#define GLOBAL_METHOD_CACHE(c, m)
Definition: vm_method.c:13
struct iseq_line_info_entry * line_info_table
Definition: vm_core.h:232
static void make_method_entry_refined(rb_method_entry_t *me)
Definition: vm_method.c:200
static VALUE rb_mod_protected(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1379
static VALUE call_cfunc_6(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
void rb_notimplement(void)
Definition: error.c:1900
static unsigned int hash(const char *str, unsigned int len)
Definition: lex.c:56
static VALUE call_cfunc_4(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
void Init_eval_method(void)
Definition: vm_method.c:1707
static VALUE rb_mod_public_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1081
#define T_CLASS
Definition: ruby.h:478
static VALUE rb_mod_private(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1406
void rb_frozen_class_p(VALUE klass)
Definition: eval.c:406
const char * name
Definition: nkf.c:208
VALUE self
Definition: vm_core.h:303
#define ID2SYM(x)
Definition: ruby.h:355
void rb_undef(VALUE klass, ID id)
Definition: vm_method.c:897
const char * rb_id2name(ID id)
Definition: ripper.c:17227
rb_method_entry_t * me
Definition: method.h:107
#define REPLICATE_METHOD(klass, id, noex)
rb_method_entry_t * rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:563
rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
Definition: vm_method.c:654
rb_serial_t rb_next_class_serial(void)
Definition: vm.c:92
void rb_warning(const char *fmt,...)
Definition: error.c:236
#define rb_check_frozen(obj)
Definition: intern.h:277
void rb_print_undef(VALUE klass, ID id, int scope)
Definition: eval_error.c:212
void void xfree(void *)
st_index_t rb_hash_proc(st_index_t hash, VALUE proc)
Definition: proc.c:995
void rb_unlink_method_entry(rb_method_entry_t *me)
Definition: vm_method.c:114
#define mod(x, y)
Definition: date_strftime.c:28
#define Qundef
Definition: ruby.h:428
rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:700
#define T_ICLASS
Definition: ruby.h:479
#define RCLASS_SERIAL(c)
Definition: internal.h:299
#define SCOPE_TEST(f)
Definition: eval_intern.h:209
static void rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_flag_t noex)
Definition: vm_method.c:93
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:924
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1488
#define ruby_verbose
Definition: ruby.h:1475
void rb_warn(const char *fmt,...)
Definition: error.c:223
ID rb_to_id(VALUE)
Definition: string.c:8730
void rb_clear_method_cache_by_class(VALUE klass)
Definition: vm_method.c:66
VALUE rb_eArgError
Definition: error.c:549
static VALUE call_cfunc_8(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
ID rb_check_attr_id(ID id)
Definition: object.c:1957
Definition: method.h:105
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1213
#define RUBY_DTRACE_METHOD_CACHE_CLEAR_ENABLED()
Definition: probes.h:79
static rb_method_entry_t * get_original_method_entry(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
Definition: vm_method.c:637
char ** argv
Definition: ruby.c:132
VALUE rb_eException
Definition: error.c:541
ID mid
Definition: vm_method.c:35
#define GET_VM()
Definition: vm_core.h:917