~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to class.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "ruby/ruby.h"
27
27
#include "ruby/st.h"
28
28
#include "method.h"
 
29
#include "constant.h"
29
30
#include "vm_core.h"
 
31
#include "internal.h"
30
32
#include <ctype.h>
31
33
 
32
34
extern st_table *rb_class_tbl;
52
54
    OBJSETUP(obj, klass, flags);
53
55
    obj->ptr = ext;
54
56
    RCLASS_IV_TBL(obj) = 0;
 
57
    RCLASS_CONST_TBL(obj) = 0;
55
58
    RCLASS_M_TBL(obj) = 0;
56
59
    RCLASS_SUPER(obj) = 0;
57
60
    RCLASS_IV_INDEX_TBL(obj) = 0;
141
144
    return ST_CONTINUE;
142
145
}
143
146
 
 
147
static int
 
148
clone_const(ID key, const rb_const_entry_t *ce, st_table *tbl)
 
149
{
 
150
    rb_const_entry_t *nce = ALLOC(rb_const_entry_t);
 
151
    *nce = *ce;
 
152
    st_insert(tbl, key, (st_data_t)nce);
 
153
    return ST_CONTINUE;
 
154
}
 
155
 
 
156
static int
 
157
clone_const_i(st_data_t key, st_data_t value, st_data_t data)
 
158
{
 
159
    return clone_const((ID)key, (const rb_const_entry_t *)value, (st_table *)data);
 
160
}
 
161
 
144
162
/* :nodoc: */
145
163
VALUE
146
164
rb_mod_init_copy(VALUE clone, VALUE orig)
152
170
    }
153
171
    RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
154
172
    if (RCLASS_IV_TBL(orig)) {
155
 
        ID id;
 
173
        st_data_t id;
156
174
 
157
175
        if (RCLASS_IV_TBL(clone)) {
158
176
            st_free_table(RCLASS_IV_TBL(clone));
159
177
        }
160
178
        RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
161
179
        CONST_ID(id, "__classpath__");
162
 
        st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
 
180
        st_delete(RCLASS_IV_TBL(clone), &id, 0);
163
181
        CONST_ID(id, "__classid__");
164
 
        st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
 
182
        st_delete(RCLASS_IV_TBL(clone), &id, 0);
 
183
    }
 
