diff options
Diffstat (limited to 'Python')
-rw-r--r-- | Python/compile.c | 43 | ||||
-rw-r--r-- | Python/symtable.c | 21 | ||||
-rw-r--r-- | Python/sysmodule.c | 2 | ||||
-rw-r--r-- | Python/thread.c | 3 | ||||
-rw-r--r-- | Python/thread_nt.h | 60 | ||||
-rw-r--r-- | Python/thread_os2.h | 3 |
6 files changed, 94 insertions, 38 deletions
diff --git a/Python/compile.c b/Python/compile.c index 199cac5ac5..6d96006f31 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2141,7 +2141,7 @@ static int compiler_if(struct compiler *c, stmt_ty s) { basicblock *end, *next; - + int constant; assert(s->kind == If_kind); end = compiler_new_block(c); if (end == NULL) @@ -2149,15 +2149,27 @@ compiler_if(struct compiler *c, stmt_ty s) next = compiler_new_block(c); if (next == NULL) return 0; - VISIT(c, expr, s->v.If.test); - ADDOP_JREL(c, JUMP_IF_FALSE, next); - ADDOP(c, POP_TOP); - VISIT_SEQ(c, stmt, s->v.If.body); - ADDOP_JREL(c, JUMP_FORWARD, end); - compiler_use_next_block(c, next); - ADDOP(c, POP_TOP); - if (s->v.If.orelse) - VISIT_SEQ(c, stmt, s->v.If.orelse); + + constant = expr_constant(s->v.If.test); + /* constant = 0: "if 0" + * constant = 1: "if 1", "if 2", ... + * constant = -1: rest */ + if (constant == 0) { + if (s->v.If.orelse) + VISIT_SEQ(c, stmt, s->v.If.orelse); + } else if (constant == 1) { + VISIT_SEQ(c, stmt, s->v.If.body); + } else { + VISIT(c, expr, s->v.If.test); + ADDOP_JREL(c, JUMP_IF_FALSE, next); + ADDOP(c, POP_TOP); + VISIT_SEQ(c, stmt, s->v.If.body); + ADDOP_JREL(c, JUMP_FORWARD, end); + compiler_use_next_block(c, next); + ADDOP(c, POP_TOP); + if (s->v.If.orelse) + VISIT_SEQ(c, stmt, s->v.If.orelse); + } compiler_use_next_block(c, end); return 1; } @@ -2623,10 +2635,6 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) if (c->u->u_ste->ste_type != FunctionBlock) return compiler_error(c, "'return' outside function"); if (s->v.Return.value) { - if (c->u->u_ste->ste_generator) { - return compiler_error(c, - "'return' with argument inside generator"); - } VISIT(c, expr, s->v.Return.value); } else @@ -3334,6 +3342,13 @@ expr_constant(expr_ty e) return PyObject_IsTrue(e->v.Num.n); case Str_kind: return PyObject_IsTrue(e->v.Str.s); + case Name_kind: + /* __debug__ is not assignable, so we can optimize + * it away in if and while statements */ + if (strcmp(PyString_AS_STRING(e->v.Name.id), + "__debug__") == 0) + return ! Py_OptimizeFlag; + /* fall through */ default: return -1; } diff --git a/Python/symtable.c b/Python/symtable.c index 184723d5dc..1dc2a2ea74 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -13,6 +13,8 @@ #define IMPORT_STAR_WARNING "import * only allowed at module level" +#define RETURN_VAL_IN_GENERATOR \ + "'return' with argument inside generator" /* XXX(nnorwitz): change name since static? */ static PySTEntryObject * @@ -66,6 +68,7 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_nested = 1; ste->ste_child_free = 0; ste->ste_generator = 0; + ste->ste_returns_value = 0; if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0) goto fail; @@ -944,8 +947,17 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; } case Return_kind: - if (s->v.Return.value) + if (s->v.Return.value) { VISIT(st, expr, s->v.Return.value); + st->st_cur->ste_returns_value = 1; + if (st->st_cur->ste_generator) { + PyErr_SetString(PyExc_SyntaxError, + RETURN_VAL_IN_GENERATOR); + PyErr_SyntaxLocation(st->st_filename, + s->lineno); + return 0; + } + } break; case Delete_kind: VISIT_SEQ(st, expr, s->v.Delete.targets); @@ -1136,6 +1148,13 @@ symtable_visit_expr(struct symtable *st, expr_ty e) if (e->v.Yield.value) VISIT(st, expr, e->v.Yield.value); st->st_cur->ste_generator = 1; + if (st->st_cur->ste_returns_value) { + PyErr_SetString(PyExc_SyntaxError, + RETURN_VAL_IN_GENERATOR); + PyErr_SyntaxLocation(st->st_filename, + e->lineno); + return 0; + } break; case Compare_kind: VISIT(st, expr, e->v.Compare.left); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 4c92a90210..fe47fd19ba 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1027,7 +1027,7 @@ _PySys_Init(void) PyObject *sysin, *sysout, *syserr; char *s; #ifdef MS_WINDOWS - char buf[10]; + char buf[128]; #endif m = Py_InitModule3("sys", sys_methods, sys_doc); diff --git a/Python/thread.c b/Python/thread.c index 5e7fc6ccc1..c9356dcbfd 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -75,7 +75,8 @@ static int initialized; static void PyThread__init_thread(void); /* Forward */ -void PyThread_init_thread(void) +void +PyThread_init_thread(void) { #ifdef Py_DEBUG char *p = getenv("THREADDEBUG"); diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 5141053b03..0b7e84ece1 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -16,7 +16,8 @@ typedef struct NRMUTEX { typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; /* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */ -static PVOID WINAPI interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand) +static PVOID WINAPI +interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand) { static LONG spinlock = 0 ; PVOID result ; @@ -54,8 +55,10 @@ static PVOID WINAPI interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand return result ; } ; -static interlocked_cmp_xchg_t *ixchg ; -BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) +static interlocked_cmp_xchg_t *ixchg; + +BOOL +InitializeNonRecursiveMutex(PNRMUTEX mutex) { if (!ixchg) { @@ -76,14 +79,16 @@ BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) #endif #define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand))) -VOID DeleteNonRecursiveMutex(PNRMUTEX mutex) +VOID +DeleteNonRecursiveMutex(PNRMUTEX mutex) { /* No in-use check */ CloseHandle(mutex->hevent) ; mutex->hevent = NULL ; /* Just in case */ } -DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) +DWORD +EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) { /* Assume that the thread waits successfully */ DWORD ret ; @@ -104,7 +109,8 @@ DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) return ret ; } -BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex) +BOOL +LeaveNonRecursiveMutex(PNRMUTEX mutex) { /* We don't own the mutex */ mutex->thread_id = 0 ; @@ -113,7 +119,8 @@ BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex) SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */ } -PNRMUTEX AllocNonRecursiveMutex(void) +PNRMUTEX +AllocNonRecursiveMutex(void) { PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ; if (mutex && !InitializeNonRecursiveMutex(mutex)) @@ -124,7 +131,8 @@ PNRMUTEX AllocNonRecursiveMutex(void) return mutex ; } -void FreeNonRecursiveMutex(PNRMUTEX mutex) +void +FreeNonRecursiveMutex(PNRMUTEX mutex) { if (mutex) { @@ -138,7 +146,8 @@ long PyThread_get_thread_ident(void); /* * Initialization of the C package, should not be needed. */ -static void PyThread__init_thread(void) +static void +PyThread__init_thread(void) { } @@ -209,7 +218,8 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) * Return the thread Id instead of an handle. The Id is said to uniquely identify the * thread in the system */ -long PyThread_get_thread_ident(void) +long +PyThread_get_thread_ident(void) { if (!initialized) PyThread_init_thread(); @@ -217,7 +227,8 @@ long PyThread_get_thread_ident(void) return GetCurrentThreadId(); } -static void do_PyThread_exit_thread(int no_cleanup) +static void +do_PyThread_exit_thread(int no_cleanup) { dprintf(("%ld: PyThread_exit_thread called\n", PyThread_get_thread_ident())); if (!initialized) @@ -228,18 +239,21 @@ static void do_PyThread_exit_thread(int no_cleanup) _endthread(); } -void PyThread_exit_thread(void) +void +PyThread_exit_thread(void) { do_PyThread_exit_thread(0); } -void PyThread__exit_thread(void) +void +PyThread__exit_thread(void) { do_PyThread_exit_thread(1); } #ifndef NO_EXIT_PROG -static void do_PyThread_exit_prog(int status, int no_cleanup) +static void +do_PyThread_exit_prog(int status, int no_cleanup) { dprintf(("PyThread_exit_prog(%d) called\n", status)); if (!initialized) @@ -249,12 +263,14 @@ static void do_PyThread_exit_prog(int status, int no_cleanup) exit(status); } -void PyThread_exit_prog(int status) +void +PyThread_exit_prog(int status) { do_PyThread_exit_prog(status, 0); } -void PyThread__exit_prog(int status) +void +PyThread__exit_prog(int status) { do_PyThread_exit_prog(status, 1); } @@ -265,7 +281,8 @@ void PyThread__exit_prog(int status) * I [Dag] tried to implement it with mutex but I could find a way to * tell whether a thread already own the lock or not. */ -PyThread_type_lock PyThread_allocate_lock(void) +PyThread_type_lock +PyThread_allocate_lock(void) { PNRMUTEX aLock; @@ -280,7 +297,8 @@ PyThread_type_lock PyThread_allocate_lock(void) return (PyThread_type_lock) aLock; } -void PyThread_free_lock(PyThread_type_lock aLock) +void +PyThread_free_lock(PyThread_type_lock aLock) { dprintf(("%ld: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); @@ -293,7 +311,8 @@ void PyThread_free_lock(PyThread_type_lock aLock) * and 0 if the lock was not acquired. This means a 0 is returned * if the lock has already been acquired by this thread! */ -int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) +int +PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) { int success ; @@ -306,7 +325,8 @@ int PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) return success; } -void PyThread_release_lock(PyThread_type_lock aLock) +void +PyThread_release_lock(PyThread_type_lock aLock) { dprintf(("%ld: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); diff --git a/Python/thread_os2.h b/Python/thread_os2.h index a18ce6fd6c..86e91c1e1a 100644 --- a/Python/thread_os2.h +++ b/Python/thread_os2.h @@ -238,7 +238,8 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) return 1; } -void PyThread_release_lock(PyThread_type_lock aLock) +void +PyThread_release_lock(PyThread_type_lock aLock) { #if !defined(PYCC_GCC) type_os2_lock lock = (type_os2_lock)aLock; |