Python: CG trace: Avoid handling jumps for now

This commit is contained in:
Rasmus Wriedt Larsen
2020-07-21 19:58:59 +02:00
parent 4e3ae98ddf
commit 0a7e6a9938
2 changed files with 42 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
class Foo:
def __init__(self):
self.list = []
def func(self, kwargs=None, result_callback=None):
self.list.append((kwargs or {}, result_callback))
foo = Foo()
foo.func()
"""
Has problematic bytecode, since to find out what method is called from instruction 16, we need
to traverse the JUMP_IF_TRUE_OR_POP which requires some more sophistication.
Disassembly of <code object func at 0x7f98f64ee030, file "example/problem-1.py", line 5>:
6 0 LOAD_FAST 0 (self)
2 LOAD_ATTR 0 (list)
4 LOAD_METHOD 1 (append)
6 LOAD_FAST 1 (kwargs)
8 JUMP_IF_TRUE_OR_POP 12
10 BUILD_MAP 0
>> 12 LOAD_FAST 2 (result_callback)
14 BUILD_TUPLE 2
16 CALL_METHOD 1
"""

View File

@@ -71,6 +71,14 @@ class BytecodeMakeFunction(BytecodeExpr):
return f"<MAKE_FUNCTION>(qualified_name={self.qualified_name})>"
@dataclasses.dataclass(frozen=True, eq=True, order=True)
class SomethingInvolvingScaryBytecodeJump(BytecodeExpr):
opname: str
def __str__(self):
return "<SomethingInvolvingScaryBytecodeJump>"
def expr_that_added_elem_to_stack(
instructions: List[Instruction], start_index: int, stack_pos: int
):
@@ -95,10 +103,18 @@ def expr_that_added_elem_to_stack(
It is assumed that if `stack_pos == 0` then the instruction you are looking for is
the one at `instructions[start_index]`. This might not hold, in case of using `NOP`
instructions.
If any jump instruction is found, `SomethingInvolvingScaryBytecodeJump` is returned
immediately. (since correctly process the bytecode when faced with jumps is not as
straight forward).
"""
LOGGER.debug(f"find_inst_that_added_elem_to_stack {start_index=} {stack_pos=}")
assert stack_pos >= 0
for inst in reversed(instructions[: start_index + 1]):
# Return immediately if faced with a jump
if inst.opcode in dis.hasjabs or inst.opcode in dis.hasjrel:
return SomethingInvolvingScaryBytecodeJump(inst.opname)
if stack_pos == 0:
LOGGER.debug(f"Found it: {inst}")
found_index = instructions.index(inst)