/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights * Reserved. This file contains Original Code and/or Modifications of * Original Code as defined in and that are subject to the Apple Public * Source License Version 1.1 (the "License"). You may not use this file * except in compliance with the License. Please obtain a copy of the * License at http://www.apple.com/publicsource and read it before using * this file. * * The Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * objc-private.h * Copyright 1988-1996, NeXT Software, Inc. */ #if !defined(_OBJC_PRIVATE_H_) #define _OBJC_PRIVATE_H_ #import // for OBJC_EXPORT OBJC_EXPORT void checkUniqueness(); #import "objc-config.h" #import #define mutex_alloc() (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t)) #define mutex_init(m) pthread_mutex_init(m, NULL) #define mutex_lock(m) pthread_mutex_lock(m) #define mutex_try_lock(m) (! pthread_mutex_trylock(m)) #define mutex_unlock(m) pthread_mutex_unlock(m) #define mutex_clear(m) #define mutex_t pthread_mutex_t* #define mutex MUTEX_DEFINE_ERROR #import #import #import #import #import #import #import // This needs <...> -- malloc.h is not ours, really... #import /* Opaque cookie used in _getObjc... routines. File format independant. * This is used in place of the mach_header. In fact, when compiling * for NEXTSTEP, this is really a (struct mach_header *). * * had been: typedef void *objc_header; */ #if defined(NeXT_PDO) typedef void headerType; #else #import typedef struct mach_header headerType; #endif #import typedef struct _ProtocolTemplate { @defs(Protocol) } ProtocolTemplate; typedef struct _NXConstantStringTemplate { Class isa; void *characters; unsigned int _length; } NXConstantStringTemplate; #if defined(NeXT_PDO) #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate** #define OBJC_CONSTANT_STRING_DEREF #define OBJC_PROTOCOL_PTR ProtocolTemplate** #define OBJC_PROTOCOL_DEREF -> #elif defined(__MACH__) #define OBJC_CONSTANT_STRING_PTR NXConstantStringTemplate* #define OBJC_CONSTANT_STRING_DEREF & #define OBJC_PROTOCOL_PTR ProtocolTemplate* #define OBJC_PROTOCOL_DEREF . #endif // both OBJC_EXPORT headerType ** _getObjcHeaders(); OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules); OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses); OBJC_EXPORT void * _getObjcHeaderData(headerType *head, unsigned *size); OBJC_EXPORT const char * _getObjcHeaderName(headerType *head); // internal routines for delaying binding void _objc_resolve_categories_for_class (struct objc_class * cls); void _objc_bindModuleContainingClass(struct objc_class * cls); // someday a logging facility // ObjC is assigned the range 0xb000 - 0xbfff for first parameter #define trace(a, b, c, d) do {} while (0) OBJC_EXPORT ProtocolTemplate * _getObjcProtocols(headerType *head, int *nprotos); OBJC_EXPORT NXConstantStringTemplate *_getObjcStringObjects(headerType *head, int *nstrs); OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess); #define END_OF_METHODS_LIST ((struct objc_method_list*)-1) typedef struct _header_info { const headerType * mhdr; Module mod_ptr; unsigned int mod_count; unsigned long image_slide; struct _header_info * next; } header_info; OBJC_EXPORT header_info *_objc_headerStart (); OBJC_EXPORT int _objcModuleCount(); OBJC_EXPORT const char *_objcModuleNameAtIndex(int i); OBJC_EXPORT Class objc_getOrigClass (const char *name); extern struct objc_method_list **get_base_method_list(Class cls); OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*); /* initialize */ OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide); OBJC_EXPORT void _class_install_relationships(Class, long); OBJC_EXPORT void *_objc_create_zone(void); OBJC_EXPORT SEL sel_registerNameNoCopy(const char *str); /* selector fixup in method lists */ #define _OBJC_FIXED_UP ((void *)1771) static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist) { unsigned i, size; Method method; struct objc_method_list *old_mlist; if ( ! mlist ) return (struct objc_method_list *)0; if ( mlist->obsolete != _OBJC_FIXED_UP ) { old_mlist = mlist; size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method); mlist = malloc_zone_malloc(_objc_create_zone(), size); memmove(mlist, old_mlist, size); for ( i = 0; i < mlist->method_count; i += 1 ) { method = &mlist->method_list[i]; method->method_name = sel_registerNameNoCopy((const char *)method->method_name); } mlist->obsolete = _OBJC_FIXED_UP; } return mlist; } /* method lookup */ /* -- inline version of class_nextMethodList(Class, void **) -- */ static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it) { struct objc_method_list ***iterator; iterator = (struct objc_method_list***)it; if (*iterator == NULL) { *iterator = &((((struct objc_class *) cls)->methodLists)[0]); } else (*iterator) += 1; // Check for list end if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) { *it = nil; return NULL; } **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator); // Return method list pointer return **iterator; } OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL); OBJC_EXPORT IMP class_lookupMethod(Class, SEL); OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel); OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name); OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list ); OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list ); /* message dispatcher */ OBJC_EXPORT Cache _cache_create(Class); OBJC_EXPORT IMP _class_lookupMethodAndLoadCache(Class, SEL); OBJC_EXPORT id _objc_msgForward (id self, SEL sel, ...); /* errors */ OBJC_EXPORT volatile void __S(_objc_fatal)(const char *message); OBJC_EXPORT volatile void _objc_error(id, const char *, va_list); OBJC_EXPORT volatile void __objc_error(id, const char *, ...); OBJC_EXPORT void _objc_inform(const char *fmt, ...); OBJC_EXPORT void _objc_syslog(const char *fmt, ...); /* magic */ OBJC_EXPORT Class _objc_getFreedObjectClass (void); OBJC_EXPORT const struct objc_cache emptyCache; OBJC_EXPORT void _objc_flush_caches (Class cls); /* locking */ #define MUTEX_TYPE pthread_mutex_t* #define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER OBJC_EXPORT pthread_mutex_t classLock; OBJC_EXPORT pthread_mutex_t messageLock; OBJC_EXPORT int _objc_multithread_mask; // _objc_msgNil is actually (unsigned dummy, id, SEL) for i386; // currently not implemented for any sparc or hppa platforms OBJC_EXPORT void (*_objc_msgNil)(id, SEL); typedef struct { long addressOffset; long selectorOffset; } FixupEntry; static inline int selEqual( SEL s1, SEL s2 ) { return (s1 == s2); } #if defined(OBJC_COLLECTING_CACHE) #define OBJC_LOCK(MUTEX) mutex_lock (MUTEX) #define OBJC_UNLOCK(MUTEX) mutex_unlock (MUTEX) #define OBJC_TRYLOCK(MUTEX) mutex_try_lock (MUTEX) #else // not OBJC_COLLECTING_CACHE #define OBJC_LOCK(MUTEX) \ do \ { \ if (!_objc_multithread_mask) \ mutex_lock (MUTEX); \ } \ while (0) #define OBJC_UNLOCK(MUTEX) \ do \ { \ if (!_objc_multithread_mask) \ mutex_unlock (MUTEX); \ } \ while (0) #endif /* OBJC_COLLECTING_CACHE */ #if !defined(SEG_OBJC) #define SEG_OBJC "__OBJC" /* objective-C runtime segment */ #endif static __inline__ int _objc_strcmp(const unsigned char *s1, const unsigned char *s2) { int a, b, idx = 0; for (;;) { a = s1[idx]; b = s2[idx]; if (a != b || 0 == a) break; idx++; } return a - b; } static __inline__ unsigned int _objc_strhash(const unsigned char *s) { unsigned int hash = 0; for (;;) { int a = *s++; if (0 == a) break; hash += (hash << 8) + a; } return hash; } #endif /* _OBJC_PRIVATE_H_ */