我试图通过在简单的Python程序中通过ceval.c中的解释器循环来跟踪不同的字节码/操作码,来加深对CPython解释器的理解。我正在使用bytecodeopcode表示同一件事。

我的python程序是这样的:

#filename: test.py

x = 2
y = 3

if x < y:
    z = x
elif True:
    z = y
else:
    z = 100


我正在使用Python 2.7.8,并使用如下调试标志来构建它:

wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz   # download
tar xvf Python-2.7.8.tgz                                        # extract
cd Python2.7.8
./configure --with-pydebug                                      # build with debug flag
make -j                                                         # parallel make


我对从解释器循环for(;;)中的不同switchopcode语句遍历ceval.c循环感兴趣,从964行开始。

我在该for循环开始后立即添加了这些行,以检查解释程序是否正在运行我的文件,如果是,则打印出opcode

964     for (;;) {
965         if (strcmp(filename, "../test.py") == 0) {
966             printf("%d\n", opcode);
967         }


我得到的输出是(手动添加的注释以显示opcodeDEFINE opcode.h):

 $ ./python.exe ../test.py | cat -n
 1  0    //  STOP_CODE
 2  90   //  HAVE_ARGUMENT
 3  90   //  HAVE_ARGUMENT
 4  101  //  LOAD_NAME
 5  101  //  LOAD_NAME
 6  101  //  LOAD_NAME
 7  90   //  STORE_NAME


我希望使用12种不同的操作码,而不是7种,因为当我分解同一文件的字节码时,有12个字节码命令。

$ ./python.exe -m dis ../pytests/test.py | sed "/^$/d" | cat -n
1    1           0 LOAD_CONST               0 (2)
2                3 STORE_NAME               0 (x)
3    2           6 LOAD_CONST               1 (3)
4                9 STORE_NAME               1 (y)
5    4          12 LOAD_NAME                0 (x)
6               15 LOAD_NAME                1 (y)
7               18 COMPARE_OP               0 (<)
8               21 POP_JUMP_IF_FALSE       33
9    5          24 LOAD_NAME                0 (x)
10              27 STORE_NAME               2 (z)
11              30 JUMP_FORWARD            21 (to 54)
12   6     >>   33 LOAD_NAME


我关于CPython交互程序如何工作的思维模型和/或我记录不同操作码的方法是错误的,或者两者都是错误的。您能解释为什么我在ceval.c文件的输出和使用python -m dis包时看到不同的操作码吗?

最佳答案

跟踪显示有问题,因为在正常情况下,您不会执行任何STOP_CODE(值0),而这会中断执行。另外,HAVE_ARGUMENT不是操作码。对于Python 2.7,操作码为STORE_NAME

至于值的差异,这在任何不是直线(基本块)代码的代码中都是可以预期的。而且您不是直线代码。在COMPARE <后面跟随POP_JUMP_IF_FALSE跳转。

09-25 17:43