]> Nishi Git Mirror - gwion.git/commitdiff
:art: Introduce '#require'
authorfennecdjay <fennecdjay@gwion.tk>
Tue, 3 Nov 2020 19:27:24 +0000 (20:27 +0100)
committerfennecdjay <fennecdjay@gwion.tk>
Tue, 3 Nov 2020 19:27:24 +0000 (20:27 +0100)
14 files changed:
ast
include/arg.h
include/engine.h
include/gwi.h
include/gwiondata.h
include/plug.h
src/arg.c
src/compile.c
src/gwion.c
src/gwiondata.c
src/import/import_internals.c
src/lib/engine.c
src/parse/scan0.c
src/plug.c

diff --git a/ast b/ast
index 42250676d6164fdc0b8505b0939cb21713cf6782..1811fe812817a12968c905c61165b146dc6a17e2 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit 42250676d6164fdc0b8505b0939cb21713cf6782
+Subproject commit 1811fe812817a12968c905c61165b146dc6a17e2
index ae9746ad8af4ed9ce957a7e287b7b329c0892f94..22b4bdf8732aaddf7e8dbabef82af33514696662 100644 (file)
@@ -3,9 +3,9 @@
 
 typedef struct Arg_ {
   struct CArg    arg;
+  struct Map_    mod;
   struct Vector_ add;
   struct Vector_ lib;
-  struct Vector_ mod;
   struct Vector_ config;
   struct SoundInfo_ *si;
   m_bool loop;
index 728d16e6fcca4522044785bed4f3d59fd32abe5c..4d1c008c8aef41fd175648874d66da52af8f219b 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ENGINE
 #define __ENGINE
-ANN m_bool type_engine_init(const Gwion gwion, const Vector);
+ANN m_bool type_engine_init(const Gwion gwion);
 #endif
index 6cee9bca6b9c08c7d952db13b2ee8f5c5770077d..d20124fdfbb3ea517289cf0abe6914f88cbbe292 100644 (file)
@@ -4,7 +4,7 @@
 #define loc(gwi) loc_cpy(gwi->gwion->mp, gwi->loc)
 
 struct Gwi_ {
-  struct Gwion_* gwion;
+  struct Gwion_ *const gwion;
   Ast body;
   struct ImportCK *ck;
   struct OperCK *oper; // _misc
@@ -15,4 +15,6 @@ struct Gwi_ {
 static inline Tmpl* gwi_tmpl(const Gwi gwi) {
   return new_tmpl_base(gwi->gwion->mp, gwi->ck->tmpl);
 }
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi));
 #endif
index 046f15b7a718d8c7bb2af794ca4c31874ac42059..eccc3d15d9d0fb735ce487921e0048374b8671bc 100644 (file)
@@ -8,7 +8,7 @@ typedef struct GwionData_ {
   struct Vector_ child2;
   struct Vector_ reserved;
   struct Passes_  *passes;
-  PlugInfo* plug;
+  struct Map_ plug;
 } GwionData;
 
 ANN GwionData* new_gwiondata(MemPool);
index 2065ae5d9aa47aa57a85e51da829500d91208cf9..57fa37dd9672815ed4e30d7398b82de8f4498778 100644 (file)
@@ -1,30 +1,22 @@
 #ifndef __PLUG
 #define __PLUG
 
-enum plug_t {
-  GWPLUG_DL,
-  GWPLUG_IMPORT,
-  GWPLUG_MODULE,
-  GWPLUG_LAST
-};
-
-typedef struct PlugInfo_ {
-  struct Map_ drv;
-  struct Vector_ vec[GWPLUG_LAST];
-} PlugInfo;
-
-ANN PlugInfo* new_pluginfo(MemPool, Vector);
-ANN void plug_run(const struct Gwion_*, const Vector);
+ANN m_bool plug_ini(const struct Gwion_*, const Vector);
+ANN m_bool driver_ini(const struct Gwion_*);
+ANN void plug_run(const struct Gwion_*, const Map);
 ANN void free_plug(const struct Gwion_*);
 ANN void* get_module(const struct Gwion_*, const m_str);
+ANN void set_module(const struct Gwion_ *gwion, const m_str name, void *const ptr);
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname);
+
 #define GWIMPORT_NAME    import
