GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gwion.c Lines: 137 138 99.3 %
Date: 2020-09-14 20:46:08 Branches: 35 38 92.1 %

Line Branch Exec Source
1
#include "gwion_util.h"
2
#include "gwion_ast.h"
3
#include "gwion_env.h"
4
#include "vm.h"
5
#include "instr.h"
6
#include "emit.h"
7
#include "driver.h"
8
#include "gwion.h"
9
#include "engine.h"
10
#include "arg.h"
11
#include "compile.h"
12
#include "object.h" // fork_clean
13
#include "pass.h" // fork_clean
14
#include "shreduler_private.h"
15
16
710
ANN static void driver_arg(const Gwion gwion, Driver *di) {
17
715
  for(m_uint i = 0; i < map_size(&gwion->data->plug->drv); ++i) {
18
6
    const m_str name = (m_str)VKEY(&gwion->data->plug->drv, i);
19
6
    const size_t len = strlen(name);
20
6
    if(!strncmp(name, di->si->arg, len)) {
21
1
      di->func = (f_bbqset)VVAL(&gwion->data->plug->drv, i);
22
1
      break;
23
    }
24
  }
25
710
}
26
27
712
ANN m_bool gwion_audio(const Gwion gwion) {
28
712
  Driver *const di = gwion->vm->bbq;
29
712
  if(di->si->arg)
30
710
    driver_arg(gwion, di);
31
712
  di->func(di->driver);
32
712
  CHECK_BB(di->driver->ini(gwion->vm, di));
33
712
  driver_alloc(di);
34
712
  return GW_OK;
35
}
36
37
712
ANN static inline m_bool gwion_engine(const Gwion gwion) {
38
712
  return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
39
}
40
41
712
ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
42
2045
  for(m_uint i = 0; i < vector_size(v); i++)
43
1333
    compile_filename(gwion, (m_str)vector_at(v, i));
44
712
}
45
46
712
ANN static void gwion_cleaner(const Gwion gwion) {
47
712
  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
48
712
  gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
49
712
  vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
50
712
}
51
52
8
ANN VM* gwion_cpy(const VM* src) {
53
8
  const Gwion gwion = mp_calloc(src->gwion->mp, Gwion);
54
8
  gwion->vm = new_vm(src->gwion->mp, 0);
55
8
  gwion->vm->gwion = gwion;
56
8
  gwion->vm->bbq->si = soundinfo_cpy(src->gwion->mp, src->bbq->si);
57
8
  gwion->emit = src->gwion->emit;
58
8
  gwion->env = src->gwion->env;
59
8
  gwion->data = cpy_gwiondata(src->gwion->mp, src->gwion->data);
60
8
  gwion->st = src->gwion->st;
61
8
  gwion->mp = src->gwion->mp;
62
8
  gwion->type = src->gwion->type;
63
8
  return gwion->vm;
64
}
65
66
715
ANN static void gwion_core(const Gwion gwion) {
67
715
  gwion->vm = new_vm(gwion->mp, 1);
68
715
  gwion->emit = new_emitter(gwion->mp);
69
715
  gwion->env = new_env(gwion->mp);
70
715
  gwion->emit->env = gwion->env;
71
715
  gwion->vm->gwion = gwion->emit->gwion = gwion->env->gwion = gwion;
72
715
}
73
74
712
ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
75
712
  gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
76
712
  shreduler_set_loop(gwion->vm->shreduler, arg->loop);
77
712
  if(gwion_audio(gwion) > 0) {
78
712
    plug_run(gwion, &arg->mod);
79
712
    if(gwion_engine(gwion)) {
80
712
      gwion_cleaner(gwion);
81
712
      gwion_compile(gwion, &arg->add);
82
712
      return GW_OK;
83
    }
84
  }
85
  return GW_ERROR;
86
}
87
88
715
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
89
715
  gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM));
90
715
  gwion->st = new_symbol_table(gwion->mp, 65347);
91
715
  gwion->ppa = mp_calloc(gwion->mp, PPArg);
92
715
  pparg_ini(gwion->mp, gwion->ppa);
93
715
  gwion_core(gwion);
94
715
  gwion->data = new_gwiondata(gwion->mp);
