• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nickg / nvc / 26417460180

25 May 2026 07:55PM UTC coverage: 92.266% (+0.001%) from 92.265%
26417460180

push

github

nickg
Constant folding for Verilog user function calls

144 of 155 new or added lines in 9 files covered. (92.9%)

32 existing lines in 4 files now uncovered.

78897 of 85510 relevant lines covered (92.27%)

626586.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.3
/src/vlog/vlog-node.c
1
//
2
//  Copyright (C) 2022-2026  Nick Gasson
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 "util.h"
19
#include "vlog/vlog-node.h"
20
#include "vlog/vlog-number.h"
21
#include "object.h"
22

23
#include <string.h>
24
#include <inttypes.h>
25
#include <stdlib.h>
26

27
static const imask_t has_map[V_LAST_NODE_KIND] = {
28
   // V_MODULE
29
   (I_IDENT | I_PORTS | I_STMTS | I_DECLS | I_IDENT2),
30

31
   // V_PORT_DECL
32
   (I_IDENT | I_SUBKIND | I_IDENT2 | I_REF | I_RANGES | I_TYPE | I_VALUE),
33

34
   // V_REF
35
   (I_IDENT | I_REF),
36

37
   // V_ALWAYS
38
   (I_IDENT | I_SUBKIND | I_STMTS),
39

40
   // V_TIMING
41
   (I_VALUE | I_STMTS),
42

43
   // V_NBASSIGN
44
   (I_TARGET | I_VALUE | I_DELAY),
45

46
   // V_EVENT
47
   (I_SUBKIND | I_VALUE),
48

49
   // V_INITIAL
50
   (I_IDENT | I_STMTS),
51

52
   // V_SEQ_BLOCK
53
   (I_IDENT | I_DECLS | I_STMTS),
54

55
   // V_SYS_TCALL
56
   (I_IDENT | I_PARAMS | I_SUBKIND),
57

58
   // V_STRING
59
   (I_NUMBER),
60

61
   // V_NUMBER
62
   (I_NUMBER),
63

64
   // V_NET_DECL
65
   (I_IDENT | I_SUBKIND | I_TYPE | I_RANGES | I_VALUE),
66

67
   // V_ASSIGN
68
   (I_TARGET | I_VALUE | I_IDENT | I_DELAY | I_PARAMS),
69

70
   // V_DIMENSION
71
   (I_SUBKIND | I_LEFT | I_RIGHT),
72

73
   // V_IF
74
   (I_CONDS),
75

76
   // V_COND
77
   (I_VALUE | I_STMTS),
78

79
   // V_VAR_DECL
80
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
81

82
   // V_DELAY_CONTROL
83
   (I_VALUE),
84

85
   // V_BINARY
86
   (I_LEFT | I_RIGHT | I_SUBKIND),
87

88
   // V_BASSIGN
89
   (I_TARGET | I_VALUE | I_DELAY),
90

91
   // V_UNARY
92
   (I_VALUE | I_SUBKIND),
93

94
   // V_GATE_INST
95
   (I_SUBKIND | I_PARAMS | I_IDENT | I_REF | I_TARGET),
96

97
   // V_STRENGTH
98
   (I_SUBKIND),
99

100
   // V_MOD_INST
101
   (I_IDENT | I_PARAMS),
102

103
   // V_BIT_SELECT
104
   (I_VALUE | I_PARAMS),
105

106
   // V_SYS_FCALL
107
   (I_IDENT | I_PARAMS | I_SUBKIND),
108

109
   // V_FOREVER
110
   (I_STMTS),
111

112
   // V_SPECIFY
113
   (I_DECLS),
114

115
   // V_PRIMITIVE
116
   (I_IDENT | I_IDENT2 | I_PORTS | I_DECLS | I_STMTS),
117

118
   // V_UDP_TABLE
119
   (I_IDENT | I_PARAMS | I_SUBKIND | I_STMTS),
120

121
   // V_UDP_ENTRY
122
   (I_PARAMS),
123

124
   // V_DATA_TYPE
125
   (I_SUBKIND | I_RANGES | I_FLAGS),
126

127
   // V_TYPE_DECL
128
   (I_IDENT | I_TYPE),
129

130
   // V_ENUM_DECL
131
   (I_IDENT | I_TYPE | I_RANGES | I_DECLS),
132

133
   // V_ENUM_NAME
134
   (I_IDENT | I_TYPE | I_VALUE),
135

136
   // V_UNION_DECL
137
   (I_IDENT | I_DECLS | I_FLAGS),
138

139
   // V_STRUCT_DECL
140
   (I_IDENT | I_DECLS | I_FLAGS),
141

142
   // V_EVENT_CONTROL
143
   (I_PARAMS),
144

145
   // V_EMPTY
146
   (0),
147

148
   // V_REPEAT
149
   (I_VALUE | I_STMTS),
150

151
   // V_WHILE
152
   (I_VALUE | I_STMTS),
153

154
   // V_DO_WHILE
155
   (I_VALUE | I_STMTS),
156

157
   // V_TASK_DECL
158
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_PORTS),
159