-#define GWMODSTR_NAME  gwmodstr
 #define GWMODINI_NAME  gwmodini
 #define GWMODEND_NAME  gwmodend
-#define GWDRIVER_NAME  gwmodend
-#define GWMODSTR(a) m_str GWMODSTR_NAME() { return #a; }
+#define GWDRIVER_NAME  gwdriver
+#define GWDEPEND_NAME  gwdepend
 #define GWMODINI(a)  ANN2(1) void* GWMODINI_NAME(const struct Gwion_ *gwion NUSED, const Vector args NUSED)
 #define GWMODEND(a)  ANN void  GWMODEND_NAME(const struct Gwion_ *gwion NUSED, void* self NUSED)
 #define GWDRIVER(a)  ANN void  GWDRIVER_NAME(DriverData* d)
+#define GWDEPEND     ANN m_str*  GWDEPEND_NAME(void)
 
 #endif
index 36e90dd29f38c6711869978b998ac53e9afd4aac..495c457710b2143704a85d78b3ea9e146016d31e 100644 (file)
--- a/src/arg.c
+++ b/src/arg.c
@@ -31,18 +31,18 @@ ANN static m_str plug_dir(void) {
 }
 
 ANN static void arg_init(Arg* arg) {
+  map_init(&arg->mod);
   vector_init(&arg->add);
   vector_init(&arg->lib);
-  vector_init(&arg->mod);
   vector_init(&arg->config);
   vector_add(&arg->lib, (vtype)plug_dir());
 }
 
 ANN void arg_release(Arg* arg) {
+  map_release(&arg->mod);
   vector_release(&arg->add);
   xfree((m_str)vector_front(&arg->lib));
   vector_release(&arg->lib);
-  vector_release(&arg->mod);
   config_end(&arg->config);
   vector_release(&arg->config);
 }
@@ -72,6 +72,22 @@ ANN2(1) static inline void arg_set_pass(const Gwion gwion, const m_str str) {
   free_vector(gwion->mp, v);
 }
 
