00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00026 #include "ruby/ruby.h"
00027 #include "ruby/st.h"
00028 #include "method.h"
00029 #include "constant.h"
00030 #include "vm_core.h"
00031 #include "internal.h"
00032 #include <ctype.h>
00033
00034 extern st_table *rb_class_tbl;
00035 static ID id_attached;
00036
00049 static VALUE
00050 class_alloc(VALUE flags, VALUE klass)
00051 {
00052 rb_classext_t *ext = ALLOC(rb_classext_t);
00053 NEWOBJ(obj, struct RClass);
00054 OBJSETUP(obj, klass, flags);
00055 obj->ptr = ext;
00056 RCLASS_IV_TBL(obj) = 0;
00057 RCLASS_CONST_TBL(obj) = 0;
00058 RCLASS_M_TBL(obj) = 0;
00059 RCLASS_SUPER(obj) = 0;
00060 RCLASS_IV_INDEX_TBL(obj) = 0;
00061 return (VALUE)obj;
00062 }
00063
00064
00074 VALUE
00075 rb_class_boot(VALUE super)
00076 {
00077 VALUE klass = class_alloc(T_CLASS, rb_cClass);
00078
00079 RCLASS_SUPER(klass) = super;
00080 RCLASS_M_TBL(klass) = st_init_numtable();
00081
00082 OBJ_INFECT(klass, super);
00083 return (VALUE)klass;
00084 }
00085
00086
00093 void
00094 rb_check_inheritable(VALUE super)
00095 {
00096 if (TYPE(super) != T_CLASS) {
00097 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
00098 rb_obj_classname(super));
00099 }
00100 if (RBASIC(super)->flags & FL_SINGLETON) {
00101 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
00102 }
00103 if (super == rb_cClass) {
00104 rb_raise(rb_eTypeError, "can't make subclass of Class");
00105 }
00106 }
00107
00108
00115 VALUE
00116 rb_class_new(VALUE super)
00117 {
00118 Check_Type(super, T_CLASS);
00119 rb_check_inheritable(super);
00120 return rb_class_boot(super);
00121 }
00122
00123 struct clone_method_data {
00124 st_table *tbl;
00125 VALUE klass;
00126 };
00127
00128 VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);
00129
00130 static int
00131 clone_method(ID mid, const rb_method_entry_t *me, struct clone_method_data *data)
00132 {
00133 VALUE newiseqval;
00134 if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
00135 rb_iseq_t *iseq;
00136 newiseqval = rb_iseq_clone(me->def->body.iseq->self, data->klass);
00137 GetISeqPtr(newiseqval, iseq);
00138 rb_add_method(data->klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
00139 RB_GC_GUARD(newiseqval);
00140 }
00141 else {
00142 rb_method_entry_set(data->klass, mid, me, me->flag);
00143 }
00144 return ST_CONTINUE;
00145 }
00146
00147 static int
00148 clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
00149 {
00150 rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
00151 *nce = *ce;
00152 st_insert(tbl, key, (st_data_t)nce);
00153 return ST_CONTINUE;
00154 }
00155
00156 static int
00157 clone_const_i(st_data_t key, st_data_t value, st_data_t data)
00158 {
00159 return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
00160 }
00161
00162
00163 VALUE
00164 rb_mod_init_copy(VALUE clone, VALUE orig)
00165 {
00166 rb_obj_init_copy(clone, orig);
00167 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00168 RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00169 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00170 }
00171 RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
00172 if (RCLASS_IV_TBL(orig)) {
00173 st_data_t id;
00174
00175 if (RCLASS_IV_TBL(clone)) {
00176 st_free_table(RCLASS_IV_TBL(clone));
00177 }
00178 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
00179 CONST_ID(id, "__classpath__");
00180 st_delete(RCLASS_IV_TBL(clone), &id, 0);
00181 CONST_ID(id, "__classid__");
00182 st_delete(RCLASS_IV_TBL(clone), &id, 0);
00183 }
00184 if (RCLASS_CONST_TBL(orig)) {
00185 if (RCLASS_CONST_TBL(clone)) {
00186 rb_free_const_table(RCLASS_CONST_TBL(clone));
00187 }
00188 RCLASS_CONST_TBL(clone) = st_init_numtable();
00189 st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00190 }
00191 if (RCLASS_M_TBL(orig)) {
00192 struct clone_method_data data;
00193
00194 if (RCLASS_M_TBL(clone)) {
00195 rb_free_m_table(RCLASS_M_TBL(clone));
00196 }
00197 data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
00198 data.klass = clone;
00199 st_foreach(RCLASS_M_TBL(orig), clone_method,
00200 (st_data_t)&data);
00201 }
00202
00203 return clone;
00204 }
00205
00206
00207 VALUE
00208 rb_class_init_copy(VALUE clone, VALUE orig)
00209 {
00210 if (orig == rb_cBasicObject) {
00211 rb_raise(rb_eTypeError, "can't copy the root class");
00212 }
00213 if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
00214 rb_raise(rb_eTypeError, "already initialized class");
00215 }
00216 if (FL_TEST(orig, FL_SINGLETON)) {
00217 rb_raise(rb_eTypeError, "can't copy singleton class");
00218 }
00219 return rb_mod_init_copy(clone, orig);
00220 }
00221
00222 VALUE
00223 rb_singleton_class_clone(VALUE obj)
00224 {
00225 VALUE klass = RBASIC(obj)->klass;
00226
00227 if (!FL_TEST(klass, FL_SINGLETON))
00228 return klass;
00229 else {
00230 struct clone_method_data data;
00231
00232 VALUE clone = class_alloc((RBASIC(klass)->flags & ~(FL_MARK)), 0);
00233
00234 if (BUILTIN_TYPE(obj) == T_CLASS) {
00235 RBASIC(clone)->klass = (VALUE)clone;
00236 }
00237 else {
00238 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00239 }
00240
00241 RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
00242 if (RCLASS_IV_TBL(klass)) {
00243 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
00244 }
00245 if (RCLASS_CONST_TBL(klass)) {
00246 RCLASS_CONST_TBL(clone) = st_init_numtable();
00247 st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00248 }
00249 RCLASS_M_TBL(clone) = st_init_numtable();
00250 data.tbl = RCLASS_M_TBL(clone);
00251 data.klass = (VALUE)clone;
00252 st_foreach(RCLASS_M_TBL(klass), clone_method,
00253 (st_data_t)&data);
00254 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00255 FL_SET(clone, FL_SINGLETON);
00256 return (VALUE)clone;
00257 }
00258 }
00259
00264 void
00265 rb_singleton_class_attached(VALUE klass, VALUE obj)
00266 {
00267 if (FL_TEST(klass, FL_SINGLETON)) {
00268 if (!RCLASS_IV_TBL(klass)) {
00269 RCLASS_IV_TBL(klass) = st_init_numtable();
00270 }
00271 st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
00272 }
00273 }
00274
00275
00276
00277 #define METACLASS_OF(k) RBASIC(k)->klass
00278
00284 #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
00285
00286
00294 #define ENSURE_EIGENCLASS(klass) \
00295 (rb_ivar_get(METACLASS_OF(klass), id_attached) == (klass) ? METACLASS_OF(klass) : make_metaclass(klass))
00296
00297
00307 static inline VALUE
00308 make_metaclass(VALUE klass)
00309 {
00310 VALUE super;
00311 VALUE metaclass = rb_class_boot(Qundef);
00312
00313 FL_SET(metaclass, FL_SINGLETON);
00314 rb_singleton_class_attached(metaclass, klass);
00315
00316 if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
00317 METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass;
00318 }
00319 else {
00320 VALUE tmp = METACLASS_OF(klass);
00321 METACLASS_OF(klass) = metaclass;
00322 METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp);
00323 }
00324
00325 super = RCLASS_SUPER(klass);
00326 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
00327 RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass;
00328
00329 OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
00330
00331 return metaclass;
00332 }
00333
00340 static inline VALUE
00341 make_singleton_class(VALUE obj)
00342 {
00343 VALUE orig_class = RBASIC(obj)->klass;
00344 VALUE klass = rb_class_boot(orig_class);
00345
00346 FL_SET(klass, FL_SINGLETON);
00347 RBASIC(obj)->klass = klass;
00348 rb_singleton_class_attached(klass, obj);
00349
00350 METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class));
00351 return klass;
00352 }
00353
00354
00355 static VALUE
00356 boot_defclass(const char *name, VALUE super)
00357 {
00358 extern st_table *rb_class_tbl;
00359 VALUE obj = rb_class_boot(super);
00360 ID id = rb_intern(name);
00361
00362 rb_name_class(obj, id);
00363 st_add_direct(rb_class_tbl, id, obj);
00364 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
00365 return obj;
00366 }
00367
00368 void
00369 Init_class_hierarchy(void)
00370 {
00371 id_attached = rb_intern("__attached__");
00372
00373 rb_cBasicObject = boot_defclass("BasicObject", 0);
00374 rb_cObject = boot_defclass("Object", rb_cBasicObject);
00375 rb_cModule = boot_defclass("Module", rb_cObject);
00376 rb_cClass = boot_defclass("Class", rb_cModule);
00377
00378 rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
00379 RBASIC(rb_cClass)->klass
00380 = RBASIC(rb_cModule)->klass
00381 = RBASIC(rb_cObject)->klass
00382 = RBASIC(rb_cBasicObject)->klass
00383 = rb_cClass;
00384 }
00385
00386
00397 VALUE
00398 rb_make_metaclass(VALUE obj, VALUE unused)
00399 {
00400 if (BUILTIN_TYPE(obj) == T_CLASS) {
00401 return make_metaclass(obj);
00402 }
00403 else {
00404 return make_singleton_class(obj);
00405 }
00406 }
00407
00408
00419 VALUE
00420 rb_define_class_id(ID id, VALUE super)
00421 {
00422 VALUE klass;
00423
00424 if (!super) super = rb_cObject;
00425 klass = rb_class_new(super);
00426 rb_make_metaclass(klass, RBASIC(super)->klass);
00427
00428 return klass;
00429 }
00430
00431
00440 VALUE
00441 rb_class_inherited(VALUE super, VALUE klass)
00442 {
00443 ID inherited;
00444 if (!super) super = rb_cObject;
00445 CONST_ID(inherited, "inherited");
00446 return rb_funcall(super, inherited, 1, klass);
00447 }
00448
00449
00450
00466 VALUE
00467 rb_define_class(const char *name, VALUE super)
00468 {
00469 VALUE klass;
00470 ID id;
00471
00472 id = rb_intern(name);
00473 if (rb_const_defined(rb_cObject, id)) {
00474 klass = rb_const_get(rb_cObject, id);
00475 if (TYPE(klass) != T_CLASS) {
00476 rb_raise(rb_eTypeError, "%s is not a class", name);
00477 }
00478 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00479 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
00480 }
00481 return klass;
00482 }
00483 if (!super) {
00484 rb_warn("no super class for `%s', Object assumed", name);
00485 }
00486 klass = rb_define_class_id(id, super);
00487 st_add_direct(rb_class_tbl, id, klass);
00488 rb_name_class(klass, id);
00489 rb_const_set(rb_cObject, id, klass);
00490 rb_class_inherited(super, klass);
00491
00492 return klass;
00493 }
00494
00495
00512 VALUE
00513 rb_define_class_under(VALUE outer, const char *name, VALUE super)
00514 {
00515 return rb_define_class_id_under(outer, rb_intern(name), super);
00516 }
00517
00518
00535 VALUE
00536 rb_define_class_id_under(VALUE outer, ID id, VALUE super)
00537 {
00538 VALUE klass;
00539
00540 if (rb_const_defined_at(outer, id)) {
00541 klass = rb_const_get_at(outer, id);
00542 if (TYPE(klass) != T_CLASS) {
00543 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
00544 }
00545 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00546 rb_name_error(id, "%s is already defined", rb_id2name(id));
00547 }
00548 return klass;
00549 }
00550 if (!super) {
00551 rb_warn("no super class for `%s::%s', Object assumed",
00552 rb_class2name(outer), rb_id2name(id));
00553 }
00554 klass = rb_define_class_id(id, super);
00555 rb_set_class_path_string(klass, outer, rb_id2str(id));
00556 rb_const_set(outer, id, klass);
00557 rb_class_inherited(super, klass);
00558 rb_gc_register_mark_object(klass);
00559
00560 return klass;
00561 }
00562
00563 VALUE
00564 rb_module_new(void)
00565 {
00566 VALUE mdl = class_alloc(T_MODULE, rb_cModule);
00567
00568 RCLASS_M_TBL(mdl) = st_init_numtable();
00569
00570 return (VALUE)mdl;
00571 }
00572
00573 VALUE
00574 rb_define_module_id(ID id)
00575 {
00576 VALUE mdl;
00577
00578 mdl = rb_module_new();
00579 rb_name_class(mdl, id);
00580
00581 return mdl;
00582 }
00583
00584 VALUE
00585 rb_define_module(const char *name)
00586 {
00587 VALUE module;
00588 ID id;
00589
00590 id = rb_intern(name);
00591 if (rb_const_defined(rb_cObject, id)) {
00592 module = rb_const_get(rb_cObject, id);
00593 if (TYPE(module) == T_MODULE)
00594 return module;
00595 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00596 }
00597 module = rb_define_module_id(id);
00598 st_add_direct(rb_class_tbl, id, module);
00599 rb_const_set(rb_cObject, id, module);
00600
00601 return module;
00602 }
00603
00604 VALUE
00605 rb_define_module_under(VALUE outer, const char *name)
00606 {
00607 return rb_define_module_id_under(outer, rb_intern(name));
00608 }
00609
00610 VALUE
00611 rb_define_module_id_under(VALUE outer, ID id)
00612 {
00613 VALUE module;
00614
00615 if (rb_const_defined_at(outer, id)) {
00616 module = rb_const_get_at(outer, id);
00617 if (TYPE(module) == T_MODULE)
00618 return module;
00619 rb_raise(rb_eTypeError, "%s::%s is not a module",
00620 rb_class2name(outer), rb_obj_classname(module));
00621 }
00622 module = rb_define_module_id(id);
00623 rb_const_set(outer, id, module);
00624 rb_set_class_path_string(module, outer, rb_id2str(id));
00625 rb_gc_register_mark_object(module);
00626
00627 return module;
00628 }
00629
00630 static VALUE
00631 include_class_new(VALUE module, VALUE super)
00632 {
00633 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
00634
00635 if (BUILTIN_TYPE(module) == T_ICLASS) {
00636 module = RBASIC(module)->klass;
00637 }
00638 if (!RCLASS_IV_TBL(module)) {
00639 RCLASS_IV_TBL(module) = st_init_numtable();
00640 }
00641 if (!RCLASS_CONST_TBL(module)) {
00642 RCLASS_CONST_TBL(module) = st_init_numtable();
00643 }
00644 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
00645 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
00646 RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
00647 RCLASS_SUPER(klass) = super;
00648 if (TYPE(module) == T_ICLASS) {
00649 RBASIC(klass)->klass = RBASIC(module)->klass;
00650 }
00651 else {
00652 RBASIC(klass)->klass = module;
00653 }
00654 OBJ_INFECT(klass, module);
00655 OBJ_INFECT(klass, super);
00656
00657 return (VALUE)klass;
00658 }
00659
00660 void
00661 rb_include_module(VALUE klass, VALUE module)
00662 {
00663 VALUE p, c;
00664 int changed = 0;
00665
00666 rb_frozen_class_p(klass);
00667 if (!OBJ_UNTRUSTED(klass)) {
00668 rb_secure(4);
00669 }
00670
00671 if (TYPE(module) != T_MODULE) {
00672 Check_Type(module, T_MODULE);
00673 }
00674
00675 OBJ_INFECT(klass, module);
00676 c = klass;
00677 while (module) {
00678 int superclass_seen = FALSE;
00679
00680 if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
00681 rb_raise(rb_eArgError, "cyclic include detected");
00682
00683 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
00684 switch (BUILTIN_TYPE(p)) {
00685 case T_ICLASS:
00686 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
00687 if (!superclass_seen) {
00688 c = p;
00689 }
00690 goto skip;
00691 }
00692 break;
00693 case T_CLASS:
00694 superclass_seen = TRUE;
00695 break;
00696 }
00697 }
00698 c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
00699 if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
00700 changed = 1;
00701 skip:
00702 module = RCLASS_SUPER(module);
00703 }
00704 if (changed) rb_clear_cache();
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 VALUE
00725 rb_mod_included_modules(VALUE mod)
00726 {
00727 VALUE ary = rb_ary_new();
00728 VALUE p;
00729
00730 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00731 if (BUILTIN_TYPE(p) == T_ICLASS) {
00732 rb_ary_push(ary, RBASIC(p)->klass);
00733 }
00734 }
00735 return ary;
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 VALUE
00758 rb_mod_include_p(VALUE mod, VALUE mod2)
00759 {
00760 VALUE p;
00761
00762 Check_Type(mod2, T_MODULE);
00763 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00764 if (BUILTIN_TYPE(p) == T_ICLASS) {
00765 if (RBASIC(p)->klass == mod2) return Qtrue;
00766 }
00767 }
00768 return Qfalse;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 VALUE
00788 rb_mod_ancestors(VALUE mod)
00789 {
00790 VALUE p, ary = rb_ary_new();
00791
00792 for (p = mod; p; p = RCLASS_SUPER(p)) {
00793 if (FL_TEST(p, FL_SINGLETON))
00794 continue;
00795 if (BUILTIN_TYPE(p) == T_ICLASS) {
00796 rb_ary_push(ary, RBASIC(p)->klass);
00797 }
00798 else {
00799 rb_ary_push(ary, p);
00800 }
00801 }
00802 return ary;
00803 }
00804
00805 #define VISI(x) ((x)&NOEX_MASK)
00806 #define VISI_CHECK(x,f) (VISI(x) == (f))
00807
00808 static int
00809 ins_methods_push(ID name, long type, VALUE ary, long visi)
00810 {
00811 if (type == -1) return ST_CONTINUE;
00812
00813 switch (visi) {
00814 case NOEX_PRIVATE:
00815 case NOEX_PROTECTED:
00816 case NOEX_PUBLIC:
00817 visi = (type == visi);
00818 break;
00819 default:
00820 visi = (type != NOEX_PRIVATE);
00821 break;
00822 }
00823 if (visi) {
00824 rb_ary_push(ary, ID2SYM(name));
00825 }
00826 return ST_CONTINUE;
00827 }
00828
00829 static int
00830 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
00831 {
00832 return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1);
00833 }
00834
00835 static int
00836 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
00837 {
00838 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED);
00839 }
00840
00841 static int
00842 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
00843 {
00844 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE);
00845 }
00846
00847 static int
00848 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
00849 {
00850 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
00851 }
00852
00853 static int
00854 method_entry_i(st_data_t key, st_data_t value, st_data_t data)
00855 {
00856 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
00857 st_table *list = (st_table *)data;
00858 long type;
00859
00860 if ((ID)key == ID_ALLOCATOR) {
00861 return ST_CONTINUE;
00862 }
00863
00864 if (!st_lookup(list, key, 0)) {
00865 if (UNDEFINED_METHOD_ENTRY_P(me)) {
00866 type = -1;
00867 }
00868 else {
00869 type = VISI(me->flag);
00870 }
00871 st_add_direct(list, key, type);
00872 }
00873 return ST_CONTINUE;
00874 }
00875
00876 static VALUE
00877 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
00878 {
00879 VALUE ary;
00880 int recur;
00881 st_table *list;
00882
00883 if (argc == 0) {
00884 recur = TRUE;
00885 }
00886 else {
00887 VALUE r;
00888 rb_scan_args(argc, argv, "01", &r);
00889 recur = RTEST(r);
00890 }
00891
00892 list = st_init_numtable();
00893 for (; mod; mod = RCLASS_SUPER(mod)) {
00894 st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
00895 if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
00896 if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
00897 if (!recur) break;
00898 }
00899 ary = rb_ary_new();
00900 st_foreach(list, func, ary);
00901 st_free_table(list);
00902
00903 return ary;
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 VALUE
00934 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
00935 {
00936 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 VALUE
00949 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
00950 {
00951 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 VALUE
00972 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
00973 {
00974 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
00975 }
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 VALUE
00987 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
00988 {
00989 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011 VALUE
01012 rb_obj_methods(int argc, VALUE *argv, VALUE obj)
01013 {
01014 retry:
01015 if (argc == 0) {
01016 VALUE args[1];
01017
01018 args[0] = Qtrue;
01019 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
01020 }
01021 else {
01022 VALUE recur;
01023
01024 rb_scan_args(argc, argv, "1", &recur);
01025 if (RTEST(recur)) {
01026 argc = 0;
01027 goto retry;
01028 }
01029 return rb_obj_singleton_methods(argc, argv, obj);
01030 }
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 VALUE
01043 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
01044 {
01045 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 VALUE
01058 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
01059 {
01060 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 VALUE
01073 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
01074 {
01075 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
01076 }
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111 VALUE
01112 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
01113 {
01114 VALUE recur, ary, klass;
01115 st_table *list;
01116
01117 if (argc == 0) {
01118 recur = Qtrue;
01119 }
01120 else {
01121 rb_scan_args(argc, argv, "01", &recur);
01122 }
01123 klass = CLASS_OF(obj);
01124 list = st_init_numtable();
01125 if (klass && FL_TEST(klass, FL_SINGLETON)) {
01126 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
01127 klass = RCLASS_SUPER(klass);
01128 }
01129 if (RTEST(recur)) {
01130 while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
01131 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
01132 klass = RCLASS_SUPER(klass);
01133 }
01134 }
01135 ary = rb_ary_new();
01136 st_foreach(list, ins_methods_i, ary);
01137 st_free_table(list);
01138
01139 return ary;
01140 }
01141
01199 void
01200 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
01201 {
01202 rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
01203 }
01204
01205 void
01206 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01207 {
01208 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
01209 }
01210
01211 void
01212 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01213 {
01214 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
01215 }
01216
01217 void
01218 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01219 {
01220 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
01221 }
01222
01223 void
01224 rb_undef_method(VALUE klass, const char *name)
01225 {
01226 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
01227 }
01228
01237 #define SPECIAL_SINGLETON(x,c) do {\
01238 if (obj == (x)) {\
01239 return (c);\
01240 }\
01241 } while (0)
01242
01243
01253 static VALUE
01254 singleton_class_of(VALUE obj)
01255 {
01256 VALUE klass;
01257
01258 if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
01259 rb_raise(rb_eTypeError, "can't define singleton");
01260 }
01261 if (rb_special_const_p(obj)) {
01262 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
01263 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
01264 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
01265 rb_bug("unknown immediate %p", (void *)obj);
01266 }
01267
01268 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
01269 rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
01270 klass = RBASIC(obj)->klass;
01271 }
01272 else {
01273 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
01274 }
01275
01276 if (OBJ_TAINTED(obj)) {
01277 OBJ_TAINT(klass);
01278 }
01279 else {
01280 FL_UNSET(klass, FL_TAINT);
01281 }
01282 if (OBJ_UNTRUSTED(obj)) {
01283 OBJ_UNTRUST(klass);
01284 }
01285 else {
01286 FL_UNSET(klass, FL_UNTRUSTED);
01287 }
01288 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
01289
01290 return klass;
01291 }
01292
01293
01311 VALUE
01312 rb_singleton_class(VALUE obj)
01313 {
01314 VALUE klass = singleton_class_of(obj);
01315
01316
01317 if (TYPE(obj) == T_CLASS) (void)ENSURE_EIGENCLASS(klass);
01318
01319 return klass;
01320 }
01321
01338 void
01339 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
01340 {
01341 rb_define_method(singleton_class_of(obj), name, func, argc);
01342 }
01343
01344
01345
01353 void
01354 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
01355 {
01356 rb_define_private_method(module, name, func, argc);
01357 rb_define_singleton_method(module, name, func, argc);
01358 }
01359
01360
01367 void
01368 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
01369 {
01370 rb_define_module_function(rb_mKernel, name, func, argc);
01371 }
01372
01373
01380 void
01381 rb_define_alias(VALUE klass, const char *name1, const char *name2)
01382 {
01383 rb_alias(klass, rb_intern(name1), rb_intern(name2));
01384 }
01385
01393 void
01394 rb_define_attr(VALUE klass, const char *name, int read, int write)
01395 {
01396 rb_attr(klass, rb_intern(name), read, write, FALSE);
01397 }
01398
01399 int
01400 rb_obj_basic_to_s_p(VALUE obj)
01401 {
01402 const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"));
01403 if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
01404 me->def->body.cfunc.func == rb_any_to_s)
01405 return 1;
01406 return 0;
01407 }
01408
01409 #include <stdarg.h>
01410
01411 int
01412 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
01413 {
01414 int i;
01415 const char *p = fmt;
01416 VALUE *var;
01417 va_list vargs;
01418 int f_var = 0, f_hash = 0, f_block = 0;
01419 int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
01420 int argi = 0;
01421 VALUE hash = Qnil;
01422
01423 if (ISDIGIT(*p)) {
01424 n_lead = *p - '0';
01425 p++;
01426 if (ISDIGIT(*p)) {
01427 n_opt = *p - '0';
01428 p++;
01429 if (ISDIGIT(*p)) {
01430 n_trail = *p - '0';
01431 p++;
01432 goto block_arg;
01433 }
01434 }
01435 }
01436 if (*p == '*') {
01437 f_var = 1;
01438 p++;
01439 if (ISDIGIT(*p)) {
01440 n_trail = *p - '0';
01441 p++;
01442 }
01443 }
01444 block_arg:
01445 if (*p == ':') {
01446 f_hash = 1;
01447 p++;
01448 }
01449 if (*p == '&') {
01450 f_block = 1;
01451 p++;
01452 }
01453 if (*p != '\0') {
01454 rb_fatal("bad scan arg format: %s", fmt);
01455 }
01456 n_mand = n_lead + n_trail;
01457
01458 if (argc < n_mand)
01459 goto argc_error;
01460
01461 va_start(vargs, fmt);
01462
01463
01464 if (f_hash && n_mand < argc) {
01465 VALUE last = argv[argc - 1];
01466
01467 if (NIL_P(last)) {
01468
01469
01470
01471 if (!f_var && n_mand + n_opt < argc)
01472 argc--;
01473 }
01474 else {
01475 hash = rb_check_convert_type(last, T_HASH, "Hash", "to_hash");
01476 if (!NIL_P(hash))
01477 argc--;
01478 }
01479 }
01480
01481 for (i = n_lead; i-- > 0; ) {
01482 var = va_arg(vargs, VALUE *);
01483 if (var) *var = argv[argi];
01484 argi++;
01485 }
01486
01487 for (i = n_opt; i-- > 0; ) {
01488 var = va_arg(vargs, VALUE *);
01489 if (argi < argc - n_trail) {
01490 if (var) *var = argv[argi];
01491 argi++;
01492 }
01493 else {
01494 if (var) *var = Qnil;
01495 }
01496 }
01497
01498 if (f_var) {
01499 int n_var = argc - argi - n_trail;
01500
01501 var = va_arg(vargs, VALUE *);
01502 if (0 < n_var) {
01503 if (var) *var = rb_ary_new4(n_var, &argv[argi]);
01504 argi += n_var;
01505 }
01506 else {
01507 if (var) *var = rb_ary_new();
01508 }
01509 }
01510
01511 for (i = n_trail; i-- > 0; ) {
01512 var = va_arg(vargs, VALUE *);
01513 if (var) *var = argv[argi];
01514 argi++;
01515 }
01516
01517 if (f_hash) {
01518 var = va_arg(vargs, VALUE *);
01519 if (var) *var = hash;
01520 }
01521
01522 if (f_block) {
01523 var = va_arg(vargs, VALUE *);
01524 if (rb_block_given_p()) {
01525 *var = rb_block_proc();
01526 }
01527 else {
01528 *var = Qnil;
01529 }
01530 }
01531 va_end(vargs);
01532
01533 if (argi < argc)
01534 goto argc_error;
01535
01536 return argc;
01537
01538 argc_error:
01539 if (0 < n_opt)
01540 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)",
01541 argc, n_mand, n_mand + n_opt, f_var ? "+" : "");
01542 else
01543 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)",
01544 argc, n_mand, f_var ? "+" : "");
01545 }
01546