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