1 #include "lib9.h"
2 #include "isa.h"
3 #include "interp.h"
4 #include "raise.h"
5 #include <kernel.h>
6
7 static void
newlink(Link * l,char * fn,int sig,Type * t)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
runtime(Module * m,Link * l,char * fn,int sig,void (* runt)(void *),Type * t)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
mlink(Module * m,Link * l,uchar * fn,int sig,int pc,Type * t)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
linkm(Module * m,Modlink * ml,int i,Import * ldt)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*
mklinkmod(Module * m,int n)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*
linkmod(Module * m,Import * ldt,int mkmp)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
destroylinks(Module * m)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