160
   // V_FUNC_DECL
161
   (I_IDENT | I_IDENT2 | I_STMTS | I_DECLS | I_TYPE | I_PORTS | I_FLAGS),
162

163
   // V_WAIT
164
   (I_VALUE | I_STMTS),
165

166
   // V_PARAM_DECL
167
   (I_IDENT | I_VALUE | I_TYPE),
168

169
   // V_COND_EXPR
170
   (I_VALUE | I_LEFT | I_RIGHT),
171

172
   // V_REAL
173
   (I_DVAL),
174

175
   // V_CONCAT
176
   (I_PARAMS | I_VALUE),
177

178
   // V_FOR_LOOP
179
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
180

181
   // V_FOR_INIT
182
   (I_DECLS | I_STMTS),
183

184
   // V_FOR_STEP
185
   (I_STMTS),
186

187
   // V_PREFIX
188
   (I_TARGET | I_SUBKIND),
189

190
   // V_POSTFIX
191
   (I_TARGET | I_SUBKIND),
192

193
   // V_LOCALPARAM
194
   (I_IDENT | I_VALUE | I_TYPE),
195

196
   // V_CASE
197
   (I_SUBKIND | I_VALUE | I_STMTS),
198

199
   // V_CASE_ITEM
200
   (I_PARAMS | I_STMTS),
201

202
   // V_INST_LIST
203
   (I_PARAMS | I_STMTS | I_IDENT),
204

205
   // V_PARAM_ASSIGN
206
   (I_IDENT | I_VALUE),
207

208
   // V_INST_BODY
209
   (I_IDENT | I_IDENT2 | I_PORTS | I_STMTS | I_DECLS),
210

211
   // V_PORT_CONN
212
   (I_IDENT | I_VALUE),
213

214
   // V_PART_SELECT
215
   (I_SUBKIND | I_VALUE | I_LEFT | I_RIGHT),
216

217
   // V_IF_GENERATE
218
   (I_CONDS),
219

220
   // V_EVENT_TRIGGER
221
   (I_IDENT),
222

223
   // V_USER_FCALL
224
   (I_IDENT | I_REF | I_PARAMS),
225

226
   // V_UDP_LEVEL
227
   (I_SUBKIND | I_IVAL),
228

229
   // V_UDP_EDGE
230
   (I_SUBKIND | I_LEFT | I_RIGHT),
231

232
   // V_SPECPARAM
233
   (I_IDENT | I_VALUE),
234

235
   // V_FORK
236
   (I_IDENT | I_DECLS | I_STMTS),
237

238
   // V_ATTR_INST
239
   (0),
240

241
   // V_USER_TCALL
242
   (I_IDENT | I_REF | I_PARAMS),
243

244
   // V_VOID_CALL
245
   (I_VALUE),
246

247
   // V_GENVAR_DECL
248
   (I_IDENT | I_TYPE),
249

250
   // V_FOR_GENERATE
251
   (I_LEFT | I_VALUE | I_RIGHT | I_STMTS),
252

253
   // V_DEASSIGN
254
   (I_TARGET),
255

256
   // V_FORCE
257
   (I_TARGET | I_VALUE),
258

259
   // V_RELEASE
260
   (I_TARGET | I_VALUE),
261

262
   // V_DISABLE
263
   (I_IDENT),
264

265
   // V_HIER_REF
266
   (I_IDENT | I_IDENT2 | I_REF),
267

268
   // V_TF_PORT_DECL
