summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-06-14 06:01:01 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-06-14 06:01:01 +0200
commit3cfa58367b1b85d346d9be6cf9ae116c63571247 (patch)
tree95d0ebf14bf0e2953a911d317a17f7fcd1fd1ccb /Zend/zend_compile.c
parentb97944c6d1469ba9979843e27050068aa914eb39 (diff)
downloadphp-git-3cfa58367b1b85d346d9be6cf9ae116c63571247.tar.gz
Expand optimizations regarding short-circuting a bit
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r--Zend/zend_compile.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f753af4483..61271f6143 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5840,31 +5840,65 @@ void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&left_node, left_ast);
+ if (left_node.op_type == IS_CONST) {
+ if (
+ (ast->kind == ZEND_AST_AND && !zend_is_true(&left_node.u.constant))
+ || (ast->kind == ZEND_AST_OR && zend_is_true(&left_node.u.constant))
+ ) {
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&left_node.u.constant));
+ } else {
+ zend_compile_expr(&right_node, right_ast);
+
+ if (right_node.op_type == IS_CONST) {
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
+ } else {
+ zend_emit_op(result, ZEND_BOOL, &right_node, NULL);
+ }
+
+ zval_ptr_dtor(&right_node.u.constant);
+ }
+
+ zval_ptr_dtor(&left_node.u.constant);
+ return;
+ }
+
opnum_jmpz = get_next_op_number(CG(active_op_array));
opline_jmpz = zend_emit_op(NULL, ast->kind == ZEND_AST_AND ? ZEND_JMPZ_EX : ZEND_JMPNZ_EX,
&left_node, NULL);
if (left_node.op_type == IS_TMP_VAR) {
SET_NODE(opline_jmpz->result, &left_node);
- } else {
- opline_jmpz->result.var = get_temporary_variable(CG(active_op_array));
- opline_jmpz->result_type = IS_TMP_VAR;
}
- GET_NODE(result, opline_jmpz->result);
zend_compile_expr(&right_node, right_ast);
- if (right_node.op_type == IS_CONST && (
- (ast->kind == ZEND_AST_AND && !zend_is_true(&right_node.u.constant))
- || (ast->kind == ZEND_AST_OR && zend_is_true(&right_node.u.constant))
- )) {
- result->op_type = IS_CONST;
- ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
+ if (right_node.op_type == IS_CONST && opnum_jmpz == CG(active_op_array)->last) {
+ if (
+ (ast->kind == ZEND_AST_AND && !zend_is_true(&right_node.u.constant))
+ || (ast->kind == ZEND_AST_OR && zend_is_true(&right_node.u.constant))
+ ) {
+ CG(active_op_array)->last--;
+ result->op_type = IS_CONST;
+ ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
+ } else {
+ opline_jmpz->opcode = ZEND_BOOL;
+ zend_make_var_result(result, opline_jmpz);
+ }
+
zval_ptr_dtor(&right_node.u.constant);
- } else {
- opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL);
- SET_NODE(opline_bool->result, result);
+ return;
+ }
+
+ if (left_node.op_type != IS_TMP_VAR) {
+ opline_jmpz->result.var = get_temporary_variable(CG(active_op_array));
+ opline_jmpz->result_type = IS_TMP_VAR;
}
+ GET_NODE(result, opline_jmpz->result);
+
+ opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL);
+ SET_NODE(opline_bool->result, result);
zend_update_jump_target_to_next(opnum_jmpz);
}