Ruby 2.1.5p273(2014-11-13revision48405)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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