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