Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 22.8% 114 / 0 / 501
Functions: 32.3% 10 / 0 / 31
Branches: 30.3% 79 / 0 / 261

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