@@ -55,7 +55,7 @@ static _locale_t current_locale = NULL;
5555#define  zend_tolower (c ) tolower(c)
5656#endif 
5757
58- #define  TYPE_PAIR (t1 ,t2 ) ((( t1) << 4) | (t2))
58+ #define  TYPE_PAIR (t1 ,t2 ) ((unsigned char) ((( t1) << 4) | (t2) ))
5959
6060#ifdef  ZEND_INTRIN_AVX2_NATIVE 
6161#define  HAVE_BLOCKCONV 
@@ -2164,127 +2164,133 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */
21642164}
21652165/* }}} */ 
21662166
2167- ZEND_API  int  ZEND_FASTCALL  zend_compare (zval  * op1 , zval  * op2 ) /* {{{ */ 
2167+ static  int  ZEND_FASTCALL  zend_compare_fast (zval  * op1 , zval  * op2 , bool  converted );
2168+ 
2169+ static  int  ZEND_FASTCALL  zend_compare_slow (zval  * op1 , zval  * op2 , bool  converted )
21682170{
2169- 	int  converted  =  0 ;
2170- 	zval  op1_copy , op2_copy ;
2171+ 	if  (Z_ISREF_P (op1 ) ||  Z_ISREF_P (op2 )) {
2172+ 		ZVAL_DEREF (op1 );
2173+ 		ZVAL_DEREF (op2 );
2174+ 		return  zend_compare_fast (op1 , op2 , converted );
2175+ 	}
21712176
2172- 	while  (1 ) {
2173- 		switch  (TYPE_PAIR (Z_TYPE_P (op1 ), Z_TYPE_P (op2 ))) {
2174- 			case  TYPE_PAIR (IS_LONG , IS_LONG ):
2175- 				return  Z_LVAL_P (op1 )> Z_LVAL_P (op2 )?1 :(Z_LVAL_P (op1 )< Z_LVAL_P (op2 )?-1 :0 );
2177+ 	if  (Z_TYPE_P (op1 ) ==  IS_OBJECT 
2178+ 		&&  Z_TYPE_P (op2 ) ==  IS_OBJECT 
2179+ 		&&  Z_OBJ_P (op1 ) ==  Z_OBJ_P (op2 )) {
2180+ 		return  0 ;
2181+ 	} else  if  (Z_TYPE_P (op1 ) ==  IS_OBJECT ) {
2182+ 		return  Z_OBJ_HANDLER_P (op1 , compare )(op1 , op2 );
2183+ 	} else  if  (Z_TYPE_P (op2 ) ==  IS_OBJECT ) {
2184+ 		return  Z_OBJ_HANDLER_P (op2 , compare )(op1 , op2 );
2185+ 	}
2186+ 
2187+ 	if  (!converted ) {
2188+ 		if  (Z_TYPE_P (op1 ) <  IS_TRUE ) {
2189+ 			return  zval_is_true (op2 ) ? -1  : 0 ;
2190+ 		} else  if  (Z_TYPE_P (op1 ) ==  IS_TRUE ) {
2191+ 			return  zval_is_true (op2 ) ? 0  : 1 ;
2192+ 		} else  if  (Z_TYPE_P (op2 ) <  IS_TRUE ) {
2193+ 			return  zval_is_true (op1 ) ? 1  : 0 ;
2194+ 		} else  if  (Z_TYPE_P (op2 ) ==  IS_TRUE ) {
2195+ 			return  zval_is_true (op1 ) ? 0  : -1 ;
2196+ 		} else  {
2197+ 			zval  op1_copy , op2_copy ;
2198+ 			op1  =  _zendi_convert_scalar_to_number_silent (op1 , & op1_copy );
2199+ 			op2  =  _zendi_convert_scalar_to_number_silent (op2 , & op2_copy );
2200+ 			if  (EG (exception )) {
2201+ 				return  1 ; /* to stop comparison of arrays */ 
2202+ 			}
2203+ 			return  zend_compare_fast (op1 , op2 , true);
2204+ 		}
2205+ 	} else  if  (Z_TYPE_P (op1 )== IS_ARRAY ) {
2206+ 		return  1 ;
2207+ 	} else  if  (Z_TYPE_P (op2 )== IS_ARRAY ) {
2208+ 		return  -1 ;
2209+ 	} else  {
2210+ 		ZEND_UNREACHABLE ();
2211+ 		zend_throw_error (NULL , "Unsupported operand types" );
2212+ 		return  1 ;
2213+ 	}
2214+ }
21762215
2177- 			case  TYPE_PAIR (IS_DOUBLE , IS_LONG ):
2178- 				return  ZEND_THREEWAY_COMPARE (Z_DVAL_P (op1 ), (double )Z_LVAL_P (op2 ));
2216+ static  inline  int  ZEND_FASTCALL  zend_compare_fast (zval  * op1 , zval  * op2 , bool  converted )
2217+ {
2218+ 	switch  (TYPE_PAIR (Z_TYPE_P (op1 ), Z_TYPE_P (op2 ))) {
2219+ 		case  TYPE_PAIR (IS_LONG , IS_LONG ):
2220+ 			return  Z_LVAL_P (op1 )> Z_LVAL_P (op2 )?1 :(Z_LVAL_P (op1 )< Z_LVAL_P (op2 )?-1 :0 );
21792221
2180- 			 case  TYPE_PAIR (IS_LONG ,  IS_DOUBLE ):
2181- 				 return  ZEND_THREEWAY_COMPARE (( double ) Z_LVAL_P ( op1 ), Z_DVAL_P (op2 ));
2222+ 		case  TYPE_PAIR (IS_DOUBLE ,  IS_LONG ):
2223+ 			return  ZEND_THREEWAY_COMPARE (Z_DVAL_P ( op1 ), ( double ) Z_LVAL_P (op2 ));
21822224
2183- 			 case  TYPE_PAIR (IS_DOUBLE , IS_DOUBLE ):
2184- 				 return  ZEND_THREEWAY_COMPARE (Z_DVAL_P (op1 ), Z_DVAL_P (op2 ));
2225+ 		case  TYPE_PAIR (IS_LONG , IS_DOUBLE ):
2226+ 			return  ZEND_THREEWAY_COMPARE (( double ) Z_LVAL_P (op1 ), Z_DVAL_P (op2 ));
21852227
2186- 			 case  TYPE_PAIR (IS_ARRAY ,  IS_ARRAY ):
2187- 				 return  zend_compare_arrays ( op1 ,  op2 );
2228+ 		case  TYPE_PAIR (IS_DOUBLE ,  IS_DOUBLE ):
2229+ 			return  ZEND_THREEWAY_COMPARE ( Z_DVAL_P ( op1 ),  Z_DVAL_P ( op2 ) );
21882230
2189- 			case  TYPE_PAIR (IS_NULL , IS_NULL ):
2190- 			case  TYPE_PAIR (IS_NULL , IS_FALSE ):
2191- 			case  TYPE_PAIR (IS_FALSE , IS_NULL ):
2192- 			case  TYPE_PAIR (IS_FALSE , IS_FALSE ):
2193- 			case  TYPE_PAIR (IS_TRUE , IS_TRUE ):
2194- 				return  0 ;
2231+ 		case  TYPE_PAIR (IS_ARRAY , IS_ARRAY ):
2232+ 			return  zend_compare_arrays (op1 , op2 );
21952233
2196- 			case  TYPE_PAIR (IS_NULL , IS_TRUE ):
2197- 				return  -1 ;
2234+ 		case  TYPE_PAIR (IS_NULL , IS_NULL ):
2235+ 		case  TYPE_PAIR (IS_NULL , IS_FALSE ):
2236+ 		case  TYPE_PAIR (IS_FALSE , IS_NULL ):
2237+ 		case  TYPE_PAIR (IS_FALSE , IS_FALSE ):
2238+ 		case  TYPE_PAIR (IS_TRUE , IS_TRUE ):
2239+ 			return  0 ;
21982240
2199- 			 case  TYPE_PAIR (IS_TRUE ,  IS_NULL ):
2200- 				 return  1 ;
2241+ 		case  TYPE_PAIR (IS_NULL ,  IS_TRUE ):
2242+ 			return  - 1
22012243
2202- 			case  TYPE_PAIR (IS_STRING , IS_STRING ):
2203- 				if  (Z_STR_P (op1 ) ==  Z_STR_P (op2 )) {
2204- 					return  0 ;
2205- 				}
2206- 				return  zendi_smart_strcmp (Z_STR_P (op1 ), Z_STR_P (op2 ));
2244+ 		case  TYPE_PAIR (IS_TRUE , IS_NULL ):
2245+ 			return  1 ;
22072246
2208- 			case  TYPE_PAIR (IS_NULL , IS_STRING ):
2209- 				return  Z_STRLEN_P (op2 ) ==  0  ? 0  : -1 ;
2247+ 		case  TYPE_PAIR (IS_STRING , IS_STRING ):
2248+ 			if  (Z_STR_P (op1 ) ==  Z_STR_P (op2 )) {
2249+ 				return  0 ;
2250+ 			}
2251+ 			return  zendi_smart_strcmp (Z_STR_P (op1 ), Z_STR_P (op2 ));
22102252
2211- 			 case  TYPE_PAIR (IS_STRING ,  IS_NULL ):
2212- 				 return  Z_STRLEN_P (op1 ) ==  0  ? 0  : 1 ;
2253+ 		case  TYPE_PAIR (IS_NULL ,  IS_STRING ):
2254+ 			return  Z_STRLEN_P (op2 ) ==  0  ? 0  : - 1
22132255
2214- 			 case  TYPE_PAIR (IS_LONG ,  IS_STRING ):
2215- 				 return  compare_long_to_string ( Z_LVAL_P ( op1 ),  Z_STR_P ( op2 )) ;
2256+ 		case  TYPE_PAIR (IS_STRING ,  IS_NULL ):
2257+ 			return  Z_STRLEN_P ( op1 )  ==   0  ?  0  :  1 ;
22162258
2217- 			 case  TYPE_PAIR (IS_STRING ,  IS_LONG ):
2218- 				 return  - compare_long_to_string (Z_LVAL_P (op2 ), Z_STR_P (op1 ));
2259+ 		case  TYPE_PAIR (IS_LONG ,  IS_STRING ):
2260+ 			return  compare_long_to_string (Z_LVAL_P (op1 ), Z_STR_P (op2 ));
22192261
2220- 			case  TYPE_PAIR (IS_DOUBLE , IS_STRING ):
2221- 				if  (zend_isnan (Z_DVAL_P (op1 ))) {
2222- 					return  1 ;
2223- 				}
2262+ 		case  TYPE_PAIR (IS_STRING , IS_LONG ):
2263+ 			return  - compare_long_to_string (Z_LVAL_P (op2 ), Z_STR_P (op1 ));
22242264
2225- 				return  compare_double_to_string (Z_DVAL_P (op1 ), Z_STR_P (op2 ));
2226- 
2227- 			case  TYPE_PAIR (IS_STRING , IS_DOUBLE ):
2228- 				if  (zend_isnan (Z_DVAL_P (op2 ))) {
2229- 					return  1 ;
2230- 				}
2265+ 		case  TYPE_PAIR (IS_DOUBLE , IS_STRING ):
2266+ 			if  (zend_isnan (Z_DVAL_P (op1 ))) {
2267+ 				return  1 ;
2268+ 			}
22312269
2232- 				 return  - compare_double_to_string (Z_DVAL_P (op2 ), Z_STR_P (op1 ));
2270+ 			return  compare_double_to_string (Z_DVAL_P (op1 ), Z_STR_P (op2 ));
22332271
2234- 			case  TYPE_PAIR (IS_OBJECT , IS_NULL ):
2272+ 		case  TYPE_PAIR (IS_STRING , IS_DOUBLE ):
2273+ 			if  (zend_isnan (Z_DVAL_P (op2 ))) {
22352274				return  1 ;
2275+ 			}
22362276
2237- 			case  TYPE_PAIR (IS_NULL , IS_OBJECT ):
2238- 				return  -1 ;
2277+ 			return  - compare_double_to_string (Z_DVAL_P (op2 ), Z_STR_P (op1 ));
22392278
2240- 			default :
2241- 				if  (Z_ISREF_P (op1 )) {
2242- 					op1  =  Z_REFVAL_P (op1 );
2243- 					continue ;
2244- 				} else  if  (Z_ISREF_P (op2 )) {
2245- 					op2  =  Z_REFVAL_P (op2 );
2246- 					continue ;
2247- 				}
2279+ 		case  TYPE_PAIR (IS_OBJECT , IS_NULL ):
2280+ 			return  1 ;
22482281
2249- 				if  (Z_TYPE_P (op1 ) ==  IS_OBJECT 
2250- 				 &&  Z_TYPE_P (op2 ) ==  IS_OBJECT 
2251- 				 &&  Z_OBJ_P (op1 ) ==  Z_OBJ_P (op2 )) {
2252- 					return  0 ;
2253- 				} else  if  (Z_TYPE_P (op1 ) ==  IS_OBJECT ) {
2254- 					return  Z_OBJ_HANDLER_P (op1 , compare )(op1 , op2 );
2255- 				} else  if  (Z_TYPE_P (op2 ) ==  IS_OBJECT ) {
2256- 					return  Z_OBJ_HANDLER_P (op2 , compare )(op1 , op2 );
2257- 				}
2282+ 		case  TYPE_PAIR (IS_NULL , IS_OBJECT ):
2283+ 			return  -1 ;
22582284
2259- 				if  (!converted ) {
2260- 					if  (Z_TYPE_P (op1 ) <  IS_TRUE ) {
2261- 						return  zval_is_true (op2 ) ? -1  : 0 ;
2262- 					} else  if  (Z_TYPE_P (op1 ) ==  IS_TRUE ) {
2263- 						return  zval_is_true (op2 ) ? 0  : 1 ;
2264- 					} else  if  (Z_TYPE_P (op2 ) <  IS_TRUE ) {
2265- 						return  zval_is_true (op1 ) ? 1  : 0 ;
2266- 					} else  if  (Z_TYPE_P (op2 ) ==  IS_TRUE ) {
2267- 						return  zval_is_true (op1 ) ? 0  : -1 ;
2268- 					} else  {
2269- 						op1  =  _zendi_convert_scalar_to_number_silent (op1 , & op1_copy );
2270- 						op2  =  _zendi_convert_scalar_to_number_silent (op2 , & op2_copy );
2271- 						if  (EG (exception )) {
2272- 							return  1 ; /* to stop comparison of arrays */ 
2273- 						}
2274- 						converted  =  1 ;
2275- 					}
2276- 				} else  if  (Z_TYPE_P (op1 )== IS_ARRAY ) {
2277- 					return  1 ;
2278- 				} else  if  (Z_TYPE_P (op2 )== IS_ARRAY ) {
2279- 					return  -1 ;
2280- 				} else  {
2281- 					ZEND_UNREACHABLE ();
2282- 					zend_throw_error (NULL , "Unsupported operand types" );
2283- 					return  1 ;
2284- 				}
2285- 		}
2285+ 		default :
2286+ 			return  zend_compare_slow (op1 , op2 , converted );
22862287	}
22872288}
2289+ 
2290+ ZEND_API  int  ZEND_FASTCALL  zend_compare (zval  * op1 , zval  * op2 ) /* {{{ */ 
2291+ {
2292+ 	return  zend_compare_fast (op1 , op2 , false);
2293+ }
22882294/* }}} */ 
22892295
22902296/* return int to be compatible with compare_func_t */ 
@@ -3190,8 +3196,7 @@ ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2)
31903196				 * so a numeric comparison would be inaccurate */ 
31913197				goto string_cmp ;
31923198			}
3193- 			dval1  =  dval1  -  dval2 ;
3194- 			return  ZEND_NORMALIZE_BOOL (dval1 );
3199+ 			return  ZEND_THREEWAY_COMPARE (dval1 , dval2 );
31953200		} else  { /* they both have to be long's */ 
31963201			return  lval1  >  lval2  ? 1  : (lval1  <  lval2  ? -1  : 0 );
31973202		}
0 commit comments