annotate libobjc/gc.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Basic data types for Objective C.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Ovidiu Predescu.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
10 any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
15 GNU General Public License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
18 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
19 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
22 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
24 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 #include "objc-private/common.h"
kono
parents:
diff changeset
27 #include "objc/objc.h"
kono
parents:
diff changeset
28
kono
parents:
diff changeset
29 #if OBJC_WITH_GC
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 #include "tconfig.h"
kono
parents:
diff changeset
32 #include <assert.h>
kono
parents:
diff changeset
33 #include <ctype.h> /* For isdigit. */
kono
parents:
diff changeset
34 #include <string.h>
kono
parents:
diff changeset
35 #include <stdlib.h>
kono
parents:
diff changeset
36 #include "objc/runtime.h"
kono
parents:
diff changeset
37 #include "objc-private/module-abi-8.h"
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 #include <gc/gc.h>
kono
parents:
diff changeset
40 #include <limits.h>
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 /* gc_typed.h uses the following but doesn't declare them */
kono
parents:
diff changeset
43 typedef GC_word word;
kono
parents:
diff changeset
44 typedef GC_signed_word signed_word;
kono
parents:
diff changeset
45 #define BITS_PER_WORD (CHAR_BIT * sizeof (word))
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 #include <gc/gc_typed.h>
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 /* The following functions set up in `mask` the corresponding pointers.
kono
parents:
diff changeset
50 The offset is incremented with the size of the type. */
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 #define ROUND(V, A) \
kono
parents:
diff changeset
53 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
kono
parents:
diff changeset
54 __a * ((__v+__a - 1)/__a); })
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 #define SET_BIT_FOR_OFFSET(mask, offset) \
kono
parents:
diff changeset
57 GC_set_bit (mask, offset / sizeof (void *))
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /* Some prototypes */
kono
parents:
diff changeset
60 static void
kono
parents:
diff changeset
61 __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
kono
parents:
diff changeset
62 static void
kono
parents:
diff changeset
63 __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 static void
kono
parents:
diff changeset
67 __objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
kono
parents:
diff changeset
68 {
kono
parents:
diff changeset
69 int i, len = atoi (type + 1);
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 while (isdigit (*++type))
kono
parents:
diff changeset
72 /* do nothing */; /* skip the size of the array */
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 switch (*type) {
kono
parents:
diff changeset
75 case _C_ARY_B:
kono
parents:
diff changeset
76 for (i = 0; i < len; i++)
kono
parents:
diff changeset
77 __objc_gc_setup_array (mask, type, offset);
kono
parents:
diff changeset
78 break;
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 case _C_STRUCT_B:
kono
parents:
diff changeset
81 for (i = 0; i < len; i++)
kono
parents:
diff changeset
82 __objc_gc_setup_struct (mask, type, offset);
kono
parents:
diff changeset
83 break;
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 case _C_UNION_B:
kono
parents:
diff changeset
86 for (i = 0; i < len; i++)
kono
parents:
diff changeset
87 __objc_gc_setup_union (mask, type, offset);
kono
parents:
diff changeset
88 break;
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 default:
kono
parents:
diff changeset
91 break;
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93 }
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 static void
kono
parents:
diff changeset
96 __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
kono
parents:
diff changeset
97 {
kono
parents:
diff changeset
98 struct objc_struct_layout layout;
kono
parents:
diff changeset
99 unsigned int position;
kono
parents:
diff changeset
100 const char *mtype;
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 objc_layout_structure (type, &layout);
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 while (objc_layout_structure_next_member (&layout))
kono
parents:
diff changeset
105 {
kono
parents:
diff changeset
106 BOOL gc_invisible = NO;
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 /* Skip the variable name */
kono
parents:
diff changeset
111 if (*mtype == '"')
kono
parents:
diff changeset
112 {
kono
parents:
diff changeset
113 for (mtype++; *mtype++ != '"';)
kono
parents:
diff changeset
114 /* do nothing */;
kono
parents:
diff changeset
115 }
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 if (*mtype == _C_GCINVISIBLE)
kono
parents:
diff changeset
118 {
kono
parents:
diff changeset
119 gc_invisible = YES;
kono
parents:
diff changeset
120 mtype++;
kono
parents:
diff changeset
121 }
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 /* Add to position the offset of this structure */
kono
parents:
diff changeset
124 position += offset;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 switch (*mtype) {
kono
parents:
diff changeset
127 case _C_ID:
kono
parents:
diff changeset
128 case _C_CLASS:
kono
parents:
diff changeset
129 case _C_SEL:
kono
parents:
diff changeset
130 case _C_PTR:
kono
parents:
diff changeset
131 case _C_CHARPTR:
kono
parents:
diff changeset
132 case _C_ATOM:
kono
parents:
diff changeset
133 if (! gc_invisible)
kono
parents:
diff changeset
134 SET_BIT_FOR_OFFSET (mask, position);
kono
parents:
diff changeset
135 break;
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 case _C_ARY_B:
kono
parents:
diff changeset
138 __objc_gc_setup_array (mask, mtype, position);
kono
parents:
diff changeset
139 break;
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 case _C_STRUCT_B:
kono
parents:
diff changeset
142 __objc_gc_setup_struct (mask, mtype, position);
kono
parents:
diff changeset
143 break;
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 case _C_UNION_B:
kono
parents:
diff changeset
146 __objc_gc_setup_union (mask, mtype, position);
kono
parents:
diff changeset
147 break;
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 default:
kono
parents:
diff changeset
150 break;
kono
parents:
diff changeset
151 }
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153 }
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 static void
kono
parents:
diff changeset
156 __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
kono
parents:
diff changeset
157 {
kono
parents:
diff changeset
158 /* Sub-optimal, quick implementation: assume the union is made of
kono
parents:
diff changeset
159 pointers, set up the mask accordingly. */
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 int i, size, align;
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 /* Skip the variable name */
kono
parents:
diff changeset
164 if (*type == '"')
kono
parents:
diff changeset
165 {
kono
parents:
diff changeset
166 for (type++; *type++ != '"';)
kono
parents:
diff changeset
167 /* do nothing */;
kono
parents:
diff changeset
168 }
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 size = objc_sizeof_type (type);
kono
parents:
diff changeset
171 align = objc_alignof_type (type);
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 offset = ROUND (offset, align);
kono
parents:
diff changeset
174 for (i = 0; i < size; i += sizeof (void *))
kono
parents:
diff changeset
175 {
kono
parents:
diff changeset
176 SET_BIT_FOR_OFFSET (mask, offset);
kono
parents:
diff changeset
177 offset += sizeof (void *);
kono
parents:
diff changeset
178 }
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 /* Iterates over the types in the structure that represents the class
kono
parents:
diff changeset
183 encoding and sets the bits in mask according to each ivar type. */
kono
parents:
diff changeset
184 static void
kono
parents:
diff changeset
185 __objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
kono
parents:
diff changeset
186 {
kono
parents:
diff changeset
187 struct objc_struct_layout layout;
kono
parents:
diff changeset
188 unsigned int offset, align;
kono
parents:
diff changeset
189 const char *ivar_type;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 objc_layout_structure (type, &layout);
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 while (objc_layout_structure_next_member (&layout))
kono
parents:
diff changeset
194 {
kono
parents:
diff changeset
195 BOOL gc_invisible = NO;
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 /* Skip the variable name */
kono
parents:
diff changeset
200 if (*ivar_type == '"')
kono
parents:
diff changeset
201 {
kono
parents:
diff changeset
202 for (ivar_type++; *ivar_type++ != '"';)
kono
parents:
diff changeset
203 /* do nothing */;
kono
parents:
diff changeset
204 }
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 if (*ivar_type == _C_GCINVISIBLE)
kono
parents:
diff changeset
207 {
kono
parents:
diff changeset
208 gc_invisible = YES;
kono
parents:
diff changeset
209 ivar_type++;
kono
parents:
diff changeset
210 }
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 switch (*ivar_type) {
kono
parents:
diff changeset
213 case _C_ID:
kono
parents:
diff changeset
214 case _C_CLASS:
kono
parents:
diff changeset
215 case _C_SEL:
kono
parents:
diff changeset
216 case _C_PTR:
kono
parents:
diff changeset
217 case _C_CHARPTR:
kono
parents:
diff changeset
218 if (! gc_invisible)
kono
parents:
diff changeset
219 SET_BIT_FOR_OFFSET (mask, offset);
kono
parents:
diff changeset
220 break;
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 case _C_ARY_B:
kono
parents:
diff changeset
223 __objc_gc_setup_array (mask, ivar_type, offset);
kono
parents:
diff changeset
224 break;
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 case _C_STRUCT_B:
kono
parents:
diff changeset
227 __objc_gc_setup_struct (mask, ivar_type, offset);
kono
parents:
diff changeset
228 break;
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 case _C_UNION_B:
kono
parents:
diff changeset
231 __objc_gc_setup_union (mask, ivar_type, offset);
kono
parents:
diff changeset
232 break;
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 default:
kono
parents:
diff changeset
235 break;
kono
parents:
diff changeset
236 }
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238 }
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 /* Computes in *type the full type encoding of this class including
kono
parents:
diff changeset
241 its super classes. '*size' gives the total number of bytes allocated
kono
parents:
diff changeset
242 into *type, '*current' the number of bytes used so far by the
kono
parents:
diff changeset
243 encoding. */
kono
parents:
diff changeset
244 static void
kono
parents:
diff changeset
245 __objc_class_structure_encoding (Class class, char **type, int *size,
kono
parents:
diff changeset
246 int *current)
kono
parents:
diff changeset
247 {
kono
parents:
diff changeset
248 int i, ivar_count;
kono
parents:
diff changeset
249 struct objc_ivar_list *ivars;
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 if (! class)
kono
parents:
diff changeset
252 {
kono
parents:
diff changeset
253 strcat (*type, "{");
kono
parents:
diff changeset
254 (*current)++;
kono
parents:
diff changeset
255 return;
kono
parents:
diff changeset
256 }
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 /* Add the type encodings of the super classes */
kono
parents:
diff changeset
259 __objc_class_structure_encoding (class->super_class, type, size, current);
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 ivars = class->ivars;
kono
parents:
diff changeset
262 if (! ivars)
kono
parents:
diff changeset
263 return;
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 ivar_count = ivars->ivar_count;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 for (i = 0; i < ivar_count; i++)
kono
parents:
diff changeset
268 {
kono
parents:
diff changeset
269 struct objc_ivar *ivar = &(ivars->ivar_list[i]);
kono
parents:
diff changeset
270 const char *ivar_type = ivar->ivar_type;
kono
parents:
diff changeset
271 int len = strlen (ivar_type);
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 if (*current + len + 1 >= *size)
kono
parents:
diff changeset
274 {
kono
parents:
diff changeset
275 /* Increase the size of the encoding string so that it
kono
parents:
diff changeset
276 contains this ivar's type. */
kono
parents:
diff changeset
277 *size = ROUND (*current + len + 1, 10);
kono
parents:
diff changeset
278 *type = objc_realloc (*type, *size);
kono
parents:
diff changeset
279 }
kono
parents:
diff changeset
280 strcat (*type + *current, ivar_type);
kono
parents:
diff changeset
281 *current += len;
kono
parents:
diff changeset
282 }
kono
parents:
diff changeset
283 }
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 /* Allocates the memory that will hold the type description for class
kono
parents:
diff changeset
287 and calls the __objc_class_structure_encoding that generates this
kono
parents:
diff changeset
288 value. */
kono
parents:
diff changeset
289 void
kono
parents:
diff changeset
290 __objc_generate_gc_type_description (Class class)
kono
parents:
diff changeset
291 {
kono
parents:
diff changeset
292 GC_bitmap mask;
kono
parents:
diff changeset
293 int bits_no, size;
kono
parents:
diff changeset
294 int type_size = 10, current;
kono
parents:
diff changeset
295 char *class_structure_type;
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 if (! CLS_ISCLASS (class))
kono
parents:
diff changeset
298 return;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 /* We have to create a mask in which each bit counts for a pointer member.
kono
parents:
diff changeset
301 We take into consideration all the non-pointer instance variables and we
kono
parents:
diff changeset
302 round them up to the alignment. */
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 /* The number of bits in the mask is the size of an instance in bytes divided
kono
parents:
diff changeset
305 by the size of a pointer. */
kono
parents:
diff changeset
306 bits_no = (ROUND (class_getInstanceSize (class), sizeof (void *))
kono
parents:
diff changeset
307 / sizeof (void *));
kono
parents:
diff changeset
308 size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
kono
parents:
diff changeset
309 mask = objc_atomic_malloc (size * sizeof (int));
kono
parents:
diff changeset
310 memset (mask, 0, size * sizeof (int));
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 class_structure_type = objc_atomic_malloc (type_size);
kono
parents:
diff changeset
313 *class_structure_type = current = 0;
kono
parents:
diff changeset
314 __objc_class_structure_encoding (class, &class_structure_type,
kono
parents:
diff changeset
315 &type_size, &current);
kono
parents:
diff changeset
316 if (current + 1 == type_size)
kono
parents:
diff changeset
317 class_structure_type = objc_realloc (class_structure_type, ++type_size);
kono
parents:
diff changeset
318 strcat (class_structure_type + current, "}");
kono
parents:
diff changeset
319 #ifdef DEBUG
kono
parents:
diff changeset
320 printf ("type description for '%s' is %s\n", class->name, class_structure_type);
kono
parents:
diff changeset
321 #endif
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 __objc_gc_type_description_from_type (mask, class_structure_type);
kono
parents:
diff changeset
324 objc_free (class_structure_type);
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 #ifdef DEBUG
kono
parents:
diff changeset
327 printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
kono
parents:
diff changeset
328 class_structure_type, class->name, bits_no, size);
kono
parents:
diff changeset
329 {
kono
parents:
diff changeset
330 int i;
kono
parents:
diff changeset
331 for (i = 0; i < size; i++)
kono
parents:
diff changeset
332 printf (" %lx", mask[i]);
kono
parents:
diff changeset
333 }
kono
parents:
diff changeset
334 puts ("");
kono
parents:
diff changeset
335 #endif
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no);
kono
parents:
diff changeset
338 }
kono
parents:
diff changeset
339
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 /* Returns YES if type denotes a pointer type, NO otherwise */
kono
parents:
diff changeset
342 static inline BOOL
kono
parents:
diff changeset
343 __objc_ivar_pointer (const char *type)
kono
parents:
diff changeset
344 {
kono
parents:
diff changeset
345 type = objc_skip_type_qualifiers (type);
kono
parents:
diff changeset
346
kono
parents:
diff changeset
347 return (*type == _C_ID
kono
parents:
diff changeset
348 || *type == _C_CLASS
kono
parents:
diff changeset
349 || *type == _C_SEL
kono
parents:
diff changeset
350 || *type == _C_PTR
kono
parents:
diff changeset
351 || *type == _C_CHARPTR
kono
parents:
diff changeset
352 || *type == _C_ATOM);
kono
parents:
diff changeset
353 }
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 /* Mark the instance variable whose name is given by ivarname as a
kono
parents:
diff changeset
357 weak pointer (a pointer hidden to the garbage collector) if
kono
parents:
diff changeset
358 gc_invisible is true. If gc_invisible is false it unmarks the
kono
parents:
diff changeset
359 instance variable and makes it a normal pointer, visible to the
kono
parents:
diff changeset
360 garbage collector.
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 This operation only makes sense on instance variables that are
kono
parents:
diff changeset
363 pointers. */
kono
parents:
diff changeset
364 void
kono
parents:
diff changeset
365 class_ivar_set_gcinvisible (Class class, const char *ivarname,
kono
parents:
diff changeset
366 BOOL gc_invisible)
kono
parents:
diff changeset
367 {
kono
parents:
diff changeset
368 int i, ivar_count;
kono
parents:
diff changeset
369 struct objc_ivar_list *ivars;
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 if (! class || ! ivarname)
kono
parents:
diff changeset
372 return;
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 ivars = class->ivars;
kono
parents:
diff changeset
375 if (! ivars)
kono
parents:
diff changeset
376 return;
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 ivar_count = ivars->ivar_count;
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 for (i = 0; i < ivar_count; i++)
kono
parents:
diff changeset
381 {
kono
parents:
diff changeset
382 struct objc_ivar *ivar = &(ivars->ivar_list[i]);
kono
parents:
diff changeset
383 const char *type;
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
kono
parents:
diff changeset
386 continue;
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 assert (ivar->ivar_type);
kono
parents:
diff changeset
389 type = ivar->ivar_type;
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 /* Skip the variable name */
kono
parents:
diff changeset
392 if (*type == '"')
kono
parents:
diff changeset
393 {
kono
parents:
diff changeset
394 for (type++; *type++ != '"';)
kono
parents:
diff changeset
395 /* do nothing */;
kono
parents:
diff changeset
396 }
kono
parents:
diff changeset
397
kono
parents:
diff changeset
398 if (*type == _C_GCINVISIBLE)
kono
parents:
diff changeset
399 {
kono
parents:
diff changeset
400 char *new_type;
kono
parents:
diff changeset
401 size_t len;
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 if (gc_invisible || ! __objc_ivar_pointer (type))
kono
parents:
diff changeset
404 return; /* The type of the variable already matches the
kono
parents:
diff changeset
405 requested gc_invisible type */
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 /* The variable is gc_invisible so we make it gc visible. */
kono
parents:
diff changeset
408 new_type = objc_atomic_malloc (strlen(ivar->ivar_type));
kono
parents:
diff changeset
409 len = (type - ivar->ivar_type);
kono
parents:
diff changeset
410 memcpy (new_type, ivar->ivar_type, len);
kono
parents:
diff changeset
411 new_type[len] = 0;
kono
parents:
diff changeset
412 strcat (new_type, type + 1);
kono
parents:
diff changeset
413 ivar->ivar_type = new_type;
kono
parents:
diff changeset
414 }
kono
parents:
diff changeset
415 else
kono
parents:
diff changeset
416 {
kono
parents:
diff changeset
417 char *new_type;
kono
parents:
diff changeset
418 size_t len;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 if (! gc_invisible || ! __objc_ivar_pointer (type))
kono
parents:
diff changeset
421 return; /* The type of the variable already matches the
kono
parents:
diff changeset
422 requested gc_invisible type */
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 /* The variable is gc visible so we make it gc_invisible. */
kono
parents:
diff changeset
425 new_type = objc_malloc (strlen(ivar->ivar_type) + 2);
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 /* Copy the variable name. */
kono
parents:
diff changeset
428 len = (type - ivar->ivar_type);
kono
parents:
diff changeset
429 memcpy (new_type, ivar->ivar_type, len);
kono
parents:
diff changeset
430 /* Add '!'. */
kono
parents:
diff changeset
431 new_type[len++] = _C_GCINVISIBLE;
kono
parents:
diff changeset
432 /* Copy the original types. */
kono
parents:
diff changeset
433 strcpy (new_type + len, type);
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 ivar->ivar_type = new_type;
kono
parents:
diff changeset
436 }
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 __objc_generate_gc_type_description (class);
kono
parents:
diff changeset
439 return;
kono
parents:
diff changeset
440 }
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 /* Search the instance variable in the superclasses */
kono
parents:
diff changeset
443 class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
kono
parents:
diff changeset
444 }
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 #else /* !OBJC_WITH_GC */
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 void
kono
parents:
diff changeset
449 __objc_generate_gc_type_description (Class class __attribute__ ((__unused__)))
kono
parents:
diff changeset
450 {
kono
parents:
diff changeset
451 }
kono
parents:
diff changeset
452
kono
parents:
diff changeset
453 void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)),
kono
parents:
diff changeset
454 const char *ivarname __attribute__ ((__unused__)),
kono
parents:
diff changeset
455 BOOL gc_invisible __attribute__ ((__unused__)))
kono
parents:
diff changeset
456 {
kono
parents:
diff changeset
457 }
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 #endif /* OBJC_WITH_GC */