184
    if (RCLASS_CONST_TBL(orig)) {
 
185
        if (RCLASS_CONST_TBL(clone)) {
 
186
            rb_free_const_table(RCLASS_CONST_TBL(clone));
 
187
        }
 
188
        RCLASS_CONST_TBL(clone) = st_init_numtable();
 
189
        st_foreach(RCLASS_CONST_TBL(orig), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
165
190
    }
166
191
    if (RCLASS_M_TBL(orig)) {
167
192
        struct clone_method_data data;
168
193
 
169
194
        if (RCLASS_M_TBL(clone)) {
170
 
            extern void rb_free_m_table(st_table *tbl);
171
195
            rb_free_m_table(RCLASS_M_TBL(clone));
172
196
        }
173
197
        data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
205
229
    else {
206
230
        struct clone_method_data data;
207
231
        /* copy singleton(unnamed) class */
208
 
        VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
 
232
        VALUE clone = class_alloc((RBASIC(klass)->flags & ~(FL_MARK)), 0);
209
233
 
210
234
        if (BUILTIN_TYPE(obj) == T_CLASS) {
211
235
            RBASIC(clone)->klass = (VALUE)clone;
218
242
        if (RCLASS_IV_TBL(klass)) {
219
243
            RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
220
244
        }
 
245
        if (RCLASS_CONST_TBL(klass)) {
 
246
            RCLASS_CONST_TBL(clone) = st_init_numtable();
 
247
            st_foreach(RCLASS_CONST_TBL(klass), clone_const_i, (st_data_t)RCLASS_CONST_TBL(clone));
 
248
        }
221
249
        RCLASS_M_TBL(clone) = st_init_numtable();
222
250
        data.tbl = RCLASS_M_TBL(clone);
223
251
        data.klass = (VALUE)clone;
253
281
 * @retval 1 if \a k is a meta^(n)-class of Class class (n >= 0)
254
282
 * @retval 0 otherwise
255
283
 */
256
 
#define META_CLASS_OF_CLASS_CLASS_P(k)  (METACLASS_OF(k) == k)
 
284
#define META_CLASS_OF_CLASS_CLASS_P(k)  (METACLASS_OF(k) == (k))
257
285
 
258
286
 
259
287
/*!
264
292
 * @note this macro creates a new eigenclass if necessary.
265
293
 */
266
294
#define ENSURE_EIGENCLASS(klass) \
267
 
 (rb_ivar_get(METACLASS_OF(klass), id_attached) == klass ? METACLASS_OF(klass) : make_metaclass(klass))
 
295
 (rb_ivar_get(METACLASS_OF(klass), id_attached) == (klass) ? METACLASS_OF(klass) : make_metaclass(klass))
268
296
 
269
297
 
270
298
/*!
347
375
    rb_cModule = boot_defclass("Module", rb_cObject);
348
376
    rb_cClass =  boot_defclass("Class",  rb_cModule);
349
377
 
 
378
    rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
350
379
    RBASIC(rb_cClass)->klass
351
380
        = RBASIC(rb_cModule)->klass
352
381
        = RBASIC(rb_cObject)->klass
609
638
    if (!RCLASS_IV_TBL(module)) {
610
639
        RCLASS_IV_TBL(module) = st_init_numtable();
611
640
    }
 
641
    if (!RCLASS_CONST_TBL(module)) {
 
642
        RCLASS_CONST_TBL(module) = st_init_numtable();
 
643
    }
612
644
    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
 
645
    RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
613
646
    RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
614
647
    RCLASS_SUPER(klass) = super;
615
648
    if (TYPE(module) == T_ICLASS) {
663
696
            }
664
697
        }
665
698
        c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
666
 
        changed = 1;
 
699
        if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
 
700
            changed = 1;
667
701
      skip:
668
702
        module = RCLASS_SUPER(module);
669
703
    }
793
827
}
794
828
 
795
829
static int
796
 
ins_methods_i(ID name, long type, VALUE ary)
797
 
{
798
 
    return ins_methods_push(name, type, ary, -1); /* everything but private */
799
 
}
800
 
 
801
 
static int
802
 
ins_methods_prot_i(ID name, long type, VALUE ary)
803
 
{
804
 
    return ins_methods_push(name, type, ary, NOEX_PROTECTED);
805
 
}
806
 
 
807
 
static int
808
 
ins_methods_priv_i(ID name, long type, VALUE ary)
809
 
{
810
 
    return ins_methods_push(name, type, ary, NOEX_PRIVATE);
811
 
}
812
 
 
813
 
static int
814
 
ins_methods_pub_i(ID name, long type, VALUE ary)
815
 
{
816
 
    return ins_methods_push(name, type, ary, NOEX_PUBLIC);
817
 
}
818
 
 
819
 
static int
820
 
method_entry(ID key, const rb_method_entry_t *me, st_table *list)
821
 
{
 
830
ins_methods_i(st_data_t name, st_data_t type, st_data_t ary)
 
831
{
 
832
    return ins_methods_push((ID)name, (long)type, (VALUE)ary, -1); /* everything but private */
 
833
}
 
834
 
 
835
static int
 
836
ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary)
 
837
{
 
838
    return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED);
 
839
}
 
840
 
 
841
static int
 
842
ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary)
 
843
{
 
844
    return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE);
 
845
}
 
846
 
 
847
static int
 
848
ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary)
 
849
{
 
850
    return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC);
 
851
}
 
852
 
 
853
static int
 
854
method_entry_i(st_data_t key, st_data_t value, st_data_t data)
 
855
{
 
856
    const rb_method_entry_t *me = (const rb_method_entry_t *)value;
 
857
    st_table *list = (st_table *)data;
822
858
    long type;
823
859
 
824
 
    if (key == ID_ALLOCATOR) {
 
860
    if ((ID)key == ID_ALLOCATOR) {
825
861
        return ST_CONTINUE;
826
862
    }
827
863
 
838
874
}
839
875
 
840
876
static VALUE
841
 
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (ID, long, VALUE))
 
877
class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t))
842
878
{
843
879
    VALUE ary;
844
880
    int recur;
855
891
 
856
892
    list = st_init_numtable();
857
893
    for (; mod; mod = RCLASS_SUPER(mod)) {
858
 
        st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
 
894
        st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list);
859
895
        if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
860
896
        if (obj && FL_TEST(mod, FL_SINGLETON)) continue;
861
897
        if (!recur) break;
957
993
 *  call-seq:
958
994
 *     obj.methods    -> array
959
995
 *
960
 
 *  Returns a list of the names of methods publicly accessible in
 
996
 *  Returns a list of the names of public and protected methods of
961
997
 *  <i>obj</i>. This will include all the methods accessible in
962
998
 *  <i>obj</i>'s ancestors.
963
999
 *
964
1000
 *     class Klass
965
 
 *       def kMethod()
 
1001
 *       def klass_method()
966
1002
 *       end
967
1003
 *     end
968
1004
 *     k = Klass.new
969
 
 *     k.methods[0..9]    #=> [:kMethod, :freeze, :nil?, :is_a?,
970
 
 *                        #    :class, :instance_variable_set,
971
 
 *                        #    :methods, :extend, :__send__, :instance_eval]
972
 
 *     k.methods.length   #=> 42
 
1005
 *     k.methods[0..9]    #=> [:klass_method, :nil?, :===,
 
1006
 *                        #    :==~, :!, :eql?
 
1007
 *                        #    :hash, :<=>, :class, :singleton_class]
 
1008
 *     k.methods.length   #=> 57
973
1009
 */
974
1010
 
975
1011
VALUE
1087
1123
    klass = CLASS_OF(obj);
1088
1124
    list = st_init_numtable();
1089
1125
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
1090
 
        st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
 
1126
        st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
1091
1127
        klass = RCLASS_SUPER(klass);
1092
1128
    }
