Ruby  2.0.0p594(2014-10-27revision48167)
class.c
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   class.c -
00004 
00005   $Author: usa $
00006   created at: Tue Aug 10 15:05:44 JST 1993
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
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 NODE*
00125 rewrite_cref_stack(NODE *node, VALUE old_klass, VALUE new_klass)
00126 {
00127     NODE *new_node;
00128     if (!node) {
00129         return NULL;
00130     }
00131     if (node->nd_clss == old_klass) {
00132         new_node = NEW_CREF(new_klass);
00133         new_node->nd_next = node->nd_next;
00134     } else {
00135         new_node = NEW_CREF(node->nd_clss);
00136         new_node->nd_next = rewrite_cref_stack(node->nd_next, old_klass, new_klass);
00137     }
00138     return new_node;
00139 }
00140 
00141 static void
00142 clone_method(VALUE klass, ID mid, const rb_method_entry_t *me)
00143 {
00144     VALUE newiseqval;
00145     if (me->def && me->def->type == VM_METHOD_TYPE_ISEQ) {
00146         rb_iseq_t *iseq;
00147         newiseqval = rb_iseq_clone(me->def->body.iseq->self, klass);
00148         GetISeqPtr(newiseqval, iseq);
00149         iseq->cref_stack = rewrite_cref_stack(me->def->body.iseq->cref_stack, me->klass, klass);
00150         rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, me->flag);
00151         RB_GC_GUARD(newiseqval);
00152     }
00153     else {
00154         rb_method_entry_set(klass, mid, me, me->flag);
00155     }
00156 }
00157 
00158 static int
00159 clone_method_i(st_data_t key, st_data_t value, st_data_t data)
00160 {
00161     clone_method((VALUE)data, (ID)key, (const rb_method_entry_t *)value);
00162     return ST_CONTINUE;
00163 }
00164 
00165 static int
00166 clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
00167 {
00168     rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
00169     *nce = *ce;
00170     st_insert(tbl, key, (st_data_t)nce);
00171     return ST_CONTINUE;
00172 }
00173 
00174 static int
00175 clone_const_i(st_data_t key, st_data_t value, st_data_t data)
00176 {
00177     return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
00178 }
00179 
00180 static void
00181 class_init_copy_check(VALUE clone, VALUE orig)
00182 {
00183     if (orig == rb_cBasicObject) {
00184         rb_raise(rb_eTypeError, "can't copy the root class");
00185     }
00186     if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) {
00187         rb_raise(rb_eTypeError, "already initialized class");
00188     }
00189     if (FL_TEST(orig, FL_SINGLETON)) {
00190         rb_raise(rb_eTypeError, "can't copy singleton class");
00191     }
00192 }
00193 
00194 /* :nodoc: */
00195 VALUE
00196 rb_mod_init_copy(VALUE clone, VALUE orig)
00197 {
00198     if (RB_TYPE_P(clone, T_CLASS)) {
00199         class_init_copy_check(clone, orig);
00200     }
00201     if (!OBJ_INIT_COPY(clone, orig)) return clone;
00202     if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00203         RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00204         rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00205     }
00206     RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
00207     RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
00208     if (RCLASS_IV_TBL(clone)) {
00209         st_free_table(RCLASS_IV_TBL(clone));
00210         RCLASS_IV_TBL(clone) = 0;
00211     }
00212     if (RCLASS_CONST_TBL(clone)) {
00213         rb_free_const_table(RCLASS_CONST_TBL(clone));
00214         RCLASS_CONST_TBL(clone) = 0;
00215     }
00216     if (RCLASS_M_TBL(clone)) {
00217         rb_free_m_table(RCLASS_M_TBL(clone));
00218         RCLASS_M_TBL(clone) = 0;
00219     }
00220     if (RCLASS_IV_TBL(orig)) {
00221         st_data_t id;
00222 
00223         RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
00224         CONST_ID(id, "__tmp_classpath__");
00225         st_delete(RCLASS_IV_TBL(clone), &id, 0);
00226         CONST_ID(id, "__classpath__");
00227         st_delete(RCLASS_IV_TBL(clone), &id, 0);
00228         CONST_ID(id, "__classid__");
00229         st_delete(RCLASS_IV_TBL(clone), &id, 0);
00230     }
00231     if (RCLASS_CONST_TBL(orig)) {
00232 
00233         RCLASS_CONST_TBL(clone) = st_init_numtable();
00234         st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00235     }
00236     if (RCLASS_M_TBL(orig)) {
00237         RCLASS_M_TBL(clone) = st_init_numtable();
00238         st_foreach(RCLASS_M_TBL(orig), clone_method_i, (st_data_t)clone);
00239     }
00240 
00241     return clone;
00242 }
00243 
00244 VALUE
00245 rb_singleton_class_clone(VALUE obj)
00246 {
00247     return rb_singleton_class_clone_and_attach(obj, Qundef);
00248 }
00249 
00250 VALUE
00251 rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach)
00252 {
00253     VALUE klass = RBASIC(obj)->klass;
00254 
00255     if (!FL_TEST(klass, FL_SINGLETON))
00256         return klass;
00257     else {
00258         /* copy singleton(unnamed) class */
00259         VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
00260 
00261         if (BUILTIN_TYPE(obj) == T_CLASS) {
00262             RBASIC(clone)->klass = clone;
00263         }
00264         else {
00265             RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00266         }
00267 
00268         RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
00269         RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
00270         if (RCLASS_IV_TBL(klass)) {
00271             RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
00272         }
00273         if (RCLASS_CONST_TBL(klass)) {
00274             RCLASS_CONST_TBL(clone) = st_init_numtable();
00275             st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
00276         }
00277         if (attach != Qundef) {
00278             rb_singleton_class_attached(clone, attach);
00279         }
00280         RCLASS_M_TBL(clone) = st_init_numtable();
00281         st_foreach(RCLASS_M_TBL(klass), clone_method_i, (st_data_t)clone);
00282         rb_singleton_class_attached(RBASIC(clone)->klass, clone);
00283         FL_SET(clone, FL_SINGLETON);
00284         return clone;
00285     }
00286 }
00287 
00292 void
00293 rb_singleton_class_attached(VALUE klass, VALUE obj)
00294 {
00295     if (FL_TEST(klass, FL_SINGLETON)) {
00296         if (!RCLASS_IV_TBL(klass)) {
00297             RCLASS_IV_TBL(klass) = st_init_numtable();
00298         }
00299         st_insert(RCLASS_IV_TBL(klass), id_attached, obj);
00300     }
00301 }
00302 
00303 
00304 
00305 #define METACLASS_OF(k) RBASIC(k)->klass
00306 
00312 #define META_CLASS_OF_CLASS_CLASS_P(k)  (METACLASS_OF(k) == (k))
00313 
00319 #define HAVE_METACLASS_P(k) \
00320     (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \
00321      rb_ivar_get(METACLASS_OF(k), id_attached) == (k))
00322 
00330 #define ENSURE_EIGENCLASS(klass) \
00331     (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass))
00332 
00333 
00343 static inline VALUE
00344 make_metaclass(VALUE klass)
00345 {
00346     VALUE super;
00347     VALUE metaclass = rb_class_boot(Qundef);
00348 
00349     FL_SET(metaclass, FL_SINGLETON);
00350     rb_singleton_class_attached(metaclass, klass);
00351 
00352     if (META_CLASS_OF_CLASS_CLASS_P(klass)) {
00353         METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass;
00354     }
00355     else {
00356         VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
00357         METACLASS_OF(klass) = metaclass;
00358         METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp);
00359     }
00360 
00361     super = RCLASS_SUPER(klass);
00362     while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super);
00363     RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass;
00364 
00365     OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
00366 
00367     return metaclass;
00368 }
00369 
00376 static inline VALUE
00377 make_singleton_class(VALUE obj)
00378 {
00379     VALUE orig_class = RBASIC(obj)->klass;
00380     VALUE klass = rb_class_boot(orig_class);
00381 
00382     FL_SET(klass, FL_SINGLETON);
00383     RBASIC(obj)->klass = klass;
00384     rb_singleton_class_attached(klass, obj);
00385 
00386     METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class));
00387     return klass;
00388 }
00389 
00390 
00391 static VALUE
00392 boot_defclass(const char *name, VALUE super)
00393 {
00394     extern st_table *rb_class_tbl;
00395     VALUE obj = rb_class_boot(super);
00396     ID id = rb_intern(name);
00397 
00398     rb_name_class(obj, id);
00399     st_add_direct(rb_class_tbl, id, obj);
00400     rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
00401     return obj;
00402 }
00403 
00404 void
00405 Init_class_hierarchy(void)
00406 {
00407     id_attached = rb_intern("__attached__");
00408 
00409     rb_cBasicObject = boot_defclass("BasicObject", 0);
00410     rb_cObject = boot_defclass("Object", rb_cBasicObject);
00411     rb_cModule = boot_defclass("Module", rb_cObject);
00412     rb_cClass =  boot_defclass("Class",  rb_cModule);
00413 
00414     rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
00415     RBASIC(rb_cClass)->klass
00416         = RBASIC(rb_cModule)->klass
00417         = RBASIC(rb_cObject)->klass
00418         = RBASIC(rb_cBasicObject)->klass
00419         = rb_cClass;
00420 }
00421 
00422 
00433 VALUE
00434 rb_make_metaclass(VALUE obj, VALUE unused)
00435 {
00436     if (BUILTIN_TYPE(obj) == T_CLASS) {
00437         return make_metaclass(obj);
00438     }
00439     else {
00440         return make_singleton_class(obj);
00441     }
00442 }
00443 
00444 
00455 VALUE
00456 rb_define_class_id(ID id, VALUE super)
00457 {
00458     VALUE klass;
00459 
00460     if (!super) super = rb_cObject;
00461     klass = rb_class_new(super);
00462     rb_make_metaclass(klass, RBASIC(super)->klass);
00463 
00464     return klass;
00465 }
00466 
00467 
00476 VALUE
00477 rb_class_inherited(VALUE super, VALUE klass)
00478 {
00479     ID inherited;
00480     if (!super) super = rb_cObject;
00481     CONST_ID(inherited, "inherited");
00482     return rb_funcall(super, inherited, 1, klass);
00483 }
00484 
00485 
00486 
00502 VALUE
00503 rb_define_class(const char *name, VALUE super)
00504 {
00505     VALUE klass;
00506     ID id;
00507 
00508     id = rb_intern(name);
00509     if (rb_const_defined(rb_cObject, id)) {
00510         klass = rb_const_get(rb_cObject, id);
00511         if (!RB_TYPE_P(klass, T_CLASS)) {
00512             rb_raise(rb_eTypeError, "%s is not a class", name);
00513         }
00514         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00515             rb_raise(rb_eTypeError, "superclass mismatch for class %s", name);
00516         }
00517         return klass;
00518     }
00519     if (!super) {
00520         rb_warn("no super class for `%s', Object assumed", name);
00521     }
00522     klass = rb_define_class_id(id, super);
00523     st_add_direct(rb_class_tbl, id, klass);
00524     rb_name_class(klass, id);
00525     rb_const_set(rb_cObject, id, klass);
00526     rb_class_inherited(super, klass);
00527 
00528     return klass;
00529 }
00530 
00531 
00548 VALUE
00549 rb_define_class_under(VALUE outer, const char *name, VALUE super)
00550 {
00551     return rb_define_class_id_under(outer, rb_intern(name), super);
00552 }
00553 
00554 
00571 VALUE
00572 rb_define_class_id_under(VALUE outer, ID id, VALUE super)
00573 {
00574     VALUE klass;
00575 
00576     if (rb_const_defined_at(outer, id)) {
00577         klass = rb_const_get_at(outer, id);
00578         if (!RB_TYPE_P(klass, T_CLASS)) {
00579             rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
00580         }
00581         if (rb_class_real(RCLASS_SUPER(klass)) != super) {
00582             rb_name_error(id, "%s is already defined", rb_id2name(id));
00583         }
00584         return klass;
00585     }
00586     if (!super) {
00587         rb_warn("no super class for `%s::%s', Object assumed",
00588                 rb_class2name(outer), rb_id2name(id));
00589     }
00590     klass = rb_define_class_id(id, super);
00591     rb_set_class_path_string(klass, outer, rb_id2str(id));
00592     rb_const_set(outer, id, klass);
00593     rb_class_inherited(super, klass);
00594     rb_gc_register_mark_object(klass);
00595 
00596     return klass;
00597 }
00598 
00599 VALUE
00600 rb_module_new(void)
00601 {
00602     VALUE mdl = class_alloc(T_MODULE, rb_cModule);
00603 
00604     RCLASS_M_TBL(mdl) = st_init_numtable();
00605 
00606     return (VALUE)mdl;
00607 }
00608 
00609 VALUE
00610 rb_define_module_id(ID id)
00611 {
00612     VALUE mdl;
00613 
00614     mdl = rb_module_new();
00615     rb_name_class(mdl, id);
00616 
00617     return mdl;
00618 }
00619 
00620 VALUE
00621 rb_define_module(const char *name)
00622 {
00623     VALUE module;
00624     ID id;
00625 
00626     id = rb_intern(name);
00627     if (rb_const_defined(rb_cObject, id)) {
00628         module = rb_const_get(rb_cObject, id);
00629         if (RB_TYPE_P(module, T_MODULE))
00630             return module;
00631         rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00632     }
00633     module = rb_define_module_id(id);
00634     st_add_direct(rb_class_tbl, id, module);
00635     rb_const_set(rb_cObject, id, module);
00636 
00637     return module;
00638 }
00639 
00640 VALUE
00641 rb_define_module_under(VALUE outer, const char *name)
00642 {
00643     return rb_define_module_id_under(outer, rb_intern(name));
00644 }
00645 
00646 VALUE
00647 rb_define_module_id_under(VALUE outer, ID id)
00648 {
00649     VALUE module;
00650 
00651     if (rb_const_defined_at(outer, id)) {
00652         module = rb_const_get_at(outer, id);
00653         if (RB_TYPE_P(module, T_MODULE))
00654             return module;
00655         rb_raise(rb_eTypeError, "%s::%s is not a module",
00656                  rb_class2name(outer), rb_obj_classname(module));
00657     }
00658     module = rb_define_module_id(id);
00659     rb_const_set(outer, id, module);
00660     rb_set_class_path_string(module, outer, rb_id2str(id));
00661     rb_gc_register_mark_object(module);
00662 
00663     return module;
00664 }
00665 
00666 VALUE
00667 rb_include_class_new(VALUE module, VALUE super)
00668 {
00669     VALUE klass = class_alloc(T_ICLASS, rb_cClass);
00670 
00671     if (BUILTIN_TYPE(module) == T_ICLASS) {
00672         module = RBASIC(module)->klass;
00673     }
00674     if (!RCLASS_IV_TBL(module)) {
00675         RCLASS_IV_TBL(module) = st_init_numtable();
00676     }
00677     if (!RCLASS_CONST_TBL(module)) {
00678         RCLASS_CONST_TBL(module) = st_init_numtable();
00679     }
00680     RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
00681     RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
00682     RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module));
00683     RCLASS_SUPER(klass) = super;
00684     if (RB_TYPE_P(module, T_ICLASS)) {
00685         RBASIC(klass)->klass = RBASIC(module)->klass;
00686     }
00687     else {
00688         RBASIC(klass)->klass = module;
00689     }
00690     OBJ_INFECT(klass, module);
00691     OBJ_INFECT(klass, super);
00692 
00693     return (VALUE)klass;
00694 }
00695 
00696 static int include_modules_at(const VALUE klass, VALUE c, VALUE module);
00697 
00698 void
00699 rb_include_module(VALUE klass, VALUE module)
00700 {
00701     int changed = 0;
00702 
00703     rb_frozen_class_p(klass);
00704     if (!OBJ_UNTRUSTED(klass)) {
00705         rb_secure(4);
00706     }
00707 
00708     if (!RB_TYPE_P(module, T_MODULE)) {
00709         Check_Type(module, T_MODULE);
00710     }
00711 
00712     OBJ_INFECT(klass, module);
00713 
00714     changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module);
00715     if (changed < 0)
00716         rb_raise(rb_eArgError, "cyclic include detected");
00717     if (changed) rb_clear_cache();
00718 }
00719 
00720 static int
00721 add_refined_method_entry_i(st_data_t key, st_data_t value, st_data_t data)
00722 {
00723     rb_add_refined_method_entry((VALUE) data, (ID) key);
00724     return ST_CONTINUE;
00725 }
00726 
00727 static int
00728 include_modules_at(const VALUE klass, VALUE c, VALUE module)
00729 {
00730     VALUE p;
00731     int changed = 0;
00732     const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass));
00733 
00734     while (module) {
00735         int superclass_seen = FALSE;
00736 
00737         if (RCLASS_ORIGIN(module) != module)
00738             goto skip;
00739         if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module))
00740             return -1;
00741         /* ignore if the module included already in superclasses */
00742         for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
00743             switch (BUILTIN_TYPE(p)) {
00744               case T_ICLASS:
00745                 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
00746                     if (!superclass_seen) {
00747                         c = p;  /* move insertion point */
00748                     }
00749                     goto skip;
00750                 }
00751                 break;
00752               case T_CLASS:
00753                 superclass_seen = TRUE;
00754                 break;
00755             }
00756         }
00757         c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c));
00758         if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
00759             VALUE refined_class =
00760                 rb_refinement_module_get_refined_class(klass);
00761 
00762             st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i,
00763                        (st_data_t) refined_class);
00764             FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT);
00765         }
00766         if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
00767             changed = 1;
00768         if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries)
00769             changed = 1;
00770       skip:
00771         module = RCLASS_SUPER(module);
00772     }
00773 
00774     return changed;
00775 }
00776 
00777 static int
00778 move_refined_method(st_data_t key, st_data_t value, st_data_t data)
00779 {
00780     rb_method_entry_t *me = (rb_method_entry_t *) value;
00781     st_table *tbl = (st_table *) data;
00782 
00783     if (me->def->type == VM_METHOD_TYPE_REFINED) {
00784         if (me->def->body.orig_me) {
00785             rb_method_entry_t *orig_me = me->def->body.orig_me, *new_me;
00786             me->def->body.orig_me = NULL;
00787             new_me = ALLOC(rb_method_entry_t);
00788             *new_me = *me;
00789             st_add_direct(tbl, key, (st_data_t) new_me);
00790             *me = *orig_me;
00791             xfree(orig_me);
00792             return ST_CONTINUE;
00793         }
00794         else {
00795             st_add_direct(tbl, key, (st_data_t) me);
00796             return ST_DELETE;
00797         }
00798     }
00799     else {
00800         return ST_CONTINUE;
00801     }
00802 }
00803 
00804 void
00805 rb_prepend_module(VALUE klass, VALUE module)
00806 {
00807     void rb_vm_check_redefinition_by_prepend(VALUE klass);
00808     VALUE origin;
00809     int changed = 0;
00810 
00811     rb_frozen_class_p(klass);
00812     if (!OBJ_UNTRUSTED(klass)) {
00813         rb_secure(4);
00814     }
00815 
00816     Check_Type(module, T_MODULE);
00817 
00818     OBJ_INFECT(klass, module);
00819 
00820     origin = RCLASS_ORIGIN(klass);
00821     if (origin == klass) {
00822         origin = class_alloc(T_ICLASS, klass);
00823         RCLASS_SUPER(origin) = RCLASS_SUPER(klass);
00824         RCLASS_SUPER(klass) = origin;
00825         RCLASS_ORIGIN(klass) = origin;
00826         RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
00827         RCLASS_M_TBL(klass) = st_init_numtable();
00828         st_foreach(RCLASS_M_TBL(origin), move_refined_method,
00829                    (st_data_t) RCLASS_M_TBL(klass));
00830     }
00831     changed = include_modules_at(klass, klass, module);
00832     if (changed < 0)
00833         rb_raise(rb_eArgError, "cyclic prepend detected");
00834     if (changed) {
00835         rb_clear_cache();
00836         rb_vm_check_redefinition_by_prepend(klass);
00837     }
00838 }
00839 
00840 /*
00841  *  call-seq:
00842  *     mod.included_modules -> array
00843  *
00844  *  Returns the list of modules included in <i>mod</i>.
00845  *
00846  *     module Mixin
00847  *     end
00848  *
00849  *     module Outer
00850  *       include Mixin
00851  *     end
00852  *
00853  *     Mixin.included_modules   #=> []
00854  *     Outer.included_modules   #=> [Mixin]
00855  */
00856 
00857 VALUE
00858 rb_mod_included_modules(VALUE mod)
00859 {
00860     VALUE ary = rb_ary_new();
00861     VALUE p;
00862     VALUE origin = RCLASS_ORIGIN(mod);
00863 
00864     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00865         if (p != origin && BUILTIN_TYPE(p) == T_ICLASS) {
00866             VALUE m = RBASIC(p)->klass;
00867             if (RB_TYPE_P(m, T_MODULE))
00868                 rb_ary_push(ary, m);
00869         }
00870     }
00871     return ary;
00872 }
00873 
00874 /*
00875  *  call-seq:
00876  *     mod.include?(module)    -> true or false
00877  *
00878  *  Returns <code>true</code> if <i>module</i> is included in
00879  *  <i>mod</i> or one of <i>mod</i>'s ancestors.
00880  *
00881  *     module A
00882  *     end
00883  *     class B
00884  *       include A
00885  *     end
00886  *     class C < B
00887  *     end
00888  *     B.include?(A)   #=> true
00889  *     C.include?(A)   #=> true
00890  *     A.include?(A)   #=> false
00891  */
00892 
00893 VALUE
00894 rb_mod_include_p(VALUE mod, VALUE mod2)
00895 {
00896     VALUE p;
00897 
00898     Check_Type(mod2, T_MODULE);
00899     for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
00900         if (BUILTIN_TYPE(p) == T_ICLASS) {
00901             if (RBASIC(p)->klass == mod2) return Qtrue;
00902         }
00903     }
00904     return Qfalse;
00905 }
00906 
00907 /*
00908  *  call-seq:
00909  *     mod.ancestors -> array
00910  *
00911  *  Returns a list of modules included in <i>mod</i> (including
00912  *  <i>mod</i> itself).
00913  *
00914  *     module Mod
00915  *       include Math
00916  *       include Comparable
00917  *     end
00918  *
00919  *     Mod.ancestors    #=> [Mod, Comparable, Math]
00920  *     Math.ancestors   #=> [Math]
00921  */
00922 
00923 VALUE
00924 rb_mod_ancestors(VALUE mod)
00925 {
00926     VALUE p, ary = rb_ary_new();
00927 
00928     for (p = mod; p; p = RCLASS_SUPER(p)) {
00929         if (FL_TEST(p, FL_SINGLETON))
00930             continue;
00931         if (BUILTIN_TYPE(p) == T_ICLASS) {
00932             rb_ary_push(ary, RBASIC(p)->klass);
00933         }
00934         else if (p == RCLASS_ORIGIN(p)) {
00935             rb_ary_push(ary, p);
00936         }
00937     }
00938     return ary;
00939 }
00940 
00941 #define VISI(x) ((x)&NOEX_MASK)
00942 #define VISI_CHECK(x,f) (VISI(x) == (f))
00943 
00944 static int
00945 ins_methods_push(ID name, long type, VALUE ary, long visi)
00946 {
00947     if (type == -1) return ST_CONTINUE;
00948 
00949     switch (visi) {
00950       case NOEX_PRIVATE:
00951       case NOEX_PROTECTED:
00952       case NOEX_PUBLIC:
00953         visi = (type == visi);
00954         break;
00955       default:
00956         visi = (type != NOEX_PRIVATE);
00957         break;
00958     }
00959     if (visi) {
00960         rb_ary_push(ary, ID2SYM(name));
00961     }
00962     return ST_CONTINUE;
00963 }
00964 
00965 static int
00966 ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
00967 {
00968     return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1); /* everything but private */
00969 }
00970 
00971 static int
00972 ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
00973 {
00974     return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED);
00975 }
00976 
00977 static int
00978 ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
00979 {
00980     return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE);
00981 }
00982 
00983 static int
00984 ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
00985 {
00986     return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
00987 }
00988 
00989 static int
00990 method_entry_i(st_data_t key, st_data_t value, st_data_t data)
00991 {
00992     const rb_method_entry_t *me = (const rb_method_entry_t *)value;
00993     st_table *list = (st_table *)data;
00994     long type;
00995 
00996     if (me && me->def->type == VM_METHOD_TYPE_REFINED) {
00997         me = rb_resolve_refined_method(Qnil, me, NULL);
00998         if (!me) return ST_CONTINUE;
00999     }
01000     if (!st_lookup(list, key, 0)) {
01001         if (UNDEFINED_METHOD_ENTRY_P(me)) {
01002             type = -1; /* none */
01003         }
01004         else {
01005             type = VISI(me->flag);
01006         }
01007         st_add_direct(list, key, type);
01008     }
01009     return ST_CONTINUE;
01010 }
01011 
01012 static VALUE
01013 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
01014 {
01015     VALUE ary;
01016     int recur, prepended = 0;
01017     st_table *list;
01018 
01019     if (argc == 0) {
01020         recur = TRUE;
01021     }
01022     else {
01023         VALUE r;
01024         rb_scan_args(argc, argv, "01", &r);
01025         recur = RTEST(r);
01026     }
01027 
01028     if (!recur && RCLASS_ORIGIN(mod) != mod) {
01029         mod = RCLASS_ORIGIN(mod);
01030         prepended = 1;
01031     }
01032 
01033     list = st_init_numtable();
01034     for (; mod; mod = RCLASS_SUPER(mod)) {
01035         if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
01036         if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue;
01037         if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
01038         if (!recur) break;
01039     }
01040     ary = rb_ary_new();
01041     st_foreach(list, func, ary);
01042     st_free_table(list);
01043 
01044     return ary;
01045 }
01046 
01047 /*
01048  *  call-seq:
01049  *     mod.instance_methods(include_super=true)   -> array
01050  *
01051  *  Returns an array containing the names of the public and protected instance
01052  *  methods in the receiver. For a module, these are the public and protected methods;
01053  *  for a class, they are the instance (not singleton) methods. With no
01054  *  argument, or with an argument that is <code>false</code>, the
01055  *  instance methods in <i>mod</i> are returned, otherwise the methods
01056  *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
01057  *
01058  *     module A
01059  *       def method1()  end
01060  *     end
01061  *     class B
01062  *       def method2()  end
01063  *     end
01064  *     class C < B
01065  *       def method3()  end
01066  *     end
01067  *
01068  *     A.instance_methods                #=> [:method1]
01069  *     B.instance_methods(false)         #=> [:method2]
01070  *     C.instance_methods(false)         #=> [:method3]
01071  *     C.instance_methods(true).length   #=> 43
01072  */
01073 
01074 VALUE
01075 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
01076 {
01077     return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
01078 }
01079 
01080 /*
01081  *  call-seq:
01082  *     mod.protected_instance_methods(include_super=true)   -> array
01083  *
01084  *  Returns a list of the protected instance methods defined in
01085  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
01086  *  methods of any ancestors are included.
01087  */
01088 
01089 VALUE
01090 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
01091 {
01092     return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
01093 }
01094 
01095 /*
01096  *  call-seq:
01097  *     mod.private_instance_methods(include_super=true)    -> array
01098  *
01099  *  Returns a list of the private instance methods defined in
01100  *  <i>mod</i>. If the optional parameter is not <code>false</code>, the
01101  *  methods of any ancestors are included.
01102  *
01103  *     module Mod
01104  *       def method1()  end
01105  *       private :method1
01106  *       def method2()  end
01107  *     end
01108  *     Mod.instance_methods           #=> [:method2]
01109  *     Mod.private_instance_methods   #=> [:method1]
01110  */
01111 
01112 VALUE
01113 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
01114 {
01115     return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
01116 }
01117 
01118 /*
01119  *  call-seq:
01120  *     mod.public_instance_methods(include_super=true)   -> array
01121  *
01122  *  Returns a list of the public instance methods defined in <i>mod</i>.
01123  *  If the optional parameter is not <code>false</code>, the methods of
01124  *  any ancestors are included.
01125  */
01126 
01127 VALUE
01128 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
01129 {
01130     return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
01131 }
01132 
01133 /*
01134  *  call-seq:
01135  *     obj.methods(all=true)    -> array
01136  *
01137  *  Returns a list of the names of public and protected methods of
01138  *  <i>obj</i>. This will include all the methods accessible in
01139  *  <i>obj</i>'s ancestors.
01140  *  If the <i>all</i> parameter is set to <code>false</code>, only those methods
01141  *  in the receiver will be listed.
01142  *
01143  *     class Klass
01144  *       def klass_method()
01145  *       end
01146  *     end
01147  *     k = Klass.new
01148  *     k.methods[0..9]    #=> [:klass_method, :nil?, :===,
01149  *                        #    :==~, :!, :eql?
01150  *                        #    :hash, :<=>, :class, :singleton_class]
01151  *     k.methods.length   #=> 57
01152  */
01153 
01154 VALUE
01155 rb_obj_methods(int argc, VALUE *argv, VALUE obj)
01156 {
01157   retry:
01158     if (argc == 0) {
01159         return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_i);
01160     }
01161     else {
01162         VALUE recur;
01163 
01164         rb_scan_args(argc, argv, "1", &recur);
01165         if (RTEST(recur)) {
01166             argc = 0;
01167             goto retry;
01168         }
01169         return rb_obj_singleton_methods(argc, argv, obj);
01170     }
01171 }
01172 
01173 /*
01174  *  call-seq:
01175  *     obj.protected_methods(all=true)   -> array
01176  *
01177  *  Returns the list of protected methods accessible to <i>obj</i>. If
01178  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01179  *  in the receiver will be listed.
01180  */
01181 
01182 VALUE
01183 rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj)
01184 {
01185     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_prot_i);
01186 }
01187 
01188 /*
01189  *  call-seq:
01190  *     obj.private_methods(all=true)   -> array
01191  *
01192  *  Returns the list of private methods accessible to <i>obj</i>. If
01193  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01194  *  in the receiver will be listed.
01195  */
01196 
01197 VALUE
01198 rb_obj_private_methods(int argc, VALUE *argv, VALUE obj)
01199 {
01200     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_priv_i);
01201 }
01202 
01203 /*
01204  *  call-seq:
01205  *     obj.public_methods(all=true)   -> array
01206  *
01207  *  Returns the list of public methods accessible to <i>obj</i>. If
01208  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
01209  *  in the receiver will be listed.
01210  */
01211 
01212 VALUE
01213 rb_obj_public_methods(int argc, VALUE *argv, VALUE obj)
01214 {
01215     return class_instance_method_list(argc, argv, CLASS_OF(obj), 1, ins_methods_pub_i);
01216 }
01217 
01218 /*
01219  *  call-seq:
01220  *     obj.singleton_methods(all=true)    -> array
01221  *
01222  *  Returns an array of the names of singleton methods for <i>obj</i>.
01223  *  If the optional <i>all</i> parameter is true, the list will include
01224  *  methods in modules included in <i>obj</i>.
01225  *  Only public and protected singleton methods are returned.
01226  *
01227  *     module Other
01228  *       def three() end
01229  *     end
01230  *
01231  *     class Single
01232  *       def Single.four() end
01233  *     end
01234  *
01235  *     a = Single.new
01236  *
01237  *     def a.one()
01238  *     end
01239  *
01240  *     class << a
01241  *       include Other
01242  *       def two()
01243  *       end
01244  *     end
01245  *
01246  *     Single.singleton_methods    #=> [:four]
01247  *     a.singleton_methods(false)  #=> [:two, :one]
01248  *     a.singleton_methods         #=> [:two, :one, :three]
01249  */
01250 
01251 VALUE
01252 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
01253 {
01254     VALUE recur, ary, klass;
01255     st_table *list;
01256 
01257     if (argc == 0) {
01258         recur = Qtrue;
01259     }
01260     else {
01261         rb_scan_args(argc, argv, "01", &recur);
01262     }
01263     klass = CLASS_OF(obj);
01264     list = st_init_numtable();
01265     if (klass && FL_TEST(klass, FL_SINGLETON)) {
01266         if (RCLASS_M_TBL(klass))
01267             st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
01268         klass = RCLASS_SUPER(klass);
01269     }
01270     if (RTEST(recur)) {
01271         while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) {
01272             if (RCLASS_M_TBL(klass))
01273                 st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
01274             klass = RCLASS_SUPER(klass);
01275         }
01276     }
01277     ary = rb_ary_new();
01278     st_foreach(list, ins_methods_i, ary);
01279     st_free_table(list);
01280 
01281     return ary;
01282 }
01283 
01341 void
01342 rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc)
01343 {
01344     rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC);
01345 }
01346 
01347 void
01348 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01349 {
01350     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC);
01351 }
01352 
01353 void
01354 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01355 {
01356     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED);
01357 }
01358 
01359 void
01360 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
01361 {
01362     rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE);
01363 }
01364 
01365 void
01366 rb_undef_method(VALUE klass, const char *name)
01367 {
01368     rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF);
01369 }
01370 
01379 #define SPECIAL_SINGLETON(x,c) do {\
01380     if (obj == (x)) {\
01381         return (c);\
01382     }\
01383 } while (0)
01384 
01385 static inline VALUE
01386 special_singleton_class_of(VALUE obj)
01387 {
01388     SPECIAL_SINGLETON(Qnil, rb_cNilClass);
01389     SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
01390     SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
01391     return Qnil;
01392 }
01393 
01394 VALUE
01395 rb_special_singleton_class(VALUE obj)
01396 {
01397     return special_singleton_class_of(obj);
01398 }
01399 
01409 static VALUE
01410 singleton_class_of(VALUE obj)
01411 {
01412     VALUE klass;
01413 
01414     if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) {
01415         rb_raise(rb_eTypeError, "can't define singleton");
01416     }
01417     if (SPECIAL_CONST_P(obj)) {
01418         klass = special_singleton_class_of(obj);
01419         if (NIL_P(klass))
01420             rb_bug("unknown immediate %p", (void *)obj);
01421         return klass;
01422     }
01423     else {
01424         enum ruby_value_type type = BUILTIN_TYPE(obj);
01425         if (type == T_FLOAT || type == T_BIGNUM) {
01426            rb_raise(rb_eTypeError, "can't define singleton");
01427         }
01428     }
01429 
01430     if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
01431         rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
01432         klass = RBASIC(obj)->klass;
01433     }
01434     else {
01435         klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
01436     }
01437 
01438     if (OBJ_TAINTED(obj)) {
01439         OBJ_TAINT(klass);
01440     }
01441     else {
01442         FL_UNSET(klass, FL_TAINT);
01443     }
01444     if (OBJ_UNTRUSTED(obj)) {
01445         OBJ_UNTRUST(klass);
01446     }
01447     else {
01448         FL_UNSET(klass, FL_UNTRUSTED);
01449     }
01450     if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
01451 
01452     return klass;
01453 }
01454 
01455 
01473 VALUE
01474 rb_singleton_class(VALUE obj)
01475 {
01476     VALUE klass = singleton_class_of(obj);
01477 
01478     /* ensures an exposed class belongs to its own eigenclass */
01479     if (RB_TYPE_P(obj, T_CLASS)) (void)ENSURE_EIGENCLASS(klass);
01480 
01481     return klass;
01482 }
01483 
01500 void
01501 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
01502 {
01503     rb_define_method(singleton_class_of(obj), name, func, argc);
01504 }
01505 
01506 
01507 
01515 void
01516 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
01517 {
01518     rb_define_private_method(module, name, func, argc);
01519     rb_define_singleton_method(module, name, func, argc);
01520 }
01521 
01522 
01529 void
01530 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
01531 {
01532     rb_define_module_function(rb_mKernel, name, func, argc);
01533 }
01534 
01535 
01542 void
01543 rb_define_alias(VALUE klass, const char *name1, const char *name2)
01544 {
01545     rb_alias(klass, rb_intern(name1), rb_intern(name2));
01546 }
01547 
01555 void
01556 rb_define_attr(VALUE klass, const char *name, int read, int write)
01557 {
01558     rb_attr(klass, rb_intern(name), read, write, FALSE);
01559 }
01560 
01561 int
01562 rb_obj_basic_to_s_p(VALUE obj)
01563 {
01564     const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"), 0);
01565     if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
01566         me->def->body.cfunc.func == rb_any_to_s)
01567         return 1;
01568     return 0;
01569 }
01570 
01571 #include <stdarg.h>
01572 
01573 int
01574 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
01575 {
01576     int i;
01577     const char *p = fmt;
01578     VALUE *var;
01579     va_list vargs;
01580     int f_var = 0, f_hash = 0, f_block = 0;
01581     int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
01582     int argi = 0;
01583     VALUE hash = Qnil;
01584 
01585     if (ISDIGIT(*p)) {
01586         n_lead = *p - '0';
01587         p++;
01588         if (ISDIGIT(*p)) {
01589             n_opt = *p - '0';
01590             p++;
01591             if (ISDIGIT(*p)) {
01592                 n_trail = *p - '0';
01593                 p++;
01594                 goto block_arg;
01595             }
01596         }
01597     }
01598     if (*p == '*') {
01599         f_var = 1;
01600         p++;
01601         if (ISDIGIT(*p)) {
01602             n_trail = *p - '0';
01603             p++;
01604         }
01605     }
01606   block_arg:
01607     if (*p == ':') {
01608         f_hash = 1;
01609         p++;
01610     }
01611     if (*p == '&') {
01612         f_block = 1;
01613         p++;
01614     }
01615     if (*p != '\0') {
01616         rb_fatal("bad scan arg format: %s", fmt);
01617     }
01618     n_mand = n_lead + n_trail;
01619 
01620     if (argc < n_mand)
01621         goto argc_error;
01622 
01623     va_start(vargs, fmt);
01624 
01625     /* capture an option hash - phase 1: pop */
01626     if (f_hash && n_mand < argc) {
01627         VALUE last = argv[argc - 1];
01628 
01629         if (NIL_P(last)) {
01630             /* nil is taken as an empty option hash only if it is not
01631                ambiguous; i.e. '*' is not specified and arguments are
01632                given more than sufficient */
01633             if (!f_var && n_mand + n_opt < argc)
01634                 argc--;
01635         }
01636         else {
01637             hash = rb_check_hash_type(last);
01638             if (!NIL_P(hash))
01639                 argc--;
01640         }
01641     }
01642     /* capture leading mandatory arguments */
01643     for (i = n_lead; i-- > 0; ) {
01644         var = va_arg(vargs, VALUE *);
01645         if (var) *var = argv[argi];
01646         argi++;
01647     }
01648     /* capture optional arguments */
01649     for (i = n_opt; i-- > 0; ) {
01650         var = va_arg(vargs, VALUE *);
01651         if (argi < argc - n_trail) {
01652             if (var) *var = argv[argi];
01653             argi++;
01654         }
01655         else {
01656             if (var) *var = Qnil;
01657         }
01658     }
01659     /* capture variable length arguments */
01660     if (f_var) {
01661         int n_var = argc - argi - n_trail;
01662 
01663         var = va_arg(vargs, VALUE *);
01664         if (0 < n_var) {
01665             if (var) *var = rb_ary_new4(n_var, &argv[argi]);
01666             argi += n_var;
01667         }
01668         else {
01669             if (var) *var = rb_ary_new();
01670         }
01671     }
01672     /* capture trailing mandatory arguments */
01673     for (i = n_trail; i-- > 0; ) {
01674         var = va_arg(vargs, VALUE *);
01675         if (var) *var = argv[argi];
01676         argi++;
01677     }
01678     /* capture an option hash - phase 2: assignment */
01679     if (f_hash) {
01680         var = va_arg(vargs, VALUE *);
01681         if (var) *var = hash;
01682     }
01683     /* capture iterator block */
01684     if (f_block) {
01685         var = va_arg(vargs, VALUE *);
01686         if (rb_block_given_p()) {
01687             *var = rb_block_proc();
01688         }
01689         else {
01690             *var = Qnil;
01691         }
01692     }
01693     va_end(vargs);
01694 
01695     if (argi < argc) {
01696       argc_error:
01697         rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
01698     }
01699 
01700     return argc;
01701 }
01702