def test_negative_float_str(self): value = Opcodes.make_addr_regoff(Opcodes.REGINDEX_TH, -42, Opcodes.ADDR_VALTYPE_FLOAT) self.assertEqual(Opcodes.make_addr_str(value).str, '[%TH-42]f')
def test_reg_addr_str(self): value = Opcodes.make_addr_reg(Opcodes.REGINDEX_TH) self.assertEqual(Opcodes.make_addr_str(value).str, '%TH')
def test_positive_int_str(self): value = Opcodes.make_addr_regoff(Opcodes.REGINDEX_TH, 42, Opcodes.ADDR_VALTYPE_INT) self.assertEqual(Opcodes.make_addr_str(value).str, '[%TH+42]i')
def disasm_one(bytecode, offset): label = '0x%04x' % offset opcode = bytecode[offset] prev_offset = offset offset += 1 maintype = Opcodes.opcode_type(opcode) subtype = Opcodes.opcode_subtype(opcode) variant = Opcodes.opcode_variant(opcode) if maintype == Opcodes.OPCODE_TYPE_BINARY: dst = Opcodes.make_addr_str(bytecode[offset:]) offset += dst.size if variant == Opcodes.OPCODE_VARIANT_C: src, = struct.unpack('<%s' % dst.type, bytecode[offset:offset + 4]) offset += 4 elif variant == Opcodes.OPCODE_VARIANT_A: src = Opcodes.make_addr_str(bytecode[offset:]) offset += src.size else: raise NotImplementedError name = { Opcodes.OPCODE_SUBTYPE_BINARY_ADD: 'ADD', Opcodes.OPCODE_SUBTYPE_BINARY_SUB: 'SUB', Opcodes.OPCODE_SUBTYPE_BINARY_MUL: 'MUL', Opcodes.OPCODE_SUBTYPE_BINARY_DIV: 'DIV', Opcodes.OPCODE_SUBTYPE_BINARY_CLT: 'CLT', Opcodes.OPCODE_SUBTYPE_BINARY_CGT: 'CGT', Opcodes.OPCODE_SUBTYPE_BINARY_CLTE: 'CLTE', Opcodes.OPCODE_SUBTYPE_BINARY_CGTE: 'CGTE', Opcodes.OPCODE_SUBTYPE_BINARY_CE: 'CE', Opcodes.OPCODE_SUBTYPE_BINARY_CN: 'CN', Opcodes.OPCODE_SUBTYPE_BINARY_AND: 'AND', Opcodes.OPCODE_SUBTYPE_BINARY_OR: 'OR', Opcodes.OPCODE_SUBTYPE_BINARY_LOAD: 'LOAD', Opcodes.OPCODE_SUBTYPE_BINARY_CAST: 'CAST', }[subtype] instr = '%- 10s %s, %s' % (name, dst, src) elif maintype == Opcodes.OPCODE_TYPE_UNARY: dst = Opcodes.make_addr_str(bytecode[offset:]) offset += dst.size name = { Opcodes.OPCODE_SUBTYPE_UNARY_NOT: 'NOT', Opcodes.OPCODE_SUBTYPE_UNARY_NEG: 'NEG', }[subtype] instr = '%- 10s %s' % (name, dst) elif maintype == Opcodes.OPCODE_TYPE_STACK: if subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSHI: val, = struct.unpack('<i', bytecode[offset:offset + 4]) offset += 4 instr = '%- 10s %s' % ('PUSH', val) elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSHF: val, = struct.unpack('<f', bytecode[offset:offset + 4]) offset += 4 instr = '%- 10s %s' % ('PUSH', val) elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_PUSH: src = Opcodes.make_addr_str(bytecode[offset:]) offset += src.size instr = '%- 10s %s' % ('PUSH', src) elif subtype == Opcodes.OPCODE_SUBTYPE_STACK_POP: src = Opcodes.make_addr_str(bytecode[offset:]) offset += src.size instr = '%- 10s %s' % ('POP', src) elif maintype == Opcodes.OPCODE_TYPE_FLOW: if subtype == Opcodes.OPCODE_SUBTYPE_FLOW_JZ: if variant == Opcodes.OPCODE_VARIANT_A: cond = Opcodes.make_addr_str(bytecode[offset:]) offset += cond.size elif variant == Opcode.OPCODE_VARIANT_CI: cond = struct.unpack('<i', bytecode[offset:offset + 2]) offset += 2 elif variant == Opcode.OPCODE_VARIANT_CF: cond = struct.unpack('<f', bytecode[offset:offset + 4]) offset += 4 else: raise NotImplementedError jumpto, = struct.unpack('<H', bytecode[offset:offset + 2]) offset += 2 instr = '%- 10s %s, 0x%04x' % ('JZ', cond, jumpto) elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_JUMP: jumpto, = struct.unpack('<H', bytecode[offset:offset + 2]) offset += 2 instr = '%- 10s 0x%04x' % ('JUMP', jumpto) elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_YIELD: instr = '%- 10s' % 'YIELD' elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_RET: instr = '%- 10s' % 'RET' elif subtype == Opcodes.OPCODE_SUBTYPE_FLOW_CALL: jumpto, = struct.unpack('<H', bytecode[offset:offset + 2]) offset += 2 instr = '%- 10s 0x%04x' % ('CALL', jumpto) else: raise NotImplementedError else: raise NotImplementedError print('%s %- 40s %s' % (label, instr, ' '.join( ['%02X' % val for val in bytecode[prev_offset:offset]]))) return offset