home *** CD-ROM | disk | FTP | other *** search
- /*
- ** ObjectiveAmiga: objc.library interface structures and definitions
- ** See GNU:lib/libobjam/ReadMe for details
- */
-
-
- #ifndef LIBRARIES_OBJC_H
- #define LIBRARIES_OBJC_H
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
-
- /****************************************************************** includes */
-
- #include <stddef.h>
-
- #ifndef EXEC_TYPES_H
- #include <exec/types.h>
- #endif
-
- #ifndef EXEC_LIBRARIES_H
- #include <exec/libraries.h>
- #endif
-
-
- /************************************************************ boolean values */
-
- #define YES TRUE
- #define NO FALSE
-
-
- /************************************************** definition of a selector */
-
- /* Selectors themselves are not unique,
- but the sel_id is a unique identifier */
-
- typedef const struct objc_selector
- {
- void *sel_id;
- const char *sel_types;
- } *SEL;
-
- inline static BOOL sel_eq (SEL s1, SEL s2)
- {
- if (s1 == 0 || s2 == 0) return s1 == s2;
- else return s1->sel_id == s2->sel_id;
- }
-
-
- /********************************************* typedef for untyped instances */
-
- typedef struct objc_object
- {
- struct objc_class* class_pointer;
- } *id;
-
-
- /************************************************* definition of method type */
-
- /* When retrieving the implementation of a method,
- this is the type of the pointer returned */
- typedef id (*IMP)(id, SEL, ...);
-
-
- /********************************************************* more simple types */
-
- #define nil (id)0 /* id of Nil instance */
- #define Nil (OCClass*)0 /* id of Nil class */
-
- typedef char *STR; /* String alias */
-
-
- /*********************************************************** class structure */
-
- /*
- ** The compiler generates one of these structures for each class.
- **
- ** This structure is the definition for classes.
- **
- ** This structure is generated by the compiler in the executable and used by
- ** the run-time during normal messaging operations. Therefore some members
- ** change type. The compiler generates "char* const" and places a string in
- ** the following member variables: super_class.
- */
-
- typedef struct objc_class MetaClass;
- typedef struct objc_class OCClass; /* 'Class' is used by BOOPSI... */
- #ifndef INTUITION_CLASSES_H
- typedef OCClass Class; /* ...but we can use it too ;) */
- #endif
-
- struct objc_class {
- MetaClass* class_pointer; /* Pointer to the class's meta class */
- struct objc_class* super_class; /* Pointer to the super class. NULL for class Object */
- const char* name; /* Name of the class */
- long version; /* Unknown */
- unsigned long info; /* Bit mask. See class masks defined above */
- long instance_size; /* Size in bytes of the class. The sum of the
- class definition and all super class definitions */
- struct objc_ivar_list *ivars; /* Pointer to a structure that describes the instance
- variables in the class definition. NULL indicates
- no instance variables. Does not include super class
- variables */
- struct objc_method_list *methods; /* Linked list of instance methods defined for the class */
- struct sarray *dtable; /* Pointer to instance method dispatch table */
- struct objc_class *subclass_list; /* Subclasses */
- struct objc_class *sibling_class;
- struct objc_protocol_list *protocols; /* Protocols conformed to */
- };
-
- #ifndef __OBJC__
- typedef struct objc_protocol {
- struct objc_class* class_pointer;
- char *protocol_name;
- struct objc_protocol_list *protocol_list;
- struct objc_method_description_list *instance_methods, *class_methods;
- } Protocol;
-
- #else /* __OBJC__ */
- @class Protocol;
- #endif
-
- typedef void* retval_t; /* return value */
- typedef void(*apply_t)(void); /* function pointer */
- typedef union {
- char *arg_ptr;
- char arg_regs[sizeof (char*)];
- } *arglist_t; /* argument frame */
-
-
- /************************************************************** method stuff */
-
- /* For functions which return Method_t */
- #define METHOD_NULL (Method_t)0
-
- /*
- ** Method descriptor returned by introspective Object methods.
- ** This is really just the first part of the more complete objc_method
- ** structure defined below and used internally by the runtime.
- */
- struct objc_method_description
- {
- SEL name; /* this is a selector, not a string */
- char *types; /* type encoding */
- };
-
- /* Filer types used to describe Ivars and Methods. */
- #define _C_ID '@'
- #define _C_CLASS '#'
- #define _C_SEL ':'
- #define _C_CHR 'c'
- #define _C_UCHR 'C'
- #define _C_SHT 's'
- #define _C_USHT 'S'
- #define _C_INT 'i'
- #define _C_UINT 'I'
- #define _C_LNG 'l'
- #define _C_ULNG 'L'
- #define _C_FLT 'f'
- #define _C_DBL 'd'
- #define _C_BFLD 'b'
- #define _C_VOID 'v'
- #define _C_UNDEF '?'
- #define _C_PTR '^'
- #define _C_CHARPTR '*'
- #define _C_ATOM '%'
- #define _C_ARY_B '['
- #define _C_ARY_E ']'
- #define _C_UNION_B '('
- #define _C_UNION_E ')'
- #define _C_STRUCT_B '{'
- #define _C_STRUCT_E '}'
-
-
- /********************************************* compiler-generated structures */
-
- /*
- ** Whereas a Module (defined further down) is the root (typically) of a file,
- ** a Symtab is the root of the class and category definitions within the
- ** module.
- **
- ** A Symtab contains a variable length array of pointers to classes and
- ** categories defined in the module.
- */
- typedef struct objc_symtab {
- unsigned long sel_ref_cnt; /* Unknown. */
- SEL *refs; /* Unknown. */
- unsigned short cls_def_cnt; /* Number of classes compiled
- (defined) in the module. */
- unsigned short cat_def_cnt; /* Number of categories
- compiled (defined) in the
- module. */
- void *defs[1]; /* Variable array of pointers.
- cls_def_cnt of type Class*
- followed by cat_def_cnt of
- type Category_t. */
- } Symtab, *Symtab_t;
-
- /*
- ** The compiler generates one of these structures for each module that
- ** composes the executable (eg main.m).
- **
- ** This data structure is the root of the definition tree for the module.
- **
- ** A collect program runs between ld stages and creates a ObjC ctor array.
- ** That array holds a pointer to each module structure of the executable.
- */
- typedef struct objc_module {
- unsigned long version; /* Compiler revision. */
- unsigned long size; /* sizeof(Module). */
- const char* name; /* Name of the file where the
- module was generated. The
- name includes the path. */
- Symtab_t symtab; /* Pointer to the Symtab of
- the module. The Symtab
- holds an array of pointers to
- the classes and categories
- defined in the module. */
- } Module, *Module_t;
-
- /*
- ** The compiler generates one of these structures for a class that has
- ** instance variables defined in its specification.
- */
- typedef struct objc_ivar* Ivar_t;
- typedef struct objc_ivar_list {
- int ivar_count; /* Number of structures (Ivar)
- contained in the list. One
- structure per instance
- variable defined in the
- class. */
- struct objc_ivar {
- const char* ivar_name; /* Name of the instance
- variable as entered in the
- class definition. */
- const char* ivar_type; /* Description of the Ivar's
- type. Useful for
- debuggers. */
- int ivar_offset; /* Byte offset from the base
- address of the instance
- structure to the variable. */
-
- } ivar_list[1]; /* Variable length
- structure. */
- } IvarList, *IvarList_t;
-
- /*
- ** The compiler generates one (or more) of these structures for a class that
- ** has methods defined in its specification.
- **
- ** The implementation of a class can be broken into separate pieces in a file
- ** and categories can break them across modules. To handle this problem is a
- ** singly linked list of methods.
- */
- typedef struct objc_method Method;
- typedef Method* Method_t;
- typedef struct objc_method_list {
- struct objc_method_list* method_next; /* This variable is used to link
- a method list to another. It
- is a singly linked list. */
- int method_count; /* Number of methods defined in
- this structure. */
- struct objc_method {
- SEL method_name; /* This variable is the method's
- name. It is a char*.
- The unique integer passed to
- objc_msg_send is a char* too.
- It is compared against
- method_name using strcmp. */
- const char* method_types; /* Description of the method's
- parameter list. Useful for
- debuggers. */
- IMP method_imp; /* Address of the method in the
- executable. */
- } method_list[1]; /* Variable length
- structure. */
- } MethodList, *MethodList_t;
-
- struct objc_protocol_list {
- struct objc_protocol_list *next;
- int count;
- Protocol *list[1];
- };
-
-
- /****************************************************** introspection macros */
-
- /*
- ** This is used to assure consistent access to the info field of
- ** classes
- */
- #ifndef HOST_BITS_PER_LONG
- #define HOST_BITS_PER_LONG (sizeof(long)*8)
- #endif
-
- #define __CLS_INFO(cls) ((cls)->info)
- #define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
- #define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask)
-
- /* The structure is of type MetaClass* */
- #define _CLS_META 0x2L
- #define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
-
-
- /* The structure is of type Class* */
- #define _CLS_CLASS 0x1L
- #define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
-
- /*
- ** The class is initialized within the runtime. This means that
- ** it has had correct super and sublinks assigned
- */
- #define _CLS_RESOLV 0x8L
- #define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV)
- #define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV)
-
- /*
- ** The class has been send a +initialize message or a such is not
- ** defined for this class
- */
- #define _CLS_INITIALIZED 0x04L
- #define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED)
- #define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED)
-
- /*
- ** The class number of this class. This must be the same for both the
- ** class and it's meta class object
- */
- #define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2))
- #define CLS_SETNUMBER(cls, num) \
- ({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \
- (cls)->info >>= (HOST_BITS_PER_LONG/2); \
- __CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); })
-
-
- /***************************************************** more compiler structs */
-
- /*
- ** The compiler generates one of these structures for each category. A class
- ** may have many categories and contain both instance and factory methods.
- */
- typedef struct objc_category {
- const char* category_name; /* Name of the category. Name
- contained in the () of the
- category definition. */
- const char* class_name; /* Name of the class to which
- the category belongs. */
- MethodList_t instance_methods; /* Linked list of instance
- methods defined in the
- category. NULL indicates no
- instance methods defined. */
- MethodList_t class_methods; /* Linked list of factory
- methods defined in the
- category. NULL indicates no
- class methods defined. */
- struct objc_protocol_list *protocols; /* List of Protocols
- conformed to */
- } Category, *Category_t;
-
- /*
- ** Structure used when a message is send to a class's super class. The
- ** compiler generates one of these structures and passes it to
- ** objc_msg_super.
- */
- typedef struct objc_super {
- id self; /* Id of the object sending
- the message. */
- OCClass* class; /* Object's super class. */
- } Super, *Super_t;
-
- IMP objc_msg_lookup_super(Super_t super, SEL sel);
-
- retval_t objc_msg_sendv(id, SEL, arglist_t);
-
-
- /********************************************************* encoding of types */
-
- #define _C_CONST 'r'
- #define _C_IN 'n'
- #define _C_INOUT 'N'
- #define _C_OUT 'o'
- #define _C_BYCOPY 'O'
- #define _C_ONEWAY 'V'
-
- #define _F_CONST 0x01
- #define _F_IN 0x01
- #define _F_OUT 0x02
- #define _F_INOUT 0x03
- #define _F_BYCOPY 0x04
- #define _F_ONEWAY 0x08
-
-
- /************************************************************** library base */
-
- #define OBJCNAME "objc-5-2-3.library"
- #define OBJCVERSION 0
-
- struct ObjcBase
- {
- struct Library lb_LibNode;
- };
-
-
- /********************************************************* memory management */
-
- typedef void NXZone; /* No introspection allowed */
-
- #define vm_page_size 4096 /* The standard page size of an MC68040 MMU */
- #define NX_NOZONE ((NXZone *)0) /* No zone */
-
- /* Redefine standard memory functions */
- #define malloc(size) NXZoneMalloc(NXDefaultMallocZone(),size)
- #define calloc(num,size) NXZoneCalloc(NXDefaultMallocZone(),num,size)
- #define realloc(block,size) NXZoneRealloc(NXDefaultMallocZone(),block,size)
- #define free(block) NXZoneFree(NXZoneFromPtr(block),block)
-
- /* NX memory functions with integrated typecasting */
- #define NX_MALLOC(VAR,TYPE,NUM) ((VAR)=(TYPE*)malloc((unsigned)(NUM)*sizeof(TYPE)))
- #define NX_REALLOC(VAR,TYPE,NUM) ((VAR)=(TYPE*)realloc((VAR),(unsigned)(NUM)*sizeof(TYPE)))
- #define NX_FREE(PTR) free((PTR));
-
-
- /************************************************************* sparse arrays */
-
- #define OBJC_SPARSE2 /* 2-level sparse array */
- /* #define OBJC_SPARSE3 */ /* 3-level sparse array */
-
- #ifdef OBJC_SPARSE2
- extern const char* __objc_sparse2_id;
- #endif
-
- #ifdef OBJC_SPARSE3
- extern const char* __objc_sparse3_id;
- #endif
-
-
- extern int nbuckets; /* for stats */
- extern int nindices;
- extern int narrays;
- extern int idxsize;
-
-
- /* An unsigned integer of same size as a pointer */
- #define SIZET_BITS (sizeof(size_t)*8)
-
- #if defined(sparc) || defined(OBJC_SPARSE2)
- #define PRECOMPUTE_SELECTORS
- #endif
-
- #ifdef OBJC_SPARSE3
-
- /* Buckets are 8 words each */
- #define BUCKET_BITS 3
- #define BUCKET_SIZE (1<<BUCKET_BITS)
- #define BUCKET_MASK (BUCKET_SIZE-1)
-
- /* Indices are 16 words each */
- #define INDEX_BITS 4
- #define INDEX_SIZE (1<<INDEX_BITS)
- #define INDEX_MASK (INDEX_SIZE-1)
-
- #define INDEX_CAPACITY (BUCKET_SIZE*INDEX_SIZE)
-
- #else /* OBJC_SPARSE2 */
-
- /* Buckets are 32 words each */
- #define BUCKET_BITS 5
- #define BUCKET_SIZE (1<<BUCKET_BITS)
- #define BUCKET_MASK (BUCKET_SIZE-1)
-
- #endif /* OBJC_SPARSE2 */
-
- typedef size_t sidx;
-
- #ifdef PRECOMPUTE_SELECTORS
-
- struct soffset {
- #ifdef OBJC_SPARSE3
- unsigned int unused : SIZET_BITS/4;
- unsigned int eoffset : SIZET_BITS/4;
- unsigned int boffset : SIZET_BITS/4;
- unsigned int ioffset : SIZET_BITS/4;
- #else /* OBJC_SPARSE2 */
- #ifdef sparc
- unsigned int boffset : (SIZET_BITS - 2) - BUCKET_BITS;
- unsigned int eoffset : BUCKET_BITS;
- unsigned int unused : 2;
- #else
- unsigned int boffset : SIZET_BITS/2;
- unsigned int eoffset : SIZET_BITS/2;
- #endif
- #endif /* OBJC_SPARSE2 */
- };
-
- union sofftype {
- struct soffset off;
- sidx idx;
- };
-
- #endif /* not PRECOMPUTE_SELECTORS */
-
- struct sbucket {
- void* elems[BUCKET_SIZE]; /* elements stored in array */
- short version; /* used for copy-on-write */
- };
-
- #ifdef OBJC_SPARSE3
-
- struct sindex {
- struct sbucket* buckets[INDEX_SIZE];
- short version;
- };
-
- #endif /* OBJC_SPARSE3 */
-
- struct sarray {
- #ifdef OBJC_SPARSE3
- struct sindex** indices;
- struct sindex* empty_index;
- #else /* OBJC_SPARSE2 */
- struct sbucket** buckets;
- #endif /* OBJC_SPARSE2 */
- struct sbucket* empty_bucket;
- short version;
- short ref_count;
- struct sarray* is_copy_of;
- int capacity;
- };
-
-
- #ifdef PRECOMPUTE_SELECTORS
- /* Transform soffset values to ints and vica verca */
- static inline unsigned int
- soffset_decode(sidx index)
- {
- union sofftype x;
- x.idx = index;
- #ifdef OBJC_SPARSE3
- return x.off.eoffset
- + (x.off.boffset*BUCKET_SIZE)
- + (x.off.ioffset*INDEX_CAPACITY);
- #else /* OBJC_SPARSE2 */
- return x.off.eoffset + (x.off.boffset*BUCKET_SIZE);
- #endif /* OBJC_SPARSE2 */
- }
-
- static inline sidx
- soffset_encode(size_t offset)
- {
- union sofftype x;
- x.off.eoffset = offset%BUCKET_SIZE;
- #ifdef OBJC_SPARSE3
- x.off.boffset = (offset/BUCKET_SIZE)%INDEX_SIZE;
- x.off.ioffset = offset/INDEX_CAPACITY;
- #else /* OBJC_SPARSE2 */
- x.off.boffset = offset/BUCKET_SIZE;
- #endif
- return (sidx)x.idx;
- }
-
- #else /* not PRECOMPUTE_SELECTORS */
-
- static inline size_t
- soffset_decode(sidx index)
- {
- return index;
- }
-
- static inline sidx
- soffset_encode(size_t offset)
- {
- return offset;
- }
- #endif /* not PRECOMPUTE_SELECTORS */
-
- /* Get element from the Sparse array `array' at offset `index' */
-
- static inline void* sarray_get(struct sarray* array, sidx index)
- {
- #ifdef PRECOMPUTE_SELECTORS
- union sofftype x;
- x.idx = index;
- #ifdef OBJC_SPARSE3
- return
- array->
- indices[x.off.ioffset]->
- buckets[x.off.boffset]->
- elems[x.off.eoffset];
- #else /* OBJC_SPARSE2 */
- return array->buckets[x.off.boffset]->elems[x.off.eoffset];
- #endif /* OBJC_SPARSE2 */
- #else /* not PRECOMPUTE_SELECTORS */
- #ifdef OBJC_SPARSE3
- return array->
- indices[index/INDEX_CAPACITY]->
- buckets[(index/BUCKET_SIZE)%INDEX_SIZE]->
- elems[index%BUCKET_SIZE];
- #else /* OBJC_SPARSE2 */
- return array->buckets[index/BUCKET_SIZE]->elems[index%BUCKET_SIZE];
- #endif /* not OBJC_SPARSE3 */
- #endif /* not PRECOMPUTE_SELECTORS */
- }
-
- static inline void* sarray_get_safe(struct sarray* array, sidx index)
- {
- if(soffset_decode(index) < array->capacity)
- return sarray_get(array, index);
- else
- return (array->empty_bucket->elems[0]);
- }
-
-
- /************************************************************ atom emulation */
-
- typedef const char *NXAtom; /* A unique string */
-
-
- /*************************************************** private data structures */
-
- struct __objclib_init_data
- {
- void *globaldata;
- void (*abort)(void);
- };
-
-
- /******************************************************************* the end */
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif /* LIBRARIES_OBJC_H */
-