-
Notifications
You must be signed in to change notification settings - Fork 17
/
tct3prg.cpp
240 lines (207 loc) · 7.62 KB
/
tct3prg.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#ifdef RCSID
static char RCSid[] =
"$Header: d:/cvsroot/tads/tads3/TCT3STM.CPP,v 1.1 1999/07/11 00:46:57 MJRoberts Exp $";
#endif
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
tct3stm.cpp - TADS 3 Compiler - T3 VM Code Generator - program-level classes
Function
Generate code for the T3 VM. This file contains program-level classes,
in order to segregate the code generation classes required for the full
compiler from those required for subsets that require only expression
parsing (such as debuggers). The program-level classes are for statements
at the outer level, outside of executable code: object definitions,
dictionary declarations, etc. This also includes code to read and
write object files.
Notes
Modified
05/08/99 MJRoberts - Creation
*/
#include <stdio.h>
#include "t3std.h"
#include "os.h"
#include "tcprs.h"
#include "tct3.h"
#include "tcgen.h"
#include "vmtype.h"
#include "vmwrtimg.h"
#include "vmfile.h"
#include "tcmain.h"
#include "tcerr.h"
/* ------------------------------------------------------------------------ */
/*
* Object Definition Statement
*/
/*
* given the offset of the start of an object in the compiled object
* stream, get the offset of the first property
*/
ulong CTPNStmObject::get_stream_first_prop_ofs(CTcDataStream *stream,
ulong obj_ofs)
{
/*
* the property table follows the superclass table, which follows
* the tads-object header; the superclass table contains 4 bytes per
* superclass (we can obtain the superclass count from the stream
* data)
*/
return obj_ofs + TCT3_TADSOBJ_SC_OFS
+ (get_stream_sc_cnt(stream, obj_ofs) * 4);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the offset of the property at the given index
*/
ulong CTPNStmObject::get_stream_prop_ofs(CTcDataStream *stream,
ulong obj_ofs, uint idx)
{
/*
* calculate the offset to the selected property from the start of
* the property table
*/
return get_stream_first_prop_ofs(stream, obj_ofs)
+ (TCT3_TADSOBJ_PROP_SIZE * idx);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the number of properties in the stream data
*/
uint CTPNStmObject::get_stream_prop_cnt(CTcDataStream *stream,
ulong obj_ofs)
{
/* the property count is at offset 2 in the tads-object header */
return stream->readu2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 2);
}
/*
* given the offset of the start of an object in the compiled object
* stream, set the number of properties in the stream data, adjusting
* the data size in the metaclass header to match
*/
size_t CTPNStmObject::set_stream_prop_cnt(CTcDataStream *stream,
ulong obj_ofs, uint prop_cnt)
{
size_t data_size;
/* the property count is at offset 2 in the tads-object header */
stream->write2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 2, prop_cnt);
/*
* calculate the new data size to store in the metaclass header --
* this is the size of the tads-object header, plus the size of the
* superclass table (4 bytes per superclass), plus the size of the
* property table
*/
data_size = TCT3_TADSOBJ_HEADER_SIZE
+ (get_stream_sc_cnt(stream, obj_ofs) * 4)
+ (prop_cnt * TCT3_TADSOBJ_PROP_SIZE);
/* write the data size to the metaclass header (it's at offset 4) */
stream->write2_at(obj_ofs + TCT3_META_HEADER_OFS + 4, data_size);
/* return the new data size */
return data_size;
}
/*
* Get the object flags from an object in a compiled stream
*/
uint CTPNStmObject::get_stream_obj_flags(CTcDataStream *stream,
ulong obj_ofs)
{
/* the flags are at offset 4 in the tads-object header */
return stream->read2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 4);
}
/*
* Set the object flags in an object in a compiled stream
*/
void CTPNStmObject::set_stream_obj_flags(CTcDataStream *stream,
ulong obj_ofs, uint flags)
{
/*
* write the new flags - they're at offset 4 in the tads-object
* header
*/
stream->write2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 4, flags);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the number of superclasses in the stream data
*/
uint CTPNStmObject::get_stream_sc_cnt(CTcDataStream *stream,
ulong obj_ofs)
{
/* the superclass count is at offset 0 in the tads-object header */
return stream->readu2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 0);
}
/*
* given the stream offset of the start of an object in the compiled
* object stream, change a superclass object ID
*/
void CTPNStmObject::set_stream_sc(CTcDataStream *stream, ulong obj_ofs,
uint sc_idx, vm_obj_id_t new_sc)
{
/*
* set the superclass - it's at offset 6 in the object data, plus
* four bytes (UINT4) per index slot
*/
stream->write2_at(obj_ofs + TCT3_TADSOBJ_HEADER_OFS + 6 + (sc_idx * 4),
new_sc);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the property ID of the property at a given index in the
* property table
*/
vm_prop_id_t CTPNStmObject::get_stream_prop_id(CTcDataStream *stream,
ulong obj_ofs, uint prop_idx)
{
ulong prop_ofs;
/* get the property's data offset */
prop_ofs = get_stream_prop_ofs(stream, obj_ofs, prop_idx);
/* read the property ID - it's at offset 0 in the property data */
return (vm_prop_id_t)stream->readu2_at(prop_ofs);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the datatype of the property at the given index in the
* property table
*/
vm_datatype_t CTPNStmObject::
get_stream_prop_type(CTcDataStream *stream, ulong obj_ofs, uint prop_idx)
{
ulong dh_ofs;
/* get the property's data holder offset */
dh_ofs = get_stream_prop_val_ofs(stream, obj_ofs, prop_idx);
/* the type is the first byte of the serialized data holder */
return (vm_datatype_t)stream->get_byte_at(dh_ofs);
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the stream offset of the serialized DATAHOLDER structure
* for the property at the given index in the property table
*/
ulong CTPNStmObject::get_stream_prop_val_ofs(CTcDataStream *stream,
ulong obj_ofs, uint prop_idx)
{
ulong prop_ofs;
/* get the property's data offset */
prop_ofs = get_stream_prop_ofs(stream, obj_ofs, prop_idx);
/* the data holder immediately follows the (UINT2) property ID */
return prop_ofs + 2;
}
/*
* given the offset of the start of an object in the compiled object
* stream, get the property ID of the property at a given index in the
* property table
*/
void CTPNStmObject::set_stream_prop_id(CTcDataStream *stream,
ulong obj_ofs, uint prop_idx,
vm_prop_id_t new_id)
{
ulong prop_ofs;
/* get the property's data offset */
prop_ofs = get_stream_prop_ofs(stream, obj_ofs, prop_idx);
/* set the data */
stream->write2_at(prop_ofs, (uint)new_id);
}