diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7d0b30ff2bdc2..6be2ff645b247 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8286,7 +8286,9 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY) value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - FREE_OP1(); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { bool strict; @@ -8897,33 +8899,63 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), OP1_TYPE == IS_CONST); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); } else if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { + ZEND_VM_SMART_BRANCH(result, 0); + } + if (OP1_TYPE & (IS_CV | IS_VAR)) { + SAVE_OPLINE(); + if ((OP1_TYPE & IS_CV) && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZEND_VM_SMART_BRANCH(0, 1); + } result = NULL; + ZVAL_DEREF(op1); + if (Z_TYPE_P(op1) == IS_STRING) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), OP1_TYPE == IS_CONST); + } else if (Z_TYPE_P(op1) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, OP1_TYPE & IS_VAR); } + ZEND_VM_SMART_BRANCH(0, 0); } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 1); + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - } else { - zend_string *key; - zval key_tmp, *val; - - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; - } - } ZEND_HASH_FOREACH_END(); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + zend_string *key; + zval key_tmp, *val; + if (OP1_TYPE & (IS_CV | IS_VAR)) { + ZVAL_DEREF(op1); } + + result = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + result = val; + break; + } + } ZEND_HASH_FOREACH_END(); FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(result, OP1_TYPE & (IS_TMP_VAR|IS_VAR)); } ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0fe4fb5bb5d0c..8e584dd4bd004 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5262,7 +5262,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST value = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { bool strict; @@ -7463,33 +7465,63 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); } else if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { + ZEND_VM_SMART_BRANCH(result, 0); + } + if (IS_CONST & (IS_CV | IS_VAR)) { + SAVE_OPLINE(); + if ((IS_CONST & IS_CV) && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZEND_VM_SMART_BRANCH(0, 1); + } result = NULL; + ZVAL_DEREF(op1); + if (Z_TYPE_P(op1) == IS_STRING) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST); + } else if (Z_TYPE_P(op1) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } + + ZEND_VM_SMART_BRANCH(result, IS_CONST & IS_VAR); } + ZEND_VM_SMART_BRANCH(0, 0); } else if (Z_TYPE_P(op1) <= IS_FALSE) { - result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - } else { - zend_string *key; - zval key_tmp, *val; + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; - } - } ZEND_HASH_FOREACH_END(); + ZEND_VM_SMART_BRANCH(result, 1); + } + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + zend_string *key; + zval key_tmp, *val; + if (IS_CONST & (IS_CV | IS_VAR)) { + ZVAL_DEREF(op1); } - ZEND_VM_SMART_BRANCH(result, 1); + result = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + result = val; + break; + } + } ZEND_HASH_FOREACH_END(); + + ZEND_VM_SMART_BRANCH(result, IS_CONST & (IS_TMP_VAR|IS_VAR)); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -14445,7 +14477,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEN value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { bool strict; @@ -19620,33 +19654,63 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); } else if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { + ZEND_VM_SMART_BRANCH(result, 0); + } + if (IS_TMP_VAR & (IS_CV | IS_VAR)) { + SAVE_OPLINE(); + if ((IS_TMP_VAR & IS_CV) && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZEND_VM_SMART_BRANCH(0, 1); + } result = NULL; + ZVAL_DEREF(op1); + if (Z_TYPE_P(op1) == IS_STRING) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST); + } else if (Z_TYPE_P(op1) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, IS_TMP_VAR & IS_VAR); } + ZEND_VM_SMART_BRANCH(0, 0); } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - } else { - zend_string *key; - zval key_tmp, *val; - - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; - } - } ZEND_HASH_FOREACH_END(); + ZEND_VM_SMART_BRANCH(result, 0); } + SAVE_OPLINE(); + zend_string *key; + zval key_tmp, *val; + if (IS_TMP_VAR & (IS_CV | IS_VAR)) { + ZVAL_DEREF(op1); + } + + result = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + result = val; + break; + } + } ZEND_HASH_FOREACH_END(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(result, IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -24626,33 +24690,63 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST); + if (IS_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); } else if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { + ZEND_VM_SMART_BRANCH(result, 0); + } + if (IS_VAR & (IS_CV | IS_VAR)) { + SAVE_OPLINE(); + if ((IS_VAR & IS_CV) && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZEND_VM_SMART_BRANCH(0, 1); + } result = NULL; + ZVAL_DEREF(op1); + if (Z_TYPE_P(op1) == IS_STRING) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST); + } else if (Z_TYPE_P(op1) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, IS_VAR & IS_VAR); } + ZEND_VM_SMART_BRANCH(0, 0); } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - } else { - zend_string *key; - zval key_tmp, *val; - - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; - } - } ZEND_HASH_FOREACH_END(); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + zend_string *key; + zval key_tmp, *val; + if (IS_VAR & (IS_CV | IS_VAR)) { + ZVAL_DEREF(op1); } + + result = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + result = val; + break; + } + } ZEND_HASH_FOREACH_END(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(result, IS_VAR & (IS_TMP_VAR|IS_VAR)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -38542,7 +38636,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP value = EX_VAR(opline->op1.var); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { bool strict; @@ -42351,33 +42447,63 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); } else if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { + ZEND_VM_SMART_BRANCH(result, 0); + } + if (IS_CV & (IS_CV | IS_VAR)) { + SAVE_OPLINE(); + if ((IS_CV & IS_CV) && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZEND_VM_SMART_BRANCH(0, 1); + } result = NULL; + ZVAL_DEREF(op1); + if (Z_TYPE_P(op1) == IS_STRING) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST); + } else if (Z_TYPE_P(op1) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } + + ZEND_VM_SMART_BRANCH(result, IS_CV & IS_VAR); } + ZEND_VM_SMART_BRANCH(0, 0); } else if (Z_TYPE_P(op1) <= IS_FALSE) { - result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - } else { - zend_string *key; - zval key_tmp, *val; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; - } - } ZEND_HASH_FOREACH_END(); + ZEND_VM_SMART_BRANCH(result, 1); + } + result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + zend_string *key; + zval key_tmp, *val; + if (IS_CV & (IS_CV | IS_VAR)) { + ZVAL_DEREF(op1); } - ZEND_VM_SMART_BRANCH(result, 1); + result = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + result = val; + break; + } + } ZEND_HASH_FOREACH_END(); + + ZEND_VM_SMART_BRANCH(result, IS_CV & (IS_TMP_VAR|IS_VAR)); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)