Coverage Report

Created: 2025-08-26 06:22

/src/wasm3/source/m3_code.c
Line
Count
Source (jump to first uncovered line)
1
//
2
//  m3_code.c
3
//
4
//  Created by Steven Massey on 4/19/19.
5
//  Copyright © 2019 Steven Massey. All rights reserved.
6
//
7
8
#include <limits.h>
9
#include "m3_code.h"
10
#include "m3_env.h"
11
12
//---------------------------------------------------------------------------------------------------------------------------------
13
14
15
IM3CodePage  NewCodePage  (IM3Runtime i_runtime, u32 i_minNumLines)
16
133
{
17
133
    IM3CodePage page;
18
19
    // check multiplication overflow
20
133
    if (i_minNumLines > UINT_MAX / sizeof (code_t)) {
21
0
        return NULL;
22
0
    }
23
133
    u32 pageSize = sizeof (M3CodePageHeader) + sizeof (code_t) * i_minNumLines;
24
25
    // check addition overflow
26
133
    if (pageSize < sizeof (M3CodePageHeader)) {
27
0
        return NULL;
28
0
    }
29
30
133
    pageSize = (pageSize + (d_m3CodePageAlignSize-1)) & ~(d_m3CodePageAlignSize-1); // align
31
    // check alignment overflow
32
133
    if (pageSize == 0) {
33
0
        return NULL;
34
0
    }
35
36
133
    page = (IM3CodePage)m3_Malloc ("M3CodePage", pageSize);
37
38
133
    if (page)
39
133
    {
40
133
        page->info.sequence = ++i_runtime->newCodePageSequence;
41
133
        page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);
42
43
#if d_m3RecordBacktraces
44
        u32 pageSizeBt = sizeof (M3CodeMappingPage) + sizeof (M3CodeMapEntry) * page->info.numLines;
45
        page->info.mapping = (M3CodeMappingPage *)m3_Malloc ("M3CodeMappingPage", pageSizeBt);
46
47
        if (page->info.mapping)
48
        {
49
            page->info.mapping->size = 0;
50
            page->info.mapping->capacity = page->info.numLines;
51
        }
52
        else
53
        {
54
            m3_Free (page);
55
            return NULL;
56
        }
57
        page->info.mapping->basePC = GetPageStartPC(page);
58
#endif // d_m3RecordBacktraces
59
60
133
        m3log (runtime, "new page: %p; seq: %d; bytes: %d; lines: %d", GetPagePC (page), page->info.sequence, pageSize, page->info.numLines);
61
133
    }
62
63
133
    return page;
