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