OMCompiler/SimulationRuntime/c/meta/meta_modelica_builtin.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 "meta_modelica_string.h" | ||
| 29 | #include "meta_modelica_builtin.h" | ||
| 30 | #include "meta_modelica.h" | ||
| 31 | #include <float.h> | ||
| 32 | #include <limits.h> | ||
| 33 | #include <assert.h> | ||
| 34 | #include <time.h> | ||
| 35 | #include <math.h> | ||
| 36 | #include <string.h> | ||
| 37 | #include <stdio.h> | ||
| 38 | #include <stdint.h> | ||
| 39 | |||
| 40 | #define GEN_META_MODELICA_BUILTIN_BOXPTR | ||
| 41 | #include "meta_modelica_builtin_boxptr.h" | ||
| 42 | #include "../util/omc_numbers.h" | ||
| 43 | |||
| 44 | 19700780 | metamodelica_string intString(modelica_integer i) | |
| 45 | { | ||
| 46 | /* 64-bit integer: 1+log_10(2**63)+1 = 20 digits max */ | ||
| 47 | char buffer[22]; | ||
| 48 | void *res; | ||
| 49 |
2/2✓ Branch 0 taken 12163920 times.
✓ Branch 1 taken 7536860 times.
|
19700780 | if (i>=0 && i<=9) /* Small integers are used so much it makes sense to cache them */ |
| 50 | 12163920 | return mmc_strings_len1['0'+i]; | |
| 51 | snprintf(buffer, 22, "%" PRINT_MMC_SINT_T, i); | ||
| 52 | 7536860 | res = mmc_mk_scon(buffer); | |
| 53 | MMC_CHECK_STRING(res); | ||
| 54 | 7536860 | return res; | |
| 55 | } | ||
| 56 | |||
| 57 | /* String Character Conversion */ | ||
| 58 | |||
| 59 | 132682 | modelica_integer nobox_stringCharInt(threadData_t *threadData,metamodelica_string chr) | |
| 60 | { | ||
| 61 | unsigned char c; | ||
| 62 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 132682 times.
|
132682 | if (MMC_STRLEN(chr) != 1) |
| 63 | ✗ | MMC_THROW_INTERNAL(); | |
| 64 | MMC_CHECK_STRING(chr); | ||
| 65 | 132682 | return (unsigned char) MMC_STRINGDATA(chr)[0]; | |
| 66 | } | ||
| 67 | |||
| 68 | ✗ | metamodelica_string nobox_intStringChar(threadData_t *threadData,modelica_integer ix) | |
| 69 | { | ||
| 70 | char chr[2]; | ||
| 71 | ✗ | if (ix < 1 || ix > 255) | |
| 72 | ✗ | MMC_THROW_INTERNAL(); | |
| 73 | ✗ | chr[0] = (char) ix; | |
| 74 | ✗ | chr[1] = '\0'; | |
| 75 | ✗ | return mmc_mk_scon(chr); | |
| 76 | } | ||
| 77 | |||
| 78 | /* String Operations */ | ||
| 79 | |||
| 80 | 60906 | modelica_integer nobox_stringInt(threadData_t *threadData,metamodelica_string s) | |
| 81 | { | ||
| 82 | modelica_integer res; | ||
| 83 | 60906 | char *endptr,*str=MMC_STRINGDATA(s); | |
| 84 | MMC_CHECK_STRING(s); | ||
| 85 | 60906 | errno = 0; | |
| 86 | #if defined(_WIN64) || defined(__MINGW64__) | ||
| 87 | res = strtoll(str,&endptr,10); | ||
| 88 | #else | ||
| 89 | 60906 | res = strtol(str,&endptr,10); | |
| 90 | #endif | ||
| 91 |
3/4✓ Branch 0 taken 60906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11753 times.
✓ Branch 3 taken 49153 times.
|
60906 | if (errno != 0 || str == endptr) |
| 92 | 11753 | MMC_THROW_INTERNAL(); | |
| 93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 49153 times.
|
49153 | if (*endptr != '\0') |
| 94 | ✗ | MMC_THROW_INTERNAL(); | |
| 95 | if (res > MODELICA_INT_MAX || res < MODELICA_INT_MIN) | ||
| 96 | MMC_THROW_INTERNAL(); | ||
| 97 | 49153 | return res; | |
| 98 | } | ||
| 99 | |||
| 100 | 1525431 | modelica_real nobox_stringReal(threadData_t *threadData,metamodelica_string s) | |
| 101 | { | ||
| 102 | modelica_real res; | ||
| 103 | 1525431 | char *endptr,*str=MMC_STRINGDATA(s); | |
| 104 | MMC_CHECK_STRING(s); | ||
| 105 | 1525431 | errno = 0; | |
| 106 | 1525431 | res = om_strtod(str,&endptr); | |
| 107 |
5/8✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1525429 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1525431 times.
|
1525431 | if ((errno != 0 && (res == 0 || res > DBL_MIN)) || str == endptr) |
| 108 | ✗ | MMC_THROW_INTERNAL(); | |
| 109 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1525431 times.
|
1525431 | if (*endptr != '\0') |
| 110 | ✗ | MMC_THROW_INTERNAL(); | |
| 111 | 1525431 | return res; | |
| 112 | } | ||
| 113 | |||
| 114 | /******************** String HASH Functions ********************/ | ||
| 115 | /* | ||
| 116 | * adrpo 2008-12-02 | ||
| 117 | * http://www.cse.yorku.ca/~oz/hash.html | ||
| 118 | * hash functions which could be useful to replace System__hash: | ||
| 119 | */ | ||
| 120 | /* A hash returned as a modelica_integer decides UnorderedSet/UnorderedMap | ||
| 121 | * bucket order, so it is accumulated fixed-width and reduced to 31 bits. */ | ||
| 122 | #define MMC_HASH_MASK 0x7fffffff | ||
| 123 | |||
| 124 | /*** djb2 hash ***/ | ||
| 125 | static inline uint32_t djb2_hash_continue(const unsigned char *str, uint32_t hash) | ||
| 126 | { | ||
| 127 | int c; | ||
| 128 |
6/6✓ Branch 0 taken 47490527 times.
✓ Branch 1 taken 40806406 times.
✓ Branch 2 taken 1490565629 times.
✓ Branch 3 taken 456180642 times.
✓ Branch 4 taken 79635776 times.
✓ Branch 5 taken 5488360 times.
|
2120167340 | while (0 != (c = *str++)) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ |
| 129 | return hash; | ||
| 130 | } | ||
| 131 | |||
| 132 | static inline uint32_t djb2_hash(const unsigned char *str) | ||
| 133 | { | ||
| 134 | return djb2_hash_continue(str, 5381); | ||
| 135 | } | ||
| 136 | |||
| 137 | /* CodegenCFunctions bakes stringHashDjb2Mod's remainder into the generated | ||
| 138 | * string-switch `case` labels, so its recurrence must not change. */ | ||
| 139 | static inline unsigned long djb2_hash_wide(const unsigned char *str) | ||
| 140 | { | ||
| 141 | unsigned long hash = 5381; | ||
| 142 | int c; | ||
| 143 |
2/2✓ Branch 0 taken 18988922 times.
✓ Branch 1 taken 2449459 times.
|
21438381 | while (0 != (c = *str++)) hash = ((hash << 5) + hash) + c; |
| 144 | return hash; | ||
| 145 | } | ||
| 146 | |||
| 147 | /*** sdbm hash ***/ | ||
| 148 | static inline uint32_t sdbm_hash(const unsigned char* str) | ||
| 149 | { | ||
| 150 | uint32_t hash = 0; | ||
| 151 | int c; | ||
| 152 | ✗ | while (0 != (c = *str++)) hash = c + (hash << 6) + (hash << 16) - hash; | |
| 153 | return hash; | ||
| 154 | } | ||
| 155 | |||
| 156 | /* adrpo: really bad hash :) */ | ||
| 157 | ✗ | modelica_integer stringHash(metamodelica_string_const s) | |
| 158 | { | ||
| 159 | ✗ | const char* str = MMC_STRINGDATA(s); | |
| 160 | long res = 0, i=0; | ||
| 161 | ✗ | while (0 != (str[i])) { res += str[i]; i++; } | |
| 162 | ✗ | return res; | |
| 163 | } | ||
| 164 | |||
| 165 | /* adrpo: see the comment above about djb2 hash */ | ||
| 166 | 5488360 | modelica_integer stringHashDjb2(metamodelica_string_const s) | |
| 167 | { | ||
| 168 | 5488360 | const char* str = MMC_STRINGDATA(s); | |
| 169 | 5488360 | return djb2_hash((const unsigned char*)str) & MMC_HASH_MASK; | |
| 170 | } | ||
| 171 | |||
| 172 | /* adrpo: see the comment above about djb2 hash */ | ||
| 173 | 456180642 | modelica_integer stringHashDjb2Continue(metamodelica_string_const s, modelica_integer hash) | |
| 174 | { | ||
| 175 | 456180642 | const char* str = MMC_STRINGDATA(s); | |
| 176 | 456180642 | return djb2_hash_continue((const unsigned char*)str, (uint32_t)hash) & MMC_HASH_MASK; | |
| 177 | } | ||
| 178 | |||
| 179 | /* Same result as stringHashDjb2Continue(intString(i), hash), without building | ||
| 180 | * the string. Cannot live in MetaModelica: MMC_HASH_MASK is not a legal | ||
| 181 | * Integer literal where modelica_integer holds 31 bits. */ | ||
| 182 | 40806406 | modelica_integer intHashDjb2Continue(modelica_integer i, modelica_integer hash) | |
| 183 | { | ||
| 184 | unsigned char buf[24]; | ||
| 185 | int n = sizeof(buf) - 1; | ||
| 186 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 40806404 times.
|
40806406 | mmc_uint_t v = i < 0 ? -(mmc_uint_t) i : (mmc_uint_t) i; |
| 187 | |||
| 188 | 40806406 | buf[n] = '\0'; | |
| 189 |
2/2✓ Branch 0 taken 6684119 times.
✓ Branch 1 taken 40806406 times.
|
47490525 | do { buf[--n] = '0' + (unsigned char) (v % 10); v /= 10; } while (v); |
| 190 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 40806404 times.
|
40806406 | if (i < 0) buf[--n] = '-'; |
| 191 | |||
| 192 | 40806406 | return djb2_hash_continue(buf + n, (uint32_t) hash) & MMC_HASH_MASK; | |
| 193 | } | ||
| 194 | |||
| 195 | /* adrpo: see the comment above about djb2 hash */ | ||
| 196 | 2449459 | modelica_integer stringHashDjb2Mod(metamodelica_string_const s, modelica_integer mod) | |
| 197 | { | ||
| 198 | 2449459 | const char* str = MMC_STRINGDATA(s); | |
| 199 | long res; | ||
| 200 |
1/2✓ Branch 0 taken 2449459 times.
✗ Branch 1 not taken.
|
2449459 | if (mod == 0) { |
| 201 | ✗ | MMC_THROW(); | |
| 202 | } | ||
| 203 | 2449459 | res = djb2_hash_wide((const unsigned char*)str) % (unsigned int) mod; | |
| 204 | 2449459 | return res; | |
| 205 | } | ||
| 206 | |||
| 207 | ✗ | modelica_metatype boxptr_stringHashDjb2Mod(threadData_t *threadData,modelica_metatype v,modelica_metatype mod) | |
| 208 | { | ||
| 209 | ✗ | modelica_integer modunbox = mmc_unbox_integer(mod); | |
| 210 | ✗ | if (modunbox < 1) { | |
| 211 | ✗ | MMC_THROW_INTERNAL(); | |
| 212 | } | ||
| 213 | ✗ | return mmc_mk_icon(stringHashDjb2Mod(v,modunbox)); | |
| 214 | } | ||
| 215 | |||
| 216 | /* adrpo: see the comment above about sdbm hash */ | ||
| 217 | ✗ | modelica_integer stringHashSdbm(metamodelica_string_const s) | |
| 218 | { | ||
| 219 | ✗ | const char* str = MMC_STRINGDATA(s); | |
| 220 | ✗ | return sdbm_hash((const unsigned char*)str) & MMC_HASH_MASK; | |
| 221 | } | ||
| 222 | |||
| 223 | 2003230 | modelica_metatype boxptr_substring(threadData_t *threadData, metamodelica_string_const str, modelica_metatype boxstart, modelica_metatype boxstop) | |
| 224 | { | ||
| 225 | unsigned header = 0, nwords; | ||
| 226 | 2003230 | long start = MMC_UNTAGFIXNUM(boxstart) - 1; | |
| 227 | 2003230 | long stop = MMC_UNTAGFIXNUM(boxstop) - 1; | |
| 228 | 2003230 | long totalLen = MMC_STRLEN(str), len = stop-start+1; | |
| 229 | struct mmc_string *res; | ||
| 230 | char *tmp; | ||
| 231 | modelica_metatype p; | ||
| 232 | /* Bad indexes */ | ||
| 233 |
3/4✓ Branch 0 taken 2003229 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 2003229 times.
|
2003230 | if (start < 0 || start >= totalLen || stop < start || stop >= totalLen) { |
| 234 | 1 | MMC_THROW_INTERNAL(); | |
| 235 | } | ||
| 236 | 2003229 | header = MMC_STRINGHDR(len); | |
| 237 | 2003229 | nwords = MMC_HDRSLOTS(header) + 1; | |
| 238 | res = (struct mmc_string *) mmc_alloc_words_atomic(nwords); | ||
| 239 | 2003229 | res->header = header; | |
| 240 | 2003229 | tmp = (char*) res->data; | |
| 241 | 2003229 | memcpy(tmp, MMC_STRINGDATA(str) + start, len); | |
| 242 | 2003229 | tmp[len] = '\0'; | |
| 243 | 2003229 | p = MMC_TAGPTR(res); | |
| 244 | MMC_CHECK_STRING(p); | ||
| 245 | 2003229 | return p; | |
| 246 | } | ||
| 247 | |||
| 248 | 26844 | metamodelica_string stringListStringChar(metamodelica_string s) | |
| 249 | { | ||
| 250 | 26844 | const char *str = MMC_STRINGDATA(s); | |
| 251 | 26844 | char chr[2] = {'\0', '\0'}; | |
| 252 | modelica_metatype res = NULL; | ||
| 253 | int i = 0; | ||
| 254 | |||
| 255 | MMC_CHECK_STRING(s); | ||
| 256 | res = mmc_mk_nil(); | ||
| 257 |
2/2✓ Branch 0 taken 854842 times.
✓ Branch 1 taken 26844 times.
|
881686 | for (i=MMC_STRLEN(s)-1; i>=0; i--) { |
| 258 | 854842 | chr[0] = str[i]; | |
| 259 | 854842 | res = mmc_mk_cons(mmc_mk_scon(chr), res); | |
| 260 | } | ||
| 261 | 26844 | return res; | |
| 262 | } | ||
| 263 | |||
| 264 | 3924564 | metamodelica_string stringAppendList(modelica_metatype lst) | |
| 265 | { | ||
| 266 | /* fprintf(stderr, "stringAppendList(%s)\n", anyString(lst)); */ | ||
| 267 | modelica_integer lstLen = 0, len = 0; | ||
| 268 | unsigned nbytes = 0, header = 0, nwords = 0; | ||
| 269 | modelica_metatype car = NULL, lstHead = NULL, lstTmp = NULL; | ||
| 270 | char *tmp = NULL; | ||
| 271 | struct mmc_string *res = NULL; | ||
| 272 | void *p = NULL; | ||
| 273 | |||
| 274 | lstLen = 0; | ||
| 275 | nbytes = 0; | ||
| 276 | lstHead = lst; | ||
| 277 | lstTmp = lst; | ||
| 278 |
2/2✓ Branch 0 taken 11405053 times.
✓ Branch 1 taken 3924564 times.
|
15329617 | while (!listEmpty(lstTmp)) { |
| 279 | MMC_CHECK_STRING(MMC_CAR(lstTmp)); | ||
| 280 | 11405053 | nbytes += MMC_STRLEN(MMC_CAR(lstTmp)); | |
| 281 | /* fprintf(stderr, "stringAppendList: Has success reading input %d: %s\n", lstLen, MMC_STRINGDATA(MMC_CAR(lst))); */ | ||
| 282 | 11405053 | lstTmp = MMC_CDR(lstTmp); | |
| 283 | 11405053 | lstLen++; | |
| 284 | } | ||
| 285 |
2/2✓ Branch 0 taken 1664 times.
✓ Branch 1 taken 3922900 times.
|
3924564 | if (nbytes == 0) return mmc_emptystring; |
| 286 |
2/2✓ Branch 0 taken 28339 times.
✓ Branch 1 taken 3894561 times.
|
3922900 | if (lstLen == 1) return MMC_CAR(lstHead); |
| 287 | |||
| 288 | 3894561 | header = MMC_STRINGHDR(nbytes); | |
| 289 | 3894561 | nwords = MMC_HDRSLOTS(header) + 1; | |
| 290 | res = (struct mmc_string *) mmc_alloc_words_atomic(nwords); | ||
| 291 | 3894561 | res->header = header; | |
| 292 | 3894561 | tmp = (char*) res->data; | |
| 293 | nbytes = 0; | ||
| 294 | lstTmp = lstHead; | ||
| 295 |
2/2✓ Branch 0 taken 11375235 times.
✓ Branch 1 taken 3894561 times.
|
15269796 | while (!listEmpty(lstTmp)) { |
| 296 | 11375235 | car = MMC_CAR(lstTmp); | |
| 297 | 11375235 | len = MMC_STRLEN(car); | |
| 298 | /* fprintf(stderr, "stringAppendList: %s %d %d\n", MMC_STRINGDATA(car), len, strlen(MMC_STRINGDATA(car))); */ | ||
| 299 | /* Might be useful to check this when debugging. String literals are often done wrong :) */ | ||
| 300 | MMC_DEBUG_ASSERT(len == strlen(MMC_STRINGDATA(car))); | ||
| 301 | 11375235 | memcpy(tmp+nbytes,MMC_STRINGDATA(car),len); | |
| 302 | 11375235 | nbytes += len; | |
| 303 | 11375235 | lstTmp = MMC_CDR(lstTmp); | |
| 304 | } | ||
| 305 | 3894561 | tmp[nbytes] = '\0'; | |
| 306 | /* fprintf(stderr, "stringAppendList(%s)=>%s\n", anyString(lstHead), anyString(MMC_TAGPTR(res))); */ | ||
| 307 | 3894561 | p = MMC_TAGPTR(res); | |
| 308 | MMC_CHECK_STRING(p); | ||
| 309 | 3894561 | return p; | |
| 310 | } | ||
| 311 | |||
| 312 | 3269480 | modelica_metatype stringDelimitList(modelica_metatype lst, metamodelica_string_const delimiter) | |
| 313 | { | ||
| 314 | /* fprintf(stderr, "stringDelimitList(%s)\n", anyString(lst)); */ | ||
| 315 | modelica_integer lstLen = 0, len = 0, lenDelimiter = 0; | ||
| 316 | unsigned nbytes = 0, header = 0, nwords = 0; | ||
| 317 | modelica_metatype car = NULL, lstHead = NULL, lstTmp = NULL; | ||
| 318 | char *tmp = 0, *delimiter_cstr = 0; | ||
| 319 | struct mmc_string *res = NULL; | ||
| 320 | void *p = NULL; | ||
| 321 | |||
| 322 | lstLen = 0; | ||
| 323 | nbytes = 0; | ||
| 324 | lstHead = lst; | ||
| 325 | lstTmp = lst; | ||
| 326 |
2/2✓ Branch 0 taken 3920975 times.
✓ Branch 1 taken 3269480 times.
|
7190455 | while (!listEmpty(lstTmp)) { |
| 327 | MMC_CHECK_STRING(MMC_CAR(lstTmp)); | ||
| 328 | 3920975 | nbytes += MMC_STRLEN(MMC_CAR(lstTmp)); | |
| 329 | /* fprintf(stderr, "stringDelimitList: Has success reading input %d: %s\n", lstLen, MMC_STRINGDATA(MMC_CAR(lst))); */ | ||
| 330 | 3920975 | lstTmp = MMC_CDR(lstTmp); | |
| 331 | 3920975 | lstLen++; | |
| 332 | } | ||
| 333 |
2/2✓ Branch 0 taken 608061 times.
✓ Branch 1 taken 2661419 times.
|
3269480 | if (nbytes == 0) return mmc_emptystring; |
| 334 |
2/2✓ Branch 0 taken 2098900 times.
✓ Branch 1 taken 562519 times.
|
2661419 | if (lstLen == 1) return MMC_CAR(lstHead); |
| 335 | 562519 | lenDelimiter = MMC_STRLEN(delimiter); | |
| 336 | 562519 | nbytes += (lstLen-1)*lenDelimiter; | |
| 337 | 562519 | delimiter_cstr = MMC_STRINGDATA(delimiter); | |
| 338 | MMC_DEBUG_ASSERT(lenDelimiter == strlen(delimiter_cstr)); | ||
| 339 | |||
| 340 | 562519 | header = MMC_STRINGHDR(nbytes); | |
| 341 | 562519 | nwords = MMC_HDRSLOTS(header) + 1; | |
| 342 | res = (struct mmc_string *) mmc_alloc_words_atomic(nwords); | ||
| 343 | 562519 | res->header = header; | |
| 344 | 562519 | tmp = (char*) res->data; | |
| 345 | nbytes = 0; | ||
| 346 | lstTmp = lstHead; | ||
| 347 | { /* Unrolled first element (not delimiter in front) */ | ||
| 348 | 562519 | car = MMC_CAR(lstTmp); | |
| 349 | 562519 | len = MMC_STRLEN(car); | |
| 350 | MMC_DEBUG_ASSERT(len == strlen(MMC_STRINGDATA(car))); | ||
| 351 | 562519 | memcpy(tmp+nbytes,MMC_STRINGDATA(car),len); | |
| 352 | 562519 | nbytes += len; | |
| 353 | 562519 | lstTmp = MMC_CDR(lstTmp); | |
| 354 | } | ||
| 355 |
2/2✓ Branch 0 taken 1259556 times.
✓ Branch 1 taken 562519 times.
|
1822075 | while (!listEmpty(lstTmp)) { |
| 356 | 1259556 | memcpy(tmp+nbytes,delimiter_cstr,lenDelimiter); | |
| 357 | 1259556 | nbytes += lenDelimiter; | |
| 358 | 1259556 | car = MMC_CAR(lstTmp); | |
| 359 | 1259556 | len = MMC_STRLEN(car); | |
| 360 | /* fprintf(stderr, "stringDelimitList: %s %d %d\n", MMC_STRINGDATA(car), len, strlen(MMC_STRINGDATA(car))); */ | ||
| 361 | /* Might be useful to check this when debugging. String literals are often done wrong :) */ | ||
| 362 | MMC_DEBUG_ASSERT(len == strlen(MMC_STRINGDATA(car))); | ||
| 363 | 1259556 | memcpy(tmp+nbytes,MMC_STRINGDATA(car),len); | |
| 364 | 1259556 | nbytes += len; | |
| 365 | 1259556 | lstTmp = MMC_CDR(lstTmp); | |
| 366 | } | ||
| 367 | 562519 | tmp[nbytes] = '\0'; | |
| 368 | /* fprintf(stderr, "stringDelimitList(%s)=>%s\n", anyString(lstHead), anyString(MMC_TAGPTR(res))); */ | ||
| 369 | 562519 | p = MMC_TAGPTR(res); | |
| 370 | MMC_CHECK_STRING(p); | ||
| 371 | 562519 | return p; | |
| 372 | } | ||
| 373 | |||
| 374 | 55089 | modelica_metatype boxptr_stringGetStringChar(threadData_t *threadData,metamodelica_string str, modelica_metatype iix) | |
| 375 | { | ||
| 376 | modelica_metatype res; | ||
| 377 | 55089 | int ix = MMC_UNTAGFIXNUM(iix); | |
| 378 | MMC_CHECK_STRING(str); | ||
| 379 |
3/4✓ Branch 0 taken 55089 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 55088 times.
|
55089 | if (ix < 1 || ix > (long) MMC_STRLEN(str)) |
| 380 | 1 | MMC_THROW_INTERNAL(); | |
| 381 | 55088 | return mmc_strings_len1[(size_t)MMC_STRINGDATA(str)[ix-1]]; | |
| 382 | } | ||
| 383 | |||
| 384 | 4544114 | modelica_integer nobox_stringGet(threadData_t *threadData,metamodelica_string str, modelica_integer ix) | |
| 385 | { | ||
| 386 |
2/4✓ Branch 0 taken 4544114 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4544114 times.
|
4544114 | if (ix < 1 || ix > (long) MMC_STRLEN(str)) |
| 387 | ✗ | MMC_THROW_INTERNAL(); | |
| 388 | 4544114 | return ((unsigned char*)MMC_STRINGDATA(str))[ix-1]; | |
| 389 | } | ||
| 390 | |||
| 391 | ✗ | modelica_metatype boxptr_stringUpdateStringChar(threadData_t *threadData,metamodelica_string str, metamodelica_string c, modelica_metatype iix) | |
| 392 | { | ||
| 393 | ✗ | int ix = MMC_UNTAGFIXNUM(iix); | |
| 394 | int length = 0; | ||
| 395 | ✗ | unsigned header = MMC_GETHDR(str); | |
| 396 | ✗ | unsigned nwords = MMC_HDRSLOTS(header) + 1; | |
| 397 | struct mmc_string *p = NULL; | ||
| 398 | void *res = NULL; | ||
| 399 | |||
| 400 | MMC_CHECK_STRING(str); | ||
| 401 | MMC_CHECK_STRING(c); | ||
| 402 | /* fprintf(stderr, "stringUpdateStringChar(%s,%s,%ld)\n", MMC_STRINGDATA(str),MMC_STRINGDATA(c),ix); */ | ||
| 403 | |||
| 404 | ✗ | if (ix < 1 || MMC_STRLEN(c) != 1) | |
| 405 | ✗ | MMC_THROW_INTERNAL(); | |
| 406 | ✗ | length = MMC_STRLEN(str); | |
| 407 | ✗ | if (ix > length) | |
| 408 | ✗ | MMC_THROW_INTERNAL(); | |
| 409 | p = (struct mmc_string *) mmc_alloc_words_atomic(nwords); | ||
| 410 | ✗ | p->header = header; | |
| 411 | ✗ | memcpy(p->data, MMC_STRINGDATA(str), length+1 /* include NULL */); | |
| 412 | ✗ | p->data[ix-1] = MMC_STRINGDATA(c)[0]; | |
| 413 | ✗ | res = MMC_TAGPTR(p); | |
| 414 | MMC_CHECK_STRING(res); | ||
| 415 | ✗ | return res; | |
| 416 | } | ||
| 417 | |||
| 418 | /* List Operations */ | ||
| 419 | |||
| 420 | 178644635 | modelica_metatype listReverse(modelica_metatype lst) | |
| 421 | { | ||
| 422 | modelica_metatype res = NULL; | ||
| 423 |
4/4✓ Branch 0 taken 161678224 times.
✓ Branch 1 taken 16966411 times.
✓ Branch 2 taken 79352511 times.
✓ Branch 3 taken 82325713 times.
|
178644635 | if (MMC_NILTEST(lst) || MMC_NILTEST(MMC_CDR(lst))) { |
| 424 | // 0/1 elements are already reversed | ||
| 425 | return lst; | ||
| 426 | } | ||
| 427 | res = mmc_mk_nil(); | ||
| 428 | do { | ||
| 429 | 364571509 | res = mmc_mk_cons(MMC_CAR(lst),res); | |
| 430 | 364571509 | lst = MMC_CDR(lst); | |
| 431 |
2/2✓ Branch 0 taken 285218998 times.
✓ Branch 1 taken 79352511 times.
|
364571509 | } while (!MMC_NILTEST(lst)); |
| 432 | return res; | ||
| 433 | } | ||
| 434 | |||
| 435 | 210891021 | modelica_metatype listReverseInPlace(modelica_metatype lst) | |
| 436 | { | ||
| 437 | modelica_metatype prev = mmc_mk_nil(); | ||
| 438 |
2/2✓ Branch 0 taken 360694360 times.
✓ Branch 1 taken 210891021 times.
|
571585381 | while (!MMC_NILTEST(lst)) |
| 439 | { | ||
| 440 | 360694360 | modelica_metatype oldcdr = MMC_CDR(lst); | |
| 441 | 360694360 | MMC_CDR(lst) = prev; | |
| 442 | prev = lst; | ||
| 443 | lst = oldcdr; | ||
| 444 | } | ||
| 445 | 210891021 | return prev; | |
| 446 | } | ||
| 447 | |||
| 448 | 2122079 | void boxptr_listSetRest(threadData_t *threadData, modelica_metatype cellToDestroy, modelica_metatype newRest) | |
| 449 | { | ||
| 450 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2122079 times.
|
2122079 | if (MMC_NILTEST(cellToDestroy)) { |
| 451 | ✗ | MMC_THROW_INTERNAL(); | |
| 452 | } | ||
| 453 | 2122079 | MMC_CDR(cellToDestroy) = newRest; | |
| 454 | 2122079 | } | |
| 455 | |||
| 456 | 113 | void boxptr_listSetFirst(threadData_t *threadData, modelica_metatype cellToDestroy, modelica_metatype newContent) | |
| 457 | { | ||
| 458 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
|
113 | if (MMC_NILTEST(cellToDestroy)) { |
| 459 | ✗ | MMC_THROW_INTERNAL(); | |
| 460 | } | ||
| 461 | 113 | MMC_CAR(cellToDestroy) = newContent; | |
| 462 | 113 | } | |
| 463 | |||
| 464 | 123 | modelica_metatype listAppendDestroy(modelica_metatype lstFirstDestroyed, modelica_metatype listSecondKept) | |
| 465 | { | ||
| 466 | modelica_metatype lst = lstFirstDestroyed; | ||
| 467 |
2/2✓ Branch 0 taken 122 times.
✓ Branch 1 taken 1 time.
|
123 | if (MMC_NILTEST(lstFirstDestroyed)) { |
| 468 | return listSecondKept; | ||
| 469 | } | ||
| 470 |
2/2✓ Branch 0 taken 199 times.
✓ Branch 1 taken 122 times.
|
321 | while (!MMC_NILTEST(MMC_CDR(lst))) { |
| 471 | lst = MMC_CDR(lst); | ||
| 472 | } | ||
| 473 | /* reached the end, set the element */ | ||
| 474 | 122 | MMC_CDR(lst) = listSecondKept; | |
| 475 | 122 | return lstFirstDestroyed; | |
| 476 | } | ||
| 477 | |||
| 478 | 275058111 | modelica_metatype listAppend(modelica_metatype l1, modelica_metatype l2) | |
| 479 | { | ||
| 480 | int length = 0, i = 0; | ||
| 481 | struct mmc_cons_struct *res = NULL; | ||
| 482 | struct mmc_cons_struct *p = NULL; | ||
| 483 |
2/2✓ Branch 0 taken 122164231 times.
✓ Branch 1 taken 152893880 times.
|
275058111 | if (MMC_NILTEST(l2)) /* If l2 is empty, simply return l1; huge performance gain for some uses of listAppend */ |
| 484 | return l1; | ||
| 485 | 122164231 | length = listLength(l1); | |
| 486 |
2/2✓ Branch 0 taken 17326758 times.
✓ Branch 1 taken 104837473 times.
|
122164231 | if (length == 0) /* We need to check for empty l1 */ |
| 487 | return l2; | ||
| 488 | 17326758 | res = (struct mmc_cons_struct*)mmc_alloc_words( length * 3 /*(sizeof(struct mmc_cons_struct)/sizeof(void*))*/ ); /* Do one single big alloc. It's cheaper */ | |
| 489 |
2/2✓ Branch 0 taken 20304485 times.
✓ Branch 1 taken 17326758 times.
|
37631243 | for (i=0; i<length-1; i++) { /* Write all except the last element... */ |
| 490 | 20304485 | p = res+i; | |
| 491 | 20304485 | p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); | |
| 492 | 20304485 | p->data[0] = MMC_CAR(l1); | |
| 493 | 20304485 | p->data[1] = MMC_TAGPTR(res+i+1); | |
| 494 | 20304485 | l1 = MMC_CDR(l1); | |
| 495 | } | ||
| 496 | /* The last element is a bit special. It points to l2. */ | ||
| 497 | 17326758 | p = res+length-1; | |
| 498 | 17326758 | p->header = MMC_STRUCTHDR(2, MMC_CONS_CTOR); | |
| 499 | 17326758 | p->data[0] = MMC_CAR(l1); | |
| 500 | 17326758 | p->data[1] = l2; | |
| 501 | 17326758 | return MMC_TAGPTR(res); | |
| 502 | } | ||
| 503 | |||
| 504 | 224368657 | modelica_integer listLength(modelica_metatype lst) | |
| 505 | { | ||
| 506 | modelica_integer res = 0; | ||
| 507 |
2/2✓ Branch 0 taken 248609397 times.
✓ Branch 1 taken 224368657 times.
|
472978054 | while (!MMC_NILTEST(lst)) |
| 508 | { | ||
| 509 | 248609397 | lst = MMC_CDR(lst); | |
| 510 | 248609397 | res++; | |
| 511 | } | ||
| 512 | 224368657 | return res; | |
| 513 | } | ||
| 514 | |||
| 515 | 10556742 | modelica_boolean listMember(modelica_metatype obj, modelica_metatype lst) | |
| 516 | { | ||
| 517 |
2/2✓ Branch 0 taken 49548806 times.
✓ Branch 1 taken 9122208 times.
|
58671014 | while (!MMC_NILTEST(lst)) |
| 518 | { | ||
| 519 |
2/2✓ Branch 1 taken 48114272 times.
✓ Branch 2 taken 1434534 times.
|
49548806 | if (valueEq(MMC_CAR(lst), obj)) { |
| 520 | return 1; | ||
| 521 | } | ||
| 522 | 48114272 | lst = MMC_CDR(lst); | |
| 523 | } | ||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | 3959883 | modelica_metatype boxptr_listGet(threadData_t *threadData,modelica_metatype lst, modelica_metatype ii) | |
| 528 | { | ||
| 529 | modelica_metatype res; | ||
| 530 | 3959883 | int i = mmc_unbox_integer(ii); | |
| 531 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3959877 times.
|
3959883 | if (i < 1) |
| 532 | 6 | MMC_THROW_INTERNAL(); | |
| 533 |
2/2✓ Branch 0 taken 38298426 times.
✓ Branch 1 taken 925 times.
|
38299351 | while (!MMC_NILTEST(lst)) |
| 534 | { | ||
| 535 |
2/2✓ Branch 0 taken 3958952 times.
✓ Branch 1 taken 34339474 times.
|
38298426 | if (i == 1) { |
| 536 | 3958952 | return MMC_CAR(lst); | |
| 537 | } | ||
| 538 | 34339474 | lst = MMC_CDR(lst); | |
| 539 | 34339474 | i--; | |
| 540 | } | ||
| 541 | 925 | MMC_THROW_INTERNAL(); /* List was not long enough */ | |
| 542 | } | ||
| 543 | |||
| 544 | 85 | modelica_metatype boxptr_listDelete(threadData_t *threadData, modelica_metatype lst, modelica_metatype iix) | |
| 545 | { | ||
| 546 | /* TODO: If we assume the index exists we can do this in a much better way */ | ||
| 547 | 85 | int ix = mmc_unbox_integer(iix); | |
| 548 | modelica_metatype *tmpArr = NULL; | ||
| 549 | int i = 0; | ||
| 550 | |||
| 551 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
|
85 | if (ix <= 0) { |
| 552 | ✗ | MMC_THROW_INTERNAL(); | |
| 553 | } | ||
| 554 | |||
| 555 | 85 | tmpArr = (modelica_metatype *) mmc_alloc_words(ix-1); /* We know the size of the first part of the list */ | |
| 556 | if (tmpArr == NULL) { | ||
| 557 | fprintf(stderr, "%s:%d: malloc failed", __FILE__, __LINE__); | ||
| 558 | EXIT(1); | ||
| 559 | } | ||
| 560 | |||
| 561 |
2/2✓ Branch 0 taken 973 times.
✓ Branch 1 taken 85 times.
|
1058 | for (i=0; i<ix-1; i++) { |
| 562 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 973 times.
|
973 | if (listEmpty(lst)) { |
| 563 | if (tmpArr) { | ||
| 564 | ✗ | GC_free(tmpArr); | |
| 565 | } | ||
| 566 | ✗ | MMC_THROW_INTERNAL(); | |
| 567 | } | ||
| 568 | 973 | tmpArr[i] = MMC_CAR(lst); | |
| 569 | 973 | lst = MMC_CDR(lst); | |
| 570 | } | ||
| 571 | |||
| 572 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
|
85 | if (listEmpty(lst)) { |
| 573 | ✗ | GC_free(tmpArr); | |
| 574 | ✗ | MMC_THROW_INTERNAL(); | |
| 575 | } | ||
| 576 | 85 | lst = MMC_CDR(lst); | |
| 577 | |||
| 578 |
2/2✓ Branch 0 taken 973 times.
✓ Branch 1 taken 85 times.
|
1058 | for (i=ix-2; i>=0; i--) { |
| 579 | 973 | lst = mmc_mk_cons(tmpArr[i], lst); | |
| 580 | } | ||
| 581 | 85 | GC_free(tmpArr); | |
| 582 | |||
| 583 | 85 | return lst; | |
| 584 | } | ||
| 585 | |||
| 586 | 90753794 | modelica_metatype boxptr_listRest(threadData_t *threadData, modelica_metatype lst) | |
| 587 | { | ||
| 588 |
2/2✓ Branch 0 taken 90753727 times.
✓ Branch 1 taken 67 times.
|
90753794 | if (!MMC_NILTEST(lst)) { |
| 589 | 90753727 | return MMC_CDR(lst); | |
| 590 | } | ||
| 591 | 67 | MMC_THROW_INTERNAL(); | |
| 592 | } | ||
| 593 | |||
| 594 | 334877134 | modelica_metatype boxptr_listHead(threadData_t *threadData, modelica_metatype lst) | |
| 595 | { | ||
| 596 |
2/2✓ Branch 0 taken 332725904 times.
✓ Branch 1 taken 2151230 times.
|
334877134 | if (!MMC_NILTEST(lst)) { |
| 597 | 332725904 | return MMC_CAR(lst); | |
| 598 | } | ||
| 599 | 2151230 | MMC_THROW_INTERNAL(); | |
| 600 | } | ||
| 601 | |||
| 602 | /* Array Operations */ | ||
| 603 | |||
| 604 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2235093 times.
|
2235093 | modelica_metatype arrayList(modelica_metatype arr) |
| 605 | { | ||
| 606 | 2235093 | int nelts = arrayLength(arr)-1; | |
| 607 | 2235093 | void **vecp = MMC_STRUCTDATA(arr); | |
| 608 | void *res = mmc_mk_nil(); | ||
| 609 |
2/2✓ Branch 0 taken 1492322 times.
✓ Branch 1 taken 2235093 times.
|
3727415 | for(; nelts >= 0; --nelts) { |
| 610 | 1492322 | res = mmc_mk_cons(vecp[nelts],res); | |
| 611 | } | ||
| 612 | 2235093 | return res; | |
| 613 | } | ||
| 614 | |||
| 615 | 3238032 | modelica_metatype listArray(modelica_metatype lst) | |
| 616 | { | ||
| 617 | 3238032 | int nelts = listLength(lst); | |
| 618 | 3238032 | void* arr = (struct mmc_struct*)mmc_mk_box_no_assign(nelts, MMC_ARRAY_TAG, MMC_IS_IMMEDIATE(MMC_CAR(lst))); | |
| 619 | 3238032 | void **arrp = MMC_STRUCTDATA(arr); | |
| 620 | int i = 0; | ||
| 621 |
2/2✓ Branch 0 taken 3880159 times.
✓ Branch 1 taken 3238032 times.
|
7118191 | for(i=0; i<nelts; i++) { |
| 622 | 3880159 | arrp[i] = MMC_CAR(lst); | |
| 623 | 3880159 | lst = MMC_CDR(lst); | |
| 624 | } | ||
| 625 | 3238032 | return arr; | |
| 626 | } | ||
| 627 | |||
| 628 | 12790 | modelica_metatype listArrayLiteral(modelica_metatype lst) | |
| 629 | { | ||
| 630 | 12790 | return listArray(lst); | |
| 631 | } | ||
| 632 | |||
| 633 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1336279 times.
|
1336279 | modelica_metatype arrayCopy(modelica_metatype arr) |
| 634 | { | ||
| 635 | 1336279 | int nelts = arrayLength(arr); | |
| 636 | 1336279 | void* res = (struct mmc_struct*)mmc_mk_box_no_assign(nelts, MMC_ARRAY_TAG, MMC_IS_IMMEDIATE(MMC_STRUCTDATA(arr)[0])); | |
| 637 | 1336279 | void **arrp = MMC_STRUCTDATA(arr); | |
| 638 | 1336279 | void **resp = MMC_STRUCTDATA(res); | |
| 639 | 1336279 | memcpy(resp, arrp, sizeof(modelica_metatype)*nelts); | |
| 640 | 1336279 | return res; | |
| 641 | } | ||
| 642 | |||
| 643 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
|
158 | modelica_metatype arrayAppend(modelica_metatype arr1, modelica_metatype arr2) |
| 644 | { | ||
| 645 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
|
158 | int nelts1 = arrayLength(arr1); |
| 646 | 158 | int nelts2 = arrayLength(arr2); | |
| 647 | 158 | void* res = (struct mmc_struct*)mmc_mk_box_no_assign(nelts1 + nelts2, MMC_ARRAY_TAG, MMC_IS_IMMEDIATE(MMC_STRUCTDATA(arr1)[0])); | |
| 648 | 158 | void **arr1p = MMC_STRUCTDATA(arr1); | |
| 649 | 158 | void **arr2p = MMC_STRUCTDATA(arr2); | |
| 650 | 158 | void **resp = MMC_STRUCTDATA(res); | |
| 651 | int i; | ||
| 652 |
2/2✓ Branch 0 taken 4602 times.
✓ Branch 1 taken 158 times.
|
4760 | for (i=0; i<nelts1; ++i) { |
| 653 | 4602 | resp[i] = arr1p[i]; | |
| 654 | } | ||
| 655 |
2/2✓ Branch 0 taken 14936 times.
✓ Branch 1 taken 158 times.
|
15094 | for (i=0; i<nelts2; ++i) { |
| 656 | 14936 | resp[i+nelts1] = arr2p[i]; | |
| 657 | } | ||
| 658 | 158 | return res; | |
| 659 | } | ||
| 660 | |||
| 661 | /* Misc Operations */ | ||
| 662 | 1 | modelica_integer tick(void) | |
| 663 | { | ||
| 664 | static modelica_integer curTick = 0; | ||
| 665 | 1 | return curTick++; | |
| 666 | } | ||
| 667 | |||
| 668 | 3 | void boxptr_print(threadData_t *threadData,modelica_metatype str) | |
| 669 | { | ||
| 670 | 3 | fputs(MMC_STRINGDATA(str), stdout); | |
| 671 | 3 | } | |
| 672 | |||
| 673 | ✗ | modelica_real mmc_clock(void) | |
| 674 | { | ||
| 675 | static double start_t; | ||
| 676 | static int init = 1; | ||
| 677 | ✗ | if (init) { | |
| 678 | ✗ | start_t = ((double)clock())/CLOCKS_PER_SEC; | |
| 679 | ✗ | init = 0; | |
| 680 | ✗ | return 0.0; | |
| 681 | } | ||
| 682 | ✗ | return (clock()-start_t)/CLOCKS_PER_SEC; | |
| 683 | } | ||
| 684 | |||
| 685 | 4 | void boxptr_equality(threadData_t *threadData,modelica_metatype in1, modelica_metatype in2) | |
| 686 | { | ||
| 687 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3 times.
|
4 | if (!valueEq(in1, in2)) { |
| 688 | /* fprintf(stderr, "%s != %s\n", anyString(in1), anyString(in2)); */ | ||
| 689 | 1 | MMC_THROW_INTERNAL(); | |
| 690 | } | ||
| 691 | 3 | } | |
| 692 | |||
| 693 | 108558325 | modelica_metatype nobox_getGlobalRoot(threadData_t *threadData, modelica_integer ix) { | |
| 694 | void *val = 0; | ||
| 695 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 108558325 times.
|
108558325 | if (ix < 0 || ix >= MMC_GC_GLOBAL_ROOTS_SIZE) { |
| 696 | ✗ | MMC_THROW_INTERNAL(); | |
| 697 |
2/2✓ Branch 0 taken 108287653 times.
✓ Branch 1 taken 270672 times.
|
108558325 | } else if (ix > 8) { |
| 698 | 108287653 | val = mmc_GC_state->global_roots[ix]; | |
| 699 | } else { | ||
| 700 | 270672 | val = threadData->localRoots[ix]; | |
| 701 | } | ||
| 702 |
2/2✓ Branch 0 taken 12170 times.
✓ Branch 1 taken 108546155 times.
|
108558325 | if (!val) { |
| 703 | 12170 | MMC_THROW_INTERNAL(); | |
| 704 | } | ||
| 705 | 108546155 | return val; | |
| 706 | } | ||
| 707 | |||
| 708 | 2158918 | void boxptr_setGlobalRoot(threadData_t *threadData, modelica_metatype i, modelica_metatype val) { | |
| 709 | 2158918 | int ix = mmc_unbox_integer(i); | |
| 710 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2158918 times.
|
2158918 | if (ix < 0 || ix >= MMC_GC_GLOBAL_ROOTS_SIZE) { |
| 711 | ✗ | MMC_THROW_INTERNAL(); | |
| 712 |
2/2✓ Branch 0 taken 2062934 times.
✓ Branch 1 taken 95984 times.
|
2158918 | } else if (ix > 8) { |
| 713 | 2062934 | mmc_GC_state->global_roots[ix] = val; | |
| 714 | } else { | ||
| 715 | 95984 | threadData->localRoots[ix] = val; | |
| 716 | } | ||
| 717 | 2158918 | } | |
| 718 | |||
| 719 | ✗ | modelica_boolean setStackOverflowSignal(modelica_boolean inSignal) | |
| 720 | { | ||
| 721 | /* return for now what we got */ | ||
| 722 | ✗ | return inSignal; | |
| 723 | } | ||
| 724 | |||
| 725 | #if (defined(__linux__) && defined(__GLIBC__)) || defined(__APPLE_CC__) || defined(__FreeBSD__) | ||
| 726 | #include <execinfo.h> | ||
| 727 | ✗ | metamodelica_string referenceDebugString(modelica_metatype fnptr) | |
| 728 | { | ||
| 729 | void *res; | ||
| 730 | ✗ | char **str = backtrace_symbols(&fnptr, 1); | |
| 731 | ✗ | if (str == 0) { | |
| 732 | ✗ | return mmc_mk_scon("Unknown symbol"); | |
| 733 | } | ||
| 734 | ✗ | res = mmc_mk_scon(*str); | |
| 735 | ✗ | free(str); | |
| 736 | ✗ | return res; | |
| 737 | } | ||
| 738 | #else | ||
| 739 | metamodelica_string referenceDebugString(modelica_metatype fnptr) | ||
| 740 | { | ||
| 741 | return mmc_mk_scon("Unknown symbol"); | ||
| 742 | } | ||
| 743 | #endif | ||
| 744 | |||
| 745 | ✗ | metamodelica_string referencePointerString(modelica_metatype ptr) | |
| 746 | { | ||
| 747 | // 2 chars per byte + 3 for "0x" and null terminator. | ||
| 748 | char str[sizeof(void*)*2 + 3]; | ||
| 749 | snprintf(str, sizeof(void*)*2 + 3, "%p", ptr); | ||
| 750 | ✗ | return mmc_mk_scon(str); | |
| 751 | } | ||
| 752 | |||
| 753 | const char* SourceInfo_SOURCEINFO__desc__fields[7] = {"fileName","isReadOnly","lineNumberStart","columnNumberStart","lineNumberEnd","columnNumberEnd","lastEditTime"}; | ||
| 754 | struct record_description SourceInfo_SOURCEINFO__desc = { | ||
| 755 | "SourceInfo_SOURCEINFO", | ||
| 756 | "SourceInfo.SOURCEINFO", | ||
| 757 | SourceInfo_SOURCEINFO__desc__fields | ||
| 758 | }; | ||
| 759 |