Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <time.h> | ||
2 | #include "gwion_util.h" | ||
3 | #include "gwion_ast.h" | ||
4 | #include "gwion_env.h" | ||
5 | #include "vm.h" | ||
6 | #include "instr.h" | ||
7 | #include "shreduler_private.h" | ||
8 | #include "emit.h" | ||
9 | #include "gwion.h" | ||
10 | #include "object.h" | ||
11 | #include "ugen.h" | ||
12 | #include "operator.h" | ||
13 | #include "import.h" | ||
14 | #include "gack.h" | ||
15 | #include "array.h" | ||
16 | |||
17 | 712 | static inline uint64_t splitmix64_stateless(uint64_t index) { | |
18 | 712 | uint64_t z = (index + UINT64_C(0x9E3779B97F4A7C15)); | |
19 | 712 | z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); | |
20 | 712 | z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB); | |
21 | 712 | return z ^ (z >> 31); | |
22 | } | ||
23 | |||
24 | 117 | static inline uint32_t rotl(const uint32_t x, int k) { | |
25 | 117 | return (x << k) | (x >> (32 - k)); | |
26 | } | ||
27 | |||
28 | 712 | void gw_seed(uint32_t rnd[2], const uint64_t s) { | |
29 | 712 | uint64_t seed = splitmix64_stateless(s); | |
30 | 712 | memcpy(rnd, &seed, sizeof(uint64_t)); | |
31 | 712 | } | |
32 | |||
33 | /*xoroshiro32** */ | ||
34 | 39 | uint32_t gw_rand(uint32_t s[2]) { | |
35 | 39 | const uint32_t s0 = s[0]; | |
36 | 39 | const uint32_t s1 = s[1] ^ s0; | |
37 | 39 | const uint32_t ret = rotl(s0 * 0x9E3779BB, 5) * 5; | |
38 | 39 | s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); | |
39 | 39 | s[1] = rotl(s1, 13); | |
40 | 39 | return ret; | |
41 | } | ||
42 | |||
43 | 8190 | ANN static inline void shred_unwind(const VM_Shred shred) { | |
44 | 8190 | register frame_t *frame = &*(frame_t *)(shred->mem - sizeof(frame_t)); | |
45 | 8190 | shred->code = frame->code; | |
46 | 8190 | shred->pc = frame->pc; | |
47 | 8190 | shred->mem -= frame->push; | |
48 | 8190 | } | |
49 | |||
50 | 18 | ANN static void clean_values(const VM_Shred shred) { | |
51 | 18 | const VM_Code code = shred->code; | |
52 | 18 | const uint16_t pc = shred->pc; | |
53 |
2/2✓ Branch 1 taken 21 times.
✓ Branch 2 taken 12 times.
|
33 | for (m_uint i = m_vector_size(&code->live_values) + 1; --i;) { |
54 | 21 | VMValue *vmval = (VMValue *)m_vector_addr(&code->live_values, i - 1); | |
55 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15 times.
|
21 | if (pc <= vmval->start) break; |
56 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
|
15 | if (pc >= vmval->end) continue; |
57 | 15 | m_bit *const data = &*(m_bit *)(shred->mem + vmval->offset); | |
58 | 15 | compound_release(shred, vmval->t, data); | |
59 | } | ||
60 | 18 | } | |
61 | |||
62 | 3 | ANN static uint16_t find_pc(const VM_Shred shred, const Symbol effect) { | |
63 | 3 | const VM_Code code = shred->code; | |
64 | 3 | const m_uint start = vector_at(&shred->info->frame, vector_size(&shred->info->frame) - 2); | |
65 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (start > shred->pc) return true; |
66 | 3 | const Map m = &shred->code->handlers; | |
67 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | for (m_uint i = 0; i < map_size(m); i++) { |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (start > shred->pc) break; |
69 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | if (start < shred->pc && VKEY(m, i) > shred->pc) { |
70 | 3 | const m_uint next = VKEY(m, i); | |
71 | 3 | const Instr instr = (Instr)vector_at(&code->instr, next); | |
72 |
2/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | if (!instr->m_val2 || (Symbol)instr->m_val2 == effect) |
73 | 3 | return next + 1; | |
74 | } | ||
75 | } | ||
76 | ✗ | return 0; | |
77 | } | ||
78 | |||
79 | 3 | ANN static inline bool find_handle(const VM_Shred shred, const Symbol effect) { | |
80 | 3 | const uint16_t pc = find_pc(shred, effect); | |
81 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (!pc) return false; // outside of a try statement |
82 | 3 | shred->reg = // restore reg | |
83 | 3 | (m_bit *)VPTR(&shred->info->frame, VLEN(&shred->info->frame) - 1); | |
84 | 3 | shredule(shred->tick->shreduler, shred, 0); | |
85 | 3 | shred->pc = pc; // VKEY(m, i); | |
86 | 3 | const Instr instr = (Instr)vector_at(&shred->code->instr, pc); | |
87 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if(!instr->m_val) |
88 | 3 | *(m_str*)(shred->mem + instr->m_val2) = s_name(effect); | |
89 | |||
90 | 3 | vector_pop(&shred->info->frame); | |
91 | 3 | vector_pop(&shred->info->frame); | |
92 | 3 | return true; | |
93 | } | ||
94 | |||
95 | 8220 | ANN bool unwind(const VM_Shred shred, const Symbol effect, const m_uint size) { | |
96 | 8220 | const VM_Code code = shred->code; | |
97 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 8202 times.
|
8220 | if (code->live_values.ptr) |
98 | 18 | clean_values(shred); | |
99 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 8193 times.
|
8220 | if (!size) return false; |
100 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8190 times.
|
8193 | if (code->handlers.ptr) |
101 | 3 | return find_handle(shred, effect); | |
102 | // there might be no more stack to unwind | ||
103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8190 times.
|
8190 | if (shred->mem == (m_bit *)shred + sizeof(struct VM_Shred_) + SIZEOF_REG) |
104 | ✗ | return false; | |
105 | 8190 | shred_unwind(shred); | |
106 | 8190 | return unwind(shred, effect, size - (code != shred->code)); | |
107 | } | ||
108 | |||
109 | ✗ | ANN static void trace(VM_Shred shred, const m_uint size) { | |
110 | ✗ | const m_uint line = vector_at(&shred->info->line, size - 1); | |
111 | m_uint i; | ||
112 | ✗ | bool can_skip = false; | |
113 | ✗ | if(!size)return; | |
114 | ✗ | for (i = size; --i;) { | |
115 | ✗ | const m_uint val = VPTR(&shred->info->line, i - 1); | |
116 | ✗ | if (!val) | |
117 | ✗ | can_skip = true; | |
118 | ✗ | else if (can_skip && val) | |
119 | ✗ | break; | |
120 | } | ||
121 | ✗ | loc_t loc = {.first = {.line = line, .column = 1}, | |
122 | .last = {.line = line, .column = 1}}; | ||
123 | ✗ | gwerr_secondary("called from here", code_name(shred->code->name, true), loc); | |
124 | ✗ | gw_err(" {M}┗━╸{0} {-}in code{0} {+W}%s{0}{-}:{0}\n", shred->code->name); | |
125 | ✗ | if (shred->mem == (m_bit *)shred + sizeof(struct VM_Shred_) + SIZEOF_REG) | |
126 | ✗ | return; | |
127 | ✗ | shred_unwind(shred); | |
128 | ✗ | trace(shred, i); | |
129 | } | ||
130 | |||
131 | struct TraceStart { | ||
132 | const VM_Code code; | ||
133 | m_bit *const reg; | ||
134 | m_bit *const mem; | ||
135 | }; | ||
136 | |||
137 | ✗ | ANN static inline void shred_trace(const VM_Shred shred, const struct TraceStart *ts) { | |
138 | ✗ | shred->code = ts->code; | |
139 | ✗ | shred->reg = ts->reg; | |
140 | ✗ | shred->mem = ts->mem; | |
141 | ✗ | gw_err("\n{-/}here is the trace:\n"); | |
142 | ✗ | trace(shred, vector_size(&shred->info->line)); | |
143 | } | ||
144 | |||
145 | 27 | ANN static inline void unhandled_pp(VM_Shred shred, const m_str effect, const struct TraceStart *ts) { | |
146 | 27 | gw_err("{-}[{0}{+}Gwion{0}{-}](VM):{0} {-}in code {/+}'%s'{0}{-}. origin: {/+}'%s'{0}{-}\n", | |
147 | ts->code->name, shred->info->orig->name); | ||
148 | 27 | gw_err("{-C}shred{W}[{Y}% 5" UINT_F "{W}]{-}:{-R}Unhandled {+R}%s{0}\n", | |
149 | shred->tick->xid, effect); | ||
150 | 27 | } | |
151 | |||
152 | 27 | ANN static inline void handle_fail(VM_Shred shred, const m_str effect, const struct TraceStart *ts) { | |
153 | 27 | unhandled_pp(shred, effect, ts); | |
154 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | if (shred->info->line.ptr) // trace if available |
155 | ✗ | shred_trace(shred, ts); | |
156 | 27 | shreduler_remove(shred->tick->shreduler, shred, true); | |
157 | 27 | } | |
158 | |||
159 | 30 | ANN bool handle(VM_Shred shred, const m_str effect) { | |
160 | 30 | shreduler_remove(shred->tick->shreduler, shred, false); | |
161 | // store trace info | ||
162 | 30 | struct TraceStart ts = { | |
163 | 30 | .code = shred->code, | |
164 | 30 | .reg = shred->reg, | |
165 | 30 | .mem = shred->mem | |
166 | }; | ||
167 | 30 | const m_uint size = | |
168 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 27 times.
|
30 | shred->info->frame.ptr ? vector_size(&shred->info->frame) : 0; |
169 | // maybe we should use a string to avoid the insert_symbol call | ||
170 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 3 times.
|
30 | if (!unwind(shred, insert_symbol(shred->info->vm->gwion->st, effect), size)) { |
171 | 27 | handle_fail(shred, effect, &ts); | |
172 | 27 | return false; | |
173 | } | ||
174 | 3 | return true; | |
175 | } | ||
176 | |||
177 | ✗ | ANN bool vm_remove(const VM *vm, const m_uint index) { | |
178 | ✗ | const Vector v = (Vector)&vm->shreduler->active_shreds; | |
179 | LOOP_OPTIM | ||
180 | ✗ | for (m_uint i = vector_size(v) + 1; --i;) { | |
181 | ✗ | const VM_Shred sh = (VM_Shred)vector_at(v, i - 1); | |
182 | ✗ | if (sh && sh->tick->xid == index) { | |
183 | ✗ | handle(sh, "MsgRemove"); | |
184 | ✗ | return true; | |
185 | } | ||
186 | } | ||
187 | ✗ | return false; | |
188 | } | ||
189 | |||
190 | 424 | ANN void vm_add_shred(const VM *vm, const VM_Shred shred) { | |
191 | 424 | shred->info->vm = (VM *)vm; | |
192 | 424 | shred->info->me = new_shred(shred); | |
193 | 424 | shreduler_add(vm->shreduler, shred); | |
194 | 424 | } | |
195 | |||
196 | 638 | ANN void vm_ini_shred(const VM *vm, const VM_Shred shred) { | |
197 | 638 | shred->info->vm = (VM *)vm; | |
198 | 638 | shred->info->me = new_shred(shred); | |
199 | 638 | shreduler_ini(vm->shreduler, shred); | |
200 | 638 | } | |
201 | |||
202 | 11 | ANN void vm_lock(VM const *vm) { | |
203 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
|
11 | if (vm->parent) vm_lock(vm->parent); |
204 | 11 | MUTEX_LOCK(vm->shreduler->mutex); | |
205 | 11 | } | |
206 | |||
207 | 11 | ANN void vm_unlock(VM const *vm) { | |
208 | 11 | do MUTEX_UNLOCK(vm->shreduler->mutex); | |
209 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
|
11 | while ((vm = vm->parent)); |
210 | 5 | } | |
211 | |||
212 | ✗ | ANN bool vm_running(VM const *vm) { | |
213 | ✗ | if (!vm->shreduler->bbq->is_running) return 0; | |
214 | ✗ | if (!vm->parent) return 1; | |
215 | ✗ | return vm->shreduler->bbq->is_running = vm_running(vm->parent); | |
216 | } | ||
217 | |||
218 | 6080218 | __attribute__((hot)) ANN static inline void compute_audio(const VM *vm) { | |
219 | 6080218 | const Vector v = (Vector)&vm->ugen; | |
220 | LOOP_OPTIM | ||
221 |
2/2✓ Branch 1 taken 12971128 times.
✓ Branch 2 taken 5914406 times.
|
18962234 | for (m_uint i = vector_size(v) + 1; --i;) { |
222 | 12971128 | const UGen u = (UGen)vector_at(v, i - 1); | |
223 | 12882016 | u->done = 0; | |
224 |
2/2✓ Branch 0 taken 6574264 times.
✓ Branch 1 taken 6307752 times.
|
12882016 | if (u->multi) { |
225 | 6574264 | struct ugen_multi_ *m = u->connect.multi; | |
226 | LOOP_OPTIM | ||
227 |
2/2✓ Branch 0 taken 13148528 times.
✓ Branch 1 taken 6574264 times.
|
19722792 | for (m_uint j = m->n_chan + 1; --j;) UGEN(m->channel[j - 1])->done = 0; |
228 | } | ||
229 | } | ||
230 | 5914406 | const UGen hole = (UGen)vector_at(v, 0); | |
231 | 5899260 | hole->compute(hole); | |
232 | 5928344 | } | |
233 | |||
234 | #ifdef DEBUG_STACK | ||
235 | #define VM_INFO \ | ||
236 | gw_err("{-C}shred{W}[{Y}% 5" UINT_F "{W}] {C}mem{W}[{Y}% 5" INT_F \ | ||
237 | "{W}] {C}reg{W}[{Y}% 5" INT_F "{W}]{0}\n", \ | ||
238 | shred->tick->xid, \ | ||
239 | mem - ((m_bit *)shred + sizeof(struct VM_Shred_) + SIZEOF_REG), \ | ||
240 | reg - ((m_bit *)shred + sizeof(struct VM_Shred_))); | ||
241 | #else | ||
242 | #define VM_INFO | ||
243 | #endif | ||
244 | |||
245 | 17136 | ANN static inline bool overflow_(const m_bit *mem, const VM_Shred c) { | |
246 | 17136 | return mem > (((m_bit *)c + sizeof(struct VM_Shred_) + SIZEOF_REG) + | |
247 | (SIZEOF_MEM)); | ||
248 | } | ||
249 | |||
250 | 74 | ANN static VM_Shred init_spork_shred(const VM_Shred shred, | |
251 | const VM_Code code) { | ||
252 | 74 | const VM_Shred sh = new_shred_base(shred, code); | |
253 | 74 | vm_add_shred(shred->info->vm, sh); | |
254 | 74 | sh->tick->parent = shred->tick; | |
255 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 43 times.
|
74 | if (!shred->tick->child.ptr) vector_init(&shred->tick->child); |
256 | 74 | vector_add(&shred->tick->child, (vtype)sh); | |
257 | 74 | return sh; | |
258 | } | ||
259 | |||
260 | ANN M_Object new_fork(const VM_Shred, const VM_Code code, const Type); | ||
261 | 5 | ANN static VM_Shred init_fork_shred(const VM_Shred shred, const VM_Code code, | |
262 | const Type t) { | ||
263 | 5 | const M_Object o = new_fork(shred, code, t); | |
264 | 5 | VM * vm = shred->info->vm; | |
265 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if (!vm->gwion->data->child.ptr) vector_init(&vm->gwion->data->child); |
266 | 5 | vector_add(&vm->gwion->data->child, (vtype)o); | |
267 | 5 | return ME(o); | |
268 | } | ||
269 | |||
270 | #define handle(a, b) VM_OUT handle(a, b); | ||
271 | #define TEST0(t, pos) \ | ||
272 | if (!*(t *)(reg - pos)) { \ | ||
273 | handle(shred, "ZeroDivideException"); \ | ||
274 | break; \ | ||
275 | } | ||
276 | |||
277 | //#define ADVANCE() { byte += BYTECODE_SZ; shred->pc++;} | ||
278 | #define IDISPATCH() \ | ||
279 | { \ | ||
280 | VM_INFO; \ | ||
281 | SDISPATCH(); \ | ||
282 | } | ||
283 | |||
284 | #define SET_BYTE(pc) (byte = bytecode + (pc)*BYTECODE_SZ) | ||
285 | |||
286 | #define PC_DISPATCH(_pc) \ | ||
287 | SET_BYTE((_pc)); \ | ||
288 | IDISPATCH(); | ||
289 | |||
290 | #define DISPATCH() \ | ||
291 | ADVANCE(); \ | ||
292 | IDISPATCH(); | ||
293 | |||
294 | #define ADISPATCH() \ | ||
295 | { \ | ||
296 | ADVANCE(); \ | ||
297 | SDISPATCH(); \ | ||
298 | } | ||
299 | |||
300 | #define PC (*(m_uint *)(byte + SZ_INT*3)) | ||
301 | |||
302 | #define OP(t, sz, op, ...) \ | ||
303 | reg -= sz; \ | ||
304 | __VA_ARGS__ \ | ||
305 | *(t *)(reg - sz) op## = *(t *)reg; \ | ||
306 | DISPATCH(); | ||
307 | |||
308 | #define INT_OP(op, ...) OP(m_int, SZ_INT, op, __VA_ARGS__) | ||
309 | #define INT_IMM_OP(op) *(m_int*)(reg-SZ_INT) op VAL; DISPATCH() | ||
310 | #define FLOAT_OP(op, ...) OP(m_float, SZ_FLOAT, op, __VA_ARGS__) | ||
311 | #define FLOAT_IMM_OP(op) *(m_float*)(reg-SZ_FLOAT) op FVAL; DISPATCH() | ||
312 | |||
313 | #define LOGICAL(t, sz0, sz, op) \ | ||
314 | reg -= sz0; \ | ||
315 | *(m_uint *)(reg - SZ_INT) = (*(t *)(reg - SZ_INT) op * (t *)(reg + sz)); \ | ||
316 | DISPATCH() | ||
317 | |||
318 | #define INT_LOGICAL(op) LOGICAL(m_int, SZ_INT, 0, op) | ||
319 | #define INT_IMM_LOGICAL(op) *(m_int *)(reg - SZ_INT) = *(m_int*)(reg-SZ_INT) op IVAL; DISPATCH(); | ||
320 | |||
321 | #define FLOAT_LOGICAL(op) \ | ||
322 | LOGICAL(m_float, SZ_FLOAT * 2 - SZ_INT, SZ_FLOAT - SZ_INT, op) | ||
323 | |||
324 | #define FLOAT_IMM_LOGICAL(op) \ | ||
325 | reg -= SZ_FLOAT - SZ_INT;\ | ||
326 | *(m_uint *)(reg - SZ_INT) = *(m_float*)(reg-SZ_INT) op FVAL; DISPATCH(); | ||
327 | |||
328 | #define SELF(t, sz, op) \ | ||
329 | *(t *)(reg - sz) = op * (t *)(reg - sz); \ | ||
330 | DISPATCH(); | ||
331 | |||
332 | // check me | ||
333 | #define R(t, sz, op, ...) \ | ||
334 | reg -= SZ_INT; \ | ||
335 | __VA_ARGS__ \ | ||
336 | *(t *)(reg - sz) = (**(t **)reg op## = (*(t *)(reg - sz))); \ | ||
337 | DISPATCH() | ||
338 | #define INT_R(op, ...) R(m_int, SZ_INT, op, __VA_ARGS__) | ||
339 | #define FLOAT_R(op, ...) R(m_float, SZ_FLOAT, op) | ||
340 | |||
341 | #define INT_PRE(op) \ | ||
342 | /*assert(*(m_int**)(reg-SZ_INT));*/ \ | ||
343 | *(m_int *)(reg - SZ_INT) = op(**(m_int **)(reg - SZ_INT)); \ | ||
344 | DISPATCH() | ||
345 | |||
346 | #define INT_POST(op) \ | ||
347 | /*assert(*(m_int**)(reg-SZ_INT));*/ \ | ||
348 | *(m_int *)(reg - SZ_INT) = (**(m_int **)(reg - SZ_INT)) op; \ | ||
349 | DISPATCH() | ||
350 | |||
351 | #define IF_OP(op) \ | ||
352 | reg -= SZ_INT; \ | ||
353 | *(m_float *)(reg - SZ_FLOAT) = (m_float) * (m_int *)(reg - SZ_FLOAT) op * \ | ||
354 | (m_float *)(reg + SZ_INT - SZ_FLOAT); \ | ||
355 | DISPATCH() | ||
356 | |||
357 | #define IF_LOGICAL(op) \ | ||
358 | reg -= SZ_FLOAT; \ | ||
359 | *(m_int *)(reg - SZ_INT) = \ | ||
360 | (m_int)(*(m_int *)(reg - SZ_INT) op * (m_float *)reg); \ | ||
361 | DISPATCH() | ||
362 | __attribute__((hot)) | ||
363 | |||
364 | #define IF_R(op) \ | ||
365 | reg -= SZ_INT * 2 - SZ_FLOAT; \ | ||
366 | *(m_float *)(reg - SZ_FLOAT) = \ | ||
367 | (**(m_float **)(reg + SZ_INT - SZ_FLOAT) op## = \ | ||
368 | (m_float) * (m_int *)(reg - SZ_FLOAT)); \ | ||
369 | DISPATCH() | ||
370 | |||
371 | #define FI_OP(op) \ | ||
372 | reg -= SZ_INT; \ | ||
373 | *(m_float *)(reg - SZ_FLOAT) op## = (m_float) * (m_int *)reg; \ | ||
374 | DISPATCH() | ||
375 | |||
376 | #define FI_LOGICAL(op) \ | ||
377 | reg -= SZ_FLOAT; \ | ||
378 | *(m_int *)(reg - SZ_INT) = (m_int)(*(m_float *)(reg - SZ_INT) op * \ | ||
379 | (m_int *)(reg + SZ_FLOAT - SZ_INT)); \ | ||
380 | DISPATCH() | ||
381 | |||
382 | #define FI_R(op, ...) \ | ||
383 | reg -= SZ_FLOAT; \ | ||
384 | __VA_ARGS__ \ | ||
385 | *(m_int *)(reg - SZ_INT) = (**(m_int **)(reg + SZ_FLOAT - SZ_INT) op## = \ | ||
386 | /*(m_int)*/ (*(m_float *)(reg - SZ_INT))); \ | ||
387 | DISPATCH() | ||
388 | |||
389 | #define STRINGIFY_NX(a) #a | ||
390 | #define STRINGIFY(a) STRINGIFY_NX(a) | ||
391 | #define PPCAT_NX(A, B) A##B | ||
392 | #define PPCAT(A, B) PPCAT_NX(A, B) | ||
393 | |||
394 | #if defined(__clang__) | ||
395 | #define COMPILER clang | ||
396 | #define UNINITIALIZED "-Wuninitialized") | ||
397 | #elif defined(__GNUC__) || defined(__GNUG__) | ||
398 | #define COMPILER GCC | ||
399 | #define UNINITIALIZED "-Wmaybe-uninitialized") | ||
400 | #endif | ||
401 | |||
402 | #define PRAGMA_PUSH() \ | ||
403 | _Pragma(STRINGIFY(COMPILER diagnostic push)) \ | ||
404 | _Pragma(STRINGIFY(COMPILER diagnostic ignored UNINITIALIZED) | ||
405 | #define PRAGMA_POP() _Pragma(STRINGIFY(COMPILER diagnostic pop)) | ||
406 | |||
407 | #define VAL (*(m_uint *)(byte + SZ_INT)) | ||
408 | #define IVAL (*(m_int *)(byte + SZ_INT)) | ||
409 | #define FVAL (*(m_float *)(byte + SZ_INT)) | ||
410 | #define VAL2 (*(m_uint *)(byte + SZ_INT + SZ_INT)) | ||
411 | #define IVAL2 (*(m_int *)(byte + SZ_INT + SZ_INT)) | ||
412 | #define SVAL (*(uint16_t *)(byte + SZ_INT + SZ_INT)) | ||
413 | #define SVAL2 (*(uint16_t *)(byte + SZ_INT + SZ_INT + sizeof(uint16_t))) | ||
414 | |||
415 | #define BRANCH_DISPATCH(check) \ | ||
416 | if (check) { \ | ||
417 | SET_BYTE(VAL); \ | ||
418 | shred->pc = VAL + 1;\ | ||
419 | } else \ | ||
420 | ADVANCE(); \ | ||
421 | IDISPATCH(); | ||
422 | |||
423 | __attribute__((hot)) void | ||
424 | 6086953 | vm_prepare(const VM *vm, m_bit *prepare_code) { // lgtm [cpp/use-of-goto] | |
425 | static const void *dispatch[] = { | ||
426 | &®setimm, &®pushimm, &®pushfloat, &®pushother, &®pushaddr, | ||
427 | &®pushmem, &®pushmemfloat, &®pushmemother, &®pushmemaddr, | ||
428 | &®pushmemderef, &&pushnow, &&baseint, &&basefloat, &&baseother, | ||
429 | &&baseaddr, &®toreg, &®toregother2, &®toregaddr, &®toregderef, | ||
430 | &&structmember, &&structmemberfloat, &&structmemberother, | ||
431 | &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat, | ||
432 | &®pushme, &®pushmaybe, &&funcreturn, &&_goto, &&allocint, | ||
433 | &&allocfloat, &&allocother, | ||
434 | &&intplus, &&intminus, &&intmul, &&intdiv, &&intmod, | ||
435 | &&intplusimm, &&intminusimm, &&intmulimm, &&intdivimm, &&intmodimm, | ||
436 | // int relationnal | ||
437 | &&inteq, &&intne, &&intand, &&intor, | ||
438 | &&intgt, &&intge, &&intlt, &&intle, | ||
439 | &&intgtimm, &&intgeimm, &&intltimm, &&intleimm, | ||
440 | &&intsl, &&intsr, &&intsand, &&intsor, &&intxor, &&intnegate, &&intnot, | ||
441 | &&intcmp, &&intrassign, &&intradd, &&intrsub, &&intrmul, &&intrdiv, | ||
442 | &&intrmod, &&intrsl, &&intrsr, &&intrsand, &&intrsor, &&intrxor, &&preinc, | ||
443 | &&predec, &&postinc, &&postdec, | ||
444 | &&floatadd, &&floatsub, &&floatmul, &&floatdiv, | ||
445 | &&floataddimm, &&floatsubimm, &&floatmulimm, &&floatdivimm, | ||
446 | // logical | ||
447 | &&floatand, &&floator, &&floateq, &&floatne, | ||
448 | &&floatgt, &&floatge, &&floatlt, &&floatle, | ||
449 | &&floatgtimm, &&floatgeimm, &&floatltimm, &&floatleimm, | ||
450 | &&floatneg, &&floatnot, &&floatrassign, &&floatradd, | ||
451 | &&floatrsub, &&floatrmul, &&floatrdiv, &&ifadd, &&ifsub, &&ifmul, &&ifdiv, | ||
452 | &&ifand, &&ifor, &&ifeq, &&ifne, &&ifgt, &&ifge, &&iflt, &&ifle, | ||
453 | &&ifrassign, &&ifradd, &&ifrsub, &&ifrmul, &&ifrdiv, &&fiadd, &&fisub, | ||
454 | &&fimul, &&fidiv, &&fiand, &&fior, &&fieq, &&fine, &&figt, &&fige, &&filt, | ||
455 | &&file, &&firassign, &&firadd, &&firsub, &&firmul, &&firdiv, &&itof, | ||
456 | &&ftoi, &&timeadv, &&recurs, &&setcode, &®move, | ||
457 | &®tomem, &®tomemother, | ||
458 | &&overflow, | ||
459 | &&funcusrend, &&funcusrend2, &&funcmemberend, | ||
460 | &&sporkini, &&forkini, &&sporkfunc, &&sporkexp, &&sporkcode, | ||
461 | &&forkend, &&sporkend, &&brancheqint, &&branchneint, &&brancheqfloat, | ||
462 | &&branchnefloat, &&unroll, &&arrayappend, &&autounrollinit, &&autoloop, | ||
463 | &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&newobj, &&addref, | ||
464 | &&addrefaddr, &&structaddref, &&structaddrefaddr, &&objassign, &&assign, | ||
465 | &&_remref, &&_remref2, &&_structreleaseregaddr, &&structreleasemem, | ||
466 | &&_except, | ||
467 | &&dotmembermem, &&dotmembermem2, /*&&dotmembermem3, */&&dotmembermem4, | ||
468 | &&dotmember, &&dotfloat, &&dotother, &&dotaddr, | ||
469 | &&unioncheck, &&unionint, &&unionfloat, | ||
470 | &&unionother, &&unionaddr, &&staticint, &&staticfloat, &&staticother, | ||
471 | &&dotfunc, &&gacktype, &&gackend, &&gack, &&try_ini, | ||
472 | &&try_end, &&handleeffect, &&performeffect, &&noop, &&debugline, | ||
473 | &&debugvalue, &&debugpush, &&debugpop, &&eoc, &&vmin, &&other}; | ||
474 | // &®pushimm}; | ||
475 | |||
476 |
2/2✓ Branch 0 taken 6083918 times.
✓ Branch 1 taken 3035 times.
|
6086953 | if(!prepare_code) { |
477 | PRAGMA_PUSH() | ||
478 | 6083918 | const Shreduler s = vm->shreduler; | |
479 | VM_Shred shred; | ||
480 |
2/2✓ Branch 1 taken 573 times.
✓ Branch 2 taken 6113154 times.
|
6084491 | while ((shred = shreduler_get(s))) { |
481 | 573 | VM_Code code = shred->code; | |
482 | 573 | m_bit * bytecode = code->bytecode; | |
483 | 573 | m_bit * byte = bytecode + shred->pc * BYTECODE_SZ; | |
484 | 573 | m_bit * reg = shred->reg; | |
485 | 573 | m_bit * mem = shred->mem; | |
486 | m_bit next; | ||
487 | |||
488 | #define VM_OUT \ | ||
489 | shred->code = code; \ | ||
490 | shred->reg = reg; \ | ||
491 | shred->mem = mem; \ | ||
492 | shred->pc = PC; | ||
493 | |||
494 | #define ADVANCE() byte += BYTECODE_SZ | ||
495 | #define SDISPATCH() goto **(void***)byte; | ||
496 | |||
497 | union { | ||
498 | M_Object obj; | ||
499 | VM_Code code; | ||
500 | } a; | ||
501 | VM_Shred child; | ||
502 | do { | ||
503 | 573 | SDISPATCH(); | |
504 | 20354 | regsetimm: | |
505 | 20354 | *(m_uint *)(reg + IVAL2) = VAL; | |
506 | 20354 | DISPATCH(); | |
507 | 8432 | regpushimm: | |
508 | 8432 | *(m_uint *)reg = VAL; | |
509 | 8432 | reg += SZ_INT; | |
510 | 8432 | DISPATCH(); | |
511 | 408 | regpushfloat: | |
512 | 408 | *(m_float *)reg = FVAL; | |
513 | 408 | reg += SZ_FLOAT; | |
514 | 408 | DISPATCH(); | |
515 | ✗ | regpushother: | |
516 | // LOOP_OPTIM | ||
517 | ✗ | for (m_uint i = 0; i <= VAL2; i += SZ_INT) | |
518 | ✗ | *(m_bit **)(reg + i) = *(m_bit **)(VAL + i); | |
519 | ✗ | reg += VAL2; | |
520 | ✗ | DISPATCH(); | |
521 | ✗ | regpushaddr: | |
522 | ✗ | *(m_uint **)reg = &VAL; | |
523 | ✗ | reg += SZ_INT; | |
524 | ✗ | DISPATCH() | |
525 | 1069 | regpushmem: | |
526 | 1069 | *(m_uint *)reg = *(m_uint *)(mem + IVAL); | |
527 | 1069 | reg += SZ_INT; | |
528 | 1069 | DISPATCH(); | |
529 | 161 | regpushmemfloat: | |
530 | 161 | *(m_float *)reg = *(m_float *)(mem + IVAL); | |
531 | 161 | reg += SZ_FLOAT; | |
532 | 161 | DISPATCH(); | |
533 | 2 | regpushmemother: | |
534 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
6 | for (m_uint i = 0; i <= VAL2; i += SZ_INT) |
535 | 4 | *(m_uint *)(reg + i) = *(m_uint *)((m_bit *)(mem + IVAL) + i); | |
536 | 2 | reg += VAL2; | |
537 | 2 | DISPATCH(); | |
538 | 315 | regpushmemaddr: | |
539 | 315 | *(m_bit **)reg = &*(m_bit *)(mem + IVAL); | |
540 | 315 | reg += SZ_INT; | |
541 | 315 | DISPATCH(); | |
542 | 27 | regpushmemderef: | |
543 | 27 | memcpy(reg, *(m_bit **)(mem + IVAL), VAL2); | |
544 | 27 | reg += VAL2; | |
545 | 27 | DISPATCH() | |
546 | 149 | pushnow: | |
547 | 149 | *(m_float *)reg = vm->bbq->pos; | |
548 | 149 | reg += SZ_FLOAT; | |
549 | 149 | DISPATCH(); | |
550 | 481 | baseint: | |
551 | 481 | *(m_uint *)reg = *(m_uint *)(shred->base + VAL); | |
552 | 481 | reg += SZ_INT; | |
553 | 481 | DISPATCH(); | |
554 | 30 | basefloat: | |
555 | 30 | *(m_float *)reg = *(m_float *)(shred->base + VAL); | |
556 | 30 | reg += SZ_FLOAT; | |
557 | 30 | DISPATCH(); | |
558 | ✗ | baseother: | |
559 | // LOOP_OPTIM | ||
560 | ✗ | for (m_uint i = 0; i <= VAL2; i += SZ_INT) | |
561 | ✗ | *(m_uint *)(reg + i) = *(m_uint *)((shred->base + VAL) + i); | |
562 | ✗ | reg += VAL2; | |
563 | ✗ | DISPATCH(); | |
564 | 89 | baseaddr: | |
565 | 89 | *(m_uint **)reg = &*(m_uint *)(shred->base + IVAL); | |
566 | 89 | reg += SZ_INT; | |
567 | 89 | DISPATCH(); | |
568 | 1506 | regtoreg: | |
569 | 1506 | *(m_uint *)(reg + IVAL) = *(m_uint *)(reg + IVAL2); | |
570 | 1506 | DISPATCH() | |
571 | 1 | regtoregother2: | |
572 | 1 | memcpy(reg - VAL2, reg + IVAL, VAL2); | |
573 | 1 | DISPATCH() | |
574 | ✗ | regtoregaddr: | |
575 | ✗ | *(m_uint **)(reg + IVAL) = &*(m_uint *)(reg + IVAL2); | |
576 | ✗ | DISPATCH() | |
577 | 15 | regtoregderef: | |
578 | 15 | memcpy(*(m_bit **)(reg - SZ_INT), *(m_bit **)(reg + IVAL), VAL2); | |
579 | 15 | DISPATCH() | |
580 | 24 | structmember: | |
581 | 24 | *(m_bit **)(reg - SZ_INT) = | |
582 | 24 | *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL); | |
583 | 24 | DISPATCH() | |
584 | 20 | structmemberfloat: | |
585 | 20 | *(m_bit **)(reg - SZ_INT) = | |
586 | 20 | *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL); | |
587 | 20 | DISPATCH() | |
588 | ✗ | structmemberother: | |
589 | ✗ | *(m_bit **)(reg - SZ_INT) = | |
590 | ✗ | *(m_bit **)(*(m_bit **)(reg - SZ_INT) + IVAL); | |
591 | ✗ | DISPATCH() | |
592 | 38 | structmemberaddr: | |
593 | 38 | *(m_bit **)(reg - SZ_INT) = &*(*(m_bit **)(reg - SZ_INT) + IVAL); | |
594 | 38 | DISPATCH() | |
595 | 104 | memsetimm: | |
596 | 104 | *(m_uint *)(mem + VAL) = VAL2; | |
597 | 104 | DISPATCH(); | |
598 | ✗ | memaddimm: | |
599 | ✗ | *(m_int *)(mem + VAL) += IVAL2; | |
600 | // (*(m_int*)(mem+VAL))--; | ||
601 | ✗ | DISPATCH(); | |
602 | 101 | repeatidx: | |
603 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100 times.
|
101 | BRANCH_DISPATCH(*(m_int *)(mem + VAL2 + SZ_INT) == |
604 | ++(*(m_int *)(mem + VAL2))); | ||
605 | 124 | repeat: | |
606 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 120 times.
|
124 | BRANCH_DISPATCH(!(*(m_uint *)(mem + VAL2))--); |
607 | 35 | regpushme: | |
608 | 35 | *(M_Object *)reg = shred->info->me; | |
609 | 35 | reg += SZ_INT; | |
610 | 35 | DISPATCH() | |
611 | 39 | regpushmaybe: | |
612 | |||
613 | #ifndef __AFL_HAVE_MANUAL_CONTROL | ||
614 | 39 | *(m_uint *)reg = gw_rand((uint32_t *)vm->rand) > (UINT32_MAX / 2); | |
615 | #else | ||
616 | *(m_uint *)reg = 0; | ||
617 | #endif | ||
618 | 39 | reg += SZ_INT; | |
619 | 39 | DISPATCH(); | |
620 | 1781 | funcreturn : { | |
621 | 1781 | register frame_t frame = *(frame_t *)(mem - sizeof(frame_t)); | |
622 | 1781 | bytecode = (code = frame.code)->bytecode; | |
623 | 1781 | mem -= frame.push; | |
624 | 1781 | PC_DISPATCH(frame.pc); | |
625 | } | ||
626 | 517 | _goto: | |
627 | 517 | PC_DISPATCH(VAL); | |
628 | 124 | allocint: | |
629 | 124 | *(m_uint *)reg = *(m_uint *)(mem + VAL) = 0; | |
630 | 124 | reg += SZ_INT; | |
631 | 124 | DISPATCH() | |
632 | 86 | allocfloat: | |
633 | 86 | *(m_float *)reg = *(m_float *)(mem + VAL) = 0; | |
634 | 86 | reg += SZ_FLOAT; | |
635 | 86 | DISPATCH() | |
636 | ✗ | allocother: | |
637 | // LOOP_OPTIM | ||
638 | ✗ | for (m_uint i = 0; i <= VAL2; i += SZ_INT) | |
639 | ✗ | *(m_uint *)(reg + i) = (*(m_uint *)(mem + VAL + i) = 0); | |
640 | ✗ | reg += VAL2; | |
641 | ✗ | DISPATCH() | |
642 | |||
643 | 72 | intplus: | |
644 | 72 | INT_OP(+) | |
645 | 1 | intminus: | |
646 | 1 | INT_OP(-) | |
647 | 1 | intmul: | |
648 | 1 | INT_OP(*) | |
649 | 3 | intdiv: | |
650 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | INT_OP(/, TEST0(m_int, 0)) |
651 | 1 | intmod: | |
652 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | INT_OP(%, TEST0(m_int, 0)) |
653 | |||
654 | 2 | intplusimm: | |
655 | 2 | INT_IMM_OP(+=) | |
656 | 104 | intminusimm: | |
657 | 104 | INT_IMM_OP(-=) | |
658 | ✗ | intmulimm: | |
659 | ✗ | INT_IMM_OP(*=) | |
660 | ✗ | intdivimm: | |
661 | ✗ | INT_IMM_OP(/=) | |
662 | ✗ | intmodimm: | |
663 | ✗ | INT_IMM_OP(%=) | |
664 | |||
665 | 167 | inteq: | |
666 | 167 | INT_LOGICAL(==) | |
667 | 2 | intne: | |
668 | 2 | INT_LOGICAL(!=) | |
669 | 1 | intand: | |
670 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | INT_LOGICAL(&&) |
671 | 1 | intor: | |
672 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | INT_LOGICAL(||) |
673 | 1 | intgt: | |
674 | 1 | INT_LOGICAL(>) | |
675 | 1 | intge: | |
676 | 1 | INT_LOGICAL(>=) | |
677 | 1 | intlt: | |
678 | 1 | INT_LOGICAL(<) | |
679 | 1 | intle: | |
680 | 1 | INT_LOGICAL(<=) | |
681 | 27 | intgtimm: | |
682 | 27 | INT_IMM_LOGICAL(>) | |
683 | ✗ | intgeimm: | |
684 | ✗ | INT_IMM_LOGICAL(>=) | |
685 | 38 | intltimm: | |
686 | 38 | INT_IMM_LOGICAL(<) | |
687 | ✗ | intleimm: | |
688 | ✗ | INT_IMM_LOGICAL(<=) | |
689 | 1 | intsl: | |
690 | 1 | INT_LOGICAL(<<) | |
691 | 1 | intsr: | |
692 | 1 | INT_LOGICAL(>>) | |
693 | 1 | intsand: | |
694 | 1 | INT_LOGICAL(&) | |
695 | 1 | intsor: | |
696 | 1 | INT_LOGICAL(|) | |
697 | 1 | intxor: | |
698 | 1 | INT_LOGICAL(^) | |
699 | |||
700 | 1 | intnegate: | |
701 | 1 | *(m_int *)(reg - SZ_INT) *= -1; | |
702 | 1 | DISPATCH() | |
703 | 24 | intnot: | |
704 | 24 | SELF(m_int, SZ_INT, !) | |
705 | ✗ | intcmp: | |
706 | ✗ | SELF(m_int, SZ_INT, ~) | |
707 | |||
708 | 1445 | intrassign: | |
709 | 1445 | reg -= SZ_INT; | |
710 | 1445 | **(m_int **)reg = *(m_int *)(reg - SZ_INT); | |
711 | 1445 | DISPATCH() | |
712 | |||
713 | 1 | intradd: | |
714 | 1 | INT_R(+) | |
715 | 1 | intrsub: | |
716 | 1 | INT_R(-) | |
717 | 1 | intrmul: | |
718 | 1 | INT_R(*) | |
719 | // intrdiv: INT_R(/, TEST0(m_int, -SZ_INT)) | ||
720 | // intrmod: INT_R(%, TEST0(m_int, -SZ_INT)) | ||
721 | 1 | intrdiv: | |
722 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | INT_R(/, TEST0(m_int, SZ_INT)) |
723 | 1 | intrmod: | |
724 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | INT_R(%, TEST0(m_int, SZ_INT)) |
725 | 1 | intrsl: | |
726 | 1 | INT_R(<<) | |
727 | 1 | intrsr: | |
728 | 1 | INT_R(>>) | |
729 | 1 | intrsand: | |
730 | 1 | INT_R(&) | |
731 | 1 | intrsor: | |
732 | 1 | INT_R(|) | |
733 | 1 | intrxor: | |
734 | 1 | INT_R(^) | |
735 | |||
736 | 67 | preinc: | |
737 | 67 | INT_PRE(++) | |
738 | 25 | predec: | |
739 | 25 | INT_PRE(--) | |
740 | |||
741 | 26 | postinc: | |
742 | 26 | INT_POST(++) | |
743 | 18 | postdec: | |
744 | 18 | INT_POST(--) | |
745 | |||
746 | 3 | floatadd: | |
747 | 3 | FLOAT_OP(+) | |
748 | 1 | floatsub: | |
749 | 1 | FLOAT_OP(-) | |
750 | 72 | floatmul: | |
751 | 72 | FLOAT_OP(*) | |
752 | 1 | floatdiv: | |
753 | 1 | FLOAT_OP(/) | |
754 | |||
755 | ✗ | floataddimm: | |
756 | ✗ | FLOAT_IMM_OP(+=) | |
757 | ✗ | floatsubimm: | |
758 | ✗ | FLOAT_IMM_OP(-=) | |
759 | ✗ | floatmulimm: | |
760 | ✗ | FLOAT_IMM_OP(*=) | |
761 | ✗ | floatdivimm: | |
762 | ✗ | FLOAT_IMM_OP(/=) | |
763 | |||
764 | 1 | floatand: | |
765 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | FLOAT_LOGICAL(&&) |
766 | 1 | floator: | |
767 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | FLOAT_LOGICAL(||) |
768 | 68 | floateq: | |
769 | 68 | FLOAT_LOGICAL(==) | |
770 | 1 | floatne: | |
771 | 1 | FLOAT_LOGICAL(!=) | |
772 | 1 | floatgt: | |
773 | 1 | FLOAT_LOGICAL(>) | |
774 | 3 | floatge: | |
775 | 3 | FLOAT_LOGICAL(>=) | |
776 | 5 | floatlt: | |
777 | 5 | FLOAT_LOGICAL(<) | |
778 | 1 | floatle: | |
779 | 1 | FLOAT_LOGICAL(<=) | |
780 | 5 | floatgtimm: | |
781 | 5 | FLOAT_IMM_LOGICAL(>) | |
782 | ✗ | floatgeimm: | |
783 | ✗ | FLOAT_IMM_LOGICAL(>=) | |
784 | ✗ | floatltimm: | |
785 | ✗ | FLOAT_IMM_LOGICAL(<) | |
786 | ✗ | floatleimm: | |
787 | ✗ | FLOAT_IMM_LOGICAL(<=) | |
788 | |||
789 | 1 | floatneg: | |
790 | 1 | SELF(m_float, SZ_FLOAT, -) | |
791 | |||
792 | 3 | floatnot: | |
793 | 3 | reg -= SZ_FLOAT - SZ_INT; | |
794 | 3 | *(m_int *)(reg - SZ_INT) = !*(m_float *)(reg - SZ_INT); | |
795 | 3 | DISPATCH() | |
796 | |||
797 | 9 | floatrassign: | |
798 | 9 | reg -= SZ_INT; | |
799 | 9 | **(m_float **)reg = *(m_float *)(reg - SZ_FLOAT); | |
800 | 9 | DISPATCH() | |
801 | |||
802 | 1 | floatradd: | |
803 | 1 | FLOAT_R(+) | |
804 | 11 | floatrsub: | |
805 | 11 | FLOAT_R(-) | |
806 | 1 | floatrmul: | |
807 | 1 | FLOAT_R(*) | |
808 | 1 | floatrdiv: | |
809 | 1 | FLOAT_R(/) | |
810 | |||
811 | 1 | ifadd: | |
812 | 1 | IF_OP(+) | |
813 | 2 | ifsub: | |
814 | 2 | IF_OP(-) | |
815 | 22 | ifmul: | |
816 | 22 | IF_OP(*) | |
817 | 1 | ifdiv: | |
818 | 1 | IF_OP(/) | |
819 | |||
820 | 1 | ifand: | |
821 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | IF_LOGICAL(&&) |
822 | 1 | ifor: | |
823 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | IF_LOGICAL(||) |
824 | 1 | ifeq: | |
825 | 1 | IF_LOGICAL(==) | |
826 | 1 | ifne: | |
827 | 1 | IF_LOGICAL(!=) | |
828 | 1 | ifgt: | |
829 | 1 | IF_LOGICAL(>) | |
830 | 1 | ifge: | |
831 | 1 | IF_LOGICAL(>=) | |
832 | 1 | iflt: | |
833 | 1 | IF_LOGICAL(<) | |
834 | 1 | ifle: | |
835 | 1 | IF_LOGICAL(<=) | |
836 | |||
837 | 13 | ifrassign: | |
838 | 13 | IF_R() | |
839 | 5 | ifradd: | |
840 | 5 | IF_R(+) | |
841 | 17 | ifrsub: | |
842 | 17 | IF_R(-) | |
843 | 1 | ifrmul: | |
844 | 1 | IF_R(*) | |
845 | 1 | ifrdiv: | |
846 | 1 | IF_R(/) | |
847 | |||
848 | 1 | fiadd: | |
849 | 1 | FI_OP(+) | |
850 | 1 | fisub: | |
851 | 1 | FI_OP(-) | |
852 | 1 | fimul: | |
853 | 1 | FI_OP(*) | |
854 | 1 | fidiv: | |
855 | 1 | FI_OP(/) | |
856 | |||
857 | 1 | fiand: | |
858 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | FI_LOGICAL(&&) |
859 | 1 | fior: | |
860 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | FI_LOGICAL(||) |
861 | 6 | fieq: | |
862 | 6 | FI_LOGICAL(==) | |
863 | 1 | fine: | |
864 | 1 | FI_LOGICAL(!=) | |
865 | 24 | figt: | |
866 | 24 | FI_LOGICAL(>) | |
867 | 1 | fige: | |
868 | 1 | FI_LOGICAL(>=) | |
869 | 1 | filt: | |
870 | 1 | FI_LOGICAL(<) | |
871 | 1 | file: | |
872 | 1 | FI_LOGICAL(<=) | |
873 | |||
874 | 1 | firassign: | |
875 | 1 | reg -= SZ_FLOAT; | |
876 | 1 | *(m_int *)(reg - SZ_INT) = **(m_int **)(reg + SZ_FLOAT - SZ_INT) = | |
877 | 1 | (m_int) * (m_float *)(reg - SZ_INT); | |
878 | 1 | DISPATCH() | |
879 | |||
880 | 1 | firadd: | |
881 | 1 | FI_R(+) | |
882 | 2 | firsub: | |
883 | 2 | FI_R(-) | |
884 | 1 | firmul: | |
885 | 1 | FI_R(*) | |
886 | 1 | firdiv: | |
887 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | FI_R(/, TEST0(m_float, SZ_INT)) |
888 | |||
889 | 14 | itof: | |
890 | 14 | reg -= SZ_INT - SZ_FLOAT; | |
891 | 14 | *(m_float *)(reg - SZ_FLOAT) = (m_float) * (m_int *)(reg - SZ_FLOAT); | |
892 | 14 | DISPATCH() | |
893 | 1 | ftoi: | |
894 | { | ||
895 | 1 | const m_float f = * (m_float *)(reg - SZ_FLOAT); | |
896 | 1 | reg -= SZ_FLOAT - SZ_INT; | |
897 | 1 | *(m_int *)(reg - SZ_INT) = (m_int)f; | |
898 | 1 | DISPATCH() | |
899 | } | ||
900 | 137 | timeadv: | |
901 | 137 | reg -= SZ_FLOAT; | |
902 | 137 | shredule(s, shred, *(m_float *)(reg - SZ_FLOAT)); | |
903 | 137 | *(m_float *)(reg - SZ_FLOAT) += vm->bbq->pos; | |
904 | 137 | VM_OUT | |
905 | 137 | break; | |
906 | 12352 | recurs: | |
907 | { | ||
908 | 12352 | register const uint push = SVAL2; | |
909 | 12352 | mem += push; | |
910 | 12352 | *(frame_t *)(mem - sizeof(frame_t)) = | |
911 | 12352 | (frame_t) {.code = code, .pc = SVAL, .push = push}; | |
912 | 12352 | reg += IVAL; | |
913 | 12352 | next = eFuncUsrEnd2; | |
914 | } | ||
915 | 12352 | DISPATCH(); | |
916 | 4784 | setcode: | |
917 | 4784 | a.code = *(VM_Code *)(reg - SZ_INT); | |
918 |
2/2✓ Branch 0 taken 4449 times.
✓ Branch 1 taken 335 times.
|
4784 | if (!a.code->builtin) { |
919 | 4449 | register const uint push = | |
920 | 4449 | *(m_uint *)reg /*+ code->stack_depth*/ + sizeof(frame_t); | |
921 | 4449 | mem += push; | |
922 | 4449 | *(frame_t *)(mem - sizeof(frame_t)) = | |
923 | 4449 | (frame_t) {.code = code, .pc = PC + SVAL, .push = push}; | |
924 | 4449 | next = eFuncUsrEnd; | |
925 | } else { | ||
926 | 335 | mem += *(m_uint *)reg; | |
927 | 335 | next = eFuncMemberEnd; | |
928 | } | ||
929 | 10020 | regmove: | |
930 | 10020 | reg += IVAL; | |
931 | 10020 | DISPATCH(); | |
932 | 4958 | regtomem: | |
933 | 4958 | *(m_uint *)(mem + VAL) = *(m_uint *)(reg + IVAL2); | |
934 | 4958 | DISPATCH() | |
935 | 218 | regtomemother: | |
936 | 218 | memcpy(mem + VAL, reg, VAL2); | |
937 | 218 | DISPATCH() | |
938 | 17136 | overflow: | |
939 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 17132 times.
|
17136 | if (overflow_(mem + VAL2, shred)) { |
940 | 4 | handle(shred, "StackOverflow"); | |
941 | 4 | continue; | |
942 | } | ||
943 | 17132 | goto *dispatch[next]; | |
944 | 4448 | funcusrend: | |
945 | 4448 | byte = bytecode = (code = a.code)->bytecode; | |
946 | 4448 | SDISPATCH(); | |
947 | 12349 | funcusrend2: | |
948 | 12349 | byte = bytecode; | |
949 | 12349 | SDISPATCH(); | |
950 | 335 | funcmemberend: | |
951 | 335 | VM_OUT { | |
952 | 335 | register const m_uint val = VAL; | |
953 | 335 | register const m_uint val2 = VAL2; | |
954 | 335 | ((f_mfun)a.code->native_func)((*(M_Object *)mem), reg, shred); | |
955 | 335 | reg += val; | |
956 | 335 | shred->mem = (mem -= val2); | |
957 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 301 times.
|
335 | if (!s->curr) break; |
958 | } | ||
959 | 301 | PC_DISPATCH(shred->pc) | |
960 | 74 | sporkini: | |
961 | 74 | child = init_spork_shred(shred, (VM_Code)VAL); | |
962 | 74 | DISPATCH() | |
963 | 5 | forkini: | |
964 | 5 | child = init_fork_shred(shred, (VM_Code)VAL, (Type)VAL2); | |
965 | 5 | DISPATCH() | |
966 | 48 | sporkfunc: | |
967 | // LOOP_OPTIM | ||
968 |
2/2✓ Branch 0 taken 99 times.
✓ Branch 1 taken 48 times.
|
147 | for (m_uint i = 0; i < VAL; i += SZ_INT) |
969 | 99 | *(m_uint *)(child->reg + i) = *(m_uint *)(reg + i + IVAL2); | |
970 | 48 | child->reg += VAL; | |
971 | 48 | DISPATCH() | |
972 | 31 | sporkexp: | |
973 | // LOOP_OPTIM | ||
974 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 31 times.
|
42 | for (m_uint i = 0; i < VAL; i += SZ_INT) |
975 | 11 | *(m_uint *)(child->mem + i) = *(m_uint *)(mem + i); | |
976 | 31 | DISPATCH() | |
977 | 11 | sporkcode: | |
978 | // LOOP_OPTIM | ||
979 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 11 times.
|
22 | for (m_uint i = 0; i < VAL; i += SZ_INT) |
980 | 11 | *(m_uint *)(child->mem + i) = *(m_uint *)(reg + i); | |
981 | 11 | DISPATCH() | |
982 | 5 | forkend: | |
983 | 5 | fork_launch(child->info->me); | |
984 | 79 | sporkend: | |
985 | assert(!VAL); // spork are not mutable | ||
986 | 79 | *(M_Object *)(reg - SZ_INT) = child->info->me; | |
987 | 79 | DISPATCH() | |
988 | 465 | brancheqint: | |
989 | 465 | reg -= SZ_INT; | |
990 |
2/2✓ Branch 0 taken 268 times.
✓ Branch 1 taken 197 times.
|
465 | BRANCH_DISPATCH(!*(m_uint *)reg); |
991 | 41 | branchneint: | |
992 | 41 | reg -= SZ_INT; | |
993 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 16 times.
|
41 | BRANCH_DISPATCH(*(m_uint *)reg); |
994 | 4 | brancheqfloat: | |
995 | 4 | reg -= SZ_FLOAT; | |
996 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | BRANCH_DISPATCH(!*(m_float *)reg); |
997 | 8 | branchnefloat: | |
998 | 8 | reg -= SZ_FLOAT; | |
999 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | BRANCH_DISPATCH(*(m_float *)reg); |
1000 | 2 | unroll : { | |
1001 | 2 | const m_uint n = *(m_uint *)(mem + VAL - SZ_INT); | |
1002 | 2 | const m_uint idx = *(m_uint *)(mem + VAL); | |
1003 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (idx > 0) { |
1004 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (idx >= n) { |
1005 | 2 | *(m_uint *)(mem + VAL) -= n; | |
1006 | 2 | DISPATCH() | |
1007 | } | ||
1008 | ✗ | *(m_uint *)(mem + VAL) = 0; | |
1009 | ✗ | PC_DISPATCH(PC + VAL2 * (idx + 1)); | |
1010 | } | ||
1011 | ✗ | PC_DISPATCH(PC + VAL2 * n + 1); | |
1012 | } | ||
1013 | ✗ | arrayappend: | |
1014 | ✗ | m_vector_add(ARRAY(*(M_Object *)(reg - SZ_INT)), reg); | |
1015 | ✗ | DISPATCH() | |
1016 | 1 | autounrollinit: | |
1017 | 1 | *(m_uint *)(mem + VAL) = | |
1018 | 1 | m_vector_size(ARRAY(*(M_Object *)(mem + VAL + SZ_INT))) + 1; | |
1019 | 1 | DISPATCH() | |
1020 | 24 | autoloop: { | |
1021 | 24 | const M_Vector array = ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT)); | |
1022 | 24 | const bool end = ++*(m_uint *)(mem + VAL2) == m_vector_size(array); | |
1023 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 6 times.
|
24 | if(!end) { |
1024 | 18 | *(m_bit **)(mem + VAL2 + SZ_INT) = | |
1025 | 18 | m_vector_addr(array, *(m_uint *)(mem + VAL2)); | |
1026 | } | ||
1027 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 18 times.
|
24 | BRANCH_DISPATCH(end); |
1028 | } | ||
1029 | 11 | arraytop: | |
1030 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 4 times.
|
11 | if (*(m_uint *)(reg - SZ_INT * 2) < *(m_uint *)(reg - SZ_INT)) |
1031 | 7 | goto newobj; | |
1032 | else | ||
1033 | 4 | goto _goto; | |
1034 | 5 | arrayaccess : { | |
1035 | 5 | register const m_int idx = *(m_int *)(reg + VAL); | |
1036 | 5 | a.obj = *(M_Object *)(reg - VAL2); | |
1037 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
|
5 | if (idx < 0 || (m_uint)idx >= m_vector_size(ARRAY(a.obj))) { |
1038 | 4 | gw_err(_("{-} ... at index {W}[{Y}%" INT_F "{W}]{0}\n"), idx); | |
1039 | // gw_err(_(" ... at dimension [%" INT_F "]\n"), VAL); | ||
1040 | // VM_OUT | ||
1041 | 4 | handle(shred, "ArrayOutofBounds"); | |
1042 | 4 | continue; // or break ? | |
1043 | } | ||
1044 | 1 | DISPATCH() | |
1045 | } | ||
1046 | 1 | arrayget: | |
1047 | 1 | m_vector_get(ARRAY(a.obj), *(m_int *)(reg + VAL), (reg + IVAL2)); | |
1048 | 1 | DISPATCH() | |
1049 | ✗ | arrayaddr: | |
1050 | ✗ | *(m_bit **)(reg + IVAL2) = | |
1051 | ✗ | m_vector_addr(ARRAY(a.obj), *(m_int *)(reg + VAL)); | |
1052 | ✗ | DISPATCH() | |
1053 | 2896 | newobj: | |
1054 | 2896 | *(M_Object *)reg = new_object(vm->gwion->mp, (Type)VAL2); | |
1055 | 2896 | reg += SZ_INT; | |
1056 | 2896 | DISPATCH() | |
1057 | 756 | addref : { | |
1058 | 756 | const M_Object o = *(M_Object *)(reg + IVAL); | |
1059 |
1/2✓ Branch 0 taken 756 times.
✗ Branch 1 not taken.
|
756 | if(o) |
1060 | 756 | ++o->ref; | |
1061 | } | ||
1062 | 756 | DISPATCH() | |
1063 | ✗ | addrefaddr : { | |
1064 | ✗ | const M_Object o = **(M_Object **)(reg + IVAL); | |
1065 | ✗ | if (o) ++o->ref; | |
1066 | } | ||
1067 | ✗ | DISPATCH() | |
1068 | ✗ | structaddref: | |
1069 | ✗ | struct_addref(vm->gwion, (Type)VAL2, (reg + IVAL)); | |
1070 | ✗ | DISPATCH() | |
1071 | ✗ | structaddrefaddr: | |
1072 | ✗ | struct_addref(vm->gwion, (Type)VAL2, *(m_bit **)(reg + IVAL)); | |
1073 | ✗ | DISPATCH() | |
1074 | 7 | objassign : { | |
1075 | 7 | const M_Object o = **(M_Object **)(reg - SZ_INT); | |
1076 | 7 | release(o, shred); | |
1077 | } | ||
1078 | 176 | assign: | |
1079 | 176 | reg -= SZ_INT; | |
1080 | 176 | **(M_Object **)reg = *(M_Object *)(reg - SZ_INT); | |
1081 | 176 | DISPATCH() | |
1082 | 203 | remref: | |
1083 | 203 | release(*(M_Object *)(mem + VAL), shred); | |
1084 | 203 | DISPATCH() | |
1085 | 19 | remref2: | |
1086 | { | ||
1087 | 19 | struct Vector_ v = { .ptr = (m_uint*)VAL }; | |
1088 |
2/2✓ Branch 1 taken 51 times.
✓ Branch 2 taken 19 times.
|
70 | for(m_uint i = 0; i < vector_size(&v); i++) |
1089 | 51 | release(*(M_Object *)(mem + vector_at(&v, i)), shred); | |
1090 | } | ||
1091 | 19 | DISPATCH() | |
1092 | ✗ | structreleaseregaddr: | |
1093 | ✗ | struct_release(shred, (Type)VAL2, *(m_bit**)(reg + IVAL)); | |
1094 | ✗ | DISPATCH(); | |
1095 | 29 | structreleasemem: | |
1096 | 29 | struct_release(shred, (Type)VAL2, mem + IVAL); | |
1097 | 29 | DISPATCH(); | |
1098 | 2 | except: | |
1099 | /* TODO: Refactor except instruction * | ||
1100 | * so that * | ||
1101 | * VAL = offset (no default SZ_INT) * | ||
1102 | * VAL2 = error message * | ||
1103 | * grep for GWOP_EXCEPT and Except, exception... */ | ||
1104 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (!*(m_bit **)(reg + (m_int)(VAL))) { |
1105 | 1 | handle(shred, "NullPtrException"); | |
1106 | 1 | continue; | |
1107 | } | ||
1108 | 1 | DISPATCH(); | |
1109 | 48 | dotmembermem: | |
1110 | 48 | *(m_uint *)reg = | |
1111 | 48 | *(m_uint *)((*(M_Object *)(mem + VAL2))->data + VAL); | |
1112 | 48 | reg += SZ_INT; | |
1113 | 48 | DISPATCH() | |
1114 | 3 | dotmembermem2: | |
1115 | 3 | *(m_float *)(reg + SZ_INT) = | |
1116 | 3 | *(m_float *)((*(M_Object *)(mem + VAL2))->data + VAL); | |
1117 | 3 | reg += SZ_INT - SZ_FLOAT; | |
1118 | 3 | DISPATCH() | |
1119 | // dotmembermem3: | ||
1120 | 1422 | dotmembermem4: | |
1121 | 1422 | *(m_bit **)reg = | |
1122 | 1422 | ((*(M_Object *)(mem + VAL2))->data + VAL); | |
1123 | 1422 | reg += SZ_INT; | |
1124 | 1422 | DISPATCH() | |
1125 | 47 | dotmember: | |
1126 | 47 | *(m_uint *)(reg - SZ_INT) = | |
1127 | 47 | *(m_uint *)((*(M_Object *)(reg - SZ_INT))->data + VAL); | |
1128 | 47 | DISPATCH() | |
1129 | 3 | dotfloat: | |
1130 | 3 | *(m_float *)(reg - SZ_INT) = | |
1131 | 3 | *(m_float *)((*(M_Object *)(reg - SZ_INT))->data + VAL); | |
1132 | 3 | reg += SZ_FLOAT - SZ_INT; | |
1133 | 3 | DISPATCH() | |
1134 | ✗ | dotother: | |
1135 | // LOOP_OPTIM | ||
1136 | ✗ | for (m_uint i = 0; i <= VAL2; i += SZ_INT) | |
1137 | ✗ | *(m_uint *)(reg + i - SZ_INT) = | |
1138 | ✗ | *(m_uint *)(((*(M_Object *)(reg - SZ_INT))->data + VAL) + i); | |
1139 | ✗ | reg += VAL2 - SZ_INT; | |
1140 | ✗ | DISPATCH() | |
1141 | 2 | dotaddr: | |
1142 | 2 | *(m_bit **)(reg - SZ_INT) = ((*(M_Object *)(reg - SZ_INT))->data + VAL); | |
1143 | 2 | DISPATCH() | |
1144 | |||
1145 | #define UNION_CHECK \ | ||
1146 | register const m_bit *data = (*(M_Object *)(reg - SZ_INT))->data; \ | ||
1147 | if (*(m_uint *)data != VAL) { \ | ||
1148 | handle(shred, "invalid union acces"); \ | ||
1149 | continue; \ | ||
1150 | } | ||
1151 | |||
1152 | ✗ | unioncheck : { | |
1153 | ✗ | if (*(m_uint *)(*(M_Object *)(reg - SZ_INT))->data != VAL2) { | |
1154 | ✗ | reg -= SZ_INT; | |
1155 | ✗ | PC_DISPATCH(VAL); | |
1156 | } | ||
1157 | ✗ | DISPATCH() | |
1158 | } | ||
1159 | 4 | unionint : { | |
1160 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
|
4 | UNION_CHECK |
1161 | 3 | *(m_uint *)(reg - SZ_INT) = *(m_uint *)(data + SZ_INT); | |
1162 | 3 | DISPATCH() | |
1163 | } | ||
1164 | 1 | unionfloat : { | |
1165 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | UNION_CHECK |
1166 | 1 | *(m_float *)(reg - SZ_INT) = *(m_float *)(data + SZ_INT); | |
1167 | 1 | reg += SZ_FLOAT - SZ_INT; | |
1168 | 1 | DISPATCH() | |
1169 | } | ||
1170 | ✗ | unionother : { | |
1171 | ✗ | UNION_CHECK | |
1172 | ✗ | for (m_uint i = 0; i <= VAL2; i += SZ_INT) | |
1173 | ✗ | *(m_uint *)(reg + i - SZ_INT) = *(m_uint *)(data + SZ_INT + i); | |
1174 | ✗ | reg += VAL2 - SZ_INT; | |
1175 | ✗ | DISPATCH() | |
1176 | } | ||
1177 | 3 | unionaddr : { | |
1178 | 3 | *(m_uint *)(*(M_Object *)(reg - SZ_INT))->data = VAL; | |
1179 | 3 | *(m_bit **)(reg - SZ_INT) = | |
1180 | 3 | &*(m_bit *)((*(M_Object *)(reg - SZ_INT))->data + SZ_INT); | |
1181 | 3 | DISPATCH() | |
1182 | } | ||
1183 | 37 | staticint: | |
1184 | 37 | *(m_uint *)reg = *(m_uint *)VAL; | |
1185 | 37 | reg += SZ_INT; | |
1186 | 37 | DISPATCH() | |
1187 | 3 | staticfloat: | |
1188 | 3 | *(m_float *)reg = *(m_float *)VAL; | |
1189 | 3 | reg += SZ_FLOAT; | |
1190 | 3 | DISPATCH() | |
1191 | ✗ | staticother: | |
1192 | // LOOP_OPTIM | ||
1193 | // for(m_uint i = 0; i <= VAL2; i += SZ_INT) | ||
1194 | // *(m_uint*)(reg+i) = *(m_uint*)((m_bit*)VAL + i); | ||
1195 | ✗ | memcpy(reg, (m_bit *)VAL, VAL2); | |
1196 | ✗ | reg += VAL2; | |
1197 | ✗ | DISPATCH() | |
1198 | 283 | dotfunc: | |
1199 | 283 | *(VM_Code *)(reg + IVAL2) = | |
1200 | 283 | ((Func)(*(M_Object *)(reg - SZ_INT))->type_ref->nspc->vtable.ptr[OFFSET + VAL])->code; | |
1201 | 283 | DISPATCH() | |
1202 | 224 | gacktype : { | |
1203 | 224 | const M_Object o = *(M_Object *)(reg - SZ_INT); | |
1204 |
1/2✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
|
224 | if (o) *(Type *)reg = o->type_ref; |
1205 | } | ||
1206 | 224 | DISPATCH() | |
1207 | 1106 | gackend : { | |
1208 | 1106 | m_str str = *(m_str *)(reg - SZ_INT); | |
1209 |
2/2✓ Branch 0 taken 985 times.
✓ Branch 1 taken 121 times.
|
1106 | if (!VAL) { |
1210 | 985 | gw_out("%s\n", str); | |
1211 | 985 | fflush(stdout); | |
1212 | } else | ||
1213 | 121 | *(M_Object *)(reg - SZ_INT) = new_string(vm->gwion, str); | |
1214 |
1/2✓ Branch 0 taken 1106 times.
✗ Branch 1 not taken.
|
1106 | if (str) mp_free2(vm->gwion->mp, strlen(str), str); |
1215 | 1106 | DISPATCH(); | |
1216 | } | ||
1217 | 1606 | gack: | |
1218 | 1606 | VM_OUT | |
1219 | 1606 | gack(shred, VAL); | |
1220 | 1606 | goto vmin; | |
1221 | 3 | try_ini: | |
1222 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | if (!shred->info->frame.ptr) // ??? |
1223 | 3 | vector_init(&shred->info->frame); | |
1224 | 3 | vector_add(&shred->info->frame, PC); | |
1225 | 3 | vector_add(&shred->info->frame, (m_uint)reg); | |
1226 | 3 | DISPATCH(); | |
1227 | 3 | try_end: | |
1228 | 3 | vector_pop(&shred->info->frame); | |
1229 | 3 | vector_pop(&shred->info->frame); | |
1230 | 3 | handleeffect: | |
1231 | // this should check the *xid* of the exception | ||
1232 | 3 | DISPATCH(); | |
1233 | 1 | performeffect: | |
1234 | { | ||
1235 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | const m_str effect = (m_str)VAL ?: *(m_str*)(mem + VAL2); |
1236 | 1 | handle(shred, effect); | |
1237 | } | ||
1238 | 1 | break; | |
1239 | 2 | noop: | |
1240 | 2 | DISPATCH(); | |
1241 | 372 | other: | |
1242 | 372 | VM_OUT((f_instr)VAL2)(shred, (Instr)VAL); | |
1243 | 1978 | vmin: | |
1244 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1958 times.
|
1978 | if (!s->curr) break; |
1245 | 1958 | bytecode = (code = shred->code)->bytecode; | |
1246 | 1958 | reg = shred->reg; | |
1247 | 1958 | mem = shred->mem; | |
1248 | 1958 | PC_DISPATCH(shred->pc) | |
1249 | ✗ | debugline: | |
1250 | ✗ | if (!shred->info->line.ptr) { // from a problem with spork it seems | |
1251 | ✗ | vector_init(&shred->info->line); | |
1252 | ✗ | vector_add(&shred->info->line, VAL); | |
1253 | ✗ | } else if (!VAL) { | |
1254 | ✗ | vector_add(&shred->info->line, VAL); | |
1255 | } else { | ||
1256 | ✗ | const m_uint sz = vector_size(&shred->info->line); | |
1257 | ✗ | vector_set(&shred->info->line, sz - 1, VAL); | |
1258 | } | ||
1259 | ✗ | DISPATCH(); | |
1260 | ✗ | debugvalue: | |
1261 | ✗ | DISPATCH(); | |
1262 | ✗ | debugpush: | |
1263 | ✗ | if (!shred->info->line.ptr) vector_init(&shred->info->line); | |
1264 | ✗ | vector_add(&shred->info->line, 0); | |
1265 | ✗ | DISPATCH(); | |
1266 | ✗ | debugpop: | |
1267 | ✗ | vector_pop(&shred->info->line); | |
1268 | ✗ | DISPATCH(); | |
1269 | 370 | eoc: | |
1270 | 370 | VM_OUT | |
1271 | 370 | vm_shred_exit(shred); | |
1272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
|
380 | } while (s->curr); |
1273 | } | ||
1274 | PRAGMA_POP() | ||
1275 | } else { | ||
1276 | |||
1277 | static void *_dispatch[] = { | ||
1278 | &&_regsetimm, &&_regpushimm, &&_regpushfloat, &&_regpushother, &&_regpushaddr, | ||
1279 | &&_regpushmem, &&_regpushmemfloat, &&_regpushmemother, &&_regpushmemaddr, | ||
1280 | &&_regpushmemderef, &&_pushnow, &&_baseint, &&_basefloat, &&_baseother, | ||
1281 | &&_baseaddr, &&_regtoreg, &&_regtoregother2, &&_regtoregaddr, &&_regtoregderef, | ||
1282 | &&_structmember, &&_structmemberfloat, &&_structmemberother, | ||
1283 | &&_structmemberaddr, &&_memsetimm, &&_memaddimm, &&_repeatidx, &&_repeat, | ||
1284 | &&_regpushme, &&_regpushmaybe, &&_funcreturn, &&__goto, &&_allocint, | ||
1285 | &&_allocfloat, &&_allocother, | ||
1286 | &&_intplus, &&_intminus, &&_intmul, &&_intdiv, &&_intmod, | ||
1287 | &&_intplusimm, &&_intminusimm, &&_intmulimm, &&_intdivimm, &&_intmodimm, | ||
1288 | // int relationnal | ||
1289 | &&_inteq, &&_intne, &&_intand, &&_intor, | ||
1290 | &&_intgt, &&_intge, &&_intlt, &&_intle, | ||
1291 | &&_intgtimm, &&_intgeimm, &&_intltimm, &&_intleimm, | ||
1292 | &&_intsl, &&_intsr, &&_intsand, &&_intsor, &&_intxor, &&_intnegate, &&_intnot, | ||
1293 | &&_intcmp, &&_intrassign, &&_intradd, &&_intrsub, &&_intrmul, &&_intrdiv, | ||
1294 | &&_intrmod, &&_intrsl, &&_intrsr, &&_intrsand, &&_intrsor, &&_intrxor, &&_preinc, | ||
1295 | &&_predec, &&_postinc, &&_postdec, | ||
1296 | &&_floatadd, &&_floatsub, &&_floatmul, &&_floatdiv, | ||
1297 | &&_floataddimm, &&_floatsubimm, &&_floatmulimm, &&_floatdivimm, | ||
1298 | // logical | ||
1299 | &&_floatand, &&_floator, &&_floateq, &&_floatne, | ||
1300 | &&_floatgt, &&_floatge, &&_floatlt, &&_floatle, | ||
1301 | &&_floatgtimm, &&_floatgeimm, &&_floatltimm, &&_floatleimm, | ||
1302 | &&_floatneg, &&_floatnot, &&_floatrassign, &&_floatradd, | ||
1303 | &&_floatrsub, &&_floatrmul, &&_floatrdiv, &&_ifadd, &&_ifsub, &&_ifmul, &&_ifdiv, | ||
1304 | &&_ifand, &&_ifor, &&_ifeq, &&_ifne, &&_ifgt, &&_ifge, &&_iflt, &&_ifle, | ||
1305 | &&_ifrassign, &&_ifradd, &&_ifrsub, &&_ifrmul, &&_ifrdiv, &&_fiadd, &&_fisub, | ||
1306 | &&_fimul, &&_fidiv, &&_fiand, &&_fior, &&_fieq, &&_fine, &&_figt, &&_fige, &&_filt, | ||
1307 | &&_file, &&_firassign, &&_firadd, &&_firsub, &&_firmul, &&_firdiv, &&_itof, | ||
1308 | &&_ftoi, &&_timeadv, &&_recurs, &&_setcode, &&_regmove, | ||
1309 | &&_regtomem, &&_regtomemother, | ||
1310 | &&_overflow, | ||
1311 | &&_funcusrend, &&_funcusrend2, &&_funcmemberend, | ||
1312 | &&_sporkini, &&_forkini, &&_sporkfunc, &&_sporkexp, &&_sporkcode, &&_forkend, | ||
1313 | &&_sporkend, &&_brancheqint, &&_branchneint, &&_brancheqfloat, | ||
1314 | &&_branchnefloat, &&_unroll, &&_arrayappend, &&_autounrollinit, &&_autoloop, | ||
1315 | &&_arraytop, &&_arrayaccess, &&_arrayget, &&_arrayaddr, &&_newobj, &&_addref, | ||
1316 | &&_addrefaddr, &&_structaddref, &&_structaddrefaddr, &&_objassign, &&_assign, | ||
1317 | &&_remref, &&_remref2, &&_structreleaseregaddr, &&_structreleasemem, | ||
1318 | &&_except, | ||
1319 | &&_dotmembermem, &&_dotmembermem2, /*&&_dotmembermem3, */&&_dotmembermem4, | ||
1320 | &&_dotmember, &&_dotfloat, &&_dotother, &&_dotaddr, | ||
1321 | &&_unioncheck, &&_unionint, &&_unionfloat, | ||
1322 | &&_unionother, &&_unionaddr, &&_staticint, &&_staticfloat, &&_staticother, | ||
1323 | &&_dotfunc, &&_gacktype, &&_gackend, &&_gack, &&_try_ini, | ||
1324 | &&_try_end, &&_handleeffect, &&_performeffect, &&_noop, &&_debugline, | ||
1325 | &&_debugvalue, &&_debugpush, &&_debugpop, &&_eoc, &&_vmin, &&_other}; | ||
1326 | |||
1327 | #define PREPARE(a) \ | ||
1328 | _##a: \ | ||
1329 | *(void**)prepare_code = &&a;\ | ||
1330 | prepare_code += BYTECODE_SZ;\ | ||
1331 | goto *_dispatch[*(m_bit*)prepare_code]; | ||
1332 | |||
1333 | 3035 | goto *_dispatch[*(m_bit*)prepare_code]; | |
1334 | 2279 | PREPARE(regsetimm); | |
1335 | 1912 | PREPARE(regpushimm); | |
1336 | 129 | PREPARE(regpushfloat); | |
1337 | ✗ | PREPARE(regpushother); | |
1338 | ✗ | PREPARE(regpushaddr); | |
1339 | 372 | PREPARE(regpushmem); | |
1340 | 94 | PREPARE(regpushmemfloat); | |
1341 | 1 | PREPARE(regpushmemother); | |
1342 | 242 | PREPARE(regpushmemaddr); | |
1343 | 17 | PREPARE(regpushmemderef); | |
1344 | 75 | PREPARE(pushnow); | |
1345 | 285 | PREPARE(baseint); | |
1346 | 12 | PREPARE(basefloat); | |
1347 | ✗ | PREPARE(baseother); | |
1348 | 51 | PREPARE(baseaddr); | |
1349 | 143 | PREPARE(regtoreg); | |
1350 | 1 | PREPARE(regtoregother2); | |
1351 | ✗ | PREPARE(regtoregaddr); | |
1352 | 14 | PREPARE(regtoregderef); | |
1353 | 22 | PREPARE(structmember); | |
1354 | 17 | PREPARE(structmemberfloat); | |
1355 | ✗ | PREPARE(structmemberother); | |
1356 | 33 | PREPARE(structmemberaddr) | |
1357 | 34 | PREPARE(memsetimm); | |
1358 | ✗ | PREPARE(memaddimm); | |
1359 | 1 | PREPARE(repeatidx); | |
1360 | 7 | PREPARE(repeat); | |
1361 | 53 | PREPARE(regpushme); | |
1362 | 19 | PREPARE(regpushmaybe); | |
1363 | // PREPARE(funcreturn); | ||
1364 | 345 | _funcreturn: | |
1365 | 345 | *(void**)prepare_code = &&funcreturn; | |
1366 | 345 | return; | |
1367 | |||
1368 | 109 | PREPARE(_goto); | |
1369 | 126 | PREPARE(allocint); | |
1370 | 75 | PREPARE(allocfloat); | |
1371 | ✗ | PREPARE(allocother) | |
1372 | 17 | PREPARE(intplus); | |
1373 | 1 | PREPARE(intminus); | |
1374 | 1 | PREPARE(intmul); | |
1375 | 3 | PREPARE(intdiv); | |
1376 | 1 | PREPARE(intmod); | |
1377 | 2 | PREPARE(intplusimm); | |
1378 | 12 | PREPARE(intminusimm); | |
1379 | ✗ | PREPARE(intmulimm); | |
1380 | ✗ | PREPARE(intdivimm); | |
1381 | ✗ | PREPARE(intmodimm); | |
1382 | |||
1383 | 14 | PREPARE(inteq); | |
1384 | 2 | PREPARE(intne); | |
1385 | 1 | PREPARE(intand); | |
1386 | 1 | PREPARE(intor); | |
1387 | 1 | PREPARE(intgt); | |
1388 | 1 | PREPARE(intge); | |
1389 | 2 | PREPARE(intlt); | |
1390 | 1 | PREPARE(intle); | |
1391 | 4 | PREPARE(intgtimm); | |
1392 | ✗ | PREPARE(intgeimm); | |
1393 | 10 | PREPARE(intltimm); | |
1394 | ✗ | PREPARE(intleimm); | |
1395 | 1 | PREPARE(intsl); | |
1396 | 1 | PREPARE(intsr); | |
1397 | 1 | PREPARE(intsand); | |
1398 | 1 | PREPARE(intsor); | |
1399 | 1 | PREPARE(intxor); | |
1400 | |||
1401 | 1 | PREPARE(intnegate); | |
1402 | 6 | PREPARE(intnot); | |
1403 | ✗ | PREPARE(intcmp); | |
1404 | |||
1405 | 78 | PREPARE(intrassign); | |
1406 | |||
1407 | 1 | PREPARE(intradd); | |
1408 | 1 | PREPARE(intrsub); | |
1409 | 1 | PREPARE(intrmul); | |
1410 | 1 | PREPARE(intrdiv); | |
1411 | 1 | PREPARE(intrmod); | |
1412 | 1 | PREPARE(intrsl); | |
1413 | 1 | PREPARE(intrsr); | |
1414 | 1 | PREPARE(intrsand); | |
1415 | 1 | PREPARE(intrsor); | |
1416 | 1 | PREPARE(intrxor) | |
1417 | |||
1418 | 4 | PREPARE(preinc); | |
1419 | 5 | PREPARE(predec); | |
1420 | 21 | PREPARE(postinc); | |
1421 | 5 | PREPARE(postdec); | |
1422 | |||
1423 | 5 | PREPARE(floatadd); | |
1424 | 1 | PREPARE(floatsub); | |
1425 | 8 | PREPARE(floatmul); | |
1426 | 1 | PREPARE(floatdiv); | |
1427 | ✗ | PREPARE(floataddimm); | |
1428 | 1 | PREPARE(floatsubimm); | |
1429 | ✗ | PREPARE(floatmulimm); | |
1430 | ✗ | PREPARE(floatdivimm); | |
1431 | |||
1432 | 1 | PREPARE(floatand); | |
1433 | 1 | PREPARE(floator); | |
1434 | 2 | PREPARE(floateq); | |
1435 | 1 | PREPARE(floatne); | |
1436 | 1 | PREPARE(floatgt); | |
1437 | 3 | PREPARE(floatge); | |
1438 | 3 | PREPARE(floatlt); | |
1439 | 1 | PREPARE(floatle); | |
1440 | 1 | PREPARE(floatgtimm); | |
1441 | ✗ | PREPARE(floatgeimm); | |
1442 | ✗ | PREPARE(floatltimm); | |
1443 | ✗ | PREPARE(floatleimm); | |
1444 | |||
1445 | 1 | PREPARE(floatneg); | |
1446 | 3 | PREPARE(floatnot); | |
1447 | |||
1448 | 12 | PREPARE(floatrassign); | |
1449 | |||
1450 | 1 | PREPARE(floatradd); | |
1451 | 2 | PREPARE(floatrsub); | |
1452 | 1 | PREPARE(floatrmul); | |
1453 | 1 | PREPARE(floatrdiv); | |
1454 | |||
1455 | 1 | PREPARE(ifadd); | |
1456 | 2 | PREPARE(ifsub); | |
1457 | 20 | PREPARE(ifmul); | |
1458 | 1 | PREPARE(ifdiv); | |
1459 | |||
1460 | 1 | PREPARE(ifand); | |
1461 | 1 | PREPARE(ifor); | |
1462 | 1 | PREPARE(ifeq); | |
1463 | 1 | PREPARE(ifne); | |
1464 | 1 | PREPARE(ifgt); | |
1465 | 1 | PREPARE(ifge); | |
1466 | 1 | PREPARE(iflt); | |
1467 | 1 | PREPARE(ifle); | |
1468 | |||
1469 | 12 | PREPARE(ifrassign); | |
1470 | 3 | PREPARE(ifradd); | |
1471 | 4 | PREPARE(ifrsub); | |
1472 | 1 | PREPARE(ifrmul); | |
1473 | 1 | PREPARE(ifrdiv); | |
1474 | |||
1475 | 1 | PREPARE(fiadd); | |
1476 | 1 | PREPARE(fisub); | |
1477 | 1 | PREPARE(fimul); | |
1478 | 1 | PREPARE(fidiv); | |
1479 | |||
1480 | 1 | PREPARE(fiand); | |
1481 | 1 | PREPARE(fior); | |
1482 | 2 | PREPARE(fieq); | |
1483 | 1 | PREPARE(fine); | |
1484 | 4 | PREPARE(figt); | |
1485 | 1 | PREPARE(fige); | |
1486 | 1 | PREPARE(filt); | |
1487 | 1 | PREPARE(file); | |
1488 | |||
1489 | 1 | PREPARE(firassign); | |
1490 | |||
1491 | 1 | PREPARE(firadd); | |
1492 | 2 | PREPARE(firsub); | |
1493 | 1 | PREPARE(firmul); | |
1494 | 1 | PREPARE(firdiv); | |
1495 | |||
1496 | 15 | PREPARE(itof); | |
1497 | 1 | PREPARE(ftoi); | |
1498 | |||
1499 | 63 | PREPARE(timeadv); | |
1500 | |||
1501 | 12 | PREPARE(recurs); | |
1502 | |||
1503 | 4994 | PREPARE(setcode); | |
1504 | 1730 | PREPARE(regmove); | |
1505 | 552 | PREPARE(regtomem); | |
1506 | 98 | PREPARE(regtomemother); | |
1507 | 5006 | PREPARE(overflow); | |
1508 | ✗ | PREPARE(funcusrend); | |
1509 | ✗ | PREPARE(funcusrend2); | |
1510 | ✗ | PREPARE(funcmemberend); | |
1511 | 45 | PREPARE(sporkini); | |
1512 | 5 | PREPARE(forkini); | |
1513 | 24 | PREPARE(sporkfunc); | |
1514 | 26 | PREPARE(sporkexp); | |
1515 | 6 | PREPARE(sporkcode); | |
1516 | 5 | PREPARE(forkend); | |
1517 | 45 | PREPARE(sporkend); | |
1518 | 77 | PREPARE(brancheqint); | |
1519 | 23 | PREPARE(branchneint); | |
1520 | 4 | PREPARE(brancheqfloat); | |
1521 | 2 | PREPARE(branchnefloat); | |
1522 | 1 | PREPARE(unroll); | |
1523 | ✗ | PREPARE(arrayappend); | |
1524 | 1 | PREPARE(autounrollinit); | |
1525 | 7 | PREPARE(autoloop); | |
1526 | 4 | PREPARE(arraytop); | |
1527 | 6 | PREPARE(arrayaccess); | |
1528 | 6 | PREPARE(arrayget); | |
1529 | ✗ | PREPARE(arrayaddr); | |
1530 | 167 | PREPARE(newobj); | |
1531 | 358 | PREPARE(addref); | |
1532 | ✗ | PREPARE(addrefaddr); | |
1533 | ✗ | PREPARE(structaddref); | |
1534 | ✗ | PREPARE(structaddrefaddr); | |
1535 | 7 | PREPARE(objassign); | |
1536 | 178 | PREPARE(assign); | |
1537 | 125 | PREPARE(remref); | |
1538 | 24 | PREPARE(remref2); | |
1539 | ✗ | PREPARE(structreleaseregaddr); | |
1540 | 30 | PREPARE(structreleasemem); | |
1541 | 6 | PREPARE(except); | |
1542 | 35 | PREPARE(dotmembermem); | |
1543 | 6 | PREPARE(dotmembermem2); | |
1544 | //PREPARE(dotmembermem3); | ||
1545 | 54 | PREPARE(dotmembermem4); | |
1546 | 32 | PREPARE(dotmember); | |
1547 | 3 | PREPARE(dotfloat); | |
1548 | ✗ | PREPARE(dotother); | |
1549 | 2 | PREPARE(dotaddr); | |
1550 | ✗ | PREPARE(unioncheck); | |
1551 | 4 | PREPARE(unionint); | |
1552 | 1 | PREPARE(unionfloat); | |
1553 | ✗ | PREPARE(unionother); | |
1554 | 3 | PREPARE(unionaddr); | |
1555 | 42 | PREPARE(staticint); | |
1556 | 6 | PREPARE(staticfloat); | |
1557 | ✗ | PREPARE(staticother); | |
1558 | 129 | PREPARE(dotfunc); | |
1559 | 132 | PREPARE(gacktype); | |
1560 | 650 | PREPARE(gackend); | |
1561 | 862 | PREPARE(gack); | |
1562 | 3 | PREPARE(try_ini); | |
1563 | 3 | PREPARE(try_end); | |
1564 | 3 | PREPARE(handleeffect); | |
1565 | 1 | PREPARE(performeffect); | |
1566 | ✗ | PREPARE(noop); | |
1567 | 9203 | _other: | |
1568 | { | ||
1569 | 9203 | *(void**)prepare_code = &&other; | |
1570 | 9203 | const f_instr exec = *(f_instr*)(prepare_code + SZ_INT *2); | |
1571 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9201 times.
|
9203 | if(exec == DTOR_EOC)return; |
1572 | 9201 | const Instr instr = *(Instr*)(prepare_code + SZ_INT); | |
1573 |
4/4✓ Branch 0 taken 9182 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 9177 times.
|
9201 | if(exec == fast_except || exec == FuncWait) |
1574 | 24 | instr->opcode = (m_uint)&&noop; | |
1575 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 9163 times.
|
9177 | else if(exec == SetFunc) |
1576 | 14 | instr->opcode = (m_uint)&®pushimm; | |
1577 | 9201 | prepare_code += BYTECODE_SZ; | |
1578 | 9201 | goto *_dispatch[*(m_bit*)prepare_code]; | |
1579 | } | ||
1580 | ✗ | PREPARE(vmin); | |
1581 | ✗ | PREPARE(debugline); | |
1582 | ✗ | PREPARE(debugvalue); | |
1583 | ✗ | PREPARE(debugpush); | |
1584 | ✗ | PREPARE(debugpop); | |
1585 | 4865 | _eoc: | |
1586 | 4865 | *(void**)prepare_code = &&eoc; | |
1587 | 4865 | return; | |
1588 | } | ||
1589 | } | ||
1590 | |||
1591 | // remove me | ||
1592 | 3287132 | ANN void next_bbq_pos(const VM *vm) { | |
1593 | 3287132 | Driver *const di = vm->bbq; | |
1594 | 3287132 | MUTEX_LOCK(vm->shreduler->mutex); | |
1595 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3287132 times.
|
3287132 | if(++di->pos == 16777216-1) { |
1596 | ✗ | const Vector v = &vm->shreduler->active_shreds; | |
1597 | ✗ | for(m_uint i = 0; i < vector_size(v); i++) { | |
1598 | ✗ | const VM_Shred shred = (VM_Shred)vector_at(v, i); | |
1599 | ✗ | shred->tick->wake_time -= 16777216.0; | |
1600 | } | ||
1601 | ✗ | di->pos = 0; | |
1602 | } | ||
1603 | 3287132 | MUTEX_UNLOCK(vm->shreduler->mutex); | |
1604 | 3287132 | } | |
1605 | |||
1606 | 6058889 | ANN void vm_run_audio(const VM *vm) { | |
1607 | 6058889 | vm_run(vm); | |
1608 | 6078098 | compute_audio(vm); | |
1609 | 5924585 | } | |
1610 | |||
1611 | 712 | VM *new_vm(MemPool p, const bool audio) { | |
1612 | 712 | VM *vm = (VM *)mp_calloc(p, VM); | |
1613 | 712 | vector_init(&vm->ugen); | |
1614 | 712 | vm->shreduler = new_shreduler(p); | |
1615 | 712 | vm->bbq = vm->shreduler->bbq = new_driver(p); | |
1616 |
1/2✓ Branch 0 taken 712 times.
✗ Branch 1 not taken.
|
712 | vm->bbq->run = audio |
1617 | ? vm_run_audio | ||
1618 | : vm_run; | ||
1619 | #ifndef __AFL_COMPILER | ||
1620 | 712 | gw_seed(vm->rand, (uint64_t)time(NULL)); | |
1621 | #else | ||
1622 | gw_seed(vm->rand, 0); | ||
1623 | #endif | ||
1624 | 712 | return vm; | |
1625 | } | ||
1626 | |||
1627 | 707 | ANN void vm_clean(const VM* vm, const Gwion gwion) { | |
1628 | 707 | gwion_end_child(vm->cleaner_shred, gwion); | |
1629 |
1/2✓ Branch 0 taken 707 times.
✗ Branch 1 not taken.
|
707 | if (vm->bbq) free_driver(vm->bbq, gwion->vm); |
1630 | 707 | } | |
1631 | |||
1632 | 708 | ANN void free_vm(VM *vm) { | |
1633 | 708 | const MemPool mp = vm->gwion->mp; | |
1634 |
2/2✓ Branch 0 taken 638 times.
✓ Branch 1 taken 70 times.
|
708 | if (vm->cleaner_shred) free_vm_shred(vm->cleaner_shred); |
1635 | 708 | free_shreduler(mp, vm->shreduler); | |
1636 | 708 | vector_release(&vm->ugen); | |
1637 | 708 | mp_free(mp, VM, vm); | |
1638 | 708 | } | |
1639 |