Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.27.2.41.2.85
diff -u -r1.647.2.27.2.41.2.85 zend_compile.c
--- Zend/zend_compile.c	29 Aug 2008 10:17:08 -0000	1.647.2.27.2.41.2.85
+++ Zend/zend_compile.c	29 Aug 2008 10:22:23 -0000
@@ -267,10 +267,23 @@
 }
 
 
-void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC)
+void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC)
 {
-	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+	zend_op *opline;
+	binary_op_type binary_op;
+
+	if (op1->op_type == IS_CONST && op2->op_type == IS_CONST && (binary_op = get_binary_op(op))) {
+		binary_op(&result->u.constant, &op1->u.constant, &op2->u.constant TSRMLS_CC);
+		zval_dtor(&op1->u.constant);
+		zval_dtor(&op2->u.constant);
 
+		INIT_PZVAL(&result->u.constant);
+		result->op_type = IS_CONST;
+
+		return;
+	}
+
+	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 	opline->opcode = op;
 	opline->result.op_type = IS_TMP_VAR;
 	opline->result.u.var = get_temporary_variable(CG(active_op_array));
@@ -280,10 +293,22 @@
 }
 
 
-void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC)
+void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC)
 {
-	zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+	zend_op *opline;
+	unary_op_type unary_op;
+
+	if (op1->op_type == IS_CONST && (unary_op = get_unary_op(op))) {
+		unary_op(&result->u.constant, &op1->u.constant TSRMLS_CC);
+		zval_dtor(&op1->u.constant);
 
+		INIT_PZVAL(&result->u.constant);
+		result->op_type = IS_CONST;
+
+		return;
+	}
+
+	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 	opline->opcode = op;
 	opline->result.op_type = IS_TMP_VAR;
 	opline->result.u.var = get_temporary_variable(CG(active_op_array));
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.8.2.12.2.32
diff -u -r1.316.2.8.2.12.2.32 zend_compile.h
--- Zend/zend_compile.h	12 Aug 2008 17:20:24 -0000	1.316.2.8.2.12.2.32
+++ Zend/zend_compile.h	29 Aug 2008 08:46:00 -0000
@@ -369,8 +369,8 @@
 
 
 /* parser-driven code generators */
-void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
-void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC);
+void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
+void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
 void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
 void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC);
 void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC);
@@ -386,9 +386,10 @@
 void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC);
 void zend_do_print(znode *result, const znode *arg TSRMLS_DC);
 void zend_do_echo(const znode *arg TSRMLS_DC);
-typedef int (*unary_op_type)(zval *, zval *);
+typedef int (*unary_op_type)(zval *, zval * TSRMLS_DC);
+typedef int (*binary_op_type)(zval *, zval *, zval * TSRMLS_DC);
 ZEND_API unary_op_type get_unary_op(int opcode);
-ZEND_API void *get_binary_op(int opcode);
+ZEND_API binary_op_type get_binary_op(int opcode);
 
 void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC);
 void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC);
Index: Zend/zend_language_parser.y
===================================================================
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
retrieving revision 1.160.2.4.2.8.2.25
diff -u -r1.160.2.4.2.8.2.25 zend_language_parser.y
--- Zend/zend_language_parser.y	12 Aug 2008 10:23:02 -0000	1.160.2.4.2.8.2.25
+++ Zend/zend_language_parser.y	28 Aug 2008 16:00:00 -0000
@@ -609,8 +609,8 @@
 	|	expr '%' expr 	{ zend_do_binary_op(ZEND_MOD, &$$, &$1, &$3 TSRMLS_CC); }
 	| 	expr T_SL expr	{ zend_do_binary_op(ZEND_SL, &$$, &$1, &$3 TSRMLS_CC); }
 	|	expr T_SR expr	{ zend_do_binary_op(ZEND_SR, &$$, &$1, &$3 TSRMLS_CC); }
-	|	'+' expr %prec T_INC { Z_LVAL($1.u.constant)=0; Z_TYPE($1.u.constant)=IS_LONG; $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_ADD, &$$, &$1, &$2 TSRMLS_CC); }
-	|	'-' expr %prec T_INC { Z_LVAL($1.u.constant)=0; Z_TYPE($1.u.constant)=IS_LONG; $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_SUB, &$$, &$1, &$2 TSRMLS_CC); }
+	|	'+' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_ADD, &$$, &$1, &$2 TSRMLS_CC); }
+	|	'-' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_SUB, &$$, &$1, &$2 TSRMLS_CC); }
 	|	'!' expr { zend_do_unary_op(ZEND_BOOL_NOT, &$$, &$2 TSRMLS_CC); }
 	|	'~' expr { zend_do_unary_op(ZEND_BW_NOT, &$$, &$2 TSRMLS_CC); }
 	|	expr T_IS_IDENTICAL expr		{ zend_do_binary_op(ZEND_IS_IDENTICAL, &$$, &$1, &$3 TSRMLS_CC); }
@@ -768,8 +768,8 @@
 		common_scalar		{ $$ = $1; }
 	|	T_STRING 		{ zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); }
 	|	T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); }
