GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/array_extensions.c
Date: 2025-10-27 19:12:55
Exec Total Coverage
Lines: 410 418 98.1%
Functions: 28 28 100.0%
Branches: 165 189 87.3%

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 22317 void lbm_array_extensions_init(void) {
63
64 22317 lbm_add_symbol_const("little-endian", &little_endian);
65 22317 lbm_add_symbol_const("big-endian", &big_endian);
66
67 22317 lbm_add_extension("free", array_extension_unsafe_free_array);
68 22317 lbm_add_extension("bufset-i8", array_extension_buffer_append_i8);
69 22317 lbm_add_extension("bufset-i16", array_extension_buffer_append_i16);
70 22317 lbm_add_extension("bufset-i32", array_extension_buffer_append_i32);
71 22317 lbm_add_extension("bufset-u8", array_extension_buffer_append_u8);
72 22317 lbm_add_extension("bufset-u16", array_extension_buffer_append_u16);
73 22317 lbm_add_extension("bufset-u24", array_extension_buffer_append_u24);
74 22317 lbm_add_extension("bufset-u32", array_extension_buffer_append_u32);
75 22317 lbm_add_extension("bufset-f32", array_extension_buffer_append_f32);
76
77 22317 lbm_add_extension("bufget-i8", array_extension_buffer_get_i8);
78 22317 lbm_add_extension("bufget-i16", array_extension_buffer_get_i16);
79 22317 lbm_add_extension("bufget-i32", array_extension_buffer_get_i32);
80 22317 lbm_add_extension("bufget-u8", array_extension_buffer_get_u8);
81 22317 lbm_add_extension("bufget-u16", array_extension_buffer_get_u16);
82 22317 lbm_add_extension("bufget-u24", array_extension_buffer_get_u24);
83 22317 lbm_add_extension("bufget-u32", array_extension_buffer_get_u32);
84 22317 lbm_add_extension("bufget-f32", array_extension_buffer_get_f32);
85
86 22317 lbm_add_extension("buflen", array_extension_buffer_length);
87 22317 lbm_add_extension("bufclear", array_extensions_bufclear);
88 22317 lbm_add_extension("bufcpy", array_extensions_bufcpy);
89 22317 lbm_add_extension("bufset-bit", array_extensions_bufset_bit);
90 22317 }
91
92 116 lbm_value array_extension_unsafe_free_array(lbm_value *args, lbm_uint argn) {
93 116 lbm_value res = ENC_SYM_EERROR;
94
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 2 times.
116 if (argn == 1) {
95
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 2 times.
114 if (lbm_is_array_rw(args[0])) {
96
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (lbm_heap_explicit_free_array(args[0])) {
97 112 res = ENC_SYM_TRUE;
98 } else {
99 res = ENC_SYM_NIL;
100 }
101 } else {
102 2 res = ENC_SYM_TERROR;
103 }
104 }
105 116 return res;
106 }
107
108 59594 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 59594 *be = true;
110 59594 *error = ENC_SYM_EERROR;
111 59594 bool res = false;
112
3/3
✓ Branch 0 taken 987 times.
✓ Branch 1 taken 58604 times.
✓ Branch 2 taken 3 times.
59594 switch(argn) {
113 987 case 4:
114
1/2
✓ Branch 0 taken 987 times.
✗ Branch 1 not taken.
987 if (lbm_type_of(args[3]) == LBM_TYPE_SYMBOL &&
115
1/2
✓ Branch 0 taken 987 times.
✗ Branch 1 not taken.
987 lbm_dec_sym(args[3]) == little_endian) {
116 987 *be = false;
117 }
118 /* fall through */
119 case 3: {
120 59591 lbm_array_header_t *array = lbm_dec_array_rw(args[0]);
121
4/4
✓ Branch 0 taken 59505 times.
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 59502 times.
✓ Branch 3 taken 3 times.
119096 if(array &&
122
2/2
✓ Branch 0 taken 59499 times.
✓ Branch 1 taken 3 times.
119007 lbm_is_number(args[1]) &&
123 59502 lbm_is_number(args[2])) {
124 59499 *a_size = array->size;
125 59499 *a_data = (uint8_t*)array->data;
126 59499 *index = lbm_dec_as_u32(args[1]);
127 59499 res = true;
128 } else {
129 92 *error = ENC_SYM_TERROR;
130 }
131 }
132 }
133 59594 return res;
134 }
135
136 59499 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 59499 lbm_uint last_index = index + (nbytes - 1);
139 59499 bool res = false;
140
2/2
✓ Branch 0 taken 59275 times.
✓ Branch 1 taken 224 times.
59499 if (last_index < d_size) {
141 59275 res = true;
142
4/4
✓ Branch 0 taken 57326 times.
✓ Branch 1 taken 650 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 1017 times.
59275 switch(nbytes) {
143 57326 case 1:
144 57326 data[index] = (uint8_t) value;
145 57326 break;
146 650 case 2:
147
2/2
✓ Branch 0 taken 368 times.
✓ Branch 1 taken 282 times.
650 if (be) {
148 368 data[index+1] = (uint8_t)value;
149 368 data[index] = (uint8_t)(value >> 8);
150 } else {
151 282 data[index] = (uint8_t)value;
152 282 data[index +1] = (uint8_t)(value >> 8);
153 }
154 650 break;
155 282 case 3:
156
2/2
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 141 times.
282 if (be) {
157 141 data[index+2] = (uint8_t)value;
158 141 data[index+1] = (uint8_t)(value >> 8);
159 141 data[index] = (uint8_t)(value >> 16);
160 } else {
161 141 data[index] = (uint8_t)value;
162 141 data[index+1] = (uint8_t)(value >> 8);
163 141 data[index+2] = (uint8_t)(value >> 16);
164 }
165 282 break;
166 1017 default:
167
2/2
✓ Branch 0 taken 733 times.
✓ Branch 1 taken 284 times.
1017 if (be) {
168 733 data[index+3] = (uint8_t) value;
169 733 data[index+2] = (uint8_t) (value >> 8);
170 733 data[index+1] = (uint8_t) (value >> 16);
171 733 data[index] = (uint8_t) (value >> 24);
172 } else {
173 284 data[index] = (uint8_t) value;
174 284 data[index+1] = (uint8_t) (value >> 8);
175 284 data[index+2] = (uint8_t) (value >> 16);
176 284 data[index+3] = (uint8_t) (value >> 24);
177 }
178 1017 break;
179 }
180 }
181 59499 return res;
182 }
183
184 56761 lbm_value array_extension_buffer_append_i8(lbm_value *args, lbm_uint argn) {
185
186 56761 lbm_value res = ENC_SYM_EERROR;
187 56761 uint8_t *data = NULL;
188 56761 lbm_uint d_size = 0;
189 56761 bool be = false;
190 56761 lbm_uint index = 0;
191
192
2/2
✓ Branch 0 taken 56672 times.
✓ Branch 1 taken 89 times.
56761 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
193
2/2
✓ Branch 0 taken 56644 times.
✓ Branch 1 taken 28 times.
56672 if (buffer_append_bytes(data, d_size, be, index, 1, (lbm_uint)lbm_dec_as_i32(args[2]))) {
194 56644 res = ENC_SYM_TRUE;
195 }
196 }
197 56761 return res;
198 }
199
200 591 lbm_value array_extension_buffer_append_i16(lbm_value *args, lbm_uint argn) {
201
202 591 lbm_value res = ENC_SYM_EERROR;
203 591 uint8_t *data = NULL;
204 591 lbm_uint d_size = 0;
205 591 bool be = false;
206 591 lbm_uint index = 0;
207
208
1/2
✓ Branch 0 taken 591 times.
✗ Branch 1 not taken.
591 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
209
2/2
✓ Branch 0 taken 563 times.
✓ Branch 1 taken 28 times.
591 if (buffer_append_bytes(data, d_size, be, index, 2, (lbm_uint)lbm_dec_as_i32(args[2]))) {
210 563 res = ENC_SYM_TRUE;
211 }
212 }
213 591 return res;
214 }
215
216 451 lbm_value array_extension_buffer_append_i32(lbm_value *args, lbm_uint argn) {
217
218 451 lbm_value res = ENC_SYM_EERROR;
219 451 uint8_t *data = NULL;
220 451 lbm_uint d_size = 0;
221 451 bool be = false;
222 451 lbm_uint index = 0;
223
224
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 1 times.
451 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
225
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 28 times.
450 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)lbm_dec_as_i32(args[2]))) {
226 422 res = ENC_SYM_TRUE;
227 }
228 }
229 451 return res;
230 }
231
232
233 711 lbm_value array_extension_buffer_append_u8(lbm_value *args, lbm_uint argn) {
234
235 711 lbm_value res = ENC_SYM_EERROR;
236 711 uint8_t *data = NULL;
237 711 lbm_uint d_size = 0;
238 711 bool be = false;
239 711 lbm_uint index = 0;
240
241
2/2
✓ Branch 0 taken 710 times.
✓ Branch 1 taken 1 times.
711 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
242
2/2
✓ Branch 0 taken 682 times.
✓ Branch 1 taken 28 times.
710 if (buffer_append_bytes(data, d_size, be, index, 1, (lbm_uint)lbm_dec_as_u32(args[2]))) {
243 682 res = ENC_SYM_TRUE;
244 }
245 }
246 711 return res;
247 }
248
249 116 lbm_value array_extension_buffer_append_u16(lbm_value *args, lbm_uint argn) {
250
251 116 lbm_value res = ENC_SYM_EERROR;
252 116 uint8_t *data = NULL;
253 116 lbm_uint d_size = 0;
254 116 bool be = false;
255 116 lbm_uint index = 0;
256
257
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 1 times.
116 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
258
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 28 times.
115 if (buffer_append_bytes(data, d_size, be, index, 2, (lbm_uint)lbm_dec_as_u32(args[2]))) {
259 87 res = ENC_SYM_TRUE;
260 }
261 }
262 116 return res;
263 }
264
265 311 lbm_value array_extension_buffer_append_u24(lbm_value *args, lbm_uint argn) {
266
267 311 lbm_value res = ENC_SYM_EERROR;
268 311 uint8_t *data = NULL;
269 311 lbm_uint d_size = 0;
270 311 bool be = false;
271 311 lbm_uint index = 0;
272
273
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 1 times.
311 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
274
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
310 if (buffer_append_bytes(data, d_size, be, index, 3, (lbm_uint)lbm_dec_as_u32(args[2]))) {
275 282 res = ENC_SYM_TRUE;
276 }
277 }
278 311 return res;
279 }
280
281 452 lbm_value array_extension_buffer_append_u32(lbm_value *args, lbm_uint argn) {
282
283 452 lbm_value res = ENC_SYM_EERROR;
284 452 uint8_t *data = NULL;
285 452 lbm_uint d_size = 0;
286 452 bool be = false;
287 452 lbm_uint index = 0;
288
289
2/2
✓ Branch 0 taken 451 times.
✓ Branch 1 taken 1 times.
452 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
290
2/2
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 28 times.
451 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)lbm_dec_as_u32(args[2]))) {
291 423 res = ENC_SYM_TRUE;
292 }
293 }
294 452 return res;
295 }
296
297 200 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 200 times.
200 if (fabsf(number) < 1.5e-38) {
301 number = 0.0;
302 }
303
304 200 int e = 0;
305 200 float sig = frexpf(number, &e);
306 200 float sig_abs = fabsf(sig);
307 200 uint32_t sig_i = 0;
308
309
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (sig_abs >= 0.5) {
310 200 sig_i = (uint32_t)((sig_abs - 0.5f) * 2.0f * 8388608.0f);
311 200 e += 126;
312 }
313
314 200 uint32_t res = (((uint32_t)e & 0xFFu) << 23) | (uint32_t)(sig_i & 0x7FFFFFu);
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (sig < 0) {
316 res |= 1U << 31;
317 }
318
319 200 return res;
320 }
321
322 170 static lbm_float u_to_float(uint32_t v) {
323
324 170 int e = (v >> 23) & 0xFF;
325 170 uint32_t sig_i = v & 0x7FFFFF;
326 170 bool neg = v & (1U << 31);
327
328 170 float sig = 0.0;
329
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
170 if (e != 0 || sig_i != 0) {
330 170 sig = (float)sig_i / (8388608.0f * 2.0f) + 0.5f;
331 170 e -= 126;
332 }
333
334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170 times.
170 if (neg) {
335 sig = -sig;
336 }
337
338 170 return ldexpf(sig, e);
339 }
340
341 201 lbm_value array_extension_buffer_append_f32(lbm_value *args, lbm_uint argn) {
342
343 201 lbm_value res = ENC_SYM_EERROR;
344 201 uint8_t *data = NULL;
345 201 lbm_uint d_size = 0;
346 201 bool be = false;
347 201 lbm_uint index = 0;
348
349
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 1 times.
201 if (decode_append_args(&res, args, argn, &index, &be, &d_size, &data)) {
350
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 28 times.
200 if (buffer_append_bytes(data, d_size, be, index, 4, (lbm_uint)float_to_u(lbm_dec_as_float(args[2])))) {
351 172 res = ENC_SYM_TRUE;
352 }
353 }
354 201 return res;
355 }
356
357 /* (buffer-get-i8 buffer index) */
358 /* (buffer-get-i16 buffer index little-endian) */
359
360 5034 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 5034 bool res = false;
362
363 5034 *be=true;
364
365
3/3
✓ Branch 0 taken 1186 times.
✓ Branch 1 taken 3845 times.
✓ Branch 2 taken 3 times.
5034 switch(argn) {
366 1186 case 3:
367
1/2
✓ Branch 0 taken 1186 times.
✗ Branch 1 not taken.
1186 if (lbm_type_of(args[2]) == LBM_TYPE_SYMBOL &&
368
2/2
✓ Branch 0 taken 1184 times.
✓ Branch 1 taken 2 times.
1186 lbm_dec_sym(args[2]) == little_endian) {
369 1184 *be = false;
370 }
371 /* fall through */
372 case 2: {
373 5031 lbm_array_header_t *array = lbm_dec_array_r(args[0]);
374
4/4
✓ Branch 0 taken 5029 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5025 times.
✓ Branch 3 taken 4 times.
10060 if (array &&
375 5029 lbm_is_number(args[1])) {
376 5025 *a_size = array->size;
377 5025 *a_data = (uint8_t*)array->data;
378 5025 *index = lbm_dec_as_u32(args[1]);
379 5025 res = true;
380 } else {
381 6 *error = ENC_SYM_TERROR;
382 }
383 }
384 }
385 5034 return res;
386 }
387
388 5025 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 5025 bool res = false;
391 5025 lbm_uint last_index = index + (nbytes - 1);
392
393
2/2
✓ Branch 0 taken 4409 times.
✓ Branch 1 taken 616 times.
5025 if (last_index < d_size) {
394 4409 lbm_uint value = 0;
395 4409 res = true;
396
4/5
✓ Branch 0 taken 2371 times.
✓ Branch 1 taken 654 times.
✓ Branch 2 taken 282 times.
✓ Branch 3 taken 1102 times.
✗ Branch 4 not taken.
4409 switch(nbytes) {
397 2371 case 1:
398 2371 value = (lbm_uint)data[index];
399 2371 break;
400 654 case 2:
401
2/2
✓ Branch 0 taken 372 times.
✓ Branch 1 taken 282 times.
654 if (be) {
402 372 value =
403 372 (lbm_uint) data[index+1] |
404 372 (lbm_uint) data[index] << 8;
405 } else {
406 282 value =
407 282 (lbm_uint) data[index] |
408 282 (lbm_uint) data[index+1] << 8;
409 }
410 654 break;
411 282 case 3:
412
2/2
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 141 times.
282 if (be) {
413 141 value =
414 141 (lbm_uint) data[index+2] |
415 141 (lbm_uint) data[index+1] << 8 |
416 141 (lbm_uint) data[index] << 16;
417 } else {
418 141 value =
419 141 (lbm_uint) data[index] |
420 141 (lbm_uint) data[index+1] << 8 |
421 141 (lbm_uint) data[index+2] << 16;
422 }
423 282 break;
424 1102 case 4:
425
2/2
✓ Branch 0 taken 817 times.
✓ Branch 1 taken 285 times.
1102 if (be) {
426 817 value =
427 817 (uint32_t) data[index+3] |
428 817 (uint32_t) data[index+2] << 8 |
429 817 (uint32_t) data[index+1] << 16 |
430 817 (uint32_t) data[index] << 24;
431 } else {
432 285 value =
433 285 (uint32_t) data[index] |
434 285 (uint32_t) data[index+1] << 8 |
435 285 (uint32_t) data[index+2] << 16 |
436 285 (uint32_t) data[index+3] << 24;
437 }
438 1102 break;
439 default:
440 res = false;
441 }
442 4409 *r_value = value;
443 }
444 5025 return res;
445 }
446
447
448
449 1404 lbm_value array_extension_buffer_get_i8(lbm_value *args, lbm_uint argn) {
450 1404 lbm_value res = ENC_SYM_EERROR;
451 1404 uint8_t *data = NULL;
452 1404 lbm_uint d_size = 0;
453 1404 bool be = false;
454 1404 lbm_uint index = 0;
455 1404 lbm_uint value = 0;
456
457
2/2
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 4 times.
1404 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
458
2/2
✓ Branch 0 taken 1316 times.
✓ Branch 1 taken 84 times.
1400 if (buffer_get_uint(&value, data, d_size, be, index, 1)) {
459 1316 res =lbm_enc_i((int8_t)value);
460 }
461 }
462 1404 return res;
463 }
464
465 703 lbm_value array_extension_buffer_get_i16(lbm_value *args, lbm_uint argn) {
466 703 lbm_value res = ENC_SYM_EERROR;
467 703 uint8_t *data = NULL;
468 703 lbm_uint d_size = 0;
469 703 bool be = false;
470 703 lbm_uint index = 0;
471 703 lbm_uint value = 0;
472
473
1/2
✓ Branch 0 taken 703 times.
✗ Branch 1 not taken.
703 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
474
2/2
✓ Branch 0 taken 563 times.
✓ Branch 1 taken 140 times.
703 if (buffer_get_uint(&value, data, d_size, be, index, 2)) {
475 563 res =lbm_enc_i((int16_t)value);
476 }
477 }
478 703 return res;
479 }
480
481 507 lbm_value array_extension_buffer_get_i32(lbm_value *args, lbm_uint argn) {
482 507 lbm_value res = ENC_SYM_EERROR;
483 507 uint8_t *data = NULL;
484 507 lbm_uint d_size = 0;
485 507 bool be = false;
486 507 lbm_uint index = 0;
487 507 lbm_uint value = 0;
488
489
2/2
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 1 times.
507 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
490
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 84 times.
506 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
491 422 res =lbm_enc_i((int32_t)value);
492 }
493 }
494 507 return res;
495 }
496
497 1140 lbm_value array_extension_buffer_get_u8(lbm_value *args, lbm_uint argn) {
498 1140 lbm_value res = ENC_SYM_EERROR;
499 1140 uint8_t *data = NULL;
500 1140 lbm_uint d_size = 0;
501 1140 bool be = false;
502 1140 lbm_uint index = 0;
503 1140 lbm_uint value = 0;
504
505
2/2
✓ Branch 0 taken 1139 times.
✓ Branch 1 taken 1 times.
1140 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
506
2/2
✓ Branch 0 taken 1055 times.
✓ Branch 1 taken 84 times.
1139 if (buffer_get_uint(&value, data, d_size, be, index, 1)) {
507 1055 res = lbm_enc_i((uint8_t)value);
508 }
509 }
510 1140 return res;
511 }
512
513 120 lbm_value array_extension_buffer_get_u16(lbm_value *args, lbm_uint argn) {
514 120 lbm_value res = ENC_SYM_EERROR;
515 120 uint8_t *data = NULL;
516 120 lbm_uint d_size = 0;
517 120 bool be = false;
518 120 lbm_uint index = 0;
519 120 lbm_uint value = 0;
520
521
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 1 times.
120 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
522
2/2
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 28 times.
119 if (buffer_get_uint(&value, data, d_size, be, index, 2)) {
523 91 res = lbm_enc_i((uint16_t)value);
524 }
525 }
526 120 return res;
527 }
528
529 367 lbm_value array_extension_buffer_get_u24(lbm_value *args, lbm_uint argn) {
530 367 lbm_value res = ENC_SYM_EERROR;
531 367 uint8_t *data = NULL;
532 367 lbm_uint d_size = 0;
533 367 bool be = false;
534 367 lbm_uint index = 0;
535 367 lbm_uint value = 0;
536
537
2/2
✓ Branch 0 taken 366 times.
✓ Branch 1 taken 1 times.
367 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
538
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 84 times.
366 if (buffer_get_uint(&value, data, d_size, be, index, 3)) {
539 282 res = lbm_enc_i((int32_t)value);
540 }
541 }
542 367 return res;
543 }
544
545 594 lbm_value array_extension_buffer_get_u32(lbm_value *args, lbm_uint argn) {
546 594 lbm_value res = ENC_SYM_EERROR;
547 594 uint8_t *data = NULL;
548 594 lbm_uint d_size = 0;
549 594 bool be = false;
550 594 lbm_uint index = 0;
551 594 lbm_uint value = 0;
552
553
1/2
✓ Branch 0 taken 594 times.
✗ Branch 1 not taken.
594 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
554
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 84 times.
594 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
555 510 res = lbm_enc_u32((uint32_t)value);
556 }
557 }
558 594 return res;
559 }
560
561 199 lbm_value array_extension_buffer_get_f32(lbm_value *args, lbm_uint argn) {
562 199 lbm_value res = ENC_SYM_EERROR;
563 199 uint8_t *data = NULL;
564 199 lbm_uint d_size = 0;
565 199 bool be = false;
566 199 lbm_uint index = 0;
567 199 lbm_uint value = 0;
568
569
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 1 times.
199 if (decode_get_args(&res, args, argn, &index, &be, &d_size, &data)) {
570
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 28 times.
198 if (buffer_get_uint(&value, data, d_size, be, index, 4)) {
571 170 res = lbm_enc_float(u_to_float((uint32_t)value));
572 }
573 }
574 199 return res;
575 }
576
577 254 lbm_value array_extension_buffer_length(lbm_value *args, lbm_uint argn) {
578 254 lbm_value res = ENC_SYM_EERROR;
579 lbm_array_header_t *array;
580
4/4
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 252 times.
✓ Branch 3 taken 1 times.
507 if (argn == 1 &&
581
1/2
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
505 (array = lbm_dec_array_r(args[0])) &&
582 252 lbm_heap_array_valid(args[0])) {
583 252 res = lbm_enc_i((lbm_int)array->size);
584 }
585 254 return res;
586 }
587
588 //TODO: Have to think about 32 vs 64 bit here
589 568 static lbm_value array_extensions_bufclear(lbm_value *args, lbm_uint argn) {
590 568 lbm_value res = ENC_SYM_EERROR;
591
4/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 510 times.
✓ Branch 3 taken 29 times.
568 if (argn >= 1 && argn <= 4) {
592 510 res = ENC_SYM_TERROR;
593
2/2
✓ Branch 0 taken 508 times.
✓ Branch 1 taken 2 times.
510 if (lbm_is_array_rw(args[0])) {
594 508 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
595
596 508 uint8_t clear_byte = 0;
597
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 84 times.
508 if (argn >= 2) {
598
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 423 times.
424 if (!lbm_is_number(args[1])) {
599 1 return res;
600 }
601 423 clear_byte = (uint8_t)lbm_dec_as_u32(args[1]);
602 }
603
604 507 uint32_t start = 0;
605
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 448 times.
507 if (argn >= 3) {
606
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 58 times.
59 if (!lbm_is_number(args[2])) {
607 1 return res;
608 }
609 58 uint32_t start_new = lbm_dec_as_u32(args[2]);
610
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 1 times.
58 if (start_new < array->size) {
611 57 start = start_new;
612 } else {
613 1 return res;
614 }
615 }
616 // Truncates size on 64 bit build
617 505 uint32_t len = (uint32_t)array->size - start;
618
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 476 times.
505 if (argn >= 4) {
619
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28 times.
29 if (!lbm_is_number(args[3])) {
620 1 return res;
621 }
622 28 uint32_t len_new = lbm_dec_as_u32(args[3]);
623
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 if (len_new <= len) {
624 28 len = len_new;
625 }
626 }
627
628 504 memset((char*)array->data + start, clear_byte, len);
629 504 res = ENC_SYM_TRUE;
630 }
631 }
632 564 return res;
633 }
634
635 141 static lbm_value array_extensions_bufcpy(lbm_value *args, lbm_uint argn) {
636 141 lbm_value res = ENC_SYM_EERROR;
637
638
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 29 times.
141 if (argn == 5) {
639 112 res = ENC_SYM_TERROR;
640
4/6
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
168 if (lbm_is_array_rw(args[0]) && lbm_is_number(args[1]) &&
641
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
112 lbm_is_array_r(args[2]) && lbm_is_number(args[3]) &&lbm_is_number(args[4])) {
642 56 lbm_array_header_t *array1 = (lbm_array_header_t *)lbm_car(args[0]);
643
644 56 uint32_t start1 = lbm_dec_as_u32(args[1]);
645
646 56 lbm_array_header_t *array2 = (lbm_array_header_t *)lbm_car(args[2]);
647
648 56 uint32_t start2 = lbm_dec_as_u32(args[3]);
649 56 uint32_t len = lbm_dec_as_u32(args[4]);
650
651
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
56 if (start1 < array1->size && start2 < array2->size) {
652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (len > (array1->size - start1)) {
653 len = ((uint32_t)array1->size - start1);
654 }
655
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (len > (array2->size - start2)) {
656 len = ((uint32_t)array2->size - start2);
657 }
658
659 56 memcpy((char*)array1->data + start1, (char*)array2->data + start2, len);
660 }
661 56 res = ENC_SYM_TRUE;
662 }
663 }
664 141 return res;
665 }
666
667 172 static lbm_value array_extensions_bufset_bit(lbm_value *args, lbm_uint argn) {
668 172 lbm_value res = ENC_SYM_EERROR;
669
670
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 85 times.
172 if (argn == 3) {
671 87 res = ENC_SYM_TERROR;
672
4/4
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 57 times.
✓ Branch 3 taken 1 times.
145 if (lbm_is_array_rw(args[0]) &&
673
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1 times.
115 lbm_is_number(args[1]) && lbm_is_number(args[2])) {
674 56 lbm_array_header_t *array = (lbm_array_header_t *)lbm_car(args[0]);
675
676 56 unsigned int pos = lbm_dec_as_u32(args[1]);
677 56 unsigned int bit = lbm_dec_as_u32(args[2]) ? 1 : 0;
678
679 56 unsigned int bytepos = pos / 8;
680
681
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (bytepos < array->size) {
682 56 unsigned int bitpos = pos % 8;
683 56 ((uint8_t*)array->data)[bytepos] &= (uint8_t)~(1 << bitpos);
684 56 ((uint8_t*)array->data)[bytepos] |= (uint8_t)(bit << bitpos);
685 }
686
687 56 res = ENC_SYM_TRUE;
688 }
689 }
690 172 return res;
691 }
692