269
   (I_IDENT | I_SUBKIND | I_RANGES | I_TYPE | I_VALUE | I_REF),
270

271
   // V_RETURN
272
   (I_REF | I_VALUE),
273

274
   // V_OP_ASSIGN
275
   (I_TARGET | I_SUBKIND | I_VALUE),
276

277
   // V_MEMBER_REF
278
   (I_VALUE | I_IDENT | I_REF),
279

280
   // V_PACKAGE
281
   (I_DECLS | I_IDENT | I_IDENT2),
282

283
   // V_MIN_TYP_MAX
284
   (I_LEFT | I_VALUE | I_RIGHT),
285

286
   // V_PROGRAM
287
   (I_IDENT | I_STMTS | I_DECLS | I_IDENT2),
288

289
   // V_CLASS_DECL
290
   (I_IDENT | I_IDENT2 | I_DECLS),
291

292
   // V_NULL
293
   (I_TYPE),
294

295
   // V_CLASS_NEW
296
   (I_TYPE | I_PARAMS),
297

298
   // V_DYNAMIC_NEW
299
   (I_TYPE | I_VALUE),
300

301
   // V_CONSTRUCTOR
302
   (I_IDENT | I_PARAMS | I_STMTS | I_DECLS),
303

304
   // V_SUPER_CALL
305
   (I_PARAMS),
306

307
   // V_IMPORT_DECL
308
   (I_REF | I_IDENT),
309

310
   // V_NAMESPACE
311
   (I_DECLS | I_IDENT),
312

313
   // V_DEFPARAM
314
   (I_TARGET | I_VALUE),
315

316
   // V_PORT_MAP
317
   (I_REF | I_VALUE),
318

319
   // V_FINAL
320
   (I_IDENT | I_STMTS),
321

322
   // V_LOCAL_DECL
323
   (I_IDENT | I_TYPE | I_RANGES | I_VALUE),
324

325
   // V_GEN_BLOCK
326
   (I_IDENT | I_DECLS | I_STMTS),
327
};
328

329
static const char *kind_text_map[V_LAST_NODE_KIND] = {
330
   "V_MODULE",        "V_PORT_DECL",   "V_REF",           "V_ALWAYS",
331
   "V_TIMING",        "V_NBASSIGN",    "V_EVENT",         "V_INITIAL",
332
   "V_SEQ_BLOCK",     "V_SYS_TCALL",   "V_STRING",        "V_NUMBER",
333
   "V_NET_DECL",      "V_ASSIGN",      "V_DIMENSION",     "V_IF",
334
   "V_COND",          "V_VAR_DECL",    "V_DELAY_CONTROL", "V_BINARY",
335
   "V_BASSIGN",       "V_UNARY",       "V_GATE_INST",     "V_STRENGTH",
336
   "V_MOD_INST",      "V_BIT_SELECT",  "V_SYS_FCALL",     "V_FOREVER",
337
   "V_SPECIFY",       "V_PRIMITIVE",   "V_UDP_TABLE",     "V_UDP_ENTRY",
338
   "V_DATA_TYPE",     "V_TYPE_DECL",   "V_ENUM_DECL",     "V_ENUM_NAME",
339
   "V_UNION_DECL",    "V_STRUCT_DECL", "V_EVENT_CONTROL", "V_EMPTY",
340
   "V_REPEAT",        "V_WHILE",       "V_DO_WHILE",      "V_TASK_DECL",
341
   "V_FUNC_DECL",     "V_WAIT",        "V_PARAM_DECL",    "V_COND_EXPR",
342
   "V_REAL",          "V_CONCAT",      "V_FOR_LOOP",      "V_FOR_INIT",
343
   "V_FOR_STEP",      "V_PREFIX",      "V_POSTFIX",       "V_LOCALPARAM",
344
   "V_CASE",          "V_CASE_ITEM",   "V_INST_LIST",     "V_PARAM_ASSIGN",
345
   "V_INST_BODY",     "V_PORT_CONN",   "V_PART_SELECT",   "V_IF_GENERATE",
346
   "V_EVENT_TRIGGER", "V_USER_FCALL",  "V_UDP_LEVEL",     "V_UDP_EDGE",
347
   "V_SPECPARAM",     "V_FORK",        "V_ATTR_INST",     "V_USER_TCALL",
348
   "V_VOID_CALL",     "V_GENVAR_DECL", "V_FOR_GENERATE",  "V_DEASSIGN",
349
   "V_FORCE",         "V_RELEASE",     "V_DISABLE",       "V_HIER_REF",
350
   "V_TF_PORT_DECL",  "V_RETURN",      "V_OP_ASSIGN",     "V_MEMBER_REF",
351
   "V_PACKAGE",       "V_MIN_TYP_MAX", "V_PROGRAM",       "V_CLASS_DECL",
352
   "V_NULL",          "V_CLASS_NEW",   "V_DYNAMIC_NEW",   "V_CONSTRUCTOR",
353
   "V_SUPER_CALL",    "V_IMPORT_DECL", "V_NAMESPACE",     "V_DEFPARAM",
354
   "V_PORT_MAP",      "V_FINAL",       "V_LOCAL_DECL",    "V_GEN_BLOCK",
355
};
356

