I have this python function and the bytecode it translates to:
Text code:
x = "-".join(str(z) for z in range(5))
assert x == "0-1-2-3-4"
print("Assert test case for generator_expression_in_join")
Disassembled code:
0 0 RESUME 0
2 2 LOAD_CONST 0 ('-')
4 LOAD_ATTR 1 (NULL|self + join)
24 LOAD_CONST 1 (<code object <genexpr> at 0x1026abe30, file "<dis>", line 2>)
26 MAKE_FUNCTION 0
28 PUSH_NULL
30 LOAD_NAME 1 (range)
32 LOAD_CONST 2 (5)
34 CALL 1
42 GET_ITER
44 CALL 0
52 CALL 1
60 STORE_NAME 2 (x)
3 62 LOAD_NAME 2 (x)
64 LOAD_CONST 3 ('0-1-2-3-4')
66 COMPARE_OP 40 (==)
70 POP_JUMP_IF_TRUE 2 (to 76)
72 LOAD_ASSERTION_ERROR
74 RAISE_VARARGS 1
4 >> 76 PUSH_NULL
78 LOAD_NAME 3 (print)
80 LOAD_CONST 4 ('Assert test case for generator_expression_in_join')
82 CALL 1
90 POP_TOP
92 RETURN_CONST 5 (None)
Disassembly of <code object <genexpr> at 0x1026abe30, file "<dis>", line 2>:
2 0 RETURN_GENERATOR
2 POP_TOP
4 RESUME 0
6 LOAD_FAST 0 (.0)
>> 8 FOR_ITER 15 (to 42)
12 STORE_FAST 1 (z)
14 LOAD_GLOBAL 1 (NULL + str)
24 LOAD_FAST 1 (z)
26 CALL 1
34 YIELD_VALUE 1
36 RESUME 1
38 POP_TOP
40 JUMP_BACKWARD 17 (to 8)
>> 42 END_FOR
44 RETURN_CONST 0 (None)
>> 46 CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR)
48 RERAISE 1
I have trouble understanding what the instruction with label 44 stands for. I understand that I have a range iterator on the top of my stack after instruction 42 (iter(range(5))
), but I don't know why one would call an iterator.
I'm trying to implement a python virtual machine, and am struggling to implement the CALL
opcode correctly. I don't see any help in the provided spec.
What is the logic behind doing CALL 0
on an iterator since an iterator isn't even callable?
argc
is the total of the positional and named arguments, excludingself
when aNULL
is not present.
Here’s one call:
28 PUSH_NULL
30 LOAD_NAME 1 (range)
32 LOAD_CONST 2 (5)
34 CALL 1
And here’s another:
24 LOAD_CONST 1 (<code object <genexpr> at 0x1026abe30, file "<dis>", line 2>)
26 MAKE_FUNCTION 0
⋮
42 GET_ITER
44 CALL 0
That is, you’re calling the generator expression with the iterator as self
.
Note that this instruction is different again in Python 3.13.