64
133
}
65
66
67
void  FreeCodePages  (IM3CodePage * io_list)
68
194
{
69
194
    IM3CodePage page = * io_list;
70
71
319
    while (page)
72
125
    {
73
125
        m3log (code, "free page: %d; %p; util: %3.1f%%", page->info.sequence, page, 100. * page->info.lineIndex / page->info.numLines);
74
75
125
        IM3CodePage next = page->info.next;
76
#if d_m3RecordBacktraces
77
        m3_Free (page->info.mapping);
78
#endif // d_m3RecordBacktraces
79
125
        m3_Free (page);
80
125
        page = next;
81
125
    }
82
83
194
    * io_list = NULL;
84
194
}
85
86
87
u32  NumFreeLines  (IM3CodePage i_page)
88
50.5k
{
89
50.5k
    d_m3Assert (i_page->info.lineIndex <= i_page->info.numLines);
90
91
50.5k
    return i_page->info.numLines - i_page->info.lineIndex;
92
50.5k
}
93
94
95
void  EmitWord_impl  (IM3CodePage i_page, void * i_word)
96
50.7k
{                                                                       d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
97
50.7k
    i_page->code [i_page->info.lineIndex++] = i_word;
98
50.7k
}
99
100
void  EmitWord32  (IM3CodePage i_page, const u32 i_word)
101
91.7k
{                                                                       d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
102
91.7k
    memcpy (& i_page->code[i_page->info.lineIndex++], & i_word, sizeof(i_word));
103
91.7k
}
104
105
void  EmitWord64  (IM3CodePage i_page, const u64 i_word)
106
2.82k
{
107
#if M3_SIZEOF_PTR == 4
108
                                                                        d_m3Assert (i_page->info.lineIndex+2 <= i_page->info.numLines);
109
    memcpy (& i_page->code[i_page->info.lineIndex], & i_word, sizeof(i_word));
110
    i_page->info.lineIndex += 2;
111
#else
112
2.82k
                                                                        d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
113
2.82k
    memcpy (& i_page->code[i_page->info.lineIndex], & i_word, sizeof(i_word));
114
2.82k
    i_page->info.lineIndex += 1;
115
2.82k
#endif
116
2.82k
}
117
118
119
#if d_m3RecordBacktraces
120
void  EmitMappingEntry  (IM3CodePage i_page, u32 i_moduleOffset)
121
{
122
    M3CodeMappingPage * page = i_page->info.mapping;
123
                                                                        d_m3Assert (page->size < page->capacity);
124
125
    M3CodeMapEntry * entry = & page->entries[page->size++];
126
    pc_t pc = GetPagePC (i_page);
127
128
    entry->pcOffset = pc - page->basePC;
129
    entry->moduleOffset = i_moduleOffset;
130
}
131
#endif // d_m3RecordBacktraces
132
133
pc_t  GetPageStartPC  (IM3CodePage i_page)
134
0
{
135
0
    return & i_page->code [0];
136
0
}
137
138
139
pc_t  GetPagePC  (IM3CodePage i_page)
140
3.68k
{
141
3.68k
    if (i_page)
142
3.17k
        return & i_page->code [i_page->info.lineIndex];
143
518
    else
144
518
        return NULL;
145
3.68k
}
146
147
148
void  PushCodePage  (IM3CodePage * i_list, IM3CodePage i_codePage)
149
690
{
150
690
    IM3CodePage next = * i_list;
151
690
    i_codePage->info.next = next;
152
690
    * i_list = i_codePage;
153
690
}
154
155
156
IM3CodePage  PopCodePage  (IM3CodePage * i_list)
157
0
{
158
0
    IM3CodePage page = * i_list;
159
0
    * i_list = page->info.next;
160
0
    page->info.next = NULL;
161
162
0
    return page;
163
0
}
164
165
166
167
u32  FindCodePageEnd  (IM3CodePage i_list, IM3CodePage * o_end)
168
0
{
169
0
    u32 numPages = 0;
170
0
    * o_end = NULL;
171
172
0
    while (i_list)
173
0
    {
174
0
        * o_end = i_list;
175
0
        ++numPages;
176
0
        i_list = i_list->info.next;
177
0
    }
178
179
0
    return numPages;
180
0
}
181
182
183
u32  CountCodePages  (IM3CodePage i_list)
184
0
{
185
0
    IM3CodePage unused;
186
0
    return FindCodePageEnd (i_list, & unused);
187
0
}
188
189
190
IM3CodePage GetEndCodePage  (IM3CodePage i_list)
191
0
{
192
0
    IM3CodePage end;
193
0
    FindCodePageEnd (i_list, & end);
194
195
0
    return end;
196
0
}
197
198
#if d_m3RecordBacktraces
199
bool  ContainsPC  (IM3CodePage i_page, pc_t i_pc)
200
{
201
    return GetPageStartPC (i_page) <= i_pc && i_pc < GetPagePC (i_page);
202
}
203
204
205
bool  MapPCToOffset  (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset)
206
{
207
    M3CodeMappingPage * mapping = i_page->info.mapping;
208
209
    u32 pcOffset = i_pc - mapping->basePC;
210
211
    u32 left = 0;
212
    u32 right = mapping->size;
213
214
    while (left < right)
215
    {
216
        u32 mid = left + (right - left) / 2;
217
218
        if (mapping->entries[mid].pcOffset < pcOffset)
219
        {
220
            left = mid + 1;
221
        }
222
        else if (mapping->entries[mid].pcOffset > pcOffset)
223
        {
224
            right = mid;
225
        }
226
        else
227
        {
228
            *o_moduleOffset = mapping->entries[mid].moduleOffset;
229
            return true;
230
        }
231
    }
232
233
    // Getting here means left is now one more than the element we want.
234
    if (left > 0)
235
    {
236
        left--;
237
        *o_moduleOffset = mapping->entries[left].moduleOffset;
238
        return true;
239
    }
240
    else return false;
241
}
242
#endif // d_m3RecordBacktraces
243
244
//---------------------------------------------------------------------------------------------------------------------------------
245
246