on master help sign in
fix to some "obvious" bugs in BitsN primops

Ok, so many primops on 8, 16, 32, 64 bit machine words in the C runtime operate by passing arg pointers to functions that begin by allocating a new VAL cell to hold the result. If this allocation results in a GC collection then the argument pointers may be pointing into the old heap, to a cell whose contents has been overwritten with a forwarding pointer. While the collection algorithm should update any references to these forwarding cells to the new cell, it can't fixup the pointer you are holding onto right now "between instructions". This bug happens when your operation is interrupted by the GC and you use the forwarding pointer(s) as the arguments, resulting in incorrect results. This would be hard to reproduce because it depends on the timing of the GC. But the package idris-tf-random nonetheless can reproduce this if it runs long enough, because it makes extensive use of BitsN operations. My canary program at http://lpaste.net/112132 dumps the output of a Bits32 generator with a static seed, but after a certain number of iterations (depending on GC timing) the sequence will act differently from previous runs (depending on the value of the forwarding pointers it is erroneously using). This commit makes the program apparently deterministic again. If you look at the GMP operations in rts/idris_gmp.c you will see in the corresponding gmp ops, after the allocation of the result, the arguments are retrieved using GETBIG which may follow this forwarding pointer. Similarly I added four GETBITSN macros which either get these bits value directly or get it from the forwarded VAL cell by testing if ty = FWD. Operations in rts/idris_bitstring.c that do not do an allocation did not get wrapped in this macro. I'm planning to review GETBIG too, since it is recursive and the shortcut case for INT (which does allocation) may suffer from this bug too.

