summaryrefslogtreecommitdiff
path: root/tests/examplefiles/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/examplefiles/ceval.c')
-rw-r--r--tests/examplefiles/ceval.c2604
1 files changed, 0 insertions, 2604 deletions
diff --git a/tests/examplefiles/ceval.c b/tests/examplefiles/ceval.c
deleted file mode 100644
index c6739630..00000000
--- a/tests/examplefiles/ceval.c
+++ /dev/null
@@ -1,2604 +0,0 @@
-
-/* 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 void 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("iiiiiiiiii",
- pcall[0], pcall[1], pcall[2], pcall[3],
- pcall[4], pcall[5], pcall[6], pcall[7],
- pcall[8], pcall[9]);
-}
-#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)
-{
- 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();
-}
-#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)
-{
- /* XXX raise SystemError if globals is NULL */
- 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 register
- variable against a constant. If the pairing was good, then the
- processor has a high likelihood of making its own successful branch
- prediction which results 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 HASARG test and the switch-case.
-
- If collecting opcode statistics, turn off prediction so that
- statistics are accurately maintained (the predictions bypass
- the opcode frequency counter updates).
-*/
-
-#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) (lltrace && prtrace(*(STACK_POINTER), "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(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(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. */
- 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) {
- err = PyFile_WriteString("\n", w);
- if (err == 0)
- PyFile_SoftSpace(w, 0);
- }
- 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;
-
- 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 {
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- PyErr_SetString(PyExc_TypeError,
- "unpack non-sequence");
- 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_New();
- PUSH(x);
- if (x != NULL) 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;
- }
- 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();
- x = NULL;
- break;
- }
- READ_TIMESTAMP(intr0);
- x = PyEval_CallObject(x, w);
- 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);
- continue;
-
- 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:
- {
- /* TOP is the context.__exit__ bound method.
- Below that are 1-3 values indicating how/why
- we entered the finally clause:
- - SECOND = None
- - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval
- - SECOND = WHY_*; no retval below it
- - (SECOND, THIRD, FOURTH) = exc_info()
- In the last case, we must call
- TOP(SECOND, THIRD, FOURTH)
- otherwise we must call
- TOP(None, None, None)
-
- 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.)
- */
-
- x = TOP();
- u = SECOND();
- if (PyInt_Check(u) || u == Py_None) {
- u = v = w = Py_None;
- }
- else {
- v = THIRD();
- w = FOURTH();
- }
- /* XXX Not the fastest way to call it... */
- x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL);
- if (x == NULL)
- break; /* Go to error exit */
- if (u != Py_None && PyObject_IsTrue(x)) {
- /* There was an exception and a true return */
- Py_DECREF(x);
- x = TOP(); /* Again */
- STACKADJ(-3);
- Py_INCREF(Py_None);
- SET_TOP(Py_None);
- Py_DECREF(x);
- Py_DECREF(u);
- Py_DECREF(v);
- Py_DECREF(w);
- } else {
- /* Let END_FINALLY do its thing */
- Py_DECREF(x);
- x = POP();
- Py_DECREF(x);
- }
- 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[1024];
- 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;
-}
-