1093
1129
    if (RTEST(recur)) {
1094
1130
        while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
1095
 
            st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
 
1131
            st_foreach(RCLASS_M_TBL(klass), method_entry_i, (st_data_t)list);
1096
1132
            klass = RCLASS_SUPER(klass);
1097
1133
        }
1098
1134
    }
1200
1236
 
1201
1237
#define SPECIAL_SINGLETON(x,c) do {\
1202
1238
    if (obj == (x)) {\
1203
 
        return c;\
 
1239
        return (c);\
1204
1240
    }\
1205
1241
} while (0)
1206
1242
 
1226
1262
        SPECIAL_SINGLETON(Qnil, rb_cNilClass);
1227
1263
        SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
1228
1264
        SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
1229
 
        rb_bug("unknown immediate %ld", obj);
 
1265
        rb_bug("unknown immediate %p", (void *)obj);
1230
1266
    }
1231
1267
 
1232
1268
    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
1278
1314
    VALUE klass = singleton_class_of(obj);
1279
1315
 
1280
1316
    /* ensures an exposed class belongs to its own eigenclass */
1281
 
    if (TYPE(obj) == T_CLASS) ENSURE_EIGENCLASS(klass);
 
1317
    if (TYPE(obj) == T_CLASS) (void)ENSURE_EIGENCLASS(klass);
1282
1318
 
1283
1319
    return klass;
1284
1320
}
1379
1415
    const char *p = fmt;
1380
1416
    VALUE *var;
1381
1417
    va_list vargs;
1382
 
    int f_var = 0, f_block = 0;
 
1418
    int f_var = 0, f_hash = 0, f_block = 0;
1383
1419
    int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
1384
1420
    int argi = 0;
 
1421
    VALUE hash = Qnil;
1385
1422
 
1386
1423
    if (ISDIGIT(*p)) {
1387
1424
        n_lead = *p - '0';
1405
1442
        }
1406
1443
    }
1407
1444
  block_arg:
 
1445
    if (*p == ':') {
 
1446
        f_hash = 1;
 
1447
        p++;
 
1448
    }
1408
1449
    if (*p == '&') {
1409
1450
        f_block = 1;
1410
1451
        p++;
1419
1460
 
1420
1461
    va_start(vargs, fmt);
1421
1462
 
 
1463
    /* capture an option hash - phase 1: pop */
 
1464
    if (f_hash && n_mand < argc) {
 
1465
        VALUE last = argv[argc - 1];
 
1466
 
 
1467
        if (NIL_P(last)) {
 
1468
            /* nil is taken as an empty option hash only if it is not
 
1469
               ambiguous; i.e. '*' is not specified and arguments are
 
1470
               given more than sufficient */
 
1471
            if (!f_var && n_mand + n_opt < argc)
 
1472
                argc--;
 
1473
        }
 
1474
        else {
 
1475
            hash = rb_check_convert_type(last, T_HASH, "Hash", "to_hash");
 
1476
            if (!NIL_P(hash))
 
1477
                argc--;
 
1478
        }
 
1479
    }
1422
1480
    /* capture leading mandatory arguments */
1423
1481
    for (i = n_lead; i-- > 0; ) {
1424
1482
        var = va_arg(vargs, VALUE *);
1455
1513
        if (var) *var = argv[argi];
1456
1514
        argi++;
1457
1515
    }
 
1516
    /* capture an option hash - phase 2: assignment */
 
1517
    if (f_hash) {
 
1518
        var = va_arg(vargs, VALUE *);
 
1519
        if (var) *var = hash;
 
1520
    }
1458
1521
    /* capture iterator block */
1459
1522
    if (f_block) {
1460
1523
        var = va_arg(vargs, VALUE *);