annotate val.c @ 158:7cd03c69d379

val: preallocate int vals for [0,10) Since many programs use small integers often, we can preallocate them and just return the right one when a new int is requested. This avoids a trip to the heap. If we don't have a preallocated one, we just allocate a new one from the heap. One of the consumers of libjeffpc saw almost a 4% reduction in struct val allocations during startup: cache buf buf buf buf memory alloc alloc name size in use in ptc total in use succeed fail ------------------------- ------ ------- ------- ------- ------- --------- ----- val-cache (before) 20 0 - 507 12K 24258 0 val-cache (after) 20 0 - 507 12K 23341 0 Note: This consumer is not a heavy user of VT_INT values. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Tue, 11 Apr 2017 11:21:20 -0400
parents dbfb30f43dae
children 11d55479b0e1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
1 /*
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
2 * Copyright (c) 2014-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
3 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
5 * of this software and associated documentation files (the "Software"), to deal
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
6 * in the Software without restriction, including without limitation the rights
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
8 * copies of the Software, and to permit persons to whom the Software is
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
9 * furnished to do so, subject to the following conditions:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
10 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
11 * The above copyright notice and this permission notice shall be included in
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
12 * all copies or substantial portions of the Software.
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
13 *
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
20 * SOFTWARE.
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
21 */
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
22
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
23 #include <string.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
24 #include <errno.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
25 #include <stddef.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
26 #include <stdio.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
27 #include <stdbool.h>
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
28 #include <ctype.h>
58
260a210c9e84 val: include inttypes.h for PRIu64
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 19
diff changeset
29 #include <inttypes.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
30 #include <umem.h>
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
31
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
32 #include <jeffpc/val.h>
19
017a4abcfe3d init: add a single initialize-the-library function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 9
diff changeset
33 #include <jeffpc/jeffpc.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
34 #include <jeffpc/error.h>
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
35 #include <jeffpc/types.h>
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
36
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
37 #define INIT_STATIC_VAL(t, memb, val) \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
38 { \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
39 .type = (t), \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
40 .static_alloc = true, \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
41 .memb = (val), \
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
42 }
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
43
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
44 static const struct val val_true = INIT_STATIC_VAL(VT_BOOL, b, true);
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
45 static const struct val val_false = INIT_STATIC_VAL(VT_BOOL, b, false);
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
46 static const struct val val_ints[10] = {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
47 [0] = INIT_STATIC_VAL(VT_INT, i, 0),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
48 [1] = INIT_STATIC_VAL(VT_INT, i, 1),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
49 [2] = INIT_STATIC_VAL(VT_INT, i, 2),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
50 [3] = INIT_STATIC_VAL(VT_INT, i, 3),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
51 [4] = INIT_STATIC_VAL(VT_INT, i, 4),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
52 [5] = INIT_STATIC_VAL(VT_INT, i, 5),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
53 [6] = INIT_STATIC_VAL(VT_INT, i, 6),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
54 [7] = INIT_STATIC_VAL(VT_INT, i, 7),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
55 [8] = INIT_STATIC_VAL(VT_INT, i, 8),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
56 [9] = INIT_STATIC_VAL(VT_INT, i, 9),
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
57 };
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
58
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
59 static umem_cache_t *val_cache;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
60
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
61 void init_val_subsys(void)
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
62 {
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
63 val_cache = umem_cache_create("val-cache", sizeof(struct val),
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
64 0, NULL, NULL, NULL, NULL, NULL, 0);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
65 ASSERT(val_cache);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
66 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
67
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
68 static struct val *__val_alloc(enum val_type type)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
69 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
70 struct val *val;
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
71
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
72 val = umem_cache_alloc(val_cache, 0);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
73 if (!val)
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
74 return val;
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
75
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
76 val->type = type;
156
9e156cc8bdb8 val: add support for static vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 153
diff changeset
77 val->static_alloc = false;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
78
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
79 refcnt_init(&val->refcnt, 1);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
80
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
81 return val;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
82 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
83
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
84 void val_free(struct val *val)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
85 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
86 ASSERT(val);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
87 ASSERT3U(refcnt_read(&val->refcnt), ==, 0);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
88
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
89 switch (val->type) {
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
90 case VT_INT:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
91 case VT_BOOL:
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
92 case VT_CHAR:
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
93 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
94 case VT_STR:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
95 case VT_SYM:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
96 str_putref(val->str);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
97 break;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
98 case VT_CONS:
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
99 val_putref(val->cons.head);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
100 val_putref(val->cons.tail);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
101 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
102 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
103
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
104 umem_cache_free(val_cache, val);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
105 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
106
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
107 #define DEF_VAL_SET(fxn, vttype, valelem, ctype) \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
108 struct val *val_alloc_##fxn(ctype v) \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
109 { \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
110 struct val *val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
111 \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
112 val = __val_alloc(vttype); \
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
113 if (!val) \
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
114 return NULL; \
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
115 \
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
116 val->_set_##valelem = v; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
117 \
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
118 return val; \
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
119 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
120
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
121 static DEF_VAL_SET(int_heap, VT_INT, i, uint64_t)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
122 DEF_VAL_SET(str, VT_STR, str, struct str *)
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
123 DEF_VAL_SET(sym, VT_SYM, str, struct str *)
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
124 DEF_VAL_SET(char, VT_CHAR, i, uint64_t)
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
125
158
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
126 struct val *val_alloc_int(uint64_t i)
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
127 {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
128 if (i < ARRAY_LEN(val_ints)) {
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
129 /*
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
130 * Cast away the const - we define the static as const to get it
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
131 * into .rodata, but we have to drop the const since everything
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
132 * expects struct val to be writable (because refcounts modify it).
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
133 * In this case, we won't get any modifications because we're marked
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
134 * as static.
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
135 */
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
136 return (struct val *) &val_ints[i];
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
137 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
138
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
139 return val_alloc_int_heap(i);
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
140 }
7cd03c69d379 val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 157
diff changeset
141
157
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
142 struct val *val_alloc_bool(bool b)
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
143 {
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
144 const struct val *ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
145
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
146 ret = b ? &val_true : &val_false;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
147
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
148 /*
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
149 * Cast away the const - we define the static as const to get it
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
150 * into .rodata, but we have to drop the const since everything
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
151 * expects struct val to be writable (because refcounts modify it).
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
152 * In this case, we won't get any modifications because we're marked
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
153 * as static.
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
154 */
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
155 return (struct val *) ret;
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
156 }
dbfb30f43dae val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 156
diff changeset
157
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
158 struct val *val_alloc_cons(struct val *head, struct val *tail)
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
159 {
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
160 struct val *val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
161
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
162 val = __val_alloc(VT_CONS);
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
163 if (!val)
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
164 return NULL;
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
165
153
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
166 val->_set_cons.head = head;
e6764c2b9d5d val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 152
diff changeset
167 val->_set_cons.tail = tail;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
168
152
3d2fdf4385bf val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 129
diff changeset
169 return val;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
170 }
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
171
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
172 void val_dump(struct val *val, int indent)
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
173 {
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
174 if (!val)
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
175 return;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
176
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
177 switch (val->type) {
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
178 case VT_STR:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
179 case VT_SYM:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
180 fprintf(stderr, "%*s'%s'\n", indent, "", str_cstr(val->str));
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
181 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
182 case VT_INT:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
183 fprintf(stderr, "%*s%"PRIu64"\n", indent, "", val->i);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
184 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
185 case VT_BOOL:
110
afacfc4a7fdf val: dumped bools need a trailing newline
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 58
diff changeset
186 fprintf(stderr, "%*s%s\n", indent, "",
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
187 val->b ? "true" : "false");
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
188 break;
129
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
189 case VT_CHAR:
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
190 if (isprint(val->i))
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
191 fprintf(stderr, "%*s\\u%04"PRIX64": '%c'\n",
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
192 indent, "", val->i, (char) val->i);
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
193 else
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
194 fprintf(stderr, "%*s\\u%04"PRIX64"\n", indent,
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
195 "", val->i);
f3e6fce14902 val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 110
diff changeset
196 break;
9
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
197 case VT_CONS:
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
198 fprintf(stderr, "%*scons head:\n", indent, "");
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
199 val_dump(val->cons.head, indent + 2);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
200 fprintf(stderr, "%*scons tail:\n", indent, "");
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
201 val_dump(val->cons.tail, indent + 2);
4c067f4ec57f val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 8
diff changeset
202 break;
8
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
203 default:
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
204 fprintf(stderr, "Unknown type %d\n", val->type);
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
205 break;
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
206 }
083d11258db6 val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
207 }