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