357
static const change_allowed_t change_allowed[] = {
358
   { -1, -1 }
359
};
360

361
object_class_t vlog_object = {
362
   .name           = "vlog",
363
   .change_allowed = change_allowed,
364
   .has_map        = has_map,
365
   .kind_text_map  = kind_text_map,
366
   .tag            = OBJECT_TAG_VLOG,
367
   .last_kind      = V_LAST_NODE_KIND,
368
   .has_loc        = true,
369
   .gc_roots       = { V_MODULE, V_PRIMITIVE, V_PROGRAM, V_PACKAGE,
370
                       V_NAMESPACE },
371
   .gc_num_roots   = 5,
372
};
373

374
struct _vlog_node {
375
   object_t object;
376
};
377

378
static inline vlog_node_t vlog_array_nth(item_t *item, unsigned n)
264,770✔
379
{
380
   object_t *o = obj_array_nth(item->obj_array, n);
264,770✔
381
   return container_of(o, struct _vlog_node, object);
264,770✔
382
}
383

384
static inline void vlog_array_add(item_t *item, vlog_node_t v)
80,294✔
385
{
386
   obj_array_add(&(item->obj_array), &(v->object));
80,294✔
387
}
80,294✔
388

389
vlog_node_t vlog_new(vlog_kind_t kind)
221,706✔
390
{
391
   object_t *o = object_new(NULL, &vlog_object, kind);
221,706✔
392
   return container_of(o, struct _vlog_node, object);
221,706✔
393
}
394

395
vlog_kind_t vlog_kind(vlog_node_t v)
1,927,413✔
396
{
397
   return v->object.kind;
1,927,413✔
398
}
399

UNCOV
400
const char *vlog_kind_str(vlog_kind_t kind)
×
401
{
UNCOV
402
   return kind_text_map[kind];
×
403
}
404

405
ident_t vlog_ident(vlog_node_t v)
146,780✔
406
{
407
   item_t *item = lookup_item(&vlog_object, v, I_IDENT);
146,780✔
408
   assert(item->ident != NULL);
146,780✔
409
   return item->ident;
146,780✔
410
}
411

412
void vlog_set_ident(vlog_node_t v, ident_t i)
73,015✔
413
{
414
   lookup_item(&vlog_object, v, I_IDENT)->ident = i;
73,015✔
415
}
73,015✔
416

417
bool vlog_has_ident(vlog_node_t v)
1,487✔
418
{
419
   return lookup_item(&vlog_object, v, I_IDENT)->ident != NULL;
1,487✔
420
}
421

422
ident_t vlog_ident2(vlog_node_t v)
3,788✔
423
{
424
   item_t *item = lookup_item(&vlog_object, v, I_IDENT2);
3,788✔
425
   assert(item->ident != NULL);
3,788✔
426
   return item->ident;
3,788✔
427
}
428

429
bool vlog_has_ident2(vlog_node_t v)
1✔
430
{
431
   return lookup_item(&vlog_object, v, I_IDENT2)->ident != NULL;
1✔
432
}
433

434
void vlog_set_ident2(vlog_node_t v, ident_t i)
3,142✔
435
{
436
   lookup_item(&vlog_object, v, I_IDENT2)->ident = i;
3,142✔
437
}
3,142✔
438

