GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gwion.c Lines: 137 138 99.3 %
Date: 2020-08-07 19:15:19 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
728
ANN static void driver_arg(const Gwion gwion, Driver *di) {
17
733
  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
728
}
26
27
730
ANN m_bool gwion_audio(const Gwion gwion) {
28
730
  Driver *const di = gwion->vm->bbq;
29
730
  if(di->si->arg)
30
728
    driver_arg(gwion, di);
31
730
  di->func(di->driver);
32
730
  CHECK_BB(di->driver->ini(gwion->vm, di));
33
730
  driver_alloc(di);
34
730
  return GW_OK;
35
}
36
37
730
ANN static inline m_bool gwion_engine(const Gwion gwion) {
38
730
  return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
39
}
40
41
730
ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
42
2099
  for(m_uint i = 0; i < vector_size(v); i++)
43
1369
    compile_filename(gwion, (m_str)vector_at(v, i));
44
730
}
45
46
730
ANN static void gwion_cleaner(const Gwion gwion) {
47
730
  const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
48
730
  gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
49
730
  vm_ini_shred(gwion->vm, gwion->vm->cleaner_shred);
50
730
}
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
733
ANN static void gwion_core(const Gwion gwion) {
67
733
  gwion->vm = new_vm(gwion->mp, 1);
68
733
  gwion->emit = new_emitter(gwion->mp);
69
733
  gwion->env = new_env(gwion->mp);
70
733
  gwion->emit->env = gwion->env;
71
733
  gwion->vm->gwion = gwion->emit->gwion = gwion->env->gwion = gwion;
72
733
}
73
74
730
ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
75
730
  gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
76
730
  shreduler_set_loop(gwion->vm->shreduler, arg->loop);
77
730
  if(gwion_audio(gwion) > 0) {
78
730
    plug_run(gwion, &arg->mod);
79
730
    if(gwion_engine(gwion)) {
80
730
      gwion_cleaner(gwion);
81
730
      gwion_compile(gwion, &arg->add);
82
730
      return GW_OK;
83
    }
84
  }
85
  return GW_ERROR;
86
}
87
88
733
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
89
733
  gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM));
90
733
  gwion->st = new_symbol_table(gwion->mp, 65347);
91
733
  gwion->ppa = mp_calloc(gwion->mp, PPArg);
92
733
  pparg_ini(gwion->mp, gwion->ppa);
93
733
  gwion_core(gwion);
94
733
  gwion->data = new_gwiondata(gwion->mp);
95
733
  gwion->type = (Type*)xcalloc(MAX_TYPE, sizeof(struct Type_*));
96
733
  pass_default(gwion);
97
733
  arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp);
98
733
  CHECK_BB(arg_parse(gwion, arg))
99
730
  return gwion_ok(gwion, arg);
100
}
101
102
730
ANN void gwion_run(const Gwion gwion) {
103
730
  VM* vm = gwion->vm;
104
730
  vm->bbq->driver->run(vm, vm->bbq);
105
729
}
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
743
ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) {
124
743
  if(gwion->data->child.ptr)
125
7
    fork_clean(shred, &gwion->data->child);
126
743
  if(gwion->data->child2.ptr)
127
4
    fork_clean2(shred, &gwion->data->child2);
128
743
}
129
130
732
ANN void gwion_end(const Gwion gwion) {
131
732
  gwion_end_child(gwion->vm->cleaner_shred, gwion);
132
732
  free_env(gwion->env);
133
732
  if(gwion->vm->cleaner_shred)
134
729
    free_vm_shred(gwion->vm->cleaner_shred);
135
732
  free_emitter(gwion->mp, gwion->emit);
136
732
  free_vm(gwion->vm);
137
732
  pparg_end(gwion->ppa);
138
732
  mp_free(gwion->mp, PPArg, gwion->ppa);
139
732
  free_gwiondata(gwion);
140
732
  free_symbols(gwion->st);
141
732
  xfree(gwion->type);
142
732
  mempool_end(gwion->mp);
143
732
}
144
145
285
ANN static void env_header(const Env env) {
146
285
  if(env->class_def)
147
43
    gw_err(_("in class: '%s'\n"), env->class_def->name);
148
285
  if(env->func)
149
32
    gw_err(_("in function: '%s'\n"), env->func->name);
150
285
}
151
152
402
ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) {
153

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