Cpython VM是否为每个操作码执行C代码?

时间:2015-12-08 10:22:07

标签: python python-internals

我已经读过一些VM将字节码转换为机器码。但我听说Cpython VM略有不同。我正在阅读here python VM “执行与操作码相匹配的一小段C代码”这是否意味着当Cpython解释器'执行'python字节代码时,最终(在很多东西之后)它调用不同的C程序,然后由处理器执行?如果我的理解是错误的,请纠正我。

2 个答案:

答案 0 :(得分:4)

CPython解释器一个正在执行Python字节代码的程序(用C编写,编译成机器代码)。解释器本质上是一个非常大的switch语句,它为每个不同的操作码执行不同的操作。你可以看到它是如何工作的in the source

例如,针对BINARY_ADD操作码(例如a + b)运行的代码如下:

TARGET(BINARY_ADD) {
    PyObject *right = POP();
    PyObject *left = TOP();
    PyObject *sum;
    if (PyUnicode_CheckExact(left) &&
             PyUnicode_CheckExact(right)) {
        sum = unicode_concatenate(left, right, f, next_instr);
        /* unicode_concatenate consumed the ref to v */
    }
    else {
        sum = PyNumber_Add(left, right);
        Py_DECREF(left);
    }
    Py_DECREF(right);
    SET_TOP(sum);
    if (sum == NULL)
        goto error;
    DISPATCH();
}

请注意,这使用了许多预处理器函数来使其更易于读写。在这个例子中,它基本上从堆栈中弹出两个对象,检查它们是否是字符串,否则调用CAPI函数PyNumber_Add,然后调用对象的基础__add____radd__函数。然后将结果推送到堆栈。

答案 1 :(得分:3)

不,它不会调用不同的程序。 CPython interpreter是一个C程序。对于每个操作码,它都会调用自己的一个函数。这些函数本身已经编译为机器代码,因为解释器是一个已编译的程序。

CPython没有将操作码转换为机器代码只是意味着它缺少compiler到本机代码,例如Just-In-Time compiler(JIT)或提前编译器。

编译器将一堆操作码转换为机器码,然后可以直接在CPU上执行。 CPython反而一次读取一个操作码并对其做出反应。