]>
Commit | Line | Data |
---|---|---|
c72fc2d9 | 1 | /* GNU Objective-C Runtime API. |
d2c60b5c | 2 | Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc. |
c72fc2d9 TW |
3 | |
4 | This file is part of GNU CC. | |
5 | ||
6 | GNU CC is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU General Public License as published by the | |
8 | Free Software Foundation; either version 2, or (at your option) any | |
9 | later version. | |
10 | ||
11 | GNU CC is distributed in the hope that it will be useful, but WITHOUT | |
12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
14 | License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GNU CC; see the file COPYING. If not, write to | |
84c09f78 RK |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
19 | Boston, MA 02111-1307, USA. */ | |
c72fc2d9 TW |
20 | |
21 | /* As a special exception, if you link this library with files compiled | |
22 | with GCC to produce an executable, this does not cause the resulting | |
23 | executable to be covered by the GNU General Public License. This | |
24 | exception does not however invalidate any other reasons why the | |
25 | executable file might be covered by the GNU General Public License. */ | |
26 | ||
27 | #ifndef __objc_api_INCLUDE_GNU | |
28 | #define __objc_api_INCLUDE_GNU | |
29 | ||
36be30f1 KKT |
30 | #include "objc/objc.h" |
31 | #include "objc/hash.h" | |
5f79ec0e | 32 | #include "objc/thr.h" |
d0b57512 | 33 | #include <stdio.h> |
d2c60b5c | 34 | #include <stdarg.h> |
c72fc2d9 | 35 | |
991d3e71 KKT |
36 | /* For functions which return Method_t */ |
37 | #define METHOD_NULL (Method_t)0 | |
38 | /* Boolean typedefs */ | |
39 | /* | |
40 | ** Method descriptor returned by introspective Object methods. | |
41 | ** This is really just the first part of the more complete objc_method | |
42 | ** structure defined below and used internally by the runtime. | |
43 | */ | |
44 | struct objc_method_description | |
45 | { | |
46 | SEL name; /* this is a selector, not a string */ | |
47 | char *types; /* type encoding */ | |
48 | }; | |
49 | ||
991d3e71 KKT |
50 | /* Filer types used to describe Ivars and Methods. */ |
51 | #define _C_ID '@' | |
52 | #define _C_CLASS '#' | |
53 | #define _C_SEL ':' | |
54 | #define _C_CHR 'c' | |
55 | #define _C_UCHR 'C' | |
56 | #define _C_SHT 's' | |
57 | #define _C_USHT 'S' | |
58 | #define _C_INT 'i' | |
59 | #define _C_UINT 'I' | |
60 | #define _C_LNG 'l' | |
61 | #define _C_ULNG 'L' | |
62 | #define _C_FLT 'f' | |
63 | #define _C_DBL 'd' | |
64 | #define _C_BFLD 'b' | |
65 | #define _C_VOID 'v' | |
66 | #define _C_UNDEF '?' | |
67 | #define _C_PTR '^' | |
68 | #define _C_CHARPTR '*' | |
69 | #define _C_ATOM '%' | |
70 | #define _C_ARY_B '[' | |
71 | #define _C_ARY_E ']' | |
72 | #define _C_UNION_B '(' | |
73 | #define _C_UNION_E ')' | |
74 | #define _C_STRUCT_B '{' | |
75 | #define _C_STRUCT_E '}' | |
76 | ||
77 | ||
d2c60b5c RK |
78 | /* |
79 | ** Error handling | |
80 | ** | |
81 | ** Call objc_error() or objc_verror() to record an error; this error | |
82 | ** routine will generally exit the program but not necessarily if the | |
83 | ** user has installed his own error handler. | |
84 | ** | |
85 | ** Call objc_set_error_handler to assign your own function for | |
86 | ** handling errors. The function should return YES if it is ok | |
87 | ** to continue execution, or return NO or just abort if the | |
88 | ** program should be stopped. The default error handler is just to | |
89 | ** print a message on stderr. | |
90 | ** | |
91 | ** The error handler function should be of type objc_error_handler | |
92 | ** The first parameter is an object instance of relevance. | |
93 | ** The second parameter is an error code. | |
94 | ** The third parameter is a format string in the printf style. | |
95 | ** The fourth parameter is a variable list of arguments. | |
96 | */ | |
97 | extern void objc_error(id object, int code, const char* fmt, ...); | |
98 | extern void objc_verror(id object, int code, const char* fmt, va_list ap); | |
99 | typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap); | |
100 | objc_error_handler objc_set_error_handler(objc_error_handler func); | |
101 | ||
102 | /* | |
103 | ** Error codes | |
104 | ** These are used by the runtime library, and your | |
105 | ** error handling may use them to determine if the error is | |
106 | ** hard or soft thus whether execution can continue or abort. | |
107 | */ | |
108 | #define OBJC_ERR_UNKNOWN 0 /* Generic error */ | |
109 | ||
110 | #define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */ | |
111 | #define OBJC_ERR_GCC_VERSION 2 /* Incorrect compiler version */ | |
112 | #define OBJC_ERR_MODULE_SIZE 3 /* Bad module size */ | |
113 | #define OBJC_ERR_PROTOCOL_VERSION 4 /* Incorrect protocol version */ | |
114 | ||
115 | #define OBJC_ERR_MEMORY 10 /* Out of memory */ | |
116 | ||
117 | #define OBJC_ERR_RECURSE_ROOT 20 /* Attempt to archive the root | |
118 | object more than once. */ | |
119 | #define OBJC_ERR_BAD_DATA 21 /* Didn't read expected data */ | |
120 | #define OBJC_ERR_BAD_KEY 22 /* Bad key for object */ | |
121 | #define OBJC_ERR_BAD_CLASS 23 /* Unknown class */ | |
122 | #define OBJC_ERR_BAD_TYPE 24 /* Bad type specification */ | |
123 | #define OBJC_ERR_NO_READ 25 /* Cannot read stream */ | |
124 | #define OBJC_ERR_NO_WRITE 26 /* Cannot write stream */ | |
125 | #define OBJC_ERR_STREAM_VERSION 27 /* Incorrect stream version */ | |
126 | #define OBJC_ERR_BAD_OPCODE 28 /* Bad opcode */ | |
127 | ||
128 | #define OBJC_ERR_UNIMPLEMENTED 30 /* Method is not implemented */ | |
991d3e71 | 129 | |
38692f1f RK |
130 | #define OBJC_ERR_BAD_STATE 40 /* Bad thread state */ |
131 | ||
991d3e71 KKT |
132 | /* |
133 | ** Set this variable nonzero to print a line describing each | |
134 | ** message that is sent. (this is currently disabled) | |
135 | */ | |
136 | extern BOOL objc_trace; | |
137 | ||
138 | ||
12d94bff RK |
139 | /* For every class which happens to have statically allocated instances in |
140 | this module, one OBJC_STATIC_INSTANCES is allocated by the compiler. | |
141 | INSTANCES is NULL terminated and points to all statically allocated | |
142 | instances of this class. */ | |
143 | struct objc_static_instances | |
144 | { | |
145 | char *class_name; | |
146 | id instances[0]; | |
147 | }; | |
148 | ||
991d3e71 KKT |
149 | /* |
150 | ** Whereas a Module (defined further down) is the root (typically) of a file, | |
151 | ** a Symtab is the root of the class and category definitions within the | |
152 | ** module. | |
153 | ** | |
154 | ** A Symtab contains a variable length array of pointers to classes and | |
155 | ** categories defined in the module. | |
156 | */ | |
157 | typedef struct objc_symtab { | |
158 | unsigned long sel_ref_cnt; /* Unknown. */ | |
a39d31bc | 159 | SEL refs; /* Unknown. */ |
991d3e71 KKT |
160 | unsigned short cls_def_cnt; /* Number of classes compiled |
161 | (defined) in the module. */ | |
162 | unsigned short cat_def_cnt; /* Number of categories | |
163 | compiled (defined) in the | |
164 | module. */ | |
12d94bff | 165 | |
991d3e71 | 166 | void *defs[1]; /* Variable array of pointers. |
e35ec852 | 167 | cls_def_cnt of type Class |
991d3e71 | 168 | followed by cat_def_cnt of |
12d94bff RK |
169 | type Category_t, followed |
170 | by a NULL terminated array | |
171 | of objc_static_instances. */ | |
991d3e71 KKT |
172 | } Symtab, *Symtab_t; |
173 | ||
174 | ||
175 | /* | |
176 | ** The compiler generates one of these structures for each module that | |
177 | ** composes the executable (eg main.m). | |
178 | ** | |
179 | ** This data structure is the root of the definition tree for the module. | |
180 | ** | |
181 | ** A collect program runs between ld stages and creates a ObjC ctor array. | |
182 | ** That array holds a pointer to each module structure of the executable. | |
183 | */ | |
184 | typedef struct objc_module { | |
185 | unsigned long version; /* Compiler revision. */ | |
186 | unsigned long size; /* sizeof(Module). */ | |
187 | const char* name; /* Name of the file where the | |
188 | module was generated. The | |
189 | name includes the path. */ | |
e35ec852 | 190 | |
991d3e71 KKT |
191 | Symtab_t symtab; /* Pointer to the Symtab of |
192 | the module. The Symtab | |
ca4da597 RK |
193 | holds an array of |
194 | pointers to | |
991d3e71 KKT |
195 | the classes and categories |
196 | defined in the module. */ | |
197 | } Module, *Module_t; | |
198 | ||
199 | ||
200 | /* | |
201 | ** The compiler generates one of these structures for a class that has | |
202 | ** instance variables defined in its specification. | |
203 | */ | |
204 | typedef struct objc_ivar* Ivar_t; | |
205 | typedef struct objc_ivar_list { | |
206 | int ivar_count; /* Number of structures (Ivar) | |
207 | contained in the list. One | |
208 | structure per instance | |
209 | variable defined in the | |
210 | class. */ | |
211 | struct objc_ivar { | |
212 | const char* ivar_name; /* Name of the instance | |
213 | variable as entered in the | |
214 | class definition. */ | |
215 | const char* ivar_type; /* Description of the Ivar's | |
216 | type. Useful for | |
217 | debuggers. */ | |
a39d31bc | 218 | int ivar_offset; /* Byte offset from the base |
991d3e71 KKT |
219 | address of the instance |
220 | structure to the variable. */ | |
221 | ||
222 | } ivar_list[1]; /* Variable length | |
223 | structure. */ | |
224 | } IvarList, *IvarList_t; | |
225 | ||
226 | ||
227 | /* | |
228 | ** The compiler generates one (or more) of these structures for a class that | |
229 | ** has methods defined in its specification. | |
230 | ** | |
231 | ** The implementation of a class can be broken into separate pieces in a file | |
232 | ** and categories can break them across modules. To handle this problem is a | |
233 | ** singly linked list of methods. | |
234 | */ | |
235 | typedef struct objc_method Method; | |
236 | typedef Method* Method_t; | |
237 | typedef struct objc_method_list { | |
238 | struct objc_method_list* method_next; /* This variable is used to link | |
239 | a method list to another. It | |
240 | is a singly linked list. */ | |
a39d31bc | 241 | int method_count; /* Number of methods defined in |
991d3e71 KKT |
242 | this structure. */ |
243 | struct objc_method { | |
244 | SEL method_name; /* This variable is the method's | |
245 | name. It is a char*. | |
246 | The unique integer passed to | |
247 | objc_msg_send is a char* too. | |
248 | It is compared against | |
249 | method_name using strcmp. */ | |
250 | const char* method_types; /* Description of the method's | |
251 | parameter list. Useful for | |
252 | debuggers. */ | |
253 | IMP method_imp; /* Address of the method in the | |
254 | executable. */ | |
255 | } method_list[1]; /* Variable length | |
256 | structure. */ | |
257 | } MethodList, *MethodList_t; | |
258 | ||
259 | struct objc_protocol_list { | |
260 | struct objc_protocol_list *next; | |
261 | int count; | |
262 | Protocol *list[1]; | |
263 | }; | |
264 | ||
265 | /* | |
266 | ** This is used to assure consistent access to the info field of | |
267 | ** classes | |
268 | */ | |
269 | #ifndef HOST_BITS_PER_LONG | |
270 | #define HOST_BITS_PER_LONG (sizeof(long)*8) | |
271 | #endif | |
272 | ||
273 | #define __CLS_INFO(cls) ((cls)->info) | |
274 | #define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask) | |
275 | #define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask) | |
276 | ||
e35ec852 | 277 | /* The structure is of type MetaClass */ |
991d3e71 KKT |
278 | #define _CLS_META 0x2L |
279 | #define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META)) | |
280 | ||
281 | ||
e35ec852 | 282 | /* The structure is of type Class */ |
991d3e71 KKT |
283 | #define _CLS_CLASS 0x1L |
284 | #define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS)) | |
285 | ||
286 | /* | |
287 | ** The class is initialized within the runtime. This means that | |
288 | ** it has had correct super and sublinks assigned | |
289 | */ | |
290 | #define _CLS_RESOLV 0x8L | |
291 | #define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV) | |
292 | #define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV) | |
293 | ||
294 | /* | |
295 | ** The class has been send a +initialize message or a such is not | |
296 | ** defined for this class | |
297 | */ | |
298 | #define _CLS_INITIALIZED 0x04L | |
299 | #define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED) | |
300 | #define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED) | |
301 | ||
302 | /* | |
303 | ** The class number of this class. This must be the same for both the | |
304 | ** class and it's meta class object | |
305 | */ | |
306 | #define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2)) | |
307 | #define CLS_SETNUMBER(cls, num) \ | |
62b9a712 KKT |
308 | ({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \ |
309 | (cls)->info >>= (HOST_BITS_PER_LONG/2); \ | |
991d3e71 KKT |
310 | __CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); }) |
311 | ||
312 | /* | |
313 | ** The compiler generates one of these structures for each category. A class | |
314 | ** may have many categories and contain both instance and factory methods. | |
315 | */ | |
316 | typedef struct objc_category { | |
317 | const char* category_name; /* Name of the category. Name | |
318 | contained in the () of the | |
319 | category definition. */ | |
320 | const char* class_name; /* Name of the class to which | |
321 | the category belongs. */ | |
322 | MethodList_t instance_methods; /* Linked list of instance | |
323 | methods defined in the | |
324 | category. NULL indicates no | |
325 | instance methods defined. */ | |
326 | MethodList_t class_methods; /* Linked list of factory | |
327 | methods defined in the | |
328 | category. NULL indicates no | |
329 | class methods defined. */ | |
330 | struct objc_protocol_list *protocols; /* List of Protocols | |
331 | conformed to */ | |
332 | } Category, *Category_t; | |
333 | ||
334 | /* | |
335 | ** Structure used when a message is send to a class's super class. The | |
336 | ** compiler generates one of these structures and passes it to | |
337 | ** objc_msg_super. | |
338 | */ | |
339 | typedef struct objc_super { | |
340 | id self; /* Id of the object sending | |
341 | the message. */ | |
e35ec852 | 342 | Class class; /* Object's super class. */ |
991d3e71 KKT |
343 | } Super, *Super_t; |
344 | ||
345 | IMP objc_msg_lookup_super(Super_t super, SEL sel); | |
346 | ||
62b9a712 | 347 | retval_t objc_msg_sendv(id, SEL, arglist_t); |
991d3e71 KKT |
348 | |
349 | ||
350 | ||
c72fc2d9 TW |
351 | /* |
352 | ** This is a hook which is called by objc_lookup_class and | |
353 | ** objc_get_class if the runtime is not able to find the class. | |
354 | ** This may e.g. try to load in the class using dynamic loading. | |
355 | ** The function is guaranteed to be passed a non-NULL name string. | |
356 | */ | |
e35ec852 | 357 | extern Class (*_objc_lookup_class)(const char *name); |
c72fc2d9 | 358 | |
a4137a04 RK |
359 | /* |
360 | ** This is a hook which is called by __objc_exec_class every time a class | |
361 | ** or a category is loaded into the runtime. This may e.g. help a | |
362 | ** dynamic loader determine the classes that have been loaded when | |
363 | ** an object file is dynamically linked in. | |
364 | */ | |
365 | extern void (*_objc_load_callback)(Class class, Category* category); | |
366 | ||
d2ca2ea6 RK |
367 | /* |
368 | ** Hook functions for allocating, copying and disposing of instances | |
369 | */ | |
e35ec852 | 370 | extern id (*_objc_object_alloc)(Class class); |
c72fc2d9 | 371 | extern id (*_objc_object_copy)(id object); |
c72fc2d9 TW |
372 | extern id (*_objc_object_dispose)(id object); |
373 | ||
d2ca2ea6 RK |
374 | /* |
375 | ** Standard functions for memory allocation and disposal. | |
376 | ** Users should use these functions in their ObjC programs so | |
377 | ** that they work properly with garbage collectors as well as | |
378 | ** can take advantage of the exception/error handling available. | |
379 | */ | |
380 | void * | |
381 | objc_malloc(size_t size); | |
382 | ||
383 | void * | |
384 | objc_atomic_malloc(size_t size); | |
385 | ||
386 | void * | |
387 | objc_valloc(size_t size); | |
388 | ||
389 | void * | |
390 | objc_realloc(void *mem, size_t size); | |
391 | ||
392 | void * | |
393 | objc_calloc(size_t nelem, size_t size); | |
394 | ||
395 | void | |
396 | objc_free(void *mem); | |
397 | ||
398 | /* | |
399 | ** Hook functions for memory allocation and disposal. | |
400 | ** This makes it easy to substitute garbage collection systems | |
401 | ** such as Boehm's GC by assigning these function pointers | |
402 | ** to the GC's allocation routines. By default these point | |
403 | ** to the ANSI standard malloc, realloc, free, etc. | |
404 | ** | |
405 | ** Users should call the normal objc routines above for | |
406 | ** memory allocation and disposal within their programs. | |
407 | */ | |
408 | extern void *(*_objc_malloc)(size_t); | |
409 | extern void *(*_objc_atomic_malloc)(size_t); | |
410 | extern void *(*_objc_valloc)(size_t); | |
411 | extern void *(*_objc_realloc)(void *, size_t); | |
412 | extern void *(*_objc_calloc)(size_t, size_t); | |
413 | extern void (*_objc_free)(void *); | |
414 | ||
e35ec852 | 415 | Method_t class_get_class_method(MetaClass class, SEL aSel); |
c72fc2d9 | 416 | |
e35ec852 | 417 | Method_t class_get_instance_method(Class class, SEL aSel); |
c72fc2d9 | 418 | |
e35ec852 | 419 | Class class_pose_as(Class impostor, Class superclass); |
c72fc2d9 | 420 | |
e35ec852 | 421 | Class objc_get_class(const char *name); |
c72fc2d9 | 422 | |
e35ec852 | 423 | Class objc_lookup_class(const char *name); |
c72fc2d9 | 424 | |
e35ec852 | 425 | Class objc_next_class(void **enum_state); |
a39d31bc | 426 | |
c72fc2d9 TW |
427 | const char *sel_get_name(SEL selector); |
428 | ||
a39d31bc KKT |
429 | const char *sel_get_type(SEL selector); |
430 | ||
c72fc2d9 TW |
431 | SEL sel_get_uid(const char *name); |
432 | ||
a39d31bc KKT |
433 | SEL sel_get_any_uid(const char *name); |
434 | ||
682d0171 RK |
435 | SEL sel_get_any_typed_uid(const char *name); |
436 | ||
a39d31bc KKT |
437 | SEL sel_get_typed_uid(const char *name, const char*); |
438 | ||
c72fc2d9 TW |
439 | SEL sel_register_name(const char *name); |
440 | ||
a39d31bc KKT |
441 | SEL sel_register_typed_name(const char *name, const char*type); |
442 | ||
443 | ||
c72fc2d9 TW |
444 | BOOL sel_is_mapped (SEL aSel); |
445 | ||
e35ec852 | 446 | extern id class_create_instance(Class class); |
c72fc2d9 | 447 | |
c72fc2d9 | 448 | static inline const char * |
e35ec852 | 449 | class_get_class_name(Class class) |
c72fc2d9 TW |
450 | { |
451 | return CLS_ISCLASS(class)?class->name:((class==Nil)?"Nil":0); | |
452 | } | |
453 | ||
c72fc2d9 | 454 | static inline long |
e35ec852 | 455 | class_get_instance_size(Class class) |
c72fc2d9 TW |
456 | { |
457 | return CLS_ISCLASS(class)?class->instance_size:0; | |
458 | } | |
459 | ||
e35ec852 RK |
460 | static inline MetaClass |
461 | class_get_meta_class(Class class) | |
c72fc2d9 TW |
462 | { |
463 | return CLS_ISCLASS(class)?class->class_pointer:Nil; | |
464 | } | |
465 | ||
e35ec852 RK |
466 | static inline Class |
467 | class_get_super_class(Class class) | |
c72fc2d9 TW |
468 | { |
469 | return CLS_ISCLASS(class)?class->super_class:Nil; | |
470 | } | |
471 | ||
c72fc2d9 | 472 | static inline int |
e35ec852 | 473 | class_get_version(Class class) |
c72fc2d9 TW |
474 | { |
475 | return CLS_ISCLASS(class)?class->version:-1; | |
476 | } | |
477 | ||
c72fc2d9 | 478 | static inline BOOL |
e35ec852 | 479 | class_is_class(Class class) |
c72fc2d9 TW |
480 | { |
481 | return CLS_ISCLASS(class); | |
482 | } | |
483 | ||
c72fc2d9 | 484 | static inline BOOL |
e35ec852 | 485 | class_is_meta_class(Class class) |
c72fc2d9 TW |
486 | { |
487 | return CLS_ISMETA(class); | |
488 | } | |
489 | ||
490 | ||
c72fc2d9 | 491 | static inline void |
e35ec852 | 492 | class_set_version(Class class, long version) |
c72fc2d9 TW |
493 | { |
494 | if (CLS_ISCLASS(class)) | |
495 | class->version = version; | |
496 | } | |
497 | ||
c72fc2d9 TW |
498 | static inline IMP |
499 | method_get_imp(Method_t method) | |
500 | { | |
501 | return (method!=METHOD_NULL)?method->method_imp:(IMP)0; | |
502 | } | |
503 | ||
e35ec852 | 504 | IMP get_imp (Class class, SEL sel); |
c72fc2d9 | 505 | |
38692f1f RK |
506 | /* Redefine on NeXTSTEP so as not to conflict with system function */ |
507 | #ifdef __NeXT__ | |
508 | #define object_copy gnu_object_copy | |
509 | #define object_dispose gnu_object_dispose | |
510 | #endif | |
511 | ||
991d3e71 | 512 | id object_copy(id object); |
c72fc2d9 | 513 | |
991d3e71 | 514 | id object_dispose(id object); |
c72fc2d9 | 515 | |
e35ec852 | 516 | static inline Class |
c72fc2d9 TW |
517 | object_get_class(id object) |
518 | { | |
519 | return ((object!=nil) | |
520 | ? (CLS_ISCLASS(object->class_pointer) | |
521 | ? object->class_pointer | |
522 | : (CLS_ISMETA(object->class_pointer) | |
e35ec852 | 523 | ? (Class)object |
c72fc2d9 TW |
524 | : Nil)) |
525 | : Nil); | |
526 | } | |
527 | ||
c72fc2d9 TW |
528 | static inline const char * |
529 | object_get_class_name(id object) | |
530 | { | |
531 | return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) | |
532 | ?object->class_pointer->name | |
e35ec852 | 533 | :((Class)object)->name) |
c72fc2d9 TW |
534 | :"Nil"); |
535 | } | |
536 | ||
e35ec852 | 537 | static inline MetaClass |
c72fc2d9 TW |
538 | object_get_meta_class(id object) |
539 | { | |
540 | return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) | |
541 | ?object->class_pointer->class_pointer | |
542 | :(CLS_ISMETA(object->class_pointer) | |
543 | ?object->class_pointer | |
544 | :Nil)) | |
545 | :Nil); | |
546 | } | |
547 | ||
e35ec852 | 548 | static inline Class |
a1d7405c KKT |
549 | object_get_super_class |
550 | (id object) | |
c72fc2d9 TW |
551 | { |
552 | return ((object!=nil)?(CLS_ISCLASS(object->class_pointer) | |
553 | ?object->class_pointer->super_class | |
554 | :(CLS_ISMETA(object->class_pointer) | |
e35ec852 | 555 | ?((Class)object)->super_class |
c72fc2d9 TW |
556 | :Nil)) |
557 | :Nil); | |
558 | } | |
559 | ||
c72fc2d9 TW |
560 | static inline BOOL |
561 | object_is_class(id object) | |
562 | { | |
e35ec852 | 563 | return CLS_ISCLASS((Class)object); |
c72fc2d9 TW |
564 | } |
565 | ||
c72fc2d9 TW |
566 | static inline BOOL |
567 | object_is_instance(id object) | |
568 | { | |
569 | return (object!=nil)&&CLS_ISCLASS(object->class_pointer); | |
570 | } | |
571 | ||
c72fc2d9 TW |
572 | static inline BOOL |
573 | object_is_meta_class(id object) | |
574 | { | |
e35ec852 | 575 | return CLS_ISMETA((Class)object); |
c72fc2d9 TW |
576 | } |
577 | ||
673a261e RK |
578 | struct sarray* |
579 | objc_get_uninstalled_dtable(); | |
580 | ||
991d3e71 | 581 | #endif /* not __objc_api_INCLUDE_GNU */ |
a1d7405c | 582 | |
36be30f1 | 583 | |
36be30f1 | 584 |