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