439
const loc_t *vlog_loc(vlog_node_t v)
259,944✔
440
{
441
   assert(v != NULL);
259,944✔
442
   return &(v->object.loc);
259,944✔
443
}
444

445
void vlog_set_loc(vlog_node_t v, const loc_t *loc)
236,488✔
446
{
447
   assert(v != NULL);
236,488✔
448
   assert(loc != NULL);
236,488✔
449
   v->object.loc = *loc;
236,488✔
450
}
236,488✔
451

452
vlog_node_t vlog_ref(vlog_node_t v)
239,593✔
453
{
454
   item_t *item = lookup_item(&vlog_object, v, I_REF);
239,593✔
455
   assert(item->object != NULL);
239,593✔
456
   return container_of(item->object, struct _vlog_node, object);
239,593✔
457
}
458

459
bool vlog_has_ref(vlog_node_t v)
60,271✔
460
{
461
   return lookup_item(&vlog_object, v, I_REF)->object != NULL;
60,271✔
462
}
463

464
void vlog_set_ref(vlog_node_t v, vlog_node_t d)
48,502✔
465
{
466
   object_t *d_obj = vlog_to_object(d);
48,502✔
467
   lookup_item(&vlog_object, v, I_REF)->object = d_obj;
48,502✔
468
   object_write_barrier(&(v->object), d_obj);
48,502✔
469
}
48,502✔
470

471
unsigned vlog_stmts(vlog_node_t v)
32,604✔
472
{
473
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
32,604✔
474
   return obj_array_count(item->obj_array);
32,604✔
475
}
476

477
vlog_node_t vlog_stmt(vlog_node_t v, unsigned n)
73,158✔
478
{
479
   item_t *item = lookup_item(&vlog_object, v, I_STMTS);
73,158✔
480
   return vlog_array_nth(item, n);
73,158✔
481
}
482

483
void vlog_add_stmt(vlog_node_t v, vlog_node_t s)
35,813✔
484
{
485
   assert(s != NULL);
35,813✔
486
   vlog_array_add(lookup_item(&vlog_object, v, I_STMTS), s);
35,813✔
487
   object_write_barrier(&(v->object), &(s->object));
35,813✔
488
}
35,813✔
489

490
unsigned vlog_ports(vlog_node_t v)
10,551✔
491
{
492
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
10,551✔
493
   return obj_array_count(item->obj_array);
10,551✔
494
}
495

496
vlog_node_t vlog_port(vlog_node_t v, unsigned n)
15,530✔
497
{
498
   item_t *item = lookup_item(&vlog_object, v, I_PORTS);
15,530✔
499
   return vlog_array_nth(item, n);
15,530✔
500
}
501

502
void vlog_add_port(vlog_node_t v, vlog_node_t p)
1,701✔
503
{
504
   assert(p != NULL);
1,701✔
505
   assert(p->object.kind == V_REF || p->object.kind == V_PORT_DECL
1,701✔
506
          || p->object.kind == V_TF_PORT_DECL);
507
   vlog_array_add(lookup_item(&vlog_object, v, I_PORTS), p);
1,701✔
508
   object_write_barrier(&(v->object), &(p->object));
1,701✔
509
}
1,701✔
510

511
unsigned vlog_params(vlog_node_t v)
43,993✔
512
{
513
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
43,993✔
514
   return obj_array_count(item->obj_array);
43,993✔
515
}
516

517
vlog_node_t vlog_param(vlog_node_t v, unsigned n)
53,015✔
518
{
519
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
53,015✔
520
   return vlog_array_nth(item, n);
53,015✔
521
}
522

523
void vlog_add_param(vlog_node_t v, vlog_node_t p)
19,029✔
524
{
525
   assert(p != NULL);
19,029✔
526
   vlog_array_add(lookup_item(&vlog_object, v, I_PARAMS), p);
19,029✔
527
   object_write_barrier(&(v->object), &(p->object));
19,029✔
528
}
19,029✔
529

530
void vlog_set_param(vlog_node_t v, unsigned n, vlog_node_t p)
×
531
{
532
   assert(p != NULL);
×
533
   item_t *item = lookup_item(&vlog_object, v, I_PARAMS);
×
534
   assert(n < obj_array_count(item->obj_array));
×
UNCOV
535
   item->obj_array->items[n] = vlog_to_object(p);
×
UNCOV
536
   object_write_barrier(&(v->object), &(p->object));
×
UNCOV
537
}
×
538

