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 NEWOBJ_OF(obj, struct RClass, klass, flags);
00053 obj->ptr = ALLOC(rb_classext_t);
00054 RCLASS_IV_TBL(obj) = 0;
00055 RCLASS_CONST_TBL(obj) = 0;
00056 RCLASS_M_TBL(obj) = 0;
00057 RCLASS_SUPER(obj) = 0;
00058 RCLASS_ORIGIN(obj) = (VALUE)obj;
00059 RCLASS_IV_INDEX_TBL(obj) = 0;
00060 RCLASS_REFINED_CLASS(obj) = Qnil;
00061 RCLASS_EXT(obj)->allocator = 0;
00062 return (VALUE)obj;
00063 }
00064
00065
00075 VALUE
00076 rb_class_boot(VALUE super)
00077 {
00078 VALUE klass = class_alloc(T_CLASS, rb_cClass);
00079
00080 RCLASS_SUPER(klass) = super;
00081 RCLASS_M_TBL(klass) = st_init_numtable();
00082
00083 OBJ_INFECT(klass, super);
00084 return (VALUE)klass;
00085 }
00086
00087
00094 void
00095 rb_check_inheritable(VALUE super)
00096 {
00097 if (!RB_TYPE_P(super, T_CLASS)) {
00098 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
00099 rb_obj_classname(super));
00100 }
00101 if (RBASIC(super)->flags & FL_SINGLETON) {
00102 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
00103 }
00104 if (super == rb_cClass) {
00105 rb_raise(rb_eTypeError, "can't make subclass of Class");
00106 }
00107 }
00108
00109
00116 VALUE
00117 rb_class_new(VALUE super)
00118 {
00119 Check_Type(super, T_CLASS);
00120 rb_check_inheritable(super);
00121 return rb_class_boot(super);
00122 }
00123
00124 static void
00125 clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
00126 {
00127 VALUE newiseqval;
00128 if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
00129 rb_iseq_t *iseq;
00130 NODE *new_cref;
00131 newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
00132 GetISeqPtr(newiseqval, iseq);
00133 rb_vm_rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass, &new_cref);
00134 iseq->cref_stack = new_cref;
00135 rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
00136 RB_GC_GUARD(newiseqval);
00137 }
00138 else {
00139 rb_method_entry_set(klass, mid, me, me->flag);
00140 }
00141 }
00142
00143 static int
00144 clone_method_i(st_data_t key, st_data_t value, st_data_t data)
00145 {
00146 clone_method((VALUE)data, (ID)key, (const rb_method_entry_t *)value);
00147 return ST_CONTINUE;
00148 }
00149
00150 static int
00151 clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
00152 {
00153 rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
00154 *nce = *ce;
00155 st_insert(tbl, key, (st_data_t)nce);
00156 return ST_CONTINUE;
00157 }
00158
00159 static int
00160 clone_const_i(st_data_t key, st_data_t value, st_data_t data)
00161 {
00162 return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
00163 }
00164
00165 static void
00166 class_init_copy_check(VALUE clone, VALUE orig)
00167 {
00168 if (orig == rb_cBasicObject) {
00169 rb_raise(rb_eTypeError, "can't copy the root class");
00170 }
00171 if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
00172 rb_raise(rb_eTypeError, "already initialized class");
00173 }
00174 if (FL_TEST(orig, FL_SINGLETON)) {
00175 rb_raise(rb_eTypeError, "can't copy singleton class");
00176 }
00177 }
00178
00179
00180 VALUE
00181 rb_mod_init_copy(VALUE clone, VALUE orig)
00182 {
00183 if (RB_TYPE_P(clone, T_CLASS)) {
00184 class_init_copy_check(clone, orig);
00185 }
00186 if (!OBJ_INIT_COPY(clone, orig)) return clone;
00187 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00188 RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00189 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00190 }
00191 RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
00192 RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
00193 if (RCLASS_IV_TBL(clone)) {
00194 st_free_table(RCLASS_IV_TBL(clone));
00195 RCLASS_IV_TBL(clone) = 0;
00196 }
00197 if (RCLASS_CONST_TBL(clone)) {
00198 rb_free_const_table(RCLASS_CONST_TBL(clone));
00199 RCLASS_CONST_TBL(clone) = 0;
00200 }
00201 if (RCLASS_M_TBL(clone)) {
00202 rb_free_m_table(RCLASS_M_TBL(clone));
00203 RCLASS_M_TBL(clone) = 0;
00204 }
00205 if (RCLASS_IV_TBL(orig)) {
00206 st_data_t id;
00207
00208 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
00209 CONST_ID(id, "__tmp_classpath__");
00210 st_delete(RCLASS_IV_TBL(clone), &id, 0);
00211 CONST_ID(id, "__classpath__");
00212 st_delete(RCLASS_IV_TBL(clone), &id, 0);
00213 CONST_ID(id, "__classid__");
00214 st_delete(RCLASS_IV_TBL(clone), &id, 0);
00215 }
00216 if (RCLASS_CONST_TBL(orig)) {
00217
00218 RCLASS_CONST_TBL(clone) = st_init_numtable();
00219 st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00220 }
00221 if (RCLASS_M_TBL(orig)) {
00222 RCLASS_M_TBL(clone) = st_init_numtable();
00223 st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone);
00224 }
00225
00226 return clone;
00227 }
00228
00229 VALUE
00230 rb_singleton_class_clone(VALUE obj)
00231 {
00232 return rb_singleton_class_clone_and_attach(obj, Qundef);
00233 }
00234
00235 VALUE
00236 rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
00237 {
00238 VALUE klass = RBASIC(obj)->klass;
00239
00240 if (!FL_TEST(klass, FL_SINGLETON))
00241 return klass;
00242 else {
00243
00244 VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
00245
00246 if (BUILTIN_TYPE(obj) == T_CLASS) {
00247 RBASIC(clone)->klass = clone;
00248 }
00249 else {
00250 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00251 }
00252
00253 RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
00254 RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
00255 if (RCLASS_IV_TBL(klass)) {
00256 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
00257 }
00258 if (RCLASS_CONST_TBL(klass)) {
00259 RCLASS_CONST_TBL(clone) = st_init_numtable();
00260 st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00261 }
00262 if (attach != Qundef) {
00263 rb_singleton_class_attached(clone, attach);
00264 }
00265 RCLASS_M_TBL(clone) = st_init_numtable();
00266 st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone);
00267 rb_singleton_class_attached(RBASIC(clone)->klass, clone);
00268 FL_SET(clone, FL_SINGLETON);
00269 return clone;
00270 }
00271 }
00272
00277 void
00278 rb_singleton_class_attached(VALUE klass, VALUE obj)
00279 {
00280 if (FL_TEST(klass, FL_SINGLETON)) {
00281 if (!RCLASS_IV_TBL(klass)) {
00282 RCLASS_IV_TBL(klass) = st_init_numtable();
00283 }
00284 st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
00285 }
00286 }
00287
00288
00289
00290 #define METACLASS_OF(k) RBASIC(k)->klass
00291
00297 #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k))
00298
00304 #define HAVE_METACLASS_P(k) \
00305 (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
00306 rb_ivar_get(METACLASS_OF(k), id_attached) == (k))
00307
00315 #define ENSURE_EIGENCLASS(klass) \
00316 (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
00317
00318
00328 static inline VALUE
00329 make_metaclass(VALUE klass)
00330 {
00331 VALUE super;
00332 VALUE metaclass = rb_class_boot(Qundef);
00333
00334 FL_SET(metaclass, FL_SINGLETON);
00335 rb_singleton_class_attached(metaclass, klass);
00336
00337 if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
00338 METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass;
00339 }
00340 else {
00341 VALUE tmp = METACLASS_OF(klass);
00342 METACLASS_OF(klass) = metaclass;
00343 METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp);
00344 }
00345
00346 super = RCLASS_SUPER(klass);
00347 while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
00348 RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass;
00349
00350 OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
00351
00352 return metaclass;
00353 }
00354
00361 static inline VALUE
00362 make_singleton_class(VALUE obj)
00363 {
00364 VALUE orig_class = RBASIC(obj)->klass;
00365 VALUE klass = rb_class_boot(orig_class);
00366
00367 FL_SET(klass, FL_SINGLETON);
00368 RBASIC(obj)->klass = klass;
00369 rb_singleton_class_attached(klass, obj);
00370
00371 METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class));
00372 return klass;
00373 }
00374
00375
00376 static VALUE
00377 boot_defclass(const char *name, VALUE super)
00378 {
00379 extern st_table *rb_class_tbl;
00380 VALUE obj = rb_class_boot(super);
00381 ID id = rb_intern(name);
00382
00383 rb_name_class(obj, id);
00384 st_add_direct(rb_class_tbl, id, obj);
00385 rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
00386 return obj;
00387 }
00388
00389 void
00390 Init_class_hierarchy(void)
00391 {
00392 id_attached = rb_intern("__attached__");
00393
00394 rb_cBasicObject = boot_defclass("BasicObject", 0);
00395 rb_cObject = boot_defclass("Object", rb_cBasicObject);
00396 rb_cModule = boot_defclass("Module", rb_cObject);
00397 rb_cClass = boot_defclass("Class", rb_cModule);
00398
00399 rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
00400 RBASIC(rb_cClass)->klass
00401 = RBASIC(rb_cModule)->klass
00402 = RBASIC(rb_cObject)->klass
00403 = RBASIC(rb_cBasicObject)->klass
00404 = rb_cClass;
00405 }
00406
00407
00418 VALUE
00419 rb_make_metaclass(VALUE obj, VALUE unused)
00420 {
00421 if (BUILTIN_TYPE(obj) == T_CLASS) {
00422 return make_metaclass(obj);
00423 }
00424 else {
00425 return make_singleton_class(obj);
00426 }
00427 }
00428
00429
00440 VALUE
00441 rb_define_class_id(ID id, VALUE super)
00442 {
00443 VALUE klass;
00444
00445 if (!super) super = rb_cObject;
00446 klass = rb_class_new(super);
00447 rb_make_metaclass(klass, RBASIC(super)->klass);
00448
00449 return klass;
00450 }
00451
00452
00461 VALUE
00462 rb_class_inherited(VALUE super, VALUE klass)
00463 {
00464 ID inherited;
00465 if (!super) super = rb_cObject;
00466 CONST_ID(inherited, "inherited");
00467 return rb_funcall(super, inherited, 1, klass);
00468 }
00469
00470
00471
00487 VALUE
00488 rb_define_class(const char *name, VALUE super)
00489 {
00490 VALUE klass;
00491 ID id;
00492
00493 id = rb_intern(name);
00494 if (rb_const_defined(rb_cObject, id)) {
00495 klass = rb_const_get(rb_cObject, id);
00496 if (!RB_TYPE_P(klass, T_CLASS)) {
00497 rb_raise(rb_eTypeError, "%s is not a class", name);
00498 }
00499 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00500 rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
00501 }
00502 return klass;
00503 }
00504 if (!super) {
00505 rb_warn("no super class for `%s', Object assumed", name);
00506 }
00507 klass = rb_define_class_id(id, super);
00508 st_add_direct(rb_class_tbl, id, klass);
00509 rb_name_class(klass, id);
00510 rb_const_set(rb_cObject, id, klass);
00511 rb_class_inherited(super, klass);
00512
00513 return klass;
00514 }
00515
00516
00533 VALUE
00534 rb_define_class_under(VALUE outer, const char *name, VALUE super)
00535 {
00536 return rb_define_class_id_under(outer, rb_intern(name), super);
00537 }
00538
00539
00556 VALUE
00557 rb_define_class_id_under(VALUE outer, ID id, VALUE super)
00558 {
00559 VALUE klass;
00560
00561 if (rb_const_defined_at(outer, id)) {
00562 klass = rb_const_get_at(outer, id);
00563 if (!RB_TYPE_P(klass, T_CLASS)) {
00564 rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
00565 }
00566 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00567 rb_name_error(id, "%s is already defined", rb_id2name(id));
00568 }
00569 return klass;
00570 }
00571 if (!super) {
00572 rb_warn("no super class for `%s::%s', Object assumed",
00573 rb_class2name(outer), rb_id2name(id));
00574 }
00575 klass = rb_define_class_id(id, super);
00576 rb_set_class_path_string(klass, outer, rb_id2str(id));
00577 rb_const_set(outer, id, klass);
00578 rb_class_inherited(super, klass);
00579 rb_gc_register_mark_object(klass);
00580
00581 return klass;
00582 }
00583
00584 VALUE
00585 rb_module_new(void)
00586 {
00587 VALUE mdl = class_alloc(T_MODULE, rb_cModule);
00588
00589 RCLASS_M_TBL(mdl) = st_init_numtable();
00590
00591 return (VALUE)mdl;
00592 }
00593
00594 VALUE
00595 rb_define_module_id(ID id)
00596 {
00597 VALUE mdl;
00598
00599 mdl = rb_module_new();
00600 rb_name_class(mdl, id);
00601
00602 return mdl;
00603 }
00604
00605 VALUE
00606 rb_define_module(const char *name)
00607 {
00608 VALUE module;
00609 ID id;
00610
00611 id = rb_intern(name);
00612 if (rb_const_defined(rb_cObject, id)) {
00613 module = rb_const_get(rb_cObject, id);
00614 if (RB_TYPE_P(module, T_MODULE))
00615 return module;
00616 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00617 }
00618 module = rb_define_module_id(id);
00619 st_add_direct(rb_class_tbl, id, module);
00620 rb_const_set(rb_cObject, id, module);
00621
00622 return module;
00623 }
00624
00625 VALUE
00626 rb_define_module_under(VALUE outer, const char *name)
00627 {
00628 return rb_define_module_id_under(outer, rb_intern(name));
00629 }
00630
00631 VALUE
00632 rb_define_module_id_under(VALUE outer, ID id)
00633 {
00634 VALUE module;
00635
00636 if (rb_const_defined_at(outer, id)) {
00637 module = rb_const_get_at(outer, id);
00638 if (RB_TYPE_P(module, T_MODULE))
00639 return module;
00640 rb_raise(rb_eTypeError, "%s::%s is not a module",
00641 rb_class2name(outer), rb_obj_classname(module));
00642 }
00643 module = rb_define_module_id(id);
00644 rb_const_set(outer, id, module);
00645 rb_set_class_path_string(module, outer, rb_id2str(id));
00646 rb_gc_register_mark_object(module);
00647
00648 return module;
00649 }
00650
00651 VALUE
00652 rb_include_class_new(VALUE module, VALUE super)
00653 {
00654 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
00655
00656 if (BUILTIN_TYPE(module) == T_ICLASS) {
00657 module = RBASIC(module)->klass;
00658 }
00659 if (!RCLASS_IV_TBL(module)) {
00660 RCLASS_IV_TBL(module) = st_init_numtable();
00661 }
00662 if (!RCLASS_CONST_TBL(module)) {
00663 RCLASS_CONST_TBL(module) = st_init_numtable();
00664 }
00665 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
00666 RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
00667 RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module));
00668 RCLASS_SUPER(klass) = super;
00669 if (RB_TYPE_P(module, T_ICLASS)) {
00670 RBASIC(klass)->klass = RBASIC(module)->klass;
00671 }
00672 else {
00673 RBASIC(klass)->klass = module;
00674 }
00675 OBJ_INFECT(klass, module);
00676 OBJ_INFECT(klass, super);
00677
00678 return (VALUE)klass;
00679 }
00680
00681 static int include_modules_at(const VALUE klass, VALUE c, VALUE module);
00682
00683 void
00684 rb_include_module(VALUE klass, VALUE module)
00685 {
00686 int changed = 0;
00687
00688 rb_frozen_class_p(klass);
00689 if (!OBJ_UNTRUSTED(klass)) {
00690 rb_secure(4);
00691 }
00692
00693 if (!RB_TYPE_P(module, T_MODULE)) {
00694 Check_Type(module, T_MODULE);
00695 }
00696
00697 OBJ_INFECT(klass, module);
00698
00699 changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module);
00700 if (changed < 0)
00701 rb_raise(rb_eArgError, "cyclic include detected");
00702 if (changed) rb_clear_cache();
00703 }
00704
00705 static int
00706 add_refined_method_entry_i(st_data_t key, st_data_t value, st_data_t data)
00707 {
00708 rb_add_refined_method_entry((VALUE) data, (ID) key);
00709 return ST_CONTINUE;
00710 }
00711
00712 static int
00713 include_modules_at(const VALUE klass, VALUE c, VALUE module)
00714 {
00715 VALUE p;
00716 int changed = 0;
00717 const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
00718
00719 while (module) {
00720 int superclass_seen = FALSE;
00721
00722 if (RCLASS_ORIGIN(module) != module)
00723 goto skip;
00724 if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
00725 return -1;
00726
00727 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
00728 switch (BUILTIN_TYPE(p)) {
00729 case T_ICLASS:
00730 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
00731 if (!superclass_seen) {
00732 c = p;
00733 }
00734 goto skip;
00735 }
00736 break;
00737 case T_CLASS:
00738 superclass_seen = TRUE;
00739 break;
00740 }
00741 }
00742 c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c));
00743 if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
00744 VALUE refined_class =
00745 rb_refinement_module_get_refined_class(klass);
00746
00747 st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i,
00748 (st_data_t) refined_class);
00749 FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
00750 }
00751 if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
00752 changed = 1;
00753 if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries)
00754 changed = 1;
00755 skip:
00756 module = RCLASS_SUPER(module);
00757 }
00758
00759 return changed;
00760 }
00761
00762 static int
00763 move_refined_method(st_data_t key, st_data_t value, st_data_t data)
00764 {
00765 rb_method_entry_t *me = (rb_method_entry_t *) value;
00766 st_table *tbl = (st_table *) data;
00767
00768 if (me->def->type == VM_METHOD_TYPE_REFINED) {
00769 if (me->def->body.orig_me) {
00770 rb_method_entry_t *orig_me = me->def->body.orig_me, *new_me;
00771 me->def->body.orig_me = NULL;
00772 new_me = ALLOC(rb_method_entry_t);
00773 *new_me = *me;
00774 st_add_direct(tbl, key, (st_data_t) new_me);
00775 *me = *orig_me;
00776 xfree(orig_me);
00777 return ST_CONTINUE;
00778 }
00779 else {
00780 st_add_direct(tbl, key, (st_data_t) me);
00781 return ST_DELETE;
00782 }
00783 }
00784 else {
00785 return ST_CONTINUE;
00786 }
00787 }
00788
00789 void
00790 rb_prepend_module(VALUE klass, VALUE module)
00791 {
00792 void rb_vm_check_redefinition_by_prepend(VALUE klass);
00793 VALUE origin;
00794 int changed = 0;
00795
00796 rb_frozen_class_p(klass);
00797 if (!OBJ_UNTRUSTED(klass)) {
00798 rb_secure(4);
00799 }
00800
00801 Check_Type(module, T_MODULE);
00802
00803 OBJ_INFECT(klass, module);
00804
00805 origin = RCLASS_ORIGIN(klass);
00806 if (origin == klass) {
00807 origin = class_alloc(T_ICLASS, klass);
00808 RCLASS_SUPER(origin) = RCLASS_SUPER(klass);
00809 RCLASS_SUPER(klass) = origin;
00810 RCLASS_ORIGIN(klass) = origin;
00811 RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
00812 RCLASS_M_TBL(klass) = st_init_numtable();
00813 st_foreach(RCLASS_M_TBL(origin), move_refined_method,
00814 (st_data_t) RCLASS_M_TBL(klass));
00815 }
00816 changed = include_modules_at(klass, klass, module);
00817 if (changed < 0)
00818 rb_raise(rb_eArgError, "cyclic prepend detected");
00819 if (changed) {
00820 rb_clear_cache();
00821 rb_vm_check_redefinition_by_prepend(klass);
00822 }
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 VALUE
00843 rb_mod_included_modules(VALUE mod)
00844 {
00845 VALUE ary = rb_ary_new();
00846 VALUE p;
00847 VALUE origin = RCLASS_ORIGIN(mod);
00848
00849 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00850 if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
00851 VALUE m = RBASIC(p)->klass;
00852 if (RB_TYPE_P(m, T_MODULE))
00853 rb_ary_push(ary, m);
00854 }
00855 }
00856 return ary;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878 VALUE
00879 rb_mod_include_p(VALUE mod, VALUE mod2)
00880 {
00881 VALUE p;
00882
00883 Check_Type(mod2, T_MODULE);
00884 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00885 if (BUILTIN_TYPE(p) == T_ICLASS) {
00886 if (RBASIC(p)->klass == mod2) return Qtrue;
00887 }
00888 }
00889 return Qfalse;
00890 }
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 VALUE
00909 rb_mod_ancestors(VALUE mod)
00910 {
00911 VALUE p, ary = rb_ary_new();
00912
00913 for (p = mod; p; p = RCLASS_SUPER(p)) {
00914 if (FL_TEST(p, FL_SINGLETON))
00915 continue;
00916 if (BUILTIN_TYPE(p) == T_ICLASS) {
00917 rb_ary_push(ary, RBASIC(p)->klass);
00918 }
00919 else if (p == RCLASS_ORIGIN(p)) {
00920 rb_ary_push(ary, p);
00921 }
00922 }
00923 return ary;
00924 }
00925
00926 #define VISI(x) ((x)&NOEX_MASK)
00927 #define VISI_CHECK(x,f) (VISI(x) == (f))
00928
00929 static int
00930 ins_methods_push(ID name, long type, VALUE ary, long visi)
00931 {
00932 if (type == -1) return ST_CONTINUE;
00933
00934 switch (visi) {
00935 case NOEX_PRIVATE:
00936 case NOEX_PROTECTED:
00937 case NOEX_PUBLIC:
00938 visi = (type == visi);
00939 break;
00940 default:
00941 visi = (type != NOEX_PRIVATE);
00942 break;
00943 }
00944 if (visi) {
00945 rb_ary_push(ary, ID2SYM(name));
00946 }
00947 return ST_CONTINUE;
00948 }
00949
00950 static int
00951 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
00952 {
00953 return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1);
00954 }
00955
00956 static int
00957 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
00958 {
00959 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED);
00960 }
00961
00962 static int
00963 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
00964 {
00965 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE);
00966 }
00967
00968 static int
00969 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
00970 {
00971 return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
00972 }
00973
00974 struct method_entry_arg {
00975 st_table *list;
00976 int recur;
00977 };
00978
00979 static int
00980 method_entry_i(st_data_t key, st_data_t value, st_data_t data)
00981 {
00982 const rb_method_entry_t *me = (const rb_method_entry_t *)value;
00983 struct method_entry_arg *arg = (struct method_entry_arg *)data;
00984 long type;
00985
00986 if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
00987 VALUE klass = me->klass;
00988 me = rb_resolve_refined_method(Qnil, me, NULL);
00989 if (!me) return ST_CONTINUE;
00990 if (!arg->recur && me->klass != klass) return ST_CONTINUE;
00991 }
00992 if (!st_lookup(arg->list, key, 0)) {
00993 if (UNDEFINED_METHOD_ENTRY_P(me)) {
00994 type = -1;
00995 }
00996 else {
00997 type = VISI(me->flag);
00998 }
00999 st_add_direct(arg->list, key, type);
01000 }
01001 return ST_CONTINUE;
01002 }
01003
01004 static VALUE
01005 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
01006 {
01007 VALUE ary;
01008 int recur, prepended = 0;
01009 struct method_entry_arg me_arg;
01010
01011 if (argc == 0) {
01012 recur = TRUE;
01013 }
01014 else {
01015 VALUE r;
01016 rb_scan_args(argc, argv, "01", &r);
01017 recur = RTEST(r);
01018 }
01019
01020 if (!recur && RCLASS_ORIGIN(mod) != mod) {
01021 mod = RCLASS_ORIGIN(mod);
01022 prepended = 1;
01023 }
01024
01025 me_arg.list = st_init_numtable();
01026 me_arg.recur = recur;
01027 for (; mod; mod = RCLASS_SUPER(mod)) {
01028 if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)&me_arg);
01029 if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
01030 if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
01031 if (!recur) break;
01032 }
01033 ary = rb_ary_new();
01034 st_foreach(me_arg.list, func, ary);
01035 st_free_table(me_arg.list);
01036
01037 return ary;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 VALUE
01068 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
01069 {
01070 return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 VALUE
01083 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
01084 {
01085 return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 VALUE
01106 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
01107 {
01108 return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120 VALUE
01121 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
01122 {
01123 return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 VALUE
01148 rb_obj_methods(int argc, VALUE *argv, VALUE obj)
01149 {
01150 retry:
01151 if (argc == 0) {
01152 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
01153 }
01154 else {
01155 VALUE recur;
01156
01157 rb_scan_args(argc, argv, "1", &recur);
01158 if (RTEST(recur)) {
01159 argc = 0;
01160 goto retry;
01161 }
01162 return rb_obj_singleton_methods(argc, argv, obj);
01163 }
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 VALUE
01176 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
01177 {
01178 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
01179 }
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190 VALUE
01191 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
01192 {
01193 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205 VALUE
01206 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
01207 {
01208 return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
01209 }
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244 VALUE
01245 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
01246 {
01247 VALUE recur, ary, klass, origin;
01248 struct method_entry_arg me_arg;
01249 st_table *mtbl;
01250
01251 if (argc == 0) {
01252 recur = Qtrue;
01253 }
01254 else {
01255 rb_scan_args(argc, argv, "01", &recur);
01256 }
01257 klass = CLASS_OF(obj);
01258 origin = RCLASS_ORIGIN(klass);
01259 me_arg.list = st_init_numtable();
01260 me_arg.recur = RTEST(recur);
01261 if (klass && FL_TEST(klass, FL_SINGLETON)) {
01262 if ((mtbl = RCLASS_M_TBL(origin)) != 0)
01263 st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg);
01264 klass = RCLASS_SUPER(klass);
01265 }
01266 if (RTEST(recur)) {
01267 while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
01268 if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0)
01269 st_foreach(mtbl, method_entry_i, (st_data_t)&me_arg);
01270 klass = RCLASS_SUPER(klass);
01271 }
01272 }
01273 ary = rb_ary_new();
01274 st_foreach(me_arg.list, ins_methods_i, ary);
01275 st_free_table(me_arg.list);
01276
01277 return ary;
01278 }
01279
01337 void
01338 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
01339 {
01340 rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
01341 }
01342
01343 void
01344 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01345 {
01346 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
01347 }
01348
01349 void
01350 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01351 {
01352 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
01353 }
01354
01355 void
01356 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01357 {
01358 rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
01359 }
01360
01361 void
01362 rb_undef_method(VALUE klass, const char *name)
01363 {
01364 rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
01365 }
01366
01375 #define SPECIAL_SINGLETON(x,c) do {\
01376 if (obj == (x)) {\
01377 return (c);\
01378 }\
01379 } while (0)
01380
01381 static inline VALUE
01382 special_singleton_class_of(VALUE obj)
01383 {
01384 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
01385 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
01386 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
01387 return Qnil;
01388 }
01389
01390 VALUE
01391 rb_special_singleton_class(VALUE obj)
01392 {
01393 return special_singleton_class_of(obj);
01394 }
01395
01405 static VALUE
01406 singleton_class_of(VALUE obj)
01407 {
01408 VALUE klass;
01409
01410 if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) {
01411 rb_raise(rb_eTypeError, "can't define singleton");
01412 }
01413 if (SPECIAL_CONST_P(obj)) {
01414 klass = special_singleton_class_of(obj);
01415 if (NIL_P(klass))
01416 rb_bug("unknown immediate %p", (void *)obj);
01417 return klass;
01418 }
01419 else {
01420 enum ruby_value_type type = BUILTIN_TYPE(obj);
01421 if (type == T_FLOAT || type == T_BIGNUM) {
01422 rb_raise(rb_eTypeError, "can't define singleton");
01423 }
01424 }
01425
01426 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
01427 rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
01428 klass = RBASIC(obj)->klass;
01429 }
01430 else {
01431 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
01432 }
01433
01434 if (OBJ_TAINTED(obj)) {
01435 OBJ_TAINT(klass);
01436 }
01437 else {
01438 FL_UNSET(klass, FL_TAINT);
01439 }
01440 if (OBJ_UNTRUSTED(obj)) {
01441 OBJ_UNTRUST(klass);
01442 }
01443 else {
01444 FL_UNSET(klass, FL_UNTRUSTED);
01445 }
01446 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
01447
01448 return klass;
01449 }
01450
01451
01469 VALUE
01470 rb_singleton_class(VALUE obj)
01471 {
01472 VALUE klass = singleton_class_of(obj);
01473
01474
01475 if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass);
01476
01477 return klass;
01478 }
01479
01496 void
01497 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
01498 {
01499 rb_define_method(singleton_class_of(obj), name, func, argc);
01500 }
01501
01502
01503
01511 void
01512 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
01513 {
01514 rb_define_private_method(module, name, func, argc);
01515 rb_define_singleton_method(module, name, func, argc);
01516 }
01517
01518
01525 void
01526 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
01527 {
01528 rb_define_module_function(rb_mKernel, name, func, argc);
01529 }
01530
01531
01538 void
01539 rb_define_alias(VALUE klass, const char *name1, const char *name2)
01540 {
01541 rb_alias(klass, rb_intern(name1), rb_intern(name2));
01542 }
01543
01551 void
01552 rb_define_attr(VALUE klass, const char *name, int read, int write)
01553 {
01554 rb_attr(klass, rb_intern(name), read, write, FALSE);
01555 }
01556
01557 int
01558 rb_obj_basic_to_s_p(VALUE obj)
01559 {
01560 const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"), 0);
01561 if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
01562 me->def->body.cfunc.func == rb_any_to_s)
01563 return 1;
01564 return 0;
01565 }
01566
01567 #include <stdarg.h>
01568
01569 int
01570 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
01571 {
01572 int i;
01573 const char *p = fmt;
01574 VALUE *var;
01575 va_list vargs;
01576 int f_var = 0, f_hash = 0, f_block = 0;
01577 int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
01578 int argi = 0;
01579 VALUE hash = Qnil;
01580
01581 if (ISDIGIT(*p)) {
01582 n_lead = *p - '0';
01583 p++;
01584 if (ISDIGIT(*p)) {
01585 n_opt = *p - '0';
01586 p++;
01587 if (ISDIGIT(*p)) {
01588 n_trail = *p - '0';
01589 p++;
01590 goto block_arg;
01591 }
01592 }
01593 }
01594 if (*p == '*') {
01595 f_var = 1;
01596 p++;
01597 if (ISDIGIT(*p)) {
01598 n_trail = *p - '0';
01599 p++;
01600 }
01601 }
01602 block_arg:
01603 if (*p == ':') {
01604 f_hash = 1;
01605 p++;
01606 }
01607 if (*p == '&') {
01608 f_block = 1;
01609 p++;
01610 }
01611 if (*p != '\0') {
01612 rb_fatal("bad scan arg format: %s", fmt);
01613 }
01614 n_mand = n_lead + n_trail;
01615
01616 if (argc < n_mand)
01617 goto argc_error;
01618
01619 va_start(vargs, fmt);
01620
01621
01622 if (f_hash && n_mand < argc) {
01623 VALUE last = argv[argc - 1];
01624
01625 if (NIL_P(last)) {
01626
01627
01628
01629 if (!f_var && n_mand + n_opt < argc)
01630 argc--;
01631 }
01632 else {
01633 hash = rb_check_hash_type(last);
01634 if (!NIL_P(hash))
01635 argc--;
01636 }
01637 }
01638
01639 for (i = n_lead; i-- > 0; ) {
01640 var = va_arg(vargs, VALUE *);
01641 if (var) *var = argv[argi];
01642 argi++;
01643 }
01644
01645 for (i = n_opt; i-- > 0; ) {
01646 var = va_arg(vargs, VALUE *);
01647 if (argi < argc - n_trail) {
01648 if (var) *var = argv[argi];
01649 argi++;
01650 }
01651 else {
01652 if (var) *var = Qnil;
01653 }
01654 }
01655
01656 if (f_var) {
01657 int n_var = argc - argi - n_trail;
01658
01659 var = va_arg(vargs, VALUE *);
01660 if (0 < n_var) {
01661 if (var) *var = rb_ary_new4(n_var, &argv[argi]);
01662 argi += n_var;
01663 }
01664 else {
01665 if (var) *var = rb_ary_new();
01666 }
01667 }
01668
01669 for (i = n_trail; i-- > 0; ) {
01670 var = va_arg(vargs, VALUE *);
01671 if (var) *var = argv[argi];
01672 argi++;
01673 }
01674
01675 if (f_hash) {
01676 var = va_arg(vargs, VALUE *);
01677 if (var) *var = hash;
01678 }
01679
01680 if (f_block) {
01681 var = va_arg(vargs, VALUE *);
01682 if (rb_block_given_p()) {
01683 *var = rb_block_proc();
01684 }
01685 else {
01686 *var = Qnil;
01687 }
01688 }
01689 va_end(vargs);
01690
01691 if (argi < argc) {
01692 argc_error:
01693 rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
01694 }
01695
01696 return argc;
01697 }
01698