diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libinterp/dlm-Plan9.c | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libinterp/dlm-Plan9.c')
| -rw-r--r-- | libinterp/dlm-Plan9.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/libinterp/dlm-Plan9.c b/libinterp/dlm-Plan9.c new file mode 100644 index 00000000..7b825028 --- /dev/null +++ b/libinterp/dlm-Plan9.c @@ -0,0 +1,101 @@ +#include "lib9.h" +#include "isa.h" +#include "interp.h" +#include "raise.h" +#include "pool.h" +#include "kernel.h" +#include "dynld.h" + +#define DBG if(1) print + +extern Dynobj* dynld(int); +extern char* enverror(void); + +typedef struct{char *name; long sig; void (*fn)(void*); int size; int np; uchar map[16];} Runtab; + +static void* +addr(char *pre, char *suf, Dynobj *o, ulong sig) +{ + char buf[64]; + + if(o == nil || strlen(pre)+strlen(suf) > 64-1) + return nil; + snprint(buf, sizeof(buf), "%s%s", pre, suf); + return dynimport(o, buf, sig); +} + +Module* +newdyncode(int fd, char *path, Dir *dir) +{ + Module *m; + void *v; + Runtab *r; + Dynobj *o; + char *name; + + DBG("module path is %s\n", path); + m = nil; + o = dynld(fd); + if(o == nil){ + DBG("%s\n", enverror()); + goto Error; + } + v = addr("XXX", "module", o, signof(char*)); + if(v == nil) + goto Error; + name = *(char**)v; + DBG("module name is %s\n", name); + r = addr(name, "modtab", o, signof(Runtab[])); + if(r == nil) + goto Error; + m = builtinmod(name, r, 0); + m->rt = DYNMOD; + m->dev = dir->dev; + m->dtype = dir->type; + m->qid = dir->qid; + m->mtime = dir->mtime; + m->path = strdup(path); + if(m->path == nil) + goto Error; + m->dlm = o; + DBG("module base is 0x%p\n", o->base); + return m; +Error: + if(o != nil) + dynobjfree(o); + if(m != nil) + freemod(m); + return nil; +} + +void +freedyncode(Module *m) +{ + dynobjfree(m->dlm); +} + +static void +callfn(Module *m, char *fn) +{ + void *v, (*f)(void); + + if(m->ref != 1) + return; + v = addr(m->name, fn, m->dlm, signof(*f)); + if(v != nil){ + f = v; + (*f)(); + } +} + +void +newdyndata(Modlink *ml) +{ + callfn(ml->m, "init"); +} + +void +freedyndata(Modlink *ml) +{ + callfn(ml->m, "end"); +} |
