为什么 Python 的 CONTINUE_LOOP 允许外循环,而 BREAK_LOOP 不允许?
Why does Python's CONTINUE_LOOP allow an outer loop, when BREAK_LOOP doesn't?
我注意到 Python 的字节码 here.
中有一个有趣的特性
CONTINUE_LOOP
操作码接受一个target
参数,表示循环继续执行的指令,这是一条FOR_ITER
指令。
然而,BREAK_LOOP
操作码不会这样做。它只会跳出当前(最内层)循环。
这背后的原因是什么?为什么可以 continue
而不是 break
外循环?
你误解了目标。不需要该值来处理嵌套循环。相反,目标标记字节码流中的点以在指令之后移动到。 BREAK
不需要这样的目标,因为该值已在别处定义。
BREAK_LOOP
结束一个循环,因此在 循环之后 继续执行。 SETUP_LOOP
instruction 已经定义了端点,所以解释器不需要任何额外的信息来执行这个操作码。
CONTINUE_LOOP
另一方面需要被告知继续到哪里。在大多数循环中,使用 JUMP_ABSOLUTE
opcode,而 CONTINUE_LOOP
在这里回应该指令。 CONTINUE_LOOP
记录了更多信息来处理 try
语句(跟踪堆栈展开)。
在评估循环中,异常处理(try: ... except:
和 try
: ... finally:
)以及上下文管理器(with ...:
和 async with ...:
)使用 frame block,其中记录了一个出口点,这就是BREAK_LOOP
指令在这里所依赖的。不必跟踪偏移量这种方式更简单,并且避免了编译器和评估循环必须自己重复(退出点也用于其他场景,而不仅仅是 break
语句)。
但是跳转更通用,因此它们的偏移量更容易跟踪与指令本身相关的内容。
我注意到 Python 的字节码 here.
中有一个有趣的特性CONTINUE_LOOP
操作码接受一个target
参数,表示循环继续执行的指令,这是一条FOR_ITER
指令。
BREAK_LOOP
操作码不会这样做。它只会跳出当前(最内层)循环。
这背后的原因是什么?为什么可以 continue
而不是 break
外循环?
你误解了目标。不需要该值来处理嵌套循环。相反,目标标记字节码流中的点以在指令之后移动到。 BREAK
不需要这样的目标,因为该值已在别处定义。
BREAK_LOOP
结束一个循环,因此在 循环之后 继续执行。 SETUP_LOOP
instruction 已经定义了端点,所以解释器不需要任何额外的信息来执行这个操作码。
CONTINUE_LOOP
另一方面需要被告知继续到哪里。在大多数循环中,使用 JUMP_ABSOLUTE
opcode,而 CONTINUE_LOOP
在这里回应该指令。 CONTINUE_LOOP
记录了更多信息来处理 try
语句(跟踪堆栈展开)。
在评估循环中,异常处理(try: ... except:
和 try
: ... finally:
)以及上下文管理器(with ...:
和 async with ...:
)使用 frame block,其中记录了一个出口点,这就是BREAK_LOOP
指令在这里所依赖的。不必跟踪偏移量这种方式更简单,并且避免了编译器和评估循环必须自己重复(退出点也用于其他场景,而不仅仅是 break
语句)。
但是跳转更通用,因此它们的偏移量更容易跟踪与指令本身相关的内容。