Ruby 2.0.0p353(2013-11-22revision43784)

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