PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_operators.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 810 981 82.6 %
Date: 2015-07-20 Functions: 61 70 87.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include <ctype.h>
      23             : 
      24             : #include "zend.h"
      25             : #include "zend_operators.h"
      26             : #include "zend_variables.h"
      27             : #include "zend_globals.h"
      28             : #include "zend_list.h"
      29             : #include "zend_API.h"
      30             : #include "zend_strtod.h"
      31             : #include "zend_exceptions.h"
      32             : #include "zend_closures.h"
      33             : 
      34             : #if ZEND_USE_TOLOWER_L
      35             : #include <locale.h>
      36             : static _locale_t current_locale = NULL;
      37             : /* this is true global! may lead to strange effects on ZTS, but so may setlocale() */
      38             : #define zend_tolower(c) _tolower_l(c, current_locale)
      39             : #else
      40             : #define zend_tolower(c) tolower(c)
      41             : #endif
      42             : 
      43             : #define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
      44             : 
      45       61325 : ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
      46             : {
      47             :         int retval;
      48             : 
      49       61325 :         if (!str_len) {
      50       40567 :                 str_len = strlen(str);
      51             :         }
      52       61325 :         retval = strtol(str, NULL, 0);
      53       61325 :         if (str_len>0) {
      54       41026 :                 switch (str[str_len-1]) {
      55             :                         case 'g':
      56             :                         case 'G':
      57           0 :                                 retval *= 1024;
      58             :                                 /* break intentionally missing */
      59             :                         case 'm':
      60             :                         case 'M':
      61           0 :                                 retval *= 1024;
      62             :                                 /* break intentionally missing */
      63             :                         case 'k':
      64             :                         case 'K':
      65           0 :                                 retval *= 1024;
      66             :                                 break;
      67             :                 }
      68             :         }
      69       61325 :         return retval;
      70             : }
      71             : /* }}} */
      72             : 
      73     1501224 : ZEND_API long zend_atol(const char *str, int str_len) /* {{{ */
      74             : {
      75             :         long retval;
      76             : 
      77     1501224 :         if (!str_len) {
      78       40464 :                 str_len = strlen(str);
      79             :         }
      80     1501224 :         retval = strtol(str, NULL, 0);
      81     1501224 :         if (str_len>0) {
      82     1460760 :                 switch (str[str_len-1]) {
      83             :                         case 'g':
      84             :                         case 'G':
      85           4 :                                 retval *= 1024;
      86             :                                 /* break intentionally missing */
      87             :                         case 'm':
      88             :                         case 'M':
      89       60784 :                                 retval *= 1024;
      90             :                                 /* break intentionally missing */
      91             :                         case 'k':
      92             :                         case 'K':
      93       81061 :                                 retval *= 1024;
      94             :                                 break;
      95             :                 }
      96             :         }
      97     1501224 :         return retval;
      98             : }
      99             : /* }}} */
     100             : 
     101           0 : ZEND_API double zend_string_to_double(const char *number, zend_uint length) /* {{{ */
     102             : {
     103           0 :         double divisor = 10.0;
     104           0 :         double result = 0.0;
     105             :         double exponent;
     106           0 :         const char *end = number+length;
     107           0 :         const char *digit = number;
     108             : 
     109           0 :         if (!length) {
     110           0 :                 return result;
     111             :         }
     112             : 
     113           0 :         while (digit < end) {
     114           0 :                 if ((*digit <= '9' && *digit >= '0')) {
     115           0 :                         result *= 10;
     116           0 :                         result += *digit - '0';
     117           0 :                 } else if (*digit == '.') {
     118           0 :                         digit++;
     119           0 :                         break;
     120           0 :                 } else if (toupper(*digit) == 'E') {
     121           0 :                         exponent = (double) atoi(digit+1);
     122           0 :                         result *= pow(10.0, exponent);
     123           0 :                         return result;
     124             :                 } else {
     125           0 :                         return result;
     126             :                 }
     127           0 :                 digit++;
     128             :         }
     129             : 
     130           0 :         while (digit < end) {
     131           0 :                 if ((*digit <= '9' && *digit >= '0')) {
     132           0 :                         result += (*digit - '0') / divisor;
     133           0 :                         divisor *= 10;
     134           0 :                 } else if (toupper(*digit) == 'E') {
     135           0 :                         exponent = (double) atoi(digit+1);
     136           0 :                         result *= pow(10.0, exponent);
     137           0 :                         return result;
     138             :                 } else {
     139           0 :                         return result;
     140             :                 }
     141           0 :                 digit++;
     142             :         }
     143           0 :         return result;
     144             : }
     145             : /* }}} */
     146             : 
     147      207778 : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
     148             : {
     149      207778 :         switch (Z_TYPE_P(op)) {
     150             :                 case IS_STRING:
     151             :                         {
     152             :                                 char *strval;
     153             : 
     154      101171 :                                 strval = Z_STRVAL_P(op);
     155      101171 :                                 if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
     156          50 :                                         ZVAL_LONG(op, 0);
     157             :                                 }
     158      101171 :                                 STR_FREE(strval);
     159      101171 :                                 break;
     160             :                         }
     161             :                 case IS_BOOL:
     162          39 :                         Z_TYPE_P(op) = IS_LONG;
     163          39 :                         break;
     164             :                 case IS_RESOURCE:
     165           7 :                         zend_list_delete(Z_LVAL_P(op));
     166           7 :                         Z_TYPE_P(op) = IS_LONG;
     167           7 :                         break;
     168             :                 case IS_OBJECT:
     169           7 :                         convert_to_long_base(op, 10);
     170           7 :                         break;
     171             :                 case IS_NULL:
     172          53 :                         ZVAL_LONG(op, 0);
     173             :                         break;
     174             :         }
     175      207778 : }
     176             : /* }}} */
     177             : 
     178             : /* {{{ zendi_convert_scalar_to_number */
     179             : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     180             :         if (op==result) {                                                                                               \
     181             :                 if (Z_TYPE_P(op) != IS_LONG) {                                                          \
     182             :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     183             :                 }                                                                                                                       \
     184             :         } else {                                                                                                                \
     185             :                 switch (Z_TYPE_P(op)) {                                                                         \
     186             :                         case IS_STRING:                                                                                 \
     187             :                                 {                                                                                                       \
     188             :                                         if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {     \
     189             :                                                 ZVAL_LONG(&(holder), 0);                                                    \
     190             :                                         }                                                                                                               \
     191             :                                         (op) = &(holder);                                                                           \
     192             :                                         break;                                                                                                  \
     193             :                                 }                                                                                                                       \
     194             :                         case IS_BOOL:                                                                                                   \
     195             :                         case IS_RESOURCE:                                                                                               \
     196             :                                 ZVAL_LONG(&(holder), Z_LVAL_P(op));                                                 \
     197             :                                 (op) = &(holder);                                                                                   \
     198             :                                 break;                                                                                                          \
     199             :                         case IS_NULL:                                                                                                   \
     200             :                                 ZVAL_LONG(&(holder), 0);                                                                    \
     201             :                                 (op) = &(holder);                                                                                   \
     202             :                                 break;                                                                                                          \
     203             :                         case IS_OBJECT:                                                                                                 \
     204             :                                 (holder) = (*(op));                                                                                     \
     205             :                                 zval_copy_ctor(&(holder));                                                                  \
     206             :                                 convert_to_long_base(&(holder), 10);                                                \
     207             :                                 if (Z_TYPE(holder) == IS_LONG) {                                                        \
     208             :                                         (op) = &(holder);                                                                           \
     209             :                                 }                                                                                                                       \
     210             :                                 break;                                                                                                          \
     211             :                 }                                                                                                                                       \
     212             :         }
     213             : 
     214             : /* }}} */
     215             : 
     216             : /* {{{ zendi_convert_to_long */
     217             : #define zendi_convert_to_long(op, holder, result)                                       \
     218             :         if (op == result) {                                                                                             \
     219             :                 convert_to_long(op);                                                                            \
     220             :         } else if (Z_TYPE_P(op) != IS_LONG) {                                                   \
     221             :                 switch (Z_TYPE_P(op)) {                                                                         \
     222             :                         case IS_NULL:                                                                                   \
     223             :                                 Z_LVAL(holder) = 0;                                                                     \
     224             :                                 break;                                                                                          \
     225             :                         case IS_DOUBLE:                                                                                 \
     226             :                                 Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));       \
     227             :                                 break;                                                                                          \
     228             :                         case IS_STRING:                                                                                 \
     229             :                                 Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);      \
     230             :                                 break;                                                                                          \
     231             :                         case IS_ARRAY:                                                                                  \
     232             :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     233             :                                 break;                                                                                          \
     234             :                         case IS_OBJECT:                                                                                 \
     235             :                                 (holder) = (*(op));                                                                     \
     236             :                                 zval_copy_ctor(&(holder));                                                  \
     237             :                                 convert_to_long_base(&(holder), 10);                                \
     238             :                                 break;                                                                                          \
     239             :                         case IS_BOOL:                                                                                   \
     240             :                         case IS_RESOURCE:                                                                               \
     241             :                                 Z_LVAL(holder) = Z_LVAL_P(op);                                          \
     242             :                                 break;                                                                                          \
     243             :                         default:                                                                                                \
     244             :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");     \
     245             :                                 Z_LVAL(holder) = 0;                                                                     \
     246             :                                 break;                                                                                          \
     247             :                 }                                                                                                                       \
     248             :                 Z_TYPE(holder) = IS_LONG;                                                                       \
     249             :                 (op) = &(holder);                                                                                   \
     250             :         }
     251             : 
     252             : /* }}} */
     253             : 
     254             : /* {{{ zendi_convert_to_boolean */
     255             : #define zendi_convert_to_boolean(op, holder, result)                            \
     256             :         if (op==result) {                                                                                               \
     257             :                 convert_to_boolean(op);                                                                         \
     258             :         } else if (Z_TYPE_P(op) != IS_BOOL) {                                                   \
     259             :                 switch (Z_TYPE_P(op)) {                                                                         \
     260             :                         case IS_NULL:                                                                                   \
     261             :                                 Z_LVAL(holder) = 0;                                                                     \
     262             :                                 break;                                                                                          \
     263             :                         case IS_RESOURCE:                                                                               \
     264             :                         case IS_LONG:                                                                                   \
     265             :                                 Z_LVAL(holder) = (Z_LVAL_P(op) ? 1 : 0);                        \
     266             :                                 break;                                                                                          \
     267             :                         case IS_DOUBLE:                                                                                 \
     268             :                                 Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0);                        \
     269             :                                 break;                                                                                          \
     270             :                         case IS_STRING:                                                                                 \
     271             :                                 if (Z_STRLEN_P(op) == 0                                                         \
     272             :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {     \
     273             :                                         Z_LVAL(holder) = 0;                                                             \
     274             :                                 } else {                                                                                        \
     275             :                                         Z_LVAL(holder) = 1;                                                             \
     276             :                                 }                                                                                                       \
     277             :                                 break;                                                                                          \
     278             :                         case IS_ARRAY:                                                                                  \
     279             :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     280             :                                 break;                                                                                          \
     281             :                         case IS_OBJECT:                                                                                 \
     282             :                                 (holder) = (*(op));                                                                     \
     283             :                                 zval_copy_ctor(&(holder));                                                  \
     284             :                                 convert_to_boolean(&(holder));                                              \
     285             :                                 break;                                                                                          \
     286             :                         default:                                                                                                \
     287             :                                 Z_LVAL(holder) = 0;                                                                     \
     288             :                                 break;                                                                                          \
     289             :                 }                                                                                                                       \
     290             :                 Z_TYPE(holder) = IS_BOOL;                                                                       \
     291             :                 (op) = &(holder);                                                                                   \
     292             :         }
     293             : 
     294             : /* }}} */
     295             : 
     296             : /* {{{ convert_object_to_type */
     297             : #define convert_object_to_type(op, ctype, conv_func)                                                                            \
     298             :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     299             :                 zval dst;                                                                                                                                                       \
     300             :                 if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) {                 \
     301             :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     302             :                                 "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name,            \
     303             :                         zend_get_type_by_const(ctype));                                                                                                 \
     304             :                 } else {                                                                                                                                                        \
     305             :                         zval_dtor(op);                                                                                                                                  \
     306             :                         Z_TYPE_P(op) = ctype;                                                                                                                   \
     307             :                         op->value = dst.value;                                                                                                                       \
     308             :                 }                                                                                                                                                                       \
     309             :         } else {                                                                                                                                                                \
     310             :                 if (Z_OBJ_HT_P(op)->get) {                                                                                                                   \
     311             :                         zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);                                                             \
     312             :                         if (Z_TYPE_P(newop) != IS_OBJECT) {                                                                                             \
     313             :                                 /* for safety - avoid loop */                                                                                           \
     314             :                                 zval_dtor(op);                                                                                                                          \
     315             :                                 *op = *newop;                                                                                                                           \
     316             :                                 FREE_ZVAL(newop);                                                                                                                       \
     317             :                                 conv_func(op);                                                                                                                          \
     318             :                         }                                                                                                                                                               \
     319             :                 }                                                                                                                                                                       \
     320             :         }
     321             : 
     322             : /* }}} */
     323             : 
     324      603152 : ZEND_API void convert_to_long(zval *op) /* {{{ */
     325             : {
     326      603152 :         if (Z_TYPE_P(op) != IS_LONG) {
     327       61327 :                 convert_to_long_base(op, 10);
     328             :         }
     329      603152 : }
     330             : /* }}} */
     331             : 
     332       65054 : ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
     333             : {
     334             :         long tmp;
     335             : 
     336       65054 :         switch (Z_TYPE_P(op)) {
     337             :                 case IS_NULL:
     338        1457 :                         Z_LVAL_P(op) = 0;
     339        1457 :                         break;
     340             :                 case IS_RESOURCE: {
     341             :                                 TSRMLS_FETCH();
     342             : 
     343         122 :                                 zend_list_delete(Z_LVAL_P(op));
     344             :                         }
     345             :                         /* break missing intentionally */
     346             :                 case IS_BOOL:
     347             :                 case IS_LONG:
     348       10575 :                         break;
     349             :                 case IS_DOUBLE:
     350       10994 :                         Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
     351        5497 :                         break;
     352             :                 case IS_STRING:
     353             :                         {
     354       46624 :                                 char *strval = Z_STRVAL_P(op);
     355             : 
     356       46624 :                                 Z_LVAL_P(op) = strtol(strval, NULL, base);
     357       46624 :                                 STR_FREE(strval);
     358             :                         }
     359       46624 :                         break;
     360             :                 case IS_ARRAY:
     361         849 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     362             :                         zval_dtor(op);
     363         849 :                         Z_LVAL_P(op) = tmp;
     364         849 :                         break;
     365             :                 case IS_OBJECT:
     366             :                         {
     367          52 :                                 int retval = 1;
     368             :                                 TSRMLS_FETCH();
     369             : 
     370         104 :                                 convert_object_to_type(op, IS_LONG, convert_to_long);
     371             : 
     372          52 :                                 if (Z_TYPE_P(op) == IS_LONG) {
     373          52 :                                         return;
     374             :                                 }
     375           0 :                                 zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
     376             : 
     377             :                                 zval_dtor(op);
     378           0 :                                 ZVAL_LONG(op, retval);
     379           0 :                                 return;
     380             :                         }
     381             :                 default:
     382           0 :                         zend_error(E_WARNING, "Cannot convert to ordinal value");
     383             :                         zval_dtor(op);
     384           0 :                         Z_LVAL_P(op) = 0;
     385             :                         break;
     386             :         }
     387             : 
     388       65002 :         Z_TYPE_P(op) = IS_LONG;
     389             : }
     390             : /* }}} */
     391             : 
     392      197732 : ZEND_API void convert_to_double(zval *op) /* {{{ */
     393             : {
     394             :         double tmp;
     395             : 
     396      197732 :         switch (Z_TYPE_P(op)) {
     397             :                 case IS_NULL:
     398         316 :                         Z_DVAL_P(op) = 0.0;
     399         316 :                         break;
     400             :                 case IS_RESOURCE: {
     401             :                                 TSRMLS_FETCH();
     402             : 
     403          48 :                                 zend_list_delete(Z_LVAL_P(op));
     404             :                         }
     405             :                         /* break missing intentionally */
     406             :                 case IS_BOOL:
     407             :                 case IS_LONG:
     408      192996 :                         Z_DVAL_P(op) = (double) Z_LVAL_P(op);
     409      192996 :                         break;
     410             :                 case IS_DOUBLE:
     411        3206 :                         break;
     412             :                 case IS_STRING:
     413             :                         {
     414         841 :                                 char *strval = Z_STRVAL_P(op);
     415             : 
     416         841 :                                 Z_DVAL_P(op) = zend_strtod(strval, NULL);
     417         841 :                                 STR_FREE(strval);
     418             :                         }
     419         841 :                         break;
     420             :                 case IS_ARRAY:
     421         359 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     422             :                         zval_dtor(op);
     423         359 :                         Z_DVAL_P(op) = tmp;
     424         359 :                         break;
     425             :                 case IS_OBJECT:
     426             :                         {
     427          14 :                                 double retval = 1.0;
     428             :                                 TSRMLS_FETCH();
     429             : 
     430          28 :                                 convert_object_to_type(op, IS_DOUBLE, convert_to_double);
     431             : 
     432          14 :                                 if (Z_TYPE_P(op) == IS_DOUBLE) {
     433          14 :                                         return;
     434             :                                 }
     435           0 :                                 zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
     436             : 
     437             :                                 zval_dtor(op);
     438           0 :                                 ZVAL_DOUBLE(op, retval);
     439           0 :                                 break;
     440             :                         }
     441             :                 default:
     442           0 :                         zend_error(E_WARNING, "Cannot convert to real value (type=%d)", Z_TYPE_P(op));
     443             :                         zval_dtor(op);
     444           0 :                         Z_DVAL_P(op) = 0;
     445             :                         break;
     446             :         }
     447      197718 :         Z_TYPE_P(op) = IS_DOUBLE;
     448             : }
     449             : /* }}} */
     450             : 
     451         914 : ZEND_API void convert_to_null(zval *op) /* {{{ */
     452             : {
     453         914 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     454           3 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     455             :                         zval *org;
     456             :                         TSRMLS_FETCH();
     457             : 
     458           3 :                         ALLOC_ZVAL(org);
     459           3 :                         *org = *op;
     460           3 :                         if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
     461             :                                 zval_dtor(org);
     462           0 :                                 return;
     463             :                         }
     464           3 :                         *op = *org;
     465           3 :                         FREE_ZVAL(org);
     466             :                 }
     467             :         }
     468             : 
     469             :         zval_dtor(op);
     470         914 :         Z_TYPE_P(op) = IS_NULL;
     471             : }
     472             : /* }}} */
     473             : 
     474       79595 : ZEND_API void convert_to_boolean(zval *op) /* {{{ */
     475             : {
     476             :         int tmp;
     477             : 
     478       79595 :         switch (Z_TYPE_P(op)) {
     479             :                 case IS_BOOL:
     480        3569 :                         break;
     481             :                 case IS_NULL:
     482         129 :                         Z_LVAL_P(op) = 0;
     483         129 :                         break;
     484             :                 case IS_RESOURCE: {
     485             :                                 TSRMLS_FETCH();
     486             : 
     487          31 :                                 zend_list_delete(Z_LVAL_P(op));
     488             :                         }
     489             :                         /* break missing intentionally */
     490             :                 case IS_LONG:
     491         767 :                         Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
     492         767 :                         break;
     493             :                 case IS_DOUBLE:
     494         133 :                         Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
     495         133 :                         break;
     496             :                 case IS_STRING:
     497             :                         {
     498         163 :                                 char *strval = Z_STRVAL_P(op);
     499             : 
     500         331 :                                 if (Z_STRLEN_P(op) == 0
     501         273 :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
     502          58 :                                         Z_LVAL_P(op) = 0;
     503             :                                 } else {
     504         105 :                                         Z_LVAL_P(op) = 1;
     505             :                                 }
     506         163 :                                 STR_FREE(strval);
     507             :                         }
     508         163 :                         break;
     509             :                 case IS_ARRAY:
     510          24 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     511             :                         zval_dtor(op);
     512          24 :                         Z_LVAL_P(op) = tmp;
     513          24 :                         break;
     514             :                 case IS_OBJECT:
     515             :                         {
     516       74810 :                                 zend_bool retval = 1;
     517             :                                 TSRMLS_FETCH();
     518             : 
     519      149620 :                                 convert_object_to_type(op, IS_BOOL, convert_to_boolean);
     520             : 
     521       74810 :                                 if (Z_TYPE_P(op) == IS_BOOL) {
     522       74810 :                                         return;
     523             :                                 }
     524             : 
     525             :                                 zval_dtor(op);
     526           0 :                                 ZVAL_BOOL(op, retval);
     527           0 :                                 break;
     528             :                         }
     529             :                 default:
     530             :                         zval_dtor(op);
     531           0 :                         Z_LVAL_P(op) = 0;
     532             :                         break;
     533             :         }
     534        4785 :         Z_TYPE_P(op) = IS_BOOL;
     535             : }
     536             : /* }}} */
     537             : 
     538     1748374 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     539             : {
     540             :         long lval;
     541             :         double dval;
     542             : 
     543     1748374 :         switch (Z_TYPE_P(op)) {
     544             :                 case IS_NULL:
     545        4004 :                         Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     546        4004 :                         Z_STRLEN_P(op) = 0;
     547        4004 :                         break;
     548             :                 case IS_STRING:
     549           0 :                         break;
     550             :                 case IS_BOOL:
     551        2092 :                         if (Z_LVAL_P(op)) {
     552         867 :                                 Z_STRVAL_P(op) = estrndup_rel("1", 1);
     553         867 :                                 Z_STRLEN_P(op) = 1;
     554             :                         } else {
     555        1225 :                                 Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     556        1225 :                                 Z_STRLEN_P(op) = 0;
     557             :                         }
     558        2092 :                         break;
     559             :                 case IS_RESOURCE: {
     560          58 :                         long tmp = Z_LVAL_P(op);
     561             :                         TSRMLS_FETCH();
     562             : 
     563          58 :                         zend_list_delete(Z_LVAL_P(op));
     564          58 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "Resource id #%ld", tmp);
     565          58 :                         break;
     566             :                 }
     567             :                 case IS_LONG:
     568     1739743 :                         lval = Z_LVAL_P(op);
     569             : 
     570     1739743 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%ld", lval);
     571     1739743 :                         break;
     572             :                 case IS_DOUBLE: {
     573             :                         TSRMLS_FETCH();
     574        2144 :                         dval = Z_DVAL_P(op);
     575        2144 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), dval);
     576             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     577        2144 :                         break;
     578             :                 }
     579             :                 case IS_ARRAY:
     580         244 :                         zend_error(E_NOTICE, "Array to string conversion");
     581             :                         zval_dtor(op);
     582         244 :                         Z_STRVAL_P(op) = estrndup_rel("Array", sizeof("Array")-1);
     583         244 :                         Z_STRLEN_P(op) = sizeof("Array")-1;
     584         244 :                         break;
     585             :                 case IS_OBJECT: {
     586             :                         TSRMLS_FETCH();
     587             : 
     588         159 :                         convert_object_to_type(op, IS_STRING, convert_to_string);
     589             : 
     590          80 :                         if (Z_TYPE_P(op) == IS_STRING) {
     591          70 :                                 return;
     592             :                         }
     593             : 
     594          10 :                         zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
     595             :                         zval_dtor(op);
     596          10 :                         Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1);
     597          10 :                         Z_STRLEN_P(op) = sizeof("Object")-1;
     598          10 :                         break;
     599             :                 }
     600             :                 default:
     601             :                         zval_dtor(op);
     602           0 :                         ZVAL_BOOL(op, 0);
     603             :                         break;
     604             :         }
     605     1748295 :         Z_TYPE_P(op) = IS_STRING;
     606             : }
     607             : /* }}} */
     608             : 
     609         201 : static void convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
     610             : {
     611             :         zval *entry;
     612             : 
     613         201 :         ALLOC_ZVAL(entry);
     614         201 :         *entry = *op;
     615         201 :         INIT_PZVAL(entry);
     616             : 
     617         201 :         switch (type) {
     618             :                 case IS_ARRAY:
     619         150 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
     620         150 :                         zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
     621         150 :                         zend_hash_index_update(Z_ARRVAL_P(op), 0, (void *) &entry, sizeof(zval *), NULL);
     622         150 :                         Z_TYPE_P(op) = IS_ARRAY;
     623         150 :                         break;
     624             :                 case IS_OBJECT:
     625          51 :                         object_init(op);
     626          51 :                         zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
     627             :                         break;
     628             :         }
     629         201 : }
     630             : /* }}} */
     631             : 
     632       20410 : ZEND_API void convert_to_array(zval *op) /* {{{ */
     633             : {
     634             :         TSRMLS_FETCH();
     635             : 
     636       20410 :         switch (Z_TYPE_P(op)) {
     637             :                 case IS_ARRAY:
     638       20221 :                         break;
     639             : /* OBJECTS_OPTIMIZE */
     640             :                 case IS_OBJECT:
     641             :                         {
     642             :                                 zval *tmp;
     643             :                                 HashTable *ht;
     644             : 
     645          18 :                                 ALLOC_HASHTABLE(ht);
     646          18 :                                 zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     647          18 :                                 if (Z_OBJCE_P(op) == zend_ce_closure) {
     648           3 :                                         convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
     649           3 :                                         if (Z_TYPE_P(op) == IS_ARRAY) {
     650           3 :                                                 zend_hash_destroy(ht);
     651           3 :                                                 FREE_HASHTABLE(ht);
     652           3 :                                                 return;
     653             :                                         }
     654          15 :                                 } else if (Z_OBJ_HT_P(op)->get_properties) {
     655          15 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
     656          15 :                                         if (obj_ht) {
     657          15 :                                                 zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     658             :                                         }
     659             :                                 } else {
     660           0 :                                         convert_object_to_type(op, IS_ARRAY, convert_to_array);
     661             : 
     662           0 :                                         if (Z_TYPE_P(op) == IS_ARRAY) {
     663           0 :                                                 zend_hash_destroy(ht);
     664           0 :                                                 FREE_HASHTABLE(ht);
     665           0 :                                                 return;
     666             :                                         }
     667             :                                 }
     668             :                                 zval_dtor(op);
     669          15 :                                 Z_TYPE_P(op) = IS_ARRAY;
     670          15 :                                 Z_ARRVAL_P(op) = ht;
     671             :                         }
     672          15 :                         break;
     673             :                 case IS_NULL:
     674          24 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
     675          24 :                         zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
     676          24 :                         Z_TYPE_P(op) = IS_ARRAY;
     677          24 :                         break;
     678             :                 default:
     679         147 :                         convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
     680             :                         break;
     681             :         }
     682             : }
     683             : /* }}} */
     684             : 
     685         129 : ZEND_API void convert_to_object(zval *op) /* {{{ */
     686             : {
     687             :         TSRMLS_FETCH();
     688             : 
     689         129 :         switch (Z_TYPE_P(op)) {
     690             :                 case IS_ARRAY:
     691             :                         {
     692          67 :                                 object_and_properties_init(op, zend_standard_class_def, Z_ARRVAL_P(op));
     693          67 :                                 break;
     694             :                         }
     695             :                 case IS_OBJECT:
     696           7 :                         break;
     697             :                 case IS_NULL:
     698           4 :                         object_init(op);
     699           4 :                         break;
     700             :                 default:
     701          51 :                         convert_scalar_to_array(op, IS_OBJECT TSRMLS_CC);
     702             :                         break;
     703             :         }
     704         129 : }
     705             : /* }}} */
     706             : 
     707           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     708             : {
     709             :         zval **arg;
     710             :         va_list ap;
     711             : 
     712           0 :         va_start(ap, argc);
     713             : 
     714           0 :         while (argc--) {
     715           0 :                 arg = va_arg(ap, zval **);
     716           0 :                 convert_to_long_ex(arg);
     717             :         }
     718             : 
     719           0 :         va_end(ap);
     720           0 : }
     721             : /* }}} */
     722             : 
     723           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     724             : {
     725             :         zval **arg;
     726             :         va_list ap;
     727             : 
     728           0 :         va_start(ap, argc);
     729             : 
     730           0 :         while (argc--) {
     731           0 :                 arg = va_arg(ap, zval **);
     732           0 :                 convert_to_double_ex(arg);
     733             :         }
     734             : 
     735           0 :         va_end(ap);
     736           0 : }
     737             : /* }}} */
     738             : 
     739           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     740             : {
     741             :         zval **arg;
     742             :         va_list ap;
     743             : 
     744           0 :         va_start(ap, argc);
     745             : 
     746           0 :         while (argc--) {
     747           0 :                 arg = va_arg(ap, zval **);
     748           0 :                 convert_to_string_ex(arg);
     749             :         }
     750             : 
     751           0 :         va_end(ap);
     752           0 : }
     753             : /* }}} */
     754             : 
     755      775156 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     756             : {
     757             :         zval op1_copy, op2_copy;
     758      775156 :         int converted = 0;
     759             : 
     760             :         while (1) {
     761      775618 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     762             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     763      774860 :                                 long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
     764             : 
     765             :                                 /* check for overflow by comparing sign bits */
     766     1549630 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     767     1549630 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     768             : 
     769           0 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     770             :                                 } else {
     771      774860 :                                         ZVAL_LONG(result, lval);
     772             :                                 }
     773      774860 :                                 return SUCCESS;
     774             :                         }
     775             : 
     776             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     777         176 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     778         176 :                                 return SUCCESS;
     779             : 
     780             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     781          57 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     782          57 :                                 return SUCCESS;
     783             : 
     784             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     785          53 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     786          53 :                                 return SUCCESS;
     787             : 
     788             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
     789             :                                 zval *tmp;
     790             : 
     791           6 :                                 if ((result == op1) && (result == op2)) {
     792             :                                         /* $a += $a */
     793           1 :                                         return SUCCESS;
     794             :                                 }
     795           5 :                                 if (result != op1) {
     796           4 :                                         *result = *op1;
     797             :                                         zval_copy_ctor(result);
     798             :                                 }
     799           5 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
     800           5 :                                 return SUCCESS;
     801             :                         }
     802             : 
     803             :                         default:
     804         466 :                                 if (!converted) {
     805         463 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     806         463 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     807         462 :                                         converted = 1;
     808             :                                 } else {
     809           4 :                                         zend_error(E_ERROR, "Unsupported operand types");
     810           0 :                                         return FAILURE; /* unknown datatype */
     811             :                                 }
     812             :                 }
     813         462 :         }
     814             : }
     815             : /* }}} */
     816             : 
     817       62968 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     818             : {
     819             :         zval op1_copy, op2_copy;
     820       62968 :         int converted = 0;
     821             : 
     822             :         while (1) {
     823       63227 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     824             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     825       61166 :                                 long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
     826             : 
     827             :                                 /* check for overflow by comparing sign bits */
     828       61184 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     829       61184 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     830             : 
     831           0 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     832             :                                 } else {
     833       61166 :                                         ZVAL_LONG(result, lval);
     834             :                                 }
     835       61166 :                                 return SUCCESS;
     836             : 
     837             :                         }
     838             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     839        1699 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     840        1699 :                                 return SUCCESS;
     841             : 
     842             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     843          48 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     844          48 :                                 return SUCCESS;
     845             : 
     846             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     847          54 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     848          54 :                                 return SUCCESS;
     849             : 
     850             :                         default:
     851         260 :                                 if (!converted) {
     852         260 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     853         259 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     854         259 :                                         converted = 1;
     855             :                                 } else {
     856           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     857           0 :                                         return FAILURE; /* unknown datatype */
     858             :                                 }
     859             :                 }
     860         259 :         }
     861             : }
     862             : /* }}} */
     863             : 
     864         290 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     865             : {
     866             :         zval op1_copy, op2_copy;
     867         290 :         int converted = 0;
     868             : 
     869             :         while (1) {
     870         521 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     871             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     872             :                                 long overflow;
     873             : 
     874         162 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
     875         162 :                                 Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     876         162 :                                 return SUCCESS;
     877             : 
     878             :                         }
     879             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     880          45 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
     881          45 :                                 return SUCCESS;
     882             : 
     883             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     884          57 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
     885          57 :                                 return SUCCESS;
     886             : 
     887             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     888          25 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
     889          25 :                                 return SUCCESS;
     890             : 
     891             :                         default:
     892         232 :                                 if (!converted) {
     893         231 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     894         231 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     895         231 :                                         converted = 1;
     896             :                                 } else {
     897           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     898           0 :                                         return FAILURE; /* unknown datatype */
     899             :                                 }
     900             :                 }
     901         231 :         }
     902             : }
     903             : /* }}} */
     904             : 
     905      148573 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     906             : {
     907             :         zval op1_copy, op2_copy;
     908      148573 :         int converted = 0;
     909             : 
     910             :         while (1) {
     911      148800 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     912             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     913      135637 :                                 if (Z_LVAL_P(op2) == 0) {
     914          43 :                                         zend_error(E_WARNING, "Division by zero");
     915          43 :                                         ZVAL_BOOL(result, 0);
     916          43 :                                         return FAILURE;                 /* division by zero */
     917      135594 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
     918             :                                         /* Prevent overflow error/crash */
     919           1 :                                         ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
     920           1 :                                         return SUCCESS;
     921             :                                 }
     922      135593 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
     923       83753 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
     924             :                                 } else {
     925       51840 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
     926             :                                 }
     927      135593 :                                 return SUCCESS;
     928             : 
     929             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     930       12724 :                                 if (Z_LVAL_P(op2) == 0) {
     931          17 :                                         zend_error(E_WARNING, "Division by zero");
     932          17 :                                         ZVAL_BOOL(result, 0);
     933          17 :                                         return FAILURE;                 /* division by zero */
     934             :                                 }
     935       12707 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
     936       12707 :                                 return SUCCESS;
     937             : 
     938             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     939          67 :                                 if (Z_DVAL_P(op2) == 0) {
     940           0 :                                         zend_error(E_WARNING, "Division by zero");
     941           0 :                                         ZVAL_BOOL(result, 0);
     942           0 :                                         return FAILURE;                 /* division by zero */
     943             :                                 }
     944          67 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
     945          67 :                                 return SUCCESS;
     946             : 
     947             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     948         144 :                                 if (Z_DVAL_P(op2) == 0) {
     949           0 :                                         zend_error(E_WARNING, "Division by zero");
     950           0 :                                         ZVAL_BOOL(result, 0);
     951           0 :                                         return FAILURE;                 /* division by zero */
     952             :                                 }
     953         144 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
     954         144 :                                 return SUCCESS;
     955             : 
     956             :                         default:
     957         228 :                                 if (!converted) {
     958         227 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     959         227 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     960         227 :                                         converted = 1;
     961             :                                 } else {
     962           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     963           0 :                                         return FAILURE; /* unknown datatype */
     964             :                                 }
     965             :                 }
     966         227 :         }
     967             : }
     968             : /* }}} */
     969             : 
     970         382 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     971             : {
     972             :         zval op1_copy, op2_copy;
     973             :         long op1_lval;
     974             : 
     975         503 :         zendi_convert_to_long(op1, op1_copy, result);
     976         382 :         op1_lval = Z_LVAL_P(op1);
     977         502 :         zendi_convert_to_long(op2, op2_copy, result);
     978             : 
     979         382 :         if (Z_LVAL_P(op2) == 0) {
     980          45 :                 zend_error(E_WARNING, "Division by zero");
     981          45 :                 ZVAL_BOOL(result, 0);
     982          45 :                 return FAILURE;                 /* modulus by zero */
     983             :         }
     984             : 
     985         337 :         if (Z_LVAL_P(op2) == -1) {
     986             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
     987           2 :                 ZVAL_LONG(result, 0);
     988           2 :                 return SUCCESS;
     989             :         }
     990             : 
     991         335 :         ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
     992         335 :         return SUCCESS;
     993             : }
     994             : /* }}} */
     995             : 
     996           0 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     997             : {
     998             :         zval op1_copy, op2_copy;
     999             :         long op1_lval;
    1000             : 
    1001           0 :         zendi_convert_to_boolean(op1, op1_copy, result);
    1002           0 :         op1_lval = Z_LVAL_P(op1);
    1003           0 :         zendi_convert_to_boolean(op2, op2_copy, result);
    1004           0 :         ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2));
    1005           0 :         return SUCCESS;
    1006             : }
    1007             : /* }}} */
    1008             : 
    1009     2974073 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1010             : {
    1011             :         zval op1_copy;
    1012             : 
    1013     3048862 :         zendi_convert_to_boolean(op1, op1_copy, result);
    1014     2974073 :         ZVAL_BOOL(result, !Z_LVAL_P(op1));
    1015     2974073 :         return SUCCESS;
    1016             : }
    1017             : /* }}} */
    1018             : 
    1019         139 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1020             : {
    1021         139 :         zval op1_copy = *op1;
    1022             : 
    1023         139 :         op1 = &op1_copy;
    1024             : 
    1025         139 :         if (Z_TYPE_P(op1) == IS_LONG) {
    1026         120 :                 ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1027         120 :                 return SUCCESS;
    1028          19 :         } else if (Z_TYPE_P(op1) == IS_DOUBLE) {
    1029           6 :                 ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1030           3 :                 return SUCCESS;
    1031          16 :         } else if (Z_TYPE_P(op1) == IS_STRING) {
    1032             :                 int i;
    1033             : 
    1034          15 :                 Z_TYPE_P(result) = IS_STRING;
    1035          15 :                 Z_STRVAL_P(result) = estrndup(Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1036          15 :                 Z_STRLEN_P(result) = Z_STRLEN_P(op1);
    1037          83 :                 for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1038          68 :                         Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1039             :                 }
    1040          15 :                 return SUCCESS;
    1041             :         }
    1042           1 :         zend_error(E_ERROR, "Unsupported operand types");
    1043           0 :         return FAILURE;                         /* unknown datatype */
    1044             : }
    1045             : /* }}} */
    1046             : 
    1047      577831 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1048             : {
    1049             :         zval op1_copy, op2_copy;
    1050             :         long op1_lval;
    1051             : 
    1052      577831 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1053             :                 zval *longer, *shorter;
    1054             :                 char *result_str;
    1055             :                 int i, result_len;
    1056             : 
    1057         200 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1058         117 :                         longer = op1;
    1059         117 :                         shorter = op2;
    1060             :                 } else {
    1061          83 :                         longer = op2;
    1062          83 :                         shorter = op1;
    1063             :                 }
    1064             : 
    1065         200 :                 Z_TYPE_P(result) = IS_STRING;
    1066         200 :                 result_len = Z_STRLEN_P(longer);
    1067         200 :                 result_str = estrndup(Z_STRVAL_P(longer), Z_STRLEN_P(longer));
    1068         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1069         688 :                         result_str[i] |= Z_STRVAL_P(shorter)[i];
    1070             :                 }
    1071         200 :                 if (result==op1) {
    1072           1 :                         STR_FREE(Z_STRVAL_P(result));
    1073             :                 }
    1074         200 :                 Z_STRVAL_P(result) = result_str;
    1075         200 :                 Z_STRLEN_P(result) = result_len;
    1076         200 :                 return SUCCESS;
    1077             :         }
    1078      577649 :         zendi_convert_to_long(op1, op1_copy, result);
    1079      577631 :         op1_lval = Z_LVAL_P(op1);
    1080      577649 :         zendi_convert_to_long(op2, op2_copy, result);
    1081             : 
    1082      577631 :         ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
    1083      577631 :         return SUCCESS;
    1084             : }
    1085             : /* }}} */
    1086             : 
    1087      359322 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1088             : {
    1089             :         zval op1_copy, op2_copy;
    1090             :         long op1_lval;
    1091             : 
    1092      359322 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1093             :                 zval *longer, *shorter;
    1094             :                 char *result_str;
    1095             :                 int i, result_len;
    1096             : 
    1097         201 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1098         117 :                         longer = op1;
    1099         117 :                         shorter = op2;
    1100             :                 } else {
    1101          84 :                         longer = op2;
    1102          84 :                         shorter = op1;
    1103             :                 }
    1104             : 
    1105         201 :                 Z_TYPE_P(result) = IS_STRING;
    1106         201 :                 result_len = Z_STRLEN_P(shorter);
    1107         201 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1108         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1109         687 :                         result_str[i] &= Z_STRVAL_P(longer)[i];
    1110             :                 }
    1111         201 :                 if (result==op1) {
    1112           1 :                         STR_FREE(Z_STRVAL_P(result));
    1113             :                 }
    1114         201 :                 Z_STRVAL_P(result) = result_str;
    1115         201 :                 Z_STRLEN_P(result) = result_len;
    1116         201 :                 return SUCCESS;
    1117             :         }
    1118             : 
    1119             : 
    1120      359139 :         zendi_convert_to_long(op1, op1_copy, result);
    1121      359121 :         op1_lval = Z_LVAL_P(op1);
    1122      359139 :         zendi_convert_to_long(op2, op2_copy, result);
    1123             : 
    1124      359121 :         ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
    1125      359121 :         return SUCCESS;
    1126             : }
    1127             : /* }}} */
    1128             : 
    1129         485 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1130             : {
    1131             :         zval op1_copy, op2_copy;
    1132             :         long op1_lval;
    1133             : 
    1134         485 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1135             :                 zval *longer, *shorter;
    1136             :                 char *result_str;
    1137             :                 int i, result_len;
    1138             : 
    1139         202 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1140         118 :                         longer = op1;
    1141         118 :                         shorter = op2;
    1142             :                 } else {
    1143          84 :                         longer = op2;
    1144          84 :                         shorter = op1;
    1145             :                 }
    1146             : 
    1147         202 :                 Z_TYPE_P(result) = IS_STRING;
    1148         202 :                 result_len = Z_STRLEN_P(shorter);
    1149         202 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1150         892 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1151         690 :                         result_str[i] ^= Z_STRVAL_P(longer)[i];
    1152             :                 }
    1153         202 :                 if (result==op1) {
    1154           1 :                         STR_FREE(Z_STRVAL_P(result));
    1155             :                 }
    1156         202 :                 Z_STRVAL_P(result) = result_str;
    1157         202 :                 Z_STRLEN_P(result) = result_len;
    1158         202 :                 return SUCCESS;
    1159             :         }
    1160             : 
    1161         301 :         zendi_convert_to_long(op1, op1_copy, result);
    1162         283 :         op1_lval = Z_LVAL_P(op1);
    1163         301 :         zendi_convert_to_long(op2, op2_copy, result);
    1164             : 
    1165         283 :         ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
    1166         283 :         return SUCCESS;
    1167             : }
    1168             : /* }}} */
    1169             : 
    1170        3418 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1171             : {
    1172             :         zval op1_copy, op2_copy;
    1173             :         long op1_lval;
    1174             : 
    1175        3436 :         zendi_convert_to_long(op1, op1_copy, result);
    1176        3418 :         op1_lval = Z_LVAL_P(op1);
    1177        3436 :         zendi_convert_to_long(op2, op2_copy, result);
    1178        3418 :         ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
    1179        3418 :         return SUCCESS;
    1180             : }
    1181             : /* }}} */
    1182             : 
    1183      350240 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1184             : {
    1185             :         zval op1_copy, op2_copy;
    1186             :         long op1_lval;
    1187             : 
    1188      350258 :         zendi_convert_to_long(op1, op1_copy, result);
    1189      350240 :         op1_lval = Z_LVAL_P(op1);
    1190      350258 :         zendi_convert_to_long(op2, op2_copy, result);
    1191      350240 :         ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
    1192      350240 :         return SUCCESS;
    1193             : }
    1194             : /* }}} */
    1195             : 
    1196             : /* must support result==op1 */
    1197     1017510 : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1198             : {
    1199     1017510 :         int length = Z_STRLEN_P(op1) + 1;
    1200             :         char *buf;
    1201             : 
    1202     1017510 :         if (IS_INTERNED(Z_STRVAL_P(op1))) {
    1203           0 :                 buf = (char *) emalloc(length + 1);
    1204           0 :                 memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1205             :         } else {
    1206     1017510 :                 buf = (char *) erealloc(Z_STRVAL_P(op1), length + 1);
    1207             :         }
    1208     1017510 :         buf[length - 1] = (char) Z_LVAL_P(op2);
    1209     1017510 :         buf[length] = 0;
    1210     1017510 :         ZVAL_STRINGL(result, buf, length, 0);
    1211     1017510 :         return SUCCESS;
    1212             : }
    1213             : /* }}} */
    1214             : 
    1215             : /* must support result==op1 */
    1216     2879539 : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1217             : {
    1218     2879539 :         int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1219             :         char *buf;
    1220             : 
    1221     2879539 :         if (IS_INTERNED(Z_STRVAL_P(op1))) {
    1222           0 :                 buf = (char *) emalloc(length+1);
    1223           0 :                 memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1224             :         } else {
    1225     2879539 :                 buf = (char *) erealloc(Z_STRVAL_P(op1), length+1);
    1226             :         }
    1227     2879539 :         memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1228     2879539 :         buf[length] = 0;
    1229     2879539 :         ZVAL_STRINGL(result, buf, length, 0);
    1230     2879539 :         return SUCCESS;
    1231             : }
    1232             : /* }}} */
    1233             : 
    1234     4738631 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1235             : {
    1236             :         zval op1_copy, op2_copy;
    1237     4738631 :         int use_copy1 = 0, use_copy2 = 0;
    1238             : 
    1239     4738631 :         if (Z_TYPE_P(op1) != IS_STRING) {
    1240       48428 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1241             :         }
    1242     4738631 :         if (Z_TYPE_P(op2) != IS_STRING) {
    1243       42297 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1244             :         }
    1245             : 
    1246     4738631 :         if (use_copy1) {
    1247             :                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1248             :                  * we have to free it.
    1249             :                  */
    1250       48428 :                 if (result == op1) {
    1251             :                         zval_dtor(op1);
    1252             :                 }
    1253       48428 :                 op1 = &op1_copy;
    1254             :         }
    1255     4738631 :         if (use_copy2) {
    1256       42297 :                 op2 = &op2_copy;
    1257             :         }
    1258     8026626 :         if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) {     /* special case, perform operations on result */
    1259     3287995 :                 uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1260             : 
    1261     3287995 :                 if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
    1262           0 :                         efree(Z_STRVAL_P(result));
    1263           0 :                         ZVAL_EMPTY_STRING(result);
    1264           0 :                         zend_error(E_ERROR, "String size overflow");
    1265             :                 }
    1266             : 
    1267     3287995 :                 Z_STRVAL_P(result) = safe_erealloc(Z_STRVAL_P(result), res_len, 1, 1);
    1268             : 
    1269     3287995 :                 memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1270     3287995 :                 Z_STRVAL_P(result)[res_len]=0;
    1271     3287995 :                 Z_STRLEN_P(result) = res_len;
    1272             :         } else {
    1273     1450636 :                 int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1274             :                 char *buf;
    1275             : 
    1276     1450636 :                 if (Z_STRLEN_P(op1) < 0 || Z_STRLEN_P(op2) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
    1277           0 :                         zend_error(E_ERROR, "String size overflow");
    1278             :                 }
    1279     1450636 :                 buf = (char *) safe_emalloc(length, 1, 1);
    1280             : 
    1281     1450636 :                 memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1282     1450636 :                 memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1283     1450636 :                 buf[length] = 0;
    1284     1450636 :                 ZVAL_STRINGL(result, buf, length, 0);
    1285             :         }
    1286     4738631 :         if (use_copy1) {
    1287             :                 zval_dtor(op1);
    1288             :         }
    1289     4738631 :         if (use_copy2) {
    1290             :                 zval_dtor(op2);
    1291             :         }
    1292     4738631 :         return SUCCESS;
    1293             : }
    1294             : /* }}} */
    1295             : 
    1296      288922 : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
    1297             : {
    1298             :         zval op1_copy, op2_copy;
    1299      288922 :         int use_copy1 = 0, use_copy2 = 0;
    1300             : 
    1301      288922 :         if (Z_TYPE_P(op1) != IS_STRING) {
    1302       71584 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1303             :         }
    1304      288922 :         if (Z_TYPE_P(op2) != IS_STRING) {
    1305       73726 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1306             :         }
    1307             : 
    1308      288922 :         if (use_copy1) {
    1309       71584 :                 op1 = &op1_copy;
    1310             :         }
    1311      288922 :         if (use_copy2) {
    1312       73726 :                 op2 = &op2_copy;
    1313             :         }
    1314             : 
    1315      288922 :         if (case_insensitive) {
    1316         109 :                 ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2));
    1317             :         } else {
    1318      288813 :                 ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
    1319             :         }
    1320             : 
    1321      288922 :         if (use_copy1) {
    1322             :                 zval_dtor(op1);
    1323             :         }
    1324      288922 :         if (use_copy2) {
    1325             :                 zval_dtor(op2);
    1326             :         }
    1327      288922 :         return SUCCESS;
    1328             : }
    1329             : /* }}} */
    1330             : 
    1331      288813 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1332             : {
    1333      288813 :         return string_compare_function_ex(result, op1, op2, 0 TSRMLS_CC);
    1334             : }
    1335             : /* }}} */
    1336             : 
    1337         109 : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1338             : {
    1339         109 :         return string_compare_function_ex(result, op1, op2, 1 TSRMLS_CC);
    1340             : }
    1341             : /* }}} */
    1342             : 
    1343             : #if HAVE_STRCOLL
    1344          33 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1345             : {
    1346             :         zval op1_copy, op2_copy;
    1347          33 :         int use_copy1 = 0, use_copy2 = 0;
    1348             : 
    1349          33 :         if (Z_TYPE_P(op1) != IS_STRING) {
    1350           0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1351             :         }
    1352          33 :         if (Z_TYPE_P(op2) != IS_STRING) {
    1353           0 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1354             :         }
    1355             : 
    1356          33 :         if (use_copy1) {
    1357           0 :                 op1 = &op1_copy;
    1358             :         }
    1359          33 :         if (use_copy2) {
    1360           0 :                 op2 = &op2_copy;
    1361             :         }
    1362             : 
    1363          33 :         ZVAL_LONG(result, strcoll(Z_STRVAL_P(op1), Z_STRVAL_P(op2)));
    1364             : 
    1365          33 :         if (use_copy1) {
    1366             :                 zval_dtor(op1);
    1367             :         }
    1368          33 :         if (use_copy2) {
    1369             :                 zval_dtor(op2);
    1370             :         }
    1371          33 :         return SUCCESS;
    1372             : }
    1373             : /* }}} */
    1374             : #endif
    1375             : 
    1376         844 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1377             : {
    1378             :         zval op1_copy, op2_copy;
    1379             : 
    1380         844 :         op1_copy = *op1;
    1381             :         zval_copy_ctor(&op1_copy);
    1382             : 
    1383         844 :         op2_copy = *op2;
    1384             :         zval_copy_ctor(&op2_copy);
    1385             : 
    1386         844 :         convert_to_double(&op1_copy);
    1387         844 :         convert_to_double(&op2_copy);
    1388             : 
    1389         844 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
    1390             : 
    1391         844 :         return SUCCESS;
    1392             : }
    1393             : /* }}} */
    1394             : 
    1395         413 : static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
    1396             : {
    1397         826 :         if (Z_REFCOUNT_P(op) == 0) {
    1398           1 :                 GC_REMOVE_ZVAL_FROM_BUFFER(op);
    1399           1 :                 zval_dtor(op);
    1400           1 :                 FREE_ZVAL(op);
    1401             :         } else {
    1402         412 :                 zval_ptr_dtor(&op);
    1403             :         }
    1404         413 : }
    1405             : /* }}} */
    1406             : 
    1407     2435524 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1408             : {
    1409             :         int ret;
    1410     2435524 :         int converted = 0;
    1411             :         zval op1_copy, op2_copy;
    1412             :         zval *op_free;
    1413             : 
    1414             :         while (1) {
    1415     2461739 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1416             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1417       45833 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1418       45833 :                                 return SUCCESS;
    1419             : 
    1420             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1421         640 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1422         640 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1423         640 :                                 return SUCCESS;
    1424             : 
    1425             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1426         295 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1427         295 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1428         295 :                                 return SUCCESS;
    1429             : 
    1430             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1431         388 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1432          99 :                                         ZVAL_LONG(result, 0);
    1433             :                                 } else {
    1434         289 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1435         289 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1436             :                                 }
    1437         388 :                                 return SUCCESS;
    1438             : 
    1439             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1440         783 :                                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1441         783 :                                 return SUCCESS;
    1442             : 
    1443             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1444         307 :                                 ZVAL_LONG(result, 0);
    1445         307 :                                 return SUCCESS;
    1446             : 
    1447             :                         case TYPE_PAIR(IS_NULL, IS_BOOL):
    1448          35 :                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1449          35 :                                 return SUCCESS;
    1450             : 
    1451             :                         case TYPE_PAIR(IS_BOOL, IS_NULL):
    1452          30 :                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1453          30 :                                 return SUCCESS;
    1454             : 
    1455             :                         case TYPE_PAIR(IS_BOOL, IS_BOOL):
    1456        4774 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1457        4774 :                                 return SUCCESS;
    1458             : 
    1459             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1460     1999493 :                                 zendi_smart_strcmp(result, op1, op2);
    1461     1999493 :                                 return SUCCESS;
    1462             : 
    1463             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1464       12502 :                                 ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1465       12502 :                                 return SUCCESS;
    1466             : 
    1467             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1468         138 :                                 ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
    1469         138 :                                 return SUCCESS;
    1470             : 
    1471             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1472          48 :                                 ZVAL_LONG(result, 1);
    1473          48 :                                 return SUCCESS;
    1474             : 
    1475             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1476          15 :                                 ZVAL_LONG(result, -1);
    1477          15 :                                 return SUCCESS;
    1478             : 
    1479             :                         case TYPE_PAIR(IS_OBJECT, IS_OBJECT):
    1480             :                                 /* If both are objects sharing the same comparision handler then use is */
    1481      346165 :                                 if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
    1482      346164 :                                         if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
    1483             :                                                 /* object handles are identical, apparently this is the same object */
    1484          23 :                                                 ZVAL_LONG(result, 0);
    1485          23 :                                                 return SUCCESS;
    1486             :                                         }
    1487      346141 :                                         ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
    1488      346137 :                                         return SUCCESS;
    1489             :                                 }
    1490             :                                 /* break missing intentionally */
    1491             : 
    1492             :                         default:
    1493       50294 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1494         217 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1495           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
    1496           1 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1497           1 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1498           1 :                                                 return ret;
    1499         216 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1500         215 :                                                 ALLOC_INIT_ZVAL(op_free);
    1501         215 :                                                 if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
    1502         112 :                                                         ZVAL_LONG(result, 1);
    1503         112 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1504         112 :                                                         return SUCCESS;
    1505             :                                                 }
    1506         103 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1507         103 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1508         103 :                                                 return ret;
    1509             :                                         }
    1510             :                                 }
    1511       50078 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1512         198 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1513           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
    1514           0 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1515           0 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1516           0 :                                                 return ret;
    1517         198 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1518         197 :                                                 ALLOC_INIT_ZVAL(op_free);
    1519         197 :                                                 if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
    1520         107 :                                                         ZVAL_LONG(result, -1);
    1521         107 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1522         107 :                                                         return SUCCESS;
    1523             :                                                 }
    1524          90 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1525          90 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1526          90 :                                                 return ret;
    1527           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1528           1 :                                                 ZVAL_LONG(result, 1);
    1529           1 :                                                 return SUCCESS;
    1530             :                                         }
    1531             :                                 }
    1532       49880 :                                 if (!converted) {
    1533       49320 :                                         if (Z_TYPE_P(op1) == IS_NULL) {
    1534         261 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1535         261 :                                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1536         261 :                                                 return SUCCESS;
    1537       49059 :                                         } else if (Z_TYPE_P(op2) == IS_NULL) {
    1538          89 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1539          89 :                                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1540          89 :                                                 return SUCCESS;
    1541       48970 :                                         } else if (Z_TYPE_P(op1) == IS_BOOL) {
    1542       19293 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1543       19293 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1544       19293 :                                                 return SUCCESS;
    1545       29677 :                                         } else if (Z_TYPE_P(op2) == IS_BOOL) {
    1546        3462 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1547        3462 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1548        3462 :                                                 return SUCCESS;
    1549             :                                         } else {
    1550       26215 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1551       26215 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1552       26215 :                                                 converted = 1;
    1553             :                                         }
    1554         560 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1555         276 :                                         ZVAL_LONG(result, 1);
    1556         276 :                                         return SUCCESS;
    1557         284 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1558         284 :                                         ZVAL_LONG(result, -1);
    1559         284 :                                         return SUCCESS;
    1560           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1561           0 :                                         ZVAL_LONG(result, 1);
    1562           0 :                                         return SUCCESS;
    1563           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1564           0 :                                         ZVAL_LONG(result, -1);
    1565           0 :                                         return SUCCESS;
    1566             :                                 } else {
    1567           0 :                                         ZVAL_LONG(result, 0);
    1568           0 :                                         return FAILURE;
    1569             :                                 }
    1570             :                 }
    1571       26215 :         }
    1572             : }
    1573             : /* }}} */
    1574             : 
    1575        1131 : static int hash_zval_identical_function(const zval **z1, const zval **z2) /* {{{ */
    1576             : {
    1577             :         zval result;
    1578             :         TSRMLS_FETCH();
    1579             : 
    1580             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1581             :          * of a difference;
    1582             :          * whereas this comparison function is expected to return 0 on identity,
    1583             :          * and non zero otherwise.
    1584             :          */
    1585        1131 :         if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    1586           0 :                 return 1;
    1587             :         }
    1588        1131 :         return !Z_LVAL(result);
    1589             : }
    1590             : /* }}} */
    1591             : 
    1592     4120091 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1593             : {
    1594     4120091 :         Z_TYPE_P(result) = IS_BOOL;
    1595     4120091 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1596     2945292 :                 Z_LVAL_P(result) = 0;
    1597     2945292 :                 return SUCCESS;
    1598             :         }
    1599     1174799 :         switch (Z_TYPE_P(op1)) {
    1600             :                 case IS_NULL:
    1601        2572 :                         Z_LVAL_P(result) = 1;
    1602        2572 :                         break;
    1603             :                 case IS_BOOL:
    1604             :                 case IS_LONG:
    1605             :                 case IS_RESOURCE:
    1606     1070968 :                         Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
    1607     1070968 :                         break;
    1608             :                 case IS_DOUBLE:
    1609         179 :                         Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
    1610         179 :                         break;
    1611             :                 case IS_STRING:
    1612       67880 :                         Z_LVAL_P(result) = ((Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
    1613       32955 :                                 && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1))));
    1614       34925 :                         break;
    1615             :                 case IS_ARRAY:
    1616         136 :                         Z_LVAL_P(result) = (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    1617          67 :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0);
    1618          69 :                         break;
    1619             :                 case IS_OBJECT:
    1620       66086 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    1621       66086 :                                 Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
    1622             :                         } else {
    1623           0 :                                 Z_LVAL_P(result) = 0;
    1624             :                         }
    1625       66086 :                         break;
    1626             :                 default:
    1627           0 :                         Z_LVAL_P(result) = 0;
    1628           0 :                         return FAILURE;
    1629             :         }
    1630     1174799 :         return SUCCESS;
    1631             : }
    1632             : /* }}} */
    1633             : 
    1634           0 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1635             : {
    1636           0 :         if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1637           0 :                 return FAILURE;
    1638             :         }
    1639           0 :         Z_LVAL_P(result) = !Z_LVAL_P(result);
    1640           0 :         return SUCCESS;
    1641             : }
    1642             : /* }}} */
    1643             : 
    1644      509015 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1645             : {
    1646      509015 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1647           0 :                 return FAILURE;
    1648             :         }
    1649      509015 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    1650      509015 :         return SUCCESS;
    1651             : }
    1652             : /* }}} */
    1653             : 
    1654           0 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1655             : {
    1656           0 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1657           0 :                 return FAILURE;
    1658             :         }
    1659           0 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    1660           0 :         return SUCCESS;
    1661             : }
    1662             : /* }}} */
    1663             : 
    1664        1892 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1665             : {
    1666        1892 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1667           0 :                 return FAILURE;
    1668             :         }
    1669        1892 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    1670        1892 :         return SUCCESS;
    1671             : }
    1672             : /* }}} */
    1673             : 
    1674        1277 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1675             : {
    1676        1277 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1677           0 :                 return FAILURE;
    1678             :         }
    1679        1277 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    1680        1277 :         return SUCCESS;
    1681             : }
    1682             : /* }}} */
    1683             : 
    1684     2452290 : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC) /* {{{ */
    1685             : {
    1686             :         zend_uint i;
    1687             : 
    1688     2940908 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    1689      554799 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    1690       66181 :                         return 1;
    1691             :                 }
    1692             :         }
    1693     2386109 :         if (!interfaces_only) {
    1694     5284495 :                 while (instance_ce) {
    1695     2396222 :                         if (instance_ce == ce) {
    1696     1883935 :                                 return 1;
    1697             :                         }
    1698      512287 :                         instance_ce = instance_ce->parent;
    1699             :                 }
    1700             :         }
    1701             : 
    1702      502174 :         return 0;
    1703             : }
    1704             : /* }}} */
    1705             : 
    1706     2388460 : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC) /* {{{ */
    1707             : {
    1708     2388460 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    1709             : }
    1710             : /* }}} */
    1711             : 
    1712             : #define LOWER_CASE 1
    1713             : #define UPPER_CASE 2
    1714             : #define NUMERIC 3
    1715             : 
    1716          46 : static void increment_string(zval *str) /* {{{ */
    1717             : {
    1718          46 :         int carry=0;
    1719          46 :         int pos=Z_STRLEN_P(str)-1;
    1720          46 :         char *s=Z_STRVAL_P(str);
    1721             :         char *t;
    1722          46 :         int last=0; /* Shut up the compiler warning */
    1723             :         int ch;
    1724             : 
    1725          46 :         if (Z_STRLEN_P(str) == 0) {
    1726           0 :                 STR_FREE(Z_STRVAL_P(str));
    1727           0 :                 Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
    1728           0 :                 Z_STRLEN_P(str) = 1;
    1729           0 :                 return;
    1730             :         }
    1731             : 
    1732          46 :         if (IS_INTERNED(s)) {
    1733          21 :                 s = (char*) emalloc(Z_STRLEN_P(str) + 1);
    1734          21 :                 memcpy(s, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1);
    1735          21 :                 Z_STRVAL_P(str) = s;
    1736             :         }
    1737             : 
    1738          96 :         while (pos >= 0) {
    1739          50 :                 ch = s[pos];
    1740          81 :                 if (ch >= 'a' && ch <= 'z') {
    1741          31 :                         if (ch == 'z') {
    1742           2 :                                 s[pos] = 'a';
    1743           2 :                                 carry=1;
    1744             :                         } else {
    1745          29 :                                 s[pos]++;
    1746          29 :                                 carry=0;
    1747             :                         }
    1748          31 :                         last=LOWER_CASE;
    1749          25 :                 } else if (ch >= 'A' && ch <= 'Z') {
    1750           6 :                         if (ch == 'Z') {
    1751           0 :                                 s[pos] = 'A';
    1752           0 :                                 carry=1;
    1753             :                         } else {
    1754           6 :                                 s[pos]++;
    1755           6 :                                 carry=0;
    1756             :                         }
    1757           6 :                         last=UPPER_CASE;
    1758          22 :                 } else if (ch >= '0' && ch <= '9') {
    1759           9 :                         if (ch == '9') {
    1760           2 :                                 s[pos] = '0';
    1761           2 :                                 carry=1;
    1762             :                         } else {
    1763           7 :                                 s[pos]++;
    1764           7 :                                 carry=0;
    1765             :                         }
    1766           9 :                         last = NUMERIC;
    1767             :                 } else {
    1768           4 :                         carry=0;
    1769           4 :                         break;
    1770             :                 }
    1771          46 :                 if (carry == 0) {
    1772          42 :                         break;
    1773             :                 }
    1774           4 :                 pos--;
    1775             :         }
    1776             : 
    1777          46 :         if (carry) {
    1778           0 :                 t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
    1779           0 :                 memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    1780           0 :                 Z_STRLEN_P(str)++;
    1781           0 :                 t[Z_STRLEN_P(str)] = '\0';
    1782           0 :                 switch (last) {
    1783             :                         case NUMERIC:
    1784           0 :                                 t[0] = '1';
    1785           0 :                                 break;
    1786             :                         case UPPER_CASE:
    1787           0 :                                 t[0] = 'A';
    1788           0 :                                 break;
    1789             :                         case LOWER_CASE:
    1790           0 :                                 t[0] = 'a';
    1791             :                                 break;
    1792             :                 }
    1793           0 :                 STR_FREE(Z_STRVAL_P(str));
    1794           0 :                 Z_STRVAL_P(str) = t;
    1795             :         }
    1796             : }
    1797             : /* }}} */
    1798             : 
    1799        4895 : ZEND_API int increment_function(zval *op1) /* {{{ */
    1800             : {
    1801        4895 :         switch (Z_TYPE_P(op1)) {
    1802             :                 case IS_LONG:
    1803        3200 :                         if (Z_LVAL_P(op1) == LONG_MAX) {
    1804             :                                 /* switch to double */
    1805           0 :                                 double d = (double)Z_LVAL_P(op1);
    1806           0 :                                 ZVAL_DOUBLE(op1, d+1);
    1807             :                         } else {
    1808        3200 :                         Z_LVAL_P(op1)++;
    1809             :                         }
    1810        3200 :                         break;
    1811             :                 case IS_DOUBLE:
    1812           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    1813           4 :                         break;
    1814             :                 case IS_NULL:
    1815          27 :                         ZVAL_LONG(op1, 1);
    1816          27 :                         break;
    1817             :                 case IS_STRING: {
    1818             :                                 long lval;
    1819             :                                 double dval;
    1820             : 
    1821        1663 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    1822             :                                         case IS_LONG:
    1823        1611 :                                                 str_efree(Z_STRVAL_P(op1));
    1824        1611 :                                                 if (lval == LONG_MAX) {
    1825             :                                                         /* switch to double */
    1826           0 :                                                         double d = (double)lval;
    1827           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    1828             :                                                 } else {
    1829        1611 :                                                         ZVAL_LONG(op1, lval+1);
    1830             :                                                 }
    1831        1611 :                                                 break;
    1832             :                                         case IS_DOUBLE:
    1833           6 :                                                 str_efree(Z_STRVAL_P(op1));
    1834           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    1835           6 :                                                 break;
    1836             :                                         default:
    1837             :                                                 /* Perl style string increment */
    1838          46 :                                                 increment_string(op1);
    1839             :                                                 break;
    1840             :                                 }
    1841             :                         }
    1842        1663 :                         break;
    1843             :                 default:
    1844           1 :                         return FAILURE;
    1845             :         }
    1846        4894 :         return SUCCESS;
    1847             : }
    1848             : /* }}} */
    1849             : 
    1850      251744 : ZEND_API int decrement_function(zval *op1) /* {{{ */
    1851             : {
    1852             :         long lval;
    1853             :         double dval;
    1854             : 
    1855      251744 :         switch (Z_TYPE_P(op1)) {
    1856             :                 case IS_LONG:
    1857           2 :                         if (Z_LVAL_P(op1) == LONG_MIN) {
    1858           0 :                                 double d = (double)Z_LVAL_P(op1);
    1859           0 :                                 ZVAL_DOUBLE(op1, d-1);
    1860             :                         } else {
    1861           2 :                         Z_LVAL_P(op1)--;
    1862             :                         }
    1863           2 :                         break;
    1864             :                 case IS_DOUBLE:
    1865      251703 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    1866      251703 :                         break;
    1867             :                 case IS_STRING:         /* Like perl we only support string increment */
    1868          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    1869           1 :                                 STR_FREE(Z_STRVAL_P(op1));
    1870           1 :                                 ZVAL_LONG(op1, -1);
    1871           1 :                                 break;
    1872             :                         }
    1873          32 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    1874             :                                 case IS_LONG:
    1875           8 :                                         STR_FREE(Z_STRVAL_P(op1));
    1876           8 :                                         if (lval == LONG_MIN) {
    1877           1 :                                                 double d = (double)lval;
    1878           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    1879             :                                         } else {
    1880           7 :                                                 ZVAL_LONG(op1, lval-1);
    1881             :                                         }
    1882           8 :                                         break;
    1883             :                                 case IS_DOUBLE:
    1884           7 :                                         STR_FREE(Z_STRVAL_P(op1));
    1885           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    1886             :                                         break;
    1887             :                         }
    1888          32 :                         break;
    1889             :                 default:
    1890           6 :                         return FAILURE;
    1891             :         }
    1892             : 
    1893      251738 :         return SUCCESS;
    1894             : }
    1895             : /* }}} */
    1896             : 
    1897        3492 : ZEND_API int zval_is_true(zval *op) /* {{{ */
    1898             : {
    1899        3492 :         convert_to_boolean(op);
    1900        3492 :         return (Z_LVAL_P(op) ? 1 : 0);
    1901             : }
    1902             : /* }}} */
    1903             : 
    1904             : #ifdef ZEND_USE_TOLOWER_L
    1905             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    1906             : {
    1907             :         current_locale = _get_current_locale();
    1908             : }
    1909             : /* }}} */
    1910             : #endif
    1911             : 
    1912    85116425 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) /* {{{ */
    1913             : {
    1914    85116425 :         register unsigned char *str = (unsigned char*)source;
    1915    85116425 :         register unsigned char *result = (unsigned char*)dest;
    1916    85116425 :         register unsigned char *end = str + length;
    1917             : 
    1918  1270599893 :         while (str < end) {
    1919  1100367043 :                 *result++ = zend_tolower((int)*str++);
    1920             :         }
    1921    85116425 :         *result = '\0';
    1922             : 
    1923    85116425 :         return dest;
    1924             : }
    1925             : /* }}} */
    1926             : 
    1927    79310231 : ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length) /* {{{ */
    1928             : {
    1929    79310231 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    1930             : }
    1931             : /* }}} */
    1932             : 
    1933     3164117 : ZEND_API void zend_str_tolower(char *str, unsigned int length) /* {{{ */
    1934             : {
    1935     3164117 :         register unsigned char *p = (unsigned char*)str;
    1936     3164117 :         register unsigned char *end = p + length;
    1937             : 
    1938    52195648 :         while (p < end) {
    1939    45867414 :                 *p = zend_tolower((int)*p);
    1940    45867414 :                 p++;
    1941             :         }
    1942     3164117 : }
    1943             : /* }}} */
    1944             : 
    1945     2334512 : ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    1946             : {
    1947             :         int retval;
    1948             : 
    1949     2334512 :         if (s1 == s2) {
    1950        3748 :                 return 0;
    1951             :         }
    1952     2330764 :         retval = memcmp(s1, s2, MIN(len1, len2));
    1953     2330764 :         if (!retval) {
    1954      306020 :                 return (len1 - len2);
    1955             :         } else {
    1956     2024744 :                 return retval;
    1957             :         }
    1958             : }
    1959             : /* }}} */
    1960             : 
    1961       13869 : ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    1962             : {
    1963             :         int retval;
    1964             : 
    1965       13869 :         if (s1 == s2) {
    1966          39 :                 return 0;
    1967             :         }
    1968       13830 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    1969       13830 :         if (!retval) {
    1970       13597 :                 return (MIN(length, len1) - MIN(length, len2));
    1971             :         } else {
    1972         233 :                 return retval;
    1973             :         }
    1974             : }
    1975             : /* }}} */
    1976             : 
    1977      303544 : ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    1978             : {
    1979             :         int len;
    1980             :         int c1, c2;
    1981             : 
    1982      303544 :         if (s1 == s2) {
    1983          35 :                 return 0;
    1984             :         }
    1985             : 
    1986      303509 :         len = MIN(len1, len2);
    1987     1323259 :         while (len--) {
    1988     1019406 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    1989     1019406 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    1990     1019406 :                 if (c1 != c2) {
    1991      303165 :                         return c1 - c2;
    1992             :                 }
    1993             :         }
    1994             : 
    1995         344 :         return len1 - len2;
    1996             : }
    1997             : /* }}} */
    1998             : 
    1999       20178 : ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2000             : {
    2001             :         int len;
    2002             :         int c1, c2;
    2003             : 
    2004       20178 :         if (s1 == s2) {
    2005          62 :                 return 0;
    2006             :         }
    2007       20116 :         len = MIN(length, MIN(len1, len2));
    2008       46843 :         while (len--) {
    2009        7077 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2010        7077 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2011        7077 :                 if (c1 != c2) {
    2012         466 :                         return c1 - c2;
    2013             :                 }
    2014             :         }
    2015             : 
    2016       19650 :         return MIN(length, len1) - MIN(length, len2);
    2017             : }
    2018             : /* }}} */
    2019             : 
    2020     1982552 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2021             : {
    2022     1982552 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2023             : }
    2024             : /* }}} */
    2025             : 
    2026           0 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2027             : {
    2028           0 :         return zend_binary_strncmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
    2029             : }
    2030             : /* }}} */
    2031             : 
    2032         109 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2033             : {
    2034         109 :         return zend_binary_strcasecmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2035             : }
    2036             : /* }}} */
    2037             : 
    2038           0 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2039             : {
    2040           0 :         return zend_binary_strncasecmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
    2041             : }
    2042             : /* }}} */
    2043             : 
    2044     1999493 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
    2045             : {
    2046             :         int ret1, ret2;
    2047             :         int oflow1, oflow2;
    2048             :         long lval1, lval2;
    2049             :         double dval1, dval2;
    2050             : 
    2051     2612411 :         if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
    2052      307164 :                 (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
    2053             : #if ULONG_MAX == 0xFFFFFFFF
    2054             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2055             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2056             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2057             : #else
    2058      306871 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2059             : #endif
    2060             :                         /* both values are integers overflown to the same side, and the
    2061             :                          * double comparison may have resulted in crucial accuracy lost */
    2062        1114 :                         goto string_cmp;
    2063             :                 }
    2064      405929 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    2065      100175 :                         if (ret1!=IS_DOUBLE) {
    2066          27 :                                 if (oflow2) {
    2067             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2068           3 :                                         ZVAL_LONG(result, -1 * oflow2);
    2069           3 :                                         return;
    2070             :                                 }
    2071          24 :                                 dval1 = (double) lval1;
    2072      100148 :                         } else if (ret2!=IS_DOUBLE) {
    2073          23 :                                 if (oflow1) {
    2074           0 :                                         ZVAL_LONG(result, oflow1);
    2075           0 :                                         return;
    2076             :                                 }
    2077          23 :                                 dval2 = (double) lval2;
    2078      100125 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2079             :                                 /* Both values overflowed and have the same sign,
    2080             :                                  * so a numeric comparison would be inaccurate */
    2081           0 :                                 goto string_cmp;
    2082             :                         }
    2083      100172 :                         Z_DVAL_P(result) = dval1 - dval2;
    2084      100172 :                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    2085             :                 } else { /* they both have to be long's */
    2086      205582 :                         ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
    2087             :                 }
    2088             :         } else {
    2089             : string_cmp:
    2090     1693736 :                 Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
    2091     1693736 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
    2092             :         }
    2093             : }
    2094             : /* }}} */
    2095             : 
    2096        2500 : static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC) /* {{{ */
    2097             : {
    2098             :         zval result;
    2099             : 
    2100        2500 :         if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    2101           0 :                 return 1;
    2102             :         }
    2103        2500 :         return Z_LVAL(result);
    2104             : }
    2105             : /* }}} */
    2106             : 
    2107         293 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2108             : {
    2109         293 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2110             : }
    2111             : /* }}} */
    2112             : 
    2113         788 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2114             : {
    2115         788 :         ZVAL_LONG(result, ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC));
    2116         788 : }
    2117             : /* }}} */
    2118             : 
    2119         783 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC) /* {{{ */
    2120             : {
    2121         783 :         zend_compare_symbol_tables(result, Z_ARRVAL_P(a1), Z_ARRVAL_P(a2) TSRMLS_CC);
    2122         783 : }
    2123             : /* }}} */
    2124             : 
    2125           1 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
    2126             : {
    2127           1 :         Z_TYPE_P(result) = IS_LONG;
    2128             : 
    2129           1 :         if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
    2130           1 :                 Z_LVAL_P(result) = 0;
    2131           1 :                 return;
    2132             :         }
    2133             : 
    2134           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2135           0 :                 Z_LVAL_P(result) = 1;
    2136             :         } else {
    2137           0 :                 Z_LVAL_P(result) = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
    2138             :         }
    2139             : }
    2140             : /* }}} */
    2141             : 
    2142        7225 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2143             : {
    2144             :         TSRMLS_FETCH();
    2145             : 
    2146        7225 :         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2147        7225 : }
    2148             : /* }}} */
    2149             : 
    2150             : /*
    2151             :  * Local variables:
    2152             :  * tab-width: 4
    2153             :  * c-basic-offset: 4
    2154             :  * indent-tabs-mode: t
    2155             :  * End:
    2156             :  */

Generated by: LCOV version 1.10

Generated at Mon, 20 Jul 2015 21:09:24 +0000 (10 days ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.