]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.2' into PHP-7.3
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 26 Sep 2019 11:47:19 +0000 (13:47 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 26 Sep 2019 11:47:19 +0000 (13:47 +0200)
1  2 
Zend/zend_operators.c

index cd857ee217c68bb29ba8237da18f68d2c88b252b,584d5d8910201e16db7079e9bac01e6a3dab6694..ef778ea100b81cbb49c975a2a8283f5975410431
@@@ -1130,90 -1066,99 +1130,99 @@@ ZEND_API int ZEND_FASTCALL pow_function
        int converted = 0;
  
        while (1) {
 -              switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
 -                      case TYPE_PAIR(IS_LONG, IS_LONG):
 -                              if (Z_LVAL_P(op2) >= 0) {
 -                                      zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
 +              zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2));
  
 -                                      if (i == 0) {
 -                                              ZVAL_LONG(result, 1L);
 -                                              return SUCCESS;
 -                                      } else if (l2 == 0) {
 -                                              ZVAL_LONG(result, 0);
 -                                              return SUCCESS;
 -                                      }
 +              if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) {
 +                      if (Z_LVAL_P(op2) >= 0) {
 +                              zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
  
 -                                      while (i >= 1) {
 -                                              zend_long overflow;
 -                                              double dval = 0.0;
 +                              if (i == 0) {
 +                                      ZVAL_LONG(result, 1L);
 +                                      return SUCCESS;
 +                              } else if (l2 == 0) {
 +                                      ZVAL_LONG(result, 0);
 +                                      return SUCCESS;
 +                              }
  
 -                                              if (i % 2) {
 -                                                      --i;
 -                                                      ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
 -                                                      if (overflow) {
 -                                                              ZVAL_DOUBLE(result, dval * pow(l2, i));
 -                                                              return SUCCESS;
 -                                                      }
 -                                              } else {
 -                                                      i /= 2;
 -                                                      ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
 -                                                      if (overflow) {
 -                                                              ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
 -                                                              return SUCCESS;
 -                                                      }
 +                              while (i >= 1) {
 +                                      zend_long overflow;
 +                                      double dval = 0.0;
 +
 +                                      if (i % 2) {
 +                                              --i;
 +                                              ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
 +                                              if (overflow) {
 +                                                      ZVAL_DOUBLE(result, dval * pow(l2, i));
 +                                                      return SUCCESS;
 +                                              }
 +                                      } else {
 +                                              i /= 2;
 +                                              ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
 +                                              if (overflow) {
 +                                                      ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
 +                                                      return SUCCESS;
                                                }
                                        }
 -                                      /* i == 0 */
 -                                      ZVAL_LONG(result, l1);
 -                              } else {
 -                                      ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
                                }
 -                              return SUCCESS;
 +                              /* i == 0 */
 +                              ZVAL_LONG(result, l1);
 +                      } else {
 +                              ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
 +                      }
 +                      return SUCCESS;
  
 -                      case TYPE_PAIR(IS_LONG, IS_DOUBLE):
 -                              ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
 -                              return SUCCESS;
 +              } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) {
 +                      ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
 +                      return SUCCESS;
  
 -                      case TYPE_PAIR(IS_DOUBLE, IS_LONG):
 -                              ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
 -                              return SUCCESS;
 +              } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) {
 +                      ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
 +                      return SUCCESS;
  
 -                      case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
 -                              ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
 -                              return SUCCESS;
 +              } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) {
 +                      ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
 +                      return SUCCESS;
  
 -                      default:
 -                              if (Z_ISREF_P(op1)) {
 -                                      op1 = Z_REFVAL_P(op1);
 -                              } else if (Z_ISREF_P(op2)) {
 -                                      op2 = Z_REFVAL_P(op2);
 -                              } else if (!converted) {
 -                                      ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
 +              } else {
 +                      if (Z_ISREF_P(op1)) {
 +                              op1 = Z_REFVAL_P(op1);
 +                      } else if (Z_ISREF_P(op2)) {
 +                              op2 = Z_REFVAL_P(op2);
 +                      } else if (!converted) {
 +                              ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
  
 -                                      if (EXPECTED(op1 != op2)) {
 -                                              if (Z_TYPE_P(op1) == IS_ARRAY) {
 -                                                      if (op1 == result) {
 -                                                              zval_ptr_dtor(result);
 -                                                      }
 -                                                      ZVAL_LONG(result, 0);
 -                                                      return SUCCESS;
 -                                              } else {
 -                                                      zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
 -                                              }
 -                                              if (Z_TYPE_P(op2) == IS_ARRAY) {
 -                                                      if (op1 == result) {
 -                                                              zval_ptr_dtor(result);
 -                                                      }
 -                                                      ZVAL_LONG(result, 1L);
 -                                                      return SUCCESS;
 -                                              } else {
 -                                                      zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
 +                              if (EXPECTED(op1 != op2)) {
 +                                      if (Z_TYPE_P(op1) == IS_ARRAY) {
++                                              if (op1 == result) {
++                                                      zval_ptr_dtor(result);
+                                               }
 +                                              ZVAL_LONG(result, 0);
 +                                              return SUCCESS;
                                        } else {
 -                                              if (Z_TYPE_P(op1) == IS_ARRAY) {
 -                                                      if (op1 == result) {
 -                                                              zval_ptr_dtor(result);
 -                                                      }
 -                                                      ZVAL_LONG(result, 0);
 -                                                      return SUCCESS;
 -                                              } else {
 -                                                      zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
 +                                              op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
 +                                      }
 +                                      if (Z_TYPE_P(op2) == IS_ARRAY) {
++                                              if (op1 == result) {
++                                                      zval_ptr_dtor(result);
+                                               }
 -                                              op2 = op1;
 +                                              ZVAL_LONG(result, 1L);
 +                                              return SUCCESS;
 +                                      } else {
 +                                              op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 0);
                                        }
 -                                      converted = 1;
                                } else {
 +                                      if (Z_TYPE_P(op1) == IS_ARRAY) {
++                                              if (op1 == result) {
++                                                      zval_ptr_dtor(result);
++                                              }
 +                                              ZVAL_LONG(result, 0);
 +                                              return SUCCESS;
 +                                      } else {
 +                                              op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 0);
 +                                      }
 +                                      op2 = op1;
 +                              }
 +                              if (EG(exception)) {
                                        if (result != op1) {
                                                ZVAL_UNDEF(result);
                                        }