super(class_, self).__init__(arg) return __init__ def _call_repr(self): positional, keyword = self.arg.to_bytes(2, 'little') return '%s(positional=%d, keyword=%d)' % ( type(self).__name__, positional, keyword, ) globals_ = globals() for name, opcode in opmap.items(): globals_[name] = class_ = InstructionMeta( opname[opcode], (Instruction, ), {}, opcode=opcode, ) if name.startswith('CALL_FUNCTION'): class_.__init__ = _mk_call_init(class_) class_.__repr__ = _call_repr del class_ # Clean up the namespace del name del globals_ del _call_repr
def from_opcode(cls, opcode, arg): return type(cls)(opname[opcode], (cls,), {}, opcode=opcode)(arg) @property def stack_effect(self): return stack_effect( self.opcode, *((self.arg,) if self.have_arg else ()) ) @classmethod def from_argcounts(cls, positional=0, keyword=0): return cls( int.from_bytes( positional.to_bytes(1, 'little') + keyword.to_bytes(1, 'little'), 'little', ), ) globals_ = globals() for name, opcode in opmap.items(): ns = {} if name.startswith('CALL_FUNCTION'): ns['from_argcounts'] = from_argcounts globals_[name] = InstructionMeta( opname[opcode], (Instruction,), ns, opcode=opcode, ) del name del globals_
@mark.parametrize("code", get_examples()) @settings(suppress_health_check=[HealthCheck.too_slow]) @given(items=lists(builds(object), max_size=maxsize // 2)) def test_readme(code: str, items: Sequence[object]) -> None: namespace: Dict[str, Any] = {"__name__": "__main__"} exec(code, namespace) # pylint: disable = exec-used actual = namespace["doubled"](items) expected = [*chain.from_iterable(zip(items, items))] assert actual == expected @mark.parametrize("opname, opcode", opmap.items()) def test_opcode(opname: str, opcode: int) -> None: arg = HAVE_ARGUMENT <= opcode assert hasattr(hax, opname) with raises(HaxUsageError if arg else TypeError): getattr(hax, opname)(...) with raises(TypeError if arg else HaxUsageError): getattr(hax, opname)() def test_label() -> None:
from struct import unpack from dis import opmap reverse_opmap = {v: k for k, v in opmap.items()} def foo(): pass foo_code = foo.__code__.co_code for pos in range(0, len(foo_code), 2): inst = unpack("BB", foo_code[pos:pos + 2]) print(f"{reverse_opmap[inst[0]]}: {inst[1]}")
# LICENSE file in the root directory of this source tree. '''Really just dis with functionality that I (correctly or incorrectly) felt was missing like an OpCode enum and other sets of opcodes ''' # We do the gross * import because we use _dis_plus as an extension to dis. from dis import * # noqa: F403,F401 from dis import opmap, hasjrel, hasjabs, opname class OpCode: pass for name, v in opmap.items(): setattr(OpCode, name, v) hasjmp = hasjrel + hasjabs hascondjmp = set([ OpCode.POP_JUMP_IF_TRUE, OpCode.POP_JUMP_IF_FALSE, OpCode.JUMP_IF_TRUE_OR_POP, OpCode.JUMP_IF_FALSE_OR_POP, ]) def opcode_key_wrapper(f): def g(*args, **kwargs): try: return f(*args, **kwargs)