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

351
  if(env->context && env->context->error)
156
91
    return;
157
#ifndef __FUZZING__
158
260
  env_header(env);
159
260
  loc_header(pos, env->name);
160
  va_list arg;
161
260
  va_start(arg, fmt);
162
260
  vfprintf(stderr, fmt, arg);
163
260
  va_end(arg);
164
260
  fprintf(stderr, "\n");
165
260
  loc_err(pos, env->name);
166
#endif
167
260
  if(env->context)
168
211
    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
1426
ANN void push_global(struct Gwion_ *gwion, const m_str name) {
181
1426
  const Nspc nspc = new_nspc(gwion->mp, name);
182
1426
  nspc->parent = gwion->env->global_nspc;
183
1426
  gwion->env->curr = gwion->env->global_nspc = nspc;
184
1426
}
185
186
2139
ANN Nspc pop_global(struct Gwion_ *gwion) {
187
2139
  const Nspc nspc = gwion->env->global_nspc->parent;
188
2139
  REM_REF(gwion->env->global_nspc, gwion)
189
2139
  return gwion->env->curr = gwion->env->global_nspc = nspc;
190
}