📄 ceval.c
字号:
break;
case STORE_ATTR:
w = GETNAMEV(oparg);
v = POP();
u = POP();
err = PyObject_SetAttr(v, w, u); /* v.w = u */
Py_DECREF(v);
Py_DECREF(u);
break;
case DELETE_ATTR:
w = GETNAMEV(oparg);
v = POP();
err = PyObject_SetAttr(v, w, (PyObject *)NULL);
/* del v.w */
Py_DECREF(v);
break;
case STORE_GLOBAL:
w = GETNAMEV(oparg);
v = POP();
err = PyDict_SetItem(f->f_globals, w, v);
Py_DECREF(v);
break;
case DELETE_GLOBAL:
w = GETNAMEV(oparg);
if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
format_exc_check_arg(
PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
break;
case LOAD_CONST:
x = GETCONST(oparg);
Py_INCREF(x);
PUSH(x);
break;
case LOAD_NAME:
w = GETNAMEV(oparg);
if ((x = f->f_locals) == NULL) {
PyErr_Format(PyExc_SystemError,
"no locals when loading %s",
PyObject_REPR(w));
break;
}
x = PyDict_GetItem(x, w);
if (x == NULL) {
x = PyDict_GetItem(f->f_globals, w);
if (x == NULL) {
x = PyDict_GetItem(f->f_builtins, w);
if (x == NULL) {
format_exc_check_arg(
PyExc_NameError,
NAME_ERROR_MSG ,w);
break;
}
}
}
Py_INCREF(x);
PUSH(x);
break;
case LOAD_GLOBAL:
w = GETNAMEV(oparg);
x = PyDict_GetItem(f->f_globals, w);
if (x == NULL) {
x = PyDict_GetItem(f->f_builtins, w);
if (x == NULL) {
format_exc_check_arg(
PyExc_NameError,
GLOBAL_NAME_ERROR_MSG ,w);
break;
}
}
Py_INCREF(x);
PUSH(x);
break;
case LOAD_FAST:
x = GETLOCAL(oparg);
if (x == NULL) {
format_exc_check_arg(
PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_varnames, oparg)
);
break;
}
Py_INCREF(x);
PUSH(x);
if (x != NULL) continue;
break;
case STORE_FAST:
v = POP();
SETLOCAL(oparg, v);
continue;
case DELETE_FAST:
x = GETLOCAL(oparg);
if (x == NULL) {
format_exc_check_arg(
PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_varnames, oparg)
);
break;
}
SETLOCAL(oparg, NULL);
continue;
case LOAD_CLOSURE:
x = freevars[oparg];
Py_INCREF(x);
PUSH(x);
break;
case LOAD_DEREF:
x = freevars[oparg];
w = PyCell_Get(x);
if (w == NULL) {
if (oparg < f->f_ncells) {
v = PyTuple_GetItem(co->co_cellvars,
oparg);
format_exc_check_arg(
PyExc_UnboundLocalError,
UNBOUNDLOCAL_ERROR_MSG,
v);
} else {
v = PyTuple_GetItem(
co->co_freevars,
oparg - f->f_ncells);
format_exc_check_arg(
PyExc_NameError,
UNBOUNDFREE_ERROR_MSG,
v);
}
err = -1;
break;
}
PUSH(w);
break;
case STORE_DEREF:
w = POP();
x = freevars[oparg];
PyCell_Set(x, w);
Py_DECREF(w);
continue;
case BUILD_TUPLE:
x = PyTuple_New(oparg);
if (x != NULL) {
for (; --oparg >= 0;) {
w = POP();
PyTuple_SET_ITEM(x, oparg, w);
}
PUSH(x);
continue;
}
break;
case BUILD_LIST:
x = PyList_New(oparg);
if (x != NULL) {
for (; --oparg >= 0;) {
w = POP();
PyList_SET_ITEM(x, oparg, w);
}
PUSH(x);
continue;
}
break;
case BUILD_MAP:
x = PyDict_New();
PUSH(x);
if (x != NULL) continue;
break;
case LOAD_ATTR:
w = GETNAMEV(oparg);
v = POP();
x = PyObject_GetAttr(v, w);
Py_DECREF(v);
PUSH(x);
if (x != NULL) continue;
break;
case COMPARE_OP:
w = POP();
v = POP();
if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
/* INLINE: cmp(int, int) */
register long a, b;
register int res;
a = PyInt_AS_LONG(v);
b = PyInt_AS_LONG(w);
switch (oparg) {
case LT: res = a < b; break;
case LE: res = a <= b; break;
case EQ: res = a == b; break;
case NE: res = a != b; break;
case GT: res = a > b; break;
case GE: res = a >= b; break;
case IS: res = v == w; break;
case IS_NOT: res = v != w; break;
default: goto slow_compare;
}
x = res ? Py_True : Py_False;
Py_INCREF(x);
}
else {
slow_compare:
x = cmp_outcome(oparg, v, w);
}
Py_DECREF(v);
Py_DECREF(w);
PUSH(x);
if (x != NULL) continue;
break;
case IMPORT_NAME:
w = GETNAMEV(oparg);
x = PyDict_GetItemString(f->f_builtins, "__import__");
if (x == NULL) {
PyErr_SetString(PyExc_ImportError,
"__import__ not found");
break;
}
u = POP();
w = Py_BuildValue("(OOOO)",
w,
f->f_globals,
f->f_locals == NULL ?
Py_None : f->f_locals,
u);
Py_DECREF(u);
if (w == NULL) {
x = NULL;
break;
}
x = PyEval_CallObject(x, w);
Py_DECREF(w);
PUSH(x);
if (x != NULL) continue;
break;
case IMPORT_STAR:
v = POP();
PyFrame_FastToLocals(f);
if ((x = f->f_locals) == NULL) {
PyErr_SetString(PyExc_SystemError,
"no locals found during 'import *'");
break;
}
err = import_all_from(x, v);
PyFrame_LocalsToFast(f, 0);
Py_DECREF(v);
if (err == 0) continue;
break;
case IMPORT_FROM:
w = GETNAMEV(oparg);
v = TOP();
x = import_from(v, w);
PUSH(x);
if (x != NULL) continue;
break;
case JUMP_FORWARD:
JUMPBY(oparg);
continue;
case JUMP_IF_FALSE:
err = PyObject_IsTrue(TOP());
if (err > 0)
err = 0;
else if (err == 0)
JUMPBY(oparg);
else
break;
continue;
case JUMP_IF_TRUE:
err = PyObject_IsTrue(TOP());
if (err > 0) {
err = 0;
JUMPBY(oparg);
}
else if (err == 0)
;
else
break;
continue;
case JUMP_ABSOLUTE:
JUMPTO(oparg);
continue;
case GET_ITER:
/* before: [obj]; after [getiter(obj)] */
v = POP();
x = PyObject_GetIter(v);
Py_DECREF(v);
if (x != NULL) {
PUSH(x);
continue;
}
break;
case FOR_ITER:
/* before: [iter]; after: [iter, iter()] *or* [] */
v = TOP();
x = PyIter_Next(v);
if (x != NULL) {
PUSH(x);
continue;
}
if (!PyErr_Occurred()) {
/* iterator ended normally */
x = v = POP();
Py_DECREF(v);
JUMPBY(oparg);
continue;
}
break;
case FOR_LOOP:
/* for v in s: ...
On entry: stack contains s, i.
On exit: stack contains s, i+1, s[i];
but if loop exhausted:
s, i are popped, and we jump */
w = POP(); /* Loop index */
v = POP(); /* Sequence object */
u = loop_subscript(v, w);
if (u != NULL) {
PUSH(v);
x = PyInt_FromLong(PyInt_AsLong(w)+1);
PUSH(x);
Py_DECREF(w);
PUSH(u);
if (x != NULL) continue;
}
else {
Py_DECREF(v);
Py_DECREF(w);
/* A NULL can mean "s exhausted"
but also an error: */
if (PyErr_Occurred())
why = WHY_EXCEPTION;
else {
JUMPBY(oparg);
continue;
}
}
break;
case SETUP_LOOP:
case SETUP_EXCEPT:
case SETUP_FINALLY:
PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
STACK_LEVEL());
continue;
case SET_LINENO:
#ifdef LLTRACE
if (lltrace)
printf("--- %s:%d \n", filename, oparg);
#endif
f->f_lineno = oparg;
if (tstate->c_tracefunc == NULL || tstate->tracing)
continue;
/* Trace each line of code reached */
f->f_lasti = INSTR_OFFSET();
f->f_stacktop = stack_pointer;
/* Inline call_trace() for performance: */
tstate->tracing++;
tstate->use_tracing = 0;
err = (tstate->c_tracefunc)(tstate->c_traceobj, f,
PyTrace_LINE, Py_None);
tstate->use_tracing = (tstate->c_tracefunc
|| tstate->c_profilefunc);
tstate->tracing--;
/* Reload possibly changed frame fields */
JUMPTO(f->f_lasti);
stack_pointer = f->f_stacktop;
assert(stack_pointer != NULL);
f->f_stacktop = NULL;
break;
case CALL_FUNCTION:
{
int na = oparg & 0xff;
int nk = (oparg>>8) & 0xff;
int n = na + 2 * nk;
PyObject **pfunc = stack_pointer - n - 1;
PyObject *func = *pfunc;
f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
/* Always dispatch PyCFunction first, because
these are presumed to be the most frequent
callable object.
*/
if (PyCFunction_Check(func)) {
int flags = PyCFunction_GET_FLAGS(func);
if (nk != 0 || (flags & METH_KEYWORDS))
x = do_call(func, &stack_pointer,
na, nk);
else if (flags == METH_VARARGS) {
PyObject *callargs;
callargs = load_args(&stack_pointer, na);
x = PyCFunction_Call(func, callargs, NULL);
Py_XDECREF(callargs);
} else
x = fast_cfunction(func,
&stack_pointer, na);
} else {
if (PyMethod_Check(func)
&& PyMethod_GET_SELF(func) != NULL) {
/* optimize access to bound methods */
PyObject *self = PyMethod_GET_SELF(func);
Py_INCREF(self);
func = PyMethod_GET_FUNCTION(func);
Py_INCREF(func);
Py_DECREF(*pfunc);
*pfunc = self;
na++;
n++;
} else
Py_INCREF(func);
if (PyFunction_Check(func)) {
x = fast_function(func, &stack_pointer,
n, na, nk);
} else {
x = do_call(func, &stack_pointer,
na, nk);
}
Py_DECREF(func);
}
while (stack_pointer > pfunc) {
w = POP();
Py_DECREF(w);
}
PUSH(x);
if (x != NULL)
continue;
break;
}
case CALL_FUNCTION_VAR:
case CALL_FUNCTION_KW:
case CALL_FUNCTION_VAR_KW:
{
int na = oparg & 0xff;
int nk = (oparg>>8) & 0xff;
int flags = (opcode - CALL_FUNCTION) & 3;
int n = na + 2 * nk;
PyObject **pfunc, *func;
if (flags & CALL_FLAG_VAR)
n++;
if (flags & CALL_FLAG_KW)
n++;
pfunc = stack_pointer - n - 1;
func = *pfunc;
f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
if (PyMethod_Check(func)
&& PyMethod_GET_SELF(func) != NULL) {
PyObject *self = PyMethod_GET_SELF(func);
Py_INCREF(self);
func = PyMethod_GET_FUNCTION(func);
Py_INCREF(func);
Py_DECREF(*pfunc);
*pfunc = self;
na++;
n++;
} else
Py_INCREF(func);
x = ext_do_call(func, &stack_pointer, flags, na, nk);
Py_DECREF(func);
while (stack_pointer > pfunc) {
w = POP();
Py_DECREF(w);
}
PUSH(x);
if (x != NULL)
continue;
break;
}
case MAKE_FUNCTION:
v = POP(); /* code object */
x = PyFunction_New(v, f->f_globals);
Py_DECREF(v);
/* XXX Maybe this should be a separate opcode? */
if (x != NULL && oparg > 0) {
v = PyTuple_New(oparg);
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
while (--oparg >= 0) {
w = POP();
PyTuple_SET_ITEM(v, oparg, w);
}
err = PyFunction_SetDefaults(x, v);
Py_DECREF(v);
}
PUSH(x);
break;
case MAKE_CLOSURE:
{
int nfree;
v = POP(); /* code object */
x = PyFunction_New(v, f->f_globals);
nfree = PyCode_GetNumFree((PyCodeObject *)v);
Py_DECREF(v);
/* XXX Maybe this should be a separate opcode? */
if (x != NULL && nfree > 0) {
v = PyTuple_New(nfree);
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
while (--nfree >= 0) {
w = POP();
PyTuple_SET_ITEM(v, nfree, w);
}
err = PyFunction_SetClosure(x, v);
Py_DECREF(v);
}
if (x != NULL && oparg > 0) {
v = PyTuple_New(oparg);
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
while (--oparg >= 0) {
w = POP();
PyTuple_SET_ITEM(v, oparg, w);
}
err = PyFunction_SetDefaults(x, v);
Py_DECREF(v);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -