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

nickg / nvc / 13738584171

08 Mar 2025 12:57PM UTC coverage: 92.236% (-0.05%) from 92.281%
13738584171

push

github

nickg
Add a simple pointer provenance tracking scheme

52 of 53 new or added lines in 3 files covered. (98.11%)

230 existing lines in 7 files now uncovered.

68028 of 73754 relevant lines covered (92.24%)

433200.43 hits per line

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

90.6
/src/mir/mir-unit.c
1
//
2
//  Copyright (C) 2024-2025  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 "hash.h"
20
#include "ident.h"
21
#include "lib.h"
22
#include "object.h"
23
#include "mir/mir-unit.h"
24
#include "mir/mir-node.h"
25
#include "mir/mir-priv.h"
26
#include "mir/mir-structs.h"
27
#include "thread.h"
28

29
#include <assert.h>
30
#include <stdlib.h>
31

32
#define TYPE_TAB_SIZE 256
33

34
mir_context_t *mir_context_new(void)
8,874✔
35
{
36
   mir_context_t *mc = xcalloc(sizeof(mir_context_t));
8,874✔
37
   mc->map  = hash_new(32);
8,874✔
38
   mc->pool = pool_new();
8,874✔
39

40
   type_tab_t *tab =
8,874✔
41
      xcalloc_flex(sizeof(type_tab_t), TYPE_TAB_SIZE, sizeof(type_data_t));
8,874✔
42
   tab->max_types = TYPE_TAB_SIZE;
8,874✔
43
   tab->hashtab = xcalloc_array(TYPE_TAB_SIZE, sizeof(uint32_t));
8,874✔
44

45
   store_release(&mc->resizing, tab);
8,874✔
46
   store_release(&mc->typetab, tab);
8,874✔
47

48
   return mc;
8,874✔
49
}
50

51
void mir_context_free(mir_context_t *mc)
8,854✔
52
{
53
   mir_free_types(mc->typetab);
8,854✔
54
   pool_free(mc->pool);
8,854✔
55
   hash_free(mc->map);
8,854✔
56
   free(mc);
8,854✔
57
}
8,854✔
58

59
mir_unit_t *mir_unit_new(mir_context_t *mc, ident_t name, object_t *object,
42,785✔
60
                         mir_unit_kind_t kind, mir_shape_t *parent)
61
{
62
   mir_unit_t *mu = xcalloc(sizeof(mir_unit_t));
42,785✔
63
   mu->context = mc;
42,785✔
64
   mu->name    = name;
42,785✔
65
   mu->object  = object;
42,785✔
66
   mu->kind    = kind;
42,785✔
67
   mu->parent  = parent;
42,785✔
68
   mu->result  = MIR_NULL_TYPE;
42,785✔
69

70
   mir_block_t entry = mir_add_block(mu);
42,785✔
71
   mir_set_cursor(mu, entry, MIR_APPEND);
42,785✔
72

73
   return mu;
42,785✔
74
}
75

76
mir_unit_kind_t mir_get_kind(mir_unit_t *mu)
250,770✔
77
{
78
   return mu->kind;
250,770✔
79
}
80

81
object_t *mir_get_object(mir_unit_t *mu)
42,732✔
82
{
83
   return mu->object;
42,732✔
84
}
85

86
static mir_shape_t *mir_build_shape(mir_unit_t *mu)
31,482✔
87
{
88
   mir_shape_t *sh = pool_malloc_flex(mu->context->pool, sizeof(mir_shape_t),
62,964✔
89
                                      mu->vars.count, sizeof(shape_slot_t));
31,482✔
90
   sh->name      = mu->name;
31,482✔
91
   sh->kind      = mu->kind;
31,482✔
92
   sh->type      = mir_self_type(mu);
31,482✔
93
   sh->num_slots = mu->vars.count;
31,482✔
94
   sh->parent    = mu->parent;
31,482✔
95

96
   for (int i = 0; i < mu->vars.count; i++) {
80,169✔
97
      const var_data_t *vd = &(mu->vars.items[i]);
48,687✔
98
      sh->slots[i].name    = vd->name;
48,687✔
99
      sh->slots[i].type    = vd->type;
48,687✔
100
      sh->slots[i].pointer = vd->pointer;
48,687✔
101
   }
102

103
   return sh;
31,482✔
104
}
105

106
void mir_unit_free(mir_unit_t *mu)
42,750✔
107
{
108
   if (mu->name != NULL) {
42,750✔
109
      void *ptr = hash_get(mu->context->map, mu->name);
31,464✔
110
      switch (pointer_tag(ptr)) {
31,464✔
111
      case UNIT_GENERATED:
31,447✔
112
         {
113
            mir_shape_t *sh = mu->shape ?: mir_build_shape(mu);
31,447✔
114
            hash_put(mu->context->map, mu->name, tag_pointer(sh, UNIT_FREED));
31,447✔
115
         }
116
         break;
31,447✔
UNCOV
117
      case UNIT_FREED:
×
118
      case UNIT_DEFERRED:
119
         should_not_reach_here();
120
      default:
121
         break;
122
      }
123
   }
124

125
#ifdef DEBUG
126
   if (mu->comments != NULL)
42,750✔
127
      tb_free(mu->comments);
5✔
128
#endif
129

130
   for (int i = 0; i < mu->blocks.count; i++)
177,660✔
131
      free(mu->blocks.items[i].nodes);
134,910✔
132

133
   ACLEAR(mu->blocks);
42,750✔
134
   ACLEAR(mu->params);
42,750✔
135
   ACLEAR(mu->vars);
42,750✔
136
   ACLEAR(mu->stamps);
42,750✔
137
   ACLEAR(mu->linkage);
42,750✔
138

139
   free(mu->nodes);
42,750✔
140
   free(mu->argspill);
42,750✔
141
   free(mu);
42,750✔
142
}
42,750✔
143

144
void mir_put_unit(mir_context_t *mc, mir_unit_t *mu)
31,481✔
145
{
146
   assert(mu->context == mc);
31,481✔
147

148
#ifdef DEBUG
149
   void *ptr = hash_get(mc->map, mu->name);
31,481✔
150
   if (ptr != NULL)
31,481✔
151
      fatal_trace("%s already registered", istr(mu->name));
152
#endif
153

154
   hash_put(mc->map, mu->name, tag_pointer(mu, UNIT_GENERATED));
31,481✔
155
}
31,481✔
156

157
mir_unit_t *mir_get_unit(mir_context_t *mc, ident_t name)
31,447✔
158
{
159
   void *ptr = hash_get(mc->map, name);
31,447✔
160
   if (ptr == NULL)
31,447✔
161
      return NULL;
162

163
   switch (pointer_tag(ptr)) {
82✔
164
   case UNIT_DEFERRED:
1✔
165
      {
166
         deferred_unit_t *du = untag_pointer(ptr, deferred_unit_t);
1✔
167

168
         mir_unit_t *mu =
1✔
169
            mir_unit_new(mc, name, du->object, du->kind, du->parent);
1✔
170
         (*du->fn)(mu, du->object);
1✔
171

172
         hash_put(mc->map, name, tag_pointer(mu, UNIT_GENERATED));
1✔
173
         return mu;
1✔
174
      }
175
   case UNIT_GENERATED:
81✔
176
      return untag_pointer(ptr, mir_unit_t);
81✔
UNCOV
177
   case UNIT_FREED:
×
178
      fatal_trace("unit %s has already been freed", istr(name));
UNCOV
179
   default:
×
180
      should_not_reach_here();
181
   }
182
}
183

184
mir_shape_t *mir_get_shape(mir_context_t *mc, ident_t name)
27,309✔
185
{
186
   void *ptr = hash_get(mc->map, name);
27,309✔
187
   if (ptr == NULL)
27,309✔
188
      return NULL;
189

190
   switch (pointer_tag(ptr)) {
27,193✔
191
   case UNIT_DEFERRED:
×
192
      {
193
         deferred_unit_t *du = untag_pointer(ptr, deferred_unit_t);
×
194

UNCOV
195
         mir_unit_t *mu =
×
UNCOV
196
            mir_unit_new(mc, name, du->object, du->kind, du->parent);
×
UNCOV
197
         (*du->fn)(mu, du->object);
×
198

UNCOV
199
         hash_put(mc->map, name, tag_pointer(mu, UNIT_GENERATED));
×
200

UNCOV
201
         return (mu->shape = mir_build_shape(mu));
×
202
      }
203
   case UNIT_GENERATED:
209✔
204
      {
205
         mir_unit_t *mu = untag_pointer(ptr, mir_unit_t);
209✔
206
         if (mu->shape != NULL)
209✔
207
            return mu->shape;
208

209
         return (mu->shape = mir_build_shape(mu));
127✔
210
      }
211
   case UNIT_FREED:
26,984✔
212
      return untag_pointer(ptr, mir_shape_t);
26,984✔
UNCOV
213
   default:
×
214
      should_not_reach_here();
215
   }
216
}
217

218
void mir_defer(mir_context_t *mc, ident_t name, mir_shape_t *parent,
1✔
219
               mir_unit_kind_t kind, mir_lower_fn_t fn, object_t *object)
220
{
221
#ifdef DEBUG
222
   void *ptr = hash_get(mc->map, name);
1✔
223
   if (ptr != NULL)
1✔
224
      fatal_trace("%s already registered", istr(name));
225
#endif
226

227
   deferred_unit_t *du = pool_malloc(mc->pool, sizeof(deferred_unit_t));
1✔
228
   du->fn     = fn;
1✔
229
   du->parent = parent;
1✔
230
   du->kind   = kind;
1✔
231
   du->object = object;
1✔
232

233
   hash_put(mc->map, name, tag_pointer(du, UNIT_DEFERRED));
1✔
234
}
1✔
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

© 2025 Coveralls, Inc