GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/array_extensions.c
Date: 2025-10-28 15:15:18
Exec Total Coverage
Lines: 412 418 98.6%
Functions: 28 28 100.0%
Branches: 169 189 89.4%

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