539
unsigned vlog_ranges(vlog_node_t v)
80,899✔
540
{
541
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
80,899✔
542
   return obj_array_count(item->obj_array);
80,899✔
543
}
544

545
vlog_node_t vlog_range(vlog_node_t v, unsigned n)
47,433✔
546
{
547
   item_t *item = lookup_item(&vlog_object, v, I_RANGES);
47,433✔
548
   return vlog_array_nth(item, n);
47,433✔
549
}
550

551
void vlog_add_range(vlog_node_t v, vlog_node_t r)
5,064✔
552
{
553
   assert(r != NULL);
5,064✔
554
   assert(r->object.kind == V_DIMENSION);
5,064✔
555
   vlog_array_add(lookup_item(&vlog_object, v, I_RANGES), r);
5,064✔
556
   object_write_barrier(&(v->object), &(r->object));
5,064✔
557
}
5,064✔
558

559
unsigned vlog_decls(vlog_node_t v)
16,013✔
560
{
561
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
16,013✔
562
   return obj_array_count(item->obj_array);
16,013✔
563
}
564

565
vlog_node_t vlog_decl(vlog_node_t v, unsigned n)
69,086✔
566
{
567
   item_t *item = lookup_item(&vlog_object, v, I_DECLS);
69,086✔
568
   return vlog_array_nth(item, n);
69,086✔
569
}
570

571
void vlog_add_decl(vlog_node_t v, vlog_node_t d)
15,422✔
572
{
573
   assert(d != NULL);
15,422✔
574
   vlog_array_add(lookup_item(&vlog_object, v, I_DECLS), d);
15,422✔
575
   object_write_barrier(&(v->object), &(d->object));
15,422✔
576
}
15,422✔
577

578
unsigned vlog_conds(vlog_node_t v)
5,549✔
579
{
580
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
5,549✔
581
   return obj_array_count(item->obj_array);
5,549✔
582
}
583

584
vlog_node_t vlog_cond(vlog_node_t v, unsigned n)
6,548✔
585
{
586
   item_t *item = lookup_item(&vlog_object, v, I_CONDS);
6,548✔
587
   return vlog_array_nth(item, n);
6,548✔
588
}
589

590
void vlog_add_cond(vlog_node_t v, vlog_node_t c)
3,265✔
591
{
592
   assert(c != NULL && c->object.kind == V_COND);
3,265✔
593
   vlog_array_add(lookup_item(&vlog_object, v, I_CONDS), c);
3,265✔
594
   object_write_barrier(&(v->object), &(c->object));
3,265✔
595
}
3,265✔
596

597
unsigned vlog_subkind(vlog_node_t v)
280,220✔
598
{
599
   return lookup_item(&vlog_object, v, I_SUBKIND)->ival;
280,220✔
600
}
601

602
void vlog_set_subkind(vlog_node_t v, unsigned sub)
69,586✔
603
{
604
   lookup_item(&vlog_object, v, I_SUBKIND)->ival = sub;
69,586✔
605
}
69,586✔
606

607
vlog_node_t vlog_value(vlog_node_t v)
118,151✔
608
{
609
   item_t *item = lookup_item(&vlog_object, v, I_VALUE);
118,151✔
610
   assert(item->object != NULL);
118,151✔
611
   return container_of(item->object, struct _vlog_node, object);
118,151✔
612
}
613

614
bool vlog_has_value(vlog_node_t v)
25,828✔
615
{
616
   return lookup_item(&vlog_object, v, I_VALUE)->object != NULL;
25,828✔
617
}
618

619
void vlog_set_value(vlog_node_t v, vlog_node_t e)
42,579✔
620
{
621
   lookup_item(&vlog_object, v, I_VALUE)->object = &(e->object);
42,579✔
622
   object_write_barrier(&(v->object), &(e->object));
42,579✔
623
}
42,579✔
624

625
vlog_node_t vlog_target(vlog_node_t v)
25,696✔
626
{
627
   item_t *item = lookup_item(&vlog_object, v, I_TARGET);
25,696✔
628
   assert(item->object != NULL);
25,696✔
629
   return container_of(item->object, struct _vlog_node, object);
25,696✔
630
}
631

632
void vlog_set_target(vlog_node_t v, vlog_node_t e)
12,646✔
633
{
634
   lookup_item(&vlog_object, v, I_TARGET)->object = &(e->object);
12,646✔
635
   object_write_barrier(&(v->object), &(e->object));
12,646✔
636
}
12,646✔
637

638
vlog_node_t vlog_delay(vlog_node_t v)
78✔
639
{
640
   item_t *item = lookup_item(&vlog_object, v, I_DELAY);
78✔
641
   assert(item->object != NULL);
78✔
642
   return container_of(item->object, struct _vlog_node, object);
78✔
643
}
644

645
bool vlog_has_delay(vlog_node_t v)
12,211✔
646
{
647
   return lookup_item(&vlog_object, v, I_DELAY)->object != NULL;
12,211✔
648
}
649

650
void vlog_set_delay(vlog_node_t v, vlog_node_t d)
762✔
651
{
652
   object_t *d_obj = vlog_to_object(d);
762✔
653
   lookup_item(&vlog_object, v, I_DELAY)->object = d_obj;
762✔
654
   object_write_barrier(&(v->object), d_obj);
762✔
655
}
762✔
656

657
vlog_node_t vlog_type(vlog_node_t v)
147,580✔
658
{
659
   item_t *item = lookup_item(&vlog_object, v, I_TYPE);
147,580✔
660
   assert(item->object != NULL);
147,580✔
661
   return container_of(item->object, struct _vlog_node, object);
147,580✔
662
}
663

664
bool vlog_has_type(vlog_node_t v)
1✔
665
{
666
   return lookup_item(&vlog_object, v, I_TYPE)->object != NULL;
1✔
667
}
668

669
void vlog_set_type(vlog_node_t v, vlog_node_t t)
9,037✔
670
{
671
   object_t *t_obj = vlog_to_object(t);
9,037✔
672
   lookup_item(&vlog_object, v, I_TYPE)->object = t_obj;
9,037✔
673
   object_write_barrier(&(v->object), t_obj);
9,037✔
674
}
9,037✔
675

676
number_t vlog_number(vlog_node_t v)
175,223✔
677
{
678
   return lookup_item(&vlog_object, v, I_NUMBER)->number;
175,223✔
679
}
680

681
void vlog_set_number(vlog_node_t v, number_t n)
58,979✔
682
{
683
   lookup_item(&vlog_object, v, I_NUMBER)->number = n;
58,979✔
684
}
58,979✔
685

686
vlog_node_t vlog_left(vlog_node_t v)
168,467✔
687
{
688
   item_t *item = lookup_item(&vlog_object, v, I_LEFT);
168,467✔
689
   assert(item->object != NULL);
168,467✔
690
   return container_of(item->object, struct _vlog_node, object);
168,467✔
691
}
692

693
void vlog_set_left(vlog_node_t v, vlog_node_t e)
40,133✔
694
{
695
   lookup_item(&vlog_object, v, I_LEFT)->object = &(e->object);
40,133✔
696
   object_write_barrier(&(v->object), &(e->object));
40,133✔
697
}
40,133✔
698

699
vlog_node_t vlog_right(vlog_node_t v)
169,835✔
700
{
701
   item_t *item = lookup_item(&vlog_object, v, I_RIGHT);
169,835✔
702
   assert(item->object != NULL);
169,835✔
703
   return container_of(item->object, struct _vlog_node, object);
169,835✔
704
}
705

706
void vlog_set_right(vlog_node_t v, vlog_node_t e)
40,125✔
707
{
708
   lookup_item(&vlog_object, v, I_RIGHT)->object = &(e->object);
40,125✔
709
   object_write_barrier(&(v->object), &(e->object));
40,125✔
710
}
40,125✔
711

712
double vlog_dval(vlog_node_t v)
782✔
713
{
714
   return lookup_item(&vlog_object, v, I_DVAL)->dval;
782✔
715
}
716

717
void vlog_set_dval(vlog_node_t v, double d)
523✔
718
{
719
   lookup_item(&vlog_object, v, I_DVAL)->dval = d;
523✔
720
}
523✔
721

722
int64_t vlog_ival(vlog_node_t v)
780✔
723
{
724
   return lookup_item(&vlog_object, v, I_IVAL)->ival;
780✔
725
}
726

