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