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