28
28
#include "method.h"
29
29
#include "constant.h"
30
30
#include "vm_core.h"
31
+ #include "vm_insnhelper.h"
31
32
#include "internal.h"
32
33
#include <ctype.h>
33
34
34
35
extern st_table * rb_class_tbl ;
35
36
static ID id_attached ;
36
37
38
+ static void
39
+ rb_class_subclass_add (VALUE super , VALUE klass )
40
+ {
41
+ rb_subclass_entry_t * entry , * head ;
42
+
43
+ if (super && super != Qundef ) {
44
+ entry = malloc (sizeof (rb_subclass_entry_t ));
45
+ entry -> klass = klass ;
46
+ entry -> next = NULL ;
47
+
48
+ head = RCLASS_SUBCLASSES (super );
49
+ if (head ) {
50
+ entry -> next = head ;
51
+ RCLASS_PARENT_SUBCLASSES (head -> klass ) = & entry -> next ;
52
+ }
53
+
54
+ RCLASS_SUBCLASSES (super ) = entry ;
55
+ RCLASS_PARENT_SUBCLASSES (klass ) = & RCLASS_SUBCLASSES (super );
56
+ }
57
+ }
58
+
59
+ static void
60
+ rb_module_add_to_subclasses_list (VALUE module , VALUE iclass )
61
+ {
62
+ rb_subclass_entry_t * entry , * head ;
63
+
64
+ entry = malloc (sizeof (rb_subclass_entry_t ));
65
+ entry -> klass = iclass ;
66
+ entry -> next = NULL ;
67
+
68
+ head = RCLASS_SUBCLASSES (module );
69
+ if (head ) {
70
+ entry -> next = head ;
71
+ RCLASS_MODULE_SUBCLASSES (head -> klass ) = & entry -> next ;
72
+ }
73
+
74
+ RCLASS_SUBCLASSES (module ) = entry ;
75
+ RCLASS_MODULE_SUBCLASSES (iclass ) = & RCLASS_SUBCLASSES (module );
76
+ }
77
+
78
+ void
79
+ rb_class_remove_from_super_subclasses (VALUE klass )
80
+ {
81
+ rb_subclass_entry_t * entry ;
82
+
83
+
84
+ if (RCLASS_PARENT_SUBCLASSES (klass )) {
85
+ entry = * RCLASS_PARENT_SUBCLASSES (klass );
86
+
87
+ * RCLASS_PARENT_SUBCLASSES (klass ) = entry -> next ;
88
+ if (entry -> next ) {
89
+ RCLASS_PARENT_SUBCLASSES (entry -> next -> klass ) = RCLASS_PARENT_SUBCLASSES (klass );
90
+ }
91
+ free (entry );
92
+ }
93
+
94
+ RCLASS_PARENT_SUBCLASSES (klass ) = NULL ;
95
+ }
96
+
97
+ void
98
+ rb_class_remove_from_module_subclasses (VALUE klass )
99
+ {
100
+ rb_subclass_entry_t * entry ;
101
+
102
+ if (RCLASS_MODULE_SUBCLASSES (klass )) {
103
+ entry = * RCLASS_MODULE_SUBCLASSES (klass );
104
+ * RCLASS_MODULE_SUBCLASSES (klass ) = entry -> next ;
105
+ if (entry -> next ) {
106
+ RCLASS_MODULE_SUBCLASSES (entry -> next -> klass ) = RCLASS_MODULE_SUBCLASSES (klass );
107
+ }
108
+ free (entry );
109
+ }
110
+
111
+ RCLASS_MODULE_SUBCLASSES (klass ) = NULL ;
112
+ }
113
+
114
+ static int
115
+ rb_class_foreach_iter_wrapper (st_data_t key , st_data_t unused , st_data_t rf )
116
+ {
117
+ int (* f )(VALUE );
118
+
119
+ f = (int (* )(VALUE )) rf ;
120
+ return f ((VALUE )key );
121
+ }
122
+
123
+ void
124
+ rb_class_foreach_subclass (VALUE klass , void (* f )(VALUE ))
125
+ {
126
+ rb_subclass_entry_t * cur ;
127
+ VALUE curklass ;
128
+
129
+ cur = RCLASS_SUBCLASSES (klass );
130
+ while (cur )
131
+ {
132
+ curklass = cur -> klass ;
133
+ cur = cur -> next ;
134
+ f (curklass );
135
+ }
136
+ }
137
+
138
+ VALUE
139
+ rb_class_set_superclass (VALUE klass , VALUE super )
140
+ {
141
+ rb_class_remove_from_super_subclasses (klass );
142
+
143
+ rb_class_subclass_add (super , klass );
144
+ RCLASS_SUPER (klass ) = super ;
145
+
146
+ return super ;
147
+ }
148
+
149
+ void
150
+ rb_class_detatch_subclasses (VALUE klass )
151
+ {
152
+ rb_class_foreach_subclass (klass , rb_class_remove_from_super_subclasses );
153
+ }
154
+
155
+ void
156
+ rb_class_detatch_module_subclasses (VALUE klass )
157
+ {
158
+ rb_class_foreach_subclass (klass , rb_class_remove_from_module_subclasses );
159
+ }
160
+
37
161
/**
38
162
* Allocates a struct RClass for a new class.
39
163
*
@@ -58,6 +182,13 @@ class_alloc(VALUE flags, VALUE klass)
58
182
RCLASS_M_TBL (obj ) = 0 ;
59
183
RCLASS_SUPER (obj ) = 0 ;
60
184
RCLASS_IV_INDEX_TBL (obj ) = 0 ;
185
+ RCLASS_SUBCLASSES (obj ) = NULL ;
186
+ RCLASS_PARENT_SUBCLASSES (obj ) = NULL ;
187
+ RCLASS_MODULE_SUBCLASSES (obj ) = NULL ;
188
+ RCLASS_SEQ (obj ) = rb_next_seq ();
189
+ RCLASS_ICLASSTARGET (obj ) = 0 ;
190
+ RCLASS_MC_TBL (obj ) = NULL ;
191
+
61
192
return (VALUE )obj ;
62
193
}
63
194
@@ -76,7 +207,7 @@ rb_class_boot(VALUE super)
76
207
{
77
208
VALUE klass = class_alloc (T_CLASS , rb_cClass );
78
209
79
- RCLASS_SUPER (klass ) = super ;
210
+ rb_class_set_superclass (klass , super ) ;
80
211
RCLASS_M_TBL (klass ) = st_init_numtable ();
81
212
82
213
OBJ_INFECT (klass , super );
@@ -168,7 +299,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
168
299
RBASIC (clone )-> klass = rb_singleton_class_clone (orig );
169
300
rb_singleton_class_attached (RBASIC (clone )-> klass , (VALUE )clone );
170
301
}
171
- RCLASS_SUPER (clone ) = RCLASS_SUPER (orig );
302
+ rb_class_set_superclass (clone , RCLASS_SUPER (orig ) );
172
303
if (RCLASS_IV_TBL (orig )) {
173
304
st_data_t id ;
174
305
@@ -238,7 +369,7 @@ rb_singleton_class_clone(VALUE obj)
238
369
RBASIC (clone )-> klass = rb_singleton_class_clone (klass );
239
370
}
240
371
241
- RCLASS_SUPER (clone ) = RCLASS_SUPER (klass );
372
+ rb_class_set_superclass (clone , RCLASS_SUPER (klass ) );
242
373
if (RCLASS_IV_TBL (klass )) {
243
374
RCLASS_IV_TBL (clone ) = st_copy (RCLASS_IV_TBL (klass ));
244
375
}
@@ -324,7 +455,7 @@ make_metaclass(VALUE klass)
324
455
325
456
super = RCLASS_SUPER (klass );
326
457
while (RB_TYPE_P (super , T_ICLASS )) super = RCLASS_SUPER (super );
327
- RCLASS_SUPER (metaclass ) = super ? ENSURE_EIGENCLASS (super ) : rb_cClass ;
458
+ rb_class_set_superclass (metaclass , super ? ENSURE_EIGENCLASS (super ) : rb_cClass ) ;
328
459
329
460
OBJ_INFECT (metaclass , RCLASS_SUPER (metaclass ));
330
461
@@ -644,13 +775,14 @@ include_class_new(VALUE module, VALUE super)
644
775
RCLASS_IV_TBL (klass ) = RCLASS_IV_TBL (module );
645
776
RCLASS_CONST_TBL (klass ) = RCLASS_CONST_TBL (module );
646
777
RCLASS_M_TBL (klass ) = RCLASS_M_TBL (module );
647
- RCLASS_SUPER (klass ) = super ;
778
+ rb_class_set_superclass (klass , super ) ;
648
779
if (TYPE (module ) == T_ICLASS ) {
649
780
RBASIC (klass )-> klass = RBASIC (module )-> klass ;
650
781
}
651
782
else {
652
783
RBASIC (klass )-> klass = module ;
653
784
}
785
+
654
786
OBJ_INFECT (klass , module );
655
787
OBJ_INFECT (klass , super );
656
788
@@ -660,7 +792,7 @@ include_class_new(VALUE module, VALUE super)
660
792
void
661
793
rb_include_module (VALUE klass , VALUE module )
662
794
{
663
- VALUE p , c ;
795
+ VALUE p , c , iclass ;
664
796
int changed = 0 ;
665
797
666
798
rb_frozen_class_p (klass );
@@ -695,13 +827,26 @@ rb_include_module(VALUE klass, VALUE module)
695
827
break ;
696
828
}
697
829
}
698
- c = RCLASS_SUPER (c ) = include_class_new (module , RCLASS_SUPER (c ));
830
+ iclass = include_class_new (module , RCLASS_SUPER (c ));
831
+ RCLASS_ICLASSTARGET (iclass ) = klass ;
832
+
833
+ c = rb_class_set_superclass (c , iclass );
834
+
835
+ if (BUILTIN_TYPE (module ) == T_ICLASS ) {
836
+ rb_module_add_to_subclasses_list (RBASIC (module )-> klass , iclass );
837
+ } else {
838
+ rb_module_add_to_subclasses_list (module , iclass );
839
+ }
840
+
699
841
if (RMODULE_M_TBL (module ) && RMODULE_M_TBL (module )-> num_entries )
700
842
changed = 1 ;
701
843
skip :
702
844
module = RCLASS_SUPER (module );
703
845
}
704
- if (changed ) rb_clear_cache ();
846
+ if (changed ) {
847
+ rb_clear_method_cache_by_class (klass );
848
+ rb_clear_constant_cache ();
849
+ }
705
850
}
706
851
707
852
/*
0 commit comments