-	|	'+' static_scalar	{ $$ = $2; }
-	|	'-' static_scalar	{ zval minus_one;  Z_TYPE(minus_one) = IS_LONG; Z_LVAL(minus_one) = -1;  mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC);  $$ = $2; }
+	|	'+' static_scalar { ZVAL_LONG(&$1.u.constant, 0); add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; }
+	|	'-' static_scalar { ZVAL_LONG(&$1.u.constant, 0); sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; }
 	|	T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; }
 	|	static_class_constant { $$ = $1; }
 ;
Index: Zend/zend_opcode.c
===================================================================
RCS file: /repository/ZendEngine2/zend_opcode.c,v
retrieving revision 1.110.2.6.2.3.2.8
diff -u -r1.110.2.6.2.3.2.8 zend_opcode.c
--- Zend/zend_opcode.c	7 May 2008 12:04:37 -0000	1.110.2.6.2.3.2.8
+++ Zend/zend_opcode.c	30 Jul 2008 11:13:58 -0000
@@ -437,73 +437,76 @@
 	}
 }
 
-ZEND_API void *get_binary_op(int opcode)
+ZEND_API binary_op_type get_binary_op(int opcode)
 {
 	switch (opcode) {
 		case ZEND_ADD:
 		case ZEND_ASSIGN_ADD:
-			return (void *) add_function;
+			return (binary_op_type) add_function;
 			break;
 		case ZEND_SUB:
 		case ZEND_ASSIGN_SUB:
-			return (void *) sub_function;
+			return (binary_op_type) sub_function;
 			break;
 		case ZEND_MUL:
 		case ZEND_ASSIGN_MUL:
-			return (void *) mul_function;
+			return (binary_op_type) mul_function;
 			break;
 		case ZEND_DIV:
 		case ZEND_ASSIGN_DIV:
-			return (void *) div_function;
+			return (binary_op_type) div_function;
 			break;
 		case ZEND_MOD:
 		case ZEND_ASSIGN_MOD:
-			return (void *) mod_function;
+			return (binary_op_type) mod_function;
 			break;
 		case ZEND_SL:
 		case ZEND_ASSIGN_SL:
-			return (void *) shift_left_function;
+			return (binary_op_type) shift_left_function;
 			break;
 		case ZEND_SR:
 		case ZEND_ASSIGN_SR:
-			return (void *) shift_right_function;
+			return (binary_op_type) shift_right_function;
 			break;
 		case ZEND_CONCAT:
 		case ZEND_ASSIGN_CONCAT:
-			return (void *) concat_function;
+			return (binary_op_type) concat_function;
 			break;
 		case ZEND_IS_IDENTICAL:
-			return (void *) is_identical_function;
+			return (binary_op_type) is_identical_function;
 			break;
 		case ZEND_IS_NOT_IDENTICAL:
-			return (void *) is_not_identical_function;
+			return (binary_op_type) is_not_identical_function;
 			break;
 		case ZEND_IS_EQUAL:
-			return (void *) is_equal_function;
+			return (binary_op_type) is_equal_function;
 			break;
 		case ZEND_IS_NOT_EQUAL:
-			return (void *) is_not_equal_function;
+			return (binary_op_type) is_not_equal_function;
 			break;
 		case ZEND_IS_SMALLER:
-			return (void *) is_smaller_function;
+			return (binary_op_type) is_smaller_function;
 			break;
 		case ZEND_IS_SMALLER_OR_EQUAL:
-			return (void *) is_smaller_or_equal_function;
+			return (binary_op_type) is_smaller_or_equal_function;
 			break;
 		case ZEND_BW_OR:
 		case ZEND_ASSIGN_BW_OR:
-			return (void *) bitwise_or_function;
+			return (binary_op_type) bitwise_or_function;
 			break;
 		case ZEND_BW_AND:
 		case ZEND_ASSIGN_BW_AND:
-			return (void *) bitwise_and_function;
+			return (binary_op_type) bitwise_and_function;
 			break;
 		case ZEND_BW_XOR:
 		case ZEND_ASSIGN_BW_XOR:
-			return (void *) bitwise_xor_function;
+			return (binary_op_type) bitwise_xor_function;
+			break;
+		case ZEND_BOOL_XOR:
+			return (binary_op_type) boolean_xor_function;
 			break;
 		default:
-			return (void *) NULL;
+			return (binary_op_type) NULL;
 			break;
 	}
 }
Index: NEWS
===================================================================
RCS file: /repository/php-src/NEWS,v
retrieving revision 1.2027.2.547.2.965.2.292
diff -u -r1.2027.2.547.2.965.2.292 NEWS
--- NEWS	29 Aug 2008 11:20:18 -0000	1.2027.2.547.2.965.2.292
+++ NEWS	29 Aug 2008 11:26:40 -0000
@@ -106,6 +106,7 @@
   . Added ability to handle exceptions in destructors. (Marcus)
 
 - Improved PHP runtime speed and memory usage:
+  . Evaluate constant expressions at compile time. (Matt, Nuno)
   . Substitute global-scope, persistent constants with their values at compile
     time. (Matt)
   . Optimized ZEND_SIGNED_MULTIPLY_LONG(). (Matt)