727
void vlog_set_ival(vlog_node_t v, int64_t i)
729✔
728
{
729
   lookup_item(&vlog_object, v, I_IVAL)->ival = i;
729✔
730
}
729✔
731

732
vlog_flags_t vlog_flags(vlog_node_t t)
31,099✔
733
{
734
   return lookup_item(&vlog_object, t, I_FLAGS)->ival;
31,099✔
735
}
736

737
void vlog_set_flags(vlog_node_t v, vlog_flags_t mask)
1,081✔
738
{
739
   lookup_item(&vlog_object, v, I_FLAGS)->ival |= mask;
1,081✔
740
}
1,081✔
741

742
void vlog_clear_flags(vlog_node_t v, vlog_flags_t mask)
34✔
743
{
744
   lookup_item(&vlog_object, v, I_FLAGS)->ival &= ~mask;
34✔
745
}
34✔
746

747
void vlog_visit(vlog_node_t v, vlog_visit_fn_t fn, void *context)
195✔
748
{
749
   vlog_visit_only(v, fn, context, V_LAST_NODE_KIND);
195✔
750
}
195✔
751

752
void vlog_visit_only(vlog_node_t v, vlog_visit_fn_t fn, void *context,
195✔
753
                     vlog_kind_t kind)
754
{
755
   assert(v != NULL);
195✔
756

757
   object_visit_ctx_t ctx = {
195✔
758
      .count      = 0,
759
      .postorder  = (object_visit_fn_t)fn,
760
      .preorder   = NULL,
761
      .context    = context,
762
      .kind       = kind,
763
      .tag        = OBJECT_TAG_VLOG,
764
      .generation = object_next_generation(),
195✔
765
      .deep       = false
766
   };
767

768
   object_visit(&(v->object), &ctx);
195✔
769
}
195✔
770
vlog_node_t vlog_rewrite(vlog_node_t v, vlog_rewrite_pre_fn_t pre_fn,
4,346✔
771
                         vlog_rewrite_post_fn_t post_fn, void *context)
772
{
773
   object_arena_t *arena = object_arena(&(v->object));
4,346✔
774
   if (arena_frozen(arena))
4,346✔
775
      return v;
776

777
   object_rewrite_ctx_t ctx = {
4,346✔
778
      .generation = object_next_generation(),
4,346✔
779
      .context    = context,
780
      .arena      = arena,
781
   };
782

783
   ctx.pre_fn[OBJECT_TAG_VLOG] = (object_rewrite_pre_fn_t)pre_fn;
4,346✔
784
   ctx.post_fn[OBJECT_TAG_VLOG] = (object_rewrite_post_fn_t)post_fn;
4,346✔
785

786
   object_t *result = object_rewrite(&(v->object), &ctx);
4,346✔
787
   free(ctx.cache);
4,346✔
788
   return container_of(result, struct _vlog_node, object);
4,346✔
789
}
790

791
vlog_node_t vlog_copy(vlog_node_t v, vlog_copy_pred_t pred, void *ctx)
1,179✔
792
{
793
   object_copy_ctx_t *copy LOCAL = xcalloc_flex(sizeof(object_copy_ctx_t),
1,179✔
794
                                                1, sizeof(object_t *));
795
   copy->generation   = object_next_generation();
1,179✔
796
   copy->pred_context = ctx;
1,179✔
797
   copy->nroots       = 1;
1,179✔
798
   copy->roots[0]     = &(v->object);
1,179✔
799

800
   copy->should_copy[OBJECT_TAG_VLOG] = (object_copy_pred_t)pred;
1,179✔
801

802
   object_copy_begin(copy);
1,179✔
803
   object_copy_finish(copy);
1,179✔
804

805
   return container_of(copy->roots[0], struct _vlog_node, object);
1,179✔
806
}
807

808
object_t *vlog_to_object(vlog_node_t v)
75,443✔
809
{
810
   return v != NULL ? &(v->object) : NULL;
75,443✔
811
}
812

813
vlog_node_t vlog_from_object(object_t *obj)
24,129✔
814
{
815
   if (obj != NULL && obj->tag == OBJECT_TAG_VLOG)
24,129✔
816
      return container_of(obj, struct _vlog_node, object);
817
   else
818
      return NULL;
15,904✔
819
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc