Gwion coverage report


Directory: src/
File: src/vm/vm.c
Date: 2023-01-30 18:32:28
Exec Total Coverage
Lines: 920 1118 82.3%
Functions: 26 30 86.7%
Branches: 129 224 57.6%

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 &&regsetimm, &&regpushimm, &&regpushfloat, &&regpushother, &&regpushaddr,
427 &&regpushmem, &&regpushmemfloat, &&regpushmemother, &&regpushmemaddr,
428 &&regpushmemderef, &&pushnow, &&baseint, &&basefloat, &&baseother,
429 &&baseaddr, &&regtoreg, &&regtoregother2, &&regtoregaddr, &&regtoregderef,
430 &&structmember, &&structmemberfloat, &&structmemberother,
431 &&structmemberaddr, &&memsetimm, &&memaddimm, &&repeatidx, &&repeat,
432 &&regpushme, &&regpushmaybe, &&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, &&regmove,
457 &&regtomem, &&regtomemother,
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 // &&regpushimm};
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)&&regpushimm;
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