]> granicus.if.org Git - php/commitdiff
Merge branch 'array_keys_strict_refs' of https://github.com/tony2001/php-src
authorBob Weinand <bobwei9@hotmail.com>
Mon, 5 Oct 2015 12:45:15 +0000 (14:45 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Mon, 5 Oct 2015 12:45:15 +0000 (14:45 +0200)
1  2 
Zend/zend_operators.c
Zend/zend_operators.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/standard/array.c

index 2345e0b2d440bf6041ad280be7d1cc0ad4403acf,2345e0b2d440bf6041ad280be7d1cc0ad4403acf..c40689ef805f39c2812bfc6336fda10efe1ffa3a
@@@ -1959,52 -1959,52 +1959,24 @@@ ZEND_API int ZEND_FASTCALL compare_func
  }
  /* }}} */
  
--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);
  }
  /* }}} */
  
index f8c155d2d2baa2d709a4292fe3d892040a9ff8a0,987d055f9e68b2e10735800fc056ca1cf6d5b529..17ae18cdd9687ea6589f62c5f98c32cf6e33f31e
@@@ -729,24 -729,28 +729,86 @@@ static zend_always_inline int fast_equa
        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)
  {
 -      ZVAL_DEREF(op1);
 -      ZVAL_DEREF(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)
  {
 -      ZVAL_DEREF(op1);
 -      ZVAL_DEREF(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)                                            \
index f0e7278459f7b5d2ed008cb726798416306969dc,f0e7278459f7b5d2ed008cb726798416306969dc..fd0e35458f1e4ccb8582cf67128f6d4f68564444
@@@ -323,8 -323,8 +323,8 @@@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, 
        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 +344,8 @@@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTIC
        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();
index 035f4ab7af0d5784d855c524d1042bb4a6951145,035f4ab7af0d5784d855c524d1042bb4a6951145..b8da79921dd9cc98a005417d2377ff0f92d14c25
@@@ -6824,7 -6824,7 +6824,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +6845,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +8533,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +8554,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +13304,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +13325,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +13857,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +13878,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
  
        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 +16406,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +16427,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +18148,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +18169,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +18360,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +18381,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +19614,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +19635,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +30092,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +30113,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +32972,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +32993,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +33183,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +33204,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +35327,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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 +35348,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS
        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);
  
  
index b9d39ea1a28324955f18077b8a0b1096e1e8aa2d,b9d39ea1a28324955f18077b8a0b1096e1e8aa2d..773b1ae1e81b6271969fe44125334572c2c81113
@@@ -1613,7 -1613,7 +1613,6 @@@ static inline void php_search_array(INT
  
        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;