home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / c / objam01.lha / objam / runtime / include / libraries / objc.h
Encoding:
C/C++ Source or Header  |  1995-02-10  |  19.8 KB  |  636 lines

  1. /*
  2. ** ObjectiveAmiga: objc.library interface structures and definitions
  3. ** See GNU:lib/libobjam/ReadMe for details
  4. */
  5.  
  6.  
  7. #ifndef LIBRARIES_OBJC_H
  8. #define LIBRARIES_OBJC_H
  9.  
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #endif
  13.  
  14.  
  15. /****************************************************************** includes */
  16.  
  17. #include <stddef.h>
  18.  
  19. #ifndef EXEC_TYPES_H
  20. #include <exec/types.h>
  21. #endif
  22.  
  23. #ifndef EXEC_LIBRARIES_H
  24. #include <exec/libraries.h>
  25. #endif
  26.  
  27.  
  28. /************************************************************ boolean values */
  29.  
  30. #define YES   TRUE
  31. #define NO    FALSE
  32.  
  33.  
  34. /************************************************** definition of a selector */
  35.  
  36. /* Selectors themselves are not unique,
  37.    but the sel_id is a unique identifier */
  38.  
  39. typedef const struct objc_selector 
  40. {
  41.   void *sel_id;
  42.   const char *sel_types;
  43. } *SEL;
  44.  
  45. inline static BOOL sel_eq (SEL s1, SEL s2)
  46. {
  47.   if (s1 == 0 || s2 == 0) return s1 == s2;
  48.   else return s1->sel_id == s2->sel_id;
  49. }
  50.  
  51.  
  52. /********************************************* typedef for untyped instances */
  53.  
  54. typedef struct objc_object
  55. {
  56.   struct objc_class*  class_pointer;
  57. } *id;
  58.  
  59.  
  60. /************************************************* definition of method type */
  61.  
  62. /* When retrieving the implementation of a method,
  63.    this is the type of the pointer returned */
  64. typedef id (*IMP)(id, SEL, ...); 
  65.  
  66.  
  67. /********************************************************* more simple types */
  68.  
  69. #define nil (id)0         /* id of Nil instance */
  70. #define Nil (OCClass*)0   /* id of Nil class */
  71.  
  72. typedef char *STR;        /* String alias */
  73.  
  74.  
  75. /*********************************************************** class structure */
  76.  
  77. /*
  78. ** The compiler generates one of these structures for each class.  
  79. ** 
  80. ** This structure is the definition for classes. 
  81. ** 
  82. ** This structure is generated by the compiler in the executable and used by
  83. ** the run-time during normal messaging operations.  Therefore some members
  84. ** change type. The compiler generates "char* const" and places a string in
  85. ** the following member variables:  super_class. 
  86. */
  87.  
  88. typedef struct objc_class MetaClass;
  89. typedef struct objc_class OCClass; /* 'Class' is used by BOOPSI... */
  90. #ifndef    INTUITION_CLASSES_H
  91. typedef OCClass Class; /* ...but we can use it too ;) */
  92. #endif
  93.  
  94. struct objc_class {     
  95.   MetaClass*          class_pointer;    /* Pointer to the class's meta class */
  96.   struct objc_class*  super_class;      /* Pointer to the super class. NULL for class Object */
  97.   const char*         name;             /* Name of the class */
  98.   long                version;          /* Unknown */
  99.   unsigned long       info;             /* Bit mask.  See class masks defined above */
  100.   long                instance_size;    /* Size in bytes of the class. The sum of the
  101.                        class definition and all super class definitions */
  102.   struct objc_ivar_list *ivars;         /* Pointer to a structure that describes the instance 
  103.                                            variables in the class definition.  NULL indicates
  104.                                            no instance variables.  Does not include super class
  105.                                            variables */
  106.   struct objc_method_list *methods;     /* Linked list of instance methods defined for the class */
  107.   struct sarray *dtable;                /* Pointer to instance method dispatch table */
  108.   struct objc_class *subclass_list;     /* Subclasses */
  109.   struct objc_class *sibling_class;
  110.   struct objc_protocol_list *protocols; /* Protocols conformed to */
  111. };
  112.  
  113. #ifndef __OBJC__
  114. typedef struct objc_protocol {
  115.   struct objc_class* class_pointer;
  116.   char *protocol_name;
  117.   struct objc_protocol_list *protocol_list;
  118.   struct objc_method_description_list *instance_methods, *class_methods; 
  119. } Protocol; 
  120.  
  121. #else /* __OBJC__ */
  122. @class Protocol;
  123. #endif 
  124.  
  125. typedef void* retval_t;        /* return value */
  126. typedef void(*apply_t)(void);    /* function pointer */
  127. typedef union {
  128.   char *arg_ptr;
  129.   char arg_regs[sizeof (char*)];
  130. } *arglist_t;            /* argument frame */
  131.  
  132.  
  133. /************************************************************** method stuff */
  134.  
  135. /* For functions which return Method_t */
  136. #define METHOD_NULL    (Method_t)0
  137.  
  138. /*
  139. ** Method descriptor returned by introspective Object methods.
  140. ** This is really just the first part of the more complete objc_method
  141. ** structure defined below and used internally by the runtime.
  142. */
  143. struct objc_method_description
  144. {
  145.     SEL name;            /* this is a selector, not a string */
  146.     char *types;        /* type encoding */
  147. };
  148.  
  149. /* Filer types used to describe Ivars and Methods.  */
  150. #define _C_ID       '@'
  151. #define _C_CLASS    '#'
  152. #define _C_SEL      ':'
  153. #define _C_CHR      'c'
  154. #define _C_UCHR     'C'
  155. #define _C_SHT      's'
  156. #define _C_USHT     'S'
  157. #define _C_INT      'i'
  158. #define _C_UINT     'I'
  159. #define _C_LNG      'l'
  160. #define _C_ULNG     'L'
  161. #define _C_FLT      'f'
  162. #define _C_DBL      'd'
  163. #define _C_BFLD     'b'
  164. #define _C_VOID     'v'
  165. #define _C_UNDEF    '?'
  166. #define _C_PTR      '^'
  167. #define _C_CHARPTR  '*'
  168. #define _C_ATOM     '%'
  169. #define _C_ARY_B    '['
  170. #define _C_ARY_E    ']'
  171. #define _C_UNION_B  '('
  172. #define _C_UNION_E  ')'
  173. #define _C_STRUCT_B '{'
  174. #define _C_STRUCT_E '}'
  175.  
  176.  
  177. /********************************************* compiler-generated structures */
  178.  
  179. /*
  180. ** Whereas a Module (defined further down) is the root (typically) of a file,
  181. ** a Symtab is the root of the class and category definitions within the
  182. ** module.  
  183. ** 
  184. ** A Symtab contains a variable length array of pointers to classes and
  185. ** categories  defined in the module. 
  186. */
  187. typedef struct objc_symtab {
  188.   unsigned long sel_ref_cnt;                     /* Unknown. */
  189.   SEL       *refs;                              /* Unknown. */
  190.   unsigned short cls_def_cnt;                   /* Number of classes compiled
  191.                                                   (defined) in the module. */
  192.   unsigned short cat_def_cnt;                   /* Number of categories 
  193.                                                   compiled (defined) in the 
  194.                                                   module. */
  195.   void      *defs[1];                           /* Variable array of pointers.
  196.                                                   cls_def_cnt of type Class* 
  197.                                                   followed by cat_def_cnt of
  198.                                                   type Category_t. */
  199. } Symtab,   *Symtab_t;
  200.  
  201. /*
  202. ** The compiler generates one of these structures for each module that
  203. ** composes the executable (eg main.m).  
  204. ** 
  205. ** This data structure is the root of the definition tree for the module.  
  206. ** 
  207. ** A collect program runs between ld stages and creates a ObjC ctor array. 
  208. ** That array holds a pointer to each module structure of the executable. 
  209. */
  210. typedef struct objc_module {
  211.   unsigned long version;                        /* Compiler revision. */
  212.   unsigned long size;                           /* sizeof(Module). */
  213.   const char* name;                             /* Name of the file where the 
  214.                                                   module was generated.   The 
  215.                                                   name includes the path. */
  216.   Symtab_t    symtab;                           /* Pointer to the Symtab of
  217.                                                   the module.  The Symtab
  218.                                                   holds an array of pointers to 
  219.                                                   the classes and categories 
  220.                                                   defined in the module. */
  221. } Module, *Module_t;
  222.  
  223. /*
  224. ** The compiler generates one of these structures for a class that has
  225. ** instance variables defined in its specification. 
  226. */
  227. typedef struct objc_ivar* Ivar_t;
  228. typedef struct objc_ivar_list {
  229.   int   ivar_count;                             /* Number of structures (Ivar) 
  230.                                                   contained in the list.  One
  231.                                                   structure per instance 
  232.                                                   variable defined in the
  233.                                                   class. */
  234.   struct objc_ivar {
  235.     const char* ivar_name;                      /* Name of the instance
  236.                                                   variable as entered in the
  237.                                                   class definition. */
  238.     const char* ivar_type;                      /* Description of the Ivar's
  239.                                                   type.  Useful for 
  240.                                                   debuggers. */
  241.     int         ivar_offset;                    /* Byte offset from the base 
  242.                                                   address of the instance 
  243.                                                   structure to the variable. */
  244.  
  245.   } ivar_list[1];                               /* Variable length 
  246.                                                   structure. */
  247. } IvarList, *IvarList_t;
  248.  
  249. /*
  250. ** The compiler generates one (or more) of these structures for a class that
  251. ** has methods defined in its specification. 
  252. ** 
  253. ** The implementation of a class can be broken into separate pieces in a file
  254. ** and categories can break them across modules. To handle this problem is a
  255. ** singly linked list of methods. 
  256. */
  257. typedef struct objc_method Method;
  258. typedef Method* Method_t;
  259. typedef struct objc_method_list {
  260.   struct objc_method_list*  method_next;      /* This variable is used to link 
  261.                                                 a method list to another.  It 
  262.                                                 is a singly linked list. */
  263.   int             method_count;               /* Number of methods defined in 
  264.                                                 this structure. */
  265.   struct objc_method {
  266.     SEL         method_name;                  /* This variable is the method's 
  267.                                                 name.  It is a char*. 
  268.                                                   The unique integer passed to 
  269.                                                 objc_msg_send is a char* too.  
  270.                                                 It is compared against 
  271.                                                 method_name using strcmp. */
  272.     const char* method_types;                 /* Description of the method's
  273.                                                 parameter list.  Useful for
  274.                                                 debuggers. */
  275.     IMP         method_imp;                   /* Address of the method in the 
  276.                                                 executable. */
  277.   } method_list[1];                           /* Variable length 
  278.                                                 structure. */
  279. } MethodList, *MethodList_t;
  280.  
  281. struct objc_protocol_list {
  282.   struct objc_protocol_list *next;
  283.   int count;
  284.   Protocol *list[1];
  285. };
  286.  
  287.  
  288. /****************************************************** introspection macros */
  289.  
  290. /*
  291. ** This is used to assure consistent access to the info field of 
  292. ** classes
  293. */
  294. #ifndef HOST_BITS_PER_LONG
  295. #define HOST_BITS_PER_LONG  (sizeof(long)*8)
  296. #endif 
  297.  
  298. #define __CLS_INFO(cls) ((cls)->info)
  299. #define __CLS_ISINFO(cls, mask) ((__CLS_INFO(cls)&mask)==mask)
  300. #define __CLS_SETINFO(cls, mask) (__CLS_INFO(cls) |= mask)
  301.  
  302. /* The structure is of type MetaClass* */
  303. #define _CLS_META 0x2L
  304. #define CLS_ISMETA(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_META))
  305.  
  306.  
  307. /* The structure is of type Class* */
  308. #define _CLS_CLASS 0x1L
  309. #define CLS_ISCLASS(cls) ((cls)&&__CLS_ISINFO(cls, _CLS_CLASS))
  310.  
  311. /*
  312. ** The class is initialized within the runtime.  This means that 
  313. ** it has had correct super and sublinks assigned
  314. */
  315. #define _CLS_RESOLV 0x8L
  316. #define CLS_ISRESOLV(cls) __CLS_ISINFO(cls, _CLS_RESOLV)
  317. #define CLS_SETRESOLV(cls) __CLS_SETINFO(cls, _CLS_RESOLV)
  318.  
  319. /*
  320. ** The class has been send a +initialize message or a such is not 
  321. ** defined for this class
  322. */
  323. #define _CLS_INITIALIZED 0x04L
  324. #define CLS_ISINITIALIZED(cls) __CLS_ISINFO(cls, _CLS_INITIALIZED)
  325. #define CLS_SETINITIALIZED(cls) __CLS_SETINFO(cls, _CLS_INITIALIZED)
  326.  
  327. /*
  328. ** The class number of this class.  This must be the same for both the 
  329. ** class and it's meta class object
  330. */
  331. #define CLS_GETNUMBER(cls) (__CLS_INFO(cls) >> (HOST_BITS_PER_LONG/2))
  332. #define CLS_SETNUMBER(cls, num) \
  333.   ({ (cls)->info <<= (HOST_BITS_PER_LONG/2); \
  334.      (cls)->info >>= (HOST_BITS_PER_LONG/2); \
  335.      __CLS_SETINFO(cls, (((unsigned long)num) << (HOST_BITS_PER_LONG/2))); })
  336.  
  337.  
  338. /***************************************************** more compiler structs */
  339.  
  340. /*
  341. ** The compiler generates one of these structures for each category.  A class
  342. ** may have many categories and contain both instance and factory methods.  
  343. */
  344. typedef struct objc_category {
  345.   const char*   category_name;                /* Name of the category.  Name
  346.                                                 contained in the () of the
  347.                                                 category definition. */
  348.   const char*   class_name;                   /* Name of the class to which
  349.                                                 the category belongs. */
  350.   MethodList_t  instance_methods;             /* Linked list of instance
  351.                                                 methods defined in the 
  352.                                                 category. NULL indicates no
  353.                                                 instance methods defined. */
  354.   MethodList_t  class_methods;                /* Linked list of factory 
  355.                                                 methods defined in the
  356.                                                 category.  NULL indicates no
  357.                                                 class methods defined. */
  358.   struct objc_protocol_list *protocols;          /* List of Protocols 
  359.                              conformed to */
  360. } Category, *Category_t;
  361.  
  362. /*
  363. ** Structure used when a message is send to a class's super class.  The
  364. ** compiler generates one of these structures and passes it to
  365. ** objc_msg_super.
  366. */
  367. typedef struct objc_super {
  368.   id      self;                           /* Id of the object sending
  369.                                              the message. */
  370.   OCClass* class;                         /* Object's super class. */
  371. } Super, *Super_t;
  372.  
  373. IMP objc_msg_lookup_super(Super_t super, SEL sel);
  374.  
  375. retval_t objc_msg_sendv(id, SEL, arglist_t);
  376.  
  377.  
  378. /********************************************************* encoding of types */
  379.  
  380. #define _C_CONST    'r'
  381. #define _C_IN       'n'
  382. #define _C_INOUT    'N'
  383. #define _C_OUT      'o'
  384. #define _C_BYCOPY   'O'
  385. #define _C_ONEWAY   'V'
  386.  
  387. #define _F_CONST    0x01
  388. #define _F_IN       0x01
  389. #define _F_OUT      0x02
  390. #define _F_INOUT    0x03
  391. #define _F_BYCOPY   0x04
  392. #define _F_ONEWAY   0x08
  393.  
  394.  
  395. /************************************************************** library base */
  396.  
  397. #define OBJCNAME "objc-5-2-3.library"
  398. #define OBJCVERSION 0
  399.  
  400. struct ObjcBase
  401. {
  402.   struct Library lb_LibNode;
  403. };
  404.  
  405.  
  406. /********************************************************* memory management */
  407.  
  408. typedef void NXZone; /* No introspection allowed */
  409.  
  410. #define vm_page_size  4096            /* The standard page size of an MC68040 MMU */
  411. #define NX_NOZONE     ((NXZone *)0)   /* No zone */
  412.  
  413. /* Redefine standard memory functions */
  414. #define malloc(size) NXZoneMalloc(NXDefaultMallocZone(),size)
  415. #define calloc(num,size) NXZoneCalloc(NXDefaultMallocZone(),num,size)
  416. #define realloc(block,size) NXZoneRealloc(NXDefaultMallocZone(),block,size)
  417. #define free(block) NXZoneFree(NXZoneFromPtr(block),block)
  418.  
  419. /* NX memory functions with integrated typecasting */
  420. #define NX_MALLOC(VAR,TYPE,NUM) ((VAR)=(TYPE*)malloc((unsigned)(NUM)*sizeof(TYPE)))
  421. #define NX_REALLOC(VAR,TYPE,NUM) ((VAR)=(TYPE*)realloc((VAR),(unsigned)(NUM)*sizeof(TYPE)))
  422. #define NX_FREE(PTR) free((PTR));
  423.  
  424.  
  425. /************************************************************* sparse arrays */
  426.  
  427. #define OBJC_SPARSE2        /* 2-level sparse array */
  428. /* #define OBJC_SPARSE3 */      /* 3-level sparse array */
  429.  
  430. #ifdef OBJC_SPARSE2
  431. extern const char* __objc_sparse2_id;
  432. #endif
  433.  
  434. #ifdef OBJC_SPARSE3
  435. extern const char* __objc_sparse3_id;
  436. #endif
  437.  
  438.  
  439. extern int nbuckets;        /* for stats */
  440. extern int nindices;
  441. extern int narrays;
  442. extern int idxsize;
  443.  
  444.  
  445. /* An unsigned integer of same size as a pointer */
  446. #define SIZET_BITS (sizeof(size_t)*8)
  447.  
  448. #if defined(sparc) || defined(OBJC_SPARSE2)
  449. #define PRECOMPUTE_SELECTORS
  450. #endif
  451.  
  452. #ifdef OBJC_SPARSE3
  453.  
  454. /* Buckets are 8 words each */
  455. #define BUCKET_BITS 3
  456. #define BUCKET_SIZE (1<<BUCKET_BITS)
  457. #define BUCKET_MASK (BUCKET_SIZE-1)
  458.  
  459. /* Indices are 16 words each */
  460. #define INDEX_BITS 4
  461. #define INDEX_SIZE (1<<INDEX_BITS)
  462. #define INDEX_MASK (INDEX_SIZE-1)
  463.  
  464. #define INDEX_CAPACITY (BUCKET_SIZE*INDEX_SIZE)
  465.  
  466. #else /* OBJC_SPARSE2 */
  467.  
  468. /* Buckets are 32 words each */
  469. #define BUCKET_BITS 5
  470. #define BUCKET_SIZE (1<<BUCKET_BITS)
  471. #define BUCKET_MASK (BUCKET_SIZE-1)
  472.  
  473. #endif /* OBJC_SPARSE2 */
  474.  
  475. typedef size_t sidx;
  476.  
  477. #ifdef PRECOMPUTE_SELECTORS
  478.  
  479. struct soffset {
  480. #ifdef OBJC_SPARSE3
  481.   unsigned int unused : SIZET_BITS/4;
  482.   unsigned int eoffset : SIZET_BITS/4;
  483.   unsigned int boffset : SIZET_BITS/4;
  484.   unsigned int ioffset : SIZET_BITS/4;
  485. #else /* OBJC_SPARSE2 */
  486. #ifdef sparc
  487.   unsigned int boffset : (SIZET_BITS - 2) - BUCKET_BITS;
  488.   unsigned int eoffset : BUCKET_BITS;
  489.   unsigned int unused  : 2;
  490. #else
  491.   unsigned int boffset : SIZET_BITS/2;
  492.   unsigned int eoffset : SIZET_BITS/2;
  493. #endif
  494. #endif /* OBJC_SPARSE2 */
  495. };
  496.  
  497. union sofftype {
  498.   struct soffset off;
  499.   sidx idx;
  500. };
  501.  
  502. #endif /* not PRECOMPUTE_SELECTORS */
  503.  
  504. struct sbucket {
  505.   void* elems[BUCKET_SIZE];    /* elements stored in array */
  506.   short version;            /* used for copy-on-write */
  507. };
  508.  
  509. #ifdef OBJC_SPARSE3
  510.  
  511. struct sindex {
  512.   struct sbucket* buckets[INDEX_SIZE];
  513.   short version;
  514. };
  515.  
  516. #endif /* OBJC_SPARSE3 */
  517.  
  518. struct sarray {
  519. #ifdef OBJC_SPARSE3
  520.   struct sindex** indices;
  521.   struct sindex* empty_index;
  522. #else /* OBJC_SPARSE2 */
  523.   struct sbucket** buckets;
  524. #endif  /* OBJC_SPARSE2 */
  525.   struct sbucket* empty_bucket;
  526.   short version;
  527.   short ref_count;
  528.   struct sarray* is_copy_of;
  529.   int capacity;
  530. };
  531.  
  532.  
  533. #ifdef PRECOMPUTE_SELECTORS
  534. /* Transform soffset values to ints and vica verca */
  535. static inline unsigned int
  536. soffset_decode(sidx index)
  537. {
  538.   union sofftype x;
  539.   x.idx = index;
  540. #ifdef OBJC_SPARSE3
  541.   return x.off.eoffset
  542.     + (x.off.boffset*BUCKET_SIZE)
  543.       + (x.off.ioffset*INDEX_CAPACITY);
  544. #else /* OBJC_SPARSE2 */
  545.   return x.off.eoffset + (x.off.boffset*BUCKET_SIZE);
  546. #endif /* OBJC_SPARSE2 */
  547. }
  548.  
  549. static inline sidx
  550. soffset_encode(size_t offset)
  551. {
  552.   union sofftype x;
  553.   x.off.eoffset = offset%BUCKET_SIZE;
  554. #ifdef OBJC_SPARSE3
  555.   x.off.boffset = (offset/BUCKET_SIZE)%INDEX_SIZE;
  556.   x.off.ioffset = offset/INDEX_CAPACITY;
  557. #else /* OBJC_SPARSE2 */
  558.   x.off.boffset = offset/BUCKET_SIZE;
  559. #endif
  560.   return (sidx)x.idx;
  561. }
  562.  
  563. #else /* not PRECOMPUTE_SELECTORS */
  564.  
  565. static inline size_t
  566. soffset_decode(sidx index)
  567. {
  568.   return index;
  569. }
  570.  
  571. static inline sidx
  572. soffset_encode(size_t offset)
  573. {
  574.   return offset;
  575. }
  576. #endif /* not PRECOMPUTE_SELECTORS */
  577.  
  578. /* Get element from the Sparse array `array' at offset `index' */
  579.  
  580. static inline void* sarray_get(struct sarray* array, sidx index)
  581. {
  582. #ifdef PRECOMPUTE_SELECTORS
  583.   union sofftype x;
  584.   x.idx = index;
  585. #ifdef OBJC_SPARSE3
  586.   return 
  587.     array->
  588.       indices[x.off.ioffset]->
  589.     buckets[x.off.boffset]->
  590.       elems[x.off.eoffset];
  591. #else /* OBJC_SPARSE2 */
  592.   return array->buckets[x.off.boffset]->elems[x.off.eoffset];
  593. #endif /* OBJC_SPARSE2 */
  594. #else /* not PRECOMPUTE_SELECTORS */
  595. #ifdef OBJC_SPARSE3
  596.   return array->
  597.     indices[index/INDEX_CAPACITY]->
  598.       buckets[(index/BUCKET_SIZE)%INDEX_SIZE]->
  599.     elems[index%BUCKET_SIZE];
  600. #else /* OBJC_SPARSE2 */
  601.   return array->buckets[index/BUCKET_SIZE]->elems[index%BUCKET_SIZE];
  602. #endif /* not OBJC_SPARSE3 */
  603. #endif /* not PRECOMPUTE_SELECTORS */
  604. }
  605.  
  606. static inline void* sarray_get_safe(struct sarray* array, sidx index)
  607. {
  608.   if(soffset_decode(index) < array->capacity)
  609.     return sarray_get(array, index);
  610.   else
  611.     return (array->empty_bucket->elems[0]);
  612. }
  613.  
  614.  
  615. /************************************************************ atom emulation */
  616.  
  617. typedef const char *NXAtom; /* A unique string */
  618.  
  619.  
  620. /*************************************************** private data structures */
  621.  
  622. struct __objclib_init_data
  623. {
  624.   void *globaldata;
  625.   void (*abort)(void);
  626. };
  627.  
  628.  
  629. /******************************************************************* the end */
  630.  
  631. #ifdef __cplusplus
  632. }
  633. #endif
  634.  
  635. #endif    /* LIBRARIES_OBJC_H */
  636.