| | 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 | |