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