GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gwion.c Lines: 138 140 98.6 %
Date: 2020-09-22 13:02:15 Branches: 36 40 90.0 %

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
      if(arg->read_stdin)
83
        compile_file(gwion, "stdin", stdin);
84
712
      return GW_OK;
85
    }
86
  }
87
  return GW_ERROR;
88
}
89
90
715
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
91
715
  gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM));
92
715
  gwion->st = new_symbol_table(gwion->mp, 65347);
93
715
  gwion->ppa = mp_calloc(gwion->mp, PPArg);
94
715
  pparg_ini(gwion->mp, gwion->ppa);
95
715
  gwion_core(gwion);
96
715
  gwion->data = new_gwiondata(gwion->mp);
97
715
  gwion->type = (Type*)xcalloc(MAX_TYPE, sizeof(struct Type_*));
98
715
  pass_default(gwion);
99
715
  arg->si = gwion->vm->bbq->si = new_soundinfo(gwion->mp);
100
715
  CHECK_BB(arg_parse(gwion, arg))
101
712
  return gwion_ok(gwion, arg);
102
}
103
104
712
ANN void gwion_run(const Gwion gwion) {
105
712
  VM* vm = gwion->vm;
106
712
  vm->bbq->driver->run(vm, vm->bbq);
107
711
}
108
109
6
ANN static inline void free_gwion_cpy(const Gwion gwion, const VM_Shred shred) {
110
6
  gwion_end_child(shred, gwion);
111
6
  free_vm(gwion->vm);
112
6
  free_gwiondata_cpy(gwion->mp, gwion->data);
113
6
  mp_free(gwion->mp, Gwion, gwion);
114
6
}
115
116
6
ANN static void fork_clean2(const VM_Shred shred, const Vector v) {
117
12
  for(m_uint i = 0; i < vector_size(v); ++i) {
118
6
    const Gwion gwion = (Gwion)vector_at(v, i);
119
6
    free_gwion_cpy(gwion, shred);
120
  }
121
6
  vector_release(v);
122
6
  v->ptr = NULL;
123
6
}
124
125
728
ANN void gwion_end_child(const VM_Shred shred, const Gwion gwion) {
126
728
  if(gwion->data->child.ptr)
127
8
    fork_clean(shred, &gwion->data->child);
128
728
  if(gwion->data->child2.ptr)
129
6
    fork_clean2(shred, &gwion->data->child2);
130
728
}
131
132
714
ANN void gwion_end(const Gwion gwion) {
133
714
  gwion_end_child(gwion->vm->cleaner_shred, gwion);
134
714
  free_env(gwion->env);
135
714
  if(gwion->vm->cleaner_shred)
136
711
    free_vm_shred(gwion->vm->cleaner_shred);
137
714
  free_emitter(gwion->mp, gwion->emit);
138
714
  free_vm(gwion->vm);
139
714
  pparg_end(gwion->ppa);
140
714
  mp_free(gwion->mp, PPArg, gwion->ppa);
141
714
  free_gwiondata(gwion);
142
714
  free_symbols(gwion->st);
143
714
  xfree(gwion->type);
144
714
  mempool_end(gwion->mp);
145
714
}
146
147
258
ANN static void env_header(const Env env) {
148
258
  if(env->class_def)
149
40
    gw_err(_("in class: '%s'\n"), env->class_def->name);
150
258
  if(env->func)
151
27
    gw_err(_("in function: '%s'\n"), env->func->name);
152
258
}
153
154
349
ANN void env_err(const Env env, const loc_t pos, const m_str fmt, ...) {
155

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