~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to class.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
  class.c -
4
4
 
5
5
  $Author: matz $
6
 
  $Date: 2007-08-25 12:29:39 +0900 (土, 25  8月 2007) $
 
6
  $Date: 2007-10-11 22:20:14 +0900 (Thu, 11 Oct 2007) $
7
7
  created at: Tue Aug 10 15:05:44 JST 1993
8
8
 
9
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
18
18
 
19
19
extern st_table *rb_class_tbl;
20
20
 
 
21
static VALUE
 
22
class_alloc(VALUE flags, VALUE klass)
 
23
{
 
24
    rb_classext_t *ext = ALLOC(rb_classext_t);
 
25
    NEWOBJ(obj, struct RClass);
 
26
    OBJSETUP(obj, klass, flags);
 
27
    obj->ptr = ext;
 
28
    RCLASS_IV_TBL(obj) = 0;
 
29
    RCLASS_M_TBL(obj) = 0;
 
30
    RCLASS_SUPER(obj) = 0;
 
31
    RCLASS_IV_INDEX_TBL(obj) = 0;
 
32
    return (VALUE)obj;
 
33
}
 
34
 
21
35
VALUE
22
36
rb_class_boot(VALUE super)
23
37
{
24
 
    NEWOBJ(klass, struct RClass);
25
 
    OBJSETUP(klass, rb_cClass, T_CLASS);
 
38
    VALUE klass = class_alloc(T_CLASS, rb_cClass);
26
39
 
27
 
    klass->super = super;
28
 
    klass->iv_tbl = 0;
29
 
    klass->m_tbl = 0;           /* safe GC */
30
 
    klass->m_tbl = st_init_numtable();
 
40
    RCLASS_SUPER(klass) = super;
 
41
    RCLASS_M_TBL(klass) = st_init_numtable();
31
42
 
32
43
    OBJ_INFECT(klass, super);
33
44
    return (VALUE)klass;
87
98
    if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
88
99
        RBASIC(clone)->klass = rb_singleton_class_clone(orig);
89
100
    }
90
 
    RCLASS(clone)->super = RCLASS(orig)->super;
91
 
    if (RCLASS(orig)->iv_tbl) {
 
101
    RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
 
102
    if (RCLASS_IV_TBL(orig)) {
92
103
        ID id;
93
104
 
94
 
        RCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl);
 
105
        RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
95
106
        id = rb_intern("__classpath__");
96
 
        st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
 
107
        st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
97
108
        id = rb_intern("__classid__");
98
 
        st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
 
109
        st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
99
110
    }
