meta_modelica_data.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * This file is part of OpenModelica.
  3. *
  4. * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC),
  5. * c/o Linköpings universitet, Department of Computer and Information Science,
  6. * SE-58183 Linköping, Sweden.
  7. *
  8. * All rights reserved.
  9. *
  10. * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
  11. * GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
  12. * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
  13. * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
  14. * ACCORDING TO RECIPIENTS CHOICE.
  15. *
  16. * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
  17. * Public License (OSMC-PL) are obtained from OSMC, either from the above
  18. * address, from the URLs: http://www.openmodelica.org or
  19. * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica
  20. * distribution. GNU version 3 is obtained from:
  21. * http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from:
  22. * http://www.opensource.org/licenses/BSD-3-Clause.
  23. *
  24. * This program is distributed WITHOUT ANY WARRANTY; without even the implied
  25. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS
  26. * EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE
  27. * CONDITIONS OF OSMC-PL.
  28. *
  29. */
  30. /* File: meta_modelica_data.h
  31. * Description: This is the C header file for the definitions of the
  32. * MetaModelicaC data types.
  33. */
  34. #ifndef META_MODELICA_DATA_H_
  35. #define META_MODELICA_DATA_H_
  36. #include "util/omc_init.h"
  37. #include "util/base_array.h"
  38. /*
  39. *
  40. * adrpo: define this to have mmk_mk_* function tracing
  41. * #define MMC_MK_DEBUG
  42. *
  43. */
  44. #if 0 /* Enable if you need to debug some MMC runtime assertions */
  45. #define MMC_DEBUG_ASSERT(x) assert(x)
  46. #else
  47. #define MMC_DEBUG_ASSERT(x)
  48. #endif
  49. #define MMC_CHECK_STRING(x) MMC_DEBUG_ASSERT(!((MMC_STRLEN(x) != strlen(MMC_STRINGDATA(x))) && (MMC_STRLEN(x) >=0)))
  50. #define MMC_SIZE_META sizeof(void*)
  51. #define MMC_WORDS_TO_BYTES(x) ((x) * MMC_SIZE_META)
  52. /*
  53. * a slot is a word on any platform!
  54. * the maximum slots in a free slot is
  55. * - 2^(32-10) + 1 (header) on 32 bit systems
  56. * - 2^(64-10) + 1 (header) on 64 bit systems
  57. */
  58. #if defined(_LP64) || defined(_LLP64) || defined(_WIN64)
  59. #define MMC_MAX_SLOTS (18014398509481984) /* max words slots header */
  60. #else
  61. #define MMC_MAX_SLOTS (4194304) /* max words slots header */
  62. #endif
  63. /* max object size on 32/64 bit systems in bytes */
  64. #define MMC_MAX_OBJECT_SIZE_BYTES MMC_WORDS_TO_BYTES(MMC_MAX_SLOTS)
  65. #if defined(_LP64)
  66. #define MMC_SIZE_DBL 8
  67. #define MMC_SIZE_INT 8
  68. #define MMC_LOG2_SIZE_INT 3
  69. #define PRINT_MMC_SINT_T "ld"
  70. #define PRINT_MMC_UINT_T "lu"
  71. typedef unsigned long mmc_uint_t;
  72. typedef long mmc_sint_t;
  73. #elif defined(_LLP64) || defined(_WIN64) || defined(__MINGW64__)
  74. #define MMC_SIZE_DBL 8
  75. #define MMC_SIZE_INT 8
  76. #define MMC_LOG2_SIZE_INT 3
  77. #ifndef PRIu64
  78. #define PRIu64 "I64u"
  79. #endif
  80. #ifndef PRId64
  81. #define PRId64 "I64d"
  82. #endif
  83. #define PRINT_MMC_SINT_T PRId64
  84. #define PRINT_MMC_UINT_T PRIu64
  85. typedef unsigned long long mmc_uint_t;
  86. typedef long long mmc_sint_t;
  87. #else
  88. #define MMC_SIZE_DBL 8
  89. #define MMC_SIZE_INT 4
  90. #define MMC_LOG2_SIZE_INT 2
  91. #define PRINT_MMC_SINT_T "ld"
  92. #define PRINT_MMC_UINT_T "lu"
  93. typedef unsigned int mmc_uint_t;
  94. typedef int mmc_sint_t;
  95. #endif
  96. /* adrpo: circumvent MinGW GCC 4.4.0 bugs with optimization */
  97. #if defined(__MINGW32__)
  98. #define GCC_VERSION (__GNUC__ * 10000 \
  99. + __GNUC_MINOR__ * 100 \
  100. + __GNUC_PATCHLEVEL__)
  101. /* Test for MinGW GCC = 4.4.0 */
  102. #if (GCC_VERSION == 40400)
  103. typedef float mmc_switch_type;
  104. #define MMC_SWITCH_CAST(X) ((int)X)
  105. #else /* not MinGW GCC 4.4.0 */
  106. typedef int mmc_switch_type;
  107. #define MMC_SWITCH_CAST(X) (X)
  108. #endif
  109. #else /* not MINGW */
  110. typedef int mmc_switch_type;
  111. #define MMC_SWITCH_CAST(X) (X)
  112. #endif
  113. #define RML_STYLE_TAGPTR
  114. #ifdef RML_STYLE_TAGPTR
  115. /* RML-style tagged pointers */
  116. #define MMC_TAGPTR(p) ((void*)((char*)(p) + 3))
  117. #define MMC_UNTAGPTR(x) ((void*)((char*)(x) - 3))
  118. #define MMC_IS_INTEGER(X) (0 == ((mmc_sint_t) X & 1))
  119. #define MMC_TAGFIXNUM(i) (((i) << 1)+0)
  120. #define MMC_UNTAGFIXNUM(X) (((mmc_sint_t) (X)) >> 1)
  121. #else
  122. #define MMC_TAGPTR(p) ((void*)((char*)(p) + 0))
  123. #define MMC_UNTAGPTR(x) ((void*)((char*)(x) - 0))
  124. #define MMC_IS_INTEGER(X) (1 == ((mmc_sint_t) X & 1))
  125. #define MMC_TAGFIXNUM(i) (((i) << 1)+1)
  126. #define MMC_UNTAGFIXNUM(X) (((mmc_sint_t) (X-1)) >> 1)
  127. #endif
  128. #define MMC_STRUCTHDR(_slots,ctor) (((_slots) << 10) + (((ctor) & 255) << 2))
  129. #define MMC_NILHDR MMC_STRUCTHDR(0,0)
  130. #define MMC_CONSHDR MMC_STRUCTHDR(2,1)
  131. #define MMC_NONEHDR MMC_STRUCTHDR(0,1)
  132. #define MMC_OFFSET(p,i) ((void*)((void**)(p) + (i)))
  133. #define MMC_FETCH(p) (*(void**)(p))
  134. #define MMC_CAR(X) MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(X),1))
  135. #define MMC_CDR(X) MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(X),2))
  136. #define MMC_NILTEST(x) (MMC_GETHDR(x) == MMC_NILHDR)
  137. #define MMC_IMMEDIATE(i) ((void*)(i))
  138. #define MMC_IS_IMMEDIATE(x) (MMC_IS_INTEGER(x))
  139. #define MMC_REALHDR (((MMC_SIZE_DBL/MMC_SIZE_INT) << 10) + 9)
  140. #define MMC_HDR_IS_FORWARD(hdr) (((hdr) & 3) == 3)
  141. /*
  142. #define MMC_REALDATA(x) (*((double*)(((mmc_uint_t*)MMC_UNTAGPTR(x))+1)))
  143. */
  144. #define MMC_REALDATA(x) (((struct mmc_real*)MMC_UNTAGPTR(x))->data)
  145. #define MMC_GETHDR(x) (*(mmc_uint_t*)MMC_UNTAGPTR(x))
  146. #define MMC_STRINGHDR(nbytes) ((((mmc_uint_t)nbytes)<<(3))+((1<<(3+MMC_LOG2_SIZE_INT))+5))
  147. #define MMC_HDRISSTRING(hdr) (((hdr) & (7)) == 5)
  148. #define MMC_HDRSTRLEN(hdr) (((hdr) >> (3)) - MMC_SIZE_INT)
  149. #define MMC_STRINGDATA(x) (((struct mmc_string*)MMC_UNTAGPTR(x))->data)
  150. #define MMC_HDRSTRINGSLOTS(hdr) (hdr >> (3+MMC_LOG2_SIZE_INT))
  151. #define MMC_HDRSLOTS(hdr) ((MMC_HDRISSTRING(hdr)) ? (MMC_HDRSTRINGSLOTS(hdr)) : ((hdr) >> 10))
  152. #define MMC_HDRCTOR(hdr) (((hdr) >> 2) & 255)
  153. #define MMC_HDRISSTRUCT(hdr) (!((hdr) & 3))
  154. #define MMC_STRUCTDATA(x) (((struct mmc_struct*)MMC_UNTAGPTR(x))->data)
  155. #define MMC_ARRAY_TAG 255
  156. #define MMC_STRLEN(x) (MMC_HDRSTRLEN(MMC_GETHDR(x)))
  157. #define MMC_OPTIONNONE(x) (0==MMC_HDRSLOTS(MMC_GETHDR(x)) ? 1 : 0)
  158. #define MMC_OPTIONSOME(x) (0==MMC_HDRSLOTS(MMC_GETHDR(x)) ? 0 : 1)
  159. /*
  160. * adrpo: if a structure has pointers
  161. * Bit 0 is zero if the node contains pointers, 1 otherwise.
  162. */
  163. #define MMC_HDRHASPTRS(hdr) (!((hdr) & 1))
  164. /*
  165. * adrpo: if this object was marked, used by GC!
  166. * [xxxxxxxx1x] (used during garbage collection) a marked node;
  167. */
  168. #define MMC_HDRISMARKED(hdr) ((hdr) & 2)
  169. #define MMC_HDR_MARK(hdr) ((hdr) | 2)
  170. #define MMC_HDR_UNMARK(hdr) ((hdr) & ~((mmc_uint_t)2))
  171. #define MMC_INT_MAX ((1<<30)-1)
  172. #define MMC_INT_MIN (-(1<<30))
  173. #define MMC_DEFSTRUCTLIT(NAME,LEN,CON) \
  174. struct { \
  175. mmc_uint_t header; \
  176. const void *data[LEN]; \
  177. } NAME = { MMC_STRUCTHDR(LEN,CON),
  178. #define MMC_DEFSTRUCT0LIT(NAME,CON) struct mmc_header NAME = { MMC_STRUCTHDR(0,CON) }
  179. #define MMC_REFSTRUCTLIT(NAME) MMC_TAGPTR(&(NAME).header)
  180. #define MMC_DEFSTRINGLIT(NAME,LEN,VAL) \
  181. struct { \
  182. mmc_uint_t header; \
  183. const char data[LEN+1]; \
  184. } NAME = { MMC_STRINGHDR(LEN), VAL }
  185. #define MMC_REFSTRINGLIT(NAME) MMC_TAGPTR(&(NAME).header)
  186. /* Unboxing */
  187. #define mmc_unbox_boolean(X) MMC_UNTAGFIXNUM(X)
  188. #define mmc_unbox_integer(X) MMC_UNTAGFIXNUM(X)
  189. #define mmc_unbox_real(X) mmc_prim_get_real(X)
  190. #define mmc_unbox_string(X) MMC_STRINGDATA(X)
  191. #define mmc_unbox_array(X) (*((base_array_t*)X))
  192. #define mmc_mk_integer mmc_mk_icon
  193. #define mmc_mk_boolean mmc_mk_bcon
  194. #define mmc_mk_real mmc_mk_rcon
  195. void* mmc_mk_modelica_array(base_array_t);
  196. void mmc_catch_dummy_fn();
  197. #define MMC_INIT(X) pthread_once(&mmc_init_once,mmc_init)
  198. #define MMC_TRY_INTERNAL(X) { jmp_buf new_mmc_jumper, *old_jumper __attribute__((unused)) = threadData->X; threadData->X = &new_mmc_jumper; if (setjmp(new_mmc_jumper) == 0) {
  199. #define MMC_TRY() { threadData_t *threadData = pthread_getspecific(mmc_thread_data_key); MMC_TRY_INTERNAL(mmc_jumper)
  200. #if !defined(_MSC_VER)
  201. #define MMC_CATCH_INTERNAL(X) } threadData->X = old_jumper;mmc_catch_dummy_fn();}
  202. #else
  203. #define MMC_CATCH_INTERNAL(X) } threadData->X = old_jumper;}
  204. #endif
  205. #define MMC_CATCH() MMC_CATCH_INTERNAL(mmc_jumper)}
  206. #define MMC_THROW_INTERNAL() {longjmp(*threadData->mmc_jumper,1);}
  207. #define MMC_THROW() {longjmp(*((threadData_t*)pthread_getspecific(mmc_thread_data_key))->mmc_jumper,1);}
  208. #define MMC_ELSE() } else { threadData->mmc_jumper = old_jumper;
  209. #define MMC_TRY_TOP() { threadData_t threadDataOnStack = {0}, *oldThreadData = (threadData_t*)pthread_getspecific(mmc_thread_data_key),*threadData = &threadDataOnStack; pthread_setspecific(mmc_thread_data_key,threadData); pthread_mutex_init(&threadData->parentMutex,NULL); mmc_init_stackoverflow(threadData); MMC_TRY_INTERNAL(mmc_jumper) threadData->mmc_stack_overflow_jumper = threadData->mmc_jumper; /* Let the default stack overflow handler be the top-level handler */
  210. #define MMC_TRY_TOP_INTERNAL() { threadData_t *oldThreadData = (threadData_t*)pthread_getspecific(mmc_thread_data_key); pthread_setspecific(mmc_thread_data_key,threadData); pthread_mutex_init(&threadData->parentMutex,NULL); mmc_init_stackoverflow(threadData); MMC_TRY_INTERNAL(mmc_jumper) threadData->mmc_stack_overflow_jumper = threadData->mmc_jumper;
  211. #define MMC_CATCH_TOP(X) pthread_setspecific(mmc_thread_data_key,oldThreadData); } else {pthread_setspecific(mmc_thread_data_key,oldThreadData);X;}}}
  212. /* adrpo: assume MMC_DBL_PAD always! */
  213. struct mmc_real_lit { /* there must be no padding between `header' and `data' */
  214. mmc_uint_t filler;
  215. mmc_uint_t header;
  216. double data;
  217. };
  218. #define MMC_DEFREALLIT(NAME,VAL) struct mmc_real_lit NAME = {0,MMC_REALHDR,VAL}
  219. #define MMC_REFREALLIT(NAME) MMC_TAGPTR(&(NAME).header)
  220. struct mmc_header {
  221. mmc_uint_t header;
  222. };
  223. struct mmc_struct {
  224. mmc_uint_t header; /* MMC_STRUCTHDR(slots,ctor) */
  225. void *data[1]; /* `slots' elements */
  226. };
  227. struct mmc_cons_struct {
  228. mmc_uint_t header; /* MMC_STRUCTHDR(slots,ctor) */
  229. void *data[2]; /* `slots' elements */
  230. };
  231. /* adrpo: assume MMC_DBL_STRICT always! */
  232. struct mmc_real {
  233. mmc_uint_t header; /* MMC_REALHDR */
  234. mmc_uint_t data[MMC_SIZE_DBL/MMC_SIZE_INT];
  235. };
  236. struct mmc_string {
  237. mmc_uint_t header; /* MMC_STRINGHDR(bytes) */
  238. char data[1]; /* `bytes' elements + terminating '\0' */
  239. };
  240. #define MMC_FALSE (mmc_mk_icon(0))
  241. #define MMC_TRUE (mmc_mk_icon(1))
  242. #define mmc_mk_bcon(X) ((X) != 0 ? MMC_TRUE : MMC_FALSE)
  243. #endif /* META_MODELICA_DATA_H_*/