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