/ lib / BlocksRuntime / Block_private.h
Block_private.h
  1  /*
  2   * Block_private.h
  3   *
  4   * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,
  5   * to any person obtaining a copy of this software and associated documentation
  6   * files (the "Software"), to deal in the Software without restriction,
  7   * including without limitation the rights to use, copy, modify, merge, publish,
  8   * distribute, sublicense, and/or sell copies of the Software, and to permit
  9   * persons to whom the Software is furnished to do so, subject to the following
 10   * conditions:
 11   * 
 12   * The above copyright notice and this permission notice shall be included in
 13   * all copies or substantial portions of the Software.
 14   * 
 15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 21   * SOFTWARE.
 22   *
 23   */
 24  
 25  #ifndef _BLOCK_PRIVATE_H_
 26  #define _BLOCK_PRIVATE_H_
 27  
 28  #if !defined(BLOCK_EXPORT)
 29  #   if defined(__cplusplus)
 30  #       define BLOCK_EXPORT extern "C" 
 31  #   else
 32  #       define BLOCK_EXPORT extern
 33  #   endif
 34  #endif
 35  
 36  #ifndef _MSC_VER
 37  #include <stdbool.h>
 38  #else
 39  /* MSVC doesn't have <stdbool.h>. Compensate. */
 40  typedef char bool;
 41  #define true (bool)1
 42  #define false (bool)0
 43  #endif
 44  
 45  #if defined(__cplusplus)
 46  extern "C" {
 47  #endif
 48  
 49  
 50  enum {
 51      BLOCK_REFCOUNT_MASK =     (0xffff),
 52      BLOCK_NEEDS_FREE =        (1 << 24),
 53      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
 54      BLOCK_HAS_CTOR =          (1 << 26), /* Helpers have C++ code. */
 55      BLOCK_IS_GC =             (1 << 27),
 56      BLOCK_IS_GLOBAL =         (1 << 28),
 57      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
 58  };
 59  
 60  
 61  /* Revised new layout. */
 62  struct Block_descriptor {
 63      unsigned long int reserved;
 64      unsigned long int size;
 65      void (*copy)(void *dst, void *src);
 66      void (*dispose)(void *);
 67  };
 68  
 69  
 70  struct Block_layout {
 71      void *isa;
 72      int flags;
 73      int reserved; 
 74      void (*invoke)(void *, ...);
 75      struct Block_descriptor *descriptor;
 76      /* Imported variables. */
 77  };
 78  
 79  
 80  struct Block_byref {
 81      void *isa;
 82      struct Block_byref *forwarding;
 83      int flags; /* refcount; */
 84      int size;
 85      void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
 86      void (*byref_destroy)(struct Block_byref *);
 87      /* long shared[0]; */
 88  };
 89  
 90  
 91  struct Block_byref_header {
 92      void *isa;
 93      struct Block_byref *forwarding;
 94      int flags;
 95      int size;
 96  };
 97  
 98  
 99  /* Runtime support functions used by compiler when generating copy/dispose helpers. */
100  
101  enum {
102      /* See function implementation for a more complete description of these fields and combinations */
103      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), block, ... */
104      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
105      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block variable */
106      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy helpers */
107      BLOCK_BYREF_CALLER      = 128  /* called from __block (byref) copy/dispose support routines. */
108  };
109  
110  /* Runtime entry point called by compiler when assigning objects inside copy helper routines */
111  BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
112      /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */
113  
114  
115  /* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
116  BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
117  
118  
119  
120  /* Other support functions */
121  
122  /* Runtime entry to get total size of a closure */
123  BLOCK_EXPORT unsigned long int Block_size(void *block_basic);
124  
125  
126  
127  /* the raw data space for runtime classes for blocks */
128  /* class+meta used for stack, malloc, and collectable based blocks */
129  BLOCK_EXPORT void * _NSConcreteStackBlock[32];
130  BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
131  BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
132  BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
133  BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
134  BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
135  
136  
137  /* the intercept routines that must be used under GC */
138  BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
139                                    void (*setHasRefcount)(const void *, const bool),
140                                    void (*gc_assign_strong)(void *, void **),
141                                    void (*gc_assign_weak)(const void *, void *),
142                                    void (*gc_memmove)(void *, void *, unsigned long));
143  
144  /* earlier version, now simply transitional */
145  BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
146                                    void (*setHasRefcount)(const void *, const bool),
147                                    void (*gc_assign_strong)(void *, void **),
148                                    void (*gc_assign_weak)(const void *, void *));
149  
150  BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
151                                   void (*release)(const void *));
152  
153  /* make a collectable GC heap based Block.  Not useful under non-GC. */
154  BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
155  
156  /* thread-unsafe diagnostic */
157  BLOCK_EXPORT const char *_Block_dump(const void *block);
158  
159  
160  /* Obsolete */
161  
162  /* first layout */
163  struct Block_basic {
164      void *isa;
165      int Block_flags;  /* int32_t */
166      int Block_size;  /* XXX should be packed into Block_flags */
167      void (*Block_invoke)(void *);
168      void (*Block_copy)(void *dst, void *src);  /* iff BLOCK_HAS_COPY_DISPOSE */
169      void (*Block_dispose)(void *);             /* iff BLOCK_HAS_COPY_DISPOSE */
170      /* long params[0];  // where const imports, __block storage references, etc. get laid down */
171  };
172  
173  
174  #if defined(__cplusplus)
175  }
176  #endif
177  
178  
179  #endif /* _BLOCK_PRIVATE_H_ */