7 /* object management routines */
10 void openrc(prot, virt, addr) /* Open new field for a record. */
17 request(prototype[ prot ]->appetite, &t1, addr);
18 M[ *addr+PROTNUM ] = prot;
20 virt->mark = M[ t1+1 ];
24 void slopen(prot, sladr, ah, am)
31 virts = thisp->prochead+M[ thisp->prochead ]+VIRTSC;
32 storevirt(*sladr, virts); /* preserve for compactifier */
33 t1 = prototype[ prot ]->appetite;
35 request(t1, ah, am); /* open field */
37 M[ *am+PROTNUM ] = prot;
38 t1 = *am+t1; /* LWA+1 of object */
39 M[ t1+SL ] = M[ virts ]; /* prepare SL pointer */
40 M[ t1+SL+1 ] = M[ virts+1 ];
41 t2 = M[ display2+M[ c1+PROTNUM ] ]; /* ah of current */
43 M[ t1+DL+1 ] = M[ t2+1 ];
48 void openobj(prot, ah, am)
55 t1 = M[ display2+prototype[ prot ]->slprototype ];
56 v1.addr = t1; /* ah of SL */
58 slopen(prot, &v1, ah, am);
62 void newarry(low, up, kind, virt, am) /* Reserve room for array */
71 case AINT : ap = APINT; break;
72 case AREAL : ap = APREAL; break;
73 case AVIRT : ap = APREF; break;
74 case APROCESS : ap = APINT; break;
78 if (up < low) errsignal(RTEILLAB); /* illegal array bounds */
80 request(up-low+ap, &virt->addr, am);
83 virt->mark = M[ virt->addr+1 ];
87 void gkill(virt) /* Generalized killer */
95 if (isprocess(virt)) /* kill remote process */
97 msg.control.type = KILLPR;
98 obj2mess( M, virt, &msg.control.receiver );
99 sendmsg1( &msg);/* send remote kill request */
102 if (virt->mark == M[ virt->addr+1 ])
104 t1 = M[ virt->addr ]; /* am */
105 t2 = M[ t1+PROTNUM ];
106 if (t2 == AINT || t2 == AREAL || t2 == AVIRT)
107 disp(virt); /* simple kill for array */
109 if (t2 == FILEOBJECT)
110 { /* First close file if opened */
111 if (M[ t1+FSTAT ] != UNKNOWN)
112 if (fclose(MF(t1+FFILE))) errsignal(RTEILLIO);
113 /* Delete file if temporary */
114 if (M[ t1+FTEMP ] == LTRUE)
115 if (unlink(MN(t1+FNAME))) errsignal(RTEILLIO);
119 else /* more than array or file */
121 ptr = prototype[ t2 ];
122 if (ptr->kind == RECORD)
129 t3 += M[ t3 ]; /* LWA of object */
130 if (M[ t3+STATSL ] != 0) errsignal(RTEILLKL);
131 t3 = M[ t3+DL ]; /* next object in DL */
132 if (t3 == 0) errsignal(RTEILLKL);
133 t3 = M[ t3 ]; /* am of DL */
135 do /* kill DL chain */
140 virt->addr = vt.addr;
141 virt->mark = vt.mark;
142 t3 = M[ virt->addr ];
143 } while (M[ virt->addr+1 ] == virt->mark);
150 /* Copy object to a new object and locate it by fresh.
153 void copy(old, fresh)
154 virtaddr *old, *fresh;
156 word t1, t2, t3, virts;
160 if (M[ old->addr+1 ] != old->mark)
161 { /* fine copy for none */
163 fresh->mark = 0; /* note M[ 1 ] <> 0 */
167 t1 = M[ old->addr ]; /* am of old */
168 notrecord = FALSE; /* assume it is a record */
169 t2 = M[ t1+PROTNUM ];
170 if (t2 != AINT && t2 != AREAL && t2 != AVIRT && t2 != FILEOBJECT)
171 { /* if not array nor file */
172 ptr = prototype[ t2 ];
173 if (ptr->kind != RECORD) /* our assumption was wrong */
177 if (M[ t3 ] != old->addr || M[ t3+1 ] != old->mark)
178 errsignal(RTEILLCP); /* non-terminated object */
181 virts = thisp->prochead+M[ thisp->prochead ]+VIRTSC;
182 storevirt(*old, virts); /* preserve for compactification */
183 request(M[ t1 ], &t2, &t3); /* book field */
184 fresh->addr = t2; /* ah */
185 fresh->mark = M[ fresh->addr+1 ];
186 t1 = M[ M[ virts ] ];
187 for (t2 = 1; t2 < M[ t1 ]; t2++ )
188 M[ t3+t2 ] = M[ t1+t2 ];
191 storevirt(*fresh, t3+M[ t3 ]+DL); /* loop up DL */
192 M[ t3+M[ t3 ]+STATSL ] = 0; /* not in any SL chain */