From fb73c1084c9da0e38c9e82d525b43415af747df8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 19 Dec 2016 15:36:37 +0300 Subject: [PATCH] Few micro-optimizations --- Zend/zend_vm_def.h | 80 +++++--- Zend/zend_vm_execute.h | 438 ++++++++++++++++++++++++----------------- 2 files changed, 304 insertions(+), 214 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e278abb0f5..fc4fd991ac 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -288,17 +288,16 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) zend_free_op free_op1, free_op2; zval *op1, *op2; - SAVE_OPLINE(); op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); - do { - if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (OP1_TYPE != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -327,19 +326,24 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + FREE_OP1(); + } while (0); + FREE_OP2(); + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } + if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); FREE_OP1(); - } while (0); - FREE_OP2(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + FREE_OP2(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) @@ -729,6 +733,13 @@ ZEND_VM_HANDLER(12, ZEND_BW_NOT, CONST|TMPVAR|CV, ANY) { USE_OPLINE zend_free_op free_op1; + zval *op1; + + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), @@ -4955,11 +4966,11 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH) USE_OPLINE zend_constant *c; - SAVE_OPLINE(); - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { + SAVE_OPLINE(); + if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); if (!actual) { @@ -7248,8 +7259,6 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) zval *object; zend_class_entry *called_scope; - SAVE_OPLINE(); - zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1))); ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); @@ -7268,7 +7277,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED) zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(func)->op_array.scope, called_scope, object); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) @@ -7681,20 +7690,26 @@ ZEND_VM_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY) zval *value; zend_free_op free_op1; - SAVE_OPLINE(); value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); -ZEND_VM_C_LABEL(try_strlen): if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE(); } else { zend_bool strict; - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = GET_OP1_UNDEF_CV(value, BP_VAR_R); - } if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); - ZEND_VM_C_GOTO(try_strlen); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = GET_OP1_UNDEF_CV(value, BP_VAR_R); } strict = EX_USES_STRICT_TYPES(); do { @@ -7788,11 +7803,11 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH) zend_class_entry *called_scope, *scope; USE_OPLINE - SAVE_OPLINE(); fetch_type = opline->extended_value; scope = EX(func)->op_array.scope; if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" when no class scope is active", fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); @@ -7806,6 +7821,7 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH) break; case ZEND_FETCH_CLASS_PARENT: if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"parent\" when current class scope has no parent"); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -7984,7 +8000,6 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) zval *value; zval *variable_ptr; - SAVE_OPLINE(); variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); zval_ptr_dtor(variable_ptr); @@ -8002,6 +8017,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) if (opline->extended_value) { if (Z_CONSTANT_P(value)) { + SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) { ZVAL_NULL(variable_ptr); HANDLE_EXCEPTION(); @@ -8023,7 +8039,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF) ZVAL_COPY(variable_ptr, value); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(184, ZEND_FETCH_THIS, UNUSED, UNUSED) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 35f0709355..c95f343ef2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1900,11 +1900,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER( zend_class_entry *called_scope, *scope; USE_OPLINE - SAVE_OPLINE(); fetch_type = opline->extended_value; scope = EX(func)->op_array.scope; if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"%s\" when no class scope is active", fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); @@ -1918,6 +1918,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER( break; case ZEND_FETCH_CLASS_PARENT: if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); zend_throw_error(NULL, "Cannot use \"parent\" when current class scope has no parent"); ZVAL_UNDEF(EX_VAR(opline->result.var)); @@ -2611,6 +2612,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND { USE_OPLINE + zval *op1; + + op1 = EX_CONSTANT(opline->op1); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), @@ -4035,20 +4043,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST_HANDLER(ZEND zval *value; - SAVE_OPLINE(); value = EX_CONSTANT(opline->op1); -try_strlen: if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + + ZEND_VM_NEXT_OPCODE(); } else { zend_bool strict; - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = GET_OP1_UNDEF_CV(value, BP_VAR_R); - } if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); - goto try_strlen; + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = GET_OP1_UNDEF_CV(value, BP_VAR_R); } strict = EX_USES_STRICT_TYPES(); do { @@ -4405,17 +4419,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE zval *op1, *op2; - SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); op2 = EX_CONSTANT(opline->op2); - do { - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -4444,19 +4457,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLE memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -8065,8 +8083,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C zval *object; zend_class_entry *called_scope; - SAVE_OPLINE(); - zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1))); ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION); @@ -8085,7 +8101,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc), EX(func)->op_array.scope, called_scope, object); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -8487,17 +8503,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z zval *op1, *op2; - SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); - do { - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -8526,19 +8541,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -10508,17 +10528,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL zend_free_op free_op2; zval *op1, *op2; - SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - do { - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -10547,19 +10566,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -28257,11 +28281,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON USE_OPLINE zend_constant *c; - SAVE_OPLINE(); - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value)) == NULL) { + SAVE_OPLINE(); + if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) { char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2))); if (!actual) { @@ -32701,6 +32725,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OP { USE_OPLINE + zval *op1; + + op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), @@ -34359,20 +34390,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP zval *value; - SAVE_OPLINE(); value = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); -try_strlen: if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + + ZEND_VM_NEXT_OPCODE(); } else { zend_bool strict; - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = GET_OP1_UNDEF_CV(value, BP_VAR_R); - } if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); - goto try_strlen; + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = GET_OP1_UNDEF_CV(value, BP_VAR_R); } strict = EX_USES_STRICT_TYPES(); do { @@ -34764,17 +34801,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); op2 = EX_CONSTANT(opline->op2); - do { - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -34803,19 +34839,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -38516,7 +38557,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND zval *value; zval *variable_ptr; - SAVE_OPLINE(); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); zval_ptr_dtor(variable_ptr); @@ -38534,6 +38574,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND if (opline->extended_value) { if (Z_CONSTANT_P(value)) { + SAVE_OPLINE(); if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) { ZVAL_NULL(variable_ptr); HANDLE_EXCEPTION(); @@ -38555,7 +38596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND ZVAL_COPY(variable_ptr, value); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -41284,17 +41325,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); - do { - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -41323,19 +41363,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -44973,17 +45018,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( zend_free_op free_op2; zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - do { - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -45012,19 +45056,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + + } while (0); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); } + concat_function(EX_VAR(opline->result.var), op1, op2); - } while (0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -48129,6 +48178,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEN { USE_OPLINE zend_free_op free_op1; + zval *op1; + + op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), @@ -48608,20 +48664,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEN zval *value; zend_free_op free_op1; - SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); -try_strlen: if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE(); } else { zend_bool strict; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = GET_OP1_UNDEF_CV(value, BP_VAR_R); - } if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); - goto try_strlen; + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = GET_OP1_UNDEF_CV(value, BP_VAR_R); } strict = EX_USES_STRICT_TYPES(); do { @@ -48908,17 +48970,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL zend_free_op free_op1; zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = EX_CONSTANT(opline->op2); - do { - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -48947,19 +49008,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(free_op1); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -51472,17 +51538,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( zend_free_op free_op1; zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); - do { - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -51511,19 +51576,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + } while (0); + + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(free_op1); - } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -52759,17 +52829,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND zend_free_op free_op1, free_op2; zval *op1, *op2; - SAVE_OPLINE(); op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - do { - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; + if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + do { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); @@ -52798,19 +52867,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(free_op1); + } while (0); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); + } + concat_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(free_op1); - } while (0); - zval_ptr_dtor_nogc(free_op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(free_op2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -- 2.50.1