95
715
  gwion->type = (Type*)xcalloc(MAX_TYPE, sizeof(struct Type_*));
96
715
  pass_default(gwion);
97
715
  arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp);
98
715
  CHECK_BB(arg_parse(gwion, arg))
99
712
  return gwion_ok(gwion, arg);
100
}
101
102
712
ANN void gwion_run(const Gwion gwion) {
103
712
  VM* vm = gwion->vm;
104
712
  vm->bbq->driver->run(vm, vm->bbq);
105
711
}
106
107
8
ANN static inline void free_gwion_cpy(const Gwion gwion, const VM_Shred shred) {
108
8
  gwion_end_child(shred, gwion);
109
8
  free_vm(gwion->vm);
110
8
  free_gwiondata_cpy(gwion->mp, gwion->data);
111
8
  mp_free(gwion->mp, Gwion, gwion);
112
8
}
113
114
8
ANN static void fork_clean2(const VM_Shred shred, const Vector v) {
115
16
  for(m_uint i = 0; i < vector_size(v); ++i) {
116
8
    const Gwion gwion = (Gwion)vector_at(v, i);
117
8
    free_gwion_cpy(gwion, shred);
118
  }
119
8
  vector_release(v);
120
8
  v->ptr = NULL;
121
8
}
122
123
730
ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) {
124
730
  if(gwion->data->child.ptr)
125
8
    fork_clean(shred, &gwion->data->child);
126
730
  if(gwion->data->child2.ptr)
127
8
    fork_clean2(shred, &gwion->data->child2);
128
730
}
129
130
714
ANN void gwion_end(const Gwion gwion) {
131
714
  gwion_end_child(gwion->vm->cleaner_shred, gwion);
132
714
  free_env(gwion->env);
133
714
  if(gwion->vm->cleaner_shred)
134
711
    free_vm_shred(gwion->vm->cleaner_shred);
135
714
  free_emitter(gwion->mp, gwion->emit);
136
714
  free_vm(gwion->vm);
137
714
  pparg_end(gwion->ppa);
138
714
  mp_free(gwion->mp, PPArg, gwion->ppa);
139
714
  free_gwiondata(gwion);
140
714
  free_symbols(gwion->st);
141
714
  xfree(gwion->type);
142
714
  mempool_end(gwion->mp);
143
714
}
144
145
262
ANN static void env_header(const Env env) {
146
262
  if(env->class_def)
147
40
    gw_err(_("in class: '%s'\n"), env->class_def->name);
148
262
  if(env->func)
149
26
    gw_err(_("in function: '%s'\n"), env->func->name);
150
262
}
151
152
373
ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) {
153

373
  if(env->context && env->context->error)
154
111
    return;
155
#ifndef __FUZZING__
156
262
  env_header(env);
157
262
  loc_header(pos, env->name);
158
  va_list arg;
159
262
  va_start(arg, fmt);
160
262
  vfprintf(stderr, fmt, arg);
161
262
  va_end(arg);
162
262
  fprintf(stderr, "\n");
163
262
  loc_err(pos, env->name);
164
#endif
165
262
  if(env->context)
166
216
    env->context->error = 1;
167
}
168
169
4067
ANN struct SpecialId_* specialid_get(const Gwion gwion, const Symbol sym) {
170
4067
  const Map map = &gwion->data->id;
171
25737
  for(m_uint i = 0; i < map_size(map); ++i) {
172
22380
    if(sym == (Symbol)VKEY(map, i))
173
710
      return (struct SpecialId_*)VVAL(map, i);
174
  }
175
3357
  return NULL;
176
}
177
178
1424
ANN void push_global(struct Gwion_ *gwion, const m_str name) {
179
1424
  const Nspc nspc = new_nspc(gwion->mp, name);
180
1424
  nspc->parent = gwion->env->global_nspc;
181
1424
  gwion->env->curr = gwion->env->global_nspc = nspc;
182
1424
}
183
184
2136
ANN Nspc pop_global(struct Gwion_ *gwion) {
185
2136
  const Nspc nspc = gwion->env->global_nspc->parent;
186
2136
  REM_REF(gwion->env->global_nspc, gwion)
187
2136
  return gwion->env->curr = gwion->env->global_nspc = nspc;
188
}