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

Does the Cpython VM execute a C code for every opcode?

我读到一些 VM 将字节码转换为机器码。但是我听说 Cpython VM 略有不同。我正在阅读 here python VM "executes a short piece of C code matching the opcode" 这是否意味着当 Cpython 解释器是 'executing' a python 字节码,最终(经过很多事情)它调用不同的 C 程序,这些程序又由处理器执行?理解有误请指正

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

CPython 不将操作码转换为机器码只是意味着它缺少 compiler to native code, such as a Just-In-Time compiler (JIT) 或提前编译器。

编译器将一堆操作码翻译成机器码,然后您可以直接在 CPU 上执行这些机器码。 CPython 改为一次读取一个操作码并对其作出反应。

CPython 解释器 一个程序(用 C 编写,编译为机器码),它正在执行 Python 字节码。解释器本质上是一个非常大的 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__ 函数.然后将结果压入堆栈。