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__
函数.然后将结果压入堆栈。
我读到一些 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__
函数.然后将结果压入堆栈。