From: Dmitry Stogov Date: Wed, 18 Mar 2009 14:17:15 +0000 (+0000) Subject: Improved speed of conditional jump instructions by checking for most useful case... X-Git-Tag: php-5.3.0RC1~33 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=daac1a6273af126a27dd76d9284c81099d6b202a;p=php Improved speed of conditional jump instructions by checking for most useful case (conditional expression) --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9a970b8749..bd6648cedd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1652,14 +1652,24 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)); + zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); + int ret; - FREE_OP1(); + if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + FREE_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (!ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -1669,14 +1679,24 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)); + zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); + int ret; - FREE_OP1(); + if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + FREE_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -1686,13 +1706,19 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)); + zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); + int retval; - FREE_OP1(); - - if (UNEXPECTED(EG(exception) != NULL)) { - ZEND_VM_CONTINUE(); - } else if (EXPECTED(retval != 0)) { + if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + FREE_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } + if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif @@ -1711,16 +1737,26 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)); + zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); + int retval; - FREE_OP1(); + if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + FREE_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -1729,16 +1765,26 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R)); + zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); + int retval; - FREE_OP1(); + if (OP1_TYPE == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + FREE_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 440a31ab59..63780a8659 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1463,13 +1463,24 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - int ret = i_zend_is_true(&opline->op1.u.constant); + zval *val = &opline->op1.u.constant; + int ret; + if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (!ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -1479,13 +1490,24 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS { zend_op *opline = EX(opline); - int ret = i_zend_is_true(&opline->op1.u.constant); + zval *val = &opline->op1.u.constant; + int ret; + if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -1495,11 +1517,19 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG { zend_op *opline = EX(opline); - int retval = i_zend_is_true(&opline->op1.u.constant); + zval *val = &opline->op1.u.constant; + int retval; - if (UNEXPECTED(EG(exception) != NULL)) { - ZEND_VM_CONTINUE(); - } else if (EXPECTED(retval != 0)) { + if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } + if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif @@ -1518,15 +1548,26 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR { zend_op *opline = EX(opline); - int retval = i_zend_is_true(&opline->op1.u.constant); + zval *val = &opline->op1.u.constant; + int retval; + + if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -1535,15 +1576,26 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A { zend_op *opline = EX(opline); - int retval = i_zend_is_true(&opline->op1.u.constant); + zval *val = &opline->op1.u.constant; + int retval; + if (IS_CONST == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -4689,14 +4741,24 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int ret; - zval_dtor(free_op1.var); + if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + zval_dtor(free_op1.var); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (!ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -4706,14 +4768,24 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int ret; - zval_dtor(free_op1.var); + if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + zval_dtor(free_op1.var); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -4723,13 +4795,19 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); - - zval_dtor(free_op1.var); + zval *val = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - if (UNEXPECTED(EG(exception) != NULL)) { - ZEND_VM_CONTINUE(); - } else if (EXPECTED(retval != 0)) { + if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + zval_dtor(free_op1.var); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } + if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif @@ -4748,16 +4826,26 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - zval_dtor(free_op1.var); + if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + zval_dtor(free_op1.var); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -4766,16 +4854,26 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - zval_dtor(free_op1.var); + if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + zval_dtor(free_op1.var); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -7898,14 +7996,24 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int ret; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (!ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -7915,14 +8023,24 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int ret = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int ret; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -7932,13 +8050,19 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - - if (UNEXPECTED(EG(exception) != NULL)) { - ZEND_VM_CONTINUE(); - } else if (EXPECTED(retval != 0)) { + if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } + if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif @@ -7957,16 +8081,26 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -7975,16 +8109,26 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG { zend_op *opline = EX(opline); zend_free_op free_op1; - int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); + zval *val = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + int retval; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -21779,13 +21923,24 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - int ret = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); + zval *val = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + int ret; + if (IS_CV == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (!ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -21795,13 +21950,24 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - int ret = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); + zval *val = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + int ret; + if (IS_CV == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + ret = Z_LVAL_P(val); + } else { + ret = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } if (ret) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); @@ -21811,11 +21977,19 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); + zval *val = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + int retval; - if (UNEXPECTED(EG(exception) != NULL)) { - ZEND_VM_CONTINUE(); - } else if (EXPECTED(retval != 0)) { + if (IS_CV == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } + if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif @@ -21834,15 +22008,26 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); + zval *val = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + int retval; + if (IS_CV == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (!retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } @@ -21851,15 +22036,26 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS { zend_op *opline = EX(opline); - int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); + zval *val = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + int retval; + if (IS_CV == IS_TMP_VAR && Z_TYPE_P(val) == IS_BOOL) { + retval = Z_LVAL_P(val); + } else { + retval = i_zend_is_true(val); + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } + } Z_LVAL(EX_T(opline->result.u.var).tmp_var) = retval; Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL; if (retval) { #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(opline->op2.u.jmp_addr); + ZEND_VM_SET_OPCODE(opline->op2.u.jmp_addr); + ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); }