summaryrefslogtreecommitdiff
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c2281
1 files changed, 1224 insertions, 1057 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 73925dc413..82f0651e89 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -37,7 +37,7 @@ typedef unsigned long long uint64;
static void
ppc_getcounter(uint64 *v)
{
- register unsigned long tbu, tb, tbu2;
+ unsigned long tbu, tb, tbu2;
loop:
asm volatile ("mftbu %0" : "=r" (tbu) );
@@ -142,8 +142,6 @@ static PyObject * special_lookup(PyObject *, _Py_Identifier *);
#define NAME_ERROR_MSG \
"name '%.200s' is not defined"
-#define GLOBAL_NAME_ERROR_MSG \
- "global name '%.200s' is not defined"
#define UNBOUNDLOCAL_ERROR_MSG \
"local variable '%.200s' referenced before assignment"
#define UNBOUNDFREE_ERROR_MSG \
@@ -364,29 +362,28 @@ PyEval_ReleaseThread(PyThreadState *tstate)
drop_gil(tstate);
}
-/* This function is called from PyOS_AfterFork to ensure that newly
- created child processes don't hold locks referring to threads which
- are not running in the child process. (This could also be done using
- pthread_atfork mechanism, at least for the pthreads implementation.) */
+/* This function is called from PyOS_AfterFork to destroy all threads which are
+ * not running in the child process, and clear internal locks which might be
+ * held by those threads. (This could also be done using pthread_atfork
+ * mechanism, at least for the pthreads implementation.) */
void
PyEval_ReInitThreads(void)
{
_Py_IDENTIFIER(_after_fork);
PyObject *threading, *result;
- PyThreadState *tstate = PyThreadState_GET();
+ PyThreadState *current_tstate = PyThreadState_GET();
if (!gil_created())
return;
recreate_gil();
pending_lock = PyThread_allocate_lock();
- take_gil(tstate);
+ take_gil(current_tstate);
main_thread = PyThread_get_thread_ident();
/* Update the threading module with the new state.
*/
- tstate = PyThreadState_GET();
- threading = PyMapping_GetItemString(tstate->interp->modules,
+ threading = PyMapping_GetItemString(current_tstate->interp->modules,
"threading");
if (threading == NULL) {
/* threading not imported */
@@ -399,6 +396,9 @@ PyEval_ReInitThreads(void)
else
Py_DECREF(result);
Py_DECREF(threading);
+
+ /* Destroy all threads except the current one */
+ _PyThreadState_DeleteExcept(current_tstate);
}
#else
@@ -742,7 +742,6 @@ _Py_CheckRecursiveCall(char *where)
enum why_code {
WHY_NOT = 0x0001, /* No error */
WHY_EXCEPTION = 0x0002, /* Exception occurred */
- WHY_RERAISE = 0x0004, /* Exception re-raised by 'finally' */
WHY_RETURN = 0x0008, /* 'return' statement */
WHY_BREAK = 0x0010, /* 'break' statement */
WHY_CONTINUE = 0x0020, /* 'continue' statement */
@@ -753,7 +752,7 @@ enum why_code {
static void save_exc_state(PyThreadState *, PyFrameObject *);
static void swap_exc_state(PyThreadState *, PyFrameObject *);
static void restore_and_clear_exc_state(PyThreadState *, PyFrameObject *);
-static enum why_code do_raise(PyObject *, PyObject *);
+static int do_raise(PyObject *, PyObject *);
static int unpack_iterable(PyObject *, int, int, PyObject **);
/* Records whether tracing is on for any thread. Counts the number of
@@ -793,18 +792,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#ifdef DXPAIRS
int lastopcode = 0;
#endif
- register PyObject **stack_pointer; /* Next free slot in value stack */
- register unsigned char *next_instr;
- register int opcode; /* Current opcode */
- register int oparg; /* Current opcode argument, if any */
- register enum why_code why; /* Reason for block stack unwind */
- register int err; /* Error status -- nonzero if error */
- register PyObject *x; /* Result object -- NULL if error */
- register PyObject *v; /* Temporary objects popped off stack */
- register PyObject *w;
- register PyObject *u;
- register PyObject *t;
- register PyObject **fastlocals, **freevars;
+ PyObject **stack_pointer; /* Next free slot in value stack */
+ unsigned char *next_instr;
+ int opcode; /* Current opcode */
+ int oparg; /* Current opcode argument, if any */
+ enum why_code why; /* Reason for block stack unwind */
+ PyObject **fastlocals, **freevars;
PyObject *retval = NULL; /* Return value */
PyThreadState *tstate = PyThreadState_GET();
PyCodeObject *co;
@@ -1189,6 +1182,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
stack_pointer = f->f_stacktop;
assert(stack_pointer != NULL);
f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
+ f->f_executing = 1;
if (co->co_flags & CO_GENERATOR && !throwflag) {
if (f->f_exc_type != NULL && f->f_exc_type != Py_None) {
@@ -1206,14 +1200,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#endif
why = WHY_NOT;
- err = 0;
- x = Py_None; /* Not a reference, just anything non-NULL */
- w = NULL;
- if (throwflag) { /* support for generator.throw() */
- why = WHY_EXCEPTION;
- goto on_error;
- }
+ if (throwflag) /* support for generator.throw() */
+ goto error;
+
+#ifdef Py_DEBUG
+ /* PyEval_EvalFrameEx() must not be called with an exception set,
+ because it may clear it (directly or indirectly) and so the
+ caller looses its exception */
+ assert(!PyErr_Occurred());
+#endif
for (;;) {
#ifdef WITH_TSC
@@ -1235,6 +1231,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#endif
assert(stack_pointer >= f->f_valuestack); /* else underflow */
assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
+ assert(!PyErr_Occurred());
/* Do periodic things. Doing this every time through
the loop would add too much overhead, so we do it
@@ -1250,15 +1247,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
a try: finally: block uninterruptible. */
goto fast_next_opcode;
}
- tstate->tick_counter++;
#ifdef WITH_TSC
ticked = 1;
#endif
if (_Py_atomic_load_relaxed(&pendingcalls_to_do)) {
- if (Py_MakePendingCalls() < 0) {
- why = WHY_EXCEPTION;
- goto on_error;
- }
+ if (Py_MakePendingCalls() < 0)
+ goto error;
}
#ifdef WITH_THREAD
if (_Py_atomic_load_relaxed(&gil_drop_request)) {
@@ -1276,13 +1270,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#endif
/* Check for asynchronous exceptions. */
if (tstate->async_exc != NULL) {
- x = tstate->async_exc;
+ PyObject *exc = tstate->async_exc;
tstate->async_exc = NULL;
UNSIGNAL_ASYNC_EXC();
- PyErr_SetNone(x);
- Py_DECREF(x);
- why = WHY_EXCEPTION;
- goto on_error;
+ PyErr_SetNone(exc);
+ Py_DECREF(exc);
+ goto error;
}
}
@@ -1293,6 +1286,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
if (_Py_TracingPossible &&
tstate->c_tracefunc != NULL && !tstate->tracing) {
+ int err;
/* see maybe_call_line_trace
for expository comments */
f->f_stacktop = stack_pointer;
@@ -1307,10 +1301,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
stack_pointer = f->f_stacktop;
f->f_stacktop = NULL;
}
- if (err) {
+ if (err)
/* trace function raised an exception */
- goto on_error;
- }
+ goto error;
}
/* Extract opcode and argument */
@@ -1357,87 +1350,99 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
TARGET(NOP)
FAST_DISPATCH();
- TARGET(LOAD_FAST)
- x = GETLOCAL(oparg);
- if (x != NULL) {
- Py_INCREF(x);
- PUSH(x);
- FAST_DISPATCH();
+ TARGET(LOAD_FAST) {
+ PyObject *value = GETLOCAL(oparg);
+ if (value == NULL) {
+ format_exc_check_arg(PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_varnames, oparg));
+ goto error;
}
- format_exc_check_arg(PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- PyTuple_GetItem(co->co_varnames, oparg));
- break;
+ Py_INCREF(value);
+ PUSH(value);
+ FAST_DISPATCH();
+ }
- TARGET(LOAD_CONST)
- x = GETITEM(consts, oparg);
- Py_INCREF(x);
- PUSH(x);
+ TARGET(LOAD_CONST) {
+ PyObject *value = GETITEM(consts, oparg);
+ Py_INCREF(value);
+ PUSH(value);
FAST_DISPATCH();
+ }
PREDICTED_WITH_ARG(STORE_FAST);
- TARGET(STORE_FAST)
- v = POP();
- SETLOCAL(oparg, v);
+ TARGET(STORE_FAST) {
+ PyObject *value = POP();
+ SETLOCAL(oparg, value);
FAST_DISPATCH();
+ }
- TARGET(POP_TOP)
- v = POP();
- Py_DECREF(v);
+ TARGET(POP_TOP) {
+ PyObject *value = POP();
+ Py_DECREF(value);
FAST_DISPATCH();
+ }
- TARGET(ROT_TWO)
- v = TOP();
- w = SECOND();
- SET_TOP(w);
- SET_SECOND(v);
+ TARGET(ROT_TWO) {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ SET_TOP(second);
+ SET_SECOND(top);
FAST_DISPATCH();
+ }
- TARGET(ROT_THREE)
- v = TOP();
- w = SECOND();
- x = THIRD();
- SET_TOP(w);
- SET_SECOND(x);
- SET_THIRD(v);
+ TARGET(ROT_THREE) {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ PyObject *third = THIRD();
+ SET_TOP(second);
+ SET_SECOND(third);
+ SET_THIRD(top);
FAST_DISPATCH();
+ }
- TARGET(DUP_TOP)
- v = TOP();
- Py_INCREF(v);
- PUSH(v);
+ TARGET(DUP_TOP) {
+ PyObject *top = TOP();
+ Py_INCREF(top);
+ PUSH(top);
FAST_DISPATCH();
+ }
- TARGET(DUP_TOP_TWO)
- x = TOP();
- Py_INCREF(x);
- w = SECOND();
- Py_INCREF(w);
+ TARGET(DUP_TOP_TWO) {
+ PyObject *top = TOP();
+ PyObject *second = SECOND();
+ Py_INCREF(top);
+ Py_INCREF(second);
STACKADJ(2);
- SET_TOP(x);
- SET_SECOND(w);
+ SET_TOP(top);
+ SET_SECOND(second);
FAST_DISPATCH();
+ }
- TARGET(UNARY_POSITIVE)
- v = TOP();
- x = PyNumber_Positive(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(UNARY_POSITIVE) {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Positive(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(UNARY_NEGATIVE)
- v = TOP();
- x = PyNumber_Negative(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(UNARY_NEGATIVE) {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Negative(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(UNARY_NOT)
- v = TOP();
- err = PyObject_IsTrue(v);
- Py_DECREF(v);
+ TARGET(UNARY_NOT) {
+ PyObject *value = TOP();
+ int err = PyObject_IsTrue(value);
+ Py_DECREF(value);
if (err == 0) {
Py_INCREF(Py_True);
SET_TOP(Py_True);
@@ -1450,416 +1455,464 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
DISPATCH();
}
STACKADJ(-1);
- break;
+ goto error;
+ }
- TARGET(UNARY_INVERT)
- v = TOP();
- x = PyNumber_Invert(v);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(UNARY_INVERT) {
+ PyObject *value = TOP();
+ PyObject *res = PyNumber_Invert(value);
+ Py_DECREF(value);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_POWER)
- w = POP();
- v = TOP();
- x = PyNumber_Power(v, w, Py_None);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_POWER) {
+ PyObject *exp = POP();
+ PyObject *base = TOP();
+ PyObject *res = PyNumber_Power(base, exp, Py_None);
+ Py_DECREF(base);
+ Py_DECREF(exp);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_MULTIPLY)
- w = POP();
- v = TOP();
- x = PyNumber_Multiply(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_MULTIPLY) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Multiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_TRUE_DIVIDE)
- w = POP();
- v = TOP();
- x = PyNumber_TrueDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_TRUE_DIVIDE) {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_TrueDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_FLOOR_DIVIDE)
- w = POP();
- v = TOP();
- x = PyNumber_FloorDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_FLOOR_DIVIDE) {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_FloorDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_MODULO)
- w = POP();
- v = TOP();
- if (PyUnicode_CheckExact(v))
- x = PyUnicode_Format(v, w);
- else
- x = PyNumber_Remainder(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_MODULO) {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *res = PyUnicode_CheckExact(dividend) ?
+ PyUnicode_Format(dividend, divisor) :
+ PyNumber_Remainder(dividend, divisor);
+ Py_DECREF(divisor);
+ Py_DECREF(dividend);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_ADD)
- w = POP();
- v = TOP();
- if (PyUnicode_CheckExact(v) &&
- PyUnicode_CheckExact(w)) {
- x = unicode_concatenate(v, w, f, next_instr);
+ 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 */
- goto skip_decref_vx;
}
else {
- x = PyNumber_Add(v, w);
+ sum = PyNumber_Add(left, right);
+ Py_DECREF(left);
}
- Py_DECREF(v);
- skip_decref_vx:
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
-
- TARGET(BINARY_SUBTRACT)
- w = POP();
- v = TOP();
- x = PyNumber_Subtract(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
-
- TARGET(BINARY_SUBSCR)
- w = POP();
- v = TOP();
- x = PyObject_GetItem(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ Py_DECREF(right);
+ SET_TOP(sum);
+ if (sum == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_LSHIFT)
- w = POP();
- v = TOP();
- x = PyNumber_Lshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_SUBTRACT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *diff = PyNumber_Subtract(left, right);
+ Py_DECREF(right);
+ Py_DECREF(left);
+ SET_TOP(diff);
+ if (diff == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_RSHIFT)
- w = POP();
- v = TOP();
- x = PyNumber_Rshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_SUBSCR) {
+ PyObject *sub = POP();
+ PyObject *container = TOP();
+ PyObject *res = PyObject_GetItem(container, sub);
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_AND)
- w = POP();
- v = TOP();
- x = PyNumber_And(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_LSHIFT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Lshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_XOR)
- w = POP();
- v = TOP();
- x = PyNumber_Xor(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_RSHIFT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Rshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(BINARY_OR)
- w = POP();
- v = TOP();
- x = PyNumber_Or(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BINARY_AND) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_And(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(LIST_APPEND)
- w = POP();
- v = PEEK(oparg);
- err = PyList_Append(v, w);
- Py_DECREF(w);
- if (err == 0) {
- PREDICT(JUMP_ABSOLUTE);
- DISPATCH();
- }
- break;
+ TARGET(BINARY_XOR) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Xor(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(SET_ADD)
- w = POP();
- v = stack_pointer[-oparg];
- err = PySet_Add(v, w);
- Py_DECREF(w);
- if (err == 0) {
- PREDICT(JUMP_ABSOLUTE);
- DISPATCH();
- }
- break;
+ TARGET(BINARY_OR) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_Or(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_POWER)
- w = POP();
- v = TOP();
- x = PyNumber_InPlacePower(v, w, Py_None);
+ TARGET(LIST_APPEND) {
+ PyObject *v = POP();
+ PyObject *list = PEEK(oparg);
+ int err;
+ err = PyList_Append(list, v);
Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
- TARGET(INPLACE_MULTIPLY)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceMultiply(v, w);
+ TARGET(SET_ADD) {
+ PyObject *v = POP();
+ PyObject *set = stack_pointer[-oparg];
+ int err;
+ err = PySet_Add(set, v);
Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
- TARGET(INPLACE_TRUE_DIVIDE)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceTrueDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_POWER) {
+ PyObject *exp = POP();
+ PyObject *base = TOP();
+ PyObject *res = PyNumber_InPlacePower(base, exp, Py_None);
+ Py_DECREF(base);
+ Py_DECREF(exp);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_FLOOR_DIVIDE)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceFloorDivide(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_MULTIPLY) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_MODULO)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceRemainder(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_TRUE_DIVIDE) {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ TARGET(INPLACE_FLOOR_DIVIDE) {
+ PyObject *divisor = POP();
+ PyObject *dividend = TOP();
+ PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor);
+ Py_DECREF(dividend);
+ Py_DECREF(divisor);
+ SET_TOP(quotient);
+ if (quotient == NULL)
+ goto error;
+ DISPATCH();
+ }
+
+ TARGET(INPLACE_MODULO) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *mod = PyNumber_InPlaceRemainder(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(mod);
+ if (mod == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_ADD)
- w = POP();
- v = TOP();
- if (PyUnicode_CheckExact(v) &&
- PyUnicode_CheckExact(w)) {
- x = unicode_concatenate(v, w, f, next_instr);
+ TARGET(INPLACE_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 */
- goto skip_decref_v;
}
else {
- x = PyNumber_InPlaceAdd(v, w);
+ sum = PyNumber_InPlaceAdd(left, right);
+ Py_DECREF(left);
}
- Py_DECREF(v);
- skip_decref_v:
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ Py_DECREF(right);
+ SET_TOP(sum);
+ if (sum == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_SUBTRACT)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceSubtract(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_SUBTRACT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *diff = PyNumber_InPlaceSubtract(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(diff);
+ if (diff == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_LSHIFT)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceLshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_LSHIFT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceLshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_RSHIFT)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceRshift(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_RSHIFT) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceRshift(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_AND)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceAnd(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_AND) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceAnd(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_XOR)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceXor(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_XOR) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceXor(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(INPLACE_OR)
- w = POP();
- v = TOP();
- x = PyNumber_InPlaceOr(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(INPLACE_OR) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceOr(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(STORE_SUBSCR)
- w = TOP();
- v = SECOND();
- u = THIRD();
+ TARGET(STORE_SUBSCR) {
+ PyObject *sub = TOP();
+ PyObject *container = SECOND();
+ PyObject *v = THIRD();
+ int err;
STACKADJ(-3);
/* v[w] = u */
- err = PyObject_SetItem(v, w, u);
- Py_DECREF(u);
+ err = PyObject_SetItem(container, sub, v);
Py_DECREF(v);
- Py_DECREF(w);
- if (err == 0) DISPATCH();
- break;
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(DELETE_SUBSCR)
- w = TOP();
- v = SECOND();
+ TARGET(DELETE_SUBSCR) {
+ PyObject *sub = TOP();
+ PyObject *container = SECOND();
+ int err;
STACKADJ(-2);
/* del v[w] */
- err = PyObject_DelItem(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- if (err == 0) DISPATCH();
- break;
+ err = PyObject_DelItem(container, sub);
+ Py_DECREF(container);
+ Py_DECREF(sub);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(PRINT_EXPR)
- v = POP();
- w = PySys_GetObject("displayhook");
- if (w == NULL) {
+ TARGET(PRINT_EXPR) {
+ _Py_IDENTIFIER(displayhook);
+ PyObject *value = POP();
+ PyObject *hook = _PySys_GetObjectId(&PyId_displayhook);
+ PyObject *res;
+ if (hook == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"lost sys.displayhook");
- err = -1;
- x = NULL;
- }
- if (err == 0) {
- x = PyTuple_Pack(1, v);
- if (x == NULL)
- err = -1;
+ Py_DECREF(value);
+ goto error;
}
- if (err == 0) {
- w = PyEval_CallObject(w, x);
- Py_XDECREF(w);
- if (w == NULL)
- err = -1;
- }
- Py_DECREF(v);
- Py_XDECREF(x);
- break;
+ res = PyObject_CallFunctionObjArgs(hook, value, NULL);
+ Py_DECREF(value);
+ if (res == NULL)
+ goto error;
+ Py_DECREF(res);
+ DISPATCH();
+ }
#ifdef CASE_TOO_BIG
default: switch (opcode) {
#endif
- TARGET(RAISE_VARARGS)
- v = w = NULL;
+ TARGET(RAISE_VARARGS) {
+ PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
- v = POP(); /* cause */
+ cause = POP(); /* cause */
case 1:
- w = POP(); /* exc */
+ exc = POP(); /* exc */
case 0: /* Fallthrough */
- why = do_raise(w, v);
+ if (do_raise(exc, cause)) {
+ why = WHY_EXCEPTION;
+ goto fast_block_end;
+ }
break;
default:
PyErr_SetString(PyExc_SystemError,
"bad RAISE_VARARGS oparg");
- why = WHY_EXCEPTION;
break;
}
- break;
-
- TARGET(STORE_LOCALS)
- x = POP();
- v = f->f_locals;
- Py_XDECREF(v);
- f->f_locals = x;
- DISPATCH();
+ goto error;
+ }
- TARGET(RETURN_VALUE)
+ TARGET(RETURN_VALUE) {
retval = POP();
why = WHY_RETURN;
goto fast_block_end;
+ }
- TARGET(YIELD_FROM)
- u = POP();
- x = TOP();
- /* send u to x */
- if (PyGen_CheckExact(x)) {
- retval = _PyGen_Send((PyGenObject *)x, u);
+ TARGET(YIELD_FROM) {
+ PyObject *v = POP();
+ PyObject *reciever = TOP();
+ int err;
+ if (PyGen_CheckExact(reciever)) {
+ retval = _PyGen_Send((PyGenObject *)reciever, v);
} else {
_Py_IDENTIFIER(send);
- if (u == Py_None)
- retval = Py_TYPE(x)->tp_iternext(x);
+ if (v == Py_None)
+ retval = Py_TYPE(reciever)->tp_iternext(reciever);
else
- retval = _PyObject_CallMethodId(x, &PyId_send, "O", u);
+ retval = _PyObject_CallMethodId(reciever, &PyId_send, "O", v);
}
- Py_DECREF(u);
- if (!retval) {
+ Py_DECREF(v);
+ if (retval == NULL) {
PyObject *val;
- x = POP(); /* Remove iter from stack */
- Py_DECREF(x);
+ if (tstate->c_tracefunc != NULL
+ && PyErr_ExceptionMatches(PyExc_StopIteration))
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f);
err = _PyGen_FetchStopIterationValue(&val);
- if (err < 0) {
- x = NULL;
- break;
- }
- x = val;
- PUSH(x);
- continue;
+ if (err < 0)
+ goto error;
+ Py_DECREF(reciever);
+ SET_TOP(val);
+ DISPATCH();
}
/* x remains on stack, retval is value to be yielded */
f->f_stacktop = stack_pointer;
@@ -1867,39 +1920,38 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
/* and repeat... */
f->f_lasti--;
goto fast_yield;
+ }
- TARGET(YIELD_VALUE)
+ TARGET(YIELD_VALUE) {
retval = POP();
f->f_stacktop = stack_pointer;
why = WHY_YIELD;
goto fast_yield;
+ }
- TARGET(POP_EXCEPT)
- {
- PyTryBlock *b = PyFrame_BlockPop(f);
- if (b->b_type != EXCEPT_HANDLER) {
- PyErr_SetString(PyExc_SystemError,
- "popped block is not an except handler");
- why = WHY_EXCEPTION;
- break;
- }
- UNWIND_EXCEPT_HANDLER(b);
+ TARGET(POP_EXCEPT) {
+ PyTryBlock *b = PyFrame_BlockPop(f);
+ if (b->b_type != EXCEPT_HANDLER) {
+ PyErr_SetString(PyExc_SystemError,
+ "popped block is not an except handler");
+ goto error;
}
+ UNWIND_EXCEPT_HANDLER(b);
DISPATCH();
+ }
- TARGET(POP_BLOCK)
- {
- PyTryBlock *b = PyFrame_BlockPop(f);
- UNWIND_BLOCK(b);
- }
+ TARGET(POP_BLOCK) {
+ PyTryBlock *b = PyFrame_BlockPop(f);
+ UNWIND_BLOCK(b);
DISPATCH();
+ }
PREDICTED(END_FINALLY);
- TARGET(END_FINALLY)
- v = POP();
- if (PyLong_Check(v)) {
- why = (enum why_code) PyLong_AS_LONG(v);
- assert(why != WHY_YIELD);
+ TARGET(END_FINALLY) {
+ PyObject *status = POP();
+ if (PyLong_Check(status)) {
+ why = (enum why_code) PyLong_AS_LONG(status);
+ assert(why != WHY_YIELD && why != WHY_EXCEPTION);
if (why == WHY_RETURN ||
why == WHY_CONTINUE)
retval = POP();
@@ -1912,248 +1964,280 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
assert(b->b_type == EXCEPT_HANDLER);
UNWIND_EXCEPT_HANDLER(b);
why = WHY_NOT;
+ Py_DECREF(status);
+ DISPATCH();
}
+ Py_DECREF(status);
+ goto fast_block_end;
}
- else if (PyExceptionClass_Check(v)) {
- w = POP();
- u = POP();
- PyErr_Restore(v, w, u);
- why = WHY_RERAISE;
- break;
+ else if (PyExceptionClass_Check(status)) {
+ PyObject *exc = POP();
+ PyObject *tb = POP();
+ PyErr_Restore(status, exc, tb);
+ why = WHY_EXCEPTION;
+ goto fast_block_end;
}
- else if (v != Py_None) {
+ else if (status != Py_None) {
PyErr_SetString(PyExc_SystemError,
"'finally' pops bad exception");
- why = WHY_EXCEPTION;
+ Py_DECREF(status);
+ goto error;
}
- Py_DECREF(v);
- break;
+ Py_DECREF(status);
+ DISPATCH();
+ }
- TARGET(LOAD_BUILD_CLASS)
- {
+ TARGET(LOAD_BUILD_CLASS) {
_Py_IDENTIFIER(__build_class__);
+ PyObject *bc;
if (PyDict_CheckExact(f->f_builtins)) {
- x = _PyDict_GetItemId(f->f_builtins, &PyId___build_class__);
- if (x == NULL) {
+ bc = _PyDict_GetItemId(f->f_builtins, &PyId___build_class__);
+ if (bc == NULL) {
PyErr_SetString(PyExc_NameError,
"__build_class__ not found");
- break;
+ goto error;
}
- Py_INCREF(x);
+ Py_INCREF(bc);
}
else {
PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__);
if (build_class_str == NULL)
break;
- x = PyObject_GetItem(f->f_builtins, build_class_str);
- if (x == NULL) {
+ bc = PyObject_GetItem(f->f_builtins, build_class_str);
+ if (bc == NULL) {
if (PyErr_ExceptionMatches(PyExc_KeyError))
PyErr_SetString(PyExc_NameError,
"__build_class__ not found");
- break;
+ goto error;
}
}
- PUSH(x);
- break;
+ PUSH(bc);
+ DISPATCH();
}
- TARGET(STORE_NAME)
- w = GETITEM(names, oparg);
- v = POP();
- if ((x = f->f_locals) != NULL) {
- if (PyDict_CheckExact(x))
- err = PyDict_SetItem(x, w, v);
- else
- err = PyObject_SetItem(x, w, v);
+ TARGET(STORE_NAME) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *v = POP();
+ PyObject *ns = f->f_locals;
+ int err;
+ if (ns == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "no locals found when storing %R", name);
Py_DECREF(v);
- if (err == 0) DISPATCH();
- break;
+ goto error;
}
- PyErr_Format(PyExc_SystemError,
- "no locals found when storing %R", w);
- break;
+ if (PyDict_CheckExact(ns))
+ err = PyDict_SetItem(ns, name, v);
+ else
+ err = PyObject_SetItem(ns, name, v);
+ Py_DECREF(v);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(DELETE_NAME)
- w = GETITEM(names, oparg);
- if ((x = f->f_locals) != NULL) {
- if ((err = PyObject_DelItem(x, w)) != 0)
- format_exc_check_arg(PyExc_NameError,
- NAME_ERROR_MSG,
- w);
- break;
+ TARGET(DELETE_NAME) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *ns = f->f_locals;
+ int err;
+ if (ns == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "no locals when deleting %R", name);
+ goto error;
}
- PyErr_Format(PyExc_SystemError,
- "no locals when deleting %R", w);
- break;
+ err = PyObject_DelItem(ns, name);
+ if (err != 0) {
+ format_exc_check_arg(PyExc_NameError,
+ NAME_ERROR_MSG,
+ name);
+ goto error;
+ }
+ DISPATCH();
+ }
PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
- TARGET(UNPACK_SEQUENCE)
- v = POP();
- if (PyTuple_CheckExact(v) &&
- PyTuple_GET_SIZE(v) == oparg) {
- PyObject **items = \
- ((PyTupleObject *)v)->ob_item;
+ TARGET(UNPACK_SEQUENCE) {
+ PyObject *seq = POP(), *item, **items;
+ if (PyTuple_CheckExact(seq) &&
+ PyTuple_GET_SIZE(seq) == oparg) {
+ items = ((PyTupleObject *)seq)->ob_item;
while (oparg--) {
- w = items[oparg];
- Py_INCREF(w);
- PUSH(w);
+ item = items[oparg];
+ Py_INCREF(item);
+ PUSH(item);
}
- Py_DECREF(v);
- DISPATCH();
- } else if (PyList_CheckExact(v) &&
- PyList_GET_SIZE(v) == oparg) {
- PyObject **items = \
- ((PyListObject *)v)->ob_item;
+ } else if (PyList_CheckExact(seq) &&
+ PyList_GET_SIZE(seq) == oparg) {
+ items = ((PyListObject *)seq)->ob_item;
while (oparg--) {
- w = items[oparg];
- Py_INCREF(w);
- PUSH(w);
+ item = items[oparg];
+ Py_INCREF(item);
+ PUSH(item);
}
- } else if (unpack_iterable(v, oparg, -1,
+ } else if (unpack_iterable(seq, oparg, -1,
stack_pointer + oparg)) {
STACKADJ(oparg);
} else {
/* unpack_iterable() raised an exception */
- why = WHY_EXCEPTION;
+ Py_DECREF(seq);
+ goto error;
}
- Py_DECREF(v);
- break;
+ Py_DECREF(seq);
+ DISPATCH();
+ }
- TARGET(UNPACK_EX)
- {
+ TARGET(UNPACK_EX) {
int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
- v = POP();
+ PyObject *seq = POP();
- if (unpack_iterable(v, oparg & 0xFF, oparg >> 8,
+ if (unpack_iterable(seq, oparg & 0xFF, oparg >> 8,
stack_pointer + totalargs)) {
stack_pointer += totalargs;
} else {
- why = WHY_EXCEPTION;
+ Py_DECREF(seq);
+ goto error;
}
- Py_DECREF(v);
- break;
+ Py_DECREF(seq);
+ DISPATCH();
}
- TARGET(STORE_ATTR)
- w = GETITEM(names, oparg);
- v = TOP();
- u = SECOND();
+ TARGET(STORE_ATTR) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = TOP();
+ PyObject *v = SECOND();
+ int err;
STACKADJ(-2);
- err = PyObject_SetAttr(v, w, u); /* v.w = u */
+ err = PyObject_SetAttr(owner, name, v);
Py_DECREF(v);
- Py_DECREF(u);
- if (err == 0) DISPATCH();
- break;
+ Py_DECREF(owner);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(DELETE_ATTR)
- w = GETITEM(names, oparg);
- v = POP();
- err = PyObject_SetAttr(v, w, (PyObject *)NULL);
- /* del v.w */
- Py_DECREF(v);
- break;
+ TARGET(DELETE_ATTR) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = POP();
+ int err;
+ err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
+ Py_DECREF(owner);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(STORE_GLOBAL)
- w = GETITEM(names, oparg);
- v = POP();
- err = PyDict_SetItem(f->f_globals, w, v);
+ TARGET(STORE_GLOBAL) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *v = POP();
+ int err;
+ err = PyDict_SetItem(f->f_globals, name, v);
Py_DECREF(v);
- if (err == 0) DISPATCH();
- break;
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(DELETE_GLOBAL)
- w = GETITEM(names, oparg);
- if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
+ TARGET(DELETE_GLOBAL) {
+ PyObject *name = GETITEM(names, oparg);
+ int err;
+ err = PyDict_DelItem(f->f_globals, name);
+ if (err != 0) {
format_exc_check_arg(
- PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
- break;
+ PyExc_NameError, NAME_ERROR_MSG, name);
+ goto error;
+ }
+ DISPATCH();
+ }
- TARGET(LOAD_NAME)
- w = GETITEM(names, oparg);
- if ((v = f->f_locals) == NULL) {
+ TARGET(LOAD_NAME) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *locals = f->f_locals;
+ PyObject *v;
+ if (locals == NULL) {
PyErr_Format(PyExc_SystemError,
- "no locals when loading %R", w);
- why = WHY_EXCEPTION;
- break;
+ "no locals when loading %R", name);
+ goto error;
}
- if (PyDict_CheckExact(v)) {
- x = PyDict_GetItem(v, w);
- Py_XINCREF(x);
+ if (PyDict_CheckExact(locals)) {
+ v = PyDict_GetItem(locals, name);
+ Py_XINCREF(v);
}
else {
- x = PyObject_GetItem(v, w);
- if (x == NULL && _PyErr_OCCURRED()) {
- if (!PyErr_ExceptionMatches(
- PyExc_KeyError))
- break;
+ v = PyObject_GetItem(locals, name);
+ if (v == NULL && _PyErr_OCCURRED()) {
+ if (!PyErr_ExceptionMatches(PyExc_KeyError))
+ goto error;
PyErr_Clear();
}
}
- if (x == NULL) {
- x = PyDict_GetItem(f->f_globals, w);
- Py_XINCREF(x);
- if (x == NULL) {
+ if (v == NULL) {
+ v = PyDict_GetItem(f->f_globals, name);
+ Py_XINCREF(v);
+ if (v == NULL) {
if (PyDict_CheckExact(f->f_builtins)) {
- x = PyDict_GetItem(f->f_builtins, w);
- if (x == NULL) {
+ v = PyDict_GetItem(f->f_builtins, name);
+ if (v == NULL) {
format_exc_check_arg(
PyExc_NameError,
- NAME_ERROR_MSG, w);
- break;
+ NAME_ERROR_MSG, name);
+ goto error;
}
- Py_INCREF(x);
+ Py_INCREF(v);
}
else {
- x = PyObject_GetItem(f->f_builtins, w);
- if (x == NULL) {
+ v = PyObject_GetItem(f->f_builtins, name);
+ if (v == NULL) {
if (PyErr_ExceptionMatches(PyExc_KeyError))
format_exc_check_arg(
PyExc_NameError,
- NAME_ERROR_MSG, w);
- break;
+ NAME_ERROR_MSG, name);
+ goto error;
}
}
}
}
- PUSH(x);
+ PUSH(v);
DISPATCH();
+ }
- TARGET(LOAD_GLOBAL)
- w = GETITEM(names, oparg);
+ TARGET(LOAD_GLOBAL) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *v;
if (PyDict_CheckExact(f->f_globals)
&& PyDict_CheckExact(f->f_builtins)) {
- x = _PyDict_LoadGlobal((PyDictObject *)f->f_globals,
+ v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals,
(PyDictObject *)f->f_builtins,
- w);
- if (x == NULL) {
+ name);
+ if (v == NULL) {
if (!_PyErr_OCCURRED())
format_exc_check_arg(PyExc_NameError,
- GLOBAL_NAME_ERROR_MSG, w);
- break;
+ NAME_ERROR_MSG, name);
+ goto error;
}
- Py_INCREF(x);
+ Py_INCREF(v);
}
else {
/* Slow-path if globals or builtins is not a dict */
- x = PyObject_GetItem(f->f_globals, w);
- if (x == NULL) {
- x = PyObject_GetItem(f->f_builtins, w);
- if (x == NULL) {
+ v = PyObject_GetItem(f->f_globals, name);
+ if (v == NULL) {
+ v = PyObject_GetItem(f->f_builtins, name);
+ if (v == NULL) {
if (PyErr_ExceptionMatches(PyExc_KeyError))
format_exc_check_arg(
PyExc_NameError,
- GLOBAL_NAME_ERROR_MSG, w);
- break;
+ NAME_ERROR_MSG, name);
+ goto error;
}
}
}
- PUSH(x);
+ PUSH(v);
DISPATCH();
+ }
- TARGET(DELETE_FAST)
- x = GETLOCAL(oparg);
- if (x != NULL) {
+ TARGET(DELETE_FAST) {
+ PyObject *v = GETLOCAL(oparg);
+ if (v != NULL) {
SETLOCAL(oparg, NULL);
DISPATCH();
}
@@ -2162,252 +2246,312 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
UNBOUNDLOCAL_ERROR_MSG,
PyTuple_GetItem(co->co_varnames, oparg)
);
- break;
+ goto error;
+ }
- TARGET(DELETE_DEREF)
- x = freevars[oparg];
- if (PyCell_GET(x) != NULL) {
- PyCell_Set(x, NULL);
+ TARGET(DELETE_DEREF) {
+ PyObject *cell = freevars[oparg];
+ if (PyCell_GET(cell) != NULL) {
+ PyCell_Set(cell, NULL);
DISPATCH();
}
- err = -1;
format_exc_unbound(co, oparg);
- break;
+ goto error;
+ }
- TARGET(LOAD_CLOSURE)
- x = freevars[oparg];
- Py_INCREF(x);
- PUSH(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(LOAD_CLOSURE) {
+ PyObject *cell = freevars[oparg];
+ Py_INCREF(cell);
+ PUSH(cell);
+ DISPATCH();
+ }
- TARGET(LOAD_DEREF)
- x = freevars[oparg];
- w = PyCell_Get(x);
- if (w != NULL) {
- PUSH(w);
- DISPATCH();
+ TARGET(LOAD_CLASSDEREF) {
+ PyObject *name, *value, *locals = f->f_locals;
+ Py_ssize_t idx;
+ assert(locals);
+ assert(oparg >= PyTuple_GET_SIZE(co->co_cellvars));
+ idx = oparg - PyTuple_GET_SIZE(co->co_cellvars);
+ assert(idx >= 0 && idx < PyTuple_GET_SIZE(co->co_freevars));
+ name = PyTuple_GET_ITEM(co->co_freevars, idx);
+ if (PyDict_CheckExact(locals)) {
+ value = PyDict_GetItem(locals, name);
+ Py_XINCREF(value);
}
- err = -1;
- format_exc_unbound(co, oparg);
- break;
+ else {
+ value = PyObject_GetItem(locals, name);
+ if (value == NULL && PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(PyExc_KeyError))
+ goto error;
+ PyErr_Clear();
+ }
+ }
+ if (!value) {
+ PyObject *cell = freevars[oparg];
+ value = PyCell_GET(cell);
+ if (value == NULL) {
+ format_exc_unbound(co, oparg);
+ goto error;
+ }
+ Py_INCREF(value);
+ }
+ PUSH(value);
+ DISPATCH();
+ }
- TARGET(STORE_DEREF)
- w = POP();
- x = freevars[oparg];
- PyCell_Set(x, w);
- Py_DECREF(w);
+ TARGET(LOAD_DEREF) {
+ PyObject *cell = freevars[oparg];
+ PyObject *value = PyCell_GET(cell);
+ if (value == NULL) {
+ format_exc_unbound(co, oparg);
+ goto error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
DISPATCH();
+ }
- TARGET(BUILD_TUPLE)
- x = PyTuple_New(oparg);
- if (x != NULL) {
- for (; --oparg >= 0;) {
- w = POP();
- PyTuple_SET_ITEM(x, oparg, w);
- }
- PUSH(x);
- DISPATCH();
+ TARGET(STORE_DEREF) {
+ PyObject *v = POP();
+ PyObject *cell = freevars[oparg];
+ PyCell_Set(cell, v);
+ Py_DECREF(v);
+ DISPATCH();
+ }
+
+ TARGET(BUILD_TUPLE) {
+ PyObject *tup = PyTuple_New(oparg);
+ if (tup == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ PyTuple_SET_ITEM(tup, oparg, item);
}
- break;
+ PUSH(tup);
+ DISPATCH();
+ }
- TARGET(BUILD_LIST)
- x = PyList_New(oparg);
- if (x != NULL) {
- for (; --oparg >= 0;) {
- w = POP();
- PyList_SET_ITEM(x, oparg, w);
- }
- PUSH(x);
- DISPATCH();
+ TARGET(BUILD_LIST) {
+ PyObject *list = PyList_New(oparg);
+ if (list == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ PyList_SET_ITEM(list, oparg, item);
}
- break;
+ PUSH(list);
+ DISPATCH();
+ }
- TARGET(BUILD_SET)
- x = PySet_New(NULL);
- if (x != NULL) {
- for (; --oparg >= 0;) {
- w = POP();
- if (err == 0)
- err = PySet_Add(x, w);
- Py_DECREF(w);
- }
- if (err != 0) {
- Py_DECREF(x);
- break;
- }
- PUSH(x);
- DISPATCH();
+ TARGET(BUILD_SET) {
+ PyObject *set = PySet_New(NULL);
+ int err = 0;
+ if (set == NULL)
+ goto error;
+ while (--oparg >= 0) {
+ PyObject *item = POP();
+ if (err == 0)
+ err = PySet_Add(set, item);
+ Py_DECREF(item);
}
- break;
+ if (err != 0) {
+ Py_DECREF(set);
+ goto error;
+ }
+ PUSH(set);
+ DISPATCH();
+ }
- TARGET(BUILD_MAP)
- x = _PyDict_NewPresized((Py_ssize_t)oparg);
- PUSH(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(BUILD_MAP) {
+ PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
+ if (map == NULL)
+ goto error;
+ PUSH(map);
+ DISPATCH();
+ }
- TARGET(STORE_MAP)
- w = TOP(); /* key */
- u = SECOND(); /* value */
- v = THIRD(); /* dict */
+ TARGET(STORE_MAP) {
+ PyObject *key = TOP();
+ PyObject *value = SECOND();
+ PyObject *map = THIRD();
+ int err;
STACKADJ(-2);
- assert (PyDict_CheckExact(v));
- err = PyDict_SetItem(v, w, u); /* v[w] = u */
- Py_DECREF(u);
- Py_DECREF(w);
- if (err == 0) DISPATCH();
- break;
+ assert(PyDict_CheckExact(map));
+ err = PyDict_SetItem(map, key, value);
+ Py_DECREF(value);
+ Py_DECREF(key);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(MAP_ADD)
- w = TOP(); /* key */
- u = SECOND(); /* value */
+ TARGET(MAP_ADD) {
+ PyObject *key = TOP();
+ PyObject *value = SECOND();
+ PyObject *map;
+ int err;
STACKADJ(-2);
- v = stack_pointer[-oparg]; /* dict */
- assert (PyDict_CheckExact(v));
- err = PyDict_SetItem(v, w, u); /* v[w] = u */
- Py_DECREF(u);
- Py_DECREF(w);
- if (err == 0) {
- PREDICT(JUMP_ABSOLUTE);
- DISPATCH();
- }
- break;
+ map = stack_pointer[-oparg]; /* dict */
+ assert(PyDict_CheckExact(map));
+ err = PyDict_SetItem(map, key, value); /* v[w] = u */
+ Py_DECREF(value);
+ Py_DECREF(key);
+ if (err != 0)
+ goto error;
+ PREDICT(JUMP_ABSOLUTE);
+ DISPATCH();
+ }
- TARGET(LOAD_ATTR)
- w = GETITEM(names, oparg);
- v = TOP();
- x = PyObject_GetAttr(v, w);
- Py_DECREF(v);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ TARGET(LOAD_ATTR) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *owner = TOP();
+ PyObject *res = PyObject_GetAttr(owner, name);
+ Py_DECREF(owner);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(COMPARE_OP)
- w = POP();
- v = TOP();
- x = cmp_outcome(oparg, v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- SET_TOP(x);
- if (x == NULL) break;
+ TARGET(COMPARE_OP) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = cmp_outcome(oparg, left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
PREDICT(POP_JUMP_IF_FALSE);
PREDICT(POP_JUMP_IF_TRUE);
DISPATCH();
+ }
- TARGET(IMPORT_NAME)
- {
+ TARGET(IMPORT_NAME) {
_Py_IDENTIFIER(__import__);
- w = GETITEM(names, oparg);
- x = _PyDict_GetItemId(f->f_builtins, &PyId___import__);
- if (x == NULL) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *func = _PyDict_GetItemId(f->f_builtins, &PyId___import__);
+ PyObject *from, *level, *args, *res;
+ if (func == NULL) {
PyErr_SetString(PyExc_ImportError,
"__import__ not found");
- break;
+ goto error;
}
- Py_INCREF(x);
- v = POP();
- u = TOP();
- if (PyLong_AsLong(u) != -1 || PyErr_Occurred())
- w = PyTuple_Pack(5,
- w,
+ Py_INCREF(func);
+ from = POP();
+ level = TOP();
+ if (PyLong_AsLong(level) != -1 || PyErr_Occurred())
+ args = PyTuple_Pack(5,
+ name,
f->f_globals,
f->f_locals == NULL ?
Py_None : f->f_locals,
- v,
- u);
+ from,
+ level);
else
- w = PyTuple_Pack(4,
- w,
+ args = PyTuple_Pack(4,
+ name,
f->f_globals,
f->f_locals == NULL ?
Py_None : f->f_locals,
- v);
- Py_DECREF(v);
- Py_DECREF(u);
- if (w == NULL) {
- u = POP();
- Py_DECREF(x);
- x = NULL;
- break;
+ from);
+ Py_DECREF(level);
+ Py_DECREF(from);
+ if (args == NULL) {
+ Py_DECREF(func);
+ STACKADJ(-1);
+ goto error;
}
READ_TIMESTAMP(intr0);
- v = x;
- x = PyEval_CallObject(v, w);
- Py_DECREF(v);
+ res = PyEval_CallObject(func, args);
READ_TIMESTAMP(intr1);
- Py_DECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ Py_DECREF(args);
+ Py_DECREF(func);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
}
- TARGET(IMPORT_STAR)
- v = POP();
- PyFrame_FastToLocals(f);
- if ((x = f->f_locals) == NULL) {
+ TARGET(IMPORT_STAR) {
+ PyObject *from = POP(), *locals;
+ int err;
+ if (PyFrame_FastToLocalsWithError(f) < 0)
+ goto error;
+
+ locals = f->f_locals;
+ if (locals == NULL) {
PyErr_SetString(PyExc_SystemError,
"no locals found during 'import *'");
- break;
+ goto error;
}
READ_TIMESTAMP(intr0);
- err = import_all_from(x, v);
+ err = import_all_from(locals, from);
READ_TIMESTAMP(intr1);
PyFrame_LocalsToFast(f, 0);
- Py_DECREF(v);
- if (err == 0) DISPATCH();
- break;
+ Py_DECREF(from);
+ if (err != 0)
+ goto error;
+ DISPATCH();
+ }
- TARGET(IMPORT_FROM)
- w = GETITEM(names, oparg);
- v = TOP();
+ TARGET(IMPORT_FROM) {
+ PyObject *name = GETITEM(names, oparg);
+ PyObject *from = TOP();
+ PyObject *res;
READ_TIMESTAMP(intr0);
- x = import_from(v, w);
+ res = import_from(from, name);
READ_TIMESTAMP(intr1);
- PUSH(x);
- if (x != NULL) DISPATCH();
- break;
+ PUSH(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(JUMP_FORWARD)
+ TARGET(JUMP_FORWARD) {
JUMPBY(oparg);
FAST_DISPATCH();
+ }
PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE);
- TARGET(POP_JUMP_IF_FALSE)
- w = POP();
- if (w == Py_True) {
- Py_DECREF(w);
+ TARGET(POP_JUMP_IF_FALSE) {
+ PyObject *cond = POP();
+ int err;
+ if (cond == Py_True) {
+ Py_DECREF(cond);
FAST_DISPATCH();
}
- if (w == Py_False) {
- Py_DECREF(w);
+ if (cond == Py_False) {
+ Py_DECREF(cond);
JUMPTO(oparg);
FAST_DISPATCH();
}
- err = PyObject_IsTrue(w);
- Py_DECREF(w);
+ err = PyObject_IsTrue(cond);
+ Py_DECREF(cond);
if (err > 0)
err = 0;
else if (err == 0)
JUMPTO(oparg);
else
- break;
+ goto error;
DISPATCH();
+ }
PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE);
- TARGET(POP_JUMP_IF_TRUE)
- w = POP();
- if (w == Py_False) {
- Py_DECREF(w);
+ TARGET(POP_JUMP_IF_TRUE) {
+ PyObject *cond = POP();
+ int err;
+ if (cond == Py_False) {
+ Py_DECREF(cond);
FAST_DISPATCH();
}
- if (w == Py_True) {
- Py_DECREF(w);
+ if (cond == Py_True) {
+ Py_DECREF(cond);
JUMPTO(oparg);
FAST_DISPATCH();
}
- err = PyObject_IsTrue(w);
- Py_DECREF(w);
+ err = PyObject_IsTrue(cond);
+ Py_DECREF(cond);
if (err > 0) {
err = 0;
JUMPTO(oparg);
@@ -2415,58 +2559,63 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
else if (err == 0)
;
else
- break;
+ goto error;
DISPATCH();
+ }
- TARGET(JUMP_IF_FALSE_OR_POP)
- w = TOP();
- if (w == Py_True) {
+ TARGET(JUMP_IF_FALSE_OR_POP) {
+ PyObject *cond = TOP();
+ int err;
+ if (cond == Py_True) {
STACKADJ(-1);
- Py_DECREF(w);
+ Py_DECREF(cond);
FAST_DISPATCH();
}
- if (w == Py_False) {
+ if (cond == Py_False) {
JUMPTO(oparg);
FAST_DISPATCH();
}
- err = PyObject_IsTrue(w);
+ err = PyObject_IsTrue(cond);
if (err > 0) {
STACKADJ(-1);
- Py_DECREF(w);
+ Py_DECREF(cond);
err = 0;
}
else if (err == 0)
JUMPTO(oparg);
else
- break;
+ goto error;
DISPATCH();
+ }
- TARGET(JUMP_IF_TRUE_OR_POP)
- w = TOP();
- if (w == Py_False) {
+ TARGET(JUMP_IF_TRUE_OR_POP) {
+ PyObject *cond = TOP();
+ int err;
+ if (cond == Py_False) {
STACKADJ(-1);
- Py_DECREF(w);
+ Py_DECREF(cond);
FAST_DISPATCH();
}
- if (w == Py_True) {
+ if (cond == Py_True) {
JUMPTO(oparg);
FAST_DISPATCH();
}
- err = PyObject_IsTrue(w);
+ err = PyObject_IsTrue(cond);
if (err > 0) {
err = 0;
JUMPTO(oparg);
}
else if (err == 0) {
STACKADJ(-1);
- Py_DECREF(w);
+ Py_DECREF(cond);
}
else
- break;
+ goto error;
DISPATCH();
+ }
PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
- TARGET(JUMP_ABSOLUTE)
+ TARGET(JUMP_ABSOLUTE) {
JUMPTO(oparg);
#if FAST_LOOPS
/* Enabling this path speeds-up all while and for-loops by bypassing
@@ -2480,60 +2629,62 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
#else
DISPATCH();
#endif
+ }
- TARGET(GET_ITER)
+ TARGET(GET_ITER) {
/* before: [obj]; after [getiter(obj)] */
- v = TOP();
- x = PyObject_GetIter(v);
- Py_DECREF(v);
- if (x != NULL) {
- SET_TOP(x);
- PREDICT(FOR_ITER);
- DISPATCH();
- }
- STACKADJ(-1);
- break;
+ PyObject *iterable = TOP();
+ PyObject *iter = PyObject_GetIter(iterable);
+ Py_DECREF(iterable);
+ SET_TOP(iter);
+ if (iter == NULL)
+ goto error;
+ PREDICT(FOR_ITER);
+ DISPATCH();
+ }
PREDICTED_WITH_ARG(FOR_ITER);
- TARGET(FOR_ITER)
+ TARGET(FOR_ITER) {
/* before: [iter]; after: [iter, iter()] *or* [] */
- v = TOP();
- x = (*v->ob_type->tp_iternext)(v);
- if (x != NULL) {
- PUSH(x);
+ PyObject *iter = TOP();
+ PyObject *next = (*iter->ob_type->tp_iternext)(iter);
+ if (next != NULL) {
+ PUSH(next);
PREDICT(STORE_FAST);
PREDICT(UNPACK_SEQUENCE);
DISPATCH();
}
if (PyErr_Occurred()) {
- if (!PyErr_ExceptionMatches(
- PyExc_StopIteration))
- break;
+ if (!PyErr_ExceptionMatches(PyExc_StopIteration))
+ goto error;
+ else if (tstate->c_tracefunc != NULL)
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f);
PyErr_Clear();
}
/* iterator ended normally */
- x = v = POP();
- Py_DECREF(v);
+ STACKADJ(-1);
+ Py_DECREF(iter);
JUMPBY(oparg);
DISPATCH();
+ }
- TARGET(BREAK_LOOP)
+ TARGET(BREAK_LOOP) {
why = WHY_BREAK;
goto fast_block_end;
+ }
- TARGET(CONTINUE_LOOP)
+ TARGET(CONTINUE_LOOP) {
retval = PyLong_FromLong(oparg);
- if (!retval) {
- x = NULL;
- break;
- }
+ if (retval == NULL)
+ goto error;
why = WHY_CONTINUE;
goto fast_block_end;
+ }
TARGET_WITH_IMPL(SETUP_LOOP, _setup_finally)
TARGET_WITH_IMPL(SETUP_EXCEPT, _setup_finally)
TARGET(SETUP_FINALLY)
- _setup_finally:
+ _setup_finally: {
/* NOTE: If you add any new block-setup opcodes that
are not try/except/finally handlers, you may need
to update the PyGen_NeedsFinalizing() function.
@@ -2542,37 +2693,35 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
STACK_LEVEL());
DISPATCH();
+ }
- TARGET(SETUP_WITH)
- {
+ TARGET(SETUP_WITH) {
_Py_IDENTIFIER(__exit__);
_Py_IDENTIFIER(__enter__);
- w = TOP();
- x = special_lookup(w, &PyId___exit__);
- if (!x)
- break;
- SET_TOP(x);
- u = special_lookup(w, &PyId___enter__);
- Py_DECREF(w);
- if (!u) {
- x = NULL;
- break;
- }
- x = PyObject_CallFunctionObjArgs(u, NULL);
- Py_DECREF(u);
- if (!x)
- break;
+ PyObject *mgr = TOP();
+ PyObject *exit = special_lookup(mgr, &PyId___exit__), *enter;
+ PyObject *res;
+ if (exit == NULL)
+ goto error;
+ SET_TOP(exit);
+ enter = special_lookup(mgr, &PyId___enter__);
+ Py_DECREF(mgr);
+ if (enter == NULL)
+ goto error;
+ res = PyObject_CallFunctionObjArgs(enter, NULL);
+ Py_DECREF(enter);
+ if (res == NULL)
+ goto error;
/* Setup the finally block before pushing the result
of __enter__ on the stack. */
PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
STACK_LEVEL());
- PUSH(x);
+ PUSH(res);
DISPATCH();
}
- TARGET(WITH_CLEANUP)
- {
+ TARGET(WITH_CLEANUP) {
/* At the top of the stack are 1-6 values indicating
how/why we entered the finally clause:
- TOP = None
@@ -2599,42 +2748,42 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
*/
PyObject *exit_func;
- u = TOP();
- if (u == Py_None) {
+ PyObject *exc = TOP(), *val = Py_None, *tb = Py_None, *res;
+ int err;
+ if (exc == Py_None) {
(void)POP();
exit_func = TOP();
- SET_TOP(u);
- v = w = Py_None;
+ SET_TOP(exc);
}
- else if (PyLong_Check(u)) {
- (void)POP();
- switch(PyLong_AsLong(u)) {
+ else if (PyLong_Check(exc)) {
+ STACKADJ(-1);
+ switch (PyLong_AsLong(exc)) {
case WHY_RETURN:
case WHY_CONTINUE:
/* Retval in TOP. */
exit_func = SECOND();
SET_SECOND(TOP());
- SET_TOP(u);
+ SET_TOP(exc);
break;
default:
exit_func = TOP();
- SET_TOP(u);
+ SET_TOP(exc);
break;
}
- u = v = w = Py_None;
+ exc = Py_None;
}
else {
- PyObject *tp, *exc, *tb;
+ PyObject *tp2, *exc2, *tb2;
PyTryBlock *block;
- v = SECOND();
- w = THIRD();
- tp = FOURTH();
- exc = PEEK(5);
- tb = PEEK(6);
+ val = SECOND();
+ tb = THIRD();
+ tp2 = FOURTH();
+ exc2 = PEEK(5);
+ tb2 = PEEK(6);
exit_func = PEEK(7);
- SET_VALUE(7, tb);
- SET_VALUE(6, exc);
- SET_VALUE(5, tp);
+ SET_VALUE(7, tb2);
+ SET_VALUE(6, exc2);
+ SET_VALUE(5, tp2);
/* UNWIND_EXCEPT_HANDLER will pop this off. */
SET_FOURTH(NULL);
/* We just shifted the stack down, so we have
@@ -2645,56 +2794,53 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
block->b_level--;
}
/* XXX Not the fastest way to call it... */
- x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
- NULL);
+ res = PyObject_CallFunctionObjArgs(exit_func, exc, val, tb, NULL);
Py_DECREF(exit_func);
- if (x == NULL)
- break; /* Go to error exit */
+ if (res == NULL)
+ goto error;
- if (u != Py_None)
- err = PyObject_IsTrue(x);
+ if (exc != Py_None)
+ err = PyObject_IsTrue(res);
else
err = 0;
- Py_DECREF(x);
+ Py_DECREF(res);
if (err < 0)
- break; /* Go to error exit */
+ goto error;
else if (err > 0) {
err = 0;
/* There was an exception and a True return */
PUSH(PyLong_FromLong((long) WHY_SILENCED));
}
PREDICT(END_FINALLY);
- break;
+ DISPATCH();
}
- TARGET(CALL_FUNCTION)
- {
- PyObject **sp;
+ TARGET(CALL_FUNCTION) {
+ PyObject **sp, *res;
PCALL(PCALL_ALL);
sp = stack_pointer;
#ifdef WITH_TSC
- x = call_function(&sp, oparg, &intr0, &intr1);
+ res = call_function(&sp, oparg, &intr0, &intr1);
#else
- x = call_function(&sp, oparg);
+ res = call_function(&sp, oparg);
#endif
stack_pointer = sp;
- PUSH(x);
- if (x != NULL)
- DISPATCH();
- break;
+ PUSH(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
}
TARGET_WITH_IMPL(CALL_FUNCTION_VAR, _call_function_var_kw)
TARGET_WITH_IMPL(CALL_FUNCTION_KW, _call_function_var_kw)
TARGET(CALL_FUNCTION_VAR_KW)
- _call_function_var_kw:
- {
+ _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, **sp;
+ PyObject **pfunc, *func, **sp, *res;
PCALL(PCALL_ALL);
if (flags & CALL_FLAG_VAR)
n++;
@@ -2717,137 +2863,156 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
Py_INCREF(func);
sp = stack_pointer;
READ_TIMESTAMP(intr0);
- x = ext_do_call(func, &sp, flags, na, nk);
+ res = ext_do_call(func, &sp, flags, na, nk);
READ_TIMESTAMP(intr1);
stack_pointer = sp;
Py_DECREF(func);
while (stack_pointer > pfunc) {
- w = POP();
- Py_DECREF(w);
+ PyObject *o = POP();
+ Py_DECREF(o);
}
- PUSH(x);
- if (x != NULL)
- DISPATCH();
- break;
+ PUSH(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
}
TARGET_WITH_IMPL(MAKE_CLOSURE, _make_function)
TARGET(MAKE_FUNCTION)
- _make_function:
- {
+ _make_function: {
int posdefaults = oparg & 0xff;
int kwdefaults = (oparg>>8) & 0xff;
int num_annotations = (oparg >> 16) & 0x7fff;
- w = POP(); /* qualname */
- v = POP(); /* code object */
- x = PyFunction_NewWithQualName(v, f->f_globals, w);
- Py_DECREF(v);
- Py_DECREF(w);
+ PyObject *qualname = POP(); /* qualname */
+ PyObject *code = POP(); /* code object */
+ PyObject *func = PyFunction_NewWithQualName(code, f->f_globals, qualname);
+ Py_DECREF(code);
+ Py_DECREF(qualname);
- if (x != NULL && opcode == MAKE_CLOSURE) {
- v = POP();
- if (PyFunction_SetClosure(x, v) != 0) {
+ if (func == NULL)
+ goto error;
+
+ if (opcode == MAKE_CLOSURE) {
+ PyObject *closure = POP();
+ if (PyFunction_SetClosure(func, closure) != 0) {
/* Can't happen unless bytecode is corrupt. */
- why = WHY_EXCEPTION;
+ Py_DECREF(func);
+ Py_DECREF(closure);
+ goto error;
}
- Py_DECREF(v);
+ Py_DECREF(closure);
}
- if (x != NULL && num_annotations > 0) {
+ if (num_annotations > 0) {
Py_ssize_t name_ix;
- u = POP(); /* names of args with annotations */
- v = PyDict_New();
- if (v == NULL) {
- Py_DECREF(x);
- x = NULL;
- break;
+ PyObject *names = POP(); /* names of args with annotations */
+ PyObject *anns = PyDict_New();
+ if (anns == NULL) {
+ Py_DECREF(func);
+ goto error;
}
- name_ix = PyTuple_Size(u);
+ name_ix = PyTuple_Size(names);
assert(num_annotations == name_ix+1);
while (name_ix > 0) {
+ PyObject *name, *value;
+ int err;
--name_ix;
- t = PyTuple_GET_ITEM(u, name_ix);
- w = POP();
- /* XXX(nnorwitz): check for errors */
- PyDict_SetItem(v, t, w);
- Py_DECREF(w);
+ name = PyTuple_GET_ITEM(names, name_ix);
+ value = POP();
+ err = PyDict_SetItem(anns, name, value);
+ Py_DECREF(value);
+ if (err != 0) {
+ Py_DECREF(anns);
+ Py_DECREF(func);
+ goto error;
+ }
}
- if (PyFunction_SetAnnotations(x, v) != 0) {
+ if (PyFunction_SetAnnotations(func, anns) != 0) {
/* Can't happen unless
PyFunction_SetAnnotations changes. */
- why = WHY_EXCEPTION;
+ Py_DECREF(anns);
+ Py_DECREF(func);
+ goto error;
}
- Py_DECREF(v);
- Py_DECREF(u);
+ Py_DECREF(anns);
+ Py_DECREF(names);
}
/* XXX Maybe this should be a separate opcode? */
- if (x != NULL && posdefaults > 0) {
- v = PyTuple_New(posdefaults);
- if (v == NULL) {
- Py_DECREF(x);
- x = NULL;
- break;
+ if (kwdefaults > 0) {
+ PyObject *defs = PyDict_New();
+ if (defs == NULL) {
+ Py_DECREF(func);
+ goto error;
}
- while (--posdefaults >= 0) {
- w = POP();
- PyTuple_SET_ITEM(v, posdefaults, w);
+ while (--kwdefaults >= 0) {
+ PyObject *v = POP(); /* default value */
+ PyObject *key = POP(); /* kw only arg name */
+ int err = PyDict_SetItem(defs, key, v);
+ Py_DECREF(v);
+ Py_DECREF(key);
+ if (err != 0) {
+ Py_DECREF(defs);
+ Py_DECREF(func);
+ goto error;
+ }
}
- if (PyFunction_SetDefaults(x, v) != 0) {
+ if (PyFunction_SetKwDefaults(func, defs) != 0) {
/* Can't happen unless
- PyFunction_SetDefaults changes. */
- why = WHY_EXCEPTION;
+ PyFunction_SetKwDefaults changes. */
+ Py_DECREF(func);
+ Py_DECREF(defs);
+ goto error;
}
- Py_DECREF(v);
+ Py_DECREF(defs);
}
- if (x != NULL && kwdefaults > 0) {
- v = PyDict_New();
- if (v == NULL) {
- Py_DECREF(x);
- x = NULL;
- break;
+ if (posdefaults > 0) {
+ PyObject *defs = PyTuple_New(posdefaults);
+ if (defs == NULL) {
+ Py_DECREF(func);
+ goto error;
}
- while (--kwdefaults >= 0) {
- w = POP(); /* default value */
- u = POP(); /* kw only arg name */
- /* XXX(nnorwitz): check for errors */
- PyDict_SetItem(v, u, w);
- Py_DECREF(w);
- Py_DECREF(u);
- }
- if (PyFunction_SetKwDefaults(x, v) != 0) {
+ while (--posdefaults >= 0)
+ PyTuple_SET_ITEM(defs, posdefaults, POP());
+ if (PyFunction_SetDefaults(func, defs) != 0) {
/* Can't happen unless
- PyFunction_SetKwDefaults changes. */
- why = WHY_EXCEPTION;
+ PyFunction_SetDefaults changes. */
+ Py_DECREF(defs);
+ Py_DECREF(func);
+ goto error;
}
- Py_DECREF(v);
+ Py_DECREF(defs);
}
- PUSH(x);
- break;
+ PUSH(func);
+ DISPATCH();
}
- TARGET(BUILD_SLICE)
+ TARGET(BUILD_SLICE) {
+ PyObject *start, *stop, *step, *slice;
if (oparg == 3)
- w = POP();
+ step = POP();
else
- w = NULL;
- v = POP();
- u = TOP();
- x = PySlice_New(u, v, w);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_XDECREF(w);
- SET_TOP(x);
- if (x != NULL) DISPATCH();
- break;
+ step = NULL;
+ stop = POP();
+ start = TOP();
+ slice = PySlice_New(start, stop, step);
+ Py_DECREF(start);
+ Py_DECREF(stop);
+ Py_XDECREF(step);
+ SET_TOP(slice);
+ if (slice == NULL)
+ goto error;
+ DISPATCH();
+ }
- TARGET(EXTENDED_ARG)
+ TARGET(EXTENDED_ARG) {
opcode = NEXTOP();
oparg = oparg<<16 | NEXTARG();
goto dispatch_opcode;
+ }
#if USE_COMPUTED_GOTOS
_unknown_opcode:
@@ -2858,8 +3023,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
PyFrame_GetLineNumber(f),
opcode);
PyErr_SetString(PyExc_SystemError, "unknown opcode");
- why = WHY_EXCEPTION;
- break;
+ goto error;
#ifdef CASE_TOO_BIG
}
@@ -2867,71 +3031,35 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
} /* switch */
- on_error:
+ /* This should never be reached. Every opcode should end with DISPATCH()
+ or goto error. */
+ assert(0);
+error:
READ_TIMESTAMP(inst1);
- /* Quickly continue if no error occurred */
-
- if (why == WHY_NOT) {
- if (err == 0 && x != NULL) {
-#ifdef CHECKEXC
- /* This check is expensive! */
- if (PyErr_Occurred())
- fprintf(stderr,
- "XXX undetected error\n");
- else {
-#endif
- READ_TIMESTAMP(loop1);
- continue; /* Normal, fast path */
-#ifdef CHECKEXC
- }
-#endif
- }
- why = WHY_EXCEPTION;
- x = Py_None;
- err = 0;
- }
-
- /* Double-check exception status */
+ assert(why == WHY_NOT);
+ why = WHY_EXCEPTION;
- if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_SystemError,
- "error return without exception set");
- why = WHY_EXCEPTION;
- }
- }
-#ifdef CHECKEXC
- else {
- /* This check is expensive! */
- if (PyErr_Occurred()) {
- char buf[128];
- sprintf(buf, "Stack unwind with exception "
- "set and why=%d", why);
- Py_FatalError(buf);
- }
- }
+ /* Double-check exception status. */
+#ifdef NDEBUG
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError,
+ "error return without exception set");
+#else
+ assert(PyErr_Occurred());
#endif
- /* Log traceback info if this is a real exception */
-
- if (why == WHY_EXCEPTION) {
- PyTraceBack_Here(f);
-
- if (tstate->c_tracefunc != NULL)
- call_exc_trace(tstate->c_tracefunc,
- tstate->c_traceobj, f);
- }
+ /* Log traceback info. */
+ PyTraceBack_Here(f);
- /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
+ if (tstate->c_tracefunc != NULL)
+ call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f);
- if (why == WHY_RERAISE)
- why = WHY_EXCEPTION;
+fast_block_end:
+ assert(why != WHY_NOT);
/* Unwind stacks if a (pseudo) exception occurred */
-
-fast_block_end:
while (why != WHY_NOT && f->f_iblock > 0) {
/* Peek at the current block. */
PyTryBlock *b = &f->f_blockstack[f->f_iblock - 1];
@@ -2978,7 +3106,10 @@ fast_block_end:
Python main loop. */
PyErr_NormalizeException(
&exc, &val, &tb);
- PyException_SetTraceback(val, tb);
+ if (tb != NULL)
+ PyException_SetTraceback(val, tb);
+ else
+ PyException_SetTraceback(val, Py_None);
Py_INCREF(exc);
tstate->exc_type = exc;
Py_INCREF(val);
@@ -3010,18 +3141,23 @@ fast_block_end:
break;
READ_TIMESTAMP(loop1);
+ assert(!PyErr_Occurred());
+
} /* main loop */
assert(why != WHY_YIELD);
/* Pop remaining stack entries. */
while (!EMPTY()) {
- v = POP();
- Py_XDECREF(v);
+ PyObject *o = POP();
+ Py_XDECREF(o);
}
if (why != WHY_RETURN)
retval = NULL;
+ assert((retval != NULL && !PyErr_Occurred())
+ || (retval == NULL && PyErr_Occurred()));
+
fast_yield:
if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) {
/* The purpose of this block is to put aside the generator's exception
@@ -3078,6 +3214,7 @@ fast_yield:
/* pop frame */
exit_eval_frame:
Py_LeaveRecursiveCall();
+ f->f_executing = 0;
tstate->frame = f->f_back;
return retval;
@@ -3243,9 +3380,9 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
{
PyCodeObject* co = (PyCodeObject*)_co;
- register PyFrameObject *f;
- register PyObject *retval = NULL;
- register PyObject **fastlocals, **freevars;
+ PyFrameObject *f;
+ PyObject *retval = NULL;
+ PyObject **fastlocals, **freevars;
PyThreadState *tstate = PyThreadState_GET();
PyObject *x, *u;
int total_args = co->co_argcount + co->co_kwonlyargcount;
@@ -3522,7 +3659,7 @@ restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f)
/* Logic for the raise statement (too complicated for inlining).
This *consumes* a reference count to each of its arguments. */
-static enum why_code
+static int
do_raise(PyObject *exc, PyObject *cause)
{
PyObject *type = NULL, *value = NULL;
@@ -3537,13 +3674,13 @@ do_raise(PyObject *exc, PyObject *cause)
if (type == Py_None) {
PyErr_SetString(PyExc_RuntimeError,
"No active exception to reraise");
- return WHY_EXCEPTION;
- }
+ return 0;
+ }
Py_XINCREF(type);
Py_XINCREF(value);
Py_XINCREF(tb);
PyErr_Restore(type, value, tb);
- return WHY_RERAISE;
+ return 1;
}
/* We support the following forms of raise:
@@ -3606,13 +3743,13 @@ do_raise(PyObject *exc, PyObject *cause)
/* PyErr_SetObject incref's its arguments */
Py_XDECREF(value);
Py_XDECREF(type);
- return WHY_EXCEPTION;
+ return 0;
raise_error:
Py_XDECREF(value);
Py_XDECREF(type);
Py_XDECREF(cause);
- return WHY_EXCEPTION;
+ return 0;
}
/* Iterate v argcnt times and store the results on the stack (via decreasing
@@ -3711,27 +3848,28 @@ prtrace(PyObject *v, char *str)
static void
call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
{
- PyObject *type, *value, *traceback, *arg;
+ PyObject *type, *value, *traceback, *orig_traceback, *arg;
int err;
- PyErr_Fetch(&type, &value, &traceback);
+ PyErr_Fetch(&type, &value, &orig_traceback);
if (value == NULL) {
value = Py_None;
Py_INCREF(value);
}
- PyErr_NormalizeException(&type, &value, &traceback);
+ PyErr_NormalizeException(&type, &value, &orig_traceback);
+ traceback = (orig_traceback != NULL) ? orig_traceback : Py_None;
arg = PyTuple_Pack(3, type, value, traceback);
if (arg == NULL) {
- PyErr_Restore(type, value, traceback);
+ PyErr_Restore(type, value, orig_traceback);
return;
}
err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
Py_DECREF(arg);
if (err == 0)
- PyErr_Restore(type, value, traceback);
+ PyErr_Restore(type, value, orig_traceback);
else {
Py_XDECREF(type);
Py_XDECREF(value);
- Py_XDECREF(traceback);
+ Py_XDECREF(orig_traceback);
}
}
@@ -3760,7 +3898,7 @@ static int
call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
int what, PyObject *arg)
{
- register PyThreadState *tstate = frame->f_tstate;
+ PyThreadState *tstate = frame->f_tstate;
int result;
if (tstate->tracing)
return 0;
@@ -3871,9 +4009,15 @@ PyObject *
PyEval_GetLocals(void)
{
PyFrameObject *current_frame = PyEval_GetFrame();
- if (current_frame == NULL)
+ if (current_frame == NULL) {
+ PyErr_SetString(PyExc_SystemError, "frame does not exist");
return NULL;
- PyFrame_FastToLocals(current_frame);
+ }
+
+ if (PyFrame_FastToLocalsWithError(current_frame) < 0)
+ return NULL;
+
+ assert(current_frame->f_locals != NULL);
return current_frame->f_locals;
}
@@ -3883,8 +4027,9 @@ PyEval_GetGlobals(void)
PyFrameObject *current_frame = PyEval_GetFrame();
if (current_frame == NULL)
return NULL;
- else
- return current_frame->f_globals;
+
+ assert(current_frame->f_globals != NULL);
+ return current_frame->f_globals;
}
PyFrameObject *
@@ -3926,6 +4071,13 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
{
PyObject *result;
+#ifdef Py_DEBUG
+ /* PyEval_CallObjectWithKeywords() must not be called with an exception
+ set, because it may clear it (directly or indirectly)
+ and so the caller looses its exception */
+ assert(!PyErr_Occurred());
+#endif
+
if (arg == NULL) {
arg = PyTuple_New(0);
if (arg == NULL)
@@ -3948,6 +4100,9 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
result = PyObject_Call(func, arg, kw);
Py_DECREF(arg);
+
+ assert((result != NULL && !PyErr_Occurred())
+ || (result == NULL && PyErr_Occurred()));
return result;
}
@@ -4065,10 +4220,15 @@ call_function(PyObject ***pp_stack, int oparg
else {
PyObject *callargs;
callargs = load_args(pp_stack, na);
- READ_TIMESTAMP(*pintr0);
- C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
- READ_TIMESTAMP(*pintr1);
- Py_XDECREF(callargs);
+ if (callargs != NULL) {
+ READ_TIMESTAMP(*pintr0);
+ C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
+ READ_TIMESTAMP(*pintr1);
+ Py_XDECREF(callargs);
+ }
+ else {
+ x = NULL;
+ }
}
} else {
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
@@ -4093,6 +4253,8 @@ call_function(PyObject ***pp_stack, int oparg
READ_TIMESTAMP(*pintr1);
Py_DECREF(func);
}
+ assert((x != NULL && !PyErr_Occurred())
+ || (x == NULL && PyErr_Occurred()));
/* Clear the stack of the function object. Also removes
the arguments in case they weren't consumed already
@@ -4103,6 +4265,9 @@ call_function(PyObject ***pp_stack, int oparg
Py_DECREF(w);
PCALL(PCALL_POP);
}
+
+ assert((x != NULL && !PyErr_Occurred())
+ || (x == NULL && PyErr_Occurred()));
return x;
}
@@ -4386,6 +4551,8 @@ ext_call_fail:
Py_XDECREF(callargs);
Py_XDECREF(kwdict);
Py_XDECREF(stararg);
+ assert((result != NULL && !PyErr_Occurred())
+ || (result == NULL && PyErr_Occurred()));
return result;
}
@@ -4424,7 +4591,7 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
"BaseException is not allowed"
static PyObject *
-cmp_outcome(int op, register PyObject *v, register PyObject *w)
+cmp_outcome(int op, PyObject *v, PyObject *w)
{
int res = 0;
switch (op) {
@@ -4482,7 +4649,7 @@ import_from(PyObject *v, PyObject *name)
x = PyObject_GetAttr(v, name);
if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
- PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
+ PyErr_Format(PyExc_ImportError, "cannot import name %R", name);
}
return x;
}