GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/array_extensions.c
Date: 2025-08-08 18:10:24
Exec Total Coverage
Lines: 404 418 96.7%
Functions: 28 28 100.0%
Branches: 134 189 70.9%

Line Branch Exec Source
1 /*
2 Copyright 2022 - 2025 Joel Svensson svenssonjoel@yahoo.se
3 Copyright 2022, 2023 Benjamin Vedder
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "extensions/array_extensions.h"
20
21 #include "extensions.h"
22 #include "symrepr.h"
23 #include "lbm_memory.h"
24
25 #include <math.h>
26
27 #ifdef LBM_OPT_ARRAY_EXTENSIONS_SIZE
28 #pragma GCC optimize ("-Os")
29 #endif
30 #ifdef LBM_OPT_ARRAY_EXTENSIONS_SIZE_AGGRESSIVE
31 #pragma GCC optimize ("-Oz")
32 #endif
33
34 static lbm_uint little_endian = 0;
35 static lbm_uint big_endian = 0;
36
37 static lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn);
38 static lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn);
39 static lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn);
40 static lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn);
41 static lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn);
42 static lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn);
43 static lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn);
44 static lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn);
45 static lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn);
46
47 static lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn);
48 static lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn);
49 static lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn);
50 static lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn);
51 static lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn);
52 static lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn);
53 static lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn);
54 static lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn);
55
56 static lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn);
57
58 static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn);
59 static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn);
60 static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn);
61
62 44260 void lbm_array_extensions_init(void) {
63
64 44260 lbm_add_symbol_const("little-endian", &little_endian);
65 44260 lbm_add_symbol_const("big-endian", &big_endian);
66
67 44260 lbm_add_extension("free", array_extension_unsafe_free_array);
68 44260 lbm_add_extension("bufset-i8", array_extension_buffer_append_i8);
69 44260 lbm_add_extension("bufset-i16", array_extension_buffer_append_i16);
70 44260 lbm_add_extension("bufset-i32", array_extension_buffer_append_i32);
71 44260 lbm_add_extension("bufset-u8", array_extension_buffer_append_u8);
72 44260 lbm_add_extension("bufset-u16", array_extension_buffer_append_u16);
73 44260 lbm_add_extension("bufset-u24", array_extension_buffer_append_u24);
74 44260 lbm_add_extension("bufset-u32", array_extension_buffer_append_u32);
75 44260 lbm_add_extension("bufset-f32", array_extension_buffer_append_f32);
76
77 44260 lbm_add_extension("bufget-i8", array_extension_buffer_get_i8);
78 44260 lbm_add_extension("bufget-i16", array_extension_buffer_get_i16);
79 44260 lbm_add_extension("bufget-i32", array_extension_buffer_get_i32);
80 44260 lbm_add_extension("bufget-u8", array_extension_buffer_get_u8);
81 44260 lbm_add_extension("bufget-u16", array_extension_buffer_get_u16);
82 44260 lbm_add_extension("bufget-u24", array_extension_buffer_get_u24);
83 44260 lbm_add_extension("bufget-u32", array_extension_buffer_get_u32);
84 44260 lbm_add_extension("bufget-f32", array_extension_buffer_get_f32);
85
86 44260 lbm_add_extension("buflen", array_extension_buffer_length);
87 44260 lbm_add_extension("bufclear", array_extensions_bufclear);
88 44260 lbm_add_extension("bufcpy", array_extensions_bufcpy);
89 44260 lbm_add_extension("bufset-bit", array_extensions_bufset_bit);
90 44260 }
91
92 224 lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn) {
93 224 lbm_value res = ENC_SYM_EERROR;
94
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (argn == 1) {
95
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (lbm_is_array_rw(args[0])) {
96
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (lbm_heap_explicit_free_array(args[0])) {
97 224 res = ENC_SYM_TRUE;
98 } else {
99 res = ENC_SYM_NIL;
100 }
101 } else {
102 res = ENC_SYM_TERROR;
103 }
104 }
105 224 return res;
106 }
107
108 119059 static bool decode_append_args(lbm_value *error, lbm_value *args, lbm_uint argn, lbm_uint *index, bool *be, lbm_uint *a_size, uint8_t **a_data) {
109 119059 *be = true;
110 119059 *error = ENC_SYM_EERROR;
111 119059 bool res = false;
112
2/3
✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 117099 times.
✗ Branch 2 not taken.
119059 switch(argn) {
113 1960 case 4:
114
1/2
✓ Branch 0 taken 1960 times.
✗ Branch 1 not taken.
1960 if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL &&
115
1/2
✓ Branch 0 taken 1960 times.
✗ Branch 1 not taken.
1960 lbm_dec_sym(args[3]) == little_endian) {
116 1960 *be = false;
117 }
118 /* fall through */
119 case 3: {
120 119059 lbm_array_header_t *array = lbm_dec_array_rw(args[0]);
121
3/4
✓ Branch 0 taken 118891 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 118891 times.
✗ Branch 3 not taken.
237950 if(array &&
122
1/2
✓ Branch 0 taken 118891 times.
✗ Branch 1 not taken.
237782 lbm_is_number(args[1]) &&
123 118891 lbm_is_number(args[2])) {
124 118891 *a_size = array->size;
125 118891 *a_data = (uint8_t*)array->data;
126 118891 *index = lbm_dec_as_u32(args[1]);
127 118891 res = true;
128 } else {
129 168 *error = ENC_SYM_TERROR;
130 }
131 }
132 }
133 119059 return res;
134 }
135
136 118891 static bool buffer_append_bytes(uint8_t *data, lbm_uint d_size, bool be, lbm_uint index, lbm_uint nbytes, lbm_uint value) {
137
138 118891 lbm_uint last_index = index + (nbytes - 1);
139 118891 bool res = false;
140
2/2
✓ Branch 0 taken 118443 times.
✓ Branch 1 taken 448 times.
118891 if (last_index < d_size) {
141 118443 res = true;
142
4/4
✓ Branch 0 taken 114577 times.
✓ Branch 1 taken 1289 times.
✓ Branch 2 taken 560 times.
✓ Branch 3 taken 2017 times.
118443 switch(nbytes) {
143 114577 case 1:
144 114577 data[index] = (uint8_t) value;
145 114577 break;
146 1289 case 2:
147
2/2
✓ Branch 0 taken 729 times.
✓ Branch 1 taken 560 times.
1289 if (be) {
148 729 data[index+1] = (uint8_t)value;
149 729 data[index] = (uint8_t)(value >> 8);
150 } else {
151 560 data[index] = (uint8_t)value;
152 560 data[index +1] = (uint8_t)(value >> 8);
153 }
154 1289 break;
155 560 case 3:
156
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 280 times.
560 if (be) {
157 280 data[index+2] = (uint8_t)value;
158 280 data[index+1] = (uint8_t)(value >> 8);
159 280 data[index] = (uint8_t)(value >> 16);
160 } else {
161 280 data[index] = (uint8_t)value;
162 280 data[index+1] = (uint8_t)(value >> 8);
163 280 data[index+2] = (uint8_t)(value >> 16);
164 }
165 560 break;
166 2017 default:
167
2/2
✓ Branch 0 taken 1457 times.
✓ Branch 1 taken 560 times.
2017 if (be) {
168 1457 data[index+3] = (uint8_t) value;
169 1457 data[index+2] = (uint8_t) (value >> 8);
170 1457 data[index+1] = (uint8_t) (value >> 16);
171 1457 data[index] = (uint8_t) (value >> 24);
172 } else {
173 560 data[index] = (uint8_t) value;
174 560 data[index+1] = (uint8_t) (value >> 8);
175 560 data[index+2] = (uint8_t) (value >> 16);
176 560 data[index+3] = (uint8_t) (value >> 24);
177 }
178 2017 break;
179 }
180 }
181 118891 return res;
182 }
183
184 113512 lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn) {
185
186 113512 lbm_value res = ENC_SYM_EERROR;
187 113512 uint8_t *data = NULL;
188 113512 lbm_uint d_size = 0;
189 113512 bool be = false;
190 113512 lbm_uint index = 0;
191
192
2/2
✓ Branch 0 taken 113344 times.
✓ Branch 1 taken 168 times.
113512 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
193
2/2
✓ Branch 0 taken 113288 times.
✓ Branch 1 taken 56 times.
113344 if (buffer_append_bytes(data, d_size, be, index, 1, (lbm_uint)lbm_dec_as_i32(args[2]))) {
194 113288 res = ENC_SYM_TRUE;
195 }
196 }
197 113512 return res;
198 }
199
200 1176 lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn) {
201
202 1176 lbm_value res = ENC_SYM_EERROR;
203 1176 uint8_t *data = NULL;
204 1176 lbm_uint d_size = 0;
205 1176 bool be = false;
206 1176 lbm_uint index = 0;
207
208
1/2
✓ Branch 0 taken 1176 times.
✗ Branch 1 not taken.
1176 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
209
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 56 times.
1176 if (buffer_append_bytes(data, d_size, be, index, 2, (lbm_uint)lbm_dec_as_i32(args[2]))) {
210 1120 res = ENC_SYM_TRUE;
211 }
212 }
213 1176 return res;
214 }
215
216 896 lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn) {
217
218 896 lbm_value res = ENC_SYM_EERROR;
219 896 uint8_t *data = NULL;
220 896 lbm_uint d_size = 0;
221 896 bool be = false;
222 896 lbm_uint index = 0;
223
224
1/2
✓ Branch 0 taken 896 times.
✗ Branch 1 not taken.
896 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
225
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 56 times.
896 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)lbm_dec_as_i32(args[2]))) {
226 840 res = ENC_SYM_TRUE;
227 }
228 }
229 896 return res;
230 }
231
232
233 1345 lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn) {
234
235 1345 lbm_value res = ENC_SYM_EERROR;
236 1345 uint8_t *data = NULL;
237 1345 lbm_uint d_size = 0;
238 1345 bool be = false;
239 1345 lbm_uint index = 0;
240
241
1/2
✓ Branch 0 taken 1345 times.
✗ Branch 1 not taken.
1345 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
242
2/2
✓ Branch 0 taken 1289 times.
✓ Branch 1 taken 56 times.
1345 if (buffer_append_bytes(data, d_size, be, index, 1, (lbm_uint)lbm_dec_as_u32(args[2]))) {
243 1289 res = ENC_SYM_TRUE;
244 }
245 }
246 1345 return res;
247 }
248
249 225 lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn) {
250
251 225 lbm_value res = ENC_SYM_EERROR;
252 225 uint8_t *data = NULL;
253 225 lbm_uint d_size = 0;
254 225 bool be = false;
255 225 lbm_uint index = 0;
256
257
1/2
✓ Branch 0 taken 225 times.
✗ Branch 1 not taken.
225 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
258
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 56 times.
225 if (buffer_append_bytes(data, d_size, be, index, 2, (lbm_uint)lbm_dec_as_u32(args[2]))) {
259 169 res = ENC_SYM_TRUE;
260 }
261 }
262 225 return res;
263 }
264
265 616 lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn) {
266
267 616 lbm_value res = ENC_SYM_EERROR;
268 616 uint8_t *data = NULL;
269 616 lbm_uint d_size = 0;
270 616 bool be = false;
271 616 lbm_uint index = 0;
272
273
1/2
✓ Branch 0 taken 616 times.
✗ Branch 1 not taken.
616 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
274
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 56 times.
616 if (buffer_append_bytes(data, d_size, be, index, 3, (lbm_uint)lbm_dec_as_u32(args[2]))) {
275 560 res = ENC_SYM_TRUE;
276 }
277 }
278 616 return res;
279 }
280
281 897 lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn) {
282
283 897 lbm_value res = ENC_SYM_EERROR;
284 897 uint8_t *data = NULL;
285 897 lbm_uint d_size = 0;
286 897 bool be = false;
287 897 lbm_uint index = 0;
288
289
1/2
✓ Branch 0 taken 897 times.
✗ Branch 1 not taken.
897 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
290
2/2
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 56 times.
897 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)lbm_dec_as_u32(args[2]))) {
291 841 res = ENC_SYM_TRUE;
292 }
293 }
294 897 return res;
295 }
296
297 392 static lbm_uint float_to_u(float number) {
298 // Set subnormal numbers to 0 as they are not handled properly
299 // using this method.
300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
392 if (fabsf(number) < 1.5e-38) {
301 number = 0.0;
302 }
303
304 392 int e = 0;
305 392 float sig = frexpf(number, &e);
306 392 float sig_abs = fabsf(sig);
307 392 uint32_t sig_i = 0;
308
309
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (sig_abs >= 0.5) {
310 392 sig_i = (uint32_t)((sig_abs - 0.5f) * 2.0f * 8388608.0f);
311 392 e += 126;
312 }
313
314 392 uint32_t res = (((uint32_t)e & 0xFFu) << 23) | (uint32_t)(sig_i & 0x7FFFFFu);
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
392 if (sig < 0) {
316 res |= 1U << 31;
317 }
318
319 392 return res;
320 }
321
322 336 static lbm_float u_to_float(uint32_t v) {
323
324 336 int e = (v >> 23) & 0xFF;
325 336 uint32_t sig_i = v & 0x7FFFFF;
326 336 bool neg = v & (1U << 31);
327
328 336 float sig = 0.0;
329
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
336 if (e != 0 || sig_i != 0) {
330 336 sig = (float)sig_i / (8388608.0f * 2.0f) + 0.5f;
331 336 e -= 126;
332 }
333
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
336 if (neg) {
335 sig = -sig;
336 }
337
338 336 return ldexpf(sig, e);
339 }
340
341 392 lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn) {
342
343 392 lbm_value res = ENC_SYM_EERROR;
344 392 uint8_t *data = NULL;
345 392 lbm_uint d_size = 0;
346 392 bool be = false;
347 392 lbm_uint index = 0;
348
349
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
350
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 56 times.
392 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)float_to_u(lbm_dec_as_float(args[2])))) {
351 336 res = ENC_SYM_TRUE;
352 }
353 }
354 392 return res;
355 }
356
357 /* (buffer-get-i8 buffer index) */
358 /* (buffer-get-i16 buffer index little-endian) */
359
360 9925 static bool decode_get_args(lbm_value *error, lbm_value *args, lbm_uint argn, lbm_uint *index, bool *be, lbm_uint *a_size, uint8_t **a_data) {
361 9925 bool res = false;
362
363 9925 *be=true;
364
365
2/3
✓ Branch 0 taken 2352 times.
✓ Branch 1 taken 7573 times.
✗ Branch 2 not taken.
9925 switch(argn) {
366 2352 case 3:
367
1/2
✓ Branch 0 taken 2352 times.
✗ Branch 1 not taken.
2352 if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL &&
368
1/2
✓ Branch 0 taken 2352 times.
✗ Branch 1 not taken.
2352 lbm_dec_sym(args[2]) == little_endian) {
369 2352 *be = false;
370 }
371 /* fall through */
372 case 2: {
373 9925 lbm_array_header_t *array = lbm_dec_array_r(args[0]);
374
2/4
✓ Branch 0 taken 9925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9925 times.
✗ Branch 3 not taken.
19850 if (array &&
375 9925 lbm_is_number(args[1])) {
376 9925 *a_size = array->size;
377 9925 *a_data = (uint8_t*)array->data;
378 9925 *index = lbm_dec_as_u32(args[1]);
379 9925 res = true;
380 } else {
381 *error = ENC_SYM_TERROR;
382 }
383 }
384 }
385 9925 return res;
386 }
387
388 9925 static bool buffer_get_uint(lbm_uint *r_value, uint8_t *data, lbm_uint d_size, bool be, lbm_uint index, lbm_uint nbytes) {
389
390 9925 bool res = false;
391 9925 lbm_uint last_index = index + (nbytes - 1);
392
393
2/2
✓ Branch 0 taken 8693 times.
✓ Branch 1 taken 1232 times.
9925 if (last_index < d_size) {
394 8693 lbm_uint value = 0;
395 8693 res = true;
396
4/5
✓ Branch 0 taken 4659 times.
✓ Branch 1 taken 1289 times.
✓ Branch 2 taken 560 times.
✓ Branch 3 taken 2185 times.
✗ Branch 4 not taken.
8693 switch(nbytes) {
397 4659 case 1:
398 4659 value = (lbm_uint)data[index];
399 4659 break;
400 1289 case 2:
401
2/2
✓ Branch 0 taken 729 times.
✓ Branch 1 taken 560 times.
1289 if (be) {
402 729 value =
403 729 (lbm_uint) data[index+1] |
404 729 (lbm_uint) data[index] << 8;
405 } else {
406 560 value =
407 560 (lbm_uint) data[index] |
408 560 (lbm_uint) data[index+1] << 8;
409 }
410 1289 break;
411 560 case 3:
412
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 280 times.
560 if (be) {
413 280 value =
414 280 (lbm_uint) data[index+2] |
415 280 (lbm_uint) data[index+1] << 8 |
416 280 (lbm_uint) data[index] << 16;
417 } else {
418 280 value =
419 280 (lbm_uint) data[index] |
420 280 (lbm_uint) data[index+1] << 8 |
421 280 (lbm_uint) data[index+2] << 16;
422 }
423 560 break;
424 2185 case 4:
425
2/2
✓ Branch 0 taken 1625 times.
✓ Branch 1 taken 560 times.
2185 if (be) {
426 1625 value =
427 1625 (uint32_t) data[index+3] |
428 1625 (uint32_t) data[index+2] << 8 |
429 1625 (uint32_t) data[index+1] << 16 |
430 1625 (uint32_t) data[index] << 24;
431 } else {
432 560 value =
433 560 (uint32_t) data[index] |
434 560 (uint32_t) data[index+1] << 8 |
435 560 (uint32_t) data[index+2] << 16 |
436 560 (uint32_t) data[index+3] << 24;
437 }
438 2185 break;
439 default:
440 res = false;
441 }
442 8693 *r_value = value;
443 }
444 9925 return res;
445 }
446
447
448
449 2800 lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn) {
450 2800 lbm_value res = ENC_SYM_EERROR;
451 2800 uint8_t *data = NULL;
452 2800 lbm_uint d_size = 0;
453 2800 bool be = false;
454 2800 lbm_uint index = 0;
455 2800 lbm_uint value = 0;
456
457
1/2
✓ Branch 0 taken 2800 times.
✗ Branch 1 not taken.
2800 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
458
2/2
✓ Branch 0 taken 2632 times.
✓ Branch 1 taken 168 times.
2800 if (buffer_get_uint(&value, data, d_size, be, index, 1)) {
459 2632 res =lbm_enc_i((int8_t)value);
460 }
461 }
462 2800 return res;
463 }
464
465 1400 lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn) {
466 1400 lbm_value res = ENC_SYM_EERROR;
467 1400 uint8_t *data = NULL;
468 1400 lbm_uint d_size = 0;
469 1400 bool be = false;
470 1400 lbm_uint index = 0;
471 1400 lbm_uint value = 0;
472
473
1/2
✓ Branch 0 taken 1400 times.
✗ Branch 1 not taken.
1400 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
474
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 280 times.
1400 if (buffer_get_uint(&value, data, d_size, be, index, 2)) {
475 1120 res =lbm_enc_i((int16_t)value);
476 }
477 }
478 1400 return res;
479 }
480
481 1008 lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn) {
482 1008 lbm_value res = ENC_SYM_EERROR;
483 1008 uint8_t *data = NULL;
484 1008 lbm_uint d_size = 0;
485 1008 bool be = false;
486 1008 lbm_uint index = 0;
487 1008 lbm_uint value = 0;
488
489
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
490
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 168 times.
1008 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
491 840 res =lbm_enc_i((int32_t)value);
492 }
493 }
494 1008 return res;
495 }
496
497 2195 lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn) {
498 2195 lbm_value res = ENC_SYM_EERROR;
499 2195 uint8_t *data = NULL;
500 2195 lbm_uint d_size = 0;
501 2195 bool be = false;
502 2195 lbm_uint index = 0;
503 2195 lbm_uint value = 0;
504
505
1/2
✓ Branch 0 taken 2195 times.
✗ Branch 1 not taken.
2195 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
506
2/2
✓ Branch 0 taken 2027 times.
✓ Branch 1 taken 168 times.
2195 if (buffer_get_uint(&value, data, d_size, be, index, 1)) {
507 2027 res = lbm_enc_i((uint8_t)value);
508 }
509 }
510 2195 return res;
511 }
512
513 225 lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn) {
514 225 lbm_value res = ENC_SYM_EERROR;
515 225 uint8_t *data = NULL;
516 225 lbm_uint d_size = 0;
517 225 bool be = false;
518 225 lbm_uint index = 0;
519 225 lbm_uint value = 0;
520
521
1/2
✓ Branch 0 taken 225 times.
✗ Branch 1 not taken.
225 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
522
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 56 times.
225 if (buffer_get_uint(&value, data, d_size, be, index, 2)) {
523 169 res = lbm_enc_i((uint16_t)value);
524 }
525 }
526 225 return res;
527 }
528
529 728 lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn) {
530 728 lbm_value res = ENC_SYM_EERROR;
531 728 uint8_t *data = NULL;
532 728 lbm_uint d_size = 0;
533 728 bool be = false;
534 728 lbm_uint index = 0;
535 728 lbm_uint value = 0;
536
537
1/2
✓ Branch 0 taken 728 times.
✗ Branch 1 not taken.
728 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
538
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 168 times.
728 if (buffer_get_uint(&value, data, d_size, be, index, 3)) {
539 560 res = lbm_enc_i((int32_t)value);
540 }
541 }
542 728 return res;
543 }
544
545 1177 lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn) {
546 1177 lbm_value res = ENC_SYM_EERROR;
547 1177 uint8_t *data = NULL;
548 1177 lbm_uint d_size = 0;
549 1177 bool be = false;
550 1177 lbm_uint index = 0;
551 1177 lbm_uint value = 0;
552
553
1/2
✓ Branch 0 taken 1177 times.
✗ Branch 1 not taken.
1177 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
554
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 168 times.
1177 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
555 1009 res = lbm_enc_u32((uint32_t)value);
556 }
557 }
558 1177 return res;
559 }
560
561 392 lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn) {
562 392 lbm_value res = ENC_SYM_EERROR;
563 392 uint8_t *data = NULL;
564 392 lbm_uint d_size = 0;
565 392 bool be = false;
566 392 lbm_uint index = 0;
567 392 lbm_uint value = 0;
568
569
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
570
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 56 times.
392 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
571 336 res = lbm_enc_float(u_to_float((uint32_t)value));
572 }
573 }
574 392 return res;
575 }
576
577 504 lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn) {
578 504 lbm_value res = ENC_SYM_EERROR;
579 lbm_array_header_t *array;
580
2/4
✓ Branch 0 taken 504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 504 times.
✗ Branch 3 not taken.
1008 if (argn == 1 &&
581
1/2
✓ Branch 0 taken 504 times.
✗ Branch 1 not taken.
1008 (array = lbm_dec_array_r(args[0])) &&
582 504 lbm_heap_array_valid(args[0])) {
583 504 res = lbm_enc_i((lbm_int)array->size);
584 }
585 504 return res;
586 }
587
588 //TODO: Have to think about 32 vs 64 bit here
589 1121 static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn) {
590 1121 lbm_value res = ENC_SYM_EERROR;
591
4/4
✓ Branch 0 taken 1065 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 1009 times.
✓ Branch 3 taken 56 times.
1121 if (argn >= 1 && argn <= 4) {
592 1009 res = ENC_SYM_TERROR;
593
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 1 times.
1009 if (lbm_is_array_rw(args[0])) {
594 1008 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
595
596 1008 uint8_t clear_byte = 0;
597
2/2
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 168 times.
1008 if (argn >= 2) {
598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 840 times.
840 if (!lbm_is_number(args[1])) {
599 return res;
600 }
601 840 clear_byte = (uint8_t)lbm_dec_as_u32(args[1]);
602 }
603
604 1008 uint32_t start = 0;
605
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 896 times.
1008 if (argn >= 3) {
606
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (!lbm_is_number(args[2])) {
607 return res;
608 }
609 112 uint32_t start_new = lbm_dec_as_u32(args[2]);
610
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (start_new < array->size) {
611 112 start = start_new;
612 } else {
613 return res;
614 }
615 }
616 // Truncates size on 64 bit build
617 1008 uint32_t len = (uint32_t)array->size - start;
618
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 952 times.
1008 if (argn >= 4) {
619
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (!lbm_is_number(args[3])) {
620 return res;
621 }
622 56 uint32_t len_new = lbm_dec_as_u32(args[3]);
623
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (len_new <= len) {
624 56 len = len_new;
625 }
626 }
627
628 1008 memset((char*)array->data + start, clear_byte, len);
629 1008 res = ENC_SYM_TRUE;
630 }
631 }
632 1121 return res;
633 }
634
635 280 static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn) {
636 280 lbm_value res = ENC_SYM_EERROR;
637
638
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 56 times.
280 if (argn == 5) {
639 224 res = ENC_SYM_TERROR;
640
4/6
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 112 times.
✗ Branch 5 not taken.
336 if (lbm_is_array_rw(args[0]) && lbm_is_number(args[1]) &&
641
2/4
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
224 lbm_is_array_r(args[2]) && lbm_is_number(args[3]) &&lbm_is_number(args[4])) {
642 112 lbm_array_header_t *array1 = (lbm_array_header_t *)lbm_car(args[0]);
643
644 112 uint32_t start1 = lbm_dec_as_u32(args[1]);
645
646 112 lbm_array_header_t *array2 = (lbm_array_header_t *)lbm_car(args[2]);
647
648 112 uint32_t start2 = lbm_dec_as_u32(args[3]);
649 112 uint32_t len = lbm_dec_as_u32(args[4]);
650
651
2/4
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 if (start1 < array1->size && start2 < array2->size) {
652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (len > (array1->size - start1)) {
653 len = ((uint32_t)array1->size - start1);
654 }
655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (len > (array2->size - start2)) {
656 len = ((uint32_t)array2->size - start2);
657 }
658
659 112 memcpy((char*)array1->data + start1, (char*)array2->data + start2, len);
660 }
661 112 res = ENC_SYM_TRUE;
662 }
663 }
664 280 return res;
665 }
666
667 336 static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn) {
668 336 lbm_value res = ENC_SYM_EERROR;
669
670
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 168 times.
336 if (argn == 3) {
671 168 res = ENC_SYM_TERROR;
672
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
280 if (lbm_is_array_rw(args[0]) &&
673
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
224 lbm_is_number(args[1]) && lbm_is_number(args[2])) {
674 112 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
675
676 112 unsigned int pos = lbm_dec_as_u32(args[1]);
677 112 unsigned int bit = lbm_dec_as_u32(args[2]) ? 1 : 0;
678
679 112 unsigned int bytepos = pos / 8;
680
681
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (bytepos < array->size) {
682 112 unsigned int bitpos = pos % 8;
683 112 ((uint8_t*)array->data)[bytepos] &= (uint8_t)~(1 << bitpos);
684 112 ((uint8_t*)array->data)[bytepos] |= (uint8_t)(bit << bitpos);
685 }
686
687 112 res = ENC_SYM_TRUE;
688 }
689 }
690 336 return res;
691 }
692