+ANN2(1) static void module_arg(const Map map, m_str str) {
+  m_str val = strchr(str, '=');
+  if(val) {
+    *val = '\0';
+    ++val;
+  }
+  const m_str key = str;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    if(!strcmp(key, (m_str)VKEY(map, i))) {
+      free((m_str)VKEY(map, i));
+      break;
+    }
+  }
+  map_set(map, (vtype)key, (vtype)val);
+}
+
 ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
   struct CArg *ca = &arg->arg;
   for(ca->idx = 1; ca->idx < ca->argc; ++ca->idx) {
@@ -91,7 +107,7 @@ ANN m_bool _arg_parse(const Gwion gwion, Arg* arg) {
           break;
         case 'm':
           CHECK_OB((tmp = option_argument(ca)))
-          vector_add(&arg->mod, (vtype)tmp);
+          module_arg(&arg->mod, tmp);
           break;
         case 'l':
           CHECK_OB((tmp = option_argument(ca)))
index 9c1644a5424d9a1d8084f6f09df66de6480a3475..4227f17dd8331645e6810e2a458008e4a0ea9285 100644 (file)
@@ -117,7 +117,6 @@ ANN static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
 }
 
 ANN static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
-//  CHECK_BB(compiler_open(gwion->mp, c))
   if(compiler_open(gwion->mp, c) < 0)
     return 0;
   if(_check(gwion, c) < 0) {
index 99036808199d944d85e5c0beea27d92eab2ac59b..9cce298c413ece753277b940941e5aa9778f882b 100644 (file)
 #include "pass.h" // fork_clean
 #include "shreduler_private.h"
 
-ANN static void driver_arg(const Gwion gwion, Driver *di) {
-  for(m_uint i = 0; i < map_size(&gwion->data->plug->drv); ++i) {
-    const m_str name = (m_str)VKEY(&gwion->data->plug->drv, i);
-    const size_t len = strlen(name);
-    if(!strncmp(name, di->si->arg, len)) {
-      di->func = (f_bbqset)VVAL(&gwion->data->plug->drv, i);
-      break;
-    }
-  }
-}
-
 ANN m_bool gwion_audio(const Gwion gwion) {
   Driver *const di = gwion->vm->bbq;
   if(di->si->arg)
-    driver_arg(gwion, di);
+    driver_ini(gwion);
   di->func(di->driver);
   CHECK_BB(di->driver->ini(gwion->vm, di));
   driver_alloc(di);
@@ -35,7 +24,7 @@ ANN m_bool gwion_audio(const Gwion gwion) {
 }
 
 ANN static inline m_bool gwion_engine(const Gwion gwion) {
-  return type_engine_init(gwion, &gwion->data->plug->vec[GWPLUG_IMPORT]) > 0;
+  return type_engine_init(gwion) > 0;
 }
 
 ANN static inline void gwion_compile(const Gwion gwion, const Vector v) {
@@ -72,7 +61,7 @@ ANN static void gwion_core(const Gwion gwion) {
 }
 
 ANN static m_bool gwion_ok(const Gwion gwion, Arg* arg) {
-  gwion->data->plug = new_pluginfo(gwion->mp, &arg->lib);
+  CHECK_BB(plug_ini(gwion, &arg->lib))
   shreduler_set_loop(gwion->vm->shreduler, arg->loop);
   if(gwion_audio(gwion) > 0) {
     plug_run(gwion, &arg->mod);
index 5f74b69726626c07f160fba06a0bdd01ecf31ed6..a85cd6a5acf6f476f440807957be9d5fc943f6db 100644 (file)
@@ -48,7 +48,7 @@ ANN void free_gwiondata(const struct Gwion_ *gwion) {
   map_release(&data->id);
   vector_release(&data->reserved);
   free_passes(gwion->mp, data->passes);
-  if(data->plug)
+  if(data->plug.ptr)
     free_plug(gwion);
   free_gwiondata_cpy(gwion->mp, data);
 }
index 659c49782446b224d0de12f83fb16b899bd224fa..69438f012c9c0bb231891f9a9333ad960f5728e8 100644 (file)
@@ -27,3 +27,10 @@ ANN void gwi_reset(const Gwi gwi) {
   }
   env_reset(gwi->gwion->env);
 }
+
+ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
+   struct loc_t_ loc = {};
+   OperCK oper = {};
+   struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
+   return f(&gwi);
+}
index 3a7c36f0a5c13eeaa29547674fed8006176c8bbb..a438d67e55d7d7fe8c11d363411720d77054c186 100644 (file)
@@ -164,19 +164,9 @@ ANN static m_bool import_core_libs(const Gwi gwi) {
   return GW_OK;
 }
 
-ANN m_bool type_engine_init(const Gwion gwion, const Vector plug_dirs) {
+ANN m_bool type_engine_init(const Gwion gwion) {
   gwion->env->name = "[builtin]";
-  struct loc_t_ loc = {};
-  OperCK oper = {};
-  struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
-  CHECK_BB(import_core_libs(&gwi))
-  push_global(gwion, "[plugins]");
-  gwion->env->name = "[imported]";
-  for(m_uint i = 0; i < vector_size(plug_dirs); ++i) {
-    m_bool (*import)(Gwi) = (m_bool(*)(Gwi))vector_at(plug_dirs, i);
-    if(import && import(&gwi) < 0)
-      gwi_reset(&gwi);
-  }
+  CHECK_BB(gwi_run(gwion, import_core_libs))
   push_global(gwion, "[user]");
   return GW_OK;
 }
index 6317cba44ffad46eaadbe84283dd4ac9208aff16..3563e3e4def00f3680db500b8126b2973f57c65a 100644 (file)
@@ -355,9 +355,12 @@ ANN static Type scan0_class_def_init(const Env env, const Class_Def cdef) {
 }
 
 ANN static m_bool scan0_stmt_list(const Env env, Stmt_List list) {
-  do if(list->stmt->stmt_type == ae_stmt_pp && list->stmt->d.stmt_pp.pp_type == ae_pp_include)
-    env->name = list->stmt->d.stmt_pp.data;
-  while((list = list->next));
+  do if(list->stmt->stmt_type == ae_stmt_pp) {
+    if(list->stmt->d.stmt_pp.pp_type == ae_pp_include)
+      env->name = list->stmt->d.stmt_pp.data;
+    else if(list->stmt->d.stmt_pp.pp_type == ae_pp_require)
+      CHECK_BB(plugin_ini(env->gwion, list->stmt->d.stmt_pp.data))
+  } while((list = list->next));
   return GW_OK;
 }
 
index 75724b18b9b537464d73810bab8e0f1781cd3f1f..619e63778cefa7b27c09ad1f86ac1be50a9b3a1b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef BUILD_ON_WINDOWS
 #include <glob.h>
 #include <dlfcn.h>
+#include <limits.h>
 #else
 #include <windows.h>
 #endif
 #include "instr.h"
 #include "object.h"
 #include "import.h"
+#include "gwi.h"
 
-typedef m_bool (*import)(Gwi);
-typedef m_str  (*modstr)(void);
+typedef m_bool (*plugin)(Gwi);
 typedef void*  (*modini)(const struct Gwion_*, const Vector);
-typedef void*  (*modrun)(const struct Gwion_*, void*);
 typedef void*  (*modend)(const struct Gwion_*, void*);
+typedef m_str* (*gwdeps)(void);
 
-struct Plug_ {
-  m_str name;
-  modini ini;
-  modend end;
-  void* self;
-};
 #define STR_EXPAND(tok) #tok
 #define STR(tok) STR_EXPAND(tok)
 #ifndef BUILD_ON_WINDOWS
@@ -44,53 +39,33 @@ struct Plug_ {
 
 struct PlugHandle {
   MemPool mp;
-  PlugInfo* pi;
-  void *dl;
-  m_str file;
-  m_str name;
+  Map map;
+  size_t len;
 };
 
-ANN static struct Plug_* new_plug(MemPool p, const modini ini) {
+typedef struct Plug_ {
+  void *dl;
+  void *self;
+  int mod;
+  int imp;
+} *Plug;
+
+ANN static struct Plug_* new_plug(MemPool p, void *dl) {
   struct Plug_ *plug = mp_calloc(p, Plug);
-  plug->ini  = ini;
+  plug->dl  = dl;
   return plug;
 }
 
-ANN static void plug_import(struct PlugHandle *h) {
-  const import imp = DLSYM(h->dl, import, GWIMPORT_NAME);
-  if(imp)
-    vector_add(&h->pi->vec[GWPLUG_IMPORT], (vtype)imp);
-}
-
-ANN static void plug_module(struct PlugHandle *h) {
-  const modini ini = DLSYM(h->dl, modini, GWMODINI_NAME);
-  if(ini) {
-    struct Plug_ *plug = new_plug(h->mp, ini);
-    plug->name = h->name;
-    plug->end  = DLSYM(h->dl, modend, GWMODEND_NAME);
-    vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
-  }
-}
-
-ANN static void plug_driver(struct PlugHandle *h) {
-  const f_bbqset drv = DLSYM(h->dl, f_bbqset, GWDRIVER_NAME);
-  if(drv)
-    map_set(&h->pi->drv, (vtype)h->name, (vtype)drv);
-}
-
-ANN static inline m_str plug_name(struct PlugHandle *h) {
-  const modstr str = DLSYM(h->dl, modstr, GWMODSTR_NAME);
-  return str ? str() : NULL;
-}
-
 ANN static void plug_get(struct PlugHandle *h, const m_str c) {
-  h->dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
-  if(h->dl) {
-    vector_add(&h->pi->vec[GWPLUG_DL], (vtype)h->dl);
-    h->name = plug_name(h);
-    plug_import(h);
-    plug_module(h);
-    plug_driver(h);
+  void *dl = DLOPEN(c, RTLD_LAZY | RTLD_GLOBAL);
+  const m_str pname = c + h->len + 1;
+  const size_t sz = strlen(pname) - 3;
+  char name[PATH_MAX];
+  memcpy(name, pname, sz);
+  name[sz] = '\0';
+  if(dl) {
+    Plug plug = new_plug(h->mp, dl);
+    map_set(h->map, (vtype)strdup(name), (vtype)plug);
   } else
     gw_err(_("error in %s."), DLERROR());
 }
@@ -113,99 +88,142 @@ ANN static void plug_get_all(struct PlugHandle *h, const m_str name) {
     strcpy(c, name);
     strcpy(c + strlen(name) - 4, filedata.cFileName);
     plug_get(h, c);
-  } while(FindNextFile(file,&filedata));
+  } while(FindNextFile(file, &filedata));
   FindClose(file);
 #endif
 }
 
-ANN2(1) static void* pp_ini(const struct Gwion_ *gwion, const Vector v) {
-  pparg_run(gwion->ppa, v);
-  return NULL;
-}
-
-ANN static void register_pp(const struct PlugHandle* h) {
-  struct Plug_ *plug = new_plug(h->mp, pp_ini);
-  plug->name = "pp";
-  vector_add(&h->pi->vec[GWPLUG_MODULE], (vtype)plug);
-}
-
-ANN PlugInfo* new_pluginfo(MemPool p, const Vector list) {
-  PlugInfo *pi = (PlugInfo*)mp_calloc(p, PlugInfo);
-  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
-    vector_init(&pi->vec[i]);
-  map_init(&pi->drv);
-  struct PlugHandle h = { .mp=p, .pi=pi };
-  register_pp(&h);
+ANN m_bool plug_ini(const struct Gwion_ *gwion, const Vector list) {
+  const Map map = &gwion->data->plug;
+  map_init(map);
+  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);
-    char name[strlen(dir) + 6];
+    h.len = strlen(dir);
+    char name[PATH_MAX];
     sprintf(name, "%s/*.so", dir);
     plug_get_all(&h, name);
   }
-  return pi;
+  return GW_OK;
 }
 
-ANN static void plug_free_module(const struct Gwion_* gwion, const Vector v) {
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    if(plug->end)
-      plug->end(gwion, plug->self);
-    mp_free(gwion->mp, Plug, plug);
+void free_plug(const struct Gwion_ *gwion) {
+  const Map map = &gwion->data->plug;
+  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);
+    if(end)
+      end(gwion, plug->self);
+    free((m_str)VKEY(map, i));
+    DLCLOSE(plug->dl);
   }
+  map_release(map);
 }
 
-ANN static inline void plug_free_dls(const Vector v) {
+ANN static void plug_free_arg(MemPool p, const Vector v) {
   for(m_uint i = 0; i < vector_size(v); ++i)
-    DLCLOSE((void*)vector_at(v, i));
-}
-
-void free_plug(const struct Gwion_ *gwion) {
-  PlugInfo *p = gwion->data->plug;
-  struct Vector_ * const v = p->vec;
-  plug_free_module(gwion, &v[GWPLUG_MODULE]);
-  plug_free_dls(&v[GWPLUG_DL]);
-  for(m_uint i = 0; i < GWPLUG_LAST; ++i)
-    vector_release(&v[i]);
-  map_release(&p->drv);
-  mp_free(gwion->mp, PlugInfo, p);
+    free_mstr(p, (m_str)vector_at(v, i));
+  free_vector(p, v);
 }
 
-ANN static Vector get_arg(MemPool p, const m_str name, const Vector v) {
-  const size_t len = strlen(name);
-  for(m_uint i = vector_size(v) + 1; --i;) {
-    const m_str str = (m_str)vector_at(v, i - 1);
-    if(!strncmp(name, str, len)) {
-      vector_rem(v, i-1);
-      const m_str arg = strchr(str, '=');
-      return arg ? split_args(p, arg+1) : NULL;
+ANN void set_module(const struct Gwion_ *gwion, const m_str name, void *const ptr) {
+  const Map map = &gwion->data->plug;
+  for(m_uint j = 0; j < map_size(map); ++j) {
+    if(!strcmp(name, (m_str)VKEY(map, j))) {
+      Plug plug = (Plug)VVAL(map, j);
+      if(plug->mod)
+        return;
+      plug->mod = 1;
+      plug->self = ptr;
+      return;
     }
   }
-  return NULL;
 }
 
-ANN static void plug_free_arg(MemPool p, const Vector v) {
-  for(m_uint i = 0; i < vector_size(v); ++i)
-    free_mstr(p, (m_str)vector_at(v, i));
-  free_vector(p, v);
+ANN void plug_run(const struct Gwion_ *gwion, const Map mod) {
+  const Map map = &gwion->data->plug;
+  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);
+    for(m_uint j = 0; j < map_size(map); ++j) {
+      if(!strcmp(name, (m_str)VKEY(map, j))) {
+        Plug plug = (Plug)VVAL(map, j);
+        const Vector arg = opt ? split_args(gwion->mp, opt) : NULL;
+        const modini ini = DLSYM(plug->dl, modini, GWMODINI_NAME);
+        plug->self = ini(gwion, arg);
+        if(arg)
+          plug_free_arg(gwion->mp, arg);
+      }
+    }
+  }
 }
 
-ANN void plug_run(const struct Gwion_ *gwion, const Vector args) {
-  const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    const Vector arg = get_arg(gwion->mp, plug->name, args);
-    plug->self = plug->ini(gwion, arg);
-    if(arg)
-      plug_free_arg(gwion->mp, arg);
+ANN static m_bool dependencies(struct Gwion_ *gwion, const Plug plug) {
+  const gwdeps dep = DLSYM(plug->dl, gwdeps, GWDEPEND_NAME);
+  if(dep) {
+    m_str *deps = dep();
+    while(*deps) {
+      CHECK_BB(plugin_ini(gwion, *deps))
+      ++deps;
+    }
   }
+  return GW_OK;
+}
+
+ANN m_bool plugin_ini(struct Gwion_ *gwion, const m_str iname) {
+  const Map map = &gwion->data->plug;
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    const Plug plug = (Plug)VVAL(map, i);
+    if(plug->imp)
+      return GW_OK;
+    const m_str name = (m_str)VKEY(map, i);
+    if(!strcmp(name, iname)) {
+      const plugin imp = DLSYM(plug->dl, plugin, GWIMPORT_NAME);
+      if(!imp)
+        break;
+      plug->imp = 1;
+      CHECK_BB(dependencies(gwion, plug))
+      const m_uint scope = env_push_global(gwion->env);
+      const m_bool ret = gwi_run(gwion, imp);
+      env_pop(gwion->env, scope);
+      return ret;
+    }
+  }
+  gw_err("no such plugin '%s'\n", iname);
+  return GW_ERROR;
+}
+
+ANN m_bool driver_ini(const struct Gwion_ *gwion) {
+  const Map map = &gwion->data->plug;
+  m_str dname = gwion->vm->bbq->si->arg;
+  m_str opt = strchr(dname, '=');
+  const char c = opt ? *opt : '\0';
+  if(opt)
+    *opt = '\0';
+  for(m_uint i = 0; i < map_size(map); ++i) {
+    const m_str name = (m_str)VKEY(map, i);
+    if(!strcmp(name, dname)) {
+      const Plug plug = (Plug)VVAL(map, i);
+      const f_bbqset drv = DLSYM(plug->dl, f_bbqset, GWDRIVER_NAME);
+      if(!drv)
+        break;
+      gwion->vm->bbq->func = drv;
+      if(opt)
+        *opt = c;
+      return GW_OK;
+    }
+  }
+  gw_err("can't find driver '%s'\n", dname);
+  return GW_ERROR;
 }
 
 ANN void* get_module(const struct Gwion_ *gwion, const m_str name) {
-  const Vector v = &gwion->data->plug->vec[GWPLUG_MODULE];
-  for(m_uint i = 0; i < vector_size(v); ++i) {
-    struct Plug_ *plug = (struct Plug_*)vector_at(v, i);
-    if(!strcmp(name, plug->name))
+  const Map map = &gwion->data->plug;
+  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);
       return plug->self;
+    }
   }
   return NULL;
 }