Coverage Report

Created: 2026-10-17 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm3/source/m3_function.c
Line
Count
Source
1
//
2
//  m3_function.c
3
//
4
//  Created by Steven Massey on 4/7/21.
5
//  Copyright © 2021 Steven Massey. All rights reserved.
6
//
7
8
#include "m3_function.h"
9
#include "m3_env.h"
10
11
12
M3Result AllocFuncType (IM3FuncType* o_functionType, u32 i_numTypes)
13
338k
{
14
338k
    *o_functionType = (IM3FuncType)m3_Malloc("M3FuncType", sizeof(M3FuncType) + i_numTypes * sizeof(m3type_t));
15
338k
    if (*o_functionType) {
16
338k
        (*o_functionType)->isContinuation = false;
17
338k
        (*o_functionType)->contFuncType   = NULL;
18
338k
        (*o_functionType)->inRecGroup     = false;
19
338k
        return m3Err_none;
20
338k
    }
21
0
    return m3Err_mallocFailed;
22
338k
}
23
24
25
#if d_m3HasTypedRefs
26
27
// The type a (ref $t) / (ref null $t) naming this function type is spelled as
28
m3type_t RefTypeOfFuncType (const IM3FuncType i_funcType, bool i_nonNull)
29
345
{
30
345
    m3type_t type = d_m3Type_ref | (i_funcType ? i_funcType->canonicalIndex : d_m3Type_heapAbstract);
31
32
345
    if (i_funcType and i_funcType->isContinuation) {
33
0
        type |= d_m3Type_refCont;
34
0
    }
35
36
345
    if (i_nonNull) {
37
265
        type |= d_m3Type_refNonNull;
38
265
    }
39
40
345
    return type;
41
345
}
42
43
#endif // d_m3HasTypedRefs
44
45
46
bool AreFuncTypesEqual (const IM3FuncType i_typeA, const IM3FuncType i_typeB)
47
1.46M
{
48
1.46M
    if (i_typeA->isContinuation != i_typeB->isContinuation) {
49
1.08k
        return false;
50
1.08k
    }
51
1.46M
    if (i_typeA->isContinuation) {
52
436
        return (i_typeA->contFuncType == i_typeB->contFuncType) or
53
145
               (i_typeA->contFuncType and i_typeB->contFuncType and
54
145
                AreFuncTypesEqual(i_typeA->contFuncType, i_typeB->contFuncType));
55
436
    }
56
1.46M
    if (i_typeA->numRets == i_typeB->numRets and i_typeA->numArgs == i_typeB->numArgs) {
57
967k
        return (memcmp(i_typeA->types, i_typeB->types,
58
967k
                       (i_typeA->numRets + i_typeA->numArgs) * sizeof(m3type_t)) == 0);
59
967k
    }
60
61
499k
    return false;
62
1.46M
}
63
64
u16 GetFuncTypeNumParams (const IM3FuncType i_funcType)
65
31.8k
{
66
31.8k
    return i_funcType ? i_funcType->numArgs : 0;
67
31.8k
}
68
69
70
m3type_t GetFuncTypeParamType (const IM3FuncType i_funcType, u16 i_index)
71
17.9k
{
72
17.9k
    m3type_t type = c_m3Type_unknown;
73
74
17.9k
    if (i_funcType) {
75
17.9k
        if (i_index < i_funcType->numArgs) {
76
17.9k
            type = i_funcType->types[i_funcType->numRets + i_index];
77
17.9k
        }
78
17.9k
    }
79
80
17.9k
    return type;
81
17.9k
}
82
83
84
u16 GetFuncTypeNumResults (const IM3FuncType i_funcType)
85
123k
{
86
123k
    return i_funcType ? i_funcType->numRets : 0;
87
123k
}
88
89
90
m3type_t GetFuncTypeResultType (const IM3FuncType i_funcType, u16 i_index)
91
38.8k
{
92
38.8k
    m3type_t type = c_m3Type_unknown;
93
94
38.8k
    if (i_funcType) {
95
38.8k
        if (i_index < i_funcType->numRets) {
96
38.8k
            type = i_funcType->types[i_index];
97
38.8k
        }
98
38.8k
    }
99
100
38.8k
    return type;
101
38.8k
}
102
103
104
//---------------------------------------------------------------------------------------------------------------
105
106
107
void FreeImportInfo (M3ImportInfo* i_info)
108
52.0k
{
109
52.0k
    m3_Free(i_info->moduleUtf8);
110
52.0k
    m3_Free(i_info->fieldUtf8);
111
52.0k
}
112
113
114
#if d_m3HasSnapshots
115
116
void SnapshotMap_Free (M3SnapshotMap* i_map)
117
56.4k
{
118
56.4k
    if (i_map) {
119
0
        m3_Free(i_map->locals);
120
0
        m3_Free(i_map->safePoints);
121
0
        m3_Free(i_map->values);
122
0
        m3_Free(i_map->blocks);
123
0
        m3_Free(i_map);
124
0
    }
125
56.4k
}
126
127
#endif
128
129
void Function_Release (IM3Function i_function)
130
31.7k
{
131
31.7k
    m3_Free(i_function->constants);
132
133
31.7k
#if d_m3HasSnapshots
134
31.7k
    SnapshotMap_Free(i_function->snapshotMap);
135
31.7k
    i_function->snapshotMap = NULL;
136
31.7k
#endif
137
138
62.7k
    for (int i = 0; i < i_function->numNames; i++) {
139
        // name can be an alias of fieldUtf8
140
31.0k
        if (i_function->names[i] != i_function->import.fieldUtf8) {
141
27.5k
            m3_Free(i_function->names[i]);
142
27.5k
        }
143
31.0k
    }
144
145
31.7k
    FreeImportInfo(&i_function->import);
146
147
31.7k
    if (i_function->ownsWasmCode) {
148
0
        m3_Free(i_function->wasm);
149
0
    }
150
151
    // Function_FreeCompiledCode (func);
152
153
#if (d_m3EnableCodePageRefCounting)
154
    {
155
        m3_Free(i_function->codePageRefs);
156
        i_function->numCodePageRefs = 0;
157
    }
158
#endif
159
31.7k
}
160
161
162
void Function_FreeCompiledCode (IM3Function i_function)
163
0
{
164
#if (d_m3EnableCodePageRefCounting)
165
    {
166
        i_function->compiled = NULL;
167
168
        while (i_function->numCodePageRefs--) {
169
            IM3CodePage page = i_function->codePageRefs[i_function->numCodePageRefs];
170
171
            if (--(page->info.usageCount) == 0) {
172
                //                printf ("free %p\n", page);
173
            }
174
        }
175
176
        m3_Free(i_function->codePageRefs);
177
178
        Runtime_ReleaseCodePages(i_function->module->runtime);
179
    }
180
#endif
181
0
}
182
183
184
cstr_t m3_GetFunctionName (IM3Function i_function)
185
1
{
186
1
    u16     numNames = 0;
187
1
    cstr_t* names    = GetFunctionNames(i_function, &numNames);
188
1
    if (numNames > 0) {
189
1
        return names[0];
190
1
    } else {
191
0
        return "<unnamed>";
192
0
    }
193
1
}
194
195
196
IM3Module m3_GetFunctionModule (IM3Function i_function)
197
0
{
198
0
    return i_function ? i_function->module : NULL;
199
0
}
200
201
202
cstr_t* GetFunctionNames (IM3Function i_function, u16* o_numNames)
203
1
{
204
1
    if (!i_function || !o_numNames) {
205
0
        return NULL;
206
0
    }
207
208
1
    if (i_function->import.fieldUtf8) {
209
0
        *o_numNames = 1;
210
0
        return &i_function->import.fieldUtf8;
211
1
    } else {
212
1
        *o_numNames = i_function->numNames;
213
1
        return i_function->names;
214
1
    }
215
1
}
216
217
218
cstr_t GetFunctionImportModuleName (IM3Function i_function)
219
1
{
220
1
    return (i_function->import.moduleUtf8) ? i_function->import.moduleUtf8 : "";
221
1
}
222
223
224
u16 GetFunctionNumArgs (IM3Function i_function)
225
65.9k
{
226
65.9k
    u16 numArgs = 0;
227
228
65.9k
    if (i_function) {
229
65.9k
        if (i_function->funcType) {
230
65.9k
            numArgs = i_function->funcType->numArgs;
231
65.9k
        }
232
65.9k
    }
233
234
65.9k
    return numArgs;
235
65.9k
}
236
237
m3type_t GetFunctionArgType (IM3Function i_function, u32 i_index)
238
3.39k
{
239
3.39k
    m3type_t type = c_m3Type_none;
240
241
3.39k
    if (i_index < GetFunctionNumArgs(i_function)) {
242
3.39k
        u32 numReturns = i_function->funcType->numRets;
243
244
3.39k
        type = i_function->funcType->types[numReturns + i_index];
245
3.39k
    }
246
247
3.39k
    return type;
248
3.39k
}
249
250
251
u16 GetFunctionNumReturns (IM3Function i_function)
252
24.7k
{
253
24.7k
    u16 numReturns = 0;
254
255
24.7k
    if (i_function) {
256
24.7k
        if (i_function->funcType) {
257
24.7k
            numReturns = i_function->funcType->numRets;
258
24.7k
        }
259
24.7k
    }
260
261
24.7k
    return numReturns;
262
24.7k
}
263
264
265
u8 GetFunctionReturnType (const IM3Function i_function, u16 i_index)
266
0
{
267
0
    return i_function ? GetFuncTypeResultType(i_function->funcType, i_index) : c_m3Type_unknown;
268
0
}
269
270
271
u32 GetFunctionNumArgsAndLocals (IM3Function i_function)
272
37.7k
{
273
37.7k
    if (i_function) {
274
37.7k
        return i_function->numLocals + GetFunctionNumArgs(i_function);
275
37.7k
    } else {
276
0
        return 0;
277
0
    }
278
37.7k
}