100
 
    if (RCLASS(orig)->m_tbl) {
 
111
    if (RCLASS_M_TBL(orig)) {
101
112
        struct clone_method_data data;
102
 
        data.tbl = RCLASS(clone)->m_tbl = st_init_numtable();
 
113
        data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
103
114
        data.klass = clone;
104
 
        st_foreach(RCLASS(orig)->m_tbl, clone_method,
 
115
        st_foreach(RCLASS_M_TBL(orig), clone_method,
105
116
          (st_data_t)&data);
106
117
    }
107
118
 
112
123
VALUE
113
124
rb_class_init_copy(VALUE clone, VALUE orig)
114
125
{
115
 
    if (RCLASS(clone)->super != 0) {
 
126
    if (RCLASS_SUPER(clone) != 0) {
116
127
        rb_raise(rb_eTypeError, "already initialized class");
117
128
    }
118
129
    if (FL_TEST(orig, FL_SINGLETON)) {
131
142
    else {
132
143
        struct clone_method_data data;
133
144
        /* copy singleton(unnamed) class */
134
 
        NEWOBJ(clone, struct RClass);
135
 
        OBJSETUP(clone, 0, RBASIC(klass)->flags);
 
145
        VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
136
146
 
137
147
        if (BUILTIN_TYPE(obj) == T_CLASS) {
138
148
            RBASIC(clone)->klass = (VALUE)clone;
141
151
            RBASIC(clone)->klass = rb_singleton_class_clone(klass);
142
152
        }
143
153
 
144
 
        clone->super = RCLASS(klass)->super;
145
 
        clone->iv_tbl = 0;
146
 
        clone->m_tbl = 0;
147
 
        if (RCLASS(klass)->iv_tbl) {
148
 
            clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
 
154
        RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
 
155
        if (RCLASS_IV_TBL(klass)) {
 
156
            RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
149
157
        }
150
 
        clone->m_tbl = st_init_numtable();
151
 
        data.tbl = clone->m_tbl;
 
158
        RCLASS_M_TBL(clone) = st_init_numtable();
 
159
        data.tbl = RCLASS_M_TBL(clone);
152
160
        data.klass = (VALUE)clone;
153
 
        st_foreach(RCLASS(klass)->m_tbl, clone_method,
 
161
        st_foreach(RCLASS_M_TBL(klass), clone_method,
154
162
          (st_data_t)&data);
155
163
        rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
156
164
        FL_SET(clone, FL_SINGLETON);
162
170
rb_singleton_class_attached(VALUE klass, VALUE obj)
163
171
{
164
172
    if (FL_TEST(klass, FL_SINGLETON)) {
165
 
        if (!RCLASS(klass)->iv_tbl) {
166
 
            RCLASS(klass)->iv_tbl = st_init_numtable();
 
173
        if (!RCLASS_IV_TBL(klass)) {
 
174
            RCLASS_IV_TBL(klass) = st_init_numtable();
167
175
        }
168
 
        st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
 
176
        st_insert(RCLASS_IV_TBL(klass), rb_intern("__attached__"), obj);
169
177
    }
170
178
}
171
179
 
223
231
        if (TYPE(klass) != T_CLASS) {
224
232
            rb_raise(rb_eTypeError, "%s is not a class", name);
225
233
        }
226
 
        if (rb_class_real(RCLASS(klass)->super) != super) {
 
234
        if (rb_class_real(RCLASS_SUPER(klass)) != super) {
227
235
            rb_name_error(id, "%s is already defined", name);
228
236
        }
229
237
        return klass;
252
260
        if (TYPE(klass) != T_CLASS) {
253
261
            rb_raise(rb_eTypeError, "%s is not a class", name);
254
262
        }
255
 
        if (rb_class_real(RCLASS(klass)->super) != super) {
 
263
        if (rb_class_real(RCLASS_SUPER(klass)) != super) {
256
264
            rb_name_error(id, "%s is already defined", name);
257
265
        }
258
266
        return klass;
272
280
VALUE
273
281
rb_module_new(void)
274
282
{
275
 
    NEWOBJ(mdl, struct RClass);
276
 
    OBJSETUP(mdl, rb_cModule, T_MODULE);
 
283
    VALUE mdl = class_alloc(T_MODULE, rb_cModule);
277
284
 
278
 
    mdl->super = 0;
279
 
    mdl->iv_tbl = 0;
280
 
    mdl->m_tbl = 0;
281
 
    mdl->m_tbl = st_init_numtable();
 
285
    RCLASS_M_TBL(mdl) = st_init_numtable();
282
286
 
283
287
    return (VALUE)mdl;
284
288
}
338
342
static VALUE
339
343
include_class_new(VALUE module, VALUE super)
340
344
{
341
 
    NEWOBJ(klass, struct RClass);
342
 
    OBJSETUP(klass, rb_cClass, T_ICLASS);
 
345
    VALUE klass = class_alloc(T_ICLASS, rb_cClass);
343
346
 
344
347
    if (BUILTIN_TYPE(module) == T_ICLASS) {
345
348
        module = RBASIC(module)->klass;
346
349
    }
347
 
    if (!RCLASS(module)->iv_tbl) {
348
 
        RCLASS(module)->iv_tbl = st_init_numtable();
 
350
    if (!RCLASS_IV_TBL(module)) {
 
351
        RCLASS_IV_TBL(module) = st_init_numtable();
349
352
    }
350
 
    klass->iv_tbl = RCLASS(module)->iv_tbl;
351
 
    klass->m_tbl = RCLASS(module)->m_tbl;
352
 
    klass->super = super;
 
353
    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
 
354
    RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
 
355
    RCLASS_SUPER(klass) = super;
353
356
    if (TYPE(module) == T_ICLASS) {
354
357
        RBASIC(klass)->klass = RBASIC(module)->klass;
355
358
    }
382
385
    while (module) {
383
386
       int superclass_seen = Qfalse;
384
387
 
385
 
        if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
 
388
        if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
386
389
            rb_raise(rb_eArgError, "cyclic include detected");
387
390
       /* ignore if the module included already in superclasses */
388
 
       for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
 
391
       for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
389
392
           switch (BUILTIN_TYPE(p)) {
390
393
             case T_ICLASS:
391
 
               if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
 
394
               if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
392
395
                   if (!superclass_seen) {
393
396
                       c = p;  /* move insertion point */
394
397
                   }
400
403
               break;
401
404
           }
402
405
       }
403
 
       c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
 
406
       c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
404
407
        changed = 1;
405
408
      skip:
406
 
        module = RCLASS(module)->super;
 
409
        module = RCLASS_SUPER(module);
407
410
    }
408
411
    if (changed) rb_clear_cache();
409
412
}
431
434
    VALUE ary = rb_ary_new();
432
435
    VALUE p;
433
436
 
434
 
    for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
 
437
    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
435
438
        if (BUILTIN_TYPE(p) == T_ICLASS) {
436
439
            rb_ary_push(ary, RBASIC(p)->klass);
437
440
        }
464
467
    VALUE p;
465
468
 
466
469
    Check_Type(mod2, T_MODULE);
467
 
    for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
 
470
    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
468
471
        if (BUILTIN_TYPE(p) == T_ICLASS) {
469
472
            if (RBASIC(p)->klass == mod2) return Qtrue;
470
473
        }
493
496
{
494
497
    VALUE p, ary = rb_ary_new();
495
498
 
496
 
    for (p = mod; p; p = RCLASS(p)->super) {
 
499
    for (p = mod; p; p = RCLASS_SUPER(p)) {
497
500
        if (FL_TEST(p, FL_SINGLETON))
498
501
            continue;
499
502
        if (BUILTIN_TYPE(p) == T_ICLASS) {
518
521
      case NOEX_PRIVATE:
519
522
      case NOEX_PROTECTED:
520
523
      case NOEX_PUBLIC:
521
 
      case NOEX_LOCAL:
522
524
        visi = (type == visi);
523
525
        break;
524
526
      default:
556
558
}
557
559
 
558
560
static int
559
 
ins_methods_local_i(ID name, long type, VALUE ary)
560
 
{
561
 
    return ins_methods_push(name, type, ary, NOEX_LOCAL);
562
 
}
563
 
 
564
 
static int
565
561
method_entry(ID key, NODE *body, st_table *list)
566
562
{
567
563
    long type;
599
595
    }
600
596
 
601
597
    list = st_init_numtable();
602
 
    for (; mod; mod = RCLASS(mod)->super) {
603
 
        st_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);
 
598
    for (; mod; mod = RCLASS_SUPER(mod)) {
 
599
        st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
604
600
        if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
605
601
        if (FL_TEST(mod, FL_SINGLETON)) continue;
606
602
        if (!recur) break;
700
696
 
701
697
/*
702
698
 *  call-seq:
703
 
 *     mod.local_methods   => array
704
 
 *  
705
 
 *  Returns a list of the local methods defined in <i>mod</i>.
706
 
 */
707
 
 
708
 
VALUE
709
 
rb_class_local_methods(VALUE mod)
710
 
{
711
 
    return class_instance_method_list(0, 0, mod, ins_methods_local_i);
712
 
}
713
 
 
714
 
/*
715
 
 *  call-seq:
716
699
 *     obj.singleton_methods(all=true)    => array
717
700
 *  
718
701
 *  Returns an array of the names of singleton methods for <i>obj</i>.
756
739
    klass = CLASS_OF(obj);
757
740
    list = st_init_numtable();
758
741
    if (klass && FL_TEST(klass, FL_SINGLETON)) {
759
 
        st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
760
 
        klass = RCLASS(klass)->super;
 
742
        st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
 
743
        klass = RCLASS_SUPER(klass);
761
744
    }
762
745
    if (RTEST(recur)) {
763
746
        while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
764
 
            st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
765
 
            klass = RCLASS(klass)->super;
 
747
            st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
 
748
            klass = RCLASS_SUPER(klass);
766
749
        }
767
750
    }
768
751
    ary = rb_ary_new();