--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Python/ceval.c Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,4545 @@
+
+/* Execute compiled code */
+
+/* XXX TO DO:
+ XXX speed up searching for keywords by using a dictionary
+ XXX document it!
+ */
+
+/* enable more aggressive intra-module optimizations, where available */
+#define PY_LOCAL_AGGRESSIVE
+
+#include "Python.h"
+
+#include "code.h"
+#include "frameobject.h"
+#include "eval.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#include <ctype.h>
+
+#ifndef WITH_TSC
+
+#define READ_TIMESTAMP(var)
+
+#else
+
+typedef unsigned long long uint64;
+
+#if defined(__ppc__) /* <- Don't know if this is the correct symbol; this
+ section should work for GCC on any PowerPC
+ platform, irrespective of OS.
+ POWER? Who knows :-) */
+
+#define READ_TIMESTAMP(var) ppc_getcounter(&var)
+
+static void
+ppc_getcounter(uint64 *v)
+{
+ register unsigned long tbu, tb, tbu2;
+
+ loop:
+ asm volatile ("mftbu %0" : "=r" (tbu) );
+ asm volatile ("mftb %0" : "=r" (tb) );
+ asm volatile ("mftbu %0" : "=r" (tbu2));
+ if (__builtin_expect(tbu != tbu2, 0)) goto loop;
+
+ /* The slightly peculiar way of writing the next lines is
+ compiled better by GCC than any other way I tried. */
+ ((long*)(v))[0] = tbu;
+ ((long*)(v))[1] = tb;
+}
+
+#else /* this is for linux/x86 (and probably any other GCC/x86 combo) */
+
+#define READ_TIMESTAMP(val) \
+ __asm__ __volatile__("rdtsc" : "=A" (val))
+
+#endif
+
+void dump_tsc(int opcode, int ticked, uint64 inst0, uint64 inst1,
+ uint64 loop0, uint64 loop1, uint64 intr0, uint64 intr1)
+{
+ uint64 intr, inst, loop;
+ PyThreadState *tstate = PyThreadState_Get();
+ if (!tstate->interp->tscdump)
+ return;
+ intr = intr1 - intr0;
+ inst = inst1 - inst0 - intr;
+ loop = loop1 - loop0 - intr;
+ fprintf(stderr, "opcode=%03d t=%d inst=%06lld loop=%06lld\n",
+ opcode, ticked, inst, loop);
+}
+
+#endif
+
+/* Turn this on if your compiler chokes on the big switch: */
+/* #define CASE_TOO_BIG 1 */
+
+#ifdef Py_DEBUG
+/* For debugging the interpreter: */
+#define LLTRACE 1 /* Low-level trace feature */
+#define CHECKEXC 1 /* Double-check exception checking */
+#endif
+
+typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
+
+/* Forward declarations */
+#ifdef WITH_TSC
+static PyObject * call_function(PyObject ***, int, uint64*, uint64*);
+#else
+static PyObject * call_function(PyObject ***, int);
+#endif
+static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
+static PyObject * do_call(PyObject *, PyObject ***, int, int);
+static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
+static PyObject * update_keyword_args(PyObject *, int, PyObject ***,
+ PyObject *);
+static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
+static PyObject * load_args(PyObject ***, int);
+#define CALL_FLAG_VAR 1
+#define CALL_FLAG_KW 2
+
+#ifdef LLTRACE
+static int lltrace;
+static int prtrace(PyObject *, char *);
+#endif
+static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
+ int, PyObject *);
+static int call_trace_protected(Py_tracefunc, PyObject *,
+ PyFrameObject *, int, PyObject *);
+static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
+static int maybe_call_line_trace(Py_tracefunc, PyObject *,
+ PyFrameObject *, int *, int *, int *);
+
+static PyObject * apply_slice(PyObject *, PyObject *, PyObject *);
+static int assign_slice(PyObject *, PyObject *,
+ PyObject *, PyObject *);
+static PyObject * cmp_outcome(int, PyObject *, PyObject *);
+static PyObject * import_from(PyObject *, PyObject *);
+static int import_all_from(PyObject *, PyObject *);
+static PyObject * build_class(PyObject *, PyObject *, PyObject *);
+static int exec_statement(PyFrameObject *,
+ PyObject *, PyObject *, PyObject *);
+static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
+static void reset_exc_info(PyThreadState *);
+static void format_exc_check_arg(PyObject *, char *, PyObject *);
+static PyObject * string_concatenate(PyObject *, PyObject *,
+ PyFrameObject *, unsigned char *);
+
+#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 \
+ "free variable '%.200s' referenced before assignment" \
+ " in enclosing scope"
+
+/* Dynamic execution profile */
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+static long dxpairs[257][256];
+#define dxp dxpairs[256]
+#else
+static long dxp[256];
+#endif
+#endif
+
+/* Function call profile */
+#ifdef CALL_PROFILE
+#define PCALL_NUM 11
+static int pcall[PCALL_NUM];
+
+#define PCALL_ALL 0
+#define PCALL_FUNCTION 1
+#define PCALL_FAST_FUNCTION 2
+#define PCALL_FASTER_FUNCTION 3
+#define PCALL_METHOD 4
+#define PCALL_BOUND_METHOD 5
+#define PCALL_CFUNCTION 6
+#define PCALL_TYPE 7
+#define PCALL_GENERATOR 8
+#define PCALL_OTHER 9
+#define PCALL_POP 10
+
+/* Notes about the statistics
+
+ PCALL_FAST stats
+
+ FAST_FUNCTION means no argument tuple needs to be created.
+ FASTER_FUNCTION means that the fast-path frame setup code is used.
+
+ If there is a method call where the call can be optimized by changing
+ the argument tuple and calling the function directly, it gets recorded
+ twice.
+
+ As a result, the relationship among the statistics appears to be
+ PCALL_ALL == PCALL_FUNCTION + PCALL_METHOD - PCALL_BOUND_METHOD +
+ PCALL_CFUNCTION + PCALL_TYPE + PCALL_GENERATOR + PCALL_OTHER
+ PCALL_FUNCTION > PCALL_FAST_FUNCTION > PCALL_FASTER_FUNCTION
+ PCALL_METHOD > PCALL_BOUND_METHOD
+*/
+
+#define PCALL(POS) pcall[POS]++
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+ return Py_BuildValue("iiiiiiiiiii",
+ pcall[0], pcall[1], pcall[2], pcall[3],
+ pcall[4], pcall[5], pcall[6], pcall[7],
+ pcall[8], pcall[9], pcall[10]);
+}
+#else
+#define PCALL(O)
+
+PyObject *
+PyEval_GetCallStats(PyObject *self)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
+#ifdef WITH_THREAD
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "pythread.h"
+
+static PyThread_type_lock interpreter_lock = 0; /* This is the GIL */
+static long main_thread = 0;
+
+int
+PyEval_ThreadsInitialized(void)
+{
+ return interpreter_lock != 0;
+}
+
+void
+PyEval_InitThreads(void)
+{
+ if (interpreter_lock)
+ return;
+ interpreter_lock = PyThread_allocate_lock();
+ PyThread_acquire_lock(interpreter_lock, 1);
+ main_thread = PyThread_get_thread_ident();
+}
+
+void
+PyEval_AcquireLock(void)
+{
+ PyThread_acquire_lock(interpreter_lock, 1);
+}
+
+void
+PyEval_ReleaseLock(void)
+{
+ PyThread_release_lock(interpreter_lock);
+}
+
+void
+PyEval_AcquireThread(PyThreadState *tstate)
+{
+ if (tstate == NULL)
+ Py_FatalError("PyEval_AcquireThread: NULL new thread state");
+ /* Check someone has called PyEval_InitThreads() to create the lock */
+ assert(interpreter_lock);
+ PyThread_acquire_lock(interpreter_lock, 1);
+ if (PyThreadState_Swap(tstate) != NULL)
+ Py_FatalError(
+ "PyEval_AcquireThread: non-NULL old thread state");
+}
+
+void
+PyEval_ReleaseThread(PyThreadState *tstate)
+{
+ if (tstate == NULL)
+ Py_FatalError("PyEval_ReleaseThread: NULL thread state");
+ if (PyThreadState_Swap(NULL) != tstate)
+ Py_FatalError("PyEval_ReleaseThread: wrong thread state");
+ PyThread_release_lock(interpreter_lock);
+}
+
+/* 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.) */
+
+void
+PyEval_ReInitThreads(void)
+{
+ PyObject *threading, *result;
+ PyThreadState *tstate;
+
+ if (!interpreter_lock)
+ return;
+ /*XXX Can't use PyThread_free_lock here because it does too
+ much error-checking. Doing this cleanly would require
+ adding a new function to each thread_*.h. Instead, just
+ create a new lock and waste a little bit of memory */
+ interpreter_lock = PyThread_allocate_lock();
+ PyThread_acquire_lock(interpreter_lock, 1);
+ main_thread = PyThread_get_thread_ident();
+
+ /* Update the threading module with the new state.
+ */
+ tstate = PyThreadState_GET();
+ threading = PyMapping_GetItemString(tstate->interp->modules,
+ "threading");
+ if (threading == NULL) {
+ /* threading not imported */
+ PyErr_Clear();
+ return;
+ }
+ result = PyObject_CallMethod(threading, "_after_fork", NULL);
+ if (result == NULL)
+ PyErr_WriteUnraisable(threading);
+ else
+ Py_DECREF(result);
+ Py_DECREF(threading);
+}
+#endif
+
+/* Functions save_thread and restore_thread are always defined so
+ dynamically loaded modules needn't be compiled separately for use
+ with and without threads: */
+
+PyThreadState *
+PyEval_SaveThread(void)
+{
+ PyThreadState *tstate = PyThreadState_Swap(NULL);
+ if (tstate == NULL)
+ Py_FatalError("PyEval_SaveThread: NULL tstate");
+#ifdef WITH_THREAD
+ if (interpreter_lock)
+ PyThread_release_lock(interpreter_lock);
+#endif
+ return tstate;
+}
+
+void
+PyEval_RestoreThread(PyThreadState *tstate)
+{
+ if (tstate == NULL)
+ Py_FatalError("PyEval_RestoreThread: NULL tstate");
+#ifdef WITH_THREAD
+ if (interpreter_lock) {
+ int err = errno;
+ PyThread_acquire_lock(interpreter_lock, 1);
+ errno = err;
+ }
+#endif
+ PyThreadState_Swap(tstate);
+}
+
+
+/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
+ signal handlers or Mac I/O completion routines) can schedule calls
+ to a function to be called synchronously.
+ The synchronous function is called with one void* argument.
+ It should return 0 for success or -1 for failure -- failure should
+ be accompanied by an exception.
+
+ If registry succeeds, the registry function returns 0; if it fails
+ (e.g. due to too many pending calls) it returns -1 (without setting
+ an exception condition).
+
+ Note that because registry may occur from within signal handlers,
+ or other asynchronous events, calling malloc() is unsafe!
+
+#ifdef WITH_THREAD
+ Any thread can schedule pending calls, but only the main thread
+ will execute them.
+#endif
+
+ XXX WARNING! ASYNCHRONOUSLY EXECUTING CODE!
+ There are two possible race conditions:
+ (1) nested asynchronous registry calls;
+ (2) registry calls made while pending calls are being processed.
+ While (1) is very unlikely, (2) is a real possibility.
+ The current code is safe against (2), but not against (1).
+ The safety against (2) is derived from the fact that only one
+ thread (the main thread) ever takes things out of the queue.
+
+ XXX Darn! With the advent of thread state, we should have an array
+ of pending calls per thread in the thread state! Later...
+*/
+
+#define NPENDINGCALLS 32
+static struct {
+ int (*func)(void *);
+ void *arg;
+} pendingcalls[NPENDINGCALLS];
+static volatile int pendingfirst = 0;
+static volatile int pendinglast = 0;
+static volatile int things_to_do = 0;
+
+int
+Py_AddPendingCall(int (*func)(void *), void *arg)
+{
+ static volatile int busy = 0;
+ int i, j;
+ /* XXX Begin critical section */
+ /* XXX If you want this to be safe against nested
+ XXX asynchronous calls, you'll have to work harder! */
+ if (busy)
+ return -1;
+ busy = 1;
+ i = pendinglast;
+ j = (i + 1) % NPENDINGCALLS;
+ if (j == pendingfirst) {
+ busy = 0;
+ return -1; /* Queue full */
+ }
+ pendingcalls[i].func = func;
+ pendingcalls[i].arg = arg;
+ pendinglast = j;
+
+ _Py_Ticker = 0;
+ things_to_do = 1; /* Signal main loop */
+ busy = 0;
+ /* XXX End critical section */
+ return 0;
+}
+
+int
+Py_MakePendingCalls(void)
+{
+ static int busy = 0;
+#ifdef WITH_THREAD
+ if (main_thread && PyThread_get_thread_ident() != main_thread)
+ return 0;
+#endif
+ if (busy)
+ return 0;
+ busy = 1;
+ things_to_do = 0;
+ for (;;) {
+ int i;
+ int (*func)(void *);
+ void *arg;
+ i = pendingfirst;
+ if (i == pendinglast)
+ break; /* Queue empty */
+ func = pendingcalls[i].func;
+ arg = pendingcalls[i].arg;
+ pendingfirst = (i + 1) % NPENDINGCALLS;
+ if (func(arg) < 0) {
+ busy = 0;
+ things_to_do = 1; /* We're not done yet */
+ return -1;
+ }
+ }
+ busy = 0;
+ return 0;
+}
+
+
+/* The interpreter's recursion limit */
+
+#ifndef Py_DEFAULT_RECURSION_LIMIT
+#define Py_DEFAULT_RECURSION_LIMIT 1000
+#endif
+static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
+int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
+
+int
+Py_GetRecursionLimit(void)
+{
+ return recursion_limit;
+}
+
+void
+Py_SetRecursionLimit(int new_limit)
+{
+ recursion_limit = new_limit;
+ _Py_CheckRecursionLimit = recursion_limit;
+}
+
+/* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
+ if the recursion_depth reaches _Py_CheckRecursionLimit.
+ If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
+ to guarantee that _Py_CheckRecursiveCall() is regularly called.
+ Without USE_STACKCHECK, there is no need for this. */
+int
+_Py_CheckRecursiveCall(char *where)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+
+#ifdef USE_STACKCHECK
+ if (PyOS_CheckStack()) {
+ --tstate->recursion_depth;
+ PyErr_SetString(PyExc_MemoryError, "Stack overflow");
+ return -1;
+ }
+#endif
+ if (tstate->recursion_depth > recursion_limit) {
+ --tstate->recursion_depth;
+ PyErr_Format(PyExc_RuntimeError,
+ "maximum recursion depth exceeded%s",
+ where);
+ return -1;
+ }
+ _Py_CheckRecursionLimit = recursion_limit;
+ return 0;
+}
+
+/* Status code for main loop (reason for stack unwind) */
+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 */
+ WHY_YIELD = 0x0040 /* 'yield' operator */
+};
+
+static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
+static int unpack_iterable(PyObject *, int, PyObject **);
+
+/* for manipulating the thread switch and periodic "stuff" - used to be
+ per thread, now just a pair o' globals */
+int _Py_CheckInterval = 100;
+volatile int _Py_Ticker = 100;
+
+PyObject *
+PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
+{
+ return PyEval_EvalCodeEx(co,
+ globals, locals,
+ (PyObject **)NULL, 0,
+ (PyObject **)NULL, 0,
+ (PyObject **)NULL, 0,
+ NULL);
+}
+
+
+/* Interpreter main loop */
+
+PyObject *
+PyEval_EvalFrame(PyFrameObject *f) {
+ /* This is for backward compatibility with extension modules that
+ used this API; core interpreter code should call
+ PyEval_EvalFrameEx() */
+ return PyEval_EvalFrameEx(f, 0);
+}
+
+PyObject *
+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 *stream = NULL; /* for PRINT opcodes */
+ register PyObject **fastlocals, **freevars;
+ PyObject *retval = NULL; /* Return value */
+ PyThreadState *tstate = PyThreadState_GET();
+ PyCodeObject *co;
+
+ /* when tracing we set things up so that
+
+ not (instr_lb <= current_bytecode_offset < instr_ub)
+
+ is true when the line being executed has changed. The
+ initial values are such as to make this false the first
+ time it is tested. */
+ int instr_ub = -1, instr_lb = 0, instr_prev = -1;
+
+ unsigned char *first_instr;
+ PyObject *names;
+ PyObject *consts;
+#if defined(Py_DEBUG) || defined(LLTRACE)
+ /* Make it easier to find out where we are with a debugger */
+ char *filename;
+#endif
+
+/* Tuple access macros */
+
+#ifndef Py_DEBUG
+#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
+#else
+#define GETITEM(v, i) PyTuple_GetItem((v), (i))
+#endif
+
+#ifdef WITH_TSC
+/* Use Pentium timestamp counter to mark certain events:
+ inst0 -- beginning of switch statement for opcode dispatch
+ inst1 -- end of switch statement (may be skipped)
+ loop0 -- the top of the mainloop
+ loop1 -- place where control returns again to top of mainloop
+ (may be skipped)
+ intr1 -- beginning of long interruption
+ intr2 -- end of long interruption
+
+ Many opcodes call out to helper C functions. In some cases, the
+ time in those functions should be counted towards the time for the
+ opcode, but not in all cases. For example, a CALL_FUNCTION opcode
+ calls another Python function; there's no point in charge all the
+ bytecode executed by the called function to the caller.
+
+ It's hard to make a useful judgement statically. In the presence
+ of operator overloading, it's impossible to tell if a call will
+ execute new Python code or not.
+
+ It's a case-by-case judgement. I'll use intr1 for the following
+ cases:
+
+ EXEC_STMT
+ IMPORT_STAR
+ IMPORT_FROM
+ CALL_FUNCTION (and friends)
+
+ */
+ uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
+ int ticked = 0;
+
+ READ_TIMESTAMP(inst0);
+ READ_TIMESTAMP(inst1);
+ READ_TIMESTAMP(loop0);
+ READ_TIMESTAMP(loop1);
+
+ /* shut up the compiler */
+ opcode = 0;
+#endif
+
+/* Code access macros */
+
+#define INSTR_OFFSET() ((int)(next_instr - first_instr))
+#define NEXTOP() (*next_instr++)
+#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
+#define PEEKARG() ((next_instr[2]<<8) + next_instr[1])
+#define JUMPTO(x) (next_instr = first_instr + (x))
+#define JUMPBY(x) (next_instr += (x))
+
+/* OpCode prediction macros
+ Some opcodes tend to come in pairs thus making it possible to
+ predict the second code when the first is run. For example,
+ COMPARE_OP is often followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And,
+ those opcodes are often followed by a POP_TOP.
+
+ Verifying the prediction costs a single high-speed test of a register
+ variable against a constant. If the pairing was good, then the
+ processor's own internal branch predication has a high likelihood of
+ success, resulting in a nearly zero-overhead transition to the
+ next opcode. A successful prediction saves a trip through the eval-loop
+ including its two unpredictable branches, the HAS_ARG test and the
+ switch-case. Combined with the processor's internal branch prediction,
+ a successful PREDICT has the effect of making the two opcodes run as if
+ they were a single new opcode with the bodies combined.
+
+ If collecting opcode statistics, your choices are to either keep the
+ predictions turned-on and interpret the results as if some opcodes
+ had been combined or turn-off predictions so that the opcode frequency
+ counter updates for both opcodes.
+*/
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#define PREDICT(op) if (0) goto PRED_##op
+#else
+#define PREDICT(op) if (*next_instr == op) goto PRED_##op
+#endif
+
+#define PREDICTED(op) PRED_##op: next_instr++
+#define PREDICTED_WITH_ARG(op) PRED_##op: oparg = PEEKARG(); next_instr += 3
+
+/* Stack manipulation macros */
+
+/* The stack can grow at most MAXINT deep, as co_nlocals and
+ co_stacksize are ints. */
+#define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack))
+#define EMPTY() (STACK_LEVEL() == 0)
+#define TOP() (stack_pointer[-1])
+#define SECOND() (stack_pointer[-2])
+#define THIRD() (stack_pointer[-3])
+#define FOURTH() (stack_pointer[-4])
+#define SET_TOP(v) (stack_pointer[-1] = (v))
+#define SET_SECOND(v) (stack_pointer[-2] = (v))
+#define SET_THIRD(v) (stack_pointer[-3] = (v))
+#define SET_FOURTH(v) (stack_pointer[-4] = (v))
+#define BASIC_STACKADJ(n) (stack_pointer += n)
+#define BASIC_PUSH(v) (*stack_pointer++ = (v))
+#define BASIC_POP() (*--stack_pointer)
+
+#ifdef LLTRACE
+#define PUSH(v) { (void)(BASIC_PUSH(v), \
+ lltrace && prtrace(TOP(), "push")); \
+ assert(STACK_LEVEL() <= co->co_stacksize); }
+#define POP() ((void)(lltrace && prtrace(TOP(), "pop")), \
+ BASIC_POP())
+#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \
+ lltrace && prtrace(TOP(), "stackadj")); \
+ assert(STACK_LEVEL() <= co->co_stacksize); }
+#define EXT_POP(STACK_POINTER) ((void)(lltrace && \
+ prtrace((STACK_POINTER)[-1], "ext_pop")), \
+ *--(STACK_POINTER))
+#else
+#define PUSH(v) BASIC_PUSH(v)
+#define POP() BASIC_POP()
+#define STACKADJ(n) BASIC_STACKADJ(n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
+#endif
+
+/* Local variable macros */
+
+#define GETLOCAL(i) (fastlocals[i])
+
+/* The SETLOCAL() macro must not DECREF the local variable in-place and
+ then store the new value; it must copy the old value to a temporary
+ value, then store the new value, and then DECREF the temporary value.
+ This is because it is possible that during the DECREF the frame is
+ accessed by other code (e.g. a __del__ method or gc.collect()) and the
+ variable would be pointing to already-freed memory. */
+#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
+ GETLOCAL(i) = value; \
+ Py_XDECREF(tmp); } while (0)
+
+/* Start of code */
+
+ if (f == NULL)
+ return NULL;
+
+ /* push frame */
+ if (Py_EnterRecursiveCall(""))
+ return NULL;
+
+ tstate->frame = f;
+
+ if (tstate->use_tracing) {
+ if (tstate->c_tracefunc != NULL) {
+ /* tstate->c_tracefunc, if defined, is a
+ function that will be called on *every* entry
+ to a code block. Its return value, if not
+ None, is a function that will be called at
+ the start of each executed line of code.
+ (Actually, the function must return itself
+ in order to continue tracing.) The trace
+ functions are called with three arguments:
+ a pointer to the current frame, a string
+ indicating why the function is called, and
+ an argument which depends on the situation.
+ The global trace function is also called
+ whenever an exception is detected. */
+ if (call_trace_protected(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ f, PyTrace_CALL, Py_None)) {
+ /* Trace function raised an error */
+ goto exit_eval_frame;
+ }
+ }
+ if (tstate->c_profilefunc != NULL) {
+ /* Similar for c_profilefunc, except it needn't
+ return itself and isn't called for "line" events */
+ if (call_trace_protected(tstate->c_profilefunc,
+ tstate->c_profileobj,
+ f, PyTrace_CALL, Py_None)) {
+ /* Profile function raised an error */
+ goto exit_eval_frame;
+ }
+ }
+ }
+
+ co = f->f_code;
+ names = co->co_names;
+ consts = co->co_consts;
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + co->co_nlocals;
+ first_instr = (unsigned char*) PyString_AS_STRING(co->co_code);
+ /* An explanation is in order for the next line.
+
+ f->f_lasti now refers to the index of the last instruction
+ executed. You might think this was obvious from the name, but
+ this wasn't always true before 2.3! PyFrame_New now sets
+ f->f_lasti to -1 (i.e. the index *before* the first instruction)
+ and YIELD_VALUE doesn't fiddle with f_lasti any more. So this
+ does work. Promise.
+
+ When the PREDICT() macros are enabled, some opcode pairs follow in
+ direct succession without updating f->f_lasti. A successful
+ prediction effectively links the two codes together as if they
+ were a single new opcode; accordingly,f->f_lasti will point to
+ the first code in the pair (for instance, GET_ITER followed by
+ FOR_ITER is effectively a single opcode and f->f_lasti will point
+ at to the beginning of the combined pair.)
+ */
+ next_instr = first_instr + f->f_lasti + 1;
+ stack_pointer = f->f_stacktop;
+ assert(stack_pointer != NULL);
+ f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
+
+#ifdef LLTRACE
+ lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
+#endif
+#if defined(Py_DEBUG) || defined(LLTRACE)
+ filename = PyString_AsString(co->co_filename);
+#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;
+ }
+
+ for (;;) {
+#ifdef WITH_TSC
+ if (inst1 == 0) {
+ /* Almost surely, the opcode executed a break
+ or a continue, preventing inst1 from being set
+ on the way out of the loop.
+ */
+ READ_TIMESTAMP(inst1);
+ loop1 = inst1;
+ }
+ dump_tsc(opcode, ticked, inst0, inst1, loop0, loop1,
+ intr0, intr1);
+ ticked = 0;
+ inst1 = 0;
+ intr0 = 0;
+ intr1 = 0;
+ READ_TIMESTAMP(loop0);
+#endif
+ assert(stack_pointer >= f->f_valuestack); /* else underflow */
+ assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
+
+ /* Do periodic things. Doing this every time through
+ the loop would add too much overhead, so we do it
+ only every Nth instruction. We also do it if
+ ``things_to_do'' is set, i.e. when an asynchronous
+ event needs attention (e.g. a signal handler or
+ async I/O handler); see Py_AddPendingCall() and
+ Py_MakePendingCalls() above. */
+
+ if (--_Py_Ticker < 0) {
+ if (*next_instr == SETUP_FINALLY) {
+ /* Make the last opcode before
+ a try: finally: block uninterruptable. */
+ goto fast_next_opcode;
+ }
+ _Py_Ticker = _Py_CheckInterval;
+ tstate->tick_counter++;
+#ifdef WITH_TSC
+ ticked = 1;
+#endif
+ if (things_to_do) {
+ if (Py_MakePendingCalls() < 0) {
+ why = WHY_EXCEPTION;
+ goto on_error;
+ }
+ if (things_to_do)
+ /* MakePendingCalls() didn't succeed.
+ Force early re-execution of this
+ "periodic" code, possibly after
+ a thread switch */
+ _Py_Ticker = 0;
+ }
+#ifdef WITH_THREAD
+ if (interpreter_lock) {
+ /* Give another thread a chance */
+
+ if (PyThreadState_Swap(NULL) != tstate)
+ Py_FatalError("ceval: tstate mix-up");
+ PyThread_release_lock(interpreter_lock);
+
+ /* Other threads may run now */
+
+ PyThread_acquire_lock(interpreter_lock, 1);
+ if (PyThreadState_Swap(tstate) != NULL)
+ Py_FatalError("ceval: orphan tstate");
+
+ /* Check for thread interrupts */
+
+ if (tstate->async_exc != NULL) {
+ x = tstate->async_exc;
+ tstate->async_exc = NULL;
+ PyErr_SetNone(x);
+ Py_DECREF(x);
+ why = WHY_EXCEPTION;
+ goto on_error;
+ }
+ }
+#endif
+ }
+
+ fast_next_opcode:
+ f->f_lasti = INSTR_OFFSET();
+
+ /* line-by-line tracing support */
+
+ if (tstate->c_tracefunc != NULL && !tstate->tracing) {
+ /* see maybe_call_line_trace
+ for expository comments */
+ f->f_stacktop = stack_pointer;
+
+ err = maybe_call_line_trace(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ f, &instr_lb, &instr_ub,
+ &instr_prev);
+ /* Reload possibly changed frame fields */
+ JUMPTO(f->f_lasti);
+ if (f->f_stacktop != NULL) {
+ stack_pointer = f->f_stacktop;
+ f->f_stacktop = NULL;
+ }
+ if (err) {
+ /* trace function raised an exception */
+ goto on_error;
+ }
+ }
+
+ /* Extract opcode and argument */
+
+ opcode = NEXTOP();
+ oparg = 0; /* allows oparg to be stored in a register because
+ it doesn't have to be remembered across a full loop */
+ if (HAS_ARG(opcode))
+ oparg = NEXTARG();
+ dispatch_opcode:
+#ifdef DYNAMIC_EXECUTION_PROFILE
+#ifdef DXPAIRS
+ dxpairs[lastopcode][opcode]++;
+ lastopcode = opcode;
+#endif
+ dxp[opcode]++;
+#endif
+
+#ifdef LLTRACE
+ /* Instruction tracing */
+
+ if (lltrace) {
+ if (HAS_ARG(opcode)) {
+ printf("%d: %d, %d\n",
+ f->f_lasti, opcode, oparg);
+ }
+ else {
+ printf("%d: %d\n",
+ f->f_lasti, opcode);
+ }
+ }
+#endif
+
+ /* Main switch on opcode */
+ READ_TIMESTAMP(inst0);
+
+ switch (opcode) {
+
+ /* BEWARE!
+ It is essential that any operation that fails sets either
+ x to NULL, err to nonzero, or why to anything but WHY_NOT,
+ and that no operation that succeeds does this! */
+
+ /* case STOP_CODE: this is an error! */
+
+ case NOP:
+ goto fast_next_opcode;
+
+ case LOAD_FAST:
+ x = GETLOCAL(oparg);
+ if (x != NULL) {
+ Py_INCREF(x);
+ PUSH(x);
+ goto fast_next_opcode;
+ }
+ format_exc_check_arg(PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_varnames, oparg));
+ break;
+
+ case LOAD_CONST:
+ x = GETITEM(consts, oparg);
+ Py_INCREF(x);
+ PUSH(x);
+ goto fast_next_opcode;
+
+ PREDICTED_WITH_ARG(STORE_FAST);
+ case STORE_FAST:
+ v = POP();
+ SETLOCAL(oparg, v);
+ goto fast_next_opcode;
+
+ PREDICTED(POP_TOP);
+ case POP_TOP:
+ v = POP();
+ Py_DECREF(v);
+ goto fast_next_opcode;
+
+ case ROT_TWO:
+ v = TOP();
+ w = SECOND();
+ SET_TOP(w);
+ SET_SECOND(v);
+ goto fast_next_opcode;
+
+ case ROT_THREE:
+ v = TOP();
+ w = SECOND();
+ x = THIRD();
+ SET_TOP(w);
+ SET_SECOND(x);
+ SET_THIRD(v);
+ goto fast_next_opcode;
+
+ case ROT_FOUR:
+ u = TOP();
+ v = SECOND();
+ w = THIRD();
+ x = FOURTH();
+ SET_TOP(v);
+ SET_SECOND(w);
+ SET_THIRD(x);
+ SET_FOURTH(u);
+ goto fast_next_opcode;
+
+ case DUP_TOP:
+ v = TOP();
+ Py_INCREF(v);
+ PUSH(v);
+ goto fast_next_opcode;
+
+ case DUP_TOPX:
+ if (oparg == 2) {
+ x = TOP();
+ Py_INCREF(x);
+ w = SECOND();
+ Py_INCREF(w);
+ STACKADJ(2);
+ SET_TOP(x);
+ SET_SECOND(w);
+ goto fast_next_opcode;
+ } else if (oparg == 3) {
+ x = TOP();
+ Py_INCREF(x);
+ w = SECOND();
+ Py_INCREF(w);
+ v = THIRD();
+ Py_INCREF(v);
+ STACKADJ(3);
+ SET_TOP(x);
+ SET_SECOND(w);
+ SET_THIRD(v);
+ goto fast_next_opcode;
+ }
+ Py_FatalError("invalid argument to DUP_TOPX"
+ " (bytecode corruption?)");
+ break;
+
+ case UNARY_POSITIVE:
+ v = TOP();
+ x = PyNumber_Positive(v);
+ Py_DECREF(v);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case UNARY_NEGATIVE:
+ v = TOP();
+ x = PyNumber_Negative(v);
+ Py_DECREF(v);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case UNARY_NOT:
+ v = TOP();
+ err = PyObject_IsTrue(v);
+ Py_DECREF(v);
+ if (err == 0) {
+ Py_INCREF(Py_True);
+ SET_TOP(Py_True);
+ continue;
+ }
+ else if (err > 0) {
+ Py_INCREF(Py_False);
+ SET_TOP(Py_False);
+ err = 0;
+ continue;
+ }
+ STACKADJ(-1);
+ break;
+
+ case UNARY_CONVERT:
+ v = TOP();
+ x = PyObject_Repr(v);
+ Py_DECREF(v);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case UNARY_INVERT:
+ v = TOP();
+ x = PyNumber_Invert(v);
+ Py_DECREF(v);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case 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) continue;
+ break;
+
+ case BINARY_MULTIPLY:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Multiply(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_DIVIDE:
+ if (!_Py_QnewFlag) {
+ w = POP();
+ v = TOP();
+ x = PyNumber_Divide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+ }
+ /* -Qnew is in effect: fall through to
+ BINARY_TRUE_DIVIDE */
+ case BINARY_TRUE_DIVIDE:
+ w = POP();
+ v = TOP();
+ x = PyNumber_TrueDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_FLOOR_DIVIDE:
+ w = POP();
+ v = TOP();
+ x = PyNumber_FloorDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_MODULO:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Remainder(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_ADD:
+ w = POP();
+ v = TOP();
+ if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+ /* INLINE: int + int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a + b;
+ if ((i^a) < 0 && (i^b) < 0)
+ goto slow_add;
+ x = PyInt_FromLong(i);
+ }
+ else if (PyString_CheckExact(v) &&
+ PyString_CheckExact(w)) {
+ x = string_concatenate(v, w, f, next_instr);
+ /* string_concatenate consumed the ref to v */
+ goto skip_decref_vx;
+ }
+ else {
+ slow_add:
+ x = PyNumber_Add(v, w);
+ }
+ Py_DECREF(v);
+ skip_decref_vx:
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_SUBTRACT:
+ w = POP();
+ v = TOP();
+ if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+ /* INLINE: int - int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a - b;
+ if ((i^a) < 0 && (i^~b) < 0)
+ goto slow_sub;
+ x = PyInt_FromLong(i);
+ }
+ else {
+ slow_sub:
+ x = PyNumber_Subtract(v, w);
+ }
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_SUBSCR:
+ w = POP();
+ v = TOP();
+ if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
+ /* INLINE: list[int] */
+ Py_ssize_t i = PyInt_AsSsize_t(w);
+ if (i < 0)
+ i += PyList_GET_SIZE(v);
+ if (i >= 0 && i < PyList_GET_SIZE(v)) {
+ x = PyList_GET_ITEM(v, i);
+ Py_INCREF(x);
+ }
+ else
+ goto slow_get;
+ }
+ else
+ slow_get:
+ x = PyObject_GetItem(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_LSHIFT:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Lshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_RSHIFT:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Rshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_AND:
+ w = POP();
+ v = TOP();
+ x = PyNumber_And(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_XOR:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Xor(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case BINARY_OR:
+ w = POP();
+ v = TOP();
+ x = PyNumber_Or(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case LIST_APPEND:
+ w = POP();
+ v = POP();
+ err = PyList_Append(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (err == 0) {
+ PREDICT(JUMP_ABSOLUTE);
+ continue;
+ }
+ break;
+
+ case INPLACE_POWER:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlacePower(v, w, Py_None);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_MULTIPLY:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceMultiply(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_DIVIDE:
+ if (!_Py_QnewFlag) {
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+ }
+ /* -Qnew is in effect: fall through to
+ INPLACE_TRUE_DIVIDE */
+ case INPLACE_TRUE_DIVIDE:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceTrueDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_FLOOR_DIVIDE:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceFloorDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_MODULO:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceRemainder(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_ADD:
+ w = POP();
+ v = TOP();
+ if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+ /* INLINE: int + int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a + b;
+ if ((i^a) < 0 && (i^b) < 0)
+ goto slow_iadd;
+ x = PyInt_FromLong(i);
+ }
+ else if (PyString_CheckExact(v) &&
+ PyString_CheckExact(w)) {
+ x = string_concatenate(v, w, f, next_instr);
+ /* string_concatenate consumed the ref to v */
+ goto skip_decref_v;
+ }
+ else {
+ slow_iadd:
+ x = PyNumber_InPlaceAdd(v, w);
+ }
+ Py_DECREF(v);
+ skip_decref_v:
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_SUBTRACT:
+ w = POP();
+ v = TOP();
+ if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
+ /* INLINE: int - int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a - b;
+ if ((i^a) < 0 && (i^~b) < 0)
+ goto slow_isub;
+ x = PyInt_FromLong(i);
+ }
+ else {
+ slow_isub:
+ x = PyNumber_InPlaceSubtract(v, w);
+ }
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_LSHIFT:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceLshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_RSHIFT:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceRshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_AND:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceAnd(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_XOR:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceXor(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_OR:
+ w = POP();
+ v = TOP();
+ x = PyNumber_InPlaceOr(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case SLICE+0:
+ case SLICE+1:
+ case SLICE+2:
+ case SLICE+3:
+ if ((opcode-SLICE) & 2)
+ w = POP();
+ else
+ w = NULL;
+ if ((opcode-SLICE) & 1)
+ v = POP();
+ else
+ v = NULL;
+ u = TOP();
+ x = apply_slice(u, v, w);
+ Py_DECREF(u);
+ Py_XDECREF(v);
+ Py_XDECREF(w);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case STORE_SLICE+0:
+ case STORE_SLICE+1:
+ case STORE_SLICE+2:
+ case STORE_SLICE+3:
+ if ((opcode-STORE_SLICE) & 2)
+ w = POP();
+ else
+ w = NULL;
+ if ((opcode-STORE_SLICE) & 1)
+ v = POP();
+ else
+ v = NULL;
+ u = POP();
+ t = POP();
+ err = assign_slice(u, v, w, t); /* u[v:w] = t */
+ Py_DECREF(t);
+ Py_DECREF(u);
+ Py_XDECREF(v);
+ Py_XDECREF(w);
+ if (err == 0) continue;
+ break;
+
+ case DELETE_SLICE+0:
+ case DELETE_SLICE+1:
+ case DELETE_SLICE+2:
+ case DELETE_SLICE+3:
+ if ((opcode-DELETE_SLICE) & 2)
+ w = POP();
+ else
+ w = NULL;
+ if ((opcode-DELETE_SLICE) & 1)
+ v = POP();
+ else
+ v = NULL;
+ u = POP();
+ err = assign_slice(u, v, w, (PyObject *)NULL);
+ /* del u[v:w] */
+ Py_DECREF(u);
+ Py_XDECREF(v);
+ Py_XDECREF(w);
+ if (err == 0) continue;
+ break;
+
+ case STORE_SUBSCR:
+ w = TOP();
+ v = SECOND();
+ u = THIRD();
+ STACKADJ(-3);
+ /* v[w] = u */
+ err = PyObject_SetItem(v, w, u);
+ Py_DECREF(u);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (err == 0) continue;
+ break;
+
+ case DELETE_SUBSCR:
+ w = TOP();
+ v = SECOND();
+ STACKADJ(-2);
+ /* del v[w] */
+ err = PyObject_DelItem(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ if (err == 0) continue;
+ break;
+
+ case PRINT_EXPR:
+ v = POP();
+ w = PySys_GetObject("displayhook");
+ if (w == 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;
+ }
+ if (err == 0) {
+ w = PyEval_CallObject(w, x);
+ Py_XDECREF(w);
+ if (w == NULL)
+ err = -1;
+ }
+ Py_DECREF(v);
+ Py_XDECREF(x);
+ break;
+
+ case PRINT_ITEM_TO:
+ w = stream = POP();
+ /* fall through to PRINT_ITEM */
+
+ case PRINT_ITEM:
+ v = POP();
+ if (stream == NULL || stream == Py_None) {
+ w = PySys_GetObject("stdout");
+ if (w == NULL) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "lost sys.stdout");
+ err = -1;
+ }
+ }
+ /* PyFile_SoftSpace() can exececute arbitrary code
+ if sys.stdout is an instance with a __getattr__.
+ If __getattr__ raises an exception, w will
+ be freed, so we need to prevent that temporarily. */
+ Py_XINCREF(w);
+ if (w != NULL && PyFile_SoftSpace(w, 0))
+ err = PyFile_WriteString(" ", w);
+ if (err == 0)
+ err = PyFile_WriteObject(v, w, Py_PRINT_RAW);
+ if (err == 0) {
+ /* XXX move into writeobject() ? */
+ if (PyString_Check(v)) {
+ char *s = PyString_AS_STRING(v);
+ Py_ssize_t len = PyString_GET_SIZE(v);
+ if (len == 0 ||
+ !isspace(Py_CHARMASK(s[len-1])) ||
+ s[len-1] == ' ')
+ PyFile_SoftSpace(w, 1);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(v)) {
+ Py_UNICODE *s = PyUnicode_AS_UNICODE(v);
+ Py_ssize_t len = PyUnicode_GET_SIZE(v);
+ if (len == 0 ||
+ !Py_UNICODE_ISSPACE(s[len-1]) ||
+ s[len-1] == ' ')
+ PyFile_SoftSpace(w, 1);
+ }
+#endif
+ else
+ PyFile_SoftSpace(w, 1);
+ }
+ Py_XDECREF(w);
+ Py_DECREF(v);
+ Py_XDECREF(stream);
+ stream = NULL;
+ if (err == 0)
+ continue;
+ break;
+
+ case PRINT_NEWLINE_TO:
+ w = stream = POP();
+ /* fall through to PRINT_NEWLINE */
+
+ case PRINT_NEWLINE:
+ if (stream == NULL || stream == Py_None) {
+ w = PySys_GetObject("stdout");
+ if (w == NULL)
+ PyErr_SetString(PyExc_RuntimeError,
+ "lost sys.stdout");
+ }
+ if (w != NULL) {
+ /* w.write() may replace sys.stdout, so we
+ * have to keep our reference to it */
+ Py_INCREF(w);
+ err = PyFile_WriteString("\n", w);
+ if (err == 0)
+ PyFile_SoftSpace(w, 0);
+ Py_DECREF(w);
+ }
+ Py_XDECREF(stream);
+ stream = NULL;
+ break;
+
+
+#ifdef CASE_TOO_BIG
+ default: switch (opcode) {
+#endif
+ case RAISE_VARARGS:
+ u = v = w = NULL;
+ switch (oparg) {
+ case 3:
+ u = POP(); /* traceback */
+ /* Fallthrough */
+ case 2:
+ v = POP(); /* value */
+ /* Fallthrough */
+ case 1:
+ w = POP(); /* exc */
+ case 0: /* Fallthrough */
+ why = do_raise(w, v, u);
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "bad RAISE_VARARGS oparg");
+ why = WHY_EXCEPTION;
+ break;
+ }
+ break;
+
+ case LOAD_LOCALS:
+ if ((x = f->f_locals) != NULL) {
+ Py_INCREF(x);
+ PUSH(x);
+ continue;
+ }
+ PyErr_SetString(PyExc_SystemError, "no locals");
+ break;
+
+ case RETURN_VALUE:
+ retval = POP();
+ why = WHY_RETURN;
+ goto fast_block_end;
+
+ case YIELD_VALUE:
+ retval = POP();
+ f->f_stacktop = stack_pointer;
+ why = WHY_YIELD;
+ goto fast_yield;
+
+ case EXEC_STMT:
+ w = TOP();
+ v = SECOND();
+ u = THIRD();
+ STACKADJ(-3);
+ READ_TIMESTAMP(intr0);
+ err = exec_statement(f, u, v, w);
+ READ_TIMESTAMP(intr1);
+ Py_DECREF(u);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ break;
+
+ case POP_BLOCK:
+ {
+ PyTryBlock *b = PyFrame_BlockPop(f);
+ while (STACK_LEVEL() > b->b_level) {
+ v = POP();
+ Py_DECREF(v);
+ }
+ }
+ continue;
+
+ PREDICTED(END_FINALLY);
+ case END_FINALLY:
+ v = POP();
+ if (PyInt_Check(v)) {
+ why = (enum why_code) PyInt_AS_LONG(v);
+ assert(why != WHY_YIELD);
+ if (why == WHY_RETURN ||
+ why == WHY_CONTINUE)
+ retval = POP();
+ }
+ else if (PyExceptionClass_Check(v) ||
+ PyString_Check(v)) {
+ w = POP();
+ u = POP();
+ PyErr_Restore(v, w, u);
+ why = WHY_RERAISE;
+ break;
+ }
+ else if (v != Py_None) {
+ PyErr_SetString(PyExc_SystemError,
+ "'finally' pops bad exception");
+ why = WHY_EXCEPTION;
+ }
+ Py_DECREF(v);
+ break;
+
+ case BUILD_CLASS:
+ u = TOP();
+ v = SECOND();
+ w = THIRD();
+ STACKADJ(-2);
+ x = build_class(u, v, w);
+ SET_TOP(x);
+ Py_DECREF(u);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ break;
+
+ case 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);
+ Py_DECREF(v);
+ if (err == 0) continue;
+ break;
+ }
+ PyErr_Format(PyExc_SystemError,
+ "no locals found when storing %s",
+ PyObject_REPR(w));
+ break;
+
+ case 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;
+ }
+ PyErr_Format(PyExc_SystemError,
+ "no locals when deleting %s",
+ PyObject_REPR(w));
+ break;
+
+ PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
+ case UNPACK_SEQUENCE:
+ v = POP();
+ if (PyTuple_CheckExact(v) &&
+ PyTuple_GET_SIZE(v) == oparg) {
+ PyObject **items = \
+ ((PyTupleObject *)v)->ob_item;
+ while (oparg--) {
+ w = items[oparg];
+ Py_INCREF(w);
+ PUSH(w);
+ }
+ Py_DECREF(v);
+ continue;
+ } else if (PyList_CheckExact(v) &&
+ PyList_GET_SIZE(v) == oparg) {
+ PyObject **items = \
+ ((PyListObject *)v)->ob_item;
+ while (oparg--) {
+ w = items[oparg];
+ Py_INCREF(w);
+ PUSH(w);
+ }
+ } else if (unpack_iterable(v, oparg,
+ stack_pointer + oparg)) {
+ stack_pointer += oparg;
+ } else {
+ /* unpack_iterable() raised an exception */
+ why = WHY_EXCEPTION;
+ }
+ Py_DECREF(v);
+ break;
+
+ case STORE_ATTR:
+ w = GETITEM(names, oparg);
+ v = TOP();
+ u = SECOND();
+ STACKADJ(-2);
+ err = PyObject_SetAttr(v, w, u); /* v.w = u */
+ Py_DECREF(v);
+ Py_DECREF(u);
+ if (err == 0) continue;
+ break;
+
+ case DELETE_ATTR:
+ w = GETITEM(names, oparg);
+ v = POP();
+ err = PyObject_SetAttr(v, w, (PyObject *)NULL);
+ /* del v.w */
+ Py_DECREF(v);
+ break;
+
+ case STORE_GLOBAL:
+ w = GETITEM(names, oparg);
+ v = POP();
+ err = PyDict_SetItem(f->f_globals, w, v);
+ Py_DECREF(v);
+ if (err == 0) continue;
+ break;
+
+ case DELETE_GLOBAL:
+ w = GETITEM(names, oparg);
+ if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
+ format_exc_check_arg(
+ PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
+ break;
+
+ case LOAD_NAME:
+ w = GETITEM(names, oparg);
+ if ((v = f->f_locals) == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "no locals when loading %s",
+ PyObject_REPR(w));
+ break;
+ }
+ if (PyDict_CheckExact(v)) {
+ x = PyDict_GetItem(v, w);
+ Py_XINCREF(x);
+ }
+ else {
+ x = PyObject_GetItem(v, w);
+ if (x == NULL && PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(
+ PyExc_KeyError))
+ break;
+ PyErr_Clear();
+ }
+ }
+ 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);
+ continue;
+
+ case LOAD_GLOBAL:
+ w = GETITEM(names, oparg);
+ if (PyString_CheckExact(w)) {
+ /* Inline the PyDict_GetItem() calls.
+ WARNING: this is an extreme speed hack.
+ Do not try this at home. */
+ long hash = ((PyStringObject *)w)->ob_shash;
+ if (hash != -1) {
+ PyDictObject *d;
+ PyDictEntry *e;
+ d = (PyDictObject *)(f->f_globals);
+ e = d->ma_lookup(d, w, hash);
+ if (e == NULL) {
+ x = NULL;
+ break;
+ }
+ x = e->me_value;
+ if (x != NULL) {
+ Py_INCREF(x);
+ PUSH(x);
+ continue;
+ }
+ d = (PyDictObject *)(f->f_builtins);
+ e = d->ma_lookup(d, w, hash);
+ if (e == NULL) {
+ x = NULL;
+ break;
+ }
+ x = e->me_value;
+ if (x != NULL) {
+ Py_INCREF(x);
+ PUSH(x);
+ continue;
+ }
+ goto load_global_error;
+ }
+ }
+ /* This is the un-inlined version of the code above */
+ x = PyDict_GetItem(f->f_globals, w);
+ if (x == NULL) {
+ x = PyDict_GetItem(f->f_builtins, w);
+ if (x == NULL) {
+ load_global_error:
+ format_exc_check_arg(
+ PyExc_NameError,
+ GLOBAL_NAME_ERROR_MSG, w);
+ break;
+ }
+ }
+ Py_INCREF(x);
+ PUSH(x);
+ continue;
+
+ case DELETE_FAST:
+ x = GETLOCAL(oparg);
+ if (x != NULL) {
+ SETLOCAL(oparg, NULL);
+ continue;
+ }
+ format_exc_check_arg(
+ PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_varnames, oparg)
+ );
+ break;
+
+ case LOAD_CLOSURE:
+ x = freevars[oparg];
+ Py_INCREF(x);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case LOAD_DEREF:
+ x = freevars[oparg];
+ w = PyCell_Get(x);
+ if (w != NULL) {
+ PUSH(w);
+ continue;
+ }
+ err = -1;
+ /* Don't stomp existing exception */
+ if (PyErr_Occurred())
+ break;
+ if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
+ v = PyTuple_GET_ITEM(co->co_cellvars,
+ oparg);
+ format_exc_check_arg(
+ PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ v);
+ } else {
+ v = PyTuple_GET_ITEM(co->co_freevars, oparg -
+ PyTuple_GET_SIZE(co->co_cellvars));
+ format_exc_check_arg(PyExc_NameError,
+ UNBOUNDFREE_ERROR_MSG, v);
+ }
+ 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_NewPresized((Py_ssize_t)oparg);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case STORE_MAP:
+ w = TOP(); /* key */
+ u = SECOND(); /* value */
+ v = THIRD(); /* dict */
+ STACKADJ(-2);
+ assert (PyDict_CheckExact(v));
+ err = PyDict_SetItem(v, w, u); /* v[w] = u */
+ Py_DECREF(u);
+ Py_DECREF(w);
+ if (err == 0) continue;
+ break;
+
+ case LOAD_ATTR:
+ w = GETITEM(names, oparg);
+ v = TOP();
+ x = PyObject_GetAttr(v, w);
+ Py_DECREF(v);
+ SET_TOP(x);
+ if (x != NULL) continue;
+ break;
+
+ case COMPARE_OP:
+ w = POP();
+ v = TOP();
+ if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
+ /* INLINE: cmp(int, int) */
+ register long a, b;
+ register int res;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ switch (oparg) {
+ case PyCmp_LT: res = a < b; break;
+ case PyCmp_LE: res = a <= b; break;
+ case PyCmp_EQ: res = a == b; break;
+ case PyCmp_NE: res = a != b; break;
+ case PyCmp_GT: res = a > b; break;
+ case PyCmp_GE: res = a >= b; break;
+ case PyCmp_IS: res = v == w; break;
+ case PyCmp_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);
+ SET_TOP(x);
+ if (x == NULL) break;
+ PREDICT(JUMP_IF_FALSE);
+ PREDICT(JUMP_IF_TRUE);
+ continue;
+
+ case IMPORT_NAME:
+ w = GETITEM(names, oparg);
+ x = PyDict_GetItemString(f->f_builtins, "__import__");
+ if (x == NULL) {
+ PyErr_SetString(PyExc_ImportError,
+ "__import__ not found");
+ break;
+ }
+ Py_INCREF(x);
+ v = POP();
+ u = TOP();
+ if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
+ w = PyTuple_Pack(5,
+ w,
+ f->f_globals,
+ f->f_locals == NULL ?
+ Py_None : f->f_locals,
+ v,
+ u);
+ else
+ w = PyTuple_Pack(4,
+ w,
+ 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;
+ }
+ READ_TIMESTAMP(intr0);
+ v = x;
+ x = PyEval_CallObject(v, w);
+ Py_DECREF(v);
+ READ_TIMESTAMP(intr1);
+ Py_DECREF(w);
+ SET_TOP(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;
+ }
+ READ_TIMESTAMP(intr0);
+ err = import_all_from(x, v);
+ READ_TIMESTAMP(intr1);
+ PyFrame_LocalsToFast(f, 0);
+ Py_DECREF(v);
+ if (err == 0) continue;
+ break;
+
+ case IMPORT_FROM:
+ w = GETITEM(names, oparg);
+ v = TOP();
+ READ_TIMESTAMP(intr0);
+ x = import_from(v, w);
+ READ_TIMESTAMP(intr1);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case JUMP_FORWARD:
+ JUMPBY(oparg);
+ goto fast_next_opcode;
+
+ PREDICTED_WITH_ARG(JUMP_IF_FALSE);
+ case JUMP_IF_FALSE:
+ w = TOP();
+ if (w == Py_True) {
+ PREDICT(POP_TOP);
+ goto fast_next_opcode;
+ }
+ if (w == Py_False) {
+ JUMPBY(oparg);
+ goto fast_next_opcode;
+ }
+ err = PyObject_IsTrue(w);
+ if (err > 0)
+ err = 0;
+ else if (err == 0)
+ JUMPBY(oparg);
+ else
+ break;
+ continue;
+
+ PREDICTED_WITH_ARG(JUMP_IF_TRUE);
+ case JUMP_IF_TRUE:
+ w = TOP();
+ if (w == Py_False) {
+ PREDICT(POP_TOP);
+ goto fast_next_opcode;
+ }
+ if (w == Py_True) {
+ JUMPBY(oparg);
+ goto fast_next_opcode;
+ }
+ err = PyObject_IsTrue(w);
+ if (err > 0) {
+ err = 0;
+ JUMPBY(oparg);
+ }
+ else if (err == 0)
+ ;
+ else
+ break;
+ continue;
+
+ PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
+ case JUMP_ABSOLUTE:
+ JUMPTO(oparg);
+#if FAST_LOOPS
+ /* Enabling this path speeds-up all while and for-loops by bypassing
+ the per-loop checks for signals. By default, this should be turned-off
+ because it prevents detection of a control-break in tight loops like
+ "while 1: pass". Compile with this option turned-on when you need
+ the speed-up and do not need break checking inside tight loops (ones
+ that contain only instructions ending with goto fast_next_opcode).
+ */
+ goto fast_next_opcode;
+#else
+ continue;
+#endif
+
+ case 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);
+ continue;
+ }
+ STACKADJ(-1);
+ break;
+
+ PREDICTED_WITH_ARG(FOR_ITER);
+ case FOR_ITER:
+ /* before: [iter]; after: [iter, iter()] *or* [] */
+ v = TOP();
+ x = (*v->ob_type->tp_iternext)(v);
+ if (x != NULL) {
+ PUSH(x);
+ PREDICT(STORE_FAST);
+ PREDICT(UNPACK_SEQUENCE);
+ continue;
+ }
+ if (PyErr_Occurred()) {
+ if (!PyErr_ExceptionMatches(
+ PyExc_StopIteration))
+ break;
+ PyErr_Clear();
+ }
+ /* iterator ended normally */
+ x = v = POP();
+ Py_DECREF(v);
+ JUMPBY(oparg);
+ continue;
+
+ case BREAK_LOOP:
+ why = WHY_BREAK;
+ goto fast_block_end;
+
+ case CONTINUE_LOOP:
+ retval = PyInt_FromLong(oparg);
+ if (!retval) {
+ x = NULL;
+ break;
+ }
+ why = WHY_CONTINUE;
+ goto fast_block_end;
+
+ case SETUP_LOOP:
+ case SETUP_EXCEPT:
+ case 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.
+ */
+
+ PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
+ STACK_LEVEL());
+ continue;
+
+ case WITH_CLEANUP:
+ {
+ /* At the top of the stack are 1-3 values indicating
+ how/why we entered the finally clause:
+ - TOP = None
+ - (TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval
+ - TOP = WHY_*; no retval below it
+ - (TOP, SECOND, THIRD) = exc_info()
+ Below them is EXIT, the context.__exit__ bound method.
+ In the last case, we must call
+ EXIT(TOP, SECOND, THIRD)
+ otherwise we must call
+ EXIT(None, None, None)
+
+ In all cases, we remove EXIT from the stack, leaving
+ the rest in the same order.
+
+ In addition, if the stack represents an exception,
+ *and* the function call returns a 'true' value, we
+ "zap" this information, to prevent END_FINALLY from
+ re-raising the exception. (But non-local gotos
+ should still be resumed.)
+ */
+
+ PyObject *exit_func;
+
+ u = POP();
+ if (u == Py_None) {
+ exit_func = TOP();
+ SET_TOP(u);
+ v = w = Py_None;
+ }
+ else if (PyInt_Check(u)) {
+ switch(PyInt_AS_LONG(u)) {
+ case WHY_RETURN:
+ case WHY_CONTINUE:
+ /* Retval in TOP. */
+ exit_func = SECOND();
+ SET_SECOND(TOP());
+ SET_TOP(u);
+ break;
+ default:
+ exit_func = TOP();
+ SET_TOP(u);
+ break;
+ }
+ u = v = w = Py_None;
+ }
+ else {
+ v = TOP();
+ w = SECOND();
+ exit_func = THIRD();
+ SET_TOP(u);
+ SET_SECOND(v);
+ SET_THIRD(w);
+ }
+ /* XXX Not the fastest way to call it... */
+ x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
+ NULL);
+ if (x == NULL) {
+ Py_DECREF(exit_func);
+ break; /* Go to error exit */
+ }
+ if (u != Py_None && PyObject_IsTrue(x)) {
+ /* There was an exception and a true return */
+ STACKADJ(-2);
+ Py_INCREF(Py_None);
+ SET_TOP(Py_None);
+ Py_DECREF(u);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ } else {
+ /* The stack was rearranged to remove EXIT
+ above. Let END_FINALLY do its thing */
+ }
+ Py_DECREF(x);
+ Py_DECREF(exit_func);
+ PREDICT(END_FINALLY);
+ break;
+ }
+
+ case CALL_FUNCTION:
+ {
+ PyObject **sp;
+ PCALL(PCALL_ALL);
+ sp = stack_pointer;
+#ifdef WITH_TSC
+ x = call_function(&sp, oparg, &intr0, &intr1);
+#else
+ x = call_function(&sp, oparg);
+#endif
+ stack_pointer = sp;
+ 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, **sp;
+ PCALL(PCALL_ALL);
+ if (flags & CALL_FLAG_VAR)
+ n++;
+ if (flags & CALL_FLAG_KW)
+ n++;
+ pfunc = stack_pointer - n - 1;
+ func = *pfunc;
+
+ 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);
+ sp = stack_pointer;
+ READ_TIMESTAMP(intr0);
+ x = 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);
+ }
+ 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:
+ {
+ v = POP(); /* code object */
+ x = PyFunction_New(v, f->f_globals);
+ Py_DECREF(v);
+ if (x != NULL) {
+ v = POP();
+ 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);
+ }
+ PUSH(x);
+ break;
+ }
+
+ case BUILD_SLICE:
+ if (oparg == 3)
+ w = 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) continue;
+ break;
+
+ case EXTENDED_ARG:
+ opcode = NEXTOP();
+ oparg = oparg<<16 | NEXTARG();
+ goto dispatch_opcode;
+
+ default:
+ fprintf(stderr,
+ "XXX lineno: %d, opcode: %d\n",
+ PyCode_Addr2Line(f->f_code, f->f_lasti),
+ opcode);
+ PyErr_SetString(PyExc_SystemError, "unknown opcode");
+ why = WHY_EXCEPTION;
+ break;
+
+#ifdef CASE_TOO_BIG
+ }
+#endif
+
+ } /* switch */
+
+ on_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 */
+
+ 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);
+ }
+ }
+#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);
+ }
+
+ /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
+
+ if (why == WHY_RERAISE)
+ why = WHY_EXCEPTION;
+
+ /* Unwind stacks if a (pseudo) exception occurred */
+
+fast_block_end:
+ while (why != WHY_NOT && f->f_iblock > 0) {
+ PyTryBlock *b = PyFrame_BlockPop(f);
+
+ assert(why != WHY_YIELD);
+ if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
+ /* For a continue inside a try block,
+ don't pop the block for the loop. */
+ PyFrame_BlockSetup(f, b->b_type, b->b_handler,
+ b->b_level);
+ why = WHY_NOT;
+ JUMPTO(PyInt_AS_LONG(retval));
+ Py_DECREF(retval);
+ break;
+ }
+
+ while (STACK_LEVEL() > b->b_level) {
+ v = POP();
+ Py_XDECREF(v);
+ }
+ if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
+ why = WHY_NOT;
+ JUMPTO(b->b_handler);
+ break;
+ }
+ if (b->b_type == SETUP_FINALLY ||
+ (b->b_type == SETUP_EXCEPT &&
+ why == WHY_EXCEPTION)) {
+ if (why == WHY_EXCEPTION) {
+ PyObject *exc, *val, *tb;
+ PyErr_Fetch(&exc, &val, &tb);
+ if (val == NULL) {
+ val = Py_None;
+ Py_INCREF(val);
+ }
+ /* Make the raw exception data
+ available to the handler,
+ so a program can emulate the
+ Python main loop. Don't do
+ this for 'finally'. */
+ if (b->b_type == SETUP_EXCEPT) {
+ PyErr_NormalizeException(
+ &exc, &val, &tb);
+ set_exc_info(tstate,
+ exc, val, tb);
+ }
+ if (tb == NULL) {
+ Py_INCREF(Py_None);
+ PUSH(Py_None);
+ } else
+ PUSH(tb);
+ PUSH(val);
+ PUSH(exc);
+ }
+ else {
+ if (why & (WHY_RETURN | WHY_CONTINUE))
+ PUSH(retval);
+ v = PyInt_FromLong((long)why);
+ PUSH(v);
+ }
+ why = WHY_NOT;
+ JUMPTO(b->b_handler);
+ break;
+ }
+ } /* unwind stack */
+
+ /* End the loop if we still have an error (or return) */
+
+ if (why != WHY_NOT)
+ break;
+ READ_TIMESTAMP(loop1);
+
+ } /* main loop */
+
+ assert(why != WHY_YIELD);
+ /* Pop remaining stack entries. */
+ while (!EMPTY()) {
+ v = POP();
+ Py_XDECREF(v);
+ }
+
+ if (why != WHY_RETURN)
+ retval = NULL;
+
+fast_yield:
+ if (tstate->use_tracing) {
+ if (tstate->c_tracefunc) {
+ if (why == WHY_RETURN || why == WHY_YIELD) {
+ if (call_trace(tstate->c_tracefunc,
+ tstate->c_traceobj, f,
+ PyTrace_RETURN, retval)) {
+ Py_XDECREF(retval);
+ retval = NULL;
+ why = WHY_EXCEPTION;
+ }
+ }
+ else if (why == WHY_EXCEPTION) {
+ call_trace_protected(tstate->c_tracefunc,
+ tstate->c_traceobj, f,
+ PyTrace_RETURN, NULL);
+ }
+ }
+ if (tstate->c_profilefunc) {
+ if (why == WHY_EXCEPTION)
+ call_trace_protected(tstate->c_profilefunc,
+ tstate->c_profileobj, f,
+ PyTrace_RETURN, NULL);
+ else if (call_trace(tstate->c_profilefunc,
+ tstate->c_profileobj, f,
+ PyTrace_RETURN, retval)) {
+ Py_XDECREF(retval);
+ retval = NULL;
+ why = WHY_EXCEPTION;
+ }
+ }
+ }
+
+ if (tstate->frame->f_exc_type != NULL)
+ reset_exc_info(tstate);
+ else {
+ assert(tstate->frame->f_exc_value == NULL);
+ assert(tstate->frame->f_exc_traceback == NULL);
+ }
+
+ /* pop frame */
+exit_eval_frame:
+ Py_LeaveRecursiveCall();
+ tstate->frame = f->f_back;
+
+ return retval;
+}
+
+/* This is gonna seem *real weird*, but if you put some other code between
+ PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
+ the test in the if statements in Misc/gdbinit (pystack and pystackv). */
+
+PyObject *
+PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
+ PyObject **args, int argcount, PyObject **kws, int kwcount,
+ PyObject **defs, int defcount, PyObject *closure)
+{
+ register PyFrameObject *f;
+ register PyObject *retval = NULL;
+ register PyObject **fastlocals, **freevars;
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject *x, *u;
+
+ if (globals == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyEval_EvalCodeEx: NULL globals");
+ return NULL;
+ }
+
+ assert(tstate != NULL);
+ assert(globals != NULL);
+ f = PyFrame_New(tstate, co, globals, locals);
+ if (f == NULL)
+ return NULL;
+
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + co->co_nlocals;
+
+ if (co->co_argcount > 0 ||
+ co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
+ int i;
+ int n = argcount;
+ PyObject *kwdict = NULL;
+ if (co->co_flags & CO_VARKEYWORDS) {
+ kwdict = PyDict_New();
+ if (kwdict == NULL)
+ goto fail;
+ i = co->co_argcount;
+ if (co->co_flags & CO_VARARGS)
+ i++;
+ SETLOCAL(i, kwdict);
+ }
+ if (argcount > co->co_argcount) {
+ if (!(co->co_flags & CO_VARARGS)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %s %d "
+ "%sargument%s (%d given)",
+ PyString_AsString(co->co_name),
+ defcount ? "at most" : "exactly",
+ co->co_argcount,
+ kwcount ? "non-keyword " : "",
+ co->co_argcount == 1 ? "" : "s",
+ argcount);
+ goto fail;
+ }
+ n = co->co_argcount;
+ }
+ for (i = 0; i < n; i++) {
+ x = args[i];
+ Py_INCREF(x);
+ SETLOCAL(i, x);
+ }
+ if (co->co_flags & CO_VARARGS) {
+ u = PyTuple_New(argcount - n);
+ if (u == NULL)
+ goto fail;
+ SETLOCAL(co->co_argcount, u);
+ for (i = n; i < argcount; i++) {
+ x = args[i];
+ Py_INCREF(x);
+ PyTuple_SET_ITEM(u, i-n, x);
+ }
+ }
+ for (i = 0; i < kwcount; i++) {
+ PyObject **co_varnames;
+ PyObject *keyword = kws[2*i];
+ PyObject *value = kws[2*i + 1];
+ int j;
+ if (keyword == NULL || !PyString_Check(keyword)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings",
+ PyString_AsString(co->co_name));
+ goto fail;
+ }
+ /* Speed hack: do raw pointer compares. As names are
+ normally interned this should almost always hit. */
+ co_varnames = PySequence_Fast_ITEMS(co->co_varnames);
+ for (j = 0; j < co->co_argcount; j++) {
+ PyObject *nm = co_varnames[j];
+ if (nm == keyword)
+ goto kw_found;
+ }
+ /* Slow fallback, just in case */
+ for (j = 0; j < co->co_argcount; j++) {
+ PyObject *nm = co_varnames[j];
+ int cmp = PyObject_RichCompareBool(
+ keyword, nm, Py_EQ);
+ if (cmp > 0)
+ goto kw_found;
+ else if (cmp < 0)
+ goto fail;
+ }
+ /* Check errors from Compare */
+ if (PyErr_Occurred())
+ goto fail;
+ if (j >= co->co_argcount) {
+ if (kwdict == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got an unexpected "
+ "keyword argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(keyword));
+ goto fail;
+ }
+ PyDict_SetItem(kwdict, keyword, value);
+ continue;
+ }
+kw_found:
+ if (GETLOCAL(j) != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got multiple "
+ "values for keyword "
+ "argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(keyword));
+ goto fail;
+ }
+ Py_INCREF(value);
+ SETLOCAL(j, value);
+ }
+ if (argcount < co->co_argcount) {
+ int m = co->co_argcount - defcount;
+ for (i = argcount; i < m; i++) {
+ if (GETLOCAL(i) == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %s %d "
+ "%sargument%s (%d given)",
+ PyString_AsString(co->co_name),
+ ((co->co_flags & CO_VARARGS) ||
+ defcount) ? "at least"
+ : "exactly",
+ m, kwcount ? "non-keyword " : "",
+ m == 1 ? "" : "s", i);
+ goto fail;
+ }
+ }
+ if (n > m)
+ i = n - m;
+ else
+ i = 0;
+ for (; i < defcount; i++) {
+ if (GETLOCAL(m+i) == NULL) {
+ PyObject *def = defs[i];
+ Py_INCREF(def);
+ SETLOCAL(m+i, def);
+ }
+ }
+ }
+ }
+ else {
+ if (argcount > 0 || kwcount > 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%d given)",
+ PyString_AsString(co->co_name),
+ argcount + kwcount);
+ goto fail;
+ }
+ }
+ /* Allocate and initialize storage for cell vars, and copy free
+ vars into frame. This isn't too efficient right now. */
+ if (PyTuple_GET_SIZE(co->co_cellvars)) {
+ int i, j, nargs, found;
+ char *cellname, *argname;
+ PyObject *c;
+
+ nargs = co->co_argcount;
+ if (co->co_flags & CO_VARARGS)
+ nargs++;
+ if (co->co_flags & CO_VARKEYWORDS)
+ nargs++;
+
+ /* Initialize each cell var, taking into account
+ cell vars that are initialized from arguments.
+
+ Should arrange for the compiler to put cellvars
+ that are arguments at the beginning of the cellvars
+ list so that we can march over it more efficiently?
+ */
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
+ cellname = PyString_AS_STRING(
+ PyTuple_GET_ITEM(co->co_cellvars, i));
+ found = 0;
+ for (j = 0; j < nargs; j++) {
+ argname = PyString_AS_STRING(
+ PyTuple_GET_ITEM(co->co_varnames, j));
+ if (strcmp(cellname, argname) == 0) {
+ c = PyCell_New(GETLOCAL(j));
+ if (c == NULL)
+ goto fail;
+ GETLOCAL(co->co_nlocals + i) = c;
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ c = PyCell_New(NULL);
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(co->co_nlocals + i, c);
+ }
+ }
+ }
+ if (PyTuple_GET_SIZE(co->co_freevars)) {
+ int i;
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
+ }
+ }
+
+ if (co->co_flags & CO_GENERATOR) {
+ /* Don't need to keep the reference to f_back, it will be set
+ * when the generator is resumed. */
+ Py_XDECREF(f->f_back);
+ f->f_back = NULL;
+
+ PCALL(PCALL_GENERATOR);
+
+ /* Create a new generator that owns the ready to run frame
+ * and return that as the value. */
+ return PyGen_New(f);
+ }
+
+ retval = PyEval_EvalFrameEx(f,0);
+
+fail: /* Jump here from prelude on failure */
+
+ /* decref'ing the frame can cause __del__ methods to get invoked,
+ which can call back into Python. While we're done with the
+ current Python frame (f), the associated C stack is still in use,
+ so recursion_depth must be boosted for the duration.
+ */
+ assert(tstate != NULL);
+ ++tstate->recursion_depth;
+ Py_DECREF(f);
+ --tstate->recursion_depth;
+ return retval;
+}
+
+
+/* Implementation notes for set_exc_info() and reset_exc_info():
+
+- Below, 'exc_ZZZ' stands for 'exc_type', 'exc_value' and
+ 'exc_traceback'. These always travel together.
+
+- tstate->curexc_ZZZ is the "hot" exception that is set by
+ PyErr_SetString(), cleared by PyErr_Clear(), and so on.
+
+- Once an exception is caught by an except clause, it is transferred
+ from tstate->curexc_ZZZ to tstate->exc_ZZZ, from which sys.exc_info()
+ can pick it up. This is the primary task of set_exc_info().
+ XXX That can't be right: set_exc_info() doesn't look at tstate->curexc_ZZZ.
+
+- Now let me explain the complicated dance with frame->f_exc_ZZZ.
+
+ Long ago, when none of this existed, there were just a few globals:
+ one set corresponding to the "hot" exception, and one set
+ corresponding to sys.exc_ZZZ. (Actually, the latter weren't C
+ globals; they were simply stored as sys.exc_ZZZ. For backwards
+ compatibility, they still are!) The problem was that in code like
+ this:
+
+ try:
+ "something that may fail"
+ except "some exception":
+ "do something else first"
+ "print the exception from sys.exc_ZZZ."
+
+ if "do something else first" invoked something that raised and caught
+ an exception, sys.exc_ZZZ were overwritten. That was a frequent
+ cause of subtle bugs. I fixed this by changing the semantics as
+ follows:
+
+ - Within one frame, sys.exc_ZZZ will hold the last exception caught
+ *in that frame*.
+
+ - But initially, and as long as no exception is caught in a given
+ frame, sys.exc_ZZZ will hold the last exception caught in the
+ previous frame (or the frame before that, etc.).
+
+ The first bullet fixed the bug in the above example. The second
+ bullet was for backwards compatibility: it was (and is) common to
+ have a function that is called when an exception is caught, and to
+ have that function access the caught exception via sys.exc_ZZZ.
+ (Example: traceback.print_exc()).
+
+ At the same time I fixed the problem that sys.exc_ZZZ weren't
+ thread-safe, by introducing sys.exc_info() which gets it from tstate;
+ but that's really a separate improvement.
+
+ The reset_exc_info() function in ceval.c restores the tstate->exc_ZZZ
+ variables to what they were before the current frame was called. The
+ set_exc_info() function saves them on the frame so that
+ reset_exc_info() can restore them. The invariant is that
+ frame->f_exc_ZZZ is NULL iff the current frame never caught an
+ exception (where "catching" an exception applies only to successful
+ except clauses); and if the current frame ever caught an exception,
+ frame->f_exc_ZZZ is the exception that was stored in tstate->exc_ZZZ
+ at the start of the current frame.
+
+*/
+
+static void
+set_exc_info(PyThreadState *tstate,
+ PyObject *type, PyObject *value, PyObject *tb)
+{
+ PyFrameObject *frame = tstate->frame;
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+
+ assert(type != NULL);
+ assert(frame != NULL);
+ if (frame->f_exc_type == NULL) {
+ assert(frame->f_exc_value == NULL);
+ assert(frame->f_exc_traceback == NULL);
+ /* This frame didn't catch an exception before. */
+ /* Save previous exception of this thread in this frame. */
+ if (tstate->exc_type == NULL) {
+ /* XXX Why is this set to Py_None? */
+ Py_INCREF(Py_None);
+ tstate->exc_type = Py_None;
+ }
+ Py_INCREF(tstate->exc_type);
+ Py_XINCREF(tstate->exc_value);
+ Py_XINCREF(tstate->exc_traceback);
+ frame->f_exc_type = tstate->exc_type;
+ frame->f_exc_value = tstate->exc_value;
+ frame->f_exc_traceback = tstate->exc_traceback;
+ }
+ /* Set new exception for this thread. */
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ Py_INCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+ /* For b/w compatibility */
+ PySys_SetObject("exc_type", type);
+ PySys_SetObject("exc_value", value);
+ PySys_SetObject("exc_traceback", tb);
+}
+
+static void
+reset_exc_info(PyThreadState *tstate)
+{
+ PyFrameObject *frame;
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+
+ /* It's a precondition that the thread state's frame caught an
+ * exception -- verify in a debug build.
+ */
+ assert(tstate != NULL);
+ frame = tstate->frame;
+ assert(frame != NULL);
+ assert(frame->f_exc_type != NULL);
+
+ /* Copy the frame's exception info back to the thread state. */
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ Py_INCREF(frame->f_exc_type);
+ Py_XINCREF(frame->f_exc_value);
+ Py_XINCREF(frame->f_exc_traceback);
+ tstate->exc_type = frame->f_exc_type;
+ tstate->exc_value = frame->f_exc_value;
+ tstate->exc_traceback = frame->f_exc_traceback;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+
+ /* For b/w compatibility */
+ PySys_SetObject("exc_type", frame->f_exc_type);
+ PySys_SetObject("exc_value", frame->f_exc_value);
+ PySys_SetObject("exc_traceback", frame->f_exc_traceback);
+
+ /* Clear the frame's exception info. */
+ tmp_type = frame->f_exc_type;
+ tmp_value = frame->f_exc_value;
+ tmp_tb = frame->f_exc_traceback;
+ frame->f_exc_type = NULL;
+ frame->f_exc_value = NULL;
+ frame->f_exc_traceback = NULL;
+ Py_DECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+}
+
+/* Logic for the raise statement (too complicated for inlining).
+ This *consumes* a reference count to each of its arguments. */
+static enum why_code
+do_raise(PyObject *type, PyObject *value, PyObject *tb)
+{
+ if (type == NULL) {
+ /* Reraise */
+ PyThreadState *tstate = PyThreadState_GET();
+ type = tstate->exc_type == NULL ? Py_None : tstate->exc_type;
+ value = tstate->exc_value;
+ tb = tstate->exc_traceback;
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ }
+
+ /* We support the following forms of raise:
+ raise <class>, <classinstance>
+ raise <class>, <argument tuple>
+ raise <class>, None
+ raise <class>, <argument>
+ raise <classinstance>, None
+ raise <string>, <object>
+ raise <string>, None
+
+ An omitted second argument is the same as None.
+
+ In addition, raise <tuple>, <anything> is the same as
+ raising the tuple's first item (and it better have one!);
+ this rule is applied recursively.
+
+ Finally, an optional third argument can be supplied, which
+ gives the traceback to be substituted (useful when
+ re-raising an exception after examining it). */
+
+ /* First, check the traceback argument, replacing None with
+ NULL. */
+ if (tb == Py_None) {
+ Py_DECREF(tb);
+ tb = NULL;
+ }
+ else if (tb != NULL && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+
+ /* Next, replace a missing value with None */
+ if (value == NULL) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+
+ /* Next, repeatedly, replace a tuple exception with its first item */
+ while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
+ PyObject *tmp = type;
+ type = PyTuple_GET_ITEM(type, 0);
+ Py_INCREF(type);
+ Py_DECREF(tmp);
+ }
+
+ if (PyExceptionClass_Check(type))
+ PyErr_NormalizeException(&type, &value, &tb);
+
+ else if (PyExceptionInstance_Check(type)) {
+ /* Raising an instance. The value should be a dummy. */
+ if (value != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ else {
+ /* Normalize to raise <class>, <instance> */
+ Py_DECREF(value);
+ value = type;
+ type = PyExceptionInstance_Class(type);
+ Py_INCREF(type);
+ }
+ }
+ else {
+ /* Not something you can raise. You get an exception
+ anyway, just not what you specified :-) */
+ PyErr_Format(PyExc_TypeError,
+ "exceptions must be classes or instances, not %s",
+ type->ob_type->tp_name);
+ goto raise_error;
+ }
+
+ assert(PyExceptionClass_Check(type));
+ if (Py_Py3kWarningFlag && PyClass_Check(type)) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "exceptions must derive from BaseException "
+ "in 3.x", 1) < 0)
+ goto raise_error;
+ }
+
+ PyErr_Restore(type, value, tb);
+ if (tb == NULL)
+ return WHY_EXCEPTION;
+ else
+ return WHY_RERAISE;
+ raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return WHY_EXCEPTION;
+}
+
+/* Iterate v argcnt times and store the results on the stack (via decreasing
+ sp). Return 1 for success, 0 if error. */
+
+static int
+unpack_iterable(PyObject *v, int argcnt, PyObject **sp)
+{
+ int i = 0;
+ PyObject *it; /* iter(v) */
+ PyObject *w;
+
+ assert(v != NULL);
+
+ it = PyObject_GetIter(v);
+ if (it == NULL)
+ goto Error;
+
+ for (; i < argcnt; i++) {
+ w = PyIter_Next(it);
+ if (w == NULL) {
+ /* Iterator done, via error or exhaustion. */
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %d value%s to unpack",
+ i, i == 1 ? "" : "s");
+ }
+ goto Error;
+ }
+ *--sp = w;
+ }
+
+ /* We better have exhausted the iterator now. */
+ w = PyIter_Next(it);
+ if (w == NULL) {
+ if (PyErr_Occurred())
+ goto Error;
+ Py_DECREF(it);
+ return 1;
+ }
+ Py_DECREF(w);
+ PyErr_SetString(PyExc_ValueError, "too many values to unpack");
+ /* fall through */
+Error:
+ for (; i > 0; i--, sp++)
+ Py_DECREF(*sp);
+ Py_XDECREF(it);
+ return 0;
+}
+
+
+#ifdef LLTRACE
+static int
+prtrace(PyObject *v, char *str)
+{
+ printf("%s ", str);
+ if (PyObject_Print(v, stdout, 0) != 0)
+ PyErr_Clear(); /* Don't know what else to do */
+ printf("\n");
+ return 1;
+}
+#endif
+
+static void
+call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
+{
+ PyObject *type, *value, *traceback, *arg;
+ int err;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value == NULL) {
+ value = Py_None;
+ Py_INCREF(value);
+ }
+ arg = PyTuple_Pack(3, type, value, traceback);
+ if (arg == NULL) {
+ PyErr_Restore(type, value, traceback);
+ return;
+ }
+ err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
+ Py_DECREF(arg);
+ if (err == 0)
+ PyErr_Restore(type, value, traceback);
+ else {
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ }
+}
+
+static int
+call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ PyObject *type, *value, *traceback;
+ int err;
+ PyErr_Fetch(&type, &value, &traceback);
+ err = call_trace(func, obj, frame, what, arg);
+ if (err == 0)
+ {
+ PyErr_Restore(type, value, traceback);
+ return 0;
+ }
+ else {
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
+ return -1;
+ }
+}
+
+static int
+call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
+ int what, PyObject *arg)
+{
+ register PyThreadState *tstate = frame->f_tstate;
+ int result;
+ if (tstate->tracing)
+ return 0;
+ tstate->tracing++;
+ tstate->use_tracing = 0;
+ result = func(obj, frame, what, arg);
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ tstate->tracing--;
+ return result;
+}
+
+PyObject *
+_PyEval_CallTracing(PyObject *func, PyObject *args)
+{
+ PyFrameObject *frame = PyEval_GetFrame();
+ PyThreadState *tstate = frame->f_tstate;
+ int save_tracing = tstate->tracing;
+ int save_use_tracing = tstate->use_tracing;
+ PyObject *result;
+
+ tstate->tracing = 0;
+ tstate->use_tracing = ((tstate->c_tracefunc != NULL)
+ || (tstate->c_profilefunc != NULL));
+ result = PyObject_Call(func, args, NULL);
+ tstate->tracing = save_tracing;
+ tstate->use_tracing = save_use_tracing;
+ return result;
+}
+
+static int
+maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
+ PyFrameObject *frame, int *instr_lb, int *instr_ub,
+ int *instr_prev)
+{
+ int result = 0;
+
+ /* If the last instruction executed isn't in the current
+ instruction window, reset the window. If the last
+ instruction happens to fall at the start of a line or if it
+ represents a jump backwards, call the trace function.
+ */
+ if ((frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub)) {
+ int line;
+ PyAddrPair bounds;
+
+ line = PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
+ &bounds);
+ if (line >= 0) {
+ frame->f_lineno = line;
+ result = call_trace(func, obj, frame,
+ PyTrace_LINE, Py_None);
+ }
+ *instr_lb = bounds.ap_lower;
+ *instr_ub = bounds.ap_upper;
+ }
+ else if (frame->f_lasti <= *instr_prev) {
+ result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);
+ }
+ *instr_prev = frame->f_lasti;
+ return result;
+}
+
+void
+PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject *temp = tstate->c_profileobj;
+ Py_XINCREF(arg);
+ tstate->c_profilefunc = NULL;
+ tstate->c_profileobj = NULL;
+ /* Must make sure that tracing is not ignored if 'temp' is freed */
+ tstate->use_tracing = tstate->c_tracefunc != NULL;
+ Py_XDECREF(temp);
+ tstate->c_profilefunc = func;
+ tstate->c_profileobj = arg;
+ /* Flag that tracing or profiling is turned on */
+ tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
+}
+
+void
+PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject *temp = tstate->c_traceobj;
+ Py_XINCREF(arg);
+ tstate->c_tracefunc = NULL;
+ tstate->c_traceobj = NULL;
+ /* Must make sure that profiling is not ignored if 'temp' is freed */
+ tstate->use_tracing = tstate->c_profilefunc != NULL;
+ Py_XDECREF(temp);
+ tstate->c_tracefunc = func;
+ tstate->c_traceobj = arg;
+ /* Flag that tracing or profiling is turned on */
+ tstate->use_tracing = ((func != NULL)
+ || (tstate->c_profilefunc != NULL));
+}
+
+PyObject *
+PyEval_GetBuiltins(void)
+{
+ PyFrameObject *current_frame = PyEval_GetFrame();
+ if (current_frame == NULL)
+ return PyThreadState_GET()->interp->builtins;
+ else
+ return current_frame->f_builtins;
+}
+
+PyObject *
+PyEval_GetLocals(void)
+{
+ PyFrameObject *current_frame = PyEval_GetFrame();
+ if (current_frame == NULL)
+ return NULL;
+ PyFrame_FastToLocals(current_frame);
+ return current_frame->f_locals;
+}
+
+PyObject *
+PyEval_GetGlobals(void)
+{
+ PyFrameObject *current_frame = PyEval_GetFrame();
+ if (current_frame == NULL)
+ return NULL;
+ else
+ return current_frame->f_globals;
+}
+
+PyFrameObject *
+PyEval_GetFrame(void)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ return _PyThreadState_GetFrame(tstate);
+}
+
+int
+PyEval_GetRestricted(void)
+{
+ PyFrameObject *current_frame = PyEval_GetFrame();
+ return current_frame == NULL ? 0 : PyFrame_IsRestricted(current_frame);
+}
+
+int
+PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
+{
+ PyFrameObject *current_frame = PyEval_GetFrame();
+ int result = cf->cf_flags != 0;
+
+ if (current_frame != NULL) {
+ const int codeflags = current_frame->f_code->co_flags;
+ const int compilerflags = codeflags & PyCF_MASK;
+ if (compilerflags) {
+ result = 1;
+ cf->cf_flags |= compilerflags;
+ }
+#if 0 /* future keyword */
+ if (codeflags & CO_GENERATOR_ALLOWED) {
+ result = 1;
+ cf->cf_flags |= CO_GENERATOR_ALLOWED;
+ }
+#endif
+ }
+ return result;
+}
+
+int
+Py_FlushLine(void)
+{
+ PyObject *f = PySys_GetObject("stdout");
+ if (f == NULL)
+ return 0;
+ if (!PyFile_SoftSpace(f, 0))
+ return 0;
+ return PyFile_WriteString("\n", f);
+}
+
+
+/* External interface to call any callable object.
+ The arg must be a tuple or NULL. */
+
+#undef PyEval_CallObject
+/* for backward compatibility: export this interface */
+
+PyObject *
+PyEval_CallObject(PyObject *func, PyObject *arg)
+{
+ return PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL);
+}
+#define PyEval_CallObject(func,arg) \
+ PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL)
+
+PyObject *
+PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
+{
+ PyObject *result;
+
+ if (arg == NULL) {
+ arg = PyTuple_New(0);
+ if (arg == NULL)
+ return NULL;
+ }
+ else if (!PyTuple_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "argument list must be a tuple");
+ return NULL;
+ }
+ else
+ Py_INCREF(arg);
+
+ if (kw != NULL && !PyDict_Check(kw)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keyword list must be a dictionary");
+ Py_DECREF(arg);
+ return NULL;
+ }
+
+ result = PyObject_Call(func, arg, kw);
+ Py_DECREF(arg);
+ return result;
+}
+
+const char *
+PyEval_GetFuncName(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
+ else if (PyFunction_Check(func))
+ return PyString_AsString(((PyFunctionObject*)func)->func_name);
+ else if (PyCFunction_Check(func))
+ return ((PyCFunctionObject*)func)->m_ml->ml_name;
+ else if (PyClass_Check(func))
+ return PyString_AsString(((PyClassObject*)func)->cl_name);
+ else if (PyInstance_Check(func)) {
+ return PyString_AsString(
+ ((PyInstanceObject*)func)->in_class->cl_name);
+ } else {
+ return func->ob_type->tp_name;
+ }
+}
+
+const char *
+PyEval_GetFuncDesc(PyObject *func)
+{
+ if (PyMethod_Check(func))
+ return "()";
+ else if (PyFunction_Check(func))
+ return "()";
+ else if (PyCFunction_Check(func))
+ return "()";
+ else if (PyClass_Check(func))
+ return " constructor";
+ else if (PyInstance_Check(func)) {
+ return " instance";
+ } else {
+ return " object";
+ }
+}
+
+static void
+err_args(PyObject *func, int flags, int nargs)
+{
+ if (flags & METH_NOARGS)
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%d given)",
+ ((PyCFunctionObject *)func)->m_ml->ml_name,
+ nargs);
+ else
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%d given)",
+ ((PyCFunctionObject *)func)->m_ml->ml_name,
+ nargs);
+}
+
+#define C_TRACE(x, call) \
+if (tstate->use_tracing && tstate->c_profilefunc) { \
+ if (call_trace(tstate->c_profilefunc, \
+ tstate->c_profileobj, \
+ tstate->frame, PyTrace_C_CALL, \
+ func)) { \
+ x = NULL; \
+ } \
+ else { \
+ x = call; \
+ if (tstate->c_profilefunc != NULL) { \
+ if (x == NULL) { \
+ call_trace_protected(tstate->c_profilefunc, \
+ tstate->c_profileobj, \
+ tstate->frame, PyTrace_C_EXCEPTION, \
+ func); \
+ /* XXX should pass (type, value, tb) */ \
+ } else { \
+ if (call_trace(tstate->c_profilefunc, \
+ tstate->c_profileobj, \
+ tstate->frame, PyTrace_C_RETURN, \
+ func)) { \
+ Py_DECREF(x); \
+ x = NULL; \
+ } \
+ } \
+ } \
+ } \
+} else { \
+ x = call; \
+ }
+
+static PyObject *
+call_function(PyObject ***pp_stack, int oparg
+#ifdef WITH_TSC
+ , uint64* pintr0, uint64* pintr1
+#endif
+ )
+{
+ int na = oparg & 0xff;
+ int nk = (oparg>>8) & 0xff;
+ int n = na + 2 * nk;
+ PyObject **pfunc = (*pp_stack) - n - 1;
+ PyObject *func = *pfunc;
+ PyObject *x, *w;
+
+ /* Always dispatch PyCFunction first, because these are
+ presumed to be the most frequent callable object.
+ */
+ if (PyCFunction_Check(func) && nk == 0) {
+ int flags = PyCFunction_GET_FLAGS(func);
+ PyThreadState *tstate = PyThreadState_GET();
+
+ PCALL(PCALL_CFUNCTION);
+ if (flags & (METH_NOARGS | METH_O)) {
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ if (flags & METH_NOARGS && na == 0) {
+ C_TRACE(x, (*meth)(self,NULL));
+ }
+ else if (flags & METH_O && na == 1) {
+ PyObject *arg = EXT_POP(*pp_stack);
+ C_TRACE(x, (*meth)(self,arg));
+ Py_DECREF(arg);
+ }
+ else {
+ err_args(func, flags, na);
+ x = NULL;
+ }
+ }
+ 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);
+ }
+ } else {
+ if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
+ /* optimize access to bound methods */
+ PyObject *self = PyMethod_GET_SELF(func);
+ PCALL(PCALL_METHOD);
+ PCALL(PCALL_BOUND_METHOD);
+ Py_INCREF(self);
+ func = PyMethod_GET_FUNCTION(func);
+ Py_INCREF(func);
+ Py_DECREF(*pfunc);
+ *pfunc = self;
+ na++;
+ n++;
+ } else
+ Py_INCREF(func);
+ READ_TIMESTAMP(*pintr0);
+ if (PyFunction_Check(func))
+ x = fast_function(func, pp_stack, n, na, nk);
+ else
+ x = do_call(func, pp_stack, na, nk);
+ READ_TIMESTAMP(*pintr1);
+ Py_DECREF(func);
+ }
+
+ /* Clear the stack of the function object. Also removes
+ the arguments in case they weren't consumed already
+ (fast_function() and err_args() leave them on the stack).
+ */
+ while ((*pp_stack) > pfunc) {
+ w = EXT_POP(*pp_stack);
+ Py_DECREF(w);
+ PCALL(PCALL_POP);
+ }
+ return x;
+}
+
+/* The fast_function() function optimize calls for which no argument
+ tuple is necessary; the objects are passed directly from the stack.
+ For the simplest case -- a function that takes only positional
+ arguments and is called with only positional arguments -- it
+ inlines the most primitive frame setup code from
+ PyEval_EvalCodeEx(), which vastly reduces the checks that must be
+ done before evaluating the frame.
+*/
+
+static PyObject *
+fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
+{
+ PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
+ PyObject *globals = PyFunction_GET_GLOBALS(func);
+ PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
+ PyObject **d = NULL;
+ int nd = 0;
+
+ PCALL(PCALL_FUNCTION);
+ PCALL(PCALL_FAST_FUNCTION);
+ if (argdefs == NULL && co->co_argcount == n && nk==0 &&
+ co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
+ PyFrameObject *f;
+ PyObject *retval = NULL;
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject **fastlocals, **stack;
+ int i;
+
+ PCALL(PCALL_FASTER_FUNCTION);
+ assert(globals != NULL);
+ /* XXX Perhaps we should create a specialized
+ PyFrame_New() that doesn't take locals, but does
+ take builtins without sanity checking them.
+ */
+ assert(tstate != NULL);
+ f = PyFrame_New(tstate, co, globals, NULL);
+ if (f == NULL)
+ return NULL;
+
+ fastlocals = f->f_localsplus;
+ stack = (*pp_stack) - n;
+
+ for (i = 0; i < n; i++) {
+ Py_INCREF(*stack);
+ fastlocals[i] = *stack++;
+ }
+ retval = PyEval_EvalFrameEx(f,0);
+ ++tstate->recursion_depth;
+ Py_DECREF(f);
+ --tstate->recursion_depth;
+ return retval;
+ }
+ if (argdefs != NULL) {
+ d = &PyTuple_GET_ITEM(argdefs, 0);
+ nd = Py_SIZE(argdefs);
+ }
+ return PyEval_EvalCodeEx(co, globals,
+ (PyObject *)NULL, (*pp_stack)-n, na,
+ (*pp_stack)-2*nk, nk, d, nd,
+ PyFunction_GET_CLOSURE(func));
+}
+
+static PyObject *
+update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
+ PyObject *func)
+{
+ PyObject *kwdict = NULL;
+ if (orig_kwdict == NULL)
+ kwdict = PyDict_New();
+ else {
+ kwdict = PyDict_Copy(orig_kwdict);
+ Py_DECREF(orig_kwdict);
+ }
+ if (kwdict == NULL)
+ return NULL;
+ while (--nk >= 0) {
+ int err;
+ PyObject *value = EXT_POP(*pp_stack);
+ PyObject *key = EXT_POP(*pp_stack);
+ if (PyDict_GetItem(kwdict, key) != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%s got multiple values "
+ "for keyword argument '%.200s'",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ PyString_AsString(key));
+ Py_DECREF(key);
+ Py_DECREF(value);
+ Py_DECREF(kwdict);
+ return NULL;
+ }
+ err = PyDict_SetItem(kwdict, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (err) {
+ Py_DECREF(kwdict);
+ return NULL;
+ }
+ }
+ return kwdict;
+}
+
+static PyObject *
+update_star_args(int nstack, int nstar, PyObject *stararg,
+ PyObject ***pp_stack)
+{
+ PyObject *callargs, *w;
+
+ callargs = PyTuple_New(nstack + nstar);
+ if (callargs == NULL) {
+ return NULL;
+ }
+ if (nstar) {
+ int i;
+ for (i = 0; i < nstar; i++) {
+ PyObject *a = PyTuple_GET_ITEM(stararg, i);
+ Py_INCREF(a);
+ PyTuple_SET_ITEM(callargs, nstack + i, a);
+ }
+ }
+ while (--nstack >= 0) {
+ w = EXT_POP(*pp_stack);
+ PyTuple_SET_ITEM(callargs, nstack, w);
+ }
+ return callargs;
+}
+
+static PyObject *
+load_args(PyObject ***pp_stack, int na)
+{
+ PyObject *args = PyTuple_New(na);
+ PyObject *w;
+
+ if (args == NULL)
+ return NULL;
+ while (--na >= 0) {
+ w = EXT_POP(*pp_stack);
+ PyTuple_SET_ITEM(args, na, w);
+ }
+ return args;
+}
+
+static PyObject *
+do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
+{
+ PyObject *callargs = NULL;
+ PyObject *kwdict = NULL;
+ PyObject *result = NULL;
+
+ if (nk > 0) {
+ kwdict = update_keyword_args(NULL, nk, pp_stack, func);
+ if (kwdict == NULL)
+ goto call_fail;
+ }
+ callargs = load_args(pp_stack, na);
+ if (callargs == NULL)
+ goto call_fail;
+#ifdef CALL_PROFILE
+ /* At this point, we have to look at the type of func to
+ update the call stats properly. Do it here so as to avoid
+ exposing the call stats machinery outside ceval.c
+ */
+ if (PyFunction_Check(func))
+ PCALL(PCALL_FUNCTION);
+ else if (PyMethod_Check(func))
+ PCALL(PCALL_METHOD);
+ else if (PyType_Check(func))
+ PCALL(PCALL_TYPE);
+ else
+ PCALL(PCALL_OTHER);
+#endif
+ result = PyObject_Call(func, callargs, kwdict);
+ call_fail:
+ Py_XDECREF(callargs);
+ Py_XDECREF(kwdict);
+ return result;
+}
+
+static PyObject *
+ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
+{
+ int nstar = 0;
+ PyObject *callargs = NULL;
+ PyObject *stararg = NULL;
+ PyObject *kwdict = NULL;
+ PyObject *result = NULL;
+
+ if (flags & CALL_FLAG_KW) {
+ kwdict = EXT_POP(*pp_stack);
+ if (!PyDict_Check(kwdict)) {
+ PyObject *d;
+ d = PyDict_New();
+ if (d == NULL)
+ goto ext_call_fail;
+ if (PyDict_Update(d, kwdict) != 0) {
+ Py_DECREF(d);
+ /* PyDict_Update raises attribute
+ * error (percolated from an attempt
+ * to get 'keys' attribute) instead of
+ * a type error if its second argument
+ * is not a mapping.
+ */
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s argument after ** "
+ "must be a mapping, not %.200s",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ kwdict->ob_type->tp_name);
+ }
+ goto ext_call_fail;
+ }
+ Py_DECREF(kwdict);
+ kwdict = d;
+ }
+ }
+ if (flags & CALL_FLAG_VAR) {
+ stararg = EXT_POP(*pp_stack);
+ if (!PyTuple_Check(stararg)) {
+ PyObject *t = NULL;
+ t = PySequence_Tuple(stararg);
+ if (t == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_TypeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s argument after * "
+ "must be a sequence, not %200s",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ stararg->ob_type->tp_name);
+ }
+ goto ext_call_fail;
+ }
+ Py_DECREF(stararg);
+ stararg = t;
+ }
+ nstar = PyTuple_GET_SIZE(stararg);
+ }
+ if (nk > 0) {
+ kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
+ if (kwdict == NULL)
+ goto ext_call_fail;
+ }
+ callargs = update_star_args(na, nstar, stararg, pp_stack);
+ if (callargs == NULL)
+ goto ext_call_fail;
+#ifdef CALL_PROFILE
+ /* At this point, we have to look at the type of func to
+ update the call stats properly. Do it here so as to avoid
+ exposing the call stats machinery outside ceval.c
+ */
+ if (PyFunction_Check(func))
+ PCALL(PCALL_FUNCTION);
+ else if (PyMethod_Check(func))
+ PCALL(PCALL_METHOD);
+ else if (PyType_Check(func))
+ PCALL(PCALL_TYPE);
+ else
+ PCALL(PCALL_OTHER);
+#endif
+ result = PyObject_Call(func, callargs, kwdict);
+ext_call_fail:
+ Py_XDECREF(callargs);
+ Py_XDECREF(kwdict);
+ Py_XDECREF(stararg);
+ return result;
+}
+
+/* Extract a slice index from a PyInt or PyLong or an object with the
+ nb_index slot defined, and store in *pi.
+ Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
+ and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
+ Return 0 on error, 1 on success.
+*/
+/* Note: If v is NULL, return success without storing into *pi. This
+ is because_PyEval_SliceIndex() is called by apply_slice(), which can be
+ called by the SLICE opcode with v and/or w equal to NULL.
+*/
+int
+_PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
+{
+ if (v != NULL) {
+ Py_ssize_t x;
+ if (PyInt_Check(v)) {
+ /* XXX(nnorwitz): I think PyInt_AS_LONG is correct,
+ however, it looks like it should be AsSsize_t.
+ There should be a comment here explaining why.
+ */
+ x = PyInt_AS_LONG(v);
+ }
+ else if (PyIndex_Check(v)) {
+ x = PyNumber_AsSsize_t(v, NULL);
+ if (x == -1 && PyErr_Occurred())
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "slice indices must be integers or "
+ "None or have an __index__ method");
+ return 0;
+ }
+ *pi = x;
+ }
+ return 1;
+}
+
+#undef ISINDEX
+#define ISINDEX(x) ((x) == NULL || \
+ PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x))
+
+static PyObject *
+apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
+{
+ PyTypeObject *tp = u->ob_type;
+ PySequenceMethods *sq = tp->tp_as_sequence;
+
+ if (sq && sq->sq_slice && ISINDEX(v) && ISINDEX(w)) {
+ Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
+ if (!_PyEval_SliceIndex(v, &ilow))
+ return NULL;
+ if (!_PyEval_SliceIndex(w, &ihigh))
+ return NULL;
+ return PySequence_GetSlice(u, ilow, ihigh);
+ }
+ else {
+ PyObject *slice = PySlice_New(v, w, NULL);
+ if (slice != NULL) {
+ PyObject *res = PyObject_GetItem(u, slice);
+ Py_DECREF(slice);
+ return res;
+ }
+ else
+ return NULL;
+ }
+}
+
+static int
+assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
+ /* u[v:w] = x */
+{
+ PyTypeObject *tp = u->ob_type;
+ PySequenceMethods *sq = tp->tp_as_sequence;
+
+ if (sq && sq->sq_ass_slice && ISINDEX(v) && ISINDEX(w)) {
+ Py_ssize_t ilow = 0, ihigh = PY_SSIZE_T_MAX;
+ if (!_PyEval_SliceIndex(v, &ilow))
+ return -1;
+ if (!_PyEval_SliceIndex(w, &ihigh))
+ return -1;
+ if (x == NULL)
+ return PySequence_DelSlice(u, ilow, ihigh);
+ else
+ return PySequence_SetSlice(u, ilow, ihigh, x);
+ }
+ else {
+ PyObject *slice = PySlice_New(v, w, NULL);
+ if (slice != NULL) {
+ int res;
+ if (x != NULL)
+ res = PyObject_SetItem(u, slice, x);
+ else
+ res = PyObject_DelItem(u, slice);
+ Py_DECREF(slice);
+ return res;
+ }
+ else
+ return -1;
+ }
+}
+
+#define Py3kExceptionClass_Check(x) \
+ (PyType_Check((x)) && \
+ PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS))
+
+#define CANNOT_CATCH_MSG "catching classes that don't inherit from " \
+ "BaseException is not allowed in 3.x"
+
+static PyObject *
+cmp_outcome(int op, register PyObject *v, register PyObject *w)
+{
+ int res = 0;
+ switch (op) {
+ case PyCmp_IS:
+ res = (v == w);
+ break;
+ case PyCmp_IS_NOT:
+ res = (v != w);
+ break;
+ case PyCmp_IN:
+ res = PySequence_Contains(w, v);
+ if (res < 0)
+ return NULL;
+ break;
+ case PyCmp_NOT_IN:
+ res = PySequence_Contains(w, v);
+ if (res < 0)
+ return NULL;
+ res = !res;
+ break;
+ case PyCmp_EXC_MATCH:
+ if (PyTuple_Check(w)) {
+ Py_ssize_t i, length;
+ length = PyTuple_Size(w);
+ for (i = 0; i < length; i += 1) {
+ PyObject *exc = PyTuple_GET_ITEM(w, i);
+ if (PyString_Check(exc)) {
+ int ret_val;
+ ret_val = PyErr_WarnEx(
+ PyExc_DeprecationWarning,
+ "catching of string "
+ "exceptions is deprecated", 1);
+ if (ret_val < 0)
+ return NULL;
+ }
+ else if (Py_Py3kWarningFlag &&
+ !PyTuple_Check(exc) &&
+ !Py3kExceptionClass_Check(exc))
+ {
+ int ret_val;
+ ret_val = PyErr_WarnEx(
+ PyExc_DeprecationWarning,
+ CANNOT_CATCH_MSG, 1);
+ if (ret_val < 0)
+ return NULL;
+ }
+ }
+ }
+ else {
+ if (PyString_Check(w)) {
+ int ret_val;
+ ret_val = PyErr_WarnEx(
+ PyExc_DeprecationWarning,
+ "catching of string "
+ "exceptions is deprecated", 1);
+ if (ret_val < 0)
+ return NULL;
+ }
+ else if (Py_Py3kWarningFlag &&
+ !PyTuple_Check(w) &&
+ !Py3kExceptionClass_Check(w))
+ {
+ int ret_val;
+ ret_val = PyErr_WarnEx(
+ PyExc_DeprecationWarning,
+ CANNOT_CATCH_MSG, 1);
+ if (ret_val < 0)
+ return NULL;
+ }
+ }
+ res = PyErr_GivenExceptionMatches(v, w);
+ break;
+ default:
+ return PyObject_RichCompare(v, w, op);
+ }
+ v = res ? Py_True : Py_False;
+ Py_INCREF(v);
+ return v;
+}
+
+static PyObject *
+import_from(PyObject *v, PyObject *name)
+{
+ PyObject *x;
+
+ x = PyObject_GetAttr(v, name);
+ if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_ImportError,
+ "cannot import name %.230s",
+ PyString_AsString(name));
+ }
+ return x;
+}
+
+static int
+import_all_from(PyObject *locals, PyObject *v)
+{
+ PyObject *all = PyObject_GetAttrString(v, "__all__");
+ PyObject *dict, *name, *value;
+ int skip_leading_underscores = 0;
+ int pos, err;
+
+ if (all == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1; /* Unexpected error */
+ PyErr_Clear();
+ dict = PyObject_GetAttrString(v, "__dict__");
+ if (dict == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ return -1;
+ PyErr_SetString(PyExc_ImportError,
+ "from-import-* object has no __dict__ and no __all__");
+ return -1;
+ }
+ all = PyMapping_Keys(dict);
+ Py_DECREF(dict);
+ if (all == NULL)
+ return -1;
+ skip_leading_underscores = 1;
+ }
+
+ for (pos = 0, err = 0; ; pos++) {
+ name = PySequence_GetItem(all, pos);
+ if (name == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_IndexError))
+ err = -1;
+ else
+ PyErr_Clear();
+ break;
+ }
+ if (skip_leading_underscores &&
+ PyString_Check(name) &&
+ PyString_AS_STRING(name)[0] == '_')
+ {
+ Py_DECREF(name);
+ continue;
+ }
+ value = PyObject_GetAttr(v, name);
+ if (value == NULL)
+ err = -1;
+ else if (PyDict_CheckExact(locals))
+ err = PyDict_SetItem(locals, name, value);
+ else
+ err = PyObject_SetItem(locals, name, value);
+ Py_DECREF(name);
+ Py_XDECREF(value);
+ if (err != 0)
+ break;
+ }
+ Py_DECREF(all);
+ return err;
+}
+
+static PyObject *
+build_class(PyObject *methods, PyObject *bases, PyObject *name)
+{
+ PyObject *metaclass = NULL, *result, *base;
+
+ if (PyDict_Check(methods))
+ metaclass = PyDict_GetItemString(methods, "__metaclass__");
+ if (metaclass != NULL)
+ Py_INCREF(metaclass);
+ else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
+ base = PyTuple_GET_ITEM(bases, 0);
+ metaclass = PyObject_GetAttrString(base, "__class__");
+ if (metaclass == NULL) {
+ PyErr_Clear();
+ metaclass = (PyObject *)base->ob_type;
+ Py_INCREF(metaclass);
+ }
+ }
+ else {
+ PyObject *g = PyEval_GetGlobals();
+ if (g != NULL && PyDict_Check(g))
+ metaclass = PyDict_GetItemString(g, "__metaclass__");
+ if (metaclass == NULL)
+ metaclass = (PyObject *) &PyClass_Type;
+ Py_INCREF(metaclass);
+ }
+ result = PyObject_CallFunctionObjArgs(metaclass, name, bases, methods,
+ NULL);
+ Py_DECREF(metaclass);
+ if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) {
+ /* A type error here likely means that the user passed
+ in a base that was not a class (such the random module
+ instead of the random.random type). Help them out with
+ by augmenting the error message with more information.*/
+
+ PyObject *ptype, *pvalue, *ptraceback;
+
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ if (PyString_Check(pvalue)) {
+ PyObject *newmsg;
+ newmsg = PyString_FromFormat(
+ "Error when calling the metaclass bases\n"
+ " %s",
+ PyString_AS_STRING(pvalue));
+ if (newmsg != NULL) {
+ Py_DECREF(pvalue);
+ pvalue = newmsg;
+ }
+ }
+ PyErr_Restore(ptype, pvalue, ptraceback);
+ }
+ return result;
+}
+
+static int
+exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
+ PyObject *locals)
+{
+ int n;
+ PyObject *v;
+ int plain = 0;
+
+ if (PyTuple_Check(prog) && globals == Py_None && locals == Py_None &&
+ ((n = PyTuple_Size(prog)) == 2 || n == 3)) {
+ /* Backward compatibility hack */
+ globals = PyTuple_GetItem(prog, 1);
+ if (n == 3)
+ locals = PyTuple_GetItem(prog, 2);
+ prog = PyTuple_GetItem(prog, 0);
+ }
+ if (globals == Py_None) {
+ globals = PyEval_GetGlobals();
+ if (locals == Py_None) {
+ locals = PyEval_GetLocals();
+ plain = 1;
+ }
+ if (!globals || !locals) {
+ PyErr_SetString(PyExc_SystemError,
+ "globals and locals cannot be NULL");
+ return -1;
+ }
+ }
+ else if (locals == Py_None)
+ locals = globals;
+ if (!PyString_Check(prog) &&
+ !PyUnicode_Check(prog) &&
+ !PyCode_Check(prog) &&
+ !PyFile_Check(prog)) {
+ PyErr_SetString(PyExc_TypeError,
+ "exec: arg 1 must be a string, file, or code object");
+ return -1;
+ }
+ if (!PyDict_Check(globals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "exec: arg 2 must be a dictionary or None");
+ return -1;
+ }
+ if (!PyMapping_Check(locals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "exec: arg 3 must be a mapping or None");
+ return -1;
+ }
+ if (PyDict_GetItemString(globals, "__builtins__") == NULL)
+ PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
+ if (PyCode_Check(prog)) {
+ if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "code object passed to exec may not contain free variables");
+ return -1;
+ }
+ v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
+ }
+ else if (PyFile_Check(prog)) {
+ FILE *fp = PyFile_AsFile(prog);
+ char *name = PyString_AsString(PyFile_Name(prog));
+ PyCompilerFlags cf;
+ if (name == NULL)
+ return -1;
+ cf.cf_flags = 0;
+ if (PyEval_MergeCompilerFlags(&cf))
+ v = PyRun_FileFlags(fp, name, Py_file_input, globals,
+ locals, &cf);
+ else
+ v = PyRun_File(fp, name, Py_file_input, globals,
+ locals);
+ }
+ else {
+ PyObject *tmp = NULL;
+ char *str;
+ PyCompilerFlags cf;
+ cf.cf_flags = 0;
+#ifdef Py_USING_UNICODE
+ if (PyUnicode_Check(prog)) {
+ tmp = PyUnicode_AsUTF8String(prog);
+ if (tmp == NULL)
+ return -1;
+ prog = tmp;
+ cf.cf_flags |= PyCF_SOURCE_IS_UTF8;
+ }
+#endif
+ if (PyString_AsStringAndSize(prog, &str, NULL))
+ return -1;
+ if (PyEval_MergeCompilerFlags(&cf))
+ v = PyRun_StringFlags(str, Py_file_input, globals,
+ locals, &cf);
+ else
+ v = PyRun_String(str, Py_file_input, globals, locals);
+ Py_XDECREF(tmp);
+ }
+ if (plain)
+ PyFrame_LocalsToFast(f, 0);
+ if (v == NULL)
+ return -1;
+ Py_DECREF(v);
+ return 0;
+}
+
+static void
+format_exc_check_arg(PyObject *exc, char *format_str, PyObject *obj)
+{
+ char *obj_str;
+
+ if (!obj)
+ return;
+
+ obj_str = PyString_AsString(obj);
+ if (!obj_str)
+ return;
+
+ PyErr_Format(exc, format_str, obj_str);
+}
+
+static PyObject *
+string_concatenate(PyObject *v, PyObject *w,
+ PyFrameObject *f, unsigned char *next_instr)
+{
+ /* This function implements 'variable += expr' when both arguments
+ are strings. */
+ Py_ssize_t v_len = PyString_GET_SIZE(v);
+ Py_ssize_t w_len = PyString_GET_SIZE(w);
+ Py_ssize_t new_len = v_len + w_len;
+ if (new_len < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "strings are too large to concat");
+ return NULL;
+ }
+
+ if (v->ob_refcnt == 2) {
+ /* In the common case, there are 2 references to the value
+ * stored in 'variable' when the += is performed: one on the
+ * value stack (in 'v') and one still stored in the
+ * 'variable'. We try to delete the variable now to reduce
+ * the refcnt to 1.
+ */
+ switch (*next_instr) {
+ case STORE_FAST:
+ {
+ int oparg = PEEKARG();
+ PyObject **fastlocals = f->f_localsplus;
+ if (GETLOCAL(oparg) == v)
+ SETLOCAL(oparg, NULL);
+ break;
+ }
+ case STORE_DEREF:
+ {
+ PyObject **freevars = (f->f_localsplus +
+ f->f_code->co_nlocals);
+ PyObject *c = freevars[PEEKARG()];
+ if (PyCell_GET(c) == v)
+ PyCell_Set(c, NULL);
+ break;
+ }
+ case STORE_NAME:
+ {
+ PyObject *names = f->f_code->co_names;
+ PyObject *name = GETITEM(names, PEEKARG());
+ PyObject *locals = f->f_locals;
+ if (PyDict_CheckExact(locals) &&
+ PyDict_GetItem(locals, name) == v) {
+ if (PyDict_DelItem(locals, name) != 0) {
+ PyErr_Clear();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (v->ob_refcnt == 1 && !PyString_CHECK_INTERNED(v)) {
+ /* Now we own the last reference to 'v', so we can resize it
+ * in-place.
+ */
+ if (_PyString_Resize(&v, new_len) != 0) {
+ /* XXX if _PyString_Resize() fails, 'v' has been
+ * deallocated so it cannot be put back into
+ * 'variable'. The MemoryError is raised when there
+ * is no value in 'variable', which might (very
+ * remotely) be a cause of incompatibilities.
+ */
+ return NULL;
+ }
+ /* copy 'w' into the newly allocated area of 'v' */
+ memcpy(PyString_AS_STRING(v) + v_len,
+ PyString_AS_STRING(w), w_len);
+ return v;
+ }
+ else {
+ /* When in-place resizing is not an option. */
+ PyString_Concat(&v, w);
+ return v;
+ }
+}
+
+#ifdef DYNAMIC_EXECUTION_PROFILE
+
+static PyObject *
+getarray(long a[256])
+{
+ int i;
+ PyObject *l = PyList_New(256);
+ if (l == NULL) return NULL;
+ for (i = 0; i < 256; i++) {
+ PyObject *x = PyInt_FromLong(a[i]);
+ if (x == NULL) {
+ Py_DECREF(l);
+ return NULL;
+ }
+ PyList_SetItem(l, i, x);
+ }
+ for (i = 0; i < 256; i++)
+ a[i] = 0;
+ return l;
+}
+
+PyObject *
+_Py_GetDXProfile(PyObject *self, PyObject *args)
+{
+#ifndef DXPAIRS
+ return getarray(dxp);
+#else
+ int i;
+ PyObject *l = PyList_New(257);
+ if (l == NULL) return NULL;
+ for (i = 0; i < 257; i++) {
+ PyObject *x = getarray(dxpairs[i]);
+ if (x == NULL) {
+ Py_DECREF(l);
+ return NULL;
+ }
+ PyList_SetItem(l, i, x);
+ }
+ return l;
+#endif
+}
+
+#endif