我有这个Python函数和它翻译成的字节码:
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
我无法理解带有标签 44 的指令代表什么。我知道在指令 42 (
iter(range(5))
) 之后我的堆栈顶部有一个范围迭代器,但我不知道为什么会调用迭代器。
我正在尝试实现一个Python虚拟机,并且正在努力正确实现
CALL
操作码。我在提供的规范中没有看到任何帮助。
既然迭代器甚至不可调用,那么在迭代器上执行
CALL 0
背后的逻辑是什么?
这是一个电话:是位置参数和命名参数的总和,不包括argc
(当self
不存在时)。NULL
28 PUSH_NULL
30 LOAD_NAME 1 (range)
32 LOAD_CONST 2 (5)
34 CALL 1
这是另一个:
24 LOAD_CONST 1 (<code object <genexpr> at 0x1026abe30, file "<dis>", line 2>)
26 MAKE_FUNCTION 0
⋮
42 GET_ITER
44 CALL 0
也就是说,您正在调用带有迭代器的生成器表达式 self
。请注意,该指令在 Python 3.13 中又有所不同。