GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gwion.c Lines: 137 138 99.3 %
Date: 2020-09-12 17:36:58 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
709
ANN static void driver_arg(const Gwion gwion, Driver *di) {
17
714
  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
709
}
26
27
711
ANN m_bool gwion_audio(const Gwion gwion) {
28
711
  Driver *const di = gwion->vm->bbq;
29
711
  if(di->si->arg)
30
709
    driver_arg(gwion, di);
31
711
  di->func(di->driver);
32
711
  CHECK_BB(di->driver->ini(gwion->vm, di));
33
711
  driver_alloc(di);
34
711
  return GW_OK;
35
}
36
37
711
ANN static inline m_bool gwion_engine(const Gwion gwion) {
38
711
  return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
39
}
40
41
711
ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
42
2042
  for(m_uint i = 0; i < vector_size(v); i++)
43
1331
    compile_filename(gwion, (m_str)vector_at(v, i));
44
711
}
45
46
711
ANN static void gwion_cleaner(const Gwion gwion) {
47
711
  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
48
711
  gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
49
711
  vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
50
711
}
51
52
7
ANN VM* gwion_cpy(const VM* src) {
53
7
  const Gwion gwion = mp_calloc(src->gwion->mp, Gwion);
54
7
  gwion->vm = new_vm(src->gwion->mp, 0);
55
7
  gwion->vm->gwion = gwion;
56
7
  gwion->vm->bbq->si = soundinfo_cpy(src->gwion->mp, src->bbq->si);
57
7
  gwion->emit = src->gwion->emit;
58
7
  gwion->env = src->gwion->env;
59
7
  gwion->data = cpy_gwiondata(src->gwion->mp, src->gwion->data);
60
7
  gwion->st = src->gwion->st;
61
7
  gwion->mp = src->gwion->mp;
62
7
  gwion->type = src->gwion->type;
63
7
  return gwion->vm;
64
}
65
66
714
ANN static void gwion_core(const Gwion gwion) {
67
714
  gwion->vm = new_vm(gwion->mp, 1);
68
714
  gwion->emit = new_emitter(gwion->mp);
69
714
  gwion->env = new_env(gwion->mp);
70
714
  gwion->emit->env = gwion->env;
71
714
  gwion->vm->gwion = gwion->emit->gwion = gwion->env->gwion = gwion;
72
714
}
73
74
711
ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
75
711
  gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
76
711
  shreduler_set_loop(gwion->vm->shreduler, arg->loop);
77
711
  if(gwion_audio(gwion) > 0) {
78
711
    plug_run(gwion, &arg->mod);
79
711
    if(gwion_engine(gwion)) {
80
711
      gwion_cleaner(gwion);
81
711
      gwion_compile(gwion, &arg->add);
82
711
      return GW_OK;
83
    }
84
  }
85
  return GW_ERROR;
86
}
87
88
714
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
89
714
  gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM));
90
714
  gwion->st = new_symbol_table(gwion->mp, 65347);
91
714
  gwion->ppa = mp_calloc(gwion->mp, PPArg);
92
714
  pparg_ini(gwion->mp, gwion->ppa);
93
714
  gwion_core(gwion);
94
714
  gwion->data = new_gwiondata(gwion->mp);
95
714
  gwion->type = (Type*)xcalloc(MAX_TYPE, sizeof(struct Type_*));
96
714
  pass_default(gwion);
97
714
  arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp);
98
714
  CHECK_BB(arg_parse(gwion, arg))
99
711
  return gwion_ok(gwion, arg);
100
}
101
102
711
ANN void gwion_run(const Gwion gwion) {
103
711
  VM* vm = gwion->vm;
104
711
  vm->bbq->driver->run(vm, vm->bbq);
105
710
}
106
107
4
ANN static inline void free_gwion_cpy(const Gwion gwion, const VM_Shred shred) {
108
4
  gwion_end_child(shred, gwion);
109
4
  free_vm(gwion->vm);
110
4
  free_gwiondata_cpy(gwion->mp, gwion->data);
111
4
  mp_free(gwion->mp, Gwion, gwion);
112
4
}
113
114
4
ANN static void fork_clean2(const VM_Shred shred, const Vector v) {
115
8
  for(m_uint i = 0; i < vector_size(v); ++i) {
116
4
    const Gwion gwion = (Gwion)vector_at(v, i);
117
4
    free_gwion_cpy(gwion, shred);
118
  }
119
4
  vector_release(v);
120
4
  v->ptr = NULL;
121
4
}
122
123
724
ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) {
124
724
  if(gwion->data->child.ptr)
125
7
    fork_clean(shred, &gwion->data->child);
126
724
  if(gwion->data->child2.ptr)
127
4
    fork_clean2(shred, &gwion->data->child2);
128
724
}
129
130
713
ANN void gwion_end(const Gwion gwion) {
131
713
  gwion_end_child(gwion->vm->cleaner_shred, gwion);
132
713
  free_env(gwion->env);
133
713
  if(gwion->vm->cleaner_shred)
134
710
    free_vm_shred(gwion->vm->cleaner_shred);
135
713
  free_emitter(gwion->mp, gwion->emit);
136
713
  free_vm(gwion->vm);
137
713
  pparg_end(gwion->ppa);
138
713
  mp_free(gwion->mp, PPArg, gwion->ppa);
139
713
  free_gwiondata(gwion);
140
713
  free_symbols(gwion->st);
141
713
  xfree(gwion->type);
142
713
  mempool_end(gwion->mp);
143
713
}
144
145
257
ANN static void env_header(const Env env) {
146
257
  if(env->class_def)
147
40
    gw_err(_("in class: '%s'\n"), env->class_def->name);
148
257
  if(env->func)
149
26
    gw_err(_("in function: '%s'\n"), env->func->name);
150
257
}
151
152
363
ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) {
153

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