commit61848565dcffd40ae3bd2beba19a575fa551bbad authorEvanR <evanrinehart@gmail.com> dateTue 7 Oct 2014, 00:36 (12 years ago) parent7dfbfac
2 files changed+84−79
rts/idris_bitstring.c+79−79 rts/idris_rts.h+5
rts/idris_bitstring.c+79−79
@@ -3,28 +3,28 @@
33VAL idris_b8CopyForGC(VM *vm, VAL a) {
44 VAL cl = allocate(vm, sizeof(Closure), 1);
55 SETTY(cl, BITS8);
6− cl->info.bits8 = a->info.bits8;
6+ cl->info.bits8 = GETBITS8(a);
77 return cl;
88}
99
1010VAL idris_b16CopyForGC(VM *vm, VAL a) {
1111 VAL cl = allocate(vm, sizeof(Closure), 1);
1212 SETTY(cl, BITS16);
13− cl->info.bits16 = a->info.bits16;
13+ cl->info.bits16 = GETBITS16(a);
1414 return cl;
1515}
1616
1717VAL idris_b32CopyForGC(VM *vm, VAL a) {
1818 VAL cl = allocate(vm, sizeof(Closure), 1);
1919 SETTY(cl, BITS32);
20− cl->info.bits32 = a->info.bits32;
20+ cl->info.bits32 = GETBITS32(a);
2121 return cl;
2222}
2323
2424VAL idris_b64CopyForGC(VM *vm, VAL a) {
2525 VAL cl = allocate(vm, sizeof(Closure), 1);
2626 SETTY(cl, BITS64);
27− cl->info.bits64 = a->info.bits64;
27+ cl->info.bits64 = GETBITS64(a);
2828 return cl;
2929}
3030
@@ -91,49 +91,49 @@ VAL idris_b64const(VM *vm, uint64_t a) {
9191VAL idris_b8Plus(VM *vm, VAL a, VAL b) {
9292 VAL cl = allocate(vm, sizeof(Closure), 0);
9393 SETTY(cl, BITS8);
94− cl->info.bits8 = a->info.bits8 + b->info.bits8;
94+ cl->info.bits8 = GETBITS8(a) + GETBITS8(b);
9595 return cl;
9696}
9797
9898VAL idris_b8Minus(VM *vm, VAL a, VAL b) {
9999 VAL cl = allocate(vm, sizeof(Closure), 0);
100100 SETTY(cl, BITS8);
101− cl->info.bits8 = a->info.bits8 - b->info.bits8;
101+ cl->info.bits8 = GETBITS8(a) - GETBITS8(b);
102102 return cl;
103103}
104104
105105VAL idris_b8Times(VM *vm, VAL a, VAL b) {
106106 VAL cl = allocate(vm, sizeof(Closure), 0);
107107 SETTY(cl, BITS8);
108− cl->info.bits8 = a->info.bits8 * b->info.bits8;
108+ cl->info.bits8 = GETBITS8(a) * GETBITS8(b);
109109 return cl;
110110}
111111
112112VAL idris_b8UDiv(VM *vm, VAL a, VAL b) {
113113 VAL cl = allocate(vm, sizeof(Closure), 0);
114114 SETTY(cl, BITS8);
115− cl->info.bits8 = a->info.bits8 / b->info.bits8;
115+ cl->info.bits8 = GETBITS8(a) / GETBITS8(b);
116116 return cl;
117117}
118118
119119VAL idris_b8SDiv(VM *vm, VAL a, VAL b) {
120120 VAL cl = allocate(vm, sizeof(Closure), 0);
121121 SETTY(cl, BITS8);
122− cl->info.bits8 = (uint8_t) (((int8_t) a->info.bits8) / ((int8_t) b->info.bits8));
122+ cl->info.bits8 = (uint8_t) (((int8_t) GETBITS8(a)) / ((int8_t) GETBITS8(b)));
123123 return cl;
124124}
125125
126126VAL idris_b8URem(VM *vm, VAL a, VAL b) {
127127 VAL cl = allocate(vm, sizeof(Closure), 0);
128128 SETTY(cl, BITS8);
129− cl->info.bits8 = a->info.bits8 % b->info.bits8;
129+ cl->info.bits8 = GETBITS8(a) % GETBITS8(b);
130130 return cl;
131131}
132132
133133VAL idris_b8SRem(VM *vm, VAL a, VAL b) {
134134 VAL cl = allocate(vm, sizeof(Closure), 0);
135135 SETTY(cl, BITS8);
136− cl->info.bits8 = (uint8_t) (((int8_t) a->info.bits8) % ((int8_t) b->info.bits8));
136+ cl->info.bits8 = (uint8_t) (((int8_t) GETBITS8(a)) % ((int8_t) GETBITS8(b)));
137137 return cl;
138138}
139139
@@ -160,77 +160,77 @@ VAL idris_b8Gte(VM *vm, VAL a, VAL b) {
160160VAL idris_b8Compl(VM *vm, VAL a) {
161161 VAL cl = allocate(vm, sizeof(Closure), 0);
162162 SETTY(cl, BITS8);
163− cl->info.bits8 = ~ a->info.bits8;
163+ cl->info.bits8 = ~ GETBITS8(a);
164164 return cl;
165165}
166166
167167VAL idris_b8And(VM *vm, VAL a, VAL b) {
168168 VAL cl = allocate(vm, sizeof(Closure), 0);
169169 SETTY(cl, BITS8);
170− cl->info.bits8 = a->info.bits8 & b->info.bits8;
170+ cl->info.bits8 = GETBITS8(a) & GETBITS8(b);
171171 return cl;
172172}
173173
174174VAL idris_b8Or(VM *vm, VAL a, VAL b) {
175175 VAL cl = allocate(vm, sizeof(Closure), 0);
176176 SETTY(cl, BITS8);
177− cl->info.bits8 = a->info.bits8 | b->info.bits8;
177+ cl->info.bits8 = GETBITS8(a) | GETBITS8(b);
178178 return cl;
179179}
180180
181181VAL idris_b8Xor(VM *vm, VAL a, VAL b) {
182182 VAL cl = allocate(vm, sizeof(Closure), 0);
183183 SETTY(cl, BITS8);
184− cl->info.bits8 = a->info.bits8 ^ b->info.bits8;
184+ cl->info.bits8 = GETBITS8(a) ^ GETBITS8(b);
185185 return cl;
186186}
187187
188188VAL idris_b8Shl(VM *vm, VAL a, VAL b) {
189189 VAL cl = allocate(vm, sizeof(Closure), 0);
190190 SETTY(cl, BITS8);
191− cl->info.bits8 = a->info.bits8 << b->info.bits8;
191+ cl->info.bits8 = GETBITS8(a) << GETBITS8(b);
192192 return cl;
193193}
194194
195195VAL idris_b8LShr(VM *vm, VAL a, VAL b) {
196196 VAL cl = allocate(vm, sizeof(Closure), 0);
197197 SETTY(cl, BITS8);
198− cl->info.bits8 = a->info.bits8 >> b->info.bits8;
198+ cl->info.bits8 = GETBITS8(a) >> GETBITS8(b);
199199 return cl;
200200}
201201
202202VAL idris_b8AShr(VM *vm, VAL a, VAL b) {
203203 VAL cl = allocate(vm, sizeof(Closure), 0);
204204 SETTY(cl, BITS8);
205− cl->info.bits8 = (uint8_t) (((int8_t)a->info.bits8) >> ((int8_t)b->info.bits8));
205+ cl->info.bits8 = (uint8_t) (((int8_t)GETBITS8(a)) >> ((int8_t)GETBITS8(b)));
206206 return cl;
207207}
208208
209209VAL idris_b16Plus(VM *vm, VAL a, VAL b) {
210210 VAL cl = allocate(vm, sizeof(Closure), 0);
211211 SETTY(cl, BITS16);
212− cl->info.bits16 = a->info.bits16 + b->info.bits16;
212+ cl->info.bits16 = GETBITS16(a) + GETBITS16(b);
213213 return cl;
214214}
215215
216216VAL idris_b16Minus(VM *vm, VAL a, VAL b) {
217217 VAL cl = allocate(vm, sizeof(Closure), 0);
218218 SETTY(cl, BITS16);
219− cl->info.bits16 = a->info.bits16 - b->info.bits16;
219+ cl->info.bits16 = GETBITS16(a) - GETBITS16(b);
220220 return cl;
221221}
222222
223223VAL idris_b16Times(VM *vm, VAL a, VAL b) {
224224 VAL cl = allocate(vm, sizeof(Closure), 0);
225225 SETTY(cl, BITS16);
226− cl->info.bits16 = a->info.bits16 * b->info.bits16;
226+ cl->info.bits16 = GETBITS16(a) * GETBITS16(b);
227227 return cl;
228228}
229229
230230VAL idris_b16UDiv(VM *vm, VAL a, VAL b) {
231231 VAL cl = allocate(vm, sizeof(Closure), 0);
232232 SETTY(cl, BITS16);
233− cl->info.bits16 = a->info.bits16 / b->info.bits16;
233+ cl->info.bits16 = GETBITS16(a) / GETBITS16(b);
234234 return cl;
235235}
236236
@@ -238,14 +238,14 @@ VAL idris_b16SDiv(VM *vm, VAL a, VAL b) {
238238 VAL cl = allocate(vm, sizeof(Closure), 0);
239239 SETTY(cl, BITS16);
240240 cl->info.bits16 =
241− (uint16_t) (((int16_t) a->info.bits16) / ((int16_t) b->info.bits16));
241+ (uint16_t) (((int16_t) GETBITS16(a)) / ((int16_t) GETBITS16(b)));
242242 return cl;
243243}
244244
245245VAL idris_b16URem(VM *vm, VAL a, VAL b) {
246246 VAL cl = allocate(vm, sizeof(Closure), 0);
247247 SETTY(cl, BITS16);
248− cl->info.bits16 = a->info.bits16 % b->info.bits16;
248+ cl->info.bits16 = GETBITS16(a) % GETBITS16(b);
249249 return cl;
250250}
251251
@@ -253,7 +253,7 @@ VAL idris_b16SRem(VM *vm, VAL a, VAL b) {
253253 VAL cl = allocate(vm, sizeof(Closure), 0);
254254 SETTY(cl, BITS16);
255255 cl->info.bits16 =
256− (uint16_t) (((int16_t) a->info.bits16) % ((int16_t) b->info.bits16));
256+ (uint16_t) (((int16_t) GETBITS16(a)) % ((int16_t) GETBITS16(b)));
257257 return cl;
258258}
259259
@@ -280,77 +280,77 @@ VAL idris_b16Gte(VM *vm, VAL a, VAL b) {
280280VAL idris_b16Compl(VM *vm, VAL a) {
281281 VAL cl = allocate(vm, sizeof(Closure), 0);
282282 SETTY(cl, BITS16);
283− cl->info.bits16 = ~ a->info.bits16;
283+ cl->info.bits16 = ~ GETBITS16(a);
284284 return cl;
285285}
286286
287287VAL idris_b16And(VM *vm, VAL a, VAL b) {
288288 VAL cl = allocate(vm, sizeof(Closure), 0);
289289 SETTY(cl, BITS16);
290− cl->info.bits16 = a->info.bits16 & b->info.bits16;
290+ cl->info.bits16 = GETBITS16(a) & GETBITS16(b);
291291 return cl;
292292}
293293
294294VAL idris_b16Or(VM *vm, VAL a, VAL b) {
295295 VAL cl = allocate(vm, sizeof(Closure), 0);
296296 SETTY(cl, BITS16);
297− cl->info.bits16 = a->info.bits16 | b->info.bits16;
297+ cl->info.bits16 = GETBITS16(a) | GETBITS16(b);
298298 return cl;
299299}
300300
301301VAL idris_b16Xor(VM *vm, VAL a, VAL b) {
302302 VAL cl = allocate(vm, sizeof(Closure), 0);
303303 SETTY(cl, BITS16);
304− cl->info.bits16 = a->info.bits16 ^ b->info.bits16;
304+ cl->info.bits16 = GETBITS16(a) ^ GETBITS16(b);
305305 return cl;
306306}
307307
308308VAL idris_b16Shl(VM *vm, VAL a, VAL b) {
309309 VAL cl = allocate(vm, sizeof(Closure), 0);
310310 SETTY(cl, BITS16);
311− cl->info.bits16 = a->info.bits16 << b->info.bits16;
311+ cl->info.bits16 = GETBITS16(a) << GETBITS16(b);
312312 return cl;
313313}
314314
315315VAL idris_b16LShr(VM *vm, VAL a, VAL b) {
316316 VAL cl = allocate(vm, sizeof(Closure), 0);
317317 SETTY(cl, BITS16);
318− cl->info.bits16 = a->info.bits16 >> b->info.bits16;
318+ cl->info.bits16 = GETBITS16(a) >> GETBITS16(b);
319319 return cl;
320320}
321321
322322VAL idris_b16AShr(VM *vm, VAL a, VAL b) {
323323 VAL cl = allocate(vm, sizeof(Closure), 0);
324324 SETTY(cl, BITS16);
325− cl->info.bits16 = (uint16_t) (((int16_t)a->info.bits16) >> ((int16_t)b->info.bits16));
325+ cl->info.bits16 = (uint16_t) (((int16_t)GETBITS16(a)) >> ((int16_t)GETBITS16(b)));
326326 return cl;
327327}
328328
329329VAL idris_b32Plus(VM *vm, VAL a, VAL b) {
330330 VAL cl = allocate(vm, sizeof(Closure), 0);
331331 SETTY(cl, BITS32);
332− cl->info.bits32 = a->info.bits32 + b->info.bits32;
332+ cl->info.bits32 = GETBITS32(a) + GETBITS32(b);
333333 return cl;
334334}
335335
336336VAL idris_b32Minus(VM *vm, VAL a, VAL b) {
337337 VAL cl = allocate(vm, sizeof(Closure), 0);
338338 SETTY(cl, BITS32);
339− cl->info.bits32 = a->info.bits32 - b->info.bits32;
339+ cl->info.bits32 = GETBITS32(a) - GETBITS32(b);
340340 return cl;
341341}
342342
343343VAL idris_b32Times(VM *vm, VAL a, VAL b) {
344344 VAL cl = allocate(vm, sizeof(Closure), 0);
345345 SETTY(cl, BITS32);
346− cl->info.bits32 = a->info.bits32 * b->info.bits32;
346+ cl->info.bits32 = GETBITS32(a) * GETBITS32(b);
347347 return cl;
348348}
349349
350350VAL idris_b32UDiv(VM *vm, VAL a, VAL b) {
351351 VAL cl = allocate(vm, sizeof(Closure), 0);
352352 SETTY(cl, BITS32);
353− cl->info.bits32 = a->info.bits32 / b->info.bits32;
353+ cl->info.bits32 = GETBITS32(a) / GETBITS32(b);
354354 return cl;
355355}
356356
@@ -358,14 +358,14 @@ VAL idris_b32SDiv(VM *vm, VAL a, VAL b) {
358358 VAL cl = allocate(vm, sizeof(Closure), 0);
359359 SETTY(cl, BITS32);
360360 cl->info.bits32 =
361− (uint32_t) (((int32_t) a->info.bits32) / ((int32_t) b->info.bits32));
361+ (uint32_t) (((int32_t) GETBITS32(a)) / ((int32_t) GETBITS32(b)));
362362 return cl;
363363}
364364
365365VAL idris_b32URem(VM *vm, VAL a, VAL b) {
366366 VAL cl = allocate(vm, sizeof(Closure), 0);
367367 SETTY(cl, BITS32);
368− cl->info.bits32 = a->info.bits32 % b->info.bits32;
368+ cl->info.bits32 = GETBITS32(a) % GETBITS32(b);
369369 return cl;
370370}
371371
@@ -373,7 +373,7 @@ VAL idris_b32SRem(VM *vm, VAL a, VAL b) {
373373 VAL cl = allocate(vm, sizeof(Closure), 0);
374374 SETTY(cl, BITS32);
375375 cl->info.bits32 =
376− (uint32_t) (((int32_t) a->info.bits32) % ((int32_t) b->info.bits32));
376+ (uint32_t) (((int32_t) GETBITS32(a)) % ((int32_t) GETBITS32(b)));
377377 return cl;
378378}
379379
@@ -400,77 +400,77 @@ VAL idris_b32Gte(VM *vm, VAL a, VAL b) {
400400VAL idris_b32Compl(VM *vm, VAL a) {
401401 VAL cl = allocate(vm, sizeof(Closure), 0);
402402 SETTY(cl, BITS32);
403− cl->info.bits32 = ~ a->info.bits32;
403+ cl->info.bits32 = ~ GETBITS32(a);
404404 return cl;
405405}
406406
407407VAL idris_b32And(VM *vm, VAL a, VAL b) {
408408 VAL cl = allocate(vm, sizeof(Closure), 0);
409409 SETTY(cl, BITS32);
410− cl->info.bits32 = a->info.bits32 & b->info.bits32;
410+ cl->info.bits32 = GETBITS32(a) & GETBITS32(b);
411411 return cl;
412412}
413413
414414VAL idris_b32Or(VM *vm, VAL a, VAL b) {
415415 VAL cl = allocate(vm, sizeof(Closure), 0);
416416 SETTY(cl, BITS32);
417− cl->info.bits32 = a->info.bits32 | b->info.bits32;
417+ cl->info.bits32 = GETBITS32(a) | GETBITS32(b);
418418 return cl;
419419}
420420
421421VAL idris_b32Xor(VM *vm, VAL a, VAL b) {
422422 VAL cl = allocate(vm, sizeof(Closure), 0);
423423 SETTY(cl, BITS32);
424− cl->info.bits32 = a->info.bits32 ^ b->info.bits32;
424+ cl->info.bits32 = GETBITS32(a) ^ GETBITS32(b);
425425 return cl;
426426}
427427
428428VAL idris_b32Shl(VM *vm, VAL a, VAL b) {
429429 VAL cl = allocate(vm, sizeof(Closure), 0);
430430 SETTY(cl, BITS32);
431− cl->info.bits32 = a->info.bits32 << b->info.bits32;
431+ cl->info.bits32 = GETBITS32(a) << GETBITS32(b);
432432 return cl;
433433}
434434
435435VAL idris_b32LShr(VM *vm, VAL a, VAL b) {
436436 VAL cl = allocate(vm, sizeof(Closure), 0);
437437 SETTY(cl, BITS32);
438− cl->info.bits32 = a->info.bits32 >> b->info.bits32;
438+ cl->info.bits32 = GETBITS32(a) >> GETBITS32(b);
439439 return cl;
440440}
441441
442442VAL idris_b32AShr(VM *vm, VAL a, VAL b) {
443443 VAL cl = allocate(vm, sizeof(Closure), 0);
444444 SETTY(cl, BITS32);
445− cl->info.bits32 = (uint32_t) (((int32_t)a->info.bits32) >> ((int32_t)b->info.bits32));
445+ cl->info.bits32 = (uint32_t) (((int32_t)GETBITS32(a)) >> ((int32_t)GETBITS32(b)));
446446 return cl;
447447}
448448
449449VAL idris_b64Plus(VM *vm, VAL a, VAL b) {
450450 VAL cl = allocate(vm, sizeof(Closure), 0);
451451 SETTY(cl, BITS64);
452− cl->info.bits64 = a->info.bits64 + b->info.bits64;
452+ cl->info.bits64 = GETBITS64(a) + GETBITS64(b);
453453 return cl;
454454}
455455
456456VAL idris_b64Minus(VM *vm, VAL a, VAL b) {
457457 VAL cl = allocate(vm, sizeof(Closure), 0);
458458 SETTY(cl, BITS64);
459− cl->info.bits64 = a->info.bits64 - b->info.bits64;
459+ cl->info.bits64 = GETBITS64(a) - GETBITS64(b);
460460 return cl;
461461}
462462
463463VAL idris_b64Times(VM *vm, VAL a, VAL b) {
464464 VAL cl = allocate(vm, sizeof(Closure), 0);
465465 SETTY(cl, BITS64);
466− cl->info.bits64 = a->info.bits64 * b->info.bits64;
466+ cl->info.bits64 = GETBITS64(a) * GETBITS64(b);
467467 return cl;
468468}
469469
470470VAL idris_b64UDiv(VM *vm, VAL a, VAL b) {
471471 VAL cl = allocate(vm, sizeof(Closure), 0);
472472 SETTY(cl, BITS64);
473− cl->info.bits64 = a->info.bits64 / b->info.bits64;
473+ cl->info.bits64 = GETBITS64(a) / GETBITS64(b);
474474 return cl;
475475}
476476
@@ -478,14 +478,14 @@ VAL idris_b64SDiv(VM *vm, VAL a, VAL b) {
478478 VAL cl = allocate(vm, sizeof(Closure), 0);
479479 SETTY(cl, BITS64);
480480 cl->info.bits64 =
481− (uint64_t) (((int64_t) a->info.bits64) / ((int64_t) b->info.bits64));
481+ (uint64_t) (((int64_t) GETBITS64(a)) / ((int64_t) GETBITS64(b)));
482482 return cl;
483483}
484484
485485VAL idris_b64URem(VM *vm, VAL a, VAL b) {
486486 VAL cl = allocate(vm, sizeof(Closure), 0);
487487 SETTY(cl, BITS64);
488− cl->info.bits64 = a->info.bits64 % b->info.bits64;
488+ cl->info.bits64 = GETBITS64(a) % GETBITS64(b);
489489 return cl;
490490}
491491
@@ -493,7 +493,7 @@ VAL idris_b64SRem(VM *vm, VAL a, VAL b) {
493493 VAL cl = allocate(vm, sizeof(Closure), 0);
494494 SETTY(cl, BITS64);
495495 cl->info.bits64 =
496− (uint64_t) (((int64_t) a->info.bits64) % ((int64_t) b->info.bits64));
496+ (uint64_t) (((int64_t) GETBITS64(a)) % ((int64_t) GETBITS64(b)));
497497 return cl;
498498}
499499
@@ -520,175 +520,175 @@ VAL idris_b64Gte(VM *vm, VAL a, VAL b) {
520520VAL idris_b64Compl(VM *vm, VAL a) {
521521 VAL cl = allocate(vm, sizeof(Closure), 0);
522522 SETTY(cl, BITS64);
523− cl->info.bits64 = ~ a->info.bits64;
523+ cl->info.bits64 = ~ GETBITS64(a);
524524 return cl;
525525}
526526
527527VAL idris_b64And(VM *vm, VAL a, VAL b) {
528528 VAL cl = allocate(vm, sizeof(Closure), 0);
529529 SETTY(cl, BITS64);
530− cl->info.bits64 = a->info.bits64 & b->info.bits64;
530+ cl->info.bits64 = GETBITS64(a) & GETBITS64(b);
531531 return cl;
532532}
533533
534534VAL idris_b64Or(VM *vm, VAL a, VAL b) {
535535 VAL cl = allocate(vm, sizeof(Closure), 0);
536536 SETTY(cl, BITS64);
537− cl->info.bits64 = a->info.bits64 | b->info.bits64;
537+ cl->info.bits64 = GETBITS64(a) | GETBITS64(b);
538538 return cl;
539539}
540540
541541VAL idris_b64Xor(VM *vm, VAL a, VAL b) {
542542 VAL cl = allocate(vm, sizeof(Closure), 0);
543543 SETTY(cl, BITS64);
544− cl->info.bits64 = a->info.bits64 ^ b->info.bits64;
544+ cl->info.bits64 = GETBITS64(a) ^ GETBITS64(b);
545545 return cl;
546546}
547547
548548VAL idris_b64Shl(VM *vm, VAL a, VAL b) {
549549 VAL cl = allocate(vm, sizeof(Closure), 0);
550550 SETTY(cl, BITS64);
551− cl->info.bits64 = a->info.bits64 << b->info.bits64;
551+ cl->info.bits64 = GETBITS64(a) << GETBITS64(b);
552552 return cl;
553553}
554554
555555VAL idris_b64LShr(VM *vm, VAL a, VAL b) {
556556 VAL cl = allocate(vm, sizeof(Closure), 0);
557557 SETTY(cl, BITS64);
558− cl->info.bits64 = a->info.bits64 >> b->info.bits64;
558+ cl->info.bits64 = GETBITS64(a) >> GETBITS64(b);
559559 return cl;
560560}
561561
562562VAL idris_b64AShr(VM *vm, VAL a, VAL b) {
563563 VAL cl = allocate(vm, sizeof(Closure), 0);
564564 SETTY(cl, BITS64);
565− cl->info.bits64 = (uint64_t) (((int64_t)a->info.bits64) >> ((int64_t)b->info.bits64));
565+ cl->info.bits64 = (uint64_t) (((int64_t)GETBITS64(a)) >> ((int64_t)GETBITS64(b)));
566566 return cl;
567567}
568568
569569VAL idris_b8Z16(VM *vm, VAL a) {
570570 VAL cl = allocate(vm, sizeof(Closure), 0);
571571 SETTY(cl, BITS16);
572− cl->info.bits16 = (uint16_t) a->info.bits8;
572+ cl->info.bits16 = (uint16_t) GETBITS8(a);
573573 return cl;
574574}
575575
576576VAL idris_b8Z32(VM *vm, VAL a) {
577577 VAL cl = allocate(vm, sizeof(Closure), 0);
578578 SETTY(cl, BITS32);
579− cl->info.bits32 = (uint32_t) a->info.bits8;
579+ cl->info.bits32 = (uint32_t) GETBITS8(a);
580580 return cl;
581581}
582582
583583VAL idris_b8Z64(VM *vm, VAL a) {
584584 VAL cl = allocate(vm, sizeof(Closure), 0);
585− SETTY(cl, BITS16);
586− cl->info.bits64 = (uint64_t) a->info.bits8;
585+ SETTY(cl, BITS64);
586+ cl->info.bits64 = (uint64_t) GETBITS8(a);
587587 return cl;
588588}
589589
590590VAL idris_b8S16(VM *vm, VAL a) {
591591 VAL cl = allocate(vm, sizeof(Closure), 0);
592592 SETTY(cl, BITS16);
593− cl->info.bits16 = (uint16_t) (int16_t) (int8_t) a->info.bits8;
593+ cl->info.bits16 = (uint16_t) (int16_t) (int8_t) GETBITS8(a);
594594 return cl;
595595}
596596
597597VAL idris_b8S32(VM *vm, VAL a) {
598598 VAL cl = allocate(vm, sizeof(Closure), 0);
599599 SETTY(cl, BITS32);
600− cl->info.bits32 = (uint32_t) (int32_t) (int8_t) a->info.bits8;
600+ cl->info.bits32 = (uint32_t) (int32_t) (int8_t) GETBITS8(a);
601601 return cl;
602602}
603603
604604VAL idris_b8S64(VM *vm, VAL a) {
605605 VAL cl = allocate(vm, sizeof(Closure), 0);
606606 SETTY(cl, BITS64);
607− cl->info.bits64 = (uint64_t) (int64_t) (int8_t) a->info.bits8;
607+ cl->info.bits64 = (uint64_t) (int64_t) (int8_t) GETBITS8(a);
608608 return cl;
609609}
610610
611611VAL idris_b16Z32(VM *vm, VAL a) {
612612 VAL cl = allocate(vm, sizeof(Closure), 0);
613613 SETTY(cl, BITS32);
614− cl->info.bits32 = (uint32_t) a->info.bits16;
614+ cl->info.bits32 = (uint32_t) GETBITS16(a);
615615 return cl;
616616}
617617
618618VAL idris_b16Z64(VM *vm, VAL a) {
619619 VAL cl = allocate(vm, sizeof(Closure), 0);
620620 SETTY(cl, BITS64);
621− cl->info.bits64 = (uint64_t) a->info.bits16;
621+ cl->info.bits64 = (uint64_t) GETBITS16(a);
622622 return cl;
623623}
624624
625625VAL idris_b16S32(VM *vm, VAL a) {
626626 VAL cl = allocate(vm, sizeof(Closure), 0);
627627 SETTY(cl, BITS32);
628− cl->info.bits32 = (uint32_t) (int32_t) (int16_t) a->info.bits16;
628+ cl->info.bits32 = (uint32_t) (int32_t) (int16_t) GETBITS16(a);
629629 return cl;
630630}
631631
632632VAL idris_b16S64(VM *vm, VAL a) {
633633 VAL cl = allocate(vm, sizeof(Closure), 0);
634634 SETTY(cl, BITS64);
635− cl->info.bits64 = (uint64_t) (int64_t) (int16_t) a->info.bits16;
635+ cl->info.bits64 = (uint64_t) (int64_t) (int16_t) GETBITS16(a);
636636 return cl;
637637}
638638
639639VAL idris_b16T8(VM *vm, VAL a) {
640640 VAL cl = allocate(vm, sizeof(Closure), 0);
641641 SETTY(cl, BITS8);
642− cl->info.bits8 = (uint8_t) a->info.bits16;
642+ cl->info.bits8 = (uint8_t) GETBITS16(a);
643643 return cl;
644644}
645645
646646VAL idris_b32Z64(VM *vm, VAL a) {
647647 VAL cl = allocate(vm, sizeof(Closure), 0);
648648 SETTY(cl, BITS64);
649− cl->info.bits64 = (uint64_t) a->info.bits32;
649+ cl->info.bits64 = (uint64_t) GETBITS32(a);
650650 return cl;
651651}
652652
653653VAL idris_b32S64(VM *vm, VAL a) {
654654 VAL cl = allocate(vm, sizeof(Closure), 0);
655655 SETTY(cl, BITS64);
656− cl->info.bits64 = (uint64_t) (int64_t) (int32_t) a->info.bits32;
656+ cl->info.bits64 = (uint64_t) (int64_t) (int32_t) GETBITS32(a);
657657 return cl;
658658}
659659
660660VAL idris_b32T8(VM *vm, VAL a) {
661661 VAL cl = allocate(vm, sizeof(Closure), 0);
662662 SETTY(cl, BITS8);
663− cl->info.bits8 = (uint8_t) a->info.bits32;
663+ cl->info.bits8 = (uint8_t) GETBITS32(a);
664664 return cl;
665665}
666666
667667VAL idris_b32T16(VM *vm, VAL a) {
668668 VAL cl = allocate(vm, sizeof(Closure), 0);
669669 SETTY(cl, BITS16);
670− cl->info.bits16 = (uint16_t) a->info.bits32;
670+ cl->info.bits16 = (uint16_t) GETBITS32(a);
671671 return cl;
672672}
673673
674674VAL idris_b64T8(VM *vm, VAL a) {
675675 VAL cl = allocate(vm, sizeof(Closure), 0);
676676 SETTY(cl, BITS8);
677− cl->info.bits8 = (uint8_t) a->info.bits64;
677+ cl->info.bits8 = (uint8_t) GETBITS64(a);
678678 return cl;
679679}
680680
681681VAL idris_b64T16(VM *vm, VAL a) {
682682 VAL cl = allocate(vm, sizeof(Closure), 0);
683683 SETTY(cl, BITS16);
684− cl->info.bits16 = (uint16_t) a->info.bits64;
684+ cl->info.bits16 = (uint16_t) GETBITS64(a);
685685 return cl;
686686}
687687
688688VAL idris_b64T32(VM *vm, VAL a) {
689689 VAL cl = allocate(vm, sizeof(Closure), 0);
690690 SETTY(cl, BITS32);
691− cl->info.bits32 = (uint32_t) a->info.bits64;
691+ cl->info.bits32 = (uint32_t) GETBITS64(a);
692692 return cl;
693693}
694694
rts/idris_rts.h+5
@@ -129,6 +129,11 @@ typedef void(*func)(VM*, VAL*);
129129#define GETMPTR(x) (((VAL)(x))->info.mptr->data)
130130#define GETFLOAT(x) (((VAL)(x))->info.f)
131131
132+#define GETBITS64(x) ((x)->ty == FWD ? ((VAL)((x)->info.ptr))->info.bits64 : (x)->info.bits64)
133+#define GETBITS32(x) ((x)->ty == FWD ? ((VAL)((x)->info.ptr))->info.bits32 : (x)->info.bits32)
134+#define GETBITS16(x) ((x)->ty == FWD ? ((VAL)((x)->info.ptr))->info.bits16 : (x)->info.bits16)
135+#define GETBITS8(x) ((x)->ty == FWD ? ((VAL)((x)->info.ptr))->info.bits8 : (x)->info.bits8)
136+
132137#define TAG(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CON ? (x)->info.c.tag_arity >> 8 : (-1)) )
133138#define ARITY(x) (ISINT(x) || x == NULL ? (-1) : ( GETTY(x) == CON ? (x)->info.c.tag_arity & 0x000000ff : (-1)) )
134139