diff options
Diffstat (limited to 'Python/compile.c')
| -rw-r--r-- | Python/compile.c | 43 | 
1 files changed, 29 insertions, 14 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;  	}  | 
