1 #include "lib9.h" 2 #include "isa.h" 3 #include "interp.h" 4 #include "raise.h" 5 #include <kernel.h> 6 7 static void 8 newlink(Link *l, char *fn, int sig, Type *t) 9 { 10 l->name = malloc(strlen(fn)+1); 11 if(l->name == nil) 12 error(exNomem); 13 strcpy(l->name, fn); 14 l->sig = sig; 15 l->frame = t; 16 } 17 18 void 19 runtime(Module *m, Link *l, char *fn, int sig, void (*runt)(void*), Type *t) 20 { 21 USED(m); 22 newlink(l, fn, sig, t); 23 l->u.runt = runt; 24 } 25 26 void 27 mlink(Module *m, Link* l, uchar *fn, int sig, int pc, Type *t) 28 { 29 newlink(l, (char*)fn, sig, t); 30 l->u.pc = m->prog+pc; 31 } 32 33 static int 34 linkm(Module *m, Modlink *ml, int i, Import *ldt) 35 { 36 Link *l; 37 int sig; 38 char e[ERRMAX]; 39 40 sig = ldt->sig; 41 for(l = m->ext; l->name; l++) 42 if(strcmp(ldt->name, l->name) == 0) 43 break; 44 45 if(l == nil) { 46 snprint(e, sizeof(e), "link failed fn %s->%s() not implemented", m->name, ldt->name); 47 goto bad; 48 } 49 if(l->sig != sig) { 50 snprint(e, sizeof(e), "link typecheck %s->%s() %ux/%ux", 51 m->name, ldt->name, l->sig, sig); 52 goto bad; 53 } 54 55 ml->links[i].u = l->u; 56 ml->links[i].frame = l->frame; 57 return 0; 58 bad: 59 kwerrstr(e); 60 print("%s\n", e); 61 return -1; 62 } 63 64 Modlink* 65 mklinkmod(Module *m, int n) 66 { 67 Heap *h; 68 Modlink *ml; 69 70 h = nheap(sizeof(Modlink)+(n-1)*sizeof(ml->links[0])); 71 h->t = &Tmodlink; 72 Tmodlink.ref++; 73 ml = H2D(Modlink*, h); 74 ml->nlinks = n; 75 ml->m = m; 76 ml->prog = m->prog; 77 ml->type = m->type; 78 ml->compiled = m->compiled; 79 ml->MP = H; 80 ml->data = nil; 81 82 return ml; 83 } 84 85 Modlink* 86 linkmod(Module *m, Import *ldt, int mkmp) 87 { 88 Type *t; 89 Heap *h; 90 int i; 91 Modlink *ml; 92 Import *l; 93 94 if(m == nil) 95 return H; 96 97 for(i = 0, l = ldt; l->name != nil; i++, l++) 98 ; 99 ml = mklinkmod(m, i); 100 101 if(mkmp){ 102 if(m->rt == DYNMOD) 103 newdyndata(ml); 104 else if(mkmp && m->origmp != H && m->ntype > 0) { 105 t = m->type[0]; 106 h = nheap(t->size); 107 h->t = t; 108 t->ref++; 109 ml->MP = H2D(uchar*, h); 110 newmp(ml->MP, m->origmp, t); 111 } 112 } 113 114 for(i = 0, l = ldt; l->name != nil; i++, l++) { 115 if(linkm(m, ml, i, l) < 0){ 116 destroy(ml); 117 return H; 118 } 119 } 120 121 return ml; 122 } 123 124 void 125 destroylinks(Module *m) 126 { 127 Link *l; 128 129 for(l = m->ext; l->name; l++) 130 free(l->name); 131 free(m->ext); 132 } 133