Ruby  2.5.0dev(2017-10-22revision60238)
vm_method.c
Go to the documentation of this file.
1 /*
2  * This file is included by vm.c
3  */
4 
5 #include "id_table.h"
6 
7 #define METHOD_DEBUG 0
8 
9 #if OPT_GLOBAL_METHOD_CACHE
10 #ifndef GLOBAL_METHOD_CACHE_SIZE
11 #define GLOBAL_METHOD_CACHE_SIZE 0x800
12 #endif
13 #define LSB_ONLY(x) ((x) & ~((x) - 1))
14 #define POWER_OF_2_P(x) ((x) == LSB_ONLY(x))
15 #if !POWER_OF_2_P(GLOBAL_METHOD_CACHE_SIZE)
16 # error GLOBAL_METHOD_CACHE_SIZE must be power of 2
17 #endif
18 #ifndef GLOBAL_METHOD_CACHE_MASK
19 #define GLOBAL_METHOD_CACHE_MASK (GLOBAL_METHOD_CACHE_SIZE-1)
20 #endif
21 
22 #define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&(global_method_cache.mask))
23 #define GLOBAL_METHOD_CACHE(c,m) (global_method_cache.entries + GLOBAL_METHOD_CACHE_KEY(c,m))
24 #else
25 #define GLOBAL_METHOD_CACHE(c,m) (rb_bug("global method cache disabled improperly"), NULL)
26 #endif
27 
28 static int vm_redefinition_check_flag(VALUE klass);
29 static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass);
30 
31 #define object_id idObject_id
32 #define added idMethod_added
33 #define singleton_added idSingleton_method_added
34 #define removed idMethod_removed
35 #define singleton_removed idSingleton_method_removed
36 #define undefined idMethod_undefined
37 #define singleton_undefined idSingleton_method_undefined
38 #define attached id__attached__
39 
40 struct cache_entry {
46 };
47 
48 #if OPT_GLOBAL_METHOD_CACHE
49 static struct {
50  unsigned int size;
51  unsigned int mask;
52  struct cache_entry *entries;
53 } global_method_cache = {
54  GLOBAL_METHOD_CACHE_SIZE,
55  GLOBAL_METHOD_CACHE_MASK,
56 };
57 #endif
58 
59 #define ruby_running (GET_VM()->running)
60 /* int ruby_running = 0; */
61 
62 static void
63 rb_class_clear_method_cache(VALUE klass, VALUE arg)
64 {
66 
67  if (RB_TYPE_P(klass, T_ICLASS)) {
68  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(klass);
69  if (table) {
70  rb_id_table_clear(table);
71  }
72  }
73  else {
74  if (RCLASS_CALLABLE_M_TBL(klass) != 0) {
75  rb_obj_info_dump(klass);
76  rb_bug("RCLASS_CALLABLE_M_TBL(klass) != 0");
77  }
78  }
79 
80  rb_class_foreach_subclass(klass, rb_class_clear_method_cache, arg);
81 }
82 
83 void
85 {
87 }
88 
89 void
91 {
92  if (klass && klass != Qundef) {
93  int global = klass == rb_cBasicObject || klass == rb_cObject || klass == rb_mKernel;
94 
95  RUBY_DTRACE_HOOK(METHOD_CACHE_CLEAR, (global ? "global" : rb_class2name(klass)));
96 
97  if (global) {
99  }
100  else {
101  rb_class_clear_method_cache(klass, Qnil);
102  }
103  }
104 
105  if (klass == rb_mKernel) {
106  rb_subclass_entry_t *entry = RCLASS_EXT(klass)->subclasses;
107 
108  for (; entry != NULL; entry = entry->next) {
109  struct rb_id_table *table = RCLASS_CALLABLE_M_TBL(entry->klass);
110  if (table)rb_id_table_clear(table);
111  }
112  }
113 }
114 
115 VALUE
117 {
118  rb_notimplement();
119 
120  UNREACHABLE;
121 }
122 
123 static void
124 rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_visibility_t visi)
125 {
126  rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, visi);
127 }
128 
129 void
131 {
132  if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc);
133  if (func != rb_f_notimplement) {
134  rb_method_cfunc_t opt;
135  opt.func = func;
136  opt.argc = argc;
137  rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, visi);
138  }
139  else {
140  rb_define_notimplement_method_id(klass, mid, visi);
141  }
142 }
143 
144 static void
145 rb_method_definition_release(rb_method_definition_t *def, int complemented)
146 {
147  if (def != NULL) {
148  const int alias_count = def->alias_count;
149  const int complemented_count = def->complemented_count;
150  VM_ASSERT(alias_count >= 0);
151  VM_ASSERT(complemented_count >= 0);
152 
153  if (alias_count + complemented_count == 0) {
154  if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d,%d (remove)\n", def, rb_id2name(def->original_id), alias_count, complemented_count);
155  xfree(def);
156  }
157  else {
158  if (complemented) def->complemented_count--;
159  else if (def->alias_count > 0) def->alias_count--;
160 
161  if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d,%d->%d (dec)\n", def, rb_id2name(def->original_id),
162  alias_count, def->alias_count, complemented_count, def->complemented_count);
163  }
164  }
165 }
166 
167 void
169 {
170  rb_method_definition_release(me->def, METHOD_ENTRY_COMPLEMENTED(me));
171 }
172 
173 static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr);
174 static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
175 
176 static inline rb_method_entry_t *
177 lookup_method_table(VALUE klass, ID id)
178 {
179  st_data_t body;
180  struct rb_id_table *m_tbl = RCLASS_M_TBL(klass);
181 
182  if (rb_id_table_lookup(m_tbl, id, &body)) {
183  return (rb_method_entry_t *) body;
184  }
185  else {
186  return 0;
187  }
188 }
189 
190 static VALUE
191 (*call_cfunc_invoker_func(int argc))(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *)
192 {
193  switch (argc) {
194  case -2: return &call_cfunc_m2;
195  case -1: return &call_cfunc_m1;
196  case 0: return &call_cfunc_0;
197  case 1: return &call_cfunc_1;
198  case 2: return &call_cfunc_2;
199  case 3: return &call_cfunc_3;
200  case 4: return &call_cfunc_4;
201  case 5: return &call_cfunc_5;
202  case 6: return &call_cfunc_6;
203  case 7: return &call_cfunc_7;
204  case 8: return &call_cfunc_8;
205  case 9: return &call_cfunc_9;
206  case 10: return &call_cfunc_10;
207  case 11: return &call_cfunc_11;
208  case 12: return &call_cfunc_12;
209  case 13: return &call_cfunc_13;
210  case 14: return &call_cfunc_14;
211  case 15: return &call_cfunc_15;
212  default:
213  rb_bug("call_cfunc_func: unsupported length: %d", argc);
214  }
215 }
216 
217 static void
218 setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(), int argc)
219 {
220  cfunc->func = func;
221  cfunc->argc = argc;
222  cfunc->invoker = call_cfunc_invoker_func(argc);
223 }
224 
225 static void
226 method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
227 {
228  *(rb_method_definition_t **)&me->def = def;
229 
230  if (opts != NULL) {
231  switch (def->type) {
232  case VM_METHOD_TYPE_ISEQ:
233  {
234  rb_method_iseq_t *iseq_body = (rb_method_iseq_t *)opts;
235  rb_cref_t *method_cref, *cref = iseq_body->cref;
236 
237  /* setup iseq first (before invoking GC) */
238  RB_OBJ_WRITE(me, &def->body.iseq.iseqptr, iseq_body->iseqptr);
239 
240  if (0) vm_cref_dump("rb_method_definition_create", cref);
241 
242  if (cref) {
243  method_cref = cref;
244  }
245  else {
246  method_cref = vm_cref_new_toplevel(GET_THREAD()); /* TODO: can we reuse? */
247  }
248 
249  RB_OBJ_WRITE(me, &def->body.iseq.cref, method_cref);
250  return;
251  }
253  {
254  rb_method_cfunc_t *cfunc = (rb_method_cfunc_t *)opts;
255  setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), cfunc->func, cfunc->argc);
256  return;
257  }
259  case VM_METHOD_TYPE_IVAR:
260  {
261  rb_thread_t *th = GET_THREAD();
262  rb_control_frame_t *cfp;
263  int line;
264 
265  def->body.attr.id = (ID)(VALUE)opts;
266 
267  cfp = rb_vm_get_ruby_level_next_cfp(th, th->ec.cfp);
268 
269  if (cfp && (line = rb_vm_get_sourceline(cfp))) {
270  VALUE location = rb_ary_new3(2, rb_iseq_path(cfp->iseq), INT2FIX(line));
271  RB_OBJ_WRITE(me, &def->body.attr.location, rb_ary_freeze(location));
272  }
273  else {
274  VM_ASSERT(def->body.attr.location == 0);
275  }
276  return;
277  }
279  RB_OBJ_WRITE(me, &def->body.proc, (VALUE)opts);
280  return;
282  setup_method_cfunc_struct(UNALIGNED_MEMBER_PTR(def, body.cfunc), rb_f_notimplement, -1);
283  return;
285  def->body.optimize_type = (enum method_optimized_type)opts;
286  return;
288  {
289  const rb_method_refined_t *refined = (rb_method_refined_t *)opts;
290  RB_OBJ_WRITE(me, &def->body.refined.orig_me, refined->orig_me);
291  RB_OBJ_WRITE(me, &def->body.refined.owner, refined->owner);
292  return;
293  }
295  RB_OBJ_WRITE(me, &def->body.alias.original_me, (rb_method_entry_t *)opts);
296  return;
300  return;
301  }
302  }
303 }
304 
305 static void
306 method_definition_reset(const rb_method_entry_t *me)
307 {
308  rb_method_definition_t *def = me->def;
309 
310  switch(def->type) {
311  case VM_METHOD_TYPE_ISEQ:
312  RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.iseqptr);
313  RB_OBJ_WRITTEN(me, Qundef, def->body.iseq.cref);
314  break;
316  case VM_METHOD_TYPE_IVAR:
317  RB_OBJ_WRITTEN(me, Qundef, def->body.attr.location);
318  break;
320  RB_OBJ_WRITTEN(me, Qundef, def->body.proc);
321  break;
323  RB_OBJ_WRITTEN(me, Qundef, def->body.refined.orig_me);
324  RB_OBJ_WRITTEN(me, Qundef, def->body.refined.owner);
325  break;
327  RB_OBJ_WRITTEN(me, Qundef, def->body.alias.original_me);
328  break;
335  break;
336  }
337 }
338 
339 static rb_method_definition_t *
340 method_definition_create(rb_method_type_t type, ID mid)
341 {
344  def->type = type;
345  def->original_id = mid;
346  return def;
347 }
348 
349 static rb_method_definition_t *
350 method_definition_addref(rb_method_definition_t *def)
351 {
352  def->alias_count++;
353  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", def, rb_id2name(def->original_id), def->alias_count);
354  return def;
355 }
356 
357 static rb_method_definition_t *
358 method_definition_addref_complement(rb_method_definition_t *def)
359 {
360  def->complemented_count++;
361  if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", def, rb_id2name(def->original_id), def->alias_count);
362  return def;
363 }
364 
365 static rb_method_entry_t *
366 rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def)
367 {
368  rb_method_entry_t *me = (rb_method_entry_t *)rb_imemo_new(imemo_ment, (VALUE)def, (VALUE)called_id, owner, defined_class);
369  return me;
370 }
371 
372 static VALUE
373 filter_defined_class(VALUE klass)
374 {
375  switch (BUILTIN_TYPE(klass)) {
376  case T_CLASS:
377  return klass;
378  case T_MODULE:
379  return 0;
380  case T_ICLASS:
381  break;
382  }
383  rb_bug("filter_defined_class: %s", rb_obj_info(klass));
384 }
385 
388 {
389  rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def);
390  METHOD_ENTRY_FLAGS_SET(me, visi, ruby_running ? FALSE : TRUE);
391  if (def != NULL) method_definition_reset(me);
392  return me;
393 }
394 
395 const rb_method_entry_t *
397 {
398  rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class,
399  method_definition_addref(src_me->def));
400  METHOD_ENTRY_FLAGS_COPY(me, src_me);
401  return me;
402 }
403 
405 rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
406 {
407  rb_method_entry_t *me = rb_method_entry_alloc(called_id, src_me->owner, defined_class,
408  method_definition_addref_complement(src_me->def));
409  METHOD_ENTRY_FLAGS_COPY(me, src_me);
411 
413 
414  return (rb_callable_method_entry_t *)me;
415 }
416 
417 void
419 {
420  *(rb_method_definition_t **)&dst->def = method_definition_addref(src->def);
421  method_definition_reset(dst);
422  dst->called_id = src->called_id;
423  RB_OBJ_WRITE((VALUE)dst, &dst->owner, src->owner);
424  RB_OBJ_WRITE((VALUE)dst, &dst->defined_class, src->defined_class);
425  METHOD_ENTRY_FLAGS_COPY(dst, src);
426 }
427 
428 static void
429 make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
430 {
431  if (me->def->type == VM_METHOD_TYPE_REFINED) {
432  return;
433  }
434  else {
435  struct {
436  struct rb_method_entry_struct *orig_me;
437  VALUE owner;
438  } refined;
439 
440  rb_vm_check_redefinition_opt_method(me, me->owner);
441 
442  refined.orig_me =
443  rb_method_entry_alloc(me->called_id, me->owner,
444  me->defined_class ?
445  me->defined_class : owner,
446  method_definition_addref(me->def));
447  METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me);
448  refined.owner = owner;
449 
450  method_definition_set(me, method_definition_create(VM_METHOD_TYPE_REFINED, me->called_id), (void *)&refined);
451  METHOD_ENTRY_VISI_SET(me, METHOD_VISI_PUBLIC);
452  }
453 }
454 
455 void
457 {
458  rb_method_entry_t *me = lookup_method_table(refined_class, mid);
459 
460  if (me) {
461  make_method_entry_refined(refined_class, me);
462  rb_clear_method_cache_by_class(refined_class);
463  }
464  else {
466  }
467 }
468 
469 static void
470 check_override_opt_method(VALUE klass, VALUE arg)
471 {
472  ID mid = (ID)arg;
473  const rb_method_entry_t *me, *newme;
474 
475  if (vm_redefinition_check_flag(klass)) {
476  me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
477  if (me) {
478  newme = rb_method_entry(klass, mid);
479  if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
480  }
481  }
482  rb_class_foreach_subclass(klass, check_override_opt_method, (VALUE)mid);
483 }
484 
485 /*
486  * klass->method_table[mid] = method_entry(defined_class, visi, def)
487  *
488  * If def is given (!= NULL), then just use it and ignore original_id and otps.
489  * If not given, then make a new def with original_id and opts.
490  */
491 static rb_method_entry_t *
492 rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibility_t visi,
493  rb_method_type_t type, rb_method_definition_t *def, ID original_id, void *opts)
494 {
496  struct rb_id_table *mtbl;
497  st_data_t data;
498  int make_refined = 0;
499 
500  if (NIL_P(klass)) {
501  klass = rb_cObject;
502  }
503  if (!FL_TEST(klass, FL_SINGLETON) &&
505  type != VM_METHOD_TYPE_ZSUPER) {
506  switch (mid) {
507  case idInitialize:
508  case idInitialize_copy:
509  case idInitialize_clone:
510  case idInitialize_dup:
512  visi = METHOD_VISI_PRIVATE;
513  }
514  }
515 
516  rb_frozen_class_p(klass);
517 
518  if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
519  VALUE refined_class = rb_refinement_module_get_refined_class(klass);
520  rb_add_refined_method_entry(refined_class, mid);
521  }
522  if (type == VM_METHOD_TYPE_REFINED) {
523  rb_method_entry_t *old_me = lookup_method_table(RCLASS_ORIGIN(klass), mid);
524  if (old_me) rb_vm_check_redefinition_opt_method(old_me, klass);
525  }
526  else {
527  klass = RCLASS_ORIGIN(klass);
528  }
529  mtbl = RCLASS_M_TBL(klass);
530 
531  /* check re-definition */
532  if (rb_id_table_lookup(mtbl, mid, &data)) {
533  rb_method_entry_t *old_me = (rb_method_entry_t *)data;
534  rb_method_definition_t *old_def = old_me->def;
535 
536  if (rb_method_definition_eq(old_def, def)) return old_me;
537  rb_vm_check_redefinition_opt_method(old_me, klass);
538 
539  if (old_def->type == VM_METHOD_TYPE_REFINED) make_refined = 1;
540 
541  if (RTEST(ruby_verbose) &&
542  type != VM_METHOD_TYPE_UNDEF &&
543  (old_def->alias_count == 0) &&
544  !make_refined &&
545  old_def->type != VM_METHOD_TYPE_UNDEF &&
546  old_def->type != VM_METHOD_TYPE_ZSUPER &&
547  old_def->type != VM_METHOD_TYPE_ALIAS) {
548  const rb_iseq_t *iseq = 0;
549 
550  rb_warning("method redefined; discarding old %"PRIsVALUE, rb_id2str(mid));
551  switch (old_def->type) {
552  case VM_METHOD_TYPE_ISEQ:
553  iseq = def_iseq_ptr(old_def);
554  break;
556  iseq = rb_proc_get_iseq(old_def->body.proc, 0);
557  break;
558  default:
559  break;
560  }
561  if (iseq) {
564  "previous definition of %"PRIsVALUE" was here",
565  rb_id2str(old_def->original_id));
566  }
567  }
568  }
569 
570  /* create method entry */
571  me = rb_method_entry_create(mid, defined_class, visi, NULL);
572  if (def == NULL) def = method_definition_create(type, original_id);
573  method_definition_set(me, def, opts);
574 
576 
577  /* check mid */
578  if (klass == rb_cObject && mid == idInitialize) {
579  rb_warn("redefining Object#initialize may cause infinite loop");
580  }
581  /* check mid */
582  if (mid == object_id || mid == id__send__) {
583  if (type == VM_METHOD_TYPE_ISEQ && search_method(klass, mid, 0)) {
584  rb_warn("redefining `%s' may cause serious problems", rb_id2name(mid));
585  }
586  }
587 
588  if (make_refined) {
589  make_method_entry_refined(klass, me);
590  }
591 
592  rb_id_table_insert(mtbl, mid, (VALUE)me);
593  RB_OBJ_WRITTEN(klass, Qundef, (VALUE)me);
594 
595  VM_ASSERT(me->def != NULL);
596 
597  /* check optimized method override by a prepended module */
598  if (RB_TYPE_P(klass, T_MODULE)) {
599  check_override_opt_method(klass, (VALUE)mid);
600  }
601 
602  return me;
603 }
604 
605 #define CALL_METHOD_HOOK(klass, hook, mid) do { \
606  const VALUE arg = ID2SYM(mid); \
607  VALUE recv_class = (klass); \
608  ID hook_id = (hook); \
609  if (FL_TEST((klass), FL_SINGLETON)) { \
610  recv_class = rb_ivar_get((klass), attached); \
611  hook_id = singleton_##hook; \
612  } \
613  rb_funcallv(recv_class, hook_id, 1, &arg); \
614  } while (0)
615 
616 static void
617 method_added(VALUE klass, ID mid)
618 {
619  if (ruby_running) {
620  CALL_METHOD_HOOK(klass, added, mid);
621  }
622 }
623 
625 rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
626 {
627  rb_method_entry_t *me = rb_method_entry_make(klass, mid, klass, visi, type, NULL, mid, opts);
628 
629  if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
630  method_added(klass, mid);
631  }
632 
633  return me;
634 }
635 
636 void
638 {
639  struct { /* should be same fields with rb_method_iseq_struct */
640  const rb_iseq_t *iseqptr;
641  rb_cref_t *cref;
642  } iseq_body;
643 
644  iseq_body.iseqptr = iseq;
645  iseq_body.cref = cref;
646  rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi);
647 }
648 
649 static rb_method_entry_t *
650 method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me,
651  rb_method_visibility_t visi, VALUE defined_class)
652 {
653  rb_method_entry_t *newme = rb_method_entry_make(klass, mid, defined_class, visi,
654  me->def->type, method_definition_addref(me->def), 0, NULL);
655  method_added(klass, mid);
656  return newme;
657 }
658 
661 {
662  return method_entry_set(klass, mid, me, visi, klass);
663 }
664 
665 #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1)
666 
667 void
669 {
670  Check_Type(klass, T_CLASS);
671  RCLASS_EXT(klass)->allocator = func;
672 }
673 
674 void
676 {
678 }
679 
682 {
683  Check_Type(klass, T_CLASS);
684 
685  for (; klass; klass = RCLASS_SUPER(klass)) {
686  rb_alloc_func_t allocator = RCLASS_EXT(klass)->allocator;
687  if (allocator == UNDEF_ALLOC_FUNC) break;
688  if (allocator) return allocator;
689  }
690  return 0;
691 }
692 
693 static inline rb_method_entry_t*
694 search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
695 {
697 
698  for (me = 0; klass; klass = RCLASS_SUPER(klass)) {
699  RB_DEBUG_COUNTER_INC(mc_search_super);
700  if ((me = lookup_method_table(klass, id)) != 0) break;
701  }
702 
703  if (defined_class_ptr)
704  *defined_class_ptr = klass;
705  return me;
706 }
707 
708 const rb_method_entry_t *
710 {
711  return lookup_method_table(klass, id);
712 }
713 
714 /*
715  * search method entry without the method cache.
716  *
717  * if you need method entry with method cache (normal case), use
718  * rb_method_entry() simply.
719  */
720 static rb_method_entry_t *
721 method_entry_get_without_cache(VALUE klass, ID id,
722  VALUE *defined_class_ptr)
723 {
725  rb_method_entry_t *me = search_method(klass, id, &defined_class);
726 
727  if (ruby_running) {
729  struct cache_entry *ent;
730  ent = GLOBAL_METHOD_CACHE(klass, id);
731  ent->class_serial = RCLASS_SERIAL(klass);
734  ent->mid = id;
735 
736  if (UNDEFINED_METHOD_ENTRY_P(me)) {
737  me = ent->me = NULL;
738  }
739  else {
740  ent->me = me;
741  }
742  }
743  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
744  me = NULL;
745  }
746  }
747  else if (UNDEFINED_METHOD_ENTRY_P(me)) {
748  me = NULL;
749  }
750 
751  if (defined_class_ptr)
752  *defined_class_ptr = defined_class;
753  return me;
754 }
755 
756 #if VM_DEBUG_VERIFY_METHOD_CACHE
757 static void
758 verify_method_cache(VALUE klass, ID id, VALUE defined_class, rb_method_entry_t *me)
759 {
760  VALUE actual_defined_class;
761  rb_method_entry_t *actual_me =
762  method_entry_get_without_cache(klass, id, &actual_defined_class);
763 
764  if (me != actual_me || defined_class != actual_defined_class) {
765  rb_bug("method cache verification failed");
766  }
767 }
768 #endif
769 
770 static rb_method_entry_t *
771 method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
772 {
773 #if OPT_GLOBAL_METHOD_CACHE
774  struct cache_entry *ent;
775  ent = GLOBAL_METHOD_CACHE(klass, id);
776  if (ent->method_state == GET_GLOBAL_METHOD_STATE() &&
777  ent->class_serial == RCLASS_SERIAL(klass) &&
778  ent->mid == id) {
779 #if VM_DEBUG_VERIFY_METHOD_CACHE
780  verify_method_cache(klass, id, ent->defined_class, ent->me);
781 #endif
782  if (defined_class_ptr) *defined_class_ptr = ent->defined_class;
783  RB_DEBUG_COUNTER_INC(mc_global_hit);
784  return ent->me;
785  }
786 #endif
787 
788  RB_DEBUG_COUNTER_INC(mc_global_miss);
789  return method_entry_get_without_cache(klass, id, defined_class_ptr);
790 }
791 
792 const rb_method_entry_t *
794 {
795  return method_entry_get(klass, id, NULL);
796 }
797 
798 static const rb_callable_method_entry_t *
799 prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_t *me)
800 {
801  struct rb_id_table *mtbl;
802  const rb_callable_method_entry_t *cme;
803 
804  if (me && me->defined_class == 0) {
805  RB_DEBUG_COUNTER_INC(mc_cme_complement);
806  VM_ASSERT(RB_TYPE_P(defined_class, T_ICLASS) || RB_TYPE_P(defined_class, T_MODULE));
807  VM_ASSERT(me->defined_class == 0);
808 
809  if ((mtbl = RCLASS_CALLABLE_M_TBL(defined_class)) == NULL) {
810  mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
811  }
812 
813  if (rb_id_table_lookup(mtbl, id, (VALUE *)&me)) {
814  RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
815  cme = (rb_callable_method_entry_t *)me;
816  VM_ASSERT(callable_method_entry_p(cme));
817  }
818  else {
819  cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
820  rb_id_table_insert(mtbl, id, (VALUE)cme);
821  VM_ASSERT(callable_method_entry_p(cme));
822  }
823  }
824  else {
825  cme = (const rb_callable_method_entry_t *)me;
826  VM_ASSERT(callable_method_entry_p(cme));
827  }
828 
829  return cme;
830 }
831 
834 {
836  rb_method_entry_t *me = method_entry_get(klass, id, &defined_class);
837  return prepare_callable_method_entry(defined_class, id, me);
838 }
839 
840 static const rb_method_entry_t *resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr);
841 
842 static const rb_method_entry_t *
843 method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *defined_class_ptr)
844 {
845  const rb_method_entry_t *me = method_entry_get(klass, id, defined_class_ptr);
846 
847  if (me) {
848  if (me->def->type == VM_METHOD_TYPE_REFINED) {
849  if (with_refinement) {
850  const rb_cref_t *cref = rb_vm_cref();
851  VALUE refinements = cref ? CREF_REFINEMENTS(cref) : Qnil;
852  me = resolve_refined_method(refinements, me, defined_class_ptr);
853  }
854  else {
855  me = resolve_refined_method(Qnil, me, defined_class_ptr);
856  }
857 
858  if (UNDEFINED_METHOD_ENTRY_P(me)) me = NULL;
859  }
860  }
861 
862  return me;
863 }
864 
865 const rb_method_entry_t *
866 rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
867 {
868  return method_entry_resolve_refinement(klass, id, TRUE, defined_class_ptr);
869 }
870 
873 {
874  VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
875  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, TRUE, dcp);
876  return prepare_callable_method_entry(*dcp, id, me);
877 }
878 
879 const rb_method_entry_t *
880 rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
881 {
882  return method_entry_resolve_refinement(klass, id, FALSE, defined_class_ptr);
883 }
884 
887 {
888  VALUE defined_class, *dcp = defined_class_ptr ? defined_class_ptr : &defined_class;
889  const rb_method_entry_t *me = method_entry_resolve_refinement(klass, id, FALSE, dcp);
890  return prepare_callable_method_entry(*dcp, id, me);
891 }
892 
893 static const rb_method_entry_t *
894 refined_method_original_method_entry(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
895 {
896  VALUE super;
897 
898  if (me->def->body.refined.orig_me) {
899  if (defined_class_ptr) *defined_class_ptr = me->def->body.refined.orig_me->defined_class;
900  return me->def->body.refined.orig_me;
901  }
902  else if (!(super = RCLASS_SUPER(me->owner))) {
903  return 0;
904  }
905  else {
906  rb_method_entry_t *tmp_me;
907  tmp_me = method_entry_get(super, me->called_id, defined_class_ptr);
908  return resolve_refined_method(refinements, tmp_me, defined_class_ptr);
909  }
910 }
911 
912 static const rb_method_entry_t *
913 resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
914 {
915  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
916  VALUE refinement;
917  rb_method_entry_t *tmp_me;
918 
919  refinement = find_refinement(refinements, me->owner);
920  if (NIL_P(refinement)) {
921  return refined_method_original_method_entry(refinements, me, defined_class_ptr);
922  }
923  else {
924  tmp_me = method_entry_get(refinement, me->called_id, defined_class_ptr);
925 
926  if (tmp_me && tmp_me->def->type != VM_METHOD_TYPE_REFINED) {
927  return tmp_me;
928  }
929  else {
930  return refined_method_original_method_entry(refinements, me, defined_class_ptr);
931  }
932  }
933  }
934  else {
935  return me;
936  }
937 }
938 
939 const rb_method_entry_t *
941 {
942  return resolve_refined_method(refinements, me, NULL);
943 }
944 
947 {
948  VALUE defined_class = me->defined_class;
949  const rb_method_entry_t *resolved_me = resolve_refined_method(refinements, (const rb_method_entry_t *)me, &defined_class);
950 
951  if (resolved_me && resolved_me->defined_class == 0) {
952  return rb_method_entry_complement_defined_class(resolved_me, me->called_id, defined_class);
953  }
954  else {
955  return (const rb_callable_method_entry_t *)resolved_me;
956  }
957 }
958 
959 static void
960 remove_method(VALUE klass, ID mid)
961 {
962  VALUE data;
963  rb_method_entry_t *me = 0;
964  VALUE self = klass;
965 
966  klass = RCLASS_ORIGIN(klass);
967  rb_frozen_class_p(klass);
968  if (mid == object_id || mid == id__send__ || mid == idInitialize) {
969  rb_warn("removing `%s' may cause serious problems", rb_id2name(mid));
970  }
971 
972  if (!rb_id_table_lookup(RCLASS_M_TBL(klass), mid, &data) ||
973  !(me = (rb_method_entry_t *)data) ||
974  (!me->def || me->def->type == VM_METHOD_TYPE_UNDEF) ||
976  rb_name_err_raise("method `%1$s' not defined in %2$s",
977  klass, ID2SYM(mid));
978  }
979 
980  rb_id_table_delete(RCLASS_M_TBL(klass), mid);
981 
982  rb_vm_check_redefinition_opt_method(me, klass);
984 
985  if (me->def->type == VM_METHOD_TYPE_REFINED) {
986  rb_add_refined_method_entry(klass, mid);
987  }
988 
989  CALL_METHOD_HOOK(self, removed, mid);
990 }
991 
992 void
994 {
995  remove_method(klass, mid);
996 }
997 
998 void
999 rb_remove_method(VALUE klass, const char *name)
1000 {
1001  remove_method(klass, rb_intern(name));
1002 }
1003 
1004 /*
1005  * call-seq:
1006  * remove_method(symbol) -> self
1007  * remove_method(string) -> self
1008  *
1009  * Removes the method identified by _symbol_ from the current
1010  * class. For an example, see <code>Module.undef_method</code>.
1011  * String arguments are converted to symbols.
1012  */
1013 
1014 static VALUE
1015 rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
1016 {
1017  int i;
1018 
1019  for (i = 0; i < argc; i++) {
1020  VALUE v = argv[i];
1021  ID id = rb_check_id(&v);
1022  if (!id) {
1023  rb_name_err_raise("method `%1$s' not defined in %2$s",
1024  mod, v);
1025  }
1026  remove_method(mod, id);
1027  }
1028  return mod;
1029 }
1030 
1031 static void
1032 rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
1033 {
1036 
1037  me = search_method(klass, name, &defined_class);
1038  if (!me && RB_TYPE_P(klass, T_MODULE)) {
1039  me = search_method(rb_cObject, name, &defined_class);
1040  }
1041 
1042  if (UNDEFINED_METHOD_ENTRY_P(me) ||
1044  rb_print_undef(klass, name, METHOD_VISI_UNDEF);
1045  }
1046 
1047  if (METHOD_ENTRY_VISI(me) != visi) {
1048  rb_vm_check_redefinition_opt_method(me, klass);
1049 
1050  if (klass == defined_class || RCLASS_ORIGIN(klass) == defined_class) {
1051  METHOD_ENTRY_VISI_SET(me, visi);
1052 
1053  if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
1054  METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
1055  }
1057  }
1058  else {
1059  rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, visi);
1060  }
1061  }
1062 }
1063 
1064 #define BOUND_PRIVATE 0x01
1065 #define BOUND_RESPONDS 0x02
1066 
1067 int
1068 rb_method_boundp(VALUE klass, ID id, int ex)
1069 {
1071 
1072  if (me != 0) {
1073  if ((ex & ~BOUND_RESPONDS) &&
1075  ((ex & BOUND_RESPONDS) && (METHOD_ENTRY_VISI(me) == METHOD_VISI_PROTECTED)))) {
1076  return 0;
1077  }
1078 
1079  if (me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
1080  if (ex & BOUND_RESPONDS) return 2;
1081  return 0;
1082  }
1083  return 1;
1084  }
1085  return 0;
1086 }
1087 
1089 rb_scope_visibility_get(void)
1090 {
1091  rb_thread_t *th = GET_THREAD();
1093 
1094  if (!vm_env_cref_by_cref(cfp->ep)) {
1095  return METHOD_VISI_PUBLIC;
1096  }
1097  else {
1098  return CREF_SCOPE_VISI(rb_vm_cref())->method_visi;
1099  }
1100 }
1101 
1102 static int
1103 rb_scope_module_func_check(void)
1104 {
1105  rb_thread_t *th = GET_THREAD();
1107 
1108  if (!vm_env_cref_by_cref(cfp->ep)) {
1109  return FALSE;
1110  }
1111  else {
1112  return CREF_SCOPE_VISI(rb_vm_cref())->module_func;
1113  }
1114 }
1115 
1116 static void
1117 vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
1118 {
1120  scope_visi->method_visi = method_visi;
1121  scope_visi->module_func = module_func;
1122 }
1123 
1124 void
1126 {
1127  vm_cref_set_visibility(visi, FALSE);
1128 }
1129 
1130 static void
1131 rb_scope_module_func_set(void)
1132 {
1133  vm_cref_set_visibility(METHOD_VISI_PRIVATE, TRUE);
1134 }
1135 
1136 void
1137 rb_attr(VALUE klass, ID id, int read, int write, int ex)
1138 {
1139  ID attriv;
1141 
1142  if (!ex) {
1143  visi = METHOD_VISI_PUBLIC;
1144  }
1145  else {
1146  switch (rb_scope_visibility_get()) {
1147  case METHOD_VISI_PRIVATE:
1148  if (rb_scope_module_func_check()) {
1149  rb_warning("attribute accessor as module_function");
1150  }
1151  visi = METHOD_VISI_PRIVATE;
1152  break;
1153  case METHOD_VISI_PROTECTED:
1154  visi = METHOD_VISI_PROTECTED;
1155  break;
1156  default:
1157  visi = METHOD_VISI_PUBLIC;
1158  break;
1159  }
1160  }
1161 
1162  attriv = rb_intern_str(rb_sprintf("@%"PRIsVALUE, rb_id2str(id)));
1163  if (read) {
1164  rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, visi);
1165  }
1166  if (write) {
1167  rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, visi);
1168  }
1169 }
1170 
1171 void
1172 rb_undef(VALUE klass, ID id)
1173 {
1174  const rb_method_entry_t *me;
1175 
1176  if (NIL_P(klass)) {
1177  rb_raise(rb_eTypeError, "no class to undef method");
1178  }
1179  rb_frozen_class_p(klass);
1180  if (id == object_id || id == id__send__ || id == idInitialize) {
1181  rb_warn("undefining `%s' may cause serious problems", rb_id2name(id));
1182  }
1183 
1184  me = search_method(klass, id, 0);
1185  if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
1186  me = rb_resolve_refined_method(Qnil, me);
1187  }
1188 
1189  if (UNDEFINED_METHOD_ENTRY_P(me) ||
1191  rb_method_name_error(klass, rb_id2str(id));
1192  }
1193 
1195 
1196  CALL_METHOD_HOOK(klass, undefined, id);
1197 }
1198 
1199 /*
1200  * call-seq:
1201  * undef_method(symbol) -> self
1202  * undef_method(string) -> self
1203  *
1204  * Prevents the current class from responding to calls to the named
1205  * method. Contrast this with <code>remove_method</code>, which deletes
1206  * the method from the particular class; Ruby will still search
1207  * superclasses and mixed-in modules for a possible receiver.
1208  * String arguments are converted to symbols.
1209  *
1210  * class Parent
1211  * def hello
1212  * puts "In parent"
1213  * end
1214  * end
1215  * class Child < Parent
1216  * def hello
1217  * puts "In child"
1218  * end
1219  * end
1220  *
1221  *
1222  * c = Child.new
1223  * c.hello
1224  *
1225  *
1226  * class Child
1227  * remove_method :hello # remove from child, still in parent
1228  * end
1229  * c.hello
1230  *
1231  *
1232  * class Child
1233  * undef_method :hello # prevent any calls to 'hello'
1234  * end
1235  * c.hello
1236  *
1237  * <em>produces:</em>
1238  *
1239  * In child
1240  * In parent
1241  * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
1242  */
1243 
1244 static VALUE
1245 rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
1246 {
1247  int i;
1248  for (i = 0; i < argc; i++) {
1249  VALUE v = argv[i];
1250  ID id = rb_check_id(&v);
1251  if (!id) {
1252  rb_method_name_error(mod, v);
1253  }
1254  rb_undef(mod, id);
1255  }
1256  return mod;
1257 }
1258 
1259 /*
1260  * call-seq:
1261  * mod.method_defined?(symbol) -> true or false
1262  * mod.method_defined?(string) -> true or false
1263  *
1264  * Returns +true+ if the named method is defined by
1265  * _mod_ (or its included modules and, if _mod_ is a class,
1266  * its ancestors). Public and protected methods are matched.
1267  * String arguments are converted to symbols.
1268  *
1269  * module A
1270  * def method1() end
1271  * def protected_method1() end
1272  * protected :protected_method1
1273  * end
1274  * class B
1275  * def method2() end
1276  * def private_method2() end
1277  * private :private_method2
1278  * end
1279  * class C < B
1280  * include A
1281  * def method3() end
1282  * end
1283  *
1284  * A.method_defined? :method1 #=> true
1285  * C.method_defined? "method1" #=> true
1286  * C.method_defined? "method2" #=> true
1287  * C.method_defined? "method3" #=> true
1288  * C.method_defined? "protected_method1" #=> true
1289  * C.method_defined? "method4" #=> false
1290  * C.method_defined? "private_method2" #=> false
1291  */
1292 
1293 static VALUE
1294 rb_mod_method_defined(VALUE mod, VALUE mid)
1295 {
1296  ID id = rb_check_id(&mid);
1297  if (!id || !rb_method_boundp(mod, id, 1)) {
1298  return Qfalse;
1299  }
1300  return Qtrue;
1301 
1302 }
1303 
1304 static VALUE
1305 check_definition(VALUE mod, VALUE mid, rb_method_visibility_t visi)
1306 {
1307  const rb_method_entry_t *me;
1308  ID id = rb_check_id(&mid);
1309  if (!id) return Qfalse;
1311  if (me) {
1312  if (METHOD_ENTRY_VISI(me) == visi) return Qtrue;
1313  }
1314  return Qfalse;
1315 }
1316 
1317 /*
1318  * call-seq:
1319  * mod.public_method_defined?(symbol) -> true or false
1320  * mod.public_method_defined?(string) -> true or false
1321  *
1322  * Returns +true+ if the named public method is defined by
1323  * _mod_ (or its included modules and, if _mod_ is a class,
1324  * its ancestors).
1325  * String arguments are converted to symbols.
1326  *
1327  * module A
1328  * def method1() end
1329  * end
1330  * class B
1331  * protected
1332  * def method2() end
1333  * end
1334  * class C < B
1335  * include A
1336  * def method3() end
1337  * end
1338  *
1339  * A.method_defined? :method1 #=> true
1340  * C.public_method_defined? "method1" #=> true
1341  * C.public_method_defined? "method2" #=> false
1342  * C.method_defined? "method2" #=> true
1343  */
1344 
1345 static VALUE
1346 rb_mod_public_method_defined(VALUE mod, VALUE mid)
1347 {
1348  return check_definition(mod, mid, METHOD_VISI_PUBLIC);
1349 }
1350 
1351 /*
1352  * call-seq:
1353  * mod.private_method_defined?(symbol) -> true or false
1354  * mod.private_method_defined?(string) -> true or false
1355  *
1356  * Returns +true+ if the named private method is defined by
1357  * _ mod_ (or its included modules and, if _mod_ is a class,
1358  * its ancestors).
1359  * String arguments are converted to symbols.
1360  *
1361  * module A
1362  * def method1() end
1363  * end
1364  * class B
1365  * private
1366  * def method2() end
1367  * end
1368  * class C < B
1369  * include A
1370  * def method3() end
1371  * end
1372  *
1373  * A.method_defined? :method1 #=> true
1374  * C.private_method_defined? "method1" #=> false
1375  * C.private_method_defined? "method2" #=> true
1376  * C.method_defined? "method2" #=> false
1377  */
1378 
1379 static VALUE
1380 rb_mod_private_method_defined(VALUE mod, VALUE mid)
1381 {
1382  return check_definition(mod, mid, METHOD_VISI_PRIVATE);
1383 }
1384 
1385 /*
1386  * call-seq:
1387  * mod.protected_method_defined?(symbol) -> true or false
1388  * mod.protected_method_defined?(string) -> true or false
1389  *
1390  * Returns +true+ if the named protected method is defined
1391  * by _mod_ (or its included modules and, if _mod_ is a
1392  * class, its ancestors).
1393  * String arguments are converted to symbols.
1394  *
1395  * module A
1396  * def method1() end
1397  * end
1398  * class B
1399  * protected
1400  * def method2() end
1401  * end
1402  * class C < B
1403  * include A
1404  * def method3() end
1405  * end
1406  *
1407  * A.method_defined? :method1 #=> true
1408  * C.protected_method_defined? "method1" #=> false
1409  * C.protected_method_defined? "method2" #=> true
1410  * C.method_defined? "method2" #=> true
1411  */
1412 
1413 static VALUE
1414 rb_mod_protected_method_defined(VALUE mod, VALUE mid)
1415 {
1416  return check_definition(mod, mid, METHOD_VISI_PROTECTED);
1417 }
1418 
1419 int
1421 {
1422  return rb_method_definition_eq(m1->def, m2->def);
1423 }
1424 
1425 static const rb_method_definition_t *
1426 original_method_definition(const rb_method_definition_t *def)
1427 {
1428  again:
1429  if (def) {
1430  switch (def->type) {
1432  if (def->body.refined.orig_me) {
1433  def = def->body.refined.orig_me->def;
1434  goto again;
1435  }
1436  break;
1437  case VM_METHOD_TYPE_ALIAS:
1438  def = def->body.alias.original_me->def;
1439  goto again;
1440  default:
1441  break;
1442  }
1443  }
1444  return def;
1445 }
1446 
1447 static int
1448 rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
1449 {
1450  d1 = original_method_definition(d1);
1451  d2 = original_method_definition(d2);
1452 
1453  if (d1 == d2) return 1;
1454  if (!d1 || !d2) return 0;
1455  if (d1->type != d2->type) return 0;
1456 
1457  switch (d1->type) {
1458  case VM_METHOD_TYPE_ISEQ:
1459  return d1->body.iseq.iseqptr == d2->body.iseq.iseqptr;
1460  case VM_METHOD_TYPE_CFUNC:
1461  return
1462  d1->body.cfunc.func == d2->body.cfunc.func &&
1463  d1->body.cfunc.argc == d2->body.cfunc.argc;
1465  case VM_METHOD_TYPE_IVAR:
1466  return d1->body.attr.id == d2->body.attr.id;
1468  return RTEST(rb_equal(d1->body.proc, d2->body.proc));
1470  return d1->original_id == d2->original_id;
1471  case VM_METHOD_TYPE_ZSUPER:
1473  case VM_METHOD_TYPE_UNDEF:
1474  return 1;
1476  return d1->body.optimize_type == d2->body.optimize_type;
1478  case VM_METHOD_TYPE_ALIAS:
1479  break;
1480  }
1481  rb_bug("rb_method_definition_eq: unsupported type: %d\n", d1->type);
1482 }
1483 
1484 static st_index_t
1485 rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
1486 {
1487  hash = rb_hash_uint(hash, def->type);
1488  def = original_method_definition(def);
1489 
1490  if (!def) return hash;
1491 
1492  switch (def->type) {
1493  case VM_METHOD_TYPE_ISEQ:
1494  return rb_hash_uint(hash, (st_index_t)def->body.iseq.iseqptr);
1495  case VM_METHOD_TYPE_CFUNC:
1496  hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
1497  return rb_hash_uint(hash, def->body.cfunc.argc);
1499  case VM_METHOD_TYPE_IVAR:
1500  return rb_hash_uint(hash, def->body.attr.id);
1502  return rb_hash_proc(hash, def->body.proc);
1504  return rb_hash_uint(hash, def->original_id);
1505  case VM_METHOD_TYPE_ZSUPER:
1507  case VM_METHOD_TYPE_UNDEF:
1508  return hash;
1510  return rb_hash_uint(hash, def->body.optimize_type);
1512  case VM_METHOD_TYPE_ALIAS:
1513  break; /* unreachable */
1514  }
1515  rb_bug("rb_hash_method_definition: unsupported method type (%d)\n", def->type);
1516  }
1517 
1518 st_index_t
1520 {
1521  return rb_hash_method_definition(hash, me->def);
1522 }
1523 
1524 void
1525 rb_alias(VALUE klass, ID alias_name, ID original_name)
1526 {
1527  const VALUE target_klass = klass;
1529  const rb_method_entry_t *orig_me;
1531 
1532  if (NIL_P(klass)) {
1533  rb_raise(rb_eTypeError, "no class to make alias");
1534  }
1535 
1536  rb_frozen_class_p(klass);
1537 
1538  again:
1539  orig_me = search_method(klass, original_name, &defined_class);
1540  if (orig_me && orig_me->def->type == VM_METHOD_TYPE_REFINED) {
1541  orig_me = rb_resolve_refined_method(Qnil, orig_me);
1542  }
1543 
1544  if (UNDEFINED_METHOD_ENTRY_P(orig_me) ||
1545  UNDEFINED_REFINED_METHOD_P(orig_me->def)) {
1546  if ((!RB_TYPE_P(klass, T_MODULE)) ||
1547  (orig_me = search_method(rb_cObject, original_name, &defined_class),
1548  UNDEFINED_METHOD_ENTRY_P(orig_me))) {
1549  rb_print_undef(klass, original_name, METHOD_VISI_UNDEF);
1550  }
1551  }
1552 
1553  if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) {
1554  klass = RCLASS_SUPER(klass);
1555  original_name = orig_me->def->original_id;
1556  visi = METHOD_ENTRY_VISI(orig_me);
1557  goto again;
1558  }
1559 
1560  if (visi == METHOD_VISI_UNDEF) visi = METHOD_ENTRY_VISI(orig_me);
1561 
1562  if (orig_me->defined_class == 0) {
1563  rb_method_entry_make(target_klass, alias_name, target_klass, visi,
1564  VM_METHOD_TYPE_ALIAS, NULL, orig_me->called_id,
1565  (void *)rb_method_entry_clone(orig_me));
1566  method_added(target_klass, alias_name);
1567  }
1568  else {
1569  rb_method_entry_t *alias_me;
1570 
1571  alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner);
1572  RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass);
1573  RB_OBJ_WRITE(alias_me, &alias_me->defined_class, defined_class);
1574  }
1575 }
1576 
1577 /*
1578  * call-seq:
1579  * alias_method(new_name, old_name) -> self
1580  *
1581  * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
1582  * be used to retain access to methods that are overridden.
1583  *
1584  * module Mod
1585  * alias_method :orig_exit, :exit
1586  * def exit(code=0)
1587  * puts "Exiting with code #{code}"
1588  * orig_exit(code)
1589  * end
1590  * end
1591  * include Mod
1592  * exit(99)
1593  *
1594  * <em>produces:</em>
1595  *
1596  * Exiting with code 99
1597  */
1598 
1599 static VALUE
1600 rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
1601 {
1602  ID oldid = rb_check_id(&oldname);
1603  if (!oldid) {
1604  rb_print_undef_str(mod, oldname);
1605  }
1606  rb_alias(mod, rb_to_id(newname), oldid);
1607  return mod;
1608 }
1609 
1610 static void
1611 set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
1612 {
1613  int i;
1614 
1615  rb_check_frozen(self);
1616  if (argc == 0) {
1617  rb_warning("%"PRIsVALUE" with no argument is just ignored",
1619  return;
1620  }
1621 
1622  for (i = 0; i < argc; i++) {
1623  VALUE v = argv[i];
1624  ID id = rb_check_id(&v);
1625  if (!id) {
1626  rb_print_undef_str(self, v);
1627  }
1628  rb_export_method(self, id, visi);
1629  }
1630 }
1631 
1632 static VALUE
1633 set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
1634 {
1635  if (argc == 0) {
1637  }
1638  else {
1639  set_method_visibility(module, argc, argv, visi);
1640  }
1641  return module;
1642 }
1643 
1644 /*
1645  * call-seq:
1646  * public -> self
1647  * public(symbol, ...) -> self
1648  * public(string, ...) -> self
1649  *
1650  * With no arguments, sets the default visibility for subsequently
1651  * defined methods to public. With arguments, sets the named methods to
1652  * have public visibility.
1653  * String arguments are converted to symbols.
1654  */
1655 
1656 static VALUE
1657 rb_mod_public(int argc, VALUE *argv, VALUE module)
1658 {
1659  return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC);
1660 }
1661 
1662 /*
1663  * call-seq:
1664  * protected -> self
1665  * protected(symbol, ...) -> self
1666  * protected(string, ...) -> self
1667  *
1668  * With no arguments, sets the default visibility for subsequently
1669  * defined methods to protected. With arguments, sets the named methods
1670  * to have protected visibility.
1671  * String arguments are converted to symbols.
1672  *
1673  * If a method has protected visibility, it is callable only where
1674  * <code>self</code> of the context is the same as the method.
1675  * (method definition or instance_eval). This behavior is different from
1676  * Java's protected method. Usually <code>private</code> should be used.
1677  *
1678  * Note that a protected method is slow because it can't use inline cache.
1679  *
1680  * To show a private method on RDoc, use <code>:doc:</code> instead of this.
1681  */
1682 
1683 static VALUE
1684 rb_mod_protected(int argc, VALUE *argv, VALUE module)
1685 {
1686  return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED);
1687 }
1688 
1689 /*
1690  * call-seq:
1691  * private -> self
1692  * private(symbol, ...) -> self
1693  * private(string, ...) -> self
1694  *
1695  * With no arguments, sets the default visibility for subsequently
1696  * defined methods to private. With arguments, sets the named methods
1697  * to have private visibility.
1698  * String arguments are converted to symbols.
1699  *
1700  * module Mod
1701  * def a() end
1702  * def b() end
1703  * private
1704  * def c() end
1705  * private :a
1706  * end
1707  * Mod.private_instance_methods #=> [:a, :c]
1708  *
1709  * Note that to show a private method on RDoc, use <code>:doc:</code>.
1710  */
1711 
1712 static VALUE
1713 rb_mod_private(int argc, VALUE *argv, VALUE module)
1714 {
1715  return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE);
1716 }
1717 
1718 /*
1719  * call-seq:
1720  * mod.public_class_method(symbol, ...) -> mod
1721  * mod.public_class_method(string, ...) -> mod
1722  *
1723  * Makes a list of existing class methods public.
1724  *
1725  * String arguments are converted to symbols.
1726  */
1727 
1728 static VALUE
1729 rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
1730 {
1731  set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PUBLIC);
1732  return obj;
1733 }
1734 
1735 /*
1736  * call-seq:
1737  * mod.private_class_method(symbol, ...) -> mod
1738  * mod.private_class_method(string, ...) -> mod
1739  *
1740  * Makes existing class methods private. Often used to hide the default
1741  * constructor <code>new</code>.
1742  *
1743  * String arguments are converted to symbols.
1744  *
1745  * class SimpleSingleton # Not thread safe
1746  * private_class_method :new
1747  * def SimpleSingleton.create(*args, &block)
1748  * @me = new(*args, &block) if ! @me
1749  * @me
1750  * end
1751  * end
1752  */
1753 
1754 static VALUE
1755 rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
1756 {
1757  set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PRIVATE);
1758  return obj;
1759 }
1760 
1761 /*
1762  * call-seq:
1763  * public
1764  * public(symbol, ...)
1765  * public(string, ...)
1766  *
1767  * With no arguments, sets the default visibility for subsequently
1768  * defined methods to public. With arguments, sets the named methods to
1769  * have public visibility.
1770  *
1771  * String arguments are converted to symbols.
1772  */
1773 
1774 static VALUE
1775 top_public(int argc, VALUE *argv)
1776 {
1777  return rb_mod_public(argc, argv, rb_cObject);
1778 }
1779 
1780 /*
1781  * call-seq:
1782  * private
1783  * private(symbol, ...)
1784  * private(string, ...)
1785  *
1786  * With no arguments, sets the default visibility for subsequently
1787  * defined methods to private. With arguments, sets the named methods to
1788  * have private visibility.
1789  *
1790  * String arguments are converted to symbols.
1791  */
1792 static VALUE
1793 top_private(int argc, VALUE *argv)
1794 {
1795  return rb_mod_private(argc, argv, rb_cObject);
1796 }
1797 
1798 /*
1799  * call-seq:
1800  * module_function(symbol, ...) -> self
1801  * module_function(string, ...) -> self
1802  *
1803  * Creates module functions for the named methods. These functions may
1804  * be called with the module as a receiver, and also become available
1805  * as instance methods to classes that mix in the module. Module
1806  * functions are copies of the original, and so may be changed
1807  * independently. The instance-method versions are made private. If
1808  * used with no arguments, subsequently defined methods become module
1809  * functions.
1810  * String arguments are converted to symbols.
1811  *
1812  * module Mod
1813  * def one
1814  * "This is one"
1815  * end
1816  * module_function :one
1817  * end
1818  * class Cls
1819  * include Mod
1820  * def call_one
1821  * one
1822  * end
1823  * end
1824  * Mod.one #=> "This is one"
1825  * c = Cls.new
1826  * c.call_one #=> "This is one"
1827  * module Mod
1828  * def one
1829  * "This is the new one"
1830  * end
1831  * end
1832  * Mod.one #=> "This is one"
1833  * c.call_one #=> "This is the new one"
1834  */
1835 
1836 static VALUE
1837 rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
1838 {
1839  int i;
1840  ID id;
1841  const rb_method_entry_t *me;
1842 
1843  if (!RB_TYPE_P(module, T_MODULE)) {
1844  rb_raise(rb_eTypeError, "module_function must be called for modules");
1845  }
1846 
1847  if (argc == 0) {
1848  rb_scope_module_func_set();
1849  return module;
1850  }
1851 
1852  set_method_visibility(module, argc, argv, METHOD_VISI_PRIVATE);
1853 
1854  for (i = 0; i < argc; i++) {
1855  VALUE m = module;
1856 
1857  id = rb_to_id(argv[i]);
1858  for (;;) {
1859  me = search_method(m, id, 0);
1860  if (me == 0) {
1861  me = search_method(rb_cObject, id, 0);
1862  }
1863  if (UNDEFINED_METHOD_ENTRY_P(me)) {
1864  rb_print_undef(module, id, METHOD_VISI_UNDEF);
1865  }
1866  if (me->def->type != VM_METHOD_TYPE_ZSUPER) {
1867  break; /* normal case: need not to follow 'super' link */
1868  }
1869  m = RCLASS_SUPER(m);
1870  if (!m)
1871  break;
1872  }
1874  }
1875  return module;
1876 }
1877 
1878 int
1880 {
1881  const rb_method_entry_t *me;
1882  if (!klass) return TRUE; /* hidden object cannot be overridden */
1883  me = rb_method_entry(klass, id);
1884  return (me && METHOD_ENTRY_BASIC(me)) ? TRUE : FALSE;
1885 }
1886 
1887 static VALUE
1888 call_method_entry(rb_thread_t *th, VALUE defined_class, VALUE obj, ID id,
1889  const rb_method_entry_t *me, int argc, const VALUE *argv)
1890 {
1891  const rb_callable_method_entry_t *cme =
1892  prepare_callable_method_entry(defined_class, id, me);
1893  VALUE passed_block_handler = vm_passed_block_handler(th);
1894  VALUE result = vm_call0(th, obj, id, argc, argv, cme);
1895  vm_passed_block_handler_set(th, passed_block_handler);
1896  return result;
1897 }
1898 
1899 static VALUE
1900 basic_obj_respond_to_missing(rb_thread_t *th, VALUE klass, VALUE obj,
1901  VALUE mid, VALUE priv)
1902 {
1903  VALUE defined_class, args[2];
1904  const ID rtmid = idRespond_to_missing;
1905  const rb_method_entry_t *const me =
1906  method_entry_get(klass, rtmid, &defined_class);
1907 
1908  if (!me || METHOD_ENTRY_BASIC(me)) return Qundef;
1909  args[0] = mid;
1910  args[1] = priv;
1911  return call_method_entry(th, defined_class, obj, rtmid, me, 2, args);
1912 }
1913 
1914 static inline int
1915 basic_obj_respond_to(rb_thread_t *th, VALUE obj, ID id, int pub)
1916 {
1917  VALUE klass = CLASS_OF(obj);
1918  VALUE ret;
1919 
1920  switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) {
1921  case 2:
1922  return FALSE;
1923  case 0:
1924  ret = basic_obj_respond_to_missing(th, klass, obj, ID2SYM(id),
1925  pub ? Qfalse : Qtrue);
1926  return RTEST(ret) && ret != Qundef;
1927  default:
1928  return TRUE;
1929  }
1930 }
1931 
1932 static int
1933 vm_respond_to(rb_thread_t *th, VALUE klass, VALUE obj, ID id, int priv)
1934 {
1936  const ID resid = idRespond_to;
1937  const rb_method_entry_t *const me =
1938  method_entry_get(klass, resid, &defined_class);
1939 
1940  if (!me) return -1;
1941  if (METHOD_ENTRY_BASIC(me)) {
1942  return -1;
1943  }
1944  else {
1945  int argc = 1;
1946  VALUE args[2];
1947  VALUE result;
1948 
1949  args[0] = ID2SYM(id);
1950  args[1] = Qtrue;
1951  if (priv) {
1952  argc = rb_method_entry_arity(me);
1953  if (argc > 2) {
1955  "respond_to? must accept 1 or 2 arguments (requires %d)",
1956  argc);
1957  }
1958  if (argc != 1) {
1959  argc = 2;
1960  }
1961  else if (!NIL_P(ruby_verbose)) {
1962  VALUE location = rb_method_entry_location(me);
1963  rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") uses"
1964  " the deprecated method signature, which takes one parameter",
1965  (FL_TEST(klass, FL_SINGLETON) ? obj : klass),
1966  (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'),
1967  QUOTE_ID(id));
1968  if (!NIL_P(location)) {
1969  VALUE path = RARRAY_AREF(location, 0);
1970  VALUE line = RARRAY_AREF(location, 1);
1971  if (!NIL_P(path)) {
1972  rb_compile_warn(RSTRING_PTR(path), NUM2INT(line),
1973  "respond_to? is defined here");
1974  }
1975  }
1976  }
1977  }
1978  result = call_method_entry(th, defined_class, obj, resid, me, argc, args);
1979  return RTEST(result);
1980  }
1981 }
1982 
1983 int
1984 rb_obj_respond_to(VALUE obj, ID id, int priv)
1985 {
1986  rb_thread_t *th = GET_THREAD();
1987  VALUE klass = CLASS_OF(obj);
1988  int ret = vm_respond_to(th, klass, obj, id, priv);
1989  if (ret == -1) ret = basic_obj_respond_to(th, obj, id, !priv);
1990  return ret;
1991 }
1992 
1993 int
1995 {
1996  return rb_obj_respond_to(obj, id, FALSE);
1997 }
1998 
1999 
2000 /*
2001  * call-seq:
2002  * obj.respond_to?(symbol, include_all=false) -> true or false
2003  * obj.respond_to?(string, include_all=false) -> true or false
2004  *
2005  * Returns +true+ if _obj_ responds to the given method. Private and
2006  * protected methods are included in the search only if the optional
2007  * second parameter evaluates to +true+.
2008  *
2009  * If the method is not implemented,
2010  * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
2011  * false is returned.
2012  *
2013  * If the method is not defined, <code>respond_to_missing?</code>
2014  * method is called and the result is returned.
2015  *
2016  * When the method name parameter is given as a string, the string is
2017  * converted to a symbol.
2018  */
2019 
2020 static VALUE
2021 obj_respond_to(int argc, VALUE *argv, VALUE obj)
2022 {
2023  VALUE mid, priv;
2024  ID id;
2025  rb_thread_t *th = GET_THREAD();
2026 
2027  rb_scan_args(argc, argv, "11", &mid, &priv);
2028  if (!(id = rb_check_id(&mid))) {
2029  VALUE ret = basic_obj_respond_to_missing(th, CLASS_OF(obj), obj,
2030  rb_to_symbol(mid), priv);
2031  if (ret == Qundef) ret = Qfalse;
2032  return ret;
2033  }
2034  if (basic_obj_respond_to(th, obj, id, !RTEST(priv)))
2035  return Qtrue;
2036  return Qfalse;
2037 }
2038 
2039 /*
2040  * call-seq:
2041  * obj.respond_to_missing?(symbol, include_all) -> true or false
2042  * obj.respond_to_missing?(string, include_all) -> true or false
2043  *
2044  * DO NOT USE THIS DIRECTLY.
2045  *
2046  * Hook method to return whether the _obj_ can respond to _id_ method
2047  * or not.
2048  *
2049  * When the method name parameter is given as a string, the string is
2050  * converted to a symbol.
2051  *
2052  * See #respond_to?, and the example of BasicObject.
2053  */
2054 static VALUE
2055 obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
2056 {
2057  return Qfalse;
2058 }
2059 
2060 void
2062 {
2063 #if OPT_GLOBAL_METHOD_CACHE
2064  char *ptr = getenv("RUBY_GLOBAL_METHOD_CACHE_SIZE");
2065  int val;
2066 
2067  if (ptr != NULL && (val = atoi(ptr)) > 0) {
2068  if ((val & (val - 1)) == 0) { /* ensure val is a power of 2 */
2069  global_method_cache.size = val;
2070  global_method_cache.mask = val - 1;
2071  }
2072  else {
2073  fprintf(stderr, "RUBY_GLOBAL_METHOD_CACHE_SIZE was set to %d but ignored because the value is not a power of 2.\n", val);
2074  }
2075  }
2076 
2077  global_method_cache.entries = (struct cache_entry *)calloc(global_method_cache.size, sizeof(struct cache_entry));
2078  if (global_method_cache.entries == NULL) {
2079  fprintf(stderr, "[FATAL] failed to allocate memory\n");
2080  exit(EXIT_FAILURE);
2081  }
2082 #endif
2083 }
2084 
2085 void
2087 {
2088 #undef rb_intern
2089 #define rb_intern(str) rb_intern_const(str)
2090 
2091  rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
2092  rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
2093 
2094  rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
2095  rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
2096  rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
2097  rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
2098  rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
2099  rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
2100  rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
2101 
2102  rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
2103  rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
2104  rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
2105  rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
2106  rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
2107  rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
2108 
2110  "public", top_public, -1);
2112  "private", top_private, -1);
2113 
2114  {
2115 #define REPLICATE_METHOD(klass, id) do { \
2116  const rb_method_entry_t *me = rb_method_entry((klass), (id)); \
2117  rb_method_entry_set((klass), (id), me, METHOD_ENTRY_VISI(me)); \
2118  } while (0)
2119 
2120  REPLICATE_METHOD(rb_eException, idMethodMissing);
2123  }
2124 }
#define UNDEFINED_REFINED_METHOD_P(def)
Definition: method.h:176
int rb_method_boundp(VALUE klass, ID id, int ex)
Definition: vm_method.c:1068
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
Definition: vm.c:498
wrapper for method_missing(id)
Definition: method.h:112
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
Definition: vm_method.c:130
#define UNDEFINED_METHOD_ENTRY_P(me)
Definition: method.h:175
method_optimized_type
Definition: method.h:148
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:915
const VALUE * ep
Definition: vm_core.h:667
const VALUE owner
Definition: method.h:145
void rb_warn(const char *fmt,...)
Definition: error.c:246
void rb_bug(const char *fmt,...)
Definition: error.c:521
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
Definition: id_table.c:226
#define FALSE
Definition: nkf.h:174
rb_method_entry_t * me
Definition: vm_method.c:44
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
Definition: eval_error.c:216
VALUE rb_ary_freeze(VALUE ary)
Definition: array.c:409
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
Definition: vm_backtrace.c:38
#define NUM2INT(x)
Definition: ruby.h:684
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1438
void rb_remove_method(VALUE klass, const char *name)
Definition: vm_method.c:999
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
Definition: vm_method.c:1519
rb_control_frame_t * cfp
Definition: vm_core.h:744
rb_subclass_entry_t * next
Definition: internal.h:741
#define d1
#define QUOTE_ID(id)
Definition: internal.h:1636
const rb_iseq_t * rb_proc_get_iseq(VALUE proc, int *is_proc)
Definition: proc.c:1086
#define CLASS_OF(v)
Definition: ruby.h:453
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define T_MODULE
Definition: ruby.h:494
#define RCLASS_EXT(c)
Definition: classext.h:15
rb_cref_t *const cref
class reference, should be marked
Definition: method.h:125
#define Qtrue
Definition: ruby.h:437
struct rb_method_definition_struct rb_method_definition_t
Definition: method.h:173
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
Definition: vm_method.c:456
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:2020
#define rb_id2str(id)
Definition: vm_backtrace.c:29
const int id
Definition: nkf.c:209
rb_alloc_func_t rb_get_alloc_func(VALUE klass)
Definition: vm_method.c:681
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1527
rb_serial_t method_state
Definition: vm_method.c:41
Ruby method.
Definition: method.h:102
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
Definition: vm_method.c:625
#define rb_intern(str)
#define UNREACHABLE
Definition: ruby.h:46
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
Definition: vm_method.c:396
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
Definition: zonetab.h:883
const VALUE owner
Definition: method.h:56
VALUE defined_class
Definition: vm_method.c:45
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
Definition: vm_method.c:833
#define ruby_running
Definition: vm_method.c:59
struct rb_iseq_constant_body * body
Definition: vm_core.h:423
void rb_print_undef_str(VALUE klass, VALUE name)
Definition: eval_error.c:231
const rb_callable_method_entry_t * rb_callable_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:886
#define Check_Type(v, t)
Definition: ruby.h:562
#define METHOD_ENTRY_COMPLEMENTED(me)
Definition: method.h:69
ID called_id
Definition: method.h:55
VALUE rb_refinement_module_get_refined_class(VALUE module)
Definition: eval.c:1388
Definition: vm_method.c:40
void rb_method_name_error(VALUE klass, VALUE str)
Definition: proc.c:1642
st_data_t st_index_t
Definition: st.h:50
#define GET_GLOBAL_METHOD_STATE()
#define RUBY_DTRACE_HOOK(name, arg)
Definition: internal.h:1934
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:9453
#define FL_TEST(x, f)
Definition: ruby.h:1282
int rb_method_basic_definition_p(VALUE klass, ID id)
Definition: vm_method.c:1879
void rb_id_table_clear(struct rb_id_table *tbl)
Definition: id_table.c:109
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj)
Definition: vm_method.c:116
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1168
refinement
Definition: method.h:113
#define UNALIGNED_MEMBER_PTR(ptr, mem)
Definition: eval_intern.h:172
#define GET_THREAD()
Definition: vm_core.h:1583
VALUE rb_eArgError
Definition: error.c:802
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
#define FL_SINGLETON
Definition: ruby.h:1208
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
Definition: class.c:1689
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
Definition: vm_method.c:1137
int rb_obj_respond_to(VALUE obj, ID id, int priv)
Definition: vm_method.c:1984
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
const rb_scope_visibility_t scope_visi
Definition: method.h:46
const rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:866
const rb_iseq_t * iseq
Definition: vm_core.h:665
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
Definition: vm_method.c:940
#define rb_intern_str(string)
Definition: generator.h:16
VALUE rb_equal(VALUE, VALUE)
call-seq: obj === other -> true or false
Definition: object.c:126
#define METHOD_ENTRY_COMPLEMENTED_SET(me)
Definition: method.h:70
Definition: internal.h:739
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
int rb_respond_to(VALUE obj, ID id)
Definition: vm_method.c:1994
RUBY_EXTERN VALUE rb_cBasicObject
Definition: ruby.h:1892
const rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
Definition: vm_method.c:946
rb_method_entry_t * rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def)
Definition: vm_method.c:387
RUBY_EXTERN VALUE rb_mKernel
Definition: ruby.h:1881
void rb_remove_method_id(VALUE klass, ID mid)
Definition: vm_method.c:993
#define RCLASS_ORIGIN(c)
Definition: internal.h:794
#define NIL_P(v)
Definition: ruby.h:451
void rb_frozen_class_p(VALUE klass)
Asserts that klass is not a frozen class.
Definition: eval.c:404
#define calloc
Definition: ripper.c:360
void rb_undef_alloc_func(VALUE klass)
Definition: vm_method.c:675
rb_method_visibility_t
Definition: method.h:26
struct rb_method_definition_struct *const def
Definition: method.h:54
struct rb_id_table * rb_id_table_create(size_t capa)
Definition: id_table.c:95
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:200
#define BOUND_RESPONDS
Definition: vm_method.c:1065
#define added
Definition: vm_method.c:32
int rb_method_entry_arity(const rb_method_entry_t *me)
Definition: proc.c:2334
void rb_notimplement(void)
Definition: error.c:2330
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define undefined
Definition: vm_method.c:36
const rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
Definition: vm_method.c:793
const VALUE defined_class
Definition: method.h:61
Definition: method.h:51
const rb_callable_method_entry_t * rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
Definition: vm_method.c:405
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1916
Definition: method.h:59
void rb_clear_constant_cache(void)
Definition: vm_method.c:84
#define EXIT_FAILURE
Definition: eval_intern.h:33
#define OPT_GLOBAL_METHOD_CACHE
Definition: vm_opts.h:41
const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:880
VALUE rb_method_entry_location(const rb_method_entry_t *me)
Definition: proc.c:2494
rb_method_type_t
Definition: method.h:101
rb_serial_t class_serial
Definition: vm_method.c:42
void rb_alias(VALUE klass, ID alias_name, ID original_name)
Definition: vm_method.c:1525
#define removed
Definition: vm_method.c:34
attr_writer or attr_accessor
Definition: method.h:104
#define ZALLOC(type)
Definition: ruby.h:1590
VALUE rb_eException
Definition: error.c:794
#define RCLASS_M_TBL(c)
Definition: internal.h:791
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
Definition: id_table.c:256
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
Definition: method.h:130
#define TRUE
Definition: nkf.h:175
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
Definition: class.c:113
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1452
unsigned long rb_serial_t
Definition: internal.h:751
VALUE rb_to_symbol(VALUE name)
Definition: string.c:10506
#define VM_ASSERT(expr)
Definition: vm_core.h:53
VALUE klass
Definition: internal.h:740
int rb_id_table_delete(struct rb_id_table *tbl, ID id)
Definition: id_table.c:262
VALUE(* func)(ANYARGS)
Definition: method.h:129
#define UNDEF_ALLOC_FUNC
Definition: vm_method.c:665
void rb_compile_warning(const char *file, int line, const char *fmt,...)
Definition: error.c:215
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
#define INC_GLOBAL_METHOD_STATE()
#define INC_GLOBAL_CONSTANT_STATE()
#define METHOD_ENTRY_VISI(me)
Definition: method.h:67
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_vm_top_self(void)
Definition: vm.c:3166
const VALUE defined_class
Definition: method.h:53
const char * rb_class2name(VALUE)
Definition: variable.c:450
VALUE rb_eTypeError
Definition: error.c:801
rb_method_visibility_t method_visi
Definition: method.h:36
#define FIX2INT(x)
Definition: ruby.h:686
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
Definition: vm_method.c:637
#define rb_ary_new3
Definition: intern.h:91
const char * rb_id2name(ID)
Definition: symbol.c:751
CREF (Class REFerence)
Definition: method.h:41
#define CALL_METHOD_HOOK(klass, hook, mid)
Definition: vm_method.c:605
Kernel::send, Proc::call, etc.
Definition: method.h:111
#define getenv(name)
Definition: win32.c:71
#define RSTRING_PTR(str)
Definition: ruby.h:975
#define RB_OBJ_WRITE(a, slot, b)
Definition: eval_intern.h:175
#define METHOD_DEBUG
Definition: vm_method.c:7
int size
Definition: encoding.c:57
#define INT2FIX(i)
Definition: ruby.h:232
#define RCLASS_SUPER(c)
Definition: classext.h:16
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
ID rb_frame_callee(void)
The name of the current method.
Definition: eval.c:1120
#define METHOD_ENTRY_BASIC(me)
Definition: method.h:68
const rb_method_entry_t * rb_method_entry_at(VALUE klass, ID id)
Definition: vm_method.c:709
#define object_id
Definition: vm_method.c:31
void Init_Method(void)
Definition: vm_method.c:2061
#define ANYARGS
Definition: defines.h:173
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
Definition: vm_method.c:1420
#define RCLASS_CALLABLE_M_TBL(c)
Definition: internal.h:792
#define RTEST(v)
Definition: ruby.h:450
void rb_warning(const char *fmt,...)
Definition: error.c:267
st_index_t rb_hash_uint(st_index_t, st_index_t)
void rb_define_alloc_func(VALUE klass, VALUE(*func)(VALUE))
Definition: vm_method.c:668
#define GLOBAL_METHOD_CACHE(c, m)
Definition: vm_method.c:25
const char * rb_obj_info(VALUE obj)
Definition: gc.c:9442
VALUE rb_iseq_path(const rb_iseq_t *iseq)
Definition: iseq.c:692
const rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr)
Definition: vm_method.c:872
void Init_eval_method(void)
Definition: vm_method.c:2086
#define T_CLASS
Definition: ruby.h:492
#define RB_DEBUG_COUNTER_INC(type)
rb_execution_context_t ec
Definition: vm_core.h:790
const char * name
Definition: nkf.c:208
#define ID2SYM(x)
Definition: ruby.h:383
#define REPLICATE_METHOD(klass, id)
void rb_undef(VALUE klass, ID id)
Definition: vm_method.c:1172
rb_serial_t rb_next_class_serial(void)
Definition: vm.c:309
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi)
Definition: vm_method.c:660
C method.
Definition: method.h:103
#define rb_check_frozen(obj)
Definition: intern.h:271
ID rb_id_attrset(ID)
Definition: symbol.c:100
const rb_iseq_t *const iseqptr
iseq pointer, should be separated from iseqval
Definition: method.h:124
void void xfree(void *)
st_index_t rb_hash_proc(st_index_t hash, VALUE proc)
Definition: proc.c:1188
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
Definition: vm_method.c:418
#define mod(x, y)
Definition: date_strftime.c:28
const struct rb_method_entry_struct *const orig_me
Definition: method.h:144
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:370
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
#define T_ICLASS
Definition: ruby.h:493
void rb_free_method_entry(const rb_method_entry_t *me)
Definition: vm_method.c:168
#define RCLASS_SERIAL(c)
Definition: internal.h:796
void rb_scope_visibility_set(rb_method_visibility_t visi)
Definition: vm_method.c:1125
attr_reader or attr_accessor
Definition: method.h:105
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
#define ruby_verbose
Definition: ruby.h:1813
rb_cref_t * rb_vm_cref(void)
Definition: vm.c:1321
ID rb_to_id(VALUE)
Definition: string.c:10496
void rb_clear_method_cache_by_class(VALUE klass)
Definition: vm_method.c:90
unsigned int module_func
Definition: method.h:37
char ** argv
Definition: ruby.c:188
rb_iseq_location_t location
Definition: vm_core.h:386
ID mid
Definition: vm_method.c:43