cfad47cfa3/t3compiler/tads3/tct3unas.cpp

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#ifdef RCSID
2
static char RCSid[] =
3
"$Header: d:/cvsroot/tads/tads3/TCT3UNAS.CPP,v 1.3 1999/07/11 00:46:57 MJRoberts Exp $";
4
#endif
5
6
/* 
7
 *   Copyright (c) 1999, 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
  tct3unas.cpp - TADS 3 Compiler - T3 Unassembler
15
Function
16
  
17
Notes
18
  
19
Modified
20
  05/10/99 MJRoberts  - Creation
21
*/
22
23
#include "t3std.h"
24
#include "vmop.h"
25
#include "tcunas.h"
26
#include "tct3unas.h"
27
#include "vmtype.h"
28
29
30
/* ------------------------------------------------------------------------ */
31
/*
32
 *   disassemble a code stream 
33
 */
34
void CTcT3Unasm::disasm(CTcUnasSrc *src, CTcUnasOut *out)
35
{
36
    /* keep going until we run out of source material */
37
    for (;;)
38
    {
39
        char ch;
40
        
41
        /* get the next byte; stop if we've reached the end of the source */
42
        if (src->next_byte(&ch))
43
            break;
44
45
        /* disassemble this instruction */
46
        disasm_instr(src, out, ch);
47
    }
48
}
49
50
/* ------------------------------------------------------------------------ */
51
/*
52
 *   T3 Instruction Information Array 
53
 */
