GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/symrepr.c
Date: 2024-11-05 17:11:09
Exec Total Coverage
Lines: 126 160 78.8%
Functions: 16 21 76.2%
Branches: 44 73 60.3%

Line Branch Exec Source
1 /*
2 Copyright 2018, 2021, 2022, 2024 Joel Svensson svenssonjoel@yahoo.se
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <inttypes.h>
23
24
25 #include <lbm_memory.h>
26 #include <heap.h>
27 #include "symrepr.h"
28 #include "extensions.h"
29 #include "lbm_utils.h"
30
31 #define NUM_SPECIAL_SYMBOLS (sizeof(special_symbols) / sizeof(special_sym))
32 #define NAME 0
33 #define ID 1
34 #define NEXT 2
35
36 typedef struct {
37 const char *name;
38 const lbm_uint id;
39 } special_sym;
40
41 special_sym const special_symbols[] = {
42 {"nil" , SYM_NIL},
43 {"quote" , SYM_QUOTE},
44 {"t" , SYM_TRUE},
45 {"if" , SYM_IF},
46 {"cond" , SYM_COND},
47 {"lambda" , SYM_LAMBDA},
48 {"closure" , SYM_CLOSURE},
49 {"let" , SYM_LET},
50 {"define" , SYM_DEFINE},
51 {"progn" , SYM_PROGN},
52 {"read" , SYM_READ},
53 {"read-program" , SYM_READ_PROGRAM},
54 {"read-eval-program", SYM_READ_AND_EVAL_PROGRAM},
55 {"match" , SYM_MATCH},
56 {"_" , SYM_DONTCARE},
57 {"send" , SYM_SEND},
58 {"recv" , SYM_RECEIVE},
59 {"recv-to" , SYM_RECEIVE_TIMEOUT},
60 {"macro" , SYM_MACRO},
61 {"call-cc" , SYM_CALLCC},
62 {"continuation" , SYM_CONT},
63 {"var" , SYM_PROGN_VAR},
64 {"timeout" , SYM_TIMEOUT},
65
66 {"set" , SYM_SETVAR},
67 {"setq" , SYM_SETQ},
68 {"move-to-flash", SYM_MOVE_TO_FLASH},
69 {"exit-ok" , SYM_EXIT_OK},
70 {"exit-error" , SYM_EXIT_ERROR},
71 {"map" , SYM_MAP},
72 {"reverse" , SYM_REVERSE},
73 {"flatten" , SYM_FLATTEN},
74 {"unflatten" , SYM_UNFLATTEN},
75 {"kill" , SYM_KILL},
76 {"sleep" , SYM_SLEEP},
77 {"merge" , SYM_MERGE},
78 {"sort" , SYM_SORT},
79 {"gc" , SYM_PERFORM_GC},
80 {"loop" , SYM_LOOP},
81 {"trap" , SYM_TRAP},
82 {"rest-args" , SYM_REST_ARGS},
83 {"rotate" , SYM_ROTATE},
84
85 // pattern matching
86 {"?" , SYM_MATCH_ANY},
87
88 // Error symbols with parsable names
89 {"no_match" , SYM_NO_MATCH},
90 {"read_error" , SYM_RERROR},
91 {"type_error" , SYM_TERROR},
92 {"eval_error" , SYM_EERROR},
93 {"out_of_memory" , SYM_MERROR},
94 {"fatal_error" , SYM_FATAL_ERROR},
95 {"out_of_stack" , SYM_STACK_ERROR},
96 {"division_by_zero" , SYM_DIVZERO},
97 {"variable_not_bound" , SYM_NOT_FOUND},
98 {"flash_full" , SYM_ERROR_FLASH_HEAP_FULL},
99
100 // Special symbols with unparsable names
101 {"$barray" , SYM_ARRAY_TYPE},
102 {"$raw_i" , SYM_RAW_I_TYPE},
103 {"$raw_u" , SYM_RAW_U_TYPE},
104 {"$raw_f" , SYM_RAW_F_TYPE},
105 {"$ind_i" , SYM_IND_I_TYPE},
106 {"$ind_u" , SYM_IND_U_TYPE},
107 {"$ind_f" , SYM_IND_F_TYPE},
108 {"$channel" , SYM_CHANNEL_TYPE},
109 {"$recovered" , SYM_RECOVERED},
110 {"$placeholder" , SYM_PLACEHOLDER},
111 {"$custom" , SYM_CUSTOM_TYPE},
112 {"$array" , SYM_LISPARRAY_TYPE},
113 {"$nonsense" , SYM_NONSENSE},
114 {"$dm-array" , SYM_DEFRAG_ARRAY_TYPE},
115 {"$dm" , SYM_DEFRAG_MEM_TYPE},
116
117 // tokenizer symbols with unparsable names
118 {"[openpar]" , SYM_OPENPAR},
119 {"[closepar]" , SYM_CLOSEPAR},
120 {"[backquote]" , SYM_BACKQUOTE},
121 {"[comma]" , SYM_COMMA},
122 {"[commaat]" , SYM_COMMAAT},
123 {"[dot]" , SYM_DOT},
124 {"[done]" , SYM_TOKENIZER_DONE},
125 {"[quote_it]" , SYM_QUOTE_IT},
126 {"[colon]" , SYM_COLON},
127 {"[wait]" , SYM_TOKENIZER_WAIT},
128 {"[openbrack]" , SYM_OPENBRACK},
129 {"[closebrack]" , SYM_CLOSEBRACK},
130 {"[rerror]" , SYM_TOKENIZER_RERROR},
131 {"[appcont]" , SYM_APP_CONT},
132
133 // special symbols with parseable names
134 {"type-list" , SYM_TYPE_LIST},
135 {"type-i" , SYM_TYPE_I},
136 {"type-u" , SYM_TYPE_U},
137 {"type-float" , SYM_TYPE_FLOAT},
138 {"type-i32" , SYM_TYPE_I32},
139 {"type-u32" , SYM_TYPE_U32},
140 {"type-double" , SYM_TYPE_DOUBLE},
141 {"type-i64" , SYM_TYPE_I64},
142 {"type-u64" , SYM_TYPE_U64},
143 {"type-array" , SYM_TYPE_ARRAY},
144 {"type-symbol" , SYM_TYPE_SYMBOL},
145 {"type-char" , SYM_TYPE_CHAR},
146 {"type-byte" , SYM_TYPE_BYTE},
147 {"type-channel" , SYM_TYPE_CHANNEL},
148 {"type-lisparray" , SYM_TYPE_LISPARRAY},
149 {"type-dm" , SYM_TYPE_DEFRAG_MEM},
150 {"type-custom" , SYM_TYPE_CUSTOM},
151
152 // Fundamental operations
153 {"+" , SYM_ADD},
154 {"-" , SYM_SUB},
155 {"*" , SYM_MUL},
156 {"/" , SYM_DIV},
157 {"//" , SYM_INT_DIV},
158 {"mod" , SYM_MOD},
159 {"=" , SYM_NUMEQ},
160 {"!=" , SYM_NUM_NOT_EQ},
161 {"<" , SYM_LT},
162 {">" , SYM_GT},
163 {"<=" , SYM_LEQ},
164 {">=" , SYM_GEQ},
165 {"eval" , SYM_EVAL},
166 {"eval-program" , SYM_EVAL_PROGRAM},
167 {"and" , SYM_AND},
168 {"or" , SYM_OR},
169 {"not" , SYM_NOT},
170 {"yield" , SYM_YIELD},
171 {"wait" , SYM_WAIT},
172 {"spawn" , SYM_SPAWN},
173 {"atomic" , SYM_ATOMIC},
174 {"self" , SYM_SELF},
175 {"spawn-trap" , SYM_SPAWN_TRAP},
176 {"set-mailbox-size" , SYM_SET_MAILBOX_SIZE},
177 {"eq" , SYM_EQ},
178 {"not-eq" , SYM_NOT_EQ},
179 {"car" , SYM_CAR},
180 {"cdr" , SYM_CDR},
181 {"cons" , SYM_CONS},
182 {"list" , SYM_LIST},
183 {"append" , SYM_APPEND},
184 {"undefine" , SYM_UNDEFINE},
185 {"bufcreate" , SYM_BYTEARRAY_CREATE},
186 {"type-of" , SYM_TYPE_OF},
187 {"sym2str" , SYM_SYMBOL_TO_STRING},
188 {"str2sym" , SYM_STRING_TO_SYMBOL},
189 {"sym2u" , SYM_SYMBOL_TO_UINT},
190 {"u2sym" , SYM_UINT_TO_SYMBOL},
191 {"setcar" , SYM_SET_CAR},
192 {"setcdr" , SYM_SET_CDR},
193 {"setix" , SYM_SET_IX},
194 {"length" , SYM_LIST_LENGTH},
195 {"range" , SYM_RANGE},
196
197 {"assoc" , SYM_ASSOC}, // lookup an association
198 {"cossa" , SYM_COSSA}, // lookup an association "backwards"
199 {"acons" , SYM_ACONS}, // Add to alist
200 {"setassoc" , SYM_SET_ASSOC}, // Change association
201
202 {"shl" , SYM_SHL},
203 {"shr" , SYM_SHR},
204 {"bitwise-and" , SYM_BITWISE_AND},
205 {"bitwise-or" , SYM_BITWISE_OR},
206 {"bitwise-xor" , SYM_BITWISE_XOR},
207 {"bitwise-not" , SYM_BITWISE_NOT},
208
209 {"custom-destruct", SYM_CUSTOM_DESTRUCT},
210
211 {"to-i" , SYM_TO_I},
212 {"to-i32" , SYM_TO_I32},
213 {"to-u" , SYM_TO_U},
214 {"to-u32" , SYM_TO_U32},
215 {"to-float" , SYM_TO_FLOAT},
216 {"to-i64" , SYM_TO_I64},
217 {"to-u64" , SYM_TO_U64},
218 {"to-double" , SYM_TO_DOUBLE},
219 {"to-byte" , SYM_TO_BYTE},
220
221 {"event-register-handler", SYM_REG_EVENT_HANDLER},
222 {"take" , SYM_TAKE},
223 {"drop" , SYM_DROP},
224 {"mkarray" , SYM_MKARRAY},
225 {"array-to-list" , SYM_ARRAY_TO_LIST},
226 {"list-to-array" , SYM_LIST_TO_ARRAY},
227
228 {"dm-create" , SYM_DM_CREATE},
229 {"dm-alloc" , SYM_DM_ALLOC},
230
231 {"list?" , SYM_IS_LIST},
232 {"number?" , SYM_IS_NUMBER},
233
234 // fast access in list
235 {"ix" , SYM_IX},
236
237 // aliases
238 {"first" , SYM_CAR},
239 {"rest" , SYM_CDR},
240 {"fn" , SYM_LAMBDA},
241 {"def" , SYM_DEFINE},
242 {"true" , SYM_TRUE},
243 {"false" , SYM_NIL},
244 {"setvar" , SYM_SETVAR},
245 {"type-f32" , SYM_TYPE_FLOAT},
246 {"type-f64" , SYM_TYPE_DOUBLE},
247 {"array-create" , SYM_BYTEARRAY_CREATE},
248 };
249
250 static lbm_uint *symlist = NULL;
251 static lbm_uint next_symbol_id = RUNTIME_SYMBOLS_START;
252 static lbm_uint symbol_table_size_list = 0;
253 static lbm_uint symbol_table_size_list_flash = 0;
254 static lbm_uint symbol_table_size_strings = 0;
255 static lbm_uint symbol_table_size_strings_flash = 0;
256
257 lbm_value symbol_x = ENC_SYM_NIL;
258 lbm_value symbol_y = ENC_SYM_NIL;
259
260 21504 int lbm_symrepr_init(void) {
261 21504 symlist = NULL;
262 21504 next_symbol_id = RUNTIME_SYMBOLS_START;
263 21504 symbol_table_size_list = 0;
264 21504 symbol_table_size_list_flash = 0;
265 21504 symbol_table_size_strings = 0;
266 21504 symbol_table_size_strings_flash = 0;
267
268 21504 lbm_uint x = 0;
269 21504 lbm_uint y = 0;
270 21504 lbm_add_symbol("x", &x);
271 21504 lbm_add_symbol("y", &y);
272 21504 symbol_x = lbm_enc_sym(x);
273 21504 symbol_y = lbm_enc_sym(y);
274 21504 return 1;
275 }
276
277 void lbm_symrepr_name_iterator(symrepr_name_iterator_fun f) {
278
279 lbm_uint *curr = symlist;
280 while (curr) {
281 f((const char *)curr[NAME]);
282 curr = (lbm_uint *)curr[NEXT];
283 }
284 }
285
286 62344 const char *lookup_symrepr_name_memory(lbm_uint id) {
287
288 62344 lbm_uint *curr = symlist;
289
1/2
✓ Branch 0 taken 795540 times.
✗ Branch 1 not taken.
795540 while (curr) {
290
2/2
✓ Branch 0 taken 62344 times.
✓ Branch 1 taken 733196 times.
795540 if (id == curr[ID]) {
291 62344 return (const char *)curr[NAME];
292 }
293 733196 curr = (lbm_uint*)curr[NEXT];
294 }
295 return NULL;
296 }
297
298 // Lookup symbol name given a symbol id
299 174713 const char *lbm_get_name_by_symbol(lbm_uint id) {
300 174713 lbm_uint sym_kind = SYMBOL_KIND(id);
301
3/3
✓ Branch 0 taken 112361 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 62344 times.
174713 switch (sym_kind) {
302 112361 case SYMBOL_KIND_SPECIAL: /* fall through */
303 case SYMBOL_KIND_FUNDAMENTAL:
304 case SYMBOL_KIND_APPFUN:
305
1/2
✓ Branch 0 taken 219399 times.
✗ Branch 1 not taken.
219399 for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) {
306
2/2
✓ Branch 0 taken 112361 times.
✓ Branch 1 taken 107038 times.
219399 if (id == special_symbols[i].id) {
307 112361 return (special_symbols[i].name);
308 }
309 }
310 return NULL;
311 break;
312 8 case SYMBOL_KIND_EXTENSION: {
313 8 lbm_uint ext_id = id - EXTENSION_SYMBOLS_START;
314
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (ext_id < lbm_get_max_extensions()) {
315 8 return extension_table[ext_id].name;
316 }
317 return NULL;
318 } break;
319 62344 default:
320 62344 return lookup_symrepr_name_memory(id);
321 }
322 }
323
324 lbm_uint *lbm_get_symbol_list_entry_by_name(char *name) {
325 lbm_uint *curr = symlist;
326 while (curr) {
327 char *str = (char*)curr[NAME];
328 if (str_eq(name, str)) {
329 return (lbm_uint *)curr;
330 }
331 curr = (lbm_uint*)curr[NEXT];
332 }
333 return NULL;
334 }
335
336 // Lookup symbol id given symbol name
337 3677158 int lbm_get_symbol_by_name(char *name, lbm_uint* id) {
338
339 // loop through special symbols
340
2/2
✓ Branch 0 taken 631572241 times.
✓ Branch 1 taken 3360223 times.
634932464 for (unsigned int i = 0; i < NUM_SPECIAL_SYMBOLS; i ++) {
341
2/2
✓ Branch 1 taken 316935 times.
✓ Branch 2 taken 631255306 times.
631572241 if (str_eq(name, (char *)special_symbols[i].name)) {
342 316935 *id = special_symbols[i].id;
343 316935 return 1;
344 }
345 }
346
347 // loop through extensions
348
2/2
✓ Branch 1 taken 657807916 times.
✓ Branch 2 taken 3316571 times.
661124487 for (unsigned int i = 0; i < lbm_get_max_extensions(); i ++) {
349
4/4
✓ Branch 0 taken 207306518 times.
✓ Branch 1 taken 450501398 times.
✓ Branch 3 taken 43652 times.
✓ Branch 4 taken 207262866 times.
657807916 if (extension_table[i].name && str_eq(name, extension_table[i].name)) {
350 43652 *id = EXTENSION_SYMBOLS_START + i;
351 43652 return 1;
352 }
353 }
354
355 3316571 lbm_uint *curr = symlist;
356
2/2
✓ Branch 0 taken 39534150 times.
✓ Branch 1 taken 2830450 times.
42364600 while (curr) {
357 39534150 char *str = (char*)curr[NAME];
358
2/2
✓ Branch 1 taken 486121 times.
✓ Branch 2 taken 39048029 times.
39534150 if (str_eq(name, str)) {
359 486121 *id = curr[ID];
360 486121 return 1;
361 }
362 39048029 curr = (lbm_uint*)curr[NEXT];
363 }
364 2830450 return 0;
365 }
366
367 extern lbm_flash_status lbm_write_const_array_padded(uint8_t *data, lbm_uint n, lbm_uint *res);
368
369
370 70 static bool store_symbol_name_flash(char *name, lbm_uint *res) {
371 70 size_t n = strlen(name) + 1;
372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (n == 1) return 0; // failure if empty symbol
373
374 lbm_uint alloc_size;
375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (n % sizeof(lbm_uint) == 0) {
376 alloc_size = n/(sizeof(lbm_uint));
377 } else {
378 70 alloc_size = (n/(sizeof(lbm_uint))) + 1;
379 }
380
381 70 lbm_uint symbol_addr = 0;
382 70 lbm_flash_status s = lbm_write_const_array_padded((uint8_t*)name, n, &symbol_addr);
383
2/4
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 70 times.
70 if (s != LBM_FLASH_WRITE_OK || symbol_addr == 0) {
384 return false;
385 }
386 70 symbol_table_size_strings_flash += alloc_size;
387 70 *res = symbol_addr;
388 70 return true;
389 }
390
391 // Symbol table
392 // non-const name copied into symbol-table-entry:
393 // Entry
394 // |
395 // [name-ptr | symbol-id | next-ptr | name n-bytes]
396 // | /
397 // ------------points here -----
398 //
399 // const name referenced by symbol-table-entry:
400 // Entry
401 // |
402 // [name-ptr | symbol-id | next-ptr]
403 // |
404 // [name n-bytes]
405 //
406 142310 static bool add_symbol_to_symtab(char* name, lbm_uint id) {
407 142310 bool r = false;
408 142310 size_t n = strlen(name) + 1;
409
2/4
✓ Branch 0 taken 142310 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142310 times.
✗ Branch 3 not taken.
142310 if (n > 1 && n <= 257) {
410 142310 size_t alloc_size = n + (3 * sizeof(lbm_uint));
411 142310 char *storage = lbm_malloc(alloc_size);
412
1/2
✓ Branch 0 taken 142310 times.
✗ Branch 1 not taken.
142310 if (storage) {
413 142310 memcpy(storage + (3 * sizeof(lbm_uint)), name, n);
414 142310 lbm_uint *m = (lbm_uint*)storage;
415
416 142310 symbol_table_size_list += 3 * sizeof(lbm_uint); // Bytes
417 142310 symbol_table_size_strings += n; // Bytes
418 142310 m[NAME] = (lbm_uint)&m[3];
419 142310 m[NEXT] = (lbm_uint) symlist;
420 142310 symlist = m;
421 142310 m[ID] =id;
422 142310 r = true;
423 }
424 }
425 142310 return r;
426 }
427
428 70 static bool add_symbol_to_symtab_flash(lbm_uint name, lbm_uint id) {
429 lbm_uint entry[3];
430 70 entry[NAME] = name;
431 70 entry[NEXT] = (lbm_uint) symlist;
432 70 entry[ID] = id;
433 70 lbm_uint entry_addr = 0;
434
1/2
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
70 if (lbm_write_const_raw(entry,3, &entry_addr) == LBM_FLASH_WRITE_OK) {
435 70 symlist = (lbm_uint*)entry_addr;
436 70 symbol_table_size_list_flash += 3;
437 70 return true;
438 }
439 return false;
440 }
441
442 142380 int lbm_add_symbol_base(char *name, lbm_uint *id, bool flash) {
443 lbm_uint symbol_name_storage;
444
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 142310 times.
142380 if (flash) {
445
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 70 times.
70 if (!store_symbol_name_flash(name, &symbol_name_storage)) return 0;
446
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 70 times.
70 if (!add_symbol_to_symtab_flash(symbol_name_storage, next_symbol_id)) return 0;
447 } else {
448
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 142310 times.
142310 if (!add_symbol_to_symtab(name, next_symbol_id)) {
449 return 0;
450 }
451 }
452 142380 *id = next_symbol_id ++;
453 142380 return 1;
454 }
455
456 106558 int lbm_add_symbol(char *name, lbm_uint* id) {
457 lbm_uint sym_id;
458
2/2
✓ Branch 1 taken 43036 times.
✓ Branch 2 taken 63522 times.
106558 if (!lbm_get_symbol_by_name(name, &sym_id)) {
459 43036 return lbm_add_symbol_base(name, id, false);
460 } else {
461 63522 *id = sym_id;
462 63522 return 1;
463 }
464 return 0;
465 }
466
467 int lbm_add_symbol_flash(char *name, lbm_uint* id) {
468 lbm_uint sym_id;
469 if (!lbm_get_symbol_by_name(name, &sym_id)) {
470 return lbm_add_symbol_base(name, id, true);
471 } else {
472 *id = sym_id;
473 return 1;
474 }
475 return 0;
476 }
477
478 408576 int lbm_add_symbol_const_base(char *name, lbm_uint* id) {
479 408576 lbm_uint *m = lbm_memory_allocate(3);
480
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 408576 times.
408576 if (m == NULL) return 0;
481 408576 symbol_table_size_list += 3;
482 408576 m[NAME] = (lbm_uint) name;
483 408576 m[NEXT] = (lbm_uint) symlist;
484 408576 symlist = m;
485 408576 m[ID] = next_symbol_id;
486 408576 *id = next_symbol_id ++;
487 408576 return 1;
488 }
489
490 408576 int lbm_add_symbol_const(char *name, lbm_uint* id) {
491 lbm_uint sym_id;
492
1/2
✓ Branch 1 taken 408576 times.
✗ Branch 2 not taken.
408576 if (!lbm_get_symbol_by_name(name, &sym_id)) {
493 408576 return lbm_add_symbol_const_base(name, id);
494 } else {
495 *id = sym_id;
496 return 1;
497 }
498 return 0;
499 }
500
501 56 int lbm_str_to_symbol(char *name, lbm_uint *sym_id) {
502
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 if (lbm_get_symbol_by_name(name, sym_id))
503 28 return 1;
504
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 else if (lbm_add_symbol(name, sym_id))
505 28 return 1;
506 return 0;
507 }
508
509 28 lbm_uint lbm_get_symbol_table_size(void) {
510 28 return (symbol_table_size_list +symbol_table_size_strings);
511 }
512
513 28 lbm_uint lbm_get_symbol_table_size_flash(void) {
514 28 return (symbol_table_size_list_flash +
515 28 symbol_table_size_strings_flash) * sizeof(lbm_uint);
516 }
517
518 28 lbm_uint lbm_get_symbol_table_size_names(void) {
519 28 return symbol_table_size_strings; // Bytes already
520 }
521
522 28 lbm_uint lbm_get_symbol_table_size_names_flash(void) {
523 28 return symbol_table_size_strings_flash * sizeof(lbm_uint);
524 }
525
526 bool lbm_symbol_in_flash(char *str) {
527 return !lbm_memory_ptr_inside((lbm_uint*)str);
528 }
529
530 bool lbm_symbol_list_entry_in_flash(char *str) {
531 lbm_uint *entry = lbm_get_symbol_list_entry_by_name(str);
532 return (entry == NULL || !lbm_memory_ptr_inside(entry));
533 }
534