summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-10-05 14:45:15 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-10-05 14:50:04 +0200
commita6be0f3fd6cdd59ac00ecd76630c6c04fee03417 (patch)
tree3339746b2cf7f7dcb5e11d52896f141ecff7c129
parent881c50252066132f83e190325e344f532be19033 (diff)
downloadphp-git-a6be0f3fd6cdd59ac00ecd76630c6c04fee03417.tar.gz
Merge branch 'array_keys_strict_refs' of https://github.com/tony2001/php-src
-rw-r--r--Zend/zend_operators.c54
-rw-r--r--Zend/zend_operators.h74
-rw-r--r--Zend/zend_vm_def.h8
-rw-r--r--Zend/zend_vm_execute.h64
-rw-r--r--ext/standard/array.c1
-rw-r--r--ext/standard/tests/array/array_keys_non_strict.phpt109
-rw-r--r--ext/standard/tests/array/array_keys_strict.phpt65
-rw-r--r--ext/standard/tests/array/array_keys_strict_ref.phpt65
8 files changed, 356 insertions, 84 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 2345e0b2d4..c40689ef80 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1959,52 +1959,24 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
}
/* }}} */
-static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
-{
- zval result;
-
- /* is_identical_function() returns 1 in case of identity and 0 in case
- * of a difference;
- * whereas this comparison function is expected to return 0 on identity,
- * and non zero otherwise.
- */
- ZVAL_DEREF(z1);
- ZVAL_DEREF(z2);
- if (is_identical_function(&result, z1, z2)==FAILURE) {
- return 1;
- }
- return Z_TYPE(result) != IS_TRUE;
-}
-/* }}} */
-
ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
- return 0;
- }
- switch (Z_TYPE_P(op1)) {
- case IS_NULL:
- case IS_FALSE:
- case IS_TRUE:
- return 1;
- case IS_LONG:
- return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
- case IS_RESOURCE:
- return (Z_RES_P(op1) == Z_RES_P(op2));
- case IS_DOUBLE:
- return (Z_DVAL_P(op1) == Z_DVAL_P(op2));
- case IS_STRING:
- return (Z_STR_P(op1) == Z_STR_P(op2) ||
- (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
- memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));
- case IS_ARRAY:
- return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
- zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0);
- case IS_OBJECT:
- return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2));
- default:
+ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) {
+ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) {
+ return 0;
+ } else {
+ op1 = Z_REFVAL_P(op1);
+ }
+ } else {
+ op2 = Z_REFVAL_P(op2);
+ }
+ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
return 0;
+ }
}
+
+ return zend_is_same_type_identical(op1, op2);
}
/* }}} */
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index f8c155d2d2..17ae18cdd9 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -729,24 +729,86 @@ static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
return Z_LVAL(result) == 0;
}
+static int hash_zval_identical_function(zval *op1, zval *op2);
+
+static inline int zend_is_same_type_identical(zval *op1, zval *op2)
+{
+ switch (Z_TYPE_P(op1)) {
+ case IS_NULL:
+ case IS_FALSE:
+ case IS_TRUE:
+ return 1;
+ case IS_LONG:
+ return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ case IS_RESOURCE:
+ return (Z_RES_P(op1) == Z_RES_P(op2));
+ case IS_DOUBLE:
+ return (Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ case IS_STRING:
+ return (Z_STR_P(op1) == Z_STR_P(op2) ||
+ (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
+ memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));
+ case IS_ARRAY:
+ return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
+ zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0);
+ case IS_OBJECT:
+ return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2));
+ case IS_REFERENCE:
+ return zend_is_identical(Z_REFVAL_P(op1), Z_REFVAL_P(op2));
+ default:
+ return 0;
+ }
+}
+
static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2)
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
- return 0;
- } else if (Z_TYPE_P(op1) <= IS_TRUE) {
+ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) {
+ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) {
+ return 0;
+ } else {
+ op2 = Z_REFVAL_P(op2);
+ }
+ } else {
+ op1 = Z_REFVAL_P(op1);
+ }
+ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
+ return 0;
+ }
+ }
+
+ if (Z_TYPE_P(op1) <= IS_TRUE) {
return 1;
}
- return zend_is_identical(op1, op2);
+ return zend_is_same_type_identical(op1, op2);
}
static zend_always_inline int fast_is_not_identical_function(zval *op1, zval *op2)
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
- return 1;
- } else if (Z_TYPE_P(op1) <= IS_TRUE) {
+ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) {
+ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) {
+ return 1;
+ } else {
+ op2 = Z_REFVAL_P(op2);
+ }
+ } else {
+ op1 = Z_REFVAL_P(op1);
+ }
+ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
+ return 1;
+ }
+ }
+
+ if (Z_TYPE_P(op1) <= IS_TRUE) {
return 0;
}
- return !zend_is_identical(op1, op2);
+ return !zend_is_same_type_identical(op1, op2);
+}
+
+static int hash_zval_identical_function(zval *op1, zval *op2)
+{
+ return !fast_is_identical_function(op1, op2);
}
#define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index f0e7278459..fd0e35458f 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -323,8 +323,8 @@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
int result;
SAVE_OPLINE();
- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
result = fast_is_identical_function(op1, op2);
FREE_OP1();
FREE_OP2();
@@ -344,8 +344,8 @@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
int result;
SAVE_OPLINE();
- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
+ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
result = fast_is_not_identical_function(op1, op2);
FREE_OP1();
FREE_OP2();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 035f4ab7af..b8da79921d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -6824,7 +6824,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HA
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
@@ -6845,7 +6845,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VA
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
@@ -8533,7 +8533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HAN
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_identical_function(op1, op2);
@@ -8554,7 +8554,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV
SAVE_OPLINE();
op1 = EX_CONSTANT(opline->op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_not_identical_function(op1, op2);
@@ -13304,7 +13304,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HAND
SAVE_OPLINE();
op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -13325,7 +13325,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_
SAVE_OPLINE();
op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -13857,7 +13857,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDL
SAVE_OPLINE();
op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -13878,7 +13878,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_H
SAVE_OPLINE();
op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -16406,7 +16406,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HA
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
op2 = EX_CONSTANT(opline->op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -16427,7 +16427,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONS
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
op2 = EX_CONSTANT(opline->op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -18148,7 +18148,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HAND
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -18169,7 +18169,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -18360,8 +18360,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HAND
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -18381,8 +18381,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -19614,8 +19614,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDL
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -19635,8 +19635,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_H
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op1);
@@ -30092,7 +30092,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
op2 = EX_CONSTANT(opline->op2);
result = fast_is_identical_function(op1, op2);
@@ -30113,7 +30113,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
op2 = EX_CONSTANT(opline->op2);
result = fast_is_not_identical_function(op1, op2);
@@ -32972,7 +32972,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDL
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
@@ -32993,7 +32993,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_H
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
@@ -33183,8 +33183,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDL
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
@@ -33204,8 +33204,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_H
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
result = fast_is_not_identical_function(op1, op2);
zval_ptr_dtor_nogc(free_op2);
@@ -35327,8 +35327,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLE
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_identical_function(op1, op2);
@@ -35348,8 +35348,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HA
int result;
SAVE_OPLINE();
- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var);
+ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
result = fast_is_not_identical_function(op1, op2);
diff --git a/ext/standard/array.c b/ext/standard/array.c
index b9d39ea1a2..773b1ae1e8 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1613,7 +1613,6 @@ static inline void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
if (strict) {
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) {
- ZVAL_DEREF(entry);
if (fast_is_identical_function(value, entry)) {
if (behavior == 0) {
RETURN_TRUE;
diff --git a/ext/standard/tests/array/array_keys_non_strict.phpt b/ext/standard/tests/array/array_keys_non_strict.phpt
new file mode 100644
index 0000000000..d418671882
--- /dev/null
+++ b/ext/standard/tests/array/array_keys_non_strict.phpt
@@ -0,0 +1,109 @@
+--TEST--
+array_keys() in non-strict mode
+--FILE--
+<?php
+
+$arr = array(1, "1", "", NULL, 0, false, true, array());
+
+$s = 1;
+var_dump(array_keys($arr, $s));
+
+$s = "1";
+var_dump(array_keys($arr, $s));
+
+$s = "";
+var_dump(array_keys($arr, $s));
+
+$s = NULL;
+var_dump(array_keys($arr, $s));
+
+$s = 0;
+var_dump(array_keys($arr, $s));
+
+$s = false;
+var_dump(array_keys($arr, $s));
+
+$s = true;
+var_dump(array_keys($arr, $s));
+
+$s = array();
+var_dump(array_keys($arr, $s));
+
+?>
+--EXPECTF--
+array(3) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(6)
+}
+array(3) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(6)
+}
+array(4) {
+ [0]=>
+ int(2)
+ [1]=>
+ int(3)
+ [2]=>
+ int(4)
+ [3]=>
+ int(5)
+}
+array(5) {
+ [0]=>
+ int(2)
+ [1]=>
+ int(3)
+ [2]=>
+ int(4)
+ [3]=>
+ int(5)
+ [4]=>
+ int(7)
+}
+array(4) {
+ [0]=>
+ int(2)
+ [1]=>
+ int(3)
+ [2]=>
+ int(4)
+ [3]=>
+ int(5)
+}
+array(5) {
+ [0]=>
+ int(2)
+ [1]=>
+ int(3)
+ [2]=>
+ int(4)
+ [3]=>
+ int(5)
+ [4]=>
+ int(7)
+}
+array(3) {
+ [0]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(6)
+}
+array(3) {
+ [0]=>
+ int(3)
+ [1]=>
+ int(5)
+ [2]=>
+ int(7)
+}
diff --git a/ext/standard/tests/array/array_keys_strict.phpt b/ext/standard/tests/array/array_keys_strict.phpt
new file mode 100644
index 0000000000..753ba3df63
--- /dev/null
+++ b/ext/standard/tests/array/array_keys_strict.phpt
@@ -0,0 +1,65 @@
+--TEST--
+array_keys() in strict mode
+--FILE--
+<?php
+
+$arr = array(1, "1", "", NULL, 0, false, true, array());
+
+$s = 1;
+var_dump(array_keys($arr, $s, true));
+
+$s = "1";
+var_dump(array_keys($arr, $s, true));
+
+$s = "";
+var_dump(array_keys($arr, $s, true));
+
+$s = NULL;
+var_dump(array_keys($arr, $s, true));
+
+$s = 0;
+var_dump(array_keys($arr, $s, true));
+
+$s = false;
+var_dump(array_keys($arr, $s, true));
+
+$s = true;
+var_dump(array_keys($arr, $s, true));
+
+$s = array();
+var_dump(array_keys($arr, $s, true));
+
+?>
+--EXPECTF--
+array(1) {
+ [0]=>
+ int(0)
+}
+array(1) {
+ [0]=>
+ int(1)
+}
+array(1) {
+ [0]=>
+ int(2)
+}
+array(1) {
+ [0]=>
+ int(3)
+}
+array(1) {
+ [0]=>
+ int(4)
+}
+array(1) {
+ [0]=>
+ int(5)
+}
+array(1) {
+ [0]=>
+ int(6)
+}
+array(1) {
+ [0]=>
+ int(7)
+}
diff --git a/ext/standard/tests/array/array_keys_strict_ref.phpt b/ext/standard/tests/array/array_keys_strict_ref.phpt
new file mode 100644
index 0000000000..cac6f09474
--- /dev/null
+++ b/ext/standard/tests/array/array_keys_strict_ref.phpt
@@ -0,0 +1,65 @@
+--TEST--
+array_keys() in strict mode with references
+--FILE--
+<?php
+
+$arr = array(1, "1", "", NULL, 0, false, true, array());
+
+$s = &$arr[0];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[1];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[2];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[3];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[4];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[5];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[6];
+var_dump(array_keys($arr, $s, true));
+
+$s = &$arr[7];
+var_dump(array_keys($arr, $s, true));
+
+?>
+--EXPECTF--
+array(1) {
+ [0]=>
+ int(0)
+}
+array(1) {
+ [0]=>
+ int(1)
+}
+array(1) {
+ [0]=>
+ int(2)
+}
+array(1) {
+ [0]=>
+ int(3)
+}
+array(1) {
+ [0]=>
+ int(4)
+}
+array(1) {
+ [0]=>
+ int(5)
+}
+array(1) {
+ [0]=>
+ int(6)
+}
+array(1) {
+ [0]=>
+ int(7)
+}