54
t3_instr_info_t CTcT3Unasm::instr_info[] =
55
{
56
    /* 0x00 */ { "db 0",  0,},
57
    /* 0x01 */ { "push_0",     0 },
58
    /* 0x02 */ { "push_1",     0 },
59
    /* 0x03 */ { "pushint8",   1, { T3OP_TYPE_8S }},
60
    /* 0x04 */ { "pushint",    1, { T3OP_TYPE_32S }},
61
    /* 0x05 */ { "pushstr",    1, { T3OP_TYPE_STR }},
62
    /* 0x06 */ { "pushlst",    1, { T3OP_TYPE_LIST }},
63
    /* 0x07 */ { "pushobj",    1, { T3OP_TYPE_OBJ }},
64
    /* 0x08 */ { "pushnil",    0 },
65
    /* 0x09 */ { "pushtrue",   0 },
66
    /* 0x0a */ { "pushpropid", 1, { T3OP_TYPE_PROP }},
67
    /* 0x0b */ { "pushfnptr",  1, { T3OP_TYPE_CODE_ABS }},
68
    /* 0x0c */ { "pushstri",   1, { T3OP_TYPE_INLINE_STR }},
69
    /* 0x0d */ { "pushparlst", 1, { T3OP_TYPE_8U }},
70
    /* 0x0e */ { "makelstpar", 0 },
71
    /* 0x0f */ { "pushenum",   1, { T3OP_TYPE_ENUM }},
72
    /* 0x10 */ { "db 0x10", 0 },
73
    /* 0x11 */ { "db 0x11", 0 },
74
    /* 0x12 */ { "db 0x12", 0 },
75
    /* 0x13 */ { "db 0x13", 0 },
76
    /* 0x14 */ { "db 0x14", 0 },
77
    /* 0x15 */ { "db 0x15", 0 },
78
    /* 0x16 */ { "db 0x16", 0 },
79
    /* 0x17 */ { "db 0x17", 0 },
80
    /* 0x18 */ { "db 0x18", 0 },
81
    /* 0x19 */ { "db 0x19", 0 },
82
    /* 0x1a */ { "db 0x1a", 0 },
83
    /* 0x1b */ { "db 0x1b", 0 },
84
    /* 0x1c */ { "db 0x1c", 0 },
85
    /* 0x1d */ { "db 0x1d", 0 },
86
    /* 0x1e */ { "db 0x1e", 0 },
87
    /* 0x1f */ { "db 0x1f", 0 },
88
    /* 0x20 */ { "neg", 0 },
89
    /* 0x21 */ { "bnot", 0 },
90
    /* 0x22 */ { "add", 0 },
91
    /* 0x23 */ { "sub", 0 },
92
    /* 0x24 */ { "mul", 0 },
93
    /* 0x25 */ { "band", 0 },
94
    /* 0x26 */ { "bor", 0 },
95
    /* 0x27 */ { "shl", 0 },
96
    /* 0x28 */ { "shr", 0 },
97
    /* 0x29 */ { "xor", 0 },
98
    /* 0x2a */ { "div", 0 },
99
    /* 0x2b */ { "mod", 0 },
100
    /* 0x2c */ { "not", 0 },
101
    /* 0x2d */ { "boolize", 0 },
102
    /* 0x2e */ { "inc", 0 },
103
    /* 0x2f */ { "dec", 0 },
104
    /* 0x30 */ { "db 0x30", 0 },
105
    /* 0x31 */ { "db 0x31", 0 },
106
    /* 0x32 */ { "db 0x32", 0 },
107
    /* 0x33 */ { "db 0x33", 0 },
108
    /* 0x34 */ { "db 0x34", 0 },
109
    /* 0x35 */ { "db 0x35", 0 },
110
    /* 0x36 */ { "db 0x36", 0 },
111
    /* 0x37 */ { "db 0x37", 0 },
112
    /* 0x38 */ { "db 0x38", 0 },
113
    /* 0x39 */ { "db 0x39", 0 },
114
    /* 0x3a */ { "db 0x3a", 0 },
115
    /* 0x3b */ { "db 0x3b", 0 },
116
    /* 0x3c */ { "db 0x3c", 0 },
117
    /* 0x3d */ { "db 0x3d", 0 },
118
    /* 0x3e */ { "db 0x3e", 0 },
119
    /* 0x3f */ { "db 0x3f", 0 },
120
    /* 0x40 */ { "eq", 0 },
121
    /* 0x41 */ { "ne", 0 },
122
    /* 0x42 */ { "lt", 0 },
123
    /* 0x43 */ { "le", 0 },
124
    /* 0x44 */ { "gt", 0 },
125
    /* 0x45 */ { "ge", 0 },
126
    /* 0x46 */ { "db 0x46", 0 },
127
    /* 0x47 */ { "db 0x47", 0 },
128
    /* 0x48 */ { "db 0x48", 0 },
129
    /* 0x49 */ { "db 0x49", 0 },
130
    /* 0x4a */ { "db 0x4a", 0 },
131
    /* 0x4b */ { "db 0x4b", 0 },
132
    /* 0x4c */ { "db 0x4c", 0 },
133
    /* 0x4d */ { "db 0x4d", 0 },
134
    /* 0x4e */ { "db 0x4e", 0 },
135
    /* 0x4f */ { "db 0x4f", 0 },
136
    /* 0x50 */ { "retval", 0 },
137
    /* 0x51 */ { "retnil", 0 },
138
    /* 0x52 */ { "rettrue", 0 },
139
    /* 0x53 */ { "db 0x53", 0 },
140
    /* 0x54 */ { "ret", 0 },
141
    /* 0x55 */ { "db 0x55", 0 },
142
    /* 0x56 */ { "db 0x56", 0 },
143
    /* 0x57 */ { "db 0x57", 0 },
144
    /* 0x58 */ { "call", 2, { T3OP_TYPE_8U, T3OP_TYPE_CODE_ABS }},
145
    /* 0x59 */ { "ptrcall", 1, { T3OP_TYPE_8U }},
146
    /* 0x5a */ { "db 0x5a", 0 },
147
    /* 0x5b */ { "db 0x5b", 0 },
148
    /* 0x5c */ { "db 0x5c", 0 },
149
    /* 0x5d */ { "db 0x5d", 0 },
150
    /* 0x5e */ { "db 0x5e", 0 },
151
    /* 0x5f */ { "db 0x5f", 0 },
152
    /* 0x60 */ { "getprop", 1, { T3OP_TYPE_PROP }},
153
    /* 0x61 */ { "callprop", 2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
154
    /* 0x62 */ { "ptrcallprop", 1, { T3OP_TYPE_8U }},
155
    /* 0x63 */ { "getpropself", 1, { T3OP_TYPE_PROP }},
156
    /* 0x64 */ { "callpropself", 2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
157
    /* 0x65 */ { "ptrcallpropself", 1, { T3OP_TYPE_8U }},
158
    /* 0x66 */ { "objgetprop", 2, { T3OP_TYPE_OBJ, T3OP_TYPE_PROP }},
159
    /* 0x67 */ { "objcallprop", 3,
160
                   { T3OP_TYPE_8U, T3OP_TYPE_OBJ, T3OP_TYPE_PROP }},
161
    /* 0x68 */ { "getpropdata", 1, { T3OP_TYPE_PROP }},
162
    /* 0x69 */ { "ptrgetpropdata", 0 },
163
    /* 0x6a */ { "getproplcl1", 2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
164
    /* 0x6b */ { "callproplcl1", 3,
165
                   { T3OP_TYPE_8U, T3OP_TYPE_8U, T3OP_TYPE_PROP }},
166
    /* 0x6c */ { "getpropr0", 1, { T3OP_TYPE_PROP }},
167
    /* 0x6d */ { "callpropr0", 2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
168
    /* 0x6e */ { "db 0x6e", 0 },
169
    /* 0x6f */ { "db 0x6f", 0 },
170
    /* 0x70 */ { "db 0x70", 0 },
171
    /* 0x71 */ { "db 0x71", 0 },
172
    /* 0x72 */ { "inherit", 2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
173
    /* 0x73 */ { "ptrinherit", 1, { T3OP_TYPE_8U }},
174
    /* 0x74 */ { "expinherit", 3,
175
                   { T3OP_TYPE_8U, T3OP_TYPE_PROP, T3OP_TYPE_OBJ }},
176
    /* 0x75 */ { "ptrexpinherit", 2, { T3OP_TYPE_8U, T3OP_TYPE_OBJ }},
177
    /* 0x76 */ { "varargc", 0 },
178
    /* 0x77 */ { "delegate",   2, { T3OP_TYPE_8U, T3OP_TYPE_PROP }},
179
    /* 0x78 */ { "ptrdelegate", 1, { T3OP_TYPE_PROP }},
180
    /* 0x79 */ { "db 0x79", 0 },
181
    /* 0x7a */ { "db 0x7a", 0 },
182
    /* 0x7b */ { "db 0x7b", 0 },
183
    /* 0x7c */ { "db 0x7c", 0 },
184
    /* 0x7d */ { "db 0x7d", 0 },
185
    /* 0x7e */ { "db 0x7e", 0 },
186
    /* 0x7f */ { "db 0x7f", 0 },
187
    /* 0x80 */ { "getlcl1", 1, { T3OP_TYPE_8U }},
188
    /* 0x81 */ { "getlcl2", 1, { T3OP_TYPE_16U }},
189
    /* 0x82 */ { "getarg1", 1, { T3OP_TYPE_8U }},
190
    /* 0x83 */ { "getarg2", 1, { T3OP_TYPE_16U }},
191
    /* 0x84 */ { "pushself", 0 },
192
    /* 0x85 */ { "getdblcl", 2, { T3OP_TYPE_16U, T3OP_TYPE_16U }},
193
    /* 0x86 */ { "getdbarg", 2, { T3OP_TYPE_16U, T3OP_TYPE_16U }},
194
    /* 0x87 */ { "getargc", 0 },
195
    /* 0x88 */ { "dup", 0 },
196
    /* 0x89 */ { "disc", 0 },
197
    /* 0x8a */ { "disc1", 1, { T3OP_TYPE_8U }},
198
    /* 0x8b */ { "getr0", 0 },
199
    /* 0x8c */ { "getdbargc", 1, { T3OP_TYPE_16U }},
200
    /* 0x8d */ { "swap", 0 },
201
    /* 0x8e */ { "pushctxele", 1, { T3OP_TYPE_CTX_ELE }},
202
    /* 0x8f */ { "db 0x8f", 0 },
203
    /* 0x90 */ { "switch", 0 },
204
    /* 0x91 */ { "jmp", 1, { T3OP_TYPE_CODE_REL }},
205
    /* 0x92 */ { "jt", 1, { T3OP_TYPE_CODE_REL }},
206
    /* 0x93 */ { "jf", 1, { T3OP_TYPE_CODE_REL }},
207
    /* 0x94 */ { "je", 1, { T3OP_TYPE_CODE_REL }},
208
    /* 0x95 */ { "jne", 1, { T3OP_TYPE_CODE_REL }},
209
    /* 0x96 */ { "jgt", 1, { T3OP_TYPE_CODE_REL }},
210
    /* 0x97 */ { "jge", 1, { T3OP_TYPE_CODE_REL }},
211
    /* 0x98 */ { "jlt", 1, { T3OP_TYPE_CODE_REL }},
212
    /* 0x99 */ { "jle", 1, { T3OP_TYPE_CODE_REL }},
213
    /* 0x9a */ { "jst", 1, { T3OP_TYPE_CODE_REL }},
214
    /* 0x9b */ { "jsf", 1, { T3OP_TYPE_CODE_REL }},
215
    /* 0x9c */ { "ljsr", 1, { T3OP_TYPE_CODE_REL }},
216
    /* 0x9d */ { "lret", 1, { T3OP_TYPE_16U }},
217
    /* 0x9e */ { "jnil", 1, { T3OP_TYPE_CODE_REL }},
218
    /* 0x9f */ { "jnotnil", 1, { T3OP_TYPE_CODE_REL }},
219
    /* 0xa0 */ { "jr0t", 1, { T3OP_TYPE_CODE_REL }},
220
    /* 0xa1 */ { "jr0f", 1, { T3OP_TYPE_CODE_REL }},
221
    /* 0xa2 */ { "db 0xa2", 0 },
222
    /* 0xa3 */ { "db 0xa3", 0 },
223
    /* 0xa4 */ { "db 0xa4", 0 },
224
    /* 0xa5 */ { "db 0xa5", 0 },
225
    /* 0xa6 */ { "db 0xa6", 0 },
226
    /* 0xa7 */ { "db 0xa7", 0 },
227
    /* 0xa8 */ { "db 0xa8", 0 },
228
    /* 0xa9 */ { "db 0xa9", 0 },
229
    /* 0xaa */ { "db 0xaa", 0 },
230
    /* 0xab */ { "db 0xab", 0 },
231
    /* 0xac */ { "db 0xac", 0 },
232
    /* 0xad */ { "db 0xad", 0 },
233
    /* 0xae */ { "db 0xae", 0 },
234
    /* 0xaf */ { "db 0xaf", 0 },
235
    /* 0xb0 */ { "say", 1, { T3OP_TYPE_STR }},
236
    /* 0xb1 */ { "builtin_a", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
237
    /* 0xb2 */ { "builtin_b", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
238
    /* 0xb3 */ { "builtin_c", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
239
    /* 0xb4 */ { "builtin_d", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
240
    /* 0xb5 */ { "builtin1", 3, { T3OP_TYPE_8U, T3OP_TYPE_8U, T3OP_TYPE_8U }},
241
    /* 0xb6 */ { "builtin2", 0, { T3OP_TYPE_16U, T3OP_TYPE_8U, T3OP_TYPE_8U }},
242
    /* 0xb7 */ { "callext", 0 },
243
    /* 0xb8 */ { "throw", 0 },
244
    /* 0xb9 */ { "sayval", 0 },
245
    /* 0xba */ { "index", 0 },
246
    /* 0xbb */ { "idxlcl1int8", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
247
    /* 0xbc */ { "idxint8", 1, { T3OP_TYPE_8U }},
248
    /* 0xbd */ { "db 0xbd", 0 },
249
    /* 0xbe */ { "db 0xbe", 0 },
250
    /* 0xbf */ { "db 0xbf", 0 },
251
    /* 0xc0 */ { "new1", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
252
    /* 0xc1 */ { "new2", 2, { T3OP_TYPE_16U, T3OP_TYPE_8U }},
253
    /* 0xc2 */ { "trnew1", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
254
    /* 0xc3 */ { "trnew2", 2, { T3OP_TYPE_16U, T3OP_TYPE_8U }},
255
    /* 0xc4 */ { "db 0xc4", 0 },
256
    /* 0xc5 */ { "db 0xc5", 0 },
257
    /* 0xc6 */ { "db 0xc6", 0 },
258
    /* 0xc7 */ { "db 0xc7", 0 },
259
    /* 0xc8 */ { "db 0xc8", 0 },
260
    /* 0xc9 */ { "db 0xc9", 0 },
261
    /* 0xca */ { "db 0xca", 0 },
262
    /* 0xcb */ { "db 0xcb", 0 },
263
    /* 0xcc */ { "db 0xcc", 0 },
264
    /* 0xcd */ { "db 0xcd", 0 },
265
    /* 0xce */ { "db 0xce", 0 },
266
    /* 0xcf */ { "db 0xcf", 0 },
267
    /* 0xd0 */ { "inclcl", 1, { T3OP_TYPE_16U }},
268
    /* 0xd1 */ { "declcl", 1, { T3OP_TYPE_16U }},
269
    /* 0xd2 */ { "addilcl1", 2, { T3OP_TYPE_8U, T3OP_TYPE_8S }},
270
    /* 0xd3 */ { "addilcl4", 2, { T3OP_TYPE_16U, T3OP_TYPE_32S }},
271
    /* 0xd4 */ { "addtolcl", 1, { T3OP_TYPE_16U }},
272
    /* 0xd5 */ { "subfromlcl", 1, { T3OP_TYPE_16U }},
273
    /* 0xd6 */ { "zerolcl1", 1, { T3OP_TYPE_8U }},
274
    /* 0xd7 */ { "zerolcl2", 1, { T3OP_TYPE_16U }},
275
    /* 0xd8 */ { "nillcl1", 1, { T3OP_TYPE_8U }},
276
    /* 0xd9 */ { "nillcl2", 1, { T3OP_TYPE_16U }},
277
    /* 0xda */ { "onelcl1", 1, { T3OP_TYPE_8U }},
278
    /* 0xdb */ { "onelcl2", 1, { T3OP_TYPE_16U }},
279
    /* 0xdc */ { "db 0xdc", 0 },
280
    /* 0xdd */ { "db 0xdd", 0 },
281
    /* 0xde */ { "db 0xde", 0 },
282
    /* 0xdf */ { "db 0xdf", 0 },
283
    /* 0xe0 */ { "setlcl1", 1, { T3OP_TYPE_8U }},
284
    /* 0xe1 */ { "setlcl2", 1, { T3OP_TYPE_16U }},
285
    /* 0xe2 */ { "setarg1", 1, { T3OP_TYPE_8U }},
286
    /* 0xe3 */ { "setarg2", 1, { T3OP_TYPE_16U }},
287
    /* 0xe4 */ { "setind", 0 },
288
    /* 0xe5 */ { "setprop", 1, { T3OP_TYPE_PROP }},
289
    /* 0xe6 */ { "ptrsetprop", 0 },
290
    /* 0xe7 */ { "setpropself", 1, { T3OP_TYPE_PROP }},
291
    /* 0xe8 */ { "objsetprop", 2, { T3OP_TYPE_OBJ, T3OP_TYPE_PROP }},
292
    /* 0xe9 */ { "setdblcl", 2, { T3OP_TYPE_16U, T3OP_TYPE_16U }},
293
    /* 0xea */ { "setdbarg", 2, { T3OP_TYPE_16U, T3OP_TYPE_16U }},
294
    /* 0xeb */ { "setself", 0 },
295
    /* 0xec */ { "loadctx", 0 },
296
    /* 0xed */ { "storectx", 0 },
297
    /* 0xee */ { "setlcl1r0", 1, { T3OP_TYPE_8U }},
298
    /* 0xef */ { "setindlcl1i8", 2, { T3OP_TYPE_8U, T3OP_TYPE_8U }},
299
    /* 0xf0 */ { "db 0xf0", 0 },
300
    /* 0xf1 */ { "bp", 0 },
301
    /* 0xf2 */ { "nop", 0 },
302
    /* 0xf3 */ { "db 0xf3", 0 },
303
    /* 0xf4 */ { "db 0xf4", 0 },
304
    /* 0xf5 */ { "db 0xf5", 0 },
305
    /* 0xf6 */ { "db 0xf6", 0 },
306
    /* 0xf7 */ { "db 0xf7", 0 },
307
    /* 0xf8 */ { "db 0xf8", 0 },
308
    /* 0xf9 */ { "db 0xf9", 0 },
309
    /* 0xfa */ { "db 0xfa", 0 },
310
    /* 0xfb */ { "db 0xfb", 0 },
311
    /* 0xfc */ { "db 0xfc", 0 },
312
    /* 0xfd */ { "db 0xfd", 0 },
313
    /* 0xfe */ { "db 0xfe", 0 },
314
    /* 0xff */ { "db 0xff", 0 }
315
};
316
317
/* ------------------------------------------------------------------------ */
318
/*
319
 *   disassemble an instruction
320
 */
321
void CTcT3Unasm::disasm_instr(CTcUnasSrc *src, CTcUnasOut *out, char ch_op)
322
{
323
    t3_instr_info_t *info;
324
    int i;
325
    ulong acc;
326
    char ch[10];
327
    ulong prv_ofs = src->get_ofs();
328
    
329
    /* get the information on this instruction */
330
    info = &instr_info[(int)(uchar)ch_op];
331
    out->print("%8lx  %-14.14s ", src->get_ofs() - 1, info->nm);
332
333
    /* check the instruction type */
334
    switch((uchar)ch_op)
335
    {
336
    case OPC_SWITCH:
337
        /* 
338
         *   It's a switch instruction - special handling is required,
339
         *   since this instruction doesn't fit any of the normal
340
         *   patterns.  First, get the number of elements in the case
341
         *   table - this is a UINT2 value at the start of the table.  
342
         */
343
        src->next_byte(ch);
344
        src->next_byte(ch+1);
345
        acc = osrp2(ch);
346
347
        /* display the count */
348
        out->print("0x%x\n", (uint)acc);
349
350
        /* display the table */
351
        for (i = 0 ; i < (int)acc ; ++i)
352
        {
353
            const char *dt;
354
            char valbuf[128];
355
            const char *val = valbuf;
356
357
            /* note the current offset */
358
            prv_ofs = src->get_ofs();
359
            
360
            /* read the DATAHOLDER value */
361
            src->next_byte(ch);
362
            src->next_byte(ch+1);
363
            src->next_byte(ch+2);
364
            src->next_byte(ch+3);
365
            src->next_byte(ch+4);
366
367
            /* read the jump offset */
368
            src->next_byte(ch+5);
369
            src->next_byte(ch+6);
370
371
            /* 
372
             *   stop looping if the offset hasn't changed - this probably
373
             *   means we're stuck trying to interpret as a "switch" some
374
             *   data at the end of the stream that happens to look like a
375
             *   switch but really isn't (such as an exception table, or
376
             *   debug records) 
377
             */
378
            if (src->get_ofs() == prv_ofs)
379
                break;
380
381
            /* show the value */
382
            switch(ch[0])
383
            {
384
            case VM_NIL:
385
                dt = "nil";
386
                val = "";
387
                break;
388
                
389
            case VM_TRUE:
390
                dt = "true";
391
                val = "";
392
                break;
393
                
394
            case VM_OBJ:
395
                dt = "object";
396
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
397
                break;
398
                
399
            case VM_PROP:
400
                dt = "prop";
401
                sprintf(valbuf, "0x%04x", osrp2(ch+1));
402
                break;
403
                
404
            case VM_INT:
405
                dt = "int";
406
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
407
                break;
408
409
            case VM_ENUM:
410
                dt = "enum";
411
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
412
                break;
413
                
414
            case VM_SSTRING:
415
                dt = "sstring";
416
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
417
                break;
418
                
419
            case VM_LIST:
420
                dt = "list";
421
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
422
                break;
423
                
424
            case VM_FUNCPTR:
425
                dt = "funcptr";
426
                sprintf(valbuf, "0x%08lx", t3rp4u(ch+1));
427
                break;
428
429
            default:
430
                dt = "???";
431
                val = "???";
432
                break;
433
            }
434
435
            /* show the slot data */
436
            out->print("          0x%08lx      %-8.8s(%-10.10s) "
437
                       "-> +0x%04lx (0x%08lx)\n",
438
                       src->get_ofs() - 7, dt, val, osrp2(ch+5),
439
                       src->get_ofs() - 2 + osrp2s(ch+5));
440
        }
441
442
        /* read and show the 'default' jump offset */
443
        src->next_byte(ch);
444
        src->next_byte(ch+1);
445
        out->print("          0x%08lx      default              "
446
                   "-> +0x%04lx (0x%08lx)\n",
447
                   src->get_ofs() - 2, osrp2(ch),
448
                   src->get_ofs() - 2 + osrp2s(ch));
449
450
        /* done */
451
        break;
452
453
    default:
454
        /* show all parameters */
455
        for (i = 0 ; i < info->op_cnt ; ++i)
456
        {
457
            /* add a separator if this isn't the first one */
458
            if (i != 0)
459
                out->print(", ");
460
            
461
            /* display the operand */
462
            switch(info->op_type[i])
463
            {
464
            case T3OP_TYPE_8S:
465
                /* 8-bit signed integer */
466
                src->next_byte(ch);
467
                out->print("0x%x", (int)ch[0]);
468
                break;
469
470
            case T3OP_TYPE_8U:
471
                /* 8-bit unsigned integer */
472
                src->next_byte(ch);
473
                out->print("0x%x", (uint)(uchar)ch[0]);
474
                break;
475
476
            case T3OP_TYPE_16S:
477
                /* 16-bit signed integer */
478
                src->next_byte(ch);
479
                src->next_byte(ch+1);
480
                acc = osrp2s(ch);
481
                out->print("0x%x", (int)acc);
482
                break;
483
484
            case T3OP_TYPE_16U:
485
                /* 16-bit unsigned integer */
486
                src->next_byte(ch);
487
                src->next_byte(ch+1);
488
                acc = osrp2(ch);
489
                out->print("0x%x", (uint)acc);
490
                break;
491
492
            case T3OP_TYPE_32S:
493
                /* 32-bit signed integer */
494
                src->next_byte(ch);
495
                src->next_byte(ch+1);
496
                src->next_byte(ch+2);
497
                src->next_byte(ch+3);
498
                acc = t3rp4u(ch);
499
                out->print("0x%lx", acc);
500
                break;
501
502
            case T3OP_TYPE_32U:
503
                /* 32-bit unsigned integer */
504
                src->next_byte(ch);
505
                src->next_byte(ch+1);
506
                src->next_byte(ch+2);
507
                src->next_byte(ch+3);
508
                acc = t3rp4u(ch);
509
                out->print("0x%lx", acc);
510
                break;
511
512
            case T3OP_TYPE_STR:
513
                /* string offset */
514
                src->next_byte(ch);
515
                src->next_byte(ch+1);
516
                src->next_byte(ch+2);
517
                src->next_byte(ch+3);
518
                acc = t3rp4u(ch);
519
                out->print("string(0x%lx)", acc);
520
                break;
521
522
            case T3OP_TYPE_LIST:
523
                /* list offset */
524
                src->next_byte(ch);
525
                src->next_byte(ch+1);
526
                src->next_byte(ch+2);
527
                src->next_byte(ch+3);
528
                acc = t3rp4u(ch);
529
                out->print("list(0x%lx)", acc);
530
                break;
531
532
            case T3OP_TYPE_CODE_ABS:
533
                /* 32-bit absolute code address */
534
                src->next_byte(ch);
535
                src->next_byte(ch+1);
536
                src->next_byte(ch+2);
537
                src->next_byte(ch+3);
538
                acc = t3rp4u(ch);
539
                out->print("code(0x%08lx)", acc);
540
                break;
541
542
            case T3OP_TYPE_CODE_REL:
543
                /* 16-bit relative code address */
544
                src->next_byte(ch);
545
                src->next_byte(ch+1);
546
                acc = osrp2s(ch);
547
                if ((long)acc < 0)
548
                    out->print("-0x%04x (0x%08lx)",
549
                               -(int)acc, src->get_ofs() - 2 + acc);
550
                else
551
                    out->print("+0x%04x (0x%08lx)",
552
                               acc, src->get_ofs() - 2 + acc);
553
                break;
554
555
            case T3OP_TYPE_OBJ:
556
                /* object ID */
557
                src->next_byte(ch);
558
                src->next_byte(ch+1);
559
                src->next_byte(ch+2);
560
                src->next_byte(ch+3);
561
                acc = t3rp4u(ch);
562
                out->print("object(0x%lx)", acc);
563
                break;
564
565
            case T3OP_TYPE_PROP:
566
                /* property ID */
567
                src->next_byte(ch);
568
                src->next_byte(ch+1);
569
                acc = osrp2(ch);
570
                out->print("property(0x%x)", (uint)acc);
571
                break;
572
573
            case T3OP_TYPE_ENUM:
574
                /* enum */
575
                src->next_byte(ch);
576
                src->next_byte(ch+1);
577
                src->next_byte(ch+2);
578
                src->next_byte(ch+3);
579
                acc = t3rp4u(ch);
580
                out->print("enum(0x%lx)", acc);
581
                break;
582
583
            case T3OP_TYPE_CTX_ELE:
584
                /* context element identifier */
585
                src->next_byte(ch);
586
                switch(ch[0])
587
                {
588
                case PUSHCTXELE_TARGPROP:
589
                    out->print("targetprop");
590
                    break;
591
592
                case PUSHCTXELE_TARGOBJ:
593
                    out->print("targetobj");
594
                    break;
595
596
                case PUSHCTXELE_DEFOBJ:
597
                    out->print("definingobj");
598
                    break;
599
600
                default:
601
                    out->print("0x%x", (int)ch[0]);
602
                    break;
603
                }
604
                break;
605
606
            case T3OP_TYPE_INLINE_STR:
607
                /* get the string length */
608
                src->next_byte(ch);
609
                src->next_byte(ch+1);
610
611
                /* show it */
612
                out->print("string(inline)");
613
614
                /* skip the string */
615
                for (acc = osrp2(ch) ; acc != 0 ; --acc)
616
                    src->next_byte(ch);
617
618
                /* done */
619
                break;
620
621
            default:
622
                out->print("...unknown type...");
623
                break;
624
            }
625
        }
626
627
        /* end the line */
628
        out->print("\n");
629
    }
630
}
631
632
/* ------------------------------------------------------------------------ */
633
/*
634
 *   Show an exception table 
635
 */
636
void CTcT3Unasm::show_exc_table(class CTcUnasSrc *src, class CTcUnasOut *out,
637
                                unsigned long base_ofs)
638
{
639
    unsigned entries;
640
    char ch[10];
641
    
642
    /* read the number of entries */
643
    src->next_byte(ch);
644
    src->next_byte(ch+1);
645
646
    /* show the entries */
647
    for (entries = osrp2(ch) ; entries != 0 ; --entries)
648
    {
649
        unsigned long start_ofs;
650
        unsigned long end_ofs;
651
        unsigned exc_obj_id;
652
        unsigned long catch_ofs;
653
        
654
        /* read the code start offset */
655
        src->next_byte(ch);
656
        src->next_byte(ch+1);
657
        start_ofs = base_ofs + osrp2(ch);
658
659
        /* read the code end offset */
660
        src->next_byte(ch);
661
        src->next_byte(ch+1);
662
        end_ofs = base_ofs + osrp2(ch);
663
664
        /* read the object ID */
665
        src->next_byte(ch);
666
        src->next_byte(ch+1);
667
        src->next_byte(ch+2);
668
        src->next_byte(ch+3);
669
        exc_obj_id = base_ofs + t3rp4u(ch);
670
671
        /* read the catch offset */
672
        src->next_byte(ch);
673
        src->next_byte(ch+1);
674
        catch_ofs = base_ofs + osrp2(ch);
675
676
        /* show it */
677
        out->print("    from %lx to %lx object %x catch %lx\n",
678
                   start_ofs, end_ofs, exc_obj_id, catch_ofs);
679
    }
680
}
681