#include "traverse.h"
#include "vm.h"
#include "parse.h"
-//#include "clean.h"
ANN static struct Env_Scope_ *new_envscope(MemPool p) {
struct Env_Scope_ *a = mp_calloc(p, Env_Scope);
env->global_nspc = new_nspc(p, "global_nspc");
env->context = NULL;
env->scope = new_envscope(p);
+ vector_add(&env->scope->nspc_stack, (vtype)env->global_nspc);
env_reset(env);
return env;
}
ANN void env_reset(const Env env) {
+const Nspc nspc = (Nspc)vector_front(&env->scope->nspc_stack);
vector_clear(&env->scope->breaks);
vector_clear(&env->scope->conts);
vector_clear(&env->scope->nspc_stack);
+ vector_add(&env->scope->nspc_stack, (vtype)nspc);
vector_add(&env->scope->nspc_stack, (vtype)env->global_nspc);
vector_clear(&env->scope->class_stack);
vector_add(&env->scope->class_stack, (vtype)NULL);
const m_uint size = vector_size(&a->known_ctx);
for (m_uint i = size + 1; --i;) {
const Context ctx = (Context)vector_at(&a->known_ctx, i - 1);
-// if (!ctx->error && ctx->global) ast_cleaner(gwion, ctx->tree);
context_remref(ctx, gwion);
}
}
ANN static void free_env_scope(struct Env_Scope_ *a, Gwion gwion) {
- release_ctx(a, gwion);
vector_release(&a->known_ctx);
vector_release(&a->nspc_stack);
vector_release(&a->class_stack);
VPTR(v, VLEN(v) - 1) = (vtype)w;
}
struct ScopeEffect eff = {effect, pos};
-// mp_vector_add(a->gwion->mp, &w, struct ScopeEffect, eff);
mp_vector_add(a->gwion->mp, (MP_Vector**)&(VPTR(v, VLEN(v) - 1)) , struct ScopeEffect, eff);
}
ANN void free_env(const Env a) {
free_env_scope(a->scope, a->gwion);
- while (pop_global(a->gwion))
- ;
+ pop_global(a->gwion);
mp_free(a->gwion->mp, Env, a);
}
-#ifdef USE_GETTEXT
-#include <locale.h>
-#include <libintl.h>
-#endif
#include <unistd.h>
#include "gwion_util.h"
#include "gwion_ast.h"
#include "engine.h"
#include "arg.h"
#include "compile.h"
-#include "object.h" // fork_clean
-#include "pass.h" // fork_clean
+#include "object.h"
+#include "pass.h"
#include "shreduler_private.h"
#include "ugen.h"
if (gwion_audio(gwion) > 0) {
plug_run(gwion, &arg->mod);
if (type_engine_init(gwion)) {
+ vector_add(&gwion->data->plugs->vec, (m_uint)gwion->env->global_nspc);
gwion->vm->cleaner_shred = gwion_cleaner(gwion);
gwion->emit->locale = gwion_locale(gwion);
(void)arg_compile(gwion, arg);
ANN void gwion_end(const Gwion gwion) {
free_killed_shred(&gwion->vm->shreduler->killed_shreds);
gwion_end_child(gwion->vm->cleaner_shred, gwion);
+ release_ctx(gwion->env->scope, gwion);
+ if (gwion->data->plugs) free_plug(gwion);
free_env(gwion->env);
if (gwion->vm->cleaner_shred) free_vm_shred(gwion->vm->cleaner_shred);
free_emitter(gwion->mp, gwion->emit);
gwion->env->curr = gwion->env->global_nspc = nspc;
}
-ANN Nspc pop_global(struct Gwion_ *gwion) {
- const Nspc nspc = gwion->env->global_nspc->parent;
- nspc_remref(gwion->env->global_nspc, gwion);
- return gwion->env->curr = gwion->env->global_nspc = nspc;
+ANN void pop_global(const Gwion gwion) {
+ Nspc nspc = gwion->env->global_nspc, parent;
+ do {
+ parent = nspc->parent;
+ nspc_remref(nspc, gwion);
+ } while((nspc = parent));
}
ANN void gwion_set_debug(const Gwion gwion, const bool dbg) {
typedef struct Plug_ {
void *dl;
void *self;
- int imp;
+ Nspc nspc;
} * Plug;
ANN static struct Plug_ *new_plug(MemPool p, void *dl) {
}
ANN m_bool plug_ini(const struct Gwion_ *gwion, const Vector list) {
- const Map map = &gwion->data->plug;
+ gwion->data->plugs = mp_calloc2(gwion->mp, sizeof(Plugs));
+ const Map map = &gwion->data->plugs->map;
map_init(map);
+ vector_init(&gwion->data->plugs->vec);
struct PlugHandle h = {.mp = gwion->mp, .map = map};
for (m_uint i = 0; i < vector_size(list); i++) {
const m_str dir = (m_str)vector_at(list, i);
h.len = strlen(dir);
char name[PATH_MAX];
- sprintf(name, "%s/*.so", dir);
+ sprintf(name, "%s/*.so" /**/, dir);
plug_get_all(&h, name);
}
return GW_OK;
}
-void free_plug(const struct Gwion_ *gwion) {
- const Map map = &gwion->data->plug;
+void free_plug(const Gwion gwion) {
+ const Map map = &gwion->data->plugs->map;
for (m_uint i = 0; i < map_size(map); ++i) {
const Plug plug = (Plug)VVAL(map, i);
const modend end = DLSYM(plug->dl, modend, GWMODEND_NAME);
DLCLOSE(plug->dl);
}
map_release(map);
+ const Vector vec = &gwion->data->plugs->vec;
+ for (m_uint i = vector_size(vec) + 1; --i;) {
+ const Nspc nspc = (Nspc)vector_at(vec, i-1);
+ nspc_remref(nspc, gwion);
+ }
+ vector_release(&gwion->data->plugs->vec);
+ mp_free2(gwion->mp, sizeof(Plugs), gwion->data->plugs);
}
ANN static void plug_free_arg(MemPool p, const Vector v) {
ANN void set_module(const struct Gwion_ *gwion, const m_str name,
void *const ptr) {
- const Map map = &gwion->data->plug;
+ const Map map = &gwion->data->plugs->map;
for (m_uint j = 0; j < map_size(map); ++j) {
if (!strcmp(name, (m_str)VKEY(map, j))) {
Plug plug = (Plug)VVAL(map, j);
}
ANN void plug_run(const struct Gwion_ *gwion, const Map mod) {
- const Map map = &gwion->data->plug;
+ const Map map = &gwion->data->plugs->map;
for (m_uint i = 0; i < map_size(mod); ++i) {
const m_str name = (m_str)VKEY(mod, i);
const m_str opt = (m_str)VVAL(mod, i);
return ret ? GW_OK : GW_ERROR;
}
+ANN static void plug_name(m_str name, const m_str iname, const m_uint size) {
+ strcpy(name, iname);
+ for (size_t j = 0; j < size; j++)
+ if (name[j] == ':' || name[j] == '[' || name[j] == ']') name[j] = '_';
+}
+
+ANN static void set_parent(const Nspc nspc, const Gwion gwion ) {
+ const Nspc user = (Nspc)vector_at(&gwion->env->scope->nspc_stack, 1);
+ nspc->parent = user->parent;
+ user->parent = nspc;
+}
+
+ANN static m_bool start(const Plug plug, const Gwion gwion, const m_str iname, const loc_t loc) {
+ const plugin imp = DLSYM(plug->dl, plugin, GWIMPORT_NAME);
+ const bool cdoc = gwion->data->cdoc;
+ gwion->data->cdoc = 0; // check cdoc
+ CHECK_BB(dependencies(gwion, plug, loc));
+ gwion->data->cdoc = cdoc;
+ plug->nspc = new_nspc(gwion->mp, iname);
+ vector_add(&gwion->data->plugs->vec, (m_uint)plug->nspc);
+ set_parent(plug->nspc, gwion);
+ const m_uint scope = env_push(gwion->env, NULL, plug->nspc);
+ const m_str name = gwion->env->name;
+ gwion->env->name = iname;
+ const m_bool ret = gwi_run(gwion, imp);
+ gwion->env->name = name;
+ env_pop(gwion->env, scope);
+ return ret;
+}
+
+ANN static m_bool started(const Plug plug, const Gwion gwion, const m_str iname) {
+ Nspc nspc = gwion->env->global_nspc->parent;
+ do if(!strcmp(nspc->name, iname))
+ return GW_OK;
+ while((nspc = nspc->parent));
+ set_parent(plug->nspc, gwion);
+ return GW_OK;
+}
+
ANN static m_bool _plugin_ini(struct Gwion_ *gwion, const m_str iname, const loc_t loc) {
- const Map map = &gwion->data->plug;
+ const Map map = &gwion->data->plugs->map;
for (m_uint i = 0; i < map_size(map); ++i) {
const Plug plug = (Plug)VVAL(map, i);
const m_str base = (m_str)VKEY(map, i);
const size_t size = strlen(iname);
char name[size + 1];
- strcpy(name, iname);
- for (size_t j = 0; j < size; j++) {
- if (name[j] == ':' || name[j] == '[' || name[j] == ']') name[j] = '_';
- }
+ plug_name(name, iname, size);
if (!strcmp(name, base)) {
- if (plug->imp) return GW_OK;
- const plugin imp = DLSYM(plug->dl, plugin, GWIMPORT_NAME);
- if (!imp) break;
- plug->imp = 1;
- const bool cdoc = gwion->data->cdoc;
- gwion->data->cdoc = 0;
- CHECK_BB(dependencies(gwion, plug, loc));
- gwion->data->cdoc = cdoc;
- const m_uint scope = env_push_global(gwion->env);
- const m_str name = gwion->env->name;
- gwion->env->name = iname;
- const m_bool ret = gwi_run(gwion, imp);
- gwion->env->name = name;
- env_pop(gwion->env, scope);
- return ret;
+ if (!plug->nspc) return start(plug, gwion, iname, loc);
+ else return started(plug, gwion, iname);
}
}
return GW_ERROR;
ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname, const loc_t loc) {
const Env env = gwion->env;
- const Context ctx = env->context;
- gwion->env->context = NULL;
- const m_bool ret = _plugin_ini(gwion, iname, loc);
- gwion->env->context = ctx;
- if(ret > 0) return GW_OK;
- if(gwion->env->context && !gwion->env->context->error)
- env_err(env, loc, "no such plugin\n");
- return GW_ERROR;
+ if(_plugin_ini(gwion, iname, loc) < 0) {
+ if(gwion->env->context && !gwion->env->context->error)
+ env_err(env, loc, "no such plugin\n");
+ return GW_ERROR;
+ }
+ return GW_OK;
}
ANN m_bool driver_ini(const struct Gwion_ *gwion) {
- const Map map = &gwion->data->plug;
+ const Map map = &gwion->data->plugs->map;
m_str dname = gwion->vm->bbq->si->arg;
m_str opt = strchr(dname, '=');
const char c = opt ? *opt : '\0';
}
ANN void *get_module(const struct Gwion_ *gwion, const m_str name) {
- const Map map = &gwion->data->plug;
+ const Map map = &gwion->data->plugs->map;
for (m_uint i = 0; i < map_size(map); ++i) {
if (!strcmp(name, (m_str)VKEY(map, i))) {
const Plug plug = (Plug)VVAL(map, i);