Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0d05d96

Browse files
committed
Python: CG trace: Handle CALL_FUNCTION_EX
1 parent 3539798 commit 0d05d96

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def func(*args, **kwargs):
2+
print("func", args, kwargs)
3+
4+
5+
args = [1, 2, 3]
6+
kwargs = {"a": 1, "b": 2}
7+
8+
# These gives rise to a CALL_FUNCTION_EX
9+
func(*args)
10+
func(**kwargs)
11+
func(*args, **kwargs)
12+
13+
14+
func(*args, foo="foo")
15+
func(*args, foo="foo", **kwargs)

python/tools/recorded-call-graph-metrics/src/cg_trace/bytecode_reconstructor.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,23 @@ def expr_from_instruction(instructions: List[Instruction], index: int) -> Byteco
162162
return BytecodeSubscript(key=key_expr, object=obj_expr)
163163

164164
# https://docs.python.org/3/library/dis.html#opcode-CALL_FUNCTION
165-
elif inst.opname in ["CALL_FUNCTION", "CALL_METHOD", "CALL_FUNCTION_KW"]:
165+
elif inst.opname in [
166+
"CALL_FUNCTION",
167+
"CALL_METHOD",
168+
"CALL_FUNCTION_KW",
169+
"CALL_FUNCTION_EX",
170+
]:
166171
assert index > 0
167172
assert isinstance(inst.arg, int)
168173
if inst.opname in ["CALL_FUNCTION", "CALL_METHOD"]:
169174
num_stack_elems = inst.arg
170175
elif inst.opname == "CALL_FUNCTION_KW":
171176
num_stack_elems = inst.arg + 1
177+
elif inst.opname == "CALL_FUNCTION_EX":
178+
# top of stack _can_ be keyword argument dictionary (indicated by lowest bit
179+
# set), always followed by the positional arguments (also if there are not
180+
# any).
181+
num_stack_elems = (1 if inst.arg & 1 == 1 else 0) + 1
172182

173183
func_expr = expr_that_added_elem_to_stack(
174184
instructions, index - 1, num_stack_elems

0 commit comments

Comments
 (0)