/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 | } |