33168d3b3cfeb378fc64806c30d524715de096d5
[vlp.git] / src / int / object.c
1 #include "depend.h"
2 #include "genint.h"
3 #include "int.h"
4 #include "process.h"
5 #include "intproto.h"
6
7 /* object management routines */
8
9 /**
10  * Open new field for a record.
11  */
12 void openrc(word prot, virtaddr *virt, word *addr)
13 {
14         word t1;
15
16         request(prototype[prot]->appetite, &t1, addr);
17         M[*addr + PROTNUM] = prot;
18         virt->addr = t1;
19         virt->mark = M[t1 + 1];
20 }
21
22 /**
23  * 
24  */
25 void slopen(word prot, virtaddr *sladr, word *ah, word *am)
26 {
27         word t1, t2, virts;
28
29         virts = thisp->prochead + M[thisp->prochead] + VIRTSC;
30         /* preserve for compactifier */
31         storevirt(*sladr, virts);
32         t1 = prototype[prot]->appetite;
33
34         /* open field */
35         request(t1, ah, am);
36
37         M[*am + PROTNUM] = prot;
38         /* LWA+1 of object */
39         t1 = *am + t1;
40         /* prepare SL pointer */
41         M[t1 + SL] = M[virts];
42         M[t1 + SL + 1] = M[virts + 1];
43         /* ah of current */
44         t2 = M[display2 + M[c1 + PROTNUM]];
45         M[t1 + DL] = t2;
46         M[t1 + DL + 1] = M[t2 + 1];
47 }
48
49
50 void openobj(word prot, word *ah, word *am)
51 {
52         virtaddr v1;
53         word t1;
54
55         t1 = M[display2 + prototype[prot]->slprototype];
56         /* ah of SL */
57         v1.addr = t1;
58         v1.mark = M[ t1+1 ];
59         slopen(prot, &v1, ah, am);
60 }
61
62 /**
63  * Reserve room for array
64  */
65 void newarry(word low, word up, word kind, virtaddr *virt, word *am)
66 {
67         word ap;
68
69         switch ((int) kind) {
70         case AINT:
71                 ap = APINT;
72                 break;
73         case AREAL:
74                 ap = APREAL;
75                 break;
76         case AVIRT:
77                 ap = APREF;
78                 break;
79         case APROCESS:
80                 ap = APINT;
81                 break;
82         }
83         low *= ap;
84         up *= ap;
85         if (up < low) {
86                 /* illegal array bounds */
87                 errsignal(RTEILLAB);
88         }
89         low -= 3;
90         request(up - low + ap, &virt->addr, am);
91         M[*am + 1] = kind;
92         M[*am + 2] = low;
93         virt->mark = M[virt->addr + 1];
94 }
95
96 /**
97  * Generalized killer
98  */
99 void gkill(virtaddr *virt)
100 {
101         word t1, t2, t3;
102         virtaddr vt;
103         protdescr *ptr;
104         message msg;
105
106         /* kill remote process */
107         if (isprocess(virt)) {
108                 msg.control.type = KILLPR;
109                 obj2mess( M, virt, &msg.control.receiver );
110                 /* send remote kill request */
111                 sendmsg1( &msg);
112         }
113         else if (virt->mark == M[virt->addr + 1]) {
114                 /* am */
115                 t1 = M[virt->addr];
116                 t2 = M[t1 + PROTNUM];
117                 if (t2 == AINT || t2 == AREAL || t2 == AVIRT) {
118                         /* simple kill for array */
119                         disp(virt);
120                 }
121                 else if (t2 == FILEOBJECT) {
122                         /* First close file if opened */
123                         if (M[t1 + FSTAT] != UNKNOWN) 
124                                 if (fclose(MF(t1 + FFILE)))
125                                         errsignal(RTEILLIO);
126                         /* Delete file if temporary */
127                         if (M[t1 + FTEMP] == LTRUE)
128                                 if (unlink(MN(t1 + FNAME)))
129                                         errsignal(RTEILLIO);
130                         free(MN(t1+FNAME));
131                         disp(virt);
132                 }
133                 /* more than array or file */
134                 else {
135                         ptr = prototype[ t2 ];
136                         if (ptr->kind == RECORD)
137                                 disp(virt);
138                         else {
139                                 t3 = t1;
140                                 do {
141                                         /* LWA of object */
142                                         t3 += M[t3];
143                                         if (M[t3 + STATSL] != 0)
144                                                 errsignal(RTEILLKL);
145                                         /* next object in DL */
146                                         t3 = M[ t3+DL ];
147                                         if (t3 == 0)
148                                                 errsignal(RTEILLKL);
149                                         /* am of DL */
150                                         t3 = M[ t3 ];
151                                 } while (t3 != t1);
152                                 /* kill DL chain */
153                                 do {
154                                         t3 += M[t3];
155                                         loadvirt(vt, t3 + DL);
156                                         disp(virt);
157                                         virt->addr = vt.addr;
158                                         virt->mark = vt.mark;
159                                         t3 = M[virt->addr];
160                                 } while (M[virt->addr + 1] == virt->mark);
161                         }
162                 }
163         }
164 }
165
166 /**
167  * Copy object to a new object and locate it by fresh.
168  */
169 void copy(virtaddr *old, virtaddr *fresh)
170 {
171         word t1, t2, t3, virts;
172         protdescr *ptr;
173         bool notrecord;
174
175         /* fine copy for none */
176         if (M[ old->addr+1 ] != old->mark) {
177                 fresh->addr = 0;
178                 /* note M[ 1 ] <> 0 */
179                 fresh->mark = 0;
180         }
181         /* not none */
182         else {
183                 /* am of old */
184                 t1 = M[old->addr];
185                 /* assume it is a record */
186                 notrecord = FALSE;
187                 t2 = M[t1 + PROTNUM];
188                 /* if not array nor file */
189                 if (t2 != AINT && t2 != AREAL && t2 != AVIRT &&
190                                                         t2 != FILEOBJECT) {
191                         ptr = prototype[t2];
192                         /* our assumption was wrong */
193                         if (ptr->kind != RECORD) {
194                                 notrecord = TRUE;
195                                 t3 = t1 + M[t1] + DL;
196                                 /* non-terminated object */
197                                 if (M[t3] != old->addr ||
198                                         M[t3 + 1] != old->mark) {
199                                         errsignal(RTEILLCP);
200                                 }
201                         }
202                 }
203                 virts = thisp->prochead + M[thisp->prochead] + VIRTSC;
204                 /* preserve for compactification */
205                 storevirt(*old, virts);
206                 /* book field */
207                 request(M[ t1 ], &t2, &t3);
208                 /* ah */
209                 fresh->addr = t2;
210                 fresh->mark = M[fresh->addr + 1];
211                 t1 = M[M[virts]];
212                 for (t2 = 1; t2 < M[t1]; t2++)
213                         M[t3 + t2] = M[t1 + t2];
214
215                 if (notrecord) {
216                         /* loop up DL */
217                         storevirt(*fresh, t3 + M[t3] + DL);
218                         /* not in any SL chain */
219                         M[t3 + M[t3] + STATSL] = 0;
220                 }
221         }
222 }