From: Dmitry Stogov Date: Wed, 26 Dec 2018 23:34:52 +0000 (+0300) Subject: Tune ARRAY_KEY_EXISTS opcode handler for speed and code size X-Git-Tag: php-7.4.0alpha1~1333 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e8daada82ef62a9f8bbd834114911f477da4ab63;p=php Tune ARRAY_KEY_EXISTS opcode handler for speed and code size --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7fbb023ed1..4f334c6b86 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2099,6 +2099,57 @@ str_offset: } } +static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC) +{ + zend_string *str; + zend_ulong hval; + +try_again: + if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { + str = Z_STR_P(key); + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_key; + } +str_key: + return zend_hash_find_ind(ht, str) != NULL ? IS_TRUE : IS_FALSE; + } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { + hval = Z_LVAL_P(key); +num_key: + return zend_hash_index_find(ht, hval) != NULL ? IS_TRUE : IS_FALSE; + } else if (EXPECTED(Z_ISREF_P(key))) { + key = Z_REFVAL_P(key); + goto try_again; + } else if (Z_TYPE_P(key) <= IS_NULL) { + if (UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_key; + } else { + zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); + return IS_FALSE; + } +} + +static zend_never_inline uint32_t ZEND_FASTCALL zend_array_key_exists_slow(zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC) +{ + if (EXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { + HashTable *ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); + uint32_t result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + zend_release_properties(ht); + return result; + } else { + if (UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + if (UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); + return IS_NULL; + } +} + static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type OPLINE_DC) { zval *ptr; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d02c75f52e..560ee34d38 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6376,64 +6376,32 @@ ZEND_VM_HANDLER(199, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST) zend_free_op free_op1, free_op2; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); subject = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); -ZEND_VM_C_LABEL(try_again_subject): if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +ZEND_VM_C_LABEL(array_key_exists_array): ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - ZEND_VM_C_GOTO(try_again_subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - FREE_OP2(); - FREE_OP1(); - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -ZEND_VM_C_LABEL(try_again_key): - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if ((OP2_TYPE & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + ZEND_VM_C_GOTO(array_key_exists_array); + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - ZEND_VM_C_GOTO(try_again_key); - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } FREE_OP2(); FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e10c490e84..b4f63d12b8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5742,63 +5742,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = RT_CONSTANT(opline, opline->op1); subject = RT_CONSTANT(opline, opline->op2); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -7766,64 +7734,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM zend_free_op free_op2; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = RT_CONSTANT(opline, opline->op1); subject = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - zval_ptr_dtor_nogc(free_op2); - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -10901,63 +10837,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = RT_CONSTANT(opline, opline->op1); subject = EX_VAR(opline->op2.var); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -14530,63 +14434,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C zend_free_op free_op1; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); subject = RT_CONSTANT(opline, opline->op2); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - zval_ptr_dtor_nogc(free_op1); - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -16057,64 +15929,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T zend_free_op free_op1, free_op2; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); subject = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -17984,63 +17824,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C zend_free_op free_op1; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC); subject = EX_VAR(opline->op2.var); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - zval_ptr_dtor_nogc(free_op1); - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -41626,63 +41434,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = EX_VAR(opline->op1.var); subject = RT_CONSTANT(opline, opline->op2); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); - } - - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -45225,64 +45001,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA zend_free_op free_op2; zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = EX_VAR(opline->op1.var); subject = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - zval_ptr_dtor_nogc(free_op2); - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(free_op2); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -51089,63 +50833,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA zval *key, *subject; - HashTable* ht; - int result; + HashTable *ht; + uint32_t result; SAVE_OPLINE(); key = EX_VAR(opline->op1.var); subject = EX_VAR(opline->op2.var); -try_again_subject: if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: ht = Z_ARRVAL_P(subject); - } else if (UNEXPECTED(Z_TYPE_P(subject) == IS_OBJECT)) { - ht = zend_get_properties_for(subject, ZEND_PROP_PURPOSE_ARRAY_CAST); - } else if (Z_ISREF_P(subject)) { - subject = Z_REFVAL_P(subject); - goto try_again_subject; + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(subject) == IS_UNDEF)) { - subject = ZVAL_UNDEFINED_OP2(); - } - zend_internal_type_error(EX_USES_STRICT_TYPES(), "array_key_exists() expects parameter 2 to be array, %s given", zend_get_type_by_const(Z_TYPE_P(subject))); - - - ZVAL_NULL(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -try_again_key: - if (EXPECTED(Z_TYPE_P(key) == IS_STRING)) { - result = zend_symtable_exists_ind(ht, Z_STR_P(key)); - } else if (EXPECTED(Z_TYPE_P(key) == IS_LONG)) { - result = zend_hash_index_exists(ht, Z_LVAL_P(key)); - } else if (UNEXPECTED(Z_TYPE_P(key) == IS_NULL)) { - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_TYPE_P(key) <= IS_NULL) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(key) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - result = zend_hash_exists_ind(ht, ZSTR_EMPTY_ALLOC()); - } else if (Z_ISREF_P(key)) { - key = Z_REFVAL_P(key); - goto try_again_key; - } else { - zend_error(E_WARNING, "array_key_exists(): The first argument should be either a string or an integer"); - result = 0; - } - - if (Z_TYPE_P(subject) != IS_ARRAY) { - zend_release_properties(ht); + result = zend_array_key_exists_slow(subject, key OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); + ZEND_VM_SMART_BRANCH(result == IS_TRUE, 1); + Z_TYPE_INFO_P(EX_VAR(opline->result.var)) = result; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); }