Ruby  2.1.10p492(2016-04-01revision54464)
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 {
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) &&
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) &&
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 
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;
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  }
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 
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  VALUE super;
643 
644  if (me->def->body.orig_me) {
645  return me->def->body.orig_me;
646  }
647  else if (!(super = RCLASS_SUPER(me->klass))) {
648  return 0;
649  }
650  else {
651  rb_method_entry_t *tmp_me;
652  tmp_me = rb_method_entry(super, me->called_id,
653  defined_class_ptr);
654  return rb_resolve_refined_method(refinements, tmp_me,
655  defined_class_ptr);
656  }
657 }
658 
661  VALUE *defined_class_ptr)
662 {
663  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
664  VALUE refinement;
665  rb_method_entry_t *tmp_me;
666 
667  refinement = find_refinement(refinements, me->klass);
668  if (NIL_P(refinement)) {
669  return get_original_method_entry(refinements, me,
670  defined_class_ptr);
671  }
672  tmp_me = rb_method_entry(refinement, me->called_id,
673  defined_class_ptr);
674  if (tmp_me && tmp_me->def->type != VM_METHOD_TYPE_REFINED) {
675  return tmp_me;
676  }
677  else {
678  return get_original_method_entry(refinements, me,
679  defined_class_ptr);
680  }
681  }
682  else {
683  return (rb_method_entry_t *)me;
684  }
685 }
686 
689  VALUE *defined_class_ptr)
690 {
693 
694  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
695  NODE *cref = rb_vm_cref();
696  VALUE refinements = cref ? cref->nd_refinements : Qnil;
697 
698  me = rb_resolve_refined_method(refinements, me, &defined_class);
699  }
700  if (defined_class_ptr)
701  *defined_class_ptr = defined_class;
702  return me;
703 }
704 
707  VALUE *defined_class_ptr)
708 {
711 
712  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
714  }
715  if (defined_class_ptr)
716  *defined_class_ptr = defined_class;
718  return 0;
719  }
720  else {
721  return me;
722  }
723 }
724 
725 static void
727 {
728  st_data_t key, data;
729  rb_method_entry_t *me = 0;
730  VALUE self = klass;
731 
732  klass = RCLASS_ORIGIN(klass);
733  rb_check_frozen(klass);
734  if (mid == object_id || mid == id__send__ || mid == idInitialize) {
735  rb_warn("removing `%s' may cause serious problems", rb_id2name(mid));
736  }
737 
738  if (!st_lookup(RCLASS_M_TBL(klass), mid, &data) ||
739  !(me = (rb_method_entry_t *)data) ||
740  (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
742  rb_name_error(mid, "method `%s' not defined in %s",
743  rb_id2name(mid), rb_class2name(klass));
744  }
745 
746  key = (st_data_t)mid;
747  st_delete(RCLASS_M_TBL(klass), &key, &data);
748 
752 
753  if (me->def->type == VM_METHOD_TYPE_REFINED) {
755  }
756 
757  CALL_METHOD_HOOK(self, removed, mid);
758 }
759 
760 void
762 {
763  remove_method(klass, mid);
764 }
765 
766 void
767 rb_remove_method(VALUE klass, const char *name)
768 {
769  remove_method(klass, rb_intern(name));
770 }
771 
772 /*
773  * call-seq:
774  * remove_method(symbol) -> self
775  * remove_method(string) -> self
776  *
777  * Removes the method identified by _symbol_ from the current
778  * class. For an example, see <code>Module.undef_method</code>.
779  * String arguments are converted to symbols.
780  */
781 
782 static VALUE
784 {
785  int i;
786 
787  for (i = 0; i < argc; i++) {
788  VALUE v = argv[i];
789  ID id = rb_check_id(&v);
790  if (!id) {
791  rb_name_error_str(v, "method `%s' not defined in %s",
793  }
794  remove_method(mod, id);
795  }
796  return mod;
797 }
798 
799 #undef rb_disable_super
800 #undef rb_enable_super
801 
802 void
803 rb_disable_super(VALUE klass, const char *name)
804 {
805  /* obsolete - no use */
806 }
807 
808 void
809 rb_enable_super(VALUE klass, const char *name)
810 {
811  rb_warning("rb_enable_super() is obsolete");
812 }
813 
814 static void
816 {
819 
820  me = search_method(klass, name, &defined_class);
821  if (!me && RB_TYPE_P(klass, T_MODULE)) {
823  }
824 
827  rb_print_undef(klass, name, 0);
828  }
829 
830  if (me->flag != noex) {
832 
833  if (klass == defined_class ||
834  RCLASS_ORIGIN(klass) == defined_class) {
835  me->flag = noex;
836  if (me->def->type == VM_METHOD_TYPE_REFINED) {
837  me->def->body.orig_me->flag = noex;
838  }
840  }
841  else {
842  rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, noex);
843  }
844  }
845 }
846 
847 int
848 rb_method_boundp(VALUE klass, ID id, int ex)
849 {
852 
853  if (me != 0) {
854  if ((ex & ~NOEX_RESPONDS) &&
855  ((me->flag & NOEX_PRIVATE) ||
856  ((ex & NOEX_RESPONDS) && (me->flag & NOEX_PROTECTED)))) {
857  return 0;
858  }
859  if (!me->def) return 0;
861  if (ex & NOEX_RESPONDS) return 2;
862  return 0;
863  }
864  return 1;
865  }
866  return 0;
867 }
868 
869 extern ID rb_check_attr_id(ID id);
870 
871 void
872 rb_attr(VALUE klass, ID id, int read, int write, int ex)
873 {
874  ID attriv;
875  VALUE aname;
876  rb_method_flag_t noex;
877 
878  if (!ex) {
879  noex = NOEX_PUBLIC;
880  }
881  else {
882  if (SCOPE_TEST(NOEX_PRIVATE)) {
883  noex = NOEX_PRIVATE;
885  "attribute accessor as module_function" :
886  "private attribute?");
887  }
888  else if (SCOPE_TEST(NOEX_PROTECTED)) {
889  noex = NOEX_PROTECTED;
890  }
891  else {
892  noex = NOEX_PUBLIC;
893  }
894  }
895 
896  aname = rb_id2str(rb_check_attr_id(id));
897  if (NIL_P(aname)) {
898  rb_raise(rb_eArgError, "argument needs to be symbol or string");
899  }
900  attriv = rb_intern_str(rb_sprintf("@%"PRIsVALUE, aname));
901  if (read) {
902  rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, noex);
903  }
904  if (write) {
905  rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, noex);
906  }
907 }
908 
909 void
910 rb_undef(VALUE klass, ID id)
911 {
913 
914  if (NIL_P(klass)) {
915  rb_raise(rb_eTypeError, "no class to undef method");
916  }
917  rb_frozen_class_p(klass);
918  if (id == object_id || id == id__send__ || id == idInitialize) {
919  rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
920  }
921 
922  me = search_method(klass, id, 0);
923 
926  const char *s0 = " class";
927  VALUE c = klass;
928 
929  if (FL_TEST(c, FL_SINGLETON)) {
930  VALUE obj = rb_ivar_get(klass, attached);
931 
932  if (RB_TYPE_P(obj, T_MODULE) || RB_TYPE_P(obj, T_CLASS)) {
933  c = obj;
934  s0 = "";
935  }
936  }
937  else if (RB_TYPE_P(c, T_MODULE)) {
938  s0 = " module";
939  }
940  rb_name_error(id, "undefined method `%"PRIsVALUE"' for%s `%"PRIsVALUE"'",
941  QUOTE_ID(id), s0, rb_class_name(c));
942  }
943 
945 
946  CALL_METHOD_HOOK(klass, undefined, id);
947 }
948 
949 /*
950  * call-seq:
951  * undef_method(symbol) -> self
952  * undef_method(string) -> self
953  *
954  * Prevents the current class from responding to calls to the named
955  * method. Contrast this with <code>remove_method</code>, which deletes
956  * the method from the particular class; Ruby will still search
957  * superclasses and mixed-in modules for a possible receiver.
958  * String arguments are converted to symbols.
959  *
960  * class Parent
961  * def hello
962  * puts "In parent"
963  * end
964  * end
965  * class Child < Parent
966  * def hello
967  * puts "In child"
968  * end
969  * end
970  *
971  *
972  * c = Child.new
973  * c.hello
974  *
975  *
976  * class Child
977  * remove_method :hello # remove from child, still in parent
978  * end
979  * c.hello
980  *
981  *
982  * class Child
983  * undef_method :hello # prevent any calls to 'hello'
984  * end
985  * c.hello
986  *
987  * <em>produces:</em>
988  *
989  * In child
990  * In parent
991  * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
992  */
993 
994 static VALUE
996 {
997  int i;
998  for (i = 0; i < argc; i++) {
999  VALUE v = argv[i];
1000  ID id = rb_check_id(&v);
1001  if (!id) {
1003  }
1004  rb_undef(mod, id);
1005  }
1006  return mod;
1007 }
1008 
1009 /*
1010  * call-seq:
1011  * mod.method_defined?(symbol) -> true or false
1012  * mod.method_defined?(string) -> true or false
1013  *
1014  * Returns +true+ if the named method is defined by
1015  * _mod_ (or its included modules and, if _mod_ is a class,
1016  * its ancestors). Public and protected methods are matched.
1017  * String arguments are converted to symbols.
1018  *
1019  * module A
1020  * def method1() end
1021  * end
1022  * class B
1023  * def method2() end
1024  * end
1025  * class C < B
1026  * include A
1027  * def method3() end
1028  * end
1029  *
1030  * A.method_defined? :method1 #=> true
1031  * C.method_defined? "method1" #=> true
1032  * C.method_defined? "method2" #=> true
1033  * C.method_defined? "method3" #=> true
1034  * C.method_defined? "method4" #=> false
1035  */
1036 
1037 static VALUE
1039 {
1040  ID id = rb_check_id(&mid);
1041  if (!id || !rb_method_boundp(mod, id, 1)) {
1042  return Qfalse;
1043  }
1044  return Qtrue;
1045 
1046 }
1047 
1048 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
1049 
1050 static VALUE
1052 {
1053  const rb_method_entry_t *me;
1054  ID id = rb_check_id(&mid);
1055  if (!id) return Qfalse;
1057  if (me) {
1058  if (VISI_CHECK(me->flag, noex))
1059  return Qtrue;
1060  }
1061  return Qfalse;
1062 }
1063 
1064 /*
1065  * call-seq:
1066  * mod.public_method_defined?(symbol) -> true or false
1067  * mod.public_method_defined?(string) -> true or false
1068  *
1069  * Returns +true+ if the named public method is defined by
1070  * _mod_ (or its included modules and, if _mod_ is a class,
1071  * its ancestors).
1072  * String arguments are converted to symbols.
1073  *
1074  * module A
1075  * def method1() end
1076  * end
1077  * class B
1078  * protected
1079  * def method2() end
1080  * end
1081  * class C < B
1082  * include A
1083  * def method3() end
1084  * end
1085  *
1086  * A.method_defined? :method1 #=> true
1087  * C.public_method_defined? "method1" #=> true
1088  * C.public_method_defined? "method2" #=> false
1089  * C.method_defined? "method2" #=> true
1090  */
1091 
1092 static VALUE
1094 {
1095  return check_definition(mod, mid, NOEX_PUBLIC);
1096 }
1097 
1098 /*
1099  * call-seq:
1100  * mod.private_method_defined?(symbol) -> true or false
1101  * mod.private_method_defined?(string) -> true or false
1102  *
1103  * Returns +true+ if the named private method is defined by
1104  * _ mod_ (or its included modules and, if _mod_ is a class,
1105  * its ancestors).
1106  * String arguments are converted to symbols.
1107  *
1108  * module A
1109  * def method1() end
1110  * end
1111  * class B
1112  * private
1113  * def method2() end
1114  * end
1115  * class C < B
1116  * include A
1117  * def method3() end
1118  * end
1119  *
1120  * A.method_defined? :method1 #=> true
1121  * C.private_method_defined? "method1" #=> false
1122  * C.private_method_defined? "method2" #=> true
1123  * C.method_defined? "method2" #=> false
1124  */
1125 
1126 static VALUE
1128 {
1130 }
1131 
1132 /*
1133  * call-seq:
1134  * mod.protected_method_defined?(symbol) -> true or false
1135  * mod.protected_method_defined?(string) -> true or false
1136  *
1137  * Returns +true+ if the named protected method is defined
1138  * by _mod_ (or its included modules and, if _mod_ is a
1139  * class, its ancestors).
1140  * String arguments are converted to symbols.
1141  *
1142  * module A
1143  * def method1() end
1144  * end
1145  * class B
1146  * protected
1147  * def method2() end
1148  * end
1149  * class C < B
1150  * include A
1151  * def method3() end
1152  * end
1153  *
1154  * A.method_defined? :method1 #=> true
1155  * C.protected_method_defined? "method1" #=> false
1156  * C.protected_method_defined? "method2" #=> true
1157  * C.method_defined? "method2" #=> true
1158  */
1159 
1160 static VALUE
1162 {
1164 }
1165 
1166 int
1168 {
1169  return rb_method_definition_eq(m1->def, m2->def);
1170 }
1171 
1172 static int
1174 {
1175  if (d1 && d1->type == VM_METHOD_TYPE_REFINED && d1->body.orig_me)
1176  d1 = d1->body.orig_me->def;
1177  if (d2 && d2->type == VM_METHOD_TYPE_REFINED && d2->body.orig_me)
1178  d2 = d2->body.orig_me->def;
1179  if (d1 == d2) return 1;
1180  if (!d1 || !d2) return 0;
1181  if (d1->type != d2->type) {
1182  return 0;
1183  }
1184  switch (d1->type) {
1185  case VM_METHOD_TYPE_ISEQ:
1186  return d1->body.iseq == d2->body.iseq;
1187  case VM_METHOD_TYPE_CFUNC:
1188  return
1189  d1->body.cfunc.func == d2->body.cfunc.func &&
1190  d1->body.cfunc.argc == d2->body.cfunc.argc;
1192  case VM_METHOD_TYPE_IVAR:
1193  return d1->body.attr.id == d2->body.attr.id;
1195  return RTEST(rb_equal(d1->body.proc, d2->body.proc));
1197  return d1->original_id == d2->original_id;
1198  case VM_METHOD_TYPE_ZSUPER:
1200  case VM_METHOD_TYPE_UNDEF:
1201  return 1;
1203  return d1->body.optimize_type == d2->body.optimize_type;
1204  default:
1205  rb_bug("rb_method_entry_eq: unsupported method type (%d)\n", d1->type);
1206  return 0;
1207  }
1208 }
1209 
1210 static st_index_t
1212 {
1213  again:
1214  hash = rb_hash_uint(hash, def->type);
1215  switch (def->type) {
1216  case VM_METHOD_TYPE_ISEQ:
1217  return rb_hash_uint(hash, (st_index_t)def->body.iseq);
1218  case VM_METHOD_TYPE_CFUNC:
1220  return rb_hash_uint(hash, def->body.cfunc.argc);
1222  case VM_METHOD_TYPE_IVAR:
1223  return rb_hash_uint(hash, def->body.attr.id);
1225  return rb_hash_proc(hash, def->body.proc);
1227  return rb_hash_uint(hash, def->original_id);
1228  case VM_METHOD_TYPE_ZSUPER:
1230  case VM_METHOD_TYPE_UNDEF:
1231  return hash;
1233  return rb_hash_uint(hash, def->body.optimize_type);
1235  if (def->body.orig_me) {
1236  def = def->body.orig_me->def;
1237  goto again;
1238  }
1239  else {
1240  return hash;
1241  }
1242  default:
1243  rb_bug("rb_hash_method_definition: unsupported method type (%d)\n", def->type);
1244  }
1245  return hash;
1246 }
1247 
1248 st_index_t
1250 {
1252 }
1253 
1254 void
1255 rb_alias(VALUE klass, ID name, ID def)
1256 {
1257  VALUE target_klass = klass;
1259  rb_method_entry_t *orig_me;
1261 
1262  if (NIL_P(klass)) {
1263  rb_raise(rb_eTypeError, "no class to make alias");
1264  }
1265 
1266  rb_frozen_class_p(klass);
1267 
1268  again:
1269  orig_me = search_method(klass, def, &defined_class);
1270 
1271  if (UNDEFINED_METHOD_ENTRY_P(orig_me) ||
1272  UNDEFINED_REFINED_METHOD_P(orig_me->def)) {
1273  if ((!RB_TYPE_P(klass, T_MODULE)) ||
1274  (orig_me = search_method(rb_cObject, def, 0),
1275  UNDEFINED_METHOD_ENTRY_P(orig_me))) {
1276  rb_print_undef(klass, def, 0);
1277  }
1278  }
1279  if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {
1280  klass = RCLASS_SUPER(klass);
1281  def = orig_me->def->original_id;
1282  flag = orig_me->flag;
1283  goto again;
1284  }
1286  VALUE real_class = RBASIC_CLASS(defined_class);
1287  if (real_class && RCLASS_ORIGIN(real_class) == defined_class)
1288  defined_class = real_class;
1289  }
1290 
1291  if (flag == NOEX_UNDEF) flag = orig_me->flag;
1292  method_entry_set(target_klass, name, orig_me, flag, defined_class);
1293 }
1294 
1295 /*
1296  * call-seq:
1297  * alias_method(new_name, old_name) -> self
1298  *
1299  * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
1300  * be used to retain access to methods that are overridden.
1301  *
1302  * module Mod
1303  * alias_method :orig_exit, :exit
1304  * def exit(code=0)
1305  * puts "Exiting with code #{code}"
1306  * orig_exit(code)
1307  * end
1308  * end
1309  * include Mod
1310  * exit(99)
1311  *
1312  * <em>produces:</em>
1313  *
1314  * Exiting with code 99
1315  */
1316 
1317 static VALUE
1319 {
1320  ID oldid = rb_check_id(&oldname);
1321  if (!oldid) {
1322  rb_print_undef_str(mod, oldname);
1323  }
1324  rb_alias(mod, rb_to_id(newname), oldid);
1325  return mod;
1326 }
1327 
1328 static void
1330 {
1331  int i;
1332 
1333  if (argc == 0) {
1334  rb_warning("%"PRIsVALUE" with no argument is just ignored",
1336  return;
1337  }
1338 
1339  for (i = 0; i < argc; i++) {
1340  VALUE v = argv[i];
1341  ID id = rb_check_id(&v);
1342  if (!id) {
1343  rb_print_undef_str(self, v);
1344  }
1345  rb_export_method(self, id, ex);
1346  }
1347 }
1348 
1349 static VALUE
1351 {
1352  if (argc == 0) {
1353  SCOPE_SET(ex);
1354  }
1355  else {
1356  set_method_visibility(module, argc, argv, ex);
1357  }
1358  return module;
1359 }
1360 
1361 /*
1362  * call-seq:
1363  * public -> self
1364  * public(symbol, ...) -> self
1365  * public(string, ...) -> self
1366  *
1367  * With no arguments, sets the default visibility for subsequently
1368  * defined methods to public. With arguments, sets the named methods to
1369  * have public visibility.
1370  * String arguments are converted to symbols.
1371  */
1372 
1373 static VALUE
1375 {
1376  return set_visibility(argc, argv, module, NOEX_PUBLIC);
1377 }
1378 
1379 /*
1380  * call-seq:
1381  * protected -> self
1382  * protected(symbol, ...) -> self
1383  * protected(string, ...) -> self
1384  *
1385  * With no arguments, sets the default visibility for subsequently
1386  * defined methods to protected. With arguments, sets the named methods
1387  * to have protected visibility.
1388  * String arguments are converted to symbols.
1389  */
1390 
1391 static VALUE
1393 {
1394  return set_visibility(argc, argv, module, NOEX_PROTECTED);
1395 }
1396 
1397 /*
1398  * call-seq:
1399  * private -> self
1400  * private(symbol, ...) -> self
1401  * private(string, ...) -> self
1402  *
1403  * With no arguments, sets the default visibility for subsequently
1404  * defined methods to private. With arguments, sets the named methods
1405  * to have private visibility.
1406  * String arguments are converted to symbols.
1407  *
1408  * module Mod
1409  * def a() end
1410  * def b() end
1411  * private
1412  * def c() end
1413  * private :a
1414  * end
1415  * Mod.private_instance_methods #=> [:a, :c]
1416  */
1417 
1418 static VALUE
1420 {
1421  return set_visibility(argc, argv, module, NOEX_PRIVATE);
1422 }
1423 
1424 /*
1425  * call-seq:
1426  * mod.public_class_method(symbol, ...) -> mod
1427  * mod.public_class_method(string, ...) -> mod
1428  *
1429  * Makes a list of existing class methods public.
1430  *
1431  * String arguments are converted to symbols.
1432  */
1433 
1434 static VALUE
1436 {
1438  return obj;
1439 }
1440 
1441 /*
1442  * call-seq:
1443  * mod.private_class_method(symbol, ...) -> mod
1444  * mod.private_class_method(string, ...) -> mod
1445  *
1446  * Makes existing class methods private. Often used to hide the default
1447  * constructor <code>new</code>.
1448  *
1449  * String arguments are converted to symbols.
1450  *
1451  * class SimpleSingleton # Not thread safe
1452  * private_class_method :new
1453  * def SimpleSingleton.create(*args, &block)
1454  * @me = new(*args, &block) if ! @me
1455  * @me
1456  * end
1457  * end
1458  */
1459 
1460 static VALUE
1462 {
1464  return obj;
1465 }
1466 
1467 /*
1468  * call-seq:
1469  * public
1470  * public(symbol, ...)
1471  * public(string, ...)
1472  *
1473  * With no arguments, sets the default visibility for subsequently
1474  * defined methods to public. With arguments, sets the named methods to
1475  * have public visibility.
1476  *
1477  * String arguments are converted to symbols.
1478  */
1479 
1480 static VALUE
1482 {
1483  return rb_mod_public(argc, argv, rb_cObject);
1484 }
1485 
1486 /*
1487  * call-seq:
1488  * private
1489  * private(symbol, ...)
1490  * private(string, ...)
1491  *
1492  * With no arguments, sets the default visibility for subsequently
1493  * defined methods to private. With arguments, sets the named methods to
1494  * have private visibility.
1495  *
1496  * String arguments are converted to symbols.
1497  */
1498 static VALUE
1500 {
1501  return rb_mod_private(argc, argv, rb_cObject);
1502 }
1503 
1504 /*
1505  * call-seq:
1506  * module_function(symbol, ...) -> self
1507  * module_function(string, ...) -> self
1508  *
1509  * Creates module functions for the named methods. These functions may
1510  * be called with the module as a receiver, and also become available
1511  * as instance methods to classes that mix in the module. Module
1512  * functions are copies of the original, and so may be changed
1513  * independently. The instance-method versions are made private. If
1514  * used with no arguments, subsequently defined methods become module
1515  * functions.
1516  * String arguments are converted to symbols.
1517  *
1518  * module Mod
1519  * def one
1520  * "This is one"
1521  * end
1522  * module_function :one
1523  * end
1524  * class Cls
1525  * include Mod
1526  * def call_one
1527  * one
1528  * end
1529  * end
1530  * Mod.one #=> "This is one"
1531  * c = Cls.new
1532  * c.call_one #=> "This is one"
1533  * module Mod
1534  * def one
1535  * "This is the new one"
1536  * end
1537  * end
1538  * Mod.one #=> "This is one"
1539  * c.call_one #=> "This is the new one"
1540  */
1541 
1542 static VALUE
1544 {
1545  int i;
1546  ID id;
1547  const rb_method_entry_t *me;
1548 
1549  if (!RB_TYPE_P(module, T_MODULE)) {
1550  rb_raise(rb_eTypeError, "module_function must be called for modules");
1551  }
1552 
1553  if (argc == 0) {
1555  return module;
1556  }
1557 
1559 
1560  for (i = 0; i < argc; i++) {
1561  VALUE m = module;
1562 
1563  id = rb_to_id(argv[i]);
1564  for (;;) {
1565  me = search_method(m, id, 0);
1566  if (me == 0) {
1567  me = search_method(rb_cObject, id, 0);
1568  }
1570  rb_print_undef(module, id, 0);
1571  }
1572  if (me->def->type != VM_METHOD_TYPE_ZSUPER) {
1573  break; /* normal case: need not to follow 'super' link */
1574  }
1575  m = RCLASS_SUPER(m);
1576  if (!m)
1577  break;
1578  }
1580  }
1581  return module;
1582 }
1583 
1584 int
1586 {
1587  const rb_method_entry_t *me = rb_method_entry(klass, id, 0);
1588  if (me && (me->flag & NOEX_BASIC))
1589  return 1;
1590  return 0;
1591 }
1592 
1593 static inline int
1594 basic_obj_respond_to(VALUE obj, ID id, int pub)
1595 {
1596  VALUE klass = CLASS_OF(obj);
1597  VALUE args[2];
1598 
1599  switch (rb_method_boundp(klass, id, pub|NOEX_RESPONDS)) {
1600  case 2:
1601  return FALSE;
1602  case 0:
1603  args[0] = ID2SYM(id);
1604  args[1] = pub ? Qfalse : Qtrue;
1605  return RTEST(rb_funcall2(obj, idRespond_to_missing, 2, args));
1606  default:
1607  return TRUE;
1608  }
1609 }
1610 
1611 int
1612 rb_obj_respond_to(VALUE obj, ID id, int priv)
1613 {
1614  VALUE klass = CLASS_OF(obj);
1615 
1617  return basic_obj_respond_to(obj, id, !RTEST(priv));
1618  }
1619  else {
1620  int argc = 1;
1621  VALUE args[2];
1622  args[0] = ID2SYM(id);
1623  args[1] = Qtrue;
1624  if (priv) {
1625  if (rb_obj_method_arity(obj, idRespond_to) != 1) {
1626  argc = 2;
1627  }
1628  else if (!NIL_P(ruby_verbose)) {
1629  VALUE klass = CLASS_OF(obj);
1630  VALUE location = rb_mod_method_location(klass, idRespond_to);
1631  rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") is"
1632  " old fashion which takes only one parameter",
1633  (FL_TEST(klass, FL_SINGLETON) ? obj : klass),
1634  (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
1635  QUOTE_ID(id));
1636  if (!NIL_P(location)) {
1637  VALUE path = RARRAY_AREF(location, 0);
1638  VALUE line = RARRAY_AREF(location, 1);
1639  if (!NIL_P(path)) {
1640  rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
1641  "respond_to? is defined here");
1642  }
1643  }
1644  }
1645  }
1646  return RTEST(rb_funcall2(obj, idRespond_to, argc, args));
1647  }
1648 }
1649 
1650 int
1652 {
1653  return rb_obj_respond_to(obj, id, FALSE);
1654 }
1655 
1656 
1657 /*
1658  * call-seq:
1659  * obj.respond_to?(symbol, include_all=false) -> true or false
1660  * obj.respond_to?(string, include_all=false) -> true or false
1661  *
1662  * Returns +true+ if _obj_ responds to the given method. Private and
1663  * protected methods are included in the search only if the optional
1664  * second parameter evaluates to +true+.
1665  *
1666  * If the method is not implemented,
1667  * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
1668  * false is returned.
1669  *
1670  * If the method is not defined, <code>respond_to_missing?</code>
1671  * method is called and the result is returned.
1672  *
1673  * When the method name parameter is given as a string, the string is
1674  * converted to a symbol.
1675  */
1676 
1677 static VALUE
1679 {
1680  VALUE mid, priv;
1681  ID id;
1682 
1683  rb_scan_args(argc, argv, "11", &mid, &priv);
1684  if (!(id = rb_check_id(&mid))) {
1686  VALUE args[2];
1687  args[0] = ID2SYM(rb_to_id(mid));
1688  args[1] = priv;
1689  return rb_funcall2(obj, idRespond_to_missing, 2, args);
1690  }
1691  return Qfalse;
1692  }
1693  if (basic_obj_respond_to(obj, id, !RTEST(priv)))
1694  return Qtrue;
1695  return Qfalse;
1696 }
1697 
1698 /*
1699  * call-seq:
1700  * obj.respond_to_missing?(symbol, include_all) -> true or false
1701  * obj.respond_to_missing?(string, include_all) -> true or false
1702  *
1703  * DO NOT USE THIS DIRECTLY.
1704  *
1705  * Hook method to return whether the _obj_ can respond to _id_ method
1706  * or not.
1707  *
1708  * When the method name parameter is given as a string, the string is
1709  * converted to a symbol.
1710  *
1711  * See #respond_to?, and the example of BasicObject.
1712  */
1713 static VALUE
1715 {
1716  return Qfalse;
1717 }
1718 
1719 void
1721 {
1722 #undef rb_intern
1723 #define rb_intern(str) rb_intern_const(str)
1724 
1725  rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
1726  rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
1727 
1734  rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
1735 
1736  rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
1737  rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
1738  rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
1739  rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
1740  rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
1741  rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
1742 
1744  "public", top_public, -1);
1746  "private", top_private, -1);
1747 
1748  {
1749 #define REPLICATE_METHOD(klass, id, noex) \
1750  rb_method_entry_set((klass), (id), \
1751  rb_method_entry((klass), (id), 0), \
1752  (rb_method_flag_t)(noex | NOEX_BASIC | NOEX_NOREDEF))
1753  REPLICATE_METHOD(rb_eException, idMethodMissing, NOEX_PRIVATE);
1756  }
1757 }
#define UNDEFINED_REFINED_METHOD_P(def)
Definition: method.h:111
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:848
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:1173
#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:1435
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:1350
static VALUE rb_mod_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1038
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:401
static VALUE rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
Definition: vm_method.c:1318
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:17201
#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:1222
void rb_remove_method(VALUE klass, const char *name)
Definition: vm_method.c:767
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1249
static VALUE rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
Definition: vm_method.c:783
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:2119
#define QUOTE_ID(id)
Definition: internal.h:718
#define CLASS_OF(v)
Definition: ruby.h:440
#define VISI_CHECK(x, f)
Definition: vm_method.c:1048
#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:803
VALUE rb_mod_method_location(VALUE mod, ID id)
Definition: proc.c:2171
#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:1190
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1491
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
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:113
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:1255
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:959
union rb_method_definition_struct::@126 body
Definition: vm_method.c:32
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1399
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:17365
int rb_method_basic_definition_p(VALUE klass, ID id)
Definition: vm_method.c:1585
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:3420
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:726
static st_index_t rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
Definition: vm_method.c:1211
static void rb_export_method(VALUE klass, ID name, rb_method_flag_t noex)
Definition: vm_method.c:815
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:1619
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
Definition: vm_method.c:872
int rb_obj_respond_to(VALUE obj, ID id, int priv)
Definition: vm_method.c:1612
#define RB_TYPE_P(obj, type)
Definition: ruby.h:1672
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:1561
int rb_respond_to(VALUE obj, ID id)
Definition: vm_method.c:1651
#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:1560
static VALUE top_public(int argc, VALUE *argv)
Definition: vm_method.c:1481
static VALUE obj_respond_to(int argc, VALUE *argv, VALUE obj)
Definition: vm_method.c:1678
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1549
void rb_remove_method_id(VALUE klass, ID mid)
Definition: vm_method.c:761
#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:1051
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:1499
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:1580
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:1594
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:2834
VALUE klass
Definition: method.h:102
#define ALLOC(type)
Definition: ruby.h:1342
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:1127
#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
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:67
#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:1374
rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:688
static void release_method_definition(rb_method_definition_t *def)
Definition: vm_method.c:160
VALUE(* func)(ANYARGS)
Definition: method.h:66
#define UNDEF_ALLOC_FUNC
Definition: vm_method.c:509
static VALUE rb_mod_protected_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1161
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1719
#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:894
#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:1543
#define rb_funcall2
Definition: ruby.h:1464
#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:15463
static VALUE obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
Definition: vm_method.c:1714
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)
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:995
#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:1329
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:1461
void rb_enable_super(VALUE klass, const char *name)
Definition: vm_method.c:809
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:1167
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:1392
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:1720
static VALUE rb_mod_public_method_defined(VALUE mod, VALUE mid)
Definition: vm_method.c:1093
#define T_CLASS
Definition: ruby.h:478
static VALUE rb_mod_private(int argc, VALUE *argv, VALUE module)
Definition: vm_method.c:1419
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:910
const char * rb_id2name(ID id)
Definition: ripper.c:17271
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:660
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:985
void rb_unlink_method_entry(rb_method_entry_t *me)
Definition: vm_method.c:114
#define mod(x, y)
Definition: date_strftime.c:28
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:374
#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:706
#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:929
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1479
#define ruby_verbose
Definition: ruby.h:1483
void rb_warn(const char *fmt,...)
Definition: error.c:223
ID rb_to_id(VALUE)
Definition: string.c:8734
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:1958
Definition: method.h:105
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1221
#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:922