cfad47cfa3/t2compiler/tads2/objcomp.c

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#ifdef RCSID
2
static char RCSid[] =
3
"$Header: d:/cvsroot/tads/TADS2/OBJCOMP.C,v 1.3 1999/07/11 00:46:30 MJRoberts Exp $";
4
#endif
5
6
/* 
7
 *   Copyright (c) 1992, 2002 Michael J. Roberts.  All Rights Reserved.
8
 *   
9
 *   Please see the accompanying license file, LICENSE.TXT, for information
10
 *   on using and copying this software.  
11
 */
12
/*
13
Name
14
  objcomp.c - object manipulation routines for compiler
15
Function
16
  Provides routines used only by the compiler
17
Notes
18
  Split off from obj main module to make run-time smaller
19
Modified
20
  12/18/92 MJRoberts     - creation
21
*/
22
23
#include "os.h"
24
#include "std.h"
25
#include "err.h"
26
#include "mcm.h"
27
#include "obj.h"
28
29
/*
30
 *   Set up for emitting code into an object.  No undo information is
31
 *   kept for this type of operation, as it is presumed that the object is
32
 *   being compiled rather than being manipulated at run-time.  Any
33
 *   previous value for the property is deleted, a property header is set
34
 *   up, and the offset of the next free byte in the object is returned.
35
 */
36
uint objemt(mcmcxdef *ctx, objnum objn, prpnum prop, dattyp typ)
37
{
38
    objdef *objptr;
39
    prpdef *p;
40
    
41
    objptr = (objdef *)mcmlck(ctx, (mcmon)objn);
42
    
43
    ERRBEGIN(ctx->mcmcxgl->mcmcxerr)
44
45
    objdelp(ctx, objn, prop, FALSE);   /* delete old property value, if any */
46
    p = objpfre(objptr);                        /* get top of property area */
47
    
48
    if ((char *)p - (char *)objptr + PRPHDRSIZ >=
49
        mcmobjsiz(ctx, (mcmon)objn))
50
    {
51
        ushort newsiz = 64 + ((objfree(objptr) + PRPHDRSIZ) -
52
                              mcmobjsiz(ctx, (mcmon)objn));
53
        objptr = objexp(ctx, objn, &newsiz);
54
        p = objpfre(objptr);                       /* object may have moved */
55
    }
56
    
57
    /* set up property header as much as we can (don't know size yet) */
58
    prpsetprop(p, prop);
59
    prptype(p) = typ;
60
    prpflg(p) = 0;
61
    objsnp(objptr, objnprop(objptr) + 1);              /* one more property */
62
63
    ERRCLEAN(ctx->mcmcxgl->mcmcxerr)
64
        mcmunlck(ctx, (mcmon)objn);
65
    ERRENDCLN(ctx->mcmcxgl->mcmcxerr)
66
67
    /* dirty the cache object and release the lock before return */
68
    mcmtch(ctx, objn);
69
    mcmunlck(ctx, (mcmon)objn);
70
    return(((uchar *)prpvalp(p)) - ((uchar *)objptr));
71
}
72
73
/* done emitting code into property - finish setting object information */
74
void objendemt(mcmcxdef *ctx, objnum objn, prpnum prop, uint endofs)
75
{
76
    objdef *objptr;
77
    prpdef *p;
78
    uint    siz;
79
    
80
    objptr = (objdef *)mcmlck(ctx, (mcmon)objn);
81
    p = objofsp(objptr, objgetp(ctx, objn, prop, (dattyp *)0));
82
    
83
    siz = endofs - (((uchar *)prpvalp(p)) - ((uchar *)objptr));
84
    
85
    prpsetsize(p, siz);
86
    objsfree(objptr, objfree(objptr) + siz + PRPHDRSIZ);
87
    
88
    /* mark the object as changed, and unlock it */
89
    mcmtch(ctx, (mcmon)objn);
90
    mcmunlck(ctx, (mcmon)objn);
91
}
92
93
/* add superclasses to an object */
94
void objaddsc(mcmcxdef *mctx, int sccnt, objnum objn)
95
{
96
    objdef *o;
97
    ushort  siz;
98
    
99
    /* get lock on object */
100
    o = (objdef *)mcmlck(mctx, objn);
101
    
102
    /* make sure there's enough space, adding space if needed */
103
    if (mcmobjsiz(mctx, (mcmon)objn) - objfree(o) < 2 * sccnt)
104
    {
105
        siz = 64 + ((2 * sccnt + objfree(o)) -
106
                    mcmobjsiz(mctx, (mcmon)objn));
107
        o = objexp(mctx, objn, &siz);                  /* expand the object */
108
    }
109
110
    /* move properties, if any, above added superclasses */
111
    if (objnprop(o))
112
        memmove(objprp(o), ((uchar *)objprp(o)) + 2 * sccnt,
113
                (size_t)(((uchar *)o) + objfree(o) - (uchar *)objprp(o)));
114
    
115
    /* set new free pointer */
116
    objsfree(o, objfree(o) + 2 * sccnt);
117
    
118
    /* mark cache object modified and unlock it */
119
    mcmtch(mctx, objn);
120
    mcmunlck(mctx, objn);
121
}
122
123
/* delete an object's properties and superclasses */
124
void objclr(mcmcxdef *mctx, objnum objn, prpnum mindel)
125
{
126
    objdef *o;
127
    prpdef *p;
128
    int     cnt;
129
    prpnum  prop;
130
    int     indexed;
131
    
132
    /* get a lock on the object */
133
    o = (objdef *)mcmlck(mctx, objn);
134
    indexed = objflg(o) & OBJFINDEX;
135
    
136
    /* delete superclasses - move properties down over former sc array */
137
    if (objnprop(o))
138
        memmove(objsc(o), objprp(o),
139
                (size_t)(((uchar *)o) + objfree(o) - (uchar *)objprp(o)));
140
    objsnsc(o, 0);                                 /* zero superclasses now */
141
    
142
    /* delete non-"system" properties (propnum < mindel) */
143
    for (p = objprp(o), cnt = objnprop(o) ; cnt ; --cnt)
144
    {
145
        if ((prop = prpprop(p)) >= mindel)
146
        {
147
            prpflg(p) &= ~PRPFIGN;   /* delete even if it was marked ignore */
148
            objdelp(mctx, objn, prop, FALSE);  /* remove prpdef from object */
149
            /* p is left pointing at next prop, as it was moved down */
150
        }
151
        else
152
            p = objpnxt(p);                   /* advance over this property */
153
    }
154
    
155
    /* mark cache object modified and unlock it */
156
    mcmtch(mctx, objn);
157
    mcmunlck(mctx, objn);
158
    if (indexed) objindx(mctx, objn);
159
}
160
161
/* set up just-compiled object:  mark static part and original props */
162
void objcomp(mcmcxdef *mctx, objnum objn, int for_debug)
163
{
164
    objdef *objptr;
165
    prpdef *p;
166
    prpdef *nxt;
167
    int     cnt;
168
    
169
    /* lock object */
170
    objptr = (objdef *)mcmlck(mctx, (mcmon)objn);
171
172
    /* 
173
     *   first, go through the properties, and delete each one that's
174
     *   marked as ignored 
175
     */
176
    for (cnt = objnprop(objptr), p = objprp(objptr) ; cnt != 0 ;
177
         p = nxt, --cnt)
178
    {
179
        /* remember the next property */
180
        nxt = objpnxt(p);
181
182
        /* if this is marked as being ignored, delete it */
183
        if ((prpflg(p) & PRPFIGN) != 0)
184
        {
185
            /* 
186
             *   Delete the property.  If we're compiling in debug mode,
187
             *   don't really delete anything, but simply mark the
188
             *   property as deleted; this is necessary because certain
189
             *   debug records are not self-relative, hence are not
190
             *   tolerant of changes to the internal structure of the
191
             *   object.  If we're not compiling for debugging, we can
192
             *   actually delete properties, because all non-debug code is
193
             *   completely self-relative and thus can be moved around
194
             *   inside the object without any problems.  
195
             */
196
            if (for_debug)
197
            {
198
                /* simply mark the property as deleted */
199
                prpflg(p) |= PRPFDEL;
200
201
                /* 
202
                 *   clear the IGNORE flag, since we IGNORE and DELETED
203
                 *   are mutually exclusive 
204
                 */
205
                prpflg(p) &= ~PRPFIGN;
206
            }
207
            else
208
            {
209
                /* clear the flags so we can really delete it */
210
                prpflg(p) &= ~(PRPFORG | PRPFIGN | PRPFDEL);
211
212
                /* delete it */
213
                objdelp(mctx, objn, (prpnum)prpprop(p), FALSE);
214
215
                /* 
216
                 *   continue from the present location, since we moved
217
                 *   the next property to the current location 
218
                 */
219
                nxt = p;
220
            }
221
        }
222
    }
223
    
224
    /* set static entries:  free space pointer, and number of properties */
225
    objsetst(objptr, objnprop(objptr));
226
    objsetrst(objptr, objfree(objptr));
227
228
    /* go through properties, marking each as original */
229
    for (cnt = objnprop(objptr), p = objprp(objptr) ; cnt != 0 ;
230
         p = objpnxt(p), --cnt)
231
    {
232
        assert(p < objptr + mcmobjsiz(mctx, (mcmon)objn));
233
        prpflg(p) |= PRPFORG;             /* set ORIGINAL flag for property */
234
    }
235
    
236
    /* mark object changed, and unlock it */
237
    mcmtch(mctx, objn);
238
    mcmunlck(mctx, objn);
239
}
240