OMCompiler/SimulationRuntime/c/meta/meta_modelica.c
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file belongs to the OpenModelica Run-Time System | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings | ||
| 5 | * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights | ||
| 6 | * reserved. | ||
| 7 | * | ||
| 8 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE | ||
| 9 | * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY | ||
| 10 | * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S | ||
| 11 | * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL | ||
| 12 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 13 | * | ||
| 14 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License | ||
| 15 | * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs: | ||
| 16 | * http://www.openmodelica.org or https://github.com/OpenModelica/ or | ||
| 17 | * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU | ||
| 18 | * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW | ||
| 19 | * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause. | ||
| 20 | * | ||
| 21 | * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY | ||
| 23 | * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF | ||
| 24 | * OSMC-PL. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include "../openmodelica.h" | ||
| 29 | #include "meta_modelica_string.h" | ||
| 30 | |||
| 31 | 36527256 | void* stringAppend(void *s1, void *s2) | |
| 32 | { | ||
| 33 | unsigned len1, len2, nbytes; | ||
| 34 | void *res; | ||
| 35 | MMC_CHECK_STRING(s1); | ||
| 36 | MMC_CHECK_STRING(s2); | ||
| 37 | 36527256 | len1 = MMC_STRLEN(s1); | |
| 38 | 36527256 | len2 = MMC_STRLEN(s2); | |
| 39 |
2/2✓ Branch 0 taken 36333995 times.
✓ Branch 1 taken 193261 times.
|
36527256 | if (len1 == 0) return s2; |
| 40 |
2/2✓ Branch 0 taken 33491052 times.
✓ Branch 1 taken 2842943 times.
|
36333995 | if (len2 == 0) return s1; |
| 41 | 33491052 | nbytes = len1 + len2; | |
| 42 | 33491052 | res = mmc_mk_scon_len(nbytes); | |
| 43 | 33491052 | memcpy(MMC_STRINGDATA(res), MMC_STRINGDATA(s1), len1); | |
| 44 | 33491052 | memcpy(MMC_STRINGDATA(res) + len1, MMC_STRINGDATA(s2), len2 + 1); | |
| 45 | MMC_CHECK_STRING(res); | ||
| 46 | 33491052 | return res; | |
| 47 | } | ||
| 48 | |||
| 49 | 1116453487 | modelica_integer mmc_stringCompare(const void *str1, const void *str2) | |
| 50 | { | ||
| 51 | int res; | ||
| 52 | MMC_CHECK_STRING(str1); | ||
| 53 | MMC_CHECK_STRING(str2); | ||
| 54 | 1116453487 | res = strcmp(MMC_STRINGDATA(str1), MMC_STRINGDATA(str2)); | |
| 55 |
2/2✓ Branch 0 taken 692633393 times.
✓ Branch 1 taken 423820094 times.
|
1116453487 | if (res < 0) return -1; |
| 56 |
2/2✓ Branch 0 taken 377418445 times.
✓ Branch 1 taken 315214948 times.
|
692633393 | if (res > 0) return 1; |
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | #include "meta_modelica.h" | ||
| 61 | #include "meta_modelica_builtin.h" | ||
| 62 | #include "../util/base_array.h" | ||
| 63 | #include <stdio.h> | ||
| 64 | #include <limits.h> | ||
| 65 | #include <stdlib.h> | ||
| 66 | #include <string.h> | ||
| 67 | |||
| 68 | /* | ||
| 69 | void* mmc_mk_rcon(double d) | ||
| 70 | { | ||
| 71 | void *p = mmc_alloc_words(MMC_SIZE_DBL/MMC_SIZE_INT+1); | ||
| 72 | ((mmc_uint_t*)p)[0] = MMC_REALHDR; | ||
| 73 | *((double*)((mmc_uint_t*)p+1)) = d; | ||
| 74 | p = MMC_TAGPTR(p); | ||
| 75 | #ifdef MMC_MK_DEBUG | ||
| 76 | fprintf(stderr, "REAL size: %u\n", MMC_SIZE_DBL/MMC_SIZE_INT+1); fflush(NULL); | ||
| 77 | #endif | ||
| 78 | return p; | ||
| 79 | } | ||
| 80 | */ | ||
| 81 | 38274320 | void* mmc_mk_rcon(double d) | |
| 82 | { | ||
| 83 | struct mmc_real *p = (struct mmc_real*)mmc_alloc_words_atomic(MMC_SIZE_DBL/MMC_SIZE_INT + 1); | ||
| 84 | mmc_prim_set_real(p, d); | ||
| 85 | 38274320 | p->header = MMC_REALHDR; | |
| 86 | #ifdef MMC_MK_DEBUG | ||
| 87 | fprintf(stderr, "REAL size: %u\n", MMC_SIZE_DBL/MMC_SIZE_INT+1); fflush(NULL); | ||
| 88 | #endif | ||
| 89 | 38274320 | return MMC_TAGPTR(p); | |
| 90 | } | ||
| 91 | |||
| 92 | ✗ | void* mmc_mk_modelica_array(base_array_t arr) | |
| 93 | { | ||
| 94 | base_array_t *cpy = mmc_alloc_words(sizeof(arr)/sizeof(void*) + 1); | ||
| 95 | memcpy(cpy, &arr, sizeof(base_array_t)); | ||
| 96 | ✗ | clone_base_array_spec(&arr, cpy); | |
| 97 | /* Note: The data is hopefully not stack-allocated and can be passed this way */ | ||
| 98 | ✗ | return cpy; | |
| 99 | } | ||
| 100 | |||
| 101 | 120 | void* mmc_mk_box_arr(mmc_sint_t slots, mmc_uint_t ctor, void** args) | |
| 102 | { | ||
| 103 | mmc_sint_t i; | ||
| 104 | 120 | struct mmc_struct *p = (struct mmc_struct*)mmc_alloc_words(slots + 1); | |
| 105 | 120 | p->header = MMC_STRUCTHDR(slots, ctor); | |
| 106 |
2/2✓ Branch 0 taken 466 times.
✓ Branch 1 taken 120 times.
|
586 | for (i = 0; i < slots; i++) { |
| 107 | 466 | p->data[i] = (void*) args[i]; | |
| 108 | } | ||
| 109 | #ifdef MMC_MK_DEBUG | ||
| 110 | fprintf(stderr, "STRUCT slots%d ctor %u\n", slots, ctor); fflush(NULL); | ||
| 111 | #endif | ||
| 112 | 120 | return MMC_TAGPTR(p); | |
| 113 | } | ||
| 114 | |||
| 115 | ✗ | char* mmc_mk_scon_len_ret_ptr(size_t nbytes) | |
| 116 | { | ||
| 117 | ✗ | mmc_uint_t header = MMC_STRINGHDR(nbytes); | |
| 118 | ✗ | mmc_uint_t nwords = MMC_HDRSLOTS(header) + 1; | |
| 119 | struct mmc_string *p; | ||
| 120 | void *res; | ||
| 121 | p = (struct mmc_string *)mmc_alloc_words_atomic(nwords); | ||
| 122 | ✗ | p->header = header; | |
| 123 | res = MMC_TAGPTR(p); | ||
| 124 | ✗ | return MMC_STRINGDATA(res); | |
| 125 | } | ||
| 126 | |||
| 127 | 89241222 | modelica_boolean valueEq(modelica_metatype lhs, modelica_metatype rhs) | |
| 128 | { | ||
| 129 | 89241222 | return 0==valueCompare(lhs, rhs); | |
| 130 | } | ||
| 131 | |||
| 132 | static int intCompare(int i1, int i2) | ||
| 133 | { | ||
| 134 |
6/10✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 10729031 times.
✓ Branch 3 taken 13414865 times.
✓ Branch 4 taken 23810554 times.
✓ Branch 5 taken 14515297 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 12923 times.
✓ Branch 9 taken 53821 times.
|
62536491 | return i1==i2 ? 0 : i1>i2 ? 1 : -1; |
| 135 | } | ||
| 136 | |||
| 137 | static double realCompare(double r1, double r2) | ||
| 138 | { | ||
| 139 |
4/4✓ Branch 0 taken 123918 times.
✓ Branch 1 taken 313675 times.
✓ Branch 2 taken 61843 times.
✓ Branch 3 taken 62075 times.
|
437593 | return r1==r2 ? 0 : r1>r2 ? 1 : -1; |
| 140 | } | ||
| 141 | |||
| 142 | 132102972 | modelica_integer valueCompare(modelica_metatype lhs, modelica_metatype rhs) | |
| 143 | { | ||
| 144 | mmc_uint_t h_lhs; | ||
| 145 | mmc_uint_t h_rhs; | ||
| 146 | mmc_sint_t numslots; | ||
| 147 | mmc_uint_t ctor; | ||
| 148 | mmc_sint_t i; | ||
| 149 | int res; | ||
| 150 | |||
| 151 |
2/2✓ Branch 0 taken 101472578 times.
✓ Branch 1 taken 33071575 times.
|
134544153 | if (lhs == rhs) { |
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 |
1/2✓ Branch 0 taken 101472578 times.
✗ Branch 1 not taken.
|
101472578 | res = intCompare(MMC_IS_INTEGER(lhs), MMC_IS_INTEGER(rhs)); |
| 156 | if (0 != res) { | ||
| 157 | /* Should trigger an assertion for most code */ | ||
| 158 | ✗ | return res; | |
| 159 | } | ||
| 160 | |||
| 161 |
2/2✓ Branch 0 taken 24143896 times.
✓ Branch 1 taken 77328682 times.
|
101472578 | if (MMC_IS_INTEGER(lhs)) { |
| 162 |
1/2✓ Branch 0 taken 24143896 times.
✗ Branch 1 not taken.
|
48287792 | return intCompare(mmc_unbox_integer(lhs), mmc_unbox_integer(rhs)); |
| 163 | } | ||
| 164 | |||
| 165 | 77328682 | h_lhs = MMC_GETHDR(lhs); | |
| 166 | 77328682 | h_rhs = MMC_GETHDR(rhs); | |
| 167 | |||
| 168 |
2/2✓ Branch 0 taken 38325851 times.
✓ Branch 1 taken 39002831 times.
|
77328682 | res = intCompare(h_lhs, h_rhs); |
| 169 | |||
| 170 | if (0 != res) { | ||
| 171 | 38325851 | return res; | |
| 172 | } | ||
| 173 | |||
| 174 |
2/2✓ Branch 0 taken 38927256 times.
✓ Branch 1 taken 75575 times.
|
39002831 | if (h_lhs == MMC_NILHDR) { |
| 175 | return 0; | ||
| 176 | } | ||
| 177 | |||
| 178 |
2/2✓ Branch 0 taken 437593 times.
✓ Branch 1 taken 38489663 times.
|
38927256 | if (h_lhs == MMC_REALHDR) { |
| 179 | 437593 | return realCompare(mmc_prim_get_real(lhs), mmc_prim_get_real(rhs)); | |
| 180 | } | ||
| 181 | |||
| 182 |
2/2✓ Branch 0 taken 5331757 times.
✓ Branch 1 taken 33157906 times.
|
38489663 | if (MMC_HDRISSTRING(h_lhs)) { |
| 183 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5331757 times.
|
5331757 | res = intCompare(MMC_STRLEN(lhs), MMC_STRLEN(rhs)); |
| 184 | 5331757 | return res==0 ? strcmp(MMC_STRINGDATA(lhs),MMC_STRINGDATA(rhs)) : res; | |
| 185 | } | ||
| 186 | |||
| 187 | 33157906 | numslots = MMC_HDRSLOTS(h_lhs); | |
| 188 | 33157906 | ctor = 255 & (h_lhs >> 2); | |
| 189 | |||
| 190 |
2/2✓ Branch 0 taken 28324351 times.
✓ Branch 1 taken 4833555 times.
|
33157906 | if (numslots>0 && ctor > 1) { /* RECORD */ |
| 191 | /* struct record_description * lhs_desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(lhs),1)); | ||
| 192 | struct record_description * rhs_desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(rhs),1)); | ||
| 193 | Slow; not needed | ||
| 194 | if (0 != strcmp(lhs_desc->name,rhs_desc->name)) | ||
| 195 | return 0; | ||
| 196 | */ | ||
| 197 |
2/2✓ Branch 0 taken 39456000 times.
✓ Branch 1 taken 21902083 times.
|
61358083 | for (i = 2; i <= numslots; i++) { |
| 198 | 39456000 | void * lhs_data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(lhs),i)); | |
| 199 | 39456000 | void * rhs_data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(rhs),i)); | |
| 200 | 39456000 | res = valueCompare(lhs_data,rhs_data); | |
| 201 |
2/2✓ Branch 0 taken 6422268 times.
✓ Branch 1 taken 33033732 times.
|
39456000 | if (0 != res) { |
| 202 | 6422268 | return res; | |
| 203 | } | ||
| 204 | } | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 |
2/2✓ Branch 0 taken 251107 times.
✓ Branch 1 taken 4582448 times.
|
4833555 | if (numslots>0 && ctor == 0) { /* TUPLE */ |
| 209 |
2/2✓ Branch 0 taken 264032 times.
✓ Branch 1 taken 8568 times.
|
272600 | for (i = 0; i < numslots; i++) { |
| 210 | void *tlhs, *trhs; | ||
| 211 | 264032 | tlhs = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(lhs),i+1)); | |
| 212 | 264032 | trhs = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(rhs),i+1)); | |
| 213 | 264032 | res = valueCompare(tlhs,trhs); | |
| 214 |
2/2✓ Branch 0 taken 242539 times.
✓ Branch 1 taken 21493 times.
|
264032 | if (0 != res) { |
| 215 | 242539 | return res; | |
| 216 | } | ||
| 217 | } | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 |
2/2✓ Branch 0 taken 4500860 times.
✓ Branch 1 taken 81588 times.
|
4582448 | if (numslots==0 && ctor==1) /* NONE() */ { |
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 |
2/2✓ Branch 0 taken 2441181 times.
✓ Branch 1 taken 2059679 times.
|
4500860 | if (numslots==1 && ctor==1) /* SOME(x) */ { |
| 226 | 2441181 | return valueCompare(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(lhs),1)),MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(rhs),1))); | |
| 227 | } | ||
| 228 | |||
| 229 |
1/2✓ Branch 0 taken 2059679 times.
✗ Branch 1 not taken.
|
2059679 | if (numslots==2 && ctor==1) { /* CONS-PAIR */ |
| 230 |
4/4✓ Branch 0 taken 2936952 times.
✓ Branch 1 taken 931437 times.
✓ Branch 2 taken 2924029 times.
✓ Branch 3 taken 12923 times.
|
3868389 | while (!MMC_NILTEST(lhs) && !MMC_NILTEST(rhs)) { |
| 231 | 2924029 | res = valueCompare(MMC_CAR(lhs),MMC_CAR(rhs)); | |
| 232 |
2/2✓ Branch 0 taken 1115319 times.
✓ Branch 1 taken 1808710 times.
|
2924029 | if (0 != res) { |
| 233 | 1115319 | return res; | |
| 234 | } | ||
| 235 | 1808710 | lhs = MMC_CDR(lhs); | |
| 236 | 1808710 | rhs = MMC_CDR(rhs); | |
| 237 | } | ||
| 238 |
2/2✓ Branch 0 taken 66744 times.
✓ Branch 1 taken 877616 times.
|
1011104 | return intCompare(MMC_NILTEST(lhs), MMC_NILTEST(rhs)); |
| 239 | } | ||
| 240 | |||
| 241 | ✗ | if (numslots==0 && ctor == MMC_ARRAY_TAG) /* zero size array??!! */ { | |
| 242 | return 0; | ||
| 243 | } | ||
| 244 | |||
| 245 | ✗ | fprintf(stderr, "%s:%d: %ld slots; ctor %lu - FAILED to detect the type\n", __FILE__, __LINE__, (long) numslots, (unsigned long) ctor); | |
| 246 | ✗ | EXIT(1); | |
| 247 | } | ||
| 248 | |||
| 249 | ✗ | void debug__print(void* prefix, void* any) | |
| 250 | { | ||
| 251 | ✗ | fprintf(stderr, "%s%s", MMC_STRINGDATA(prefix), anyString(any)); | |
| 252 | ✗ | } | |
| 253 | |||
| 254 | static char *anyStringBuf = 0; | ||
| 255 | mmc_sint_t anyStringBufSize = 0; | ||
| 256 | |||
| 257 | 86 | inline static void checkAnyStringBufSize(mmc_sint_t ix, mmc_sint_t szNewObject) | |
| 258 | { | ||
| 259 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
|
86 | if (anyStringBufSize-ix < szNewObject+1) { |
| 260 | ✗ | anyStringBuf = realloc(anyStringBuf, anyStringBufSize*2 + szNewObject); | |
| 261 | ✗ | assert(anyStringBuf != NULL); | |
| 262 | ✗ | anyStringBufSize = anyStringBufSize*2 + szNewObject; | |
| 263 | } | ||
| 264 | 86 | } | |
| 265 | |||
| 266 | 26 | void initializeStringBuffer(void) | |
| 267 | { | ||
| 268 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 25 times.
|
26 | if (anyStringBufSize == 0) { |
| 269 | 1 | anyStringBuf = malloc(8192); | |
| 270 | 1 | anyStringBufSize = 8192; | |
| 271 | } | ||
| 272 | 26 | *anyStringBuf = '\0'; | |
| 273 | 26 | } | |
| 274 | |||
| 275 | 56 | inline static mmc_sint_t anyStringWork(void* any, mmc_sint_t ix, modelica_metatype stack) | |
| 276 | { | ||
| 277 | mmc_uint_t hdr; | ||
| 278 | mmc_sint_t numslots; | ||
| 279 | mmc_uint_t ctor; | ||
| 280 | mmc_sint_t i; | ||
| 281 | void *data; | ||
| 282 | /* char buf[34] = {0}; */ | ||
| 283 | |||
| 284 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if (MMC_IS_INTEGER(any)) { |
| 285 | ✗ | checkAnyStringBufSize(ix,40); | |
| 286 | ✗ | ix += sprintf(anyStringBuf+ix, "%ld", (mmc_sint_t) MMC_UNTAGFIXNUM(any)); | |
| 287 | ✗ | return ix; | |
| 288 | } | ||
| 289 | |||
| 290 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if (MMC_HDR_IS_FORWARD(MMC_GETHDR(any))) { |
| 291 | ✗ | checkAnyStringBufSize(ix,40); | |
| 292 | ✗ | ix += sprintf(anyStringBuf+ix, "Forward"); | |
| 293 | ✗ | return ix; | |
| 294 | } | ||
| 295 | |||
| 296 | 56 | hdr = MMC_HDR_UNMARK(MMC_GETHDR(any)); | |
| 297 | |||
| 298 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if (hdr == MMC_NILHDR) { |
| 299 | ✗ | checkAnyStringBufSize(ix,2); | |
| 300 | ✗ | ix += sprintf(anyStringBuf+ix, "{NIL}"); | |
| 301 | ✗ | return ix; | |
| 302 | } | ||
| 303 | |||
| 304 |
2/2✓ Branch 0 taken 46 times.
✓ Branch 1 taken 10 times.
|
56 | if (hdr == MMC_REALHDR) { |
| 305 | 46 | checkAnyStringBufSize(ix,40); | |
| 306 | 46 | ix += sprintf(anyStringBuf+ix, "%.7g", (double) mmc_prim_get_real(any)); | |
| 307 | 46 | return ix; | |
| 308 | } | ||
| 309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (MMC_HDRISSTRING(hdr)) { |
| 310 | MMC_CHECK_STRING(any); | ||
| 311 | ✗ | checkAnyStringBufSize(ix,strlen(MMC_STRINGDATA(any))+4); | |
| 312 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", MMC_STRINGDATA(any)); | |
| 313 | ✗ | return ix; | |
| 314 | } | ||
| 315 | |||
| 316 | 10 | numslots = MMC_HDRSLOTS(hdr); | |
| 317 | 10 | ctor = MMC_HDRCTOR(hdr); | |
| 318 | |||
| 319 | /* Ugly hack to "detect" function pointers. If these parameters are outside | ||
| 320 | * these bounds, then we probably have a function pointer. This is just to | ||
| 321 | * keep the debugger from crashing. */ | ||
| 322 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots < 0 || numslots > 1024 || ctor > 255) { |
| 323 | ✗ | checkAnyStringBufSize(ix, 2); | |
| 324 | ✗ | ix += sprintf(anyStringBuf+ix, "0"); | |
| 325 | ✗ | return ix; | |
| 326 | } | ||
| 327 | |||
| 328 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots>0 && ctor == MMC_FREE_OBJECT_CTOR) { /* FREE OBJECT! */ |
| 329 | ✗ | checkAnyStringBufSize(ix,100); | |
| 330 | ✗ | ix += sprintf(anyStringBuf+ix, "FREE(%ld)", (long) numslots); | |
| 331 | ✗ | return ix; | |
| 332 | } | ||
| 333 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots>=0 && ctor == MMC_ARRAY_TAG) { /* MetaModelica-style array */ |
| 334 | ✗ | checkAnyStringBufSize(ix,40); | |
| 335 | ✗ | ix += sprintf(anyStringBuf+ix, "MetaArray("); | |
| 336 | ✗ | for (i = 1; i <= numslots; i++) { | |
| 337 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 338 | ✗ | ix = anyStringWork(data, ix, mmc_mk_cons(data, stack)); | |
| 339 | ✗ | if (i!=numslots) { | |
| 340 | ✗ | checkAnyStringBufSize(ix,3); | |
| 341 | ✗ | ix += sprintf(anyStringBuf+ix, ", "); | |
| 342 | } | ||
| 343 | } | ||
| 344 | ✗ | checkAnyStringBufSize(ix,2); | |
| 345 | ✗ | ix += sprintf(anyStringBuf+ix, ")"); | |
| 346 | ✗ | return ix; | |
| 347 | } | ||
| 348 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots>0 && ctor > 1) { /* RECORD */ |
| 349 | ✗ | struct record_description * desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)); | |
| 350 | ✗ | checkAnyStringBufSize(ix,strlen(desc->name)+2); | |
| 351 | ✗ | ix += sprintf(anyStringBuf+ix, "%s(", desc->name); | |
| 352 | ✗ | for (i = 2; i <= numslots; i++) { | |
| 353 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 354 | ✗ | checkAnyStringBufSize(ix,strlen(desc->fieldNames[i-2])+3); | |
| 355 | ✗ | ix += sprintf(anyStringBuf+ix, "%s = ", desc->fieldNames[i-2]); | |
| 356 | ✗ | ix = anyStringWork(data, ix, mmc_mk_cons(any, mmc_mk_cons(data, stack))); | |
| 357 | ✗ | if (i!=numslots) { | |
| 358 | ✗ | checkAnyStringBufSize(ix,3); | |
| 359 | ✗ | ix += sprintf(anyStringBuf+ix, ", "); | |
| 360 | } | ||
| 361 | } | ||
| 362 | ✗ | checkAnyStringBufSize(ix,2); | |
| 363 | ✗ | ix += sprintf(anyStringBuf+ix, ")"); | |
| 364 | ✗ | return ix; | |
| 365 | } | ||
| 366 | |||
| 367 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots > 0 && ctor == 0) { /* TUPLE */ |
| 368 | /* Pointers.mo, pointer are saved as tuples, check if we have it in the stack so we break the cycle */ | ||
| 369 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)); | |
| 370 | ✗ | if (listMember(data, stack)) | |
| 371 | { | ||
| 372 | ✗ | checkAnyStringBufSize(ix,12); | |
| 373 | ✗ | ix += sprintf(anyStringBuf+ix, "(Pointer())"); | |
| 374 | ✗ | return ix; | |
| 375 | } | ||
| 376 | ✗ | checkAnyStringBufSize(ix,2); | |
| 377 | ✗ | ix += sprintf(anyStringBuf+ix, "("); | |
| 378 | ✗ | for (i = 0; i < numslots; i++) { | |
| 379 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i+1)); | |
| 380 | ✗ | ix = anyStringWork(data, ix, mmc_mk_cons(any, mmc_mk_cons(data, stack))); | |
| 381 | ✗ | if (i != numslots-1) { | |
| 382 | ✗ | checkAnyStringBufSize(ix,3); | |
| 383 | ✗ | ix += sprintf(anyStringBuf+ix, ", "); | |
| 384 | } | ||
| 385 | } | ||
| 386 | ✗ | checkAnyStringBufSize(ix,2); | |
| 387 | ✗ | ix += sprintf(anyStringBuf+ix, ")"); | |
| 388 | ✗ | return ix; | |
| 389 | } | ||
| 390 | |||
| 391 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots == 0 && ctor == 1) /* NONE() */ { |
| 392 | ✗ | checkAnyStringBufSize(ix,7); | |
| 393 | ✗ | ix += sprintf(anyStringBuf+ix, "NONE()"); | |
| 394 | ✗ | return ix; | |
| 395 | } | ||
| 396 | |||
| 397 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
10 | if (numslots==1 && ctor==1) /* SOME(x) */ { |
| 398 | ✗ | checkAnyStringBufSize(ix,6); | |
| 399 | ✗ | ix += sprintf(anyStringBuf+ix, "SOME("); | |
| 400 | ✗ | ix = anyStringWork(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any), 1)), ix, stack); | |
| 401 | ✗ | checkAnyStringBufSize(ix,2); | |
| 402 | ✗ | ix += sprintf(anyStringBuf+ix, ")"); | |
| 403 | ✗ | return ix; | |
| 404 | } | ||
| 405 | |||
| 406 |
1/2✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
|
10 | if (numslots==2 && ctor==1) { /* CONS-PAIR */ |
| 407 | 10 | checkAnyStringBufSize(ix,2); | |
| 408 | 10 | ix += sprintf(anyStringBuf+ix, "{"); | |
| 409 | 20 | ix = anyStringWork(MMC_CAR(any), ix, mmc_mk_cons(any, mmc_mk_cons(MMC_CAR(any), stack))); | |
| 410 | 10 | any = MMC_CDR(any); | |
| 411 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
|
30 | while (!MMC_NILTEST(any)) { |
| 412 | 20 | checkAnyStringBufSize(ix,3); | |
| 413 | 20 | ix += sprintf(anyStringBuf+ix, ", "); | |
| 414 | 40 | ix = anyStringWork(MMC_CAR(any), ix, mmc_mk_cons(any, mmc_mk_cons(MMC_CAR(any), stack))); | |
| 415 | 20 | any = MMC_CDR(any); | |
| 416 | } | ||
| 417 | 10 | checkAnyStringBufSize(ix,2); | |
| 418 | 10 | ix += sprintf(anyStringBuf+ix, "}"); | |
| 419 | 10 | return ix; | |
| 420 | } | ||
| 421 | |||
| 422 | ✗ | fprintf(stderr, "%s:%d: %ld slots; ctor %lu - FAILED to detect the type\n", __FILE__, __LINE__, (long) numslots, (unsigned long) ctor); | |
| 423 | /* fprintf(stderr, "object: %032s||", ltoa((int)hdr, buf, 2)); */ | ||
| 424 | ✗ | checkAnyStringBufSize(ix,5); | |
| 425 | ✗ | ix += sprintf(anyStringBuf+ix, "UNK("); | |
| 426 | ✗ | for (i=1; i<=numslots; i++) | |
| 427 | { | ||
| 428 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 429 | ✗ | ix = anyStringWork(data, ix, mmc_mk_cons(any, mmc_mk_cons(data, stack))); | |
| 430 | /* fprintf(stderr, "%032s|", ltoa((int)data, buf, 2)); */ | ||
| 431 | } | ||
| 432 | ✗ | checkAnyStringBufSize(ix,2); | |
| 433 | ✗ | ix += sprintf(anyStringBuf+ix, ")"); | |
| 434 | ✗ | fprintf(stderr, "\n"); fflush(NULL); | |
| 435 | /* EXIT(1); */ | ||
| 436 | ✗ | return ix; | |
| 437 | } | ||
| 438 | |||
| 439 | ✗ | char* anyString(void* any) | |
| 440 | { | ||
| 441 | ✗ | initializeStringBuffer(); | |
| 442 | ✗ | anyStringWork(any, 0, mmc_mk_nil()); | |
| 443 | ✗ | return anyStringBuf; | |
| 444 | } | ||
| 445 | |||
| 446 | 26 | void* mmc_anyString(void* any) | |
| 447 | { | ||
| 448 | 26 | initializeStringBuffer(); | |
| 449 | 26 | anyStringWork(any, 0, mmc_mk_nil()); | |
| 450 | 26 | return mmc_mk_scon(anyStringBuf); | |
| 451 | } | ||
| 452 | |||
| 453 | ✗ | modelica_metatype mmc_gdb_listGet(threadData_t* threadData, modelica_metatype lst, modelica_integer i) | |
| 454 | { | ||
| 455 | ✗ | return boxptr_listGet(threadData, lst, mmc_mk_icon(i)); | |
| 456 | } | ||
| 457 | |||
| 458 | ✗ | modelica_metatype mmc_gdb_arrayGet(threadData_t* threadData, modelica_metatype arr, modelica_integer i) | |
| 459 | { | ||
| 460 | ✗ | return boxptr_arrayGet(threadData, arr, mmc_mk_icon(i)); | |
| 461 | } | ||
| 462 | |||
| 463 | ✗ | void printAny(void* any) | |
| 464 | { | ||
| 465 | ✗ | initializeStringBuffer(); | |
| 466 | ✗ | anyStringWork(any, 0, mmc_mk_nil()); | |
| 467 | ✗ | fputs(anyStringBuf, stderr); | |
| 468 | ✗ | } | |
| 469 | |||
| 470 | static int globalId; | ||
| 471 | |||
| 472 | ✗ | inline static mmc_sint_t anyStringWorkCode(void* any, mmc_sint_t ix, mmc_sint_t id, modelica_metatype stack) | |
| 473 | { | ||
| 474 | mmc_uint_t hdr; | ||
| 475 | mmc_sint_t numslots; | ||
| 476 | mmc_uint_t ctor; | ||
| 477 | int i; | ||
| 478 | void *data; | ||
| 479 | int base_id; | ||
| 480 | /* char buf[34] = {0}; */ | ||
| 481 | |||
| 482 | ✗ | if (MMC_IS_IMMEDIATE(any)) { | |
| 483 | ✗ | checkAnyStringBufSize(ix,400); | |
| 484 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld ((void*)%" PRINT_MMC_SINT_T ")\n", (long) id, (mmc_sint_t) any); | |
| 485 | ✗ | return ix; | |
| 486 | } | ||
| 487 | |||
| 488 | ✗ | if (MMC_HDR_IS_FORWARD(MMC_GETHDR(any))) { | |
| 489 | ✗ | assert(0); | |
| 490 | } | ||
| 491 | |||
| 492 | ✗ | hdr = MMC_HDR_UNMARK(MMC_GETHDR(any)); | |
| 493 | |||
| 494 | ✗ | if (hdr == MMC_NILHDR) { | |
| 495 | ✗ | checkAnyStringBufSize(ix,400); | |
| 496 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld (MMC_REFSTRUCTLIT(mmc_nil))\n", (long) id); | |
| 497 | ✗ | return ix; | |
| 498 | } | ||
| 499 | |||
| 500 | ✗ | if (hdr == MMC_REALHDR) { | |
| 501 | ✗ | checkAnyStringBufSize(ix,500); | |
| 502 | ✗ | ix += sprintf(anyStringBuf+ix, "static const MMC_DEFREALLIT(omc_tmp%ld_data,%g);\n#define omc_tmp%ld MMC_REFREALLIT(omc_tmp%ld_data)\n", (long) id, (double) mmc_prim_get_real(any), (long) id, (long) id); | |
| 503 | ✗ | return ix; | |
| 504 | } | ||
| 505 | ✗ | if (MMC_HDRISSTRING(hdr)) { | |
| 506 | int unescapedLength; | ||
| 507 | char *str; | ||
| 508 | MMC_CHECK_STRING(any); | ||
| 509 | ✗ | unescapedLength = strlen(MMC_STRINGDATA(any)); | |
| 510 | ✗ | str = omc__escapedString(MMC_STRINGDATA(any), 1); | |
| 511 | ✗ | checkAnyStringBufSize(ix,unescapedLength+800); | |
| 512 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld_data \"%s\"\n", (long) id, str ? str : MMC_STRINGDATA(any)); | |
| 513 | ✗ | ix += sprintf(anyStringBuf+ix, "static const size_t omc_tmp%ld_strlen = %d;\n", (long) id, unescapedLength); | |
| 514 | ✗ | ix += sprintf(anyStringBuf+ix, "static const MMC_DEFSTRINGLIT(omc_tmp%ld_data2,%d,omc_tmp%ld_data);\n", (long) id, unescapedLength, (long) id); | |
| 515 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld MMC_REFSTRINGLIT(omc_tmp%ld_data2)\n", (long) id, (long) id); | |
| 516 | ✗ | if (str) free(str); | |
| 517 | ✗ | return ix; | |
| 518 | } | ||
| 519 | |||
| 520 | ✗ | numslots = MMC_HDRSLOTS(hdr); | |
| 521 | ✗ | ctor = MMC_HDRCTOR(hdr); | |
| 522 | |||
| 523 | /* Ugly hack to "detect" function pointers. If these parameters are outside | ||
| 524 | * these bounds, then we probably have a function pointer. This is just to | ||
| 525 | * keep the debugger from crashing. */ | ||
| 526 | ✗ | if (numslots < 0 || numslots > 1024 || ctor > 255) { | |
| 527 | ✗ | checkAnyStringBufSize(ix, 100); | |
| 528 | ✗ | assert(0); | |
| 529 | return ix; | ||
| 530 | } | ||
| 531 | |||
| 532 | ✗ | if (numslots>0 && ctor == MMC_FREE_OBJECT_CTOR) { /* FREE OBJECT! */ | |
| 533 | ✗ | assert(0); | |
| 534 | return ix; | ||
| 535 | } | ||
| 536 | ✗ | if (numslots>=0 && ctor == MMC_ARRAY_TAG) { /* MetaModelica-style array */ | |
| 537 | ✗ | assert(0); | |
| 538 | return ix; | ||
| 539 | } | ||
| 540 | ✗ | if (numslots>0 && ctor > 1) { /* RECORD */ | |
| 541 | ✗ | int base_id = globalId; | |
| 542 | ✗ | struct record_description* desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)); | |
| 543 | ✗ | globalId += numslots-1; | |
| 544 | ✗ | for (i=2; i<=numslots; i++) { | |
| 545 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 546 | ✗ | ix = anyStringWorkCode(data, ix, base_id+i-1, stack); | |
| 547 | } | ||
| 548 | ✗ | checkAnyStringBufSize(ix,numslots*100+400); | |
| 549 | ✗ | ix += sprintf(anyStringBuf+ix, "static const MMC_DEFSTRUCTLIT(omc_tmp%ld_data,%ld,%lu) {&%s__desc", (long) id, (long) numslots, (unsigned long) ctor, desc->path); | |
| 550 | ✗ | for (i=2; i<=numslots; i++) { | |
| 551 | ✗ | ix += sprintf(anyStringBuf+ix, ",omc_tmp%d", base_id+i-1); | |
| 552 | } | ||
| 553 | ✗ | ix += sprintf(anyStringBuf+ix, "}};\n"); | |
| 554 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld MMC_REFSTRUCTLIT(omc_tmp%ld_data)\n", (long) id, (long) id); | |
| 555 | ✗ | return ix; | |
| 556 | } | ||
| 557 | |||
| 558 | ✗ | base_id = globalId; | |
| 559 | ✗ | globalId += numslots; | |
| 560 | ✗ | for (i=1; i<=numslots; i++) { | |
| 561 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 562 | ✗ | ix = anyStringWorkCode(data, ix, base_id+i, stack); | |
| 563 | } | ||
| 564 | ✗ | checkAnyStringBufSize(ix,numslots*100+400); | |
| 565 | ✗ | ix += sprintf(anyStringBuf+ix, "static const MMC_DEFSTRUCTLIT(omc_tmp%ld_data,%ld,%lu) {", (long) id, (long) numslots, (unsigned long) ctor); | |
| 566 | ✗ | for (i=1; i<=numslots; i++) { | |
| 567 | ✗ | ix += sprintf(anyStringBuf+ix, "%somc_tmp%d", i==1 ? "" : ",", base_id+i); | |
| 568 | } | ||
| 569 | ✗ | ix += sprintf(anyStringBuf+ix, "}};\n"); | |
| 570 | ✗ | ix += sprintf(anyStringBuf+ix, "#define omc_tmp%ld MMC_REFSTRUCTLIT(omc_tmp%ld_data)\n", (long) id, (long) id); | |
| 571 | ✗ | return ix; | |
| 572 | } | ||
| 573 | |||
| 574 | ✗ | void* mmc_anyStringCode(void* any) | |
| 575 | { | ||
| 576 | ✗ | initializeStringBuffer(); | |
| 577 | globalId = 0; | ||
| 578 | ✗ | anyStringWorkCode(any, 0, globalId++, mmc_mk_nil()); | |
| 579 | ✗ | return mmc_mk_scon(anyStringBuf); | |
| 580 | } | ||
| 581 | |||
| 582 | ✗ | const char* anyStringCode(void* any) | |
| 583 | { | ||
| 584 | ✗ | initializeStringBuffer(); | |
| 585 | globalId = 0; | ||
| 586 | ✗ | anyStringWorkCode(any, 0, globalId++, mmc_mk_nil()); | |
| 587 | ✗ | fprintf(stderr, "%s", anyStringBuf); | |
| 588 | ✗ | return anyStringBuf; | |
| 589 | } | ||
| 590 | |||
| 591 | ✗ | void printTypeOfAny(void* any) /* for debugging */ | |
| 592 | { | ||
| 593 | mmc_uint_t hdr; | ||
| 594 | int numslots; | ||
| 595 | unsigned int ctor; | ||
| 596 | void *data; | ||
| 597 | |||
| 598 | ✗ | if (MMC_IS_INTEGER(any)) { | |
| 599 | ✗ | fprintf(stderr, "Integer"); | |
| 600 | ✗ | return; | |
| 601 | } | ||
| 602 | |||
| 603 | ✗ | hdr = MMC_GETHDR(any); | |
| 604 | |||
| 605 | ✗ | if (MMC_HDR_IS_FORWARD(hdr)) { | |
| 606 | ✗ | fprintf(stderr, "Forward"); | |
| 607 | ✗ | return; | |
| 608 | } | ||
| 609 | |||
| 610 | ✗ | if (hdr == MMC_NILHDR) { | |
| 611 | ✗ | fprintf(stderr, "list<Any>"); | |
| 612 | ✗ | return; | |
| 613 | } | ||
| 614 | |||
| 615 | ✗ | if (hdr == MMC_REALHDR) { | |
| 616 | ✗ | fprintf(stderr, "Real"); | |
| 617 | ✗ | return; | |
| 618 | } | ||
| 619 | |||
| 620 | ✗ | if (MMC_HDRISSTRING(hdr)) { | |
| 621 | ✗ | fprintf(stderr, "String"); | |
| 622 | ✗ | return; | |
| 623 | } | ||
| 624 | |||
| 625 | ✗ | numslots = MMC_HDRSLOTS(hdr); | |
| 626 | ✗ | ctor = 255 & (hdr >> 2); | |
| 627 | |||
| 628 | ✗ | if (numslots>0 && ctor == MMC_ARRAY_TAG) { /* MetaModelica-style array */ | |
| 629 | ✗ | fprintf(stderr, "meta_array<"); | |
| 630 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)); | |
| 631 | ✗ | printTypeOfAny(data); | |
| 632 | ✗ | fprintf(stderr, ">"); | |
| 633 | ✗ | return; | |
| 634 | } | ||
| 635 | /* empty array??!! */ | ||
| 636 | ✗ | if (numslots == 0 && ctor == MMC_ARRAY_TAG) { /* MetaModelica-style array */ | |
| 637 | ✗ | fprintf(stderr, "meta_array<>"); | |
| 638 | ✗ | return; | |
| 639 | } | ||
| 640 | |||
| 641 | ✗ | if (numslots>0 && ctor > 1) { /* RECORD */ | |
| 642 | int i; | ||
| 643 | ✗ | struct record_description * desc = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)); | |
| 644 | ✗ | fprintf(stderr, "%s(", desc->name); | |
| 645 | ✗ | for (i=2; i<=numslots; i++) { | |
| 646 | ✗ | data = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i)); | |
| 647 | ✗ | fprintf(stderr, "%s = ", desc->fieldNames[i-2]); | |
| 648 | ✗ | printTypeOfAny(data); | |
| 649 | ✗ | if (i!=numslots) | |
| 650 | ✗ | fprintf(stderr, ", "); | |
| 651 | } | ||
| 652 | ✗ | fprintf(stderr, ")"); | |
| 653 | ✗ | return; | |
| 654 | } | ||
| 655 | |||
| 656 | ✗ | if (numslots>0 && ctor == 0) { /* TUPLE */ | |
| 657 | ✗ | fprintf(stderr, "tuple<"); | |
| 658 | ✗ | printTypeOfAny(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1))); | |
| 659 | ✗ | fprintf(stderr, ">"); | |
| 660 | ✗ | return; | |
| 661 | } | ||
| 662 | |||
| 663 | ✗ | if (numslots==0 && ctor==1) /* NONE() */ { | |
| 664 | ✗ | fprintf(stderr, "Option<Any>"); | |
| 665 | ✗ | return; | |
| 666 | } | ||
| 667 | |||
| 668 | ✗ | if (numslots==1 && ctor==1) /* SOME(x) */ { | |
| 669 | ✗ | fprintf(stderr, "Option<"); | |
| 670 | ✗ | printTypeOfAny(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1))); | |
| 671 | ✗ | fprintf(stderr, ">"); | |
| 672 | ✗ | return; | |
| 673 | } | ||
| 674 | |||
| 675 | ✗ | if (numslots==2 && ctor==1) { /* CONS-PAIR */ | |
| 676 | ✗ | fprintf(stderr, "list<"); | |
| 677 | ✗ | printTypeOfAny(MMC_CAR(any)); | |
| 678 | ✗ | fprintf(stderr, ">"); | |
| 679 | ✗ | return; | |
| 680 | } | ||
| 681 | |||
| 682 | ✗ | fprintf(stderr, "%s:%d: %d slots; ctor %u - FAILED to detect the type\n", __FILE__, __LINE__, numslots, ctor); | |
| 683 | ✗ | EXIT(1); | |
| 684 | } | ||
| 685 | |||
| 686 | ✗ | inline static int getTypeOfAnyWork(void* any, int ix, int inRecord, modelica_metatype stack) /* for debugging */ | |
| 687 | { | ||
| 688 | mmc_uint_t hdr; | ||
| 689 | int numslots; | ||
| 690 | unsigned int ctor; | ||
| 691 | int i; | ||
| 692 | |||
| 693 | ✗ | if (any == NULL && !inRecord) { // To handle integer inside Record. | |
| 694 | ✗ | checkAnyStringBufSize(ix,21); | |
| 695 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "replaceable type Any"); | |
| 696 | ✗ | return ix; | |
| 697 | } | ||
| 698 | |||
| 699 | ✗ | if (MMC_IS_INTEGER(any)) { | |
| 700 | ✗ | checkAnyStringBufSize(ix,8); | |
| 701 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "Integer"); | |
| 702 | ✗ | return ix; | |
| 703 | } | ||
| 704 | |||
| 705 | ✗ | hdr = MMC_GETHDR(any); | |
| 706 | |||
| 707 | ✗ | if (hdr == MMC_NILHDR) { | |
| 708 | ✗ | checkAnyStringBufSize(ix,10); | |
| 709 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "list<Any>"); | |
| 710 | ✗ | return ix; | |
| 711 | } | ||
| 712 | |||
| 713 | ✗ | if (hdr == MMC_REALHDR) { | |
| 714 | ✗ | checkAnyStringBufSize(ix,5); | |
| 715 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "Real"); | |
| 716 | ✗ | return ix; | |
| 717 | } | ||
| 718 | |||
| 719 | ✗ | if (MMC_HDRISSTRING(hdr)) { | |
| 720 | ✗ | checkAnyStringBufSize(ix,7); | |
| 721 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "String"); | |
| 722 | ✗ | return ix; | |
| 723 | } | ||
| 724 | |||
| 725 | ✗ | numslots = MMC_HDRSLOTS(hdr); | |
| 726 | ✗ | ctor = 255 & (hdr >> 2); | |
| 727 | |||
| 728 | /* Ugly hack to "detect" function pointers. If these parameters are outside | ||
| 729 | * these bounds, then we probably have a function pointer. This is just to | ||
| 730 | * keep the debugger from crashing. */ | ||
| 731 | ✗ | if (numslots < 0 || numslots > 1024 || ctor > 255) { | |
| 732 | ✗ | checkAnyStringBufSize(ix, 8); | |
| 733 | ✗ | ix += sprintf(anyStringBuf+ix, "%s", "Integer"); | |
| 734 | ✗ | return ix; | |
| 735 | } | ||
| 736 | |||
| 737 | ✗ | if (numslots>0 && ctor == MMC_ARRAY_TAG) { | |
| 738 | ✗ | checkAnyStringBufSize(ix,7); | |
| 739 | ✗ | ix += sprintf(anyStringBuf+ix, "Array<"); | |
| 740 | ✗ | ix = getTypeOfAnyWork(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),1)), ix, inRecord, stack); | |
| 741 | ✗ | checkAnyStringBufSize(ix,2); | |
| 742 | ✗ | ix += sprintf(anyStringBuf+ix, ">"); | |
| 743 | ✗ | return ix; | |
| 744 | } | ||
| 745 | |||
| 746 | ✗ | if (numslots>0 && ctor > 1) { /* RECORD */ | |
| 747 | ✗ | struct record_description * desc = MMC_CAR(any); | |
| 748 | ✗ | checkAnyStringBufSize(ix,strlen(desc->name)+8); | |
| 749 | ✗ | ix += sprintf(anyStringBuf+ix, "record<%s>", desc->name); | |
| 750 | ✗ | return ix; | |
| 751 | } | ||
| 752 | |||
| 753 | ✗ | if (numslots>0 && ctor == 0) { /* TUPLE */ | |
| 754 | ✗ | checkAnyStringBufSize(ix,7); | |
| 755 | ✗ | ix += sprintf(anyStringBuf+ix, "tuple<"); | |
| 756 | ✗ | for (i=0; i<numslots; i++) { | |
| 757 | ✗ | ix = getTypeOfAnyWork(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i+1)), ix, inRecord, stack); | |
| 758 | ✗ | if (i!=numslots-1) { | |
| 759 | ✗ | checkAnyStringBufSize(ix,3); | |
| 760 | ✗ | ix += sprintf(anyStringBuf+ix, ", "); | |
| 761 | } | ||
| 762 | } | ||
| 763 | ✗ | checkAnyStringBufSize(ix,2); | |
| 764 | ✗ | ix += sprintf(anyStringBuf+ix, ">"); | |
| 765 | ✗ | return ix; | |
| 766 | } | ||
| 767 | |||
| 768 | ✗ | if (numslots==0 && ctor==1) /* NONE() */ { | |
| 769 | ✗ | checkAnyStringBufSize(ix,12); | |
| 770 | ✗ | ix += sprintf(anyStringBuf+ix, "Option<Any>"); | |
| 771 | ✗ | return ix; | |
| 772 | } | ||
| 773 | |||
| 774 | ✗ | if (numslots==1 && ctor==1) /* SOME(x) */ { | |
| 775 | ✗ | checkAnyStringBufSize(ix,8); | |
| 776 | ✗ | ix += sprintf(anyStringBuf+ix, "Option<"); | |
| 777 | ✗ | for (i=0; i<numslots; i++) { | |
| 778 | ✗ | ix = getTypeOfAnyWork(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(any),i+1)), ix, inRecord, stack); | |
| 779 | if (i!=numslots-1) { | ||
| 780 | checkAnyStringBufSize(ix,3); | ||
| 781 | ix += sprintf(anyStringBuf+ix, ", "); | ||
| 782 | } | ||
| 783 | } | ||
| 784 | ✗ | checkAnyStringBufSize(ix,2); | |
| 785 | ✗ | ix += sprintf(anyStringBuf+ix, ">"); | |
| 786 | ✗ | return ix; | |
| 787 | } | ||
| 788 | |||
| 789 | ✗ | if (numslots==2 && ctor==1) { /* CONS-PAIR */ | |
| 790 | ✗ | checkAnyStringBufSize(ix,6); | |
| 791 | ✗ | ix += sprintf(anyStringBuf+ix, "list<"); | |
| 792 | ✗ | ix = getTypeOfAnyWork(MMC_CAR(any), ix, inRecord, stack); | |
| 793 | ✗ | checkAnyStringBufSize(ix,2); | |
| 794 | ✗ | ix += sprintf(anyStringBuf+ix, ">"); | |
| 795 | ✗ | return ix; | |
| 796 | } | ||
| 797 | |||
| 798 | ✗ | ix = sprintf(anyStringBuf+ix, "%s:%d: %d slots; ctor %u - FAILED to detect the type\n", __FILE__, __LINE__, numslots, ctor); | |
| 799 | ✗ | return ix; | |
| 800 | } | ||
| 801 | |||
| 802 | ✗ | char* getTypeOfAny(void* any, int inRecord) /* for debugging */ | |
| 803 | { | ||
| 804 | ✗ | initializeStringBuffer(); | |
| 805 | ✗ | getTypeOfAnyWork(any,0, inRecord, mmc_mk_nil()); | |
| 806 | ✗ | return anyStringBuf; | |
| 807 | } | ||
| 808 | |||
| 809 | /* | ||
| 810 | * Used by MDT for debugging. | ||
| 811 | * Returns the name of the particular field of the Record. | ||
| 812 | * */ | ||
| 813 | ✗ | char* getRecordElementName(void* any, int element) { | |
| 814 | struct record_description *desc; | ||
| 815 | |||
| 816 | ✗ | initializeStringBuffer(); | |
| 817 | |||
| 818 | ✗ | desc = MMC_CAR(any); | |
| 819 | ✗ | checkAnyStringBufSize(0,strlen(desc->fieldNames[element])); | |
| 820 | ✗ | sprintf(anyStringBuf, "%s", desc->fieldNames[element]); | |
| 821 | ✗ | return anyStringBuf; | |
| 822 | } | ||
| 823 | |||
| 824 | /* | ||
| 825 | * Used by MDT for debugging just return whether Option type contain something or not. | ||
| 826 | * */ | ||
| 827 | ✗ | int isOptionNone(void* any) | |
| 828 | { | ||
| 829 | ✗ | return MMC_OPTIONNONE(any); | |
| 830 | } | ||
| 831 | |||
| 832 | /* | ||
| 833 | * The gdb often use the buffer based stdout. | ||
| 834 | * So printf does not print straight away on the console. | ||
| 835 | * changing it to NULL fix the problem. | ||
| 836 | * */ | ||
| 837 | ✗ | void changeStdStreamBuffer(void) { | |
| 838 | ✗ | setbuf(stdout, NULL); | |
| 839 | ✗ | setbuf(stderr, NULL); | |
| 840 | ✗ | } | |
| 841 | |||
| 842 | ✗ | modelica_integer mmc_gdb_arrayLength(modelica_metatype arr) | |
| 843 | { | ||
| 844 | ✗ | return MMC_HDRSLOTS(MMC_GETHDR(arr)); | |
| 845 | } | ||
| 846 | |||
| 847 | /* | ||
| 848 | * Used by OMEdit for debugging. | ||
| 849 | * Returns the metatype element as an array e.g ^done,omc_element={name, displayName, type} | ||
| 850 | */ | ||
| 851 | ✗ | char* getMetaTypeElement(modelica_metatype arr, modelica_integer i, metaType mt) { | |
| 852 | void *name; | ||
| 853 | char *displayName = NULL, *ty = NULL, *formatString = NULL; | ||
| 854 | ✗ | const char *formattedString = NULL; | |
| 855 | int n, n1; | ||
| 856 | |||
| 857 | /* get the pointer to the element from the array/list */ | ||
| 858 | ✗ | switch (mt) { | |
| 859 | ✗ | case record_metaType: | |
| 860 | case option_metaType: | ||
| 861 | case tuple_metaType: | ||
| 862 | case array_metaType: | ||
| 863 | ✗ | name = (void*)mmc_gdb_arrayGet(0, arr, i); | |
| 864 | ✗ | break; | |
| 865 | ✗ | case list_metaType: | |
| 866 | ✗ | name = (void*)mmc_gdb_listGet(0, arr, i); | |
| 867 | ✗ | break; | |
| 868 | default: /* should never be reached */ | ||
| 869 | return "Unknown meta type"; | ||
| 870 | } | ||
| 871 | |||
| 872 | /* get the name of the element */ | ||
| 873 | ✗ | if (mt == record_metaType) { | |
| 874 | ✗ | getRecordElementName(arr, i - 2); | |
| 875 | ✗ | displayName = malloc(strlen(anyStringBuf) + 1); | |
| 876 | strcpy(displayName, anyStringBuf); | ||
| 877 | } | ||
| 878 | |||
| 879 | /* get the type of the element */ | ||
| 880 | ✗ | if (mt == record_metaType) { | |
| 881 | ✗ | getTypeOfAny(name, 1); | |
| 882 | } else { | ||
| 883 | ✗ | getTypeOfAny(name, 0); | |
| 884 | } | ||
| 885 | ✗ | ty = malloc(strlen(anyStringBuf) + 1); | |
| 886 | strcpy(ty, anyStringBuf); | ||
| 887 | /* format the anyStringBuf as array to return it */ | ||
| 888 | /* if Integer then unbox the pointer */ | ||
| 889 | ✗ | if (strcmp(ty, "Integer") == 0) { | |
| 890 | ✗ | name = (char*)anyString(name); | |
| 891 | formatString = "^done,omc_element={name=\"%s\",displayName=\"%s\",type=\"%s\"}"; | ||
| 892 | ✗ | if (-1 == GC_asprintf(&formattedString, formatString, name, displayName, ty)) { | |
| 893 | ✗ | assert(0); | |
| 894 | } | ||
| 895 | ✗ | } else if (mt == record_metaType) { | |
| 896 | formatString = "^done,omc_element={name=\"%ld\",displayName=\"%s\",type=\"%s\"}"; | ||
| 897 | ✗ | if (-1 == GC_asprintf(&formattedString, formatString, (mmc_uint_t)name, displayName, ty)) { | |
| 898 | ✗ | assert(0); | |
| 899 | } | ||
| 900 | } else { | ||
| 901 | formatString = "^done,omc_element={name=\"%ld\",displayName=\"[%d]\",type=\"%s\"}"; | ||
| 902 | ✗ | if (-1 == GC_asprintf(&formattedString, formatString, (mmc_uint_t)name, (int)i, ty)) { | |
| 903 | ✗ | assert(0); | |
| 904 | } | ||
| 905 | } | ||
| 906 | ✗ | n1 = strlen(formattedString) + 1; | |
| 907 | ✗ | n = snprintf(anyStringBuf, n1, "%s", formattedString); | |
| 908 | ✗ | if (n > n1) { | |
| 909 | ✗ | checkAnyStringBufSize(0, n1); | |
| 910 | ✗ | snprintf(anyStringBuf, n1, "%s", formattedString); | |
| 911 | } | ||
| 912 | |||
| 913 | /* free the memory */ | ||
| 914 | ✗ | if (mt == record_metaType) { | |
| 915 | ✗ | free(displayName); | |
| 916 | } | ||
| 917 | ✗ | free(ty); | |
| 918 | |||
| 919 | ✗ | return anyStringBuf; | |
| 920 | } | ||
| 921 | |||
| 922 | static inline mmc_uint_t djb2_hash_iter(const unsigned char *str /* data; not null-terminated */, int len, mmc_uint_t hash /* start at 5381 */) | ||
| 923 | { | ||
| 924 | int i; | ||
| 925 | ✗ | for (i=0; i<len; i++) { | |
| 926 | ✗ | hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + c */ | |
| 927 | } | ||
| 928 | return hash; | ||
| 929 | } | ||
| 930 | |||
| 931 | ✗ | mmc_uint_t mmc_prim_hash(void *p, mmc_uint_t hash /* start at 5381 */) | |
| 932 | { | ||
| 933 | mmc_uint_t phdr = 0; | ||
| 934 | |||
| 935 | ✗ | mmc_prim_hash_tail_recur: | |
| 936 | ✗ | if (MMC_IS_INTEGER(p)) | |
| 937 | { | ||
| 938 | ✗ | mmc_uint_t l = (mmc_uint_t)MMC_UNTAGFIXNUM(p); | |
| 939 | return djb2_hash_iter((unsigned char*)&l, sizeof(mmc_uint_t), hash); | ||
| 940 | } | ||
| 941 | |||
| 942 | ✗ | phdr = MMC_GETHDR(p); | |
| 943 | |||
| 944 | ✗ | if( phdr == MMC_REALHDR ) | |
| 945 | { | ||
| 946 | ✗ | double d = mmc_unbox_real(p); | |
| 947 | return djb2_hash_iter((unsigned char*)&d, sizeof(double), hash); | ||
| 948 | } | ||
| 949 | |||
| 950 | ✗ | if( MMC_HDRISSTRING(phdr) ) | |
| 951 | { | ||
| 952 | ✗ | return djb2_hash_iter((const unsigned char *) MMC_STRINGDATA(p),MMC_STRLEN(p),hash); | |
| 953 | } | ||
| 954 | |||
| 955 | ✗ | if( MMC_HDRISSTRUCT(phdr) ) | |
| 956 | { | ||
| 957 | int i; | ||
| 958 | ✗ | int slots = MMC_HDRSLOTS(phdr); | |
| 959 | ✗ | int ctor = MMC_HDRCTOR(phdr); | |
| 960 | hash = djb2_hash_iter((unsigned char*)&ctor, sizeof(int), hash); | ||
| 961 | ✗ | if (slots == 0) | |
| 962 | ✗ | return hash; | |
| 963 | |||
| 964 | ✗ | for (i=2; i<slots; i++) { | |
| 965 | ✗ | hash = mmc_prim_hash(MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(p),i)),hash); | |
| 966 | } | ||
| 967 | ✗ | p = MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(p),slots)); | |
| 968 | ✗ | goto mmc_prim_hash_tail_recur; | |
| 969 | } | ||
| 970 | return hash; | ||
| 971 | } | ||
| 972 | |||
| 973 | ✗ | modelica_integer valueHashMod(void *p, modelica_integer mod) | |
| 974 | { | ||
| 975 | ✗ | modelica_integer res = mmc_prim_hash(p,5381) % (mmc_uint_t) mod; | |
| 976 | ✗ | return res; | |
| 977 | } | ||
| 978 | |||
| 979 | ✗ | void* boxptr_valueHashMod(threadData_t *threadData,void *p, void *mod) | |
| 980 | { | ||
| 981 | ✗ | return mmc_mk_icon(mmc_prim_hash(p,5381) % (mmc_uint_t) mmc_unbox_integer(mod)); | |
| 982 | } | ||
| 983 |