1 2 /* 3 +------------------------------------------------------------------------+ 4 | Zephir Language | 5 +------------------------------------------------------------------------+ 6 | Copyright (c) 2011-2017 Zephir Team (http://www.zephir-lang.com) | 7 +------------------------------------------------------------------------+ 8 | This source file is subject to the New BSD License that is bundled | 9 | with this package in the file docs/LICENSE.txt. | 10 | | 11 | If you did not receive a copy of the license and are unable to | 12 | obtain it through the world-wide-web, please send an email | 13 | to license@zephir-lang.com so we can send you a copy immediately. | 14 +------------------------------------------------------------------------+ 15 | Authors: Andres Gutierrez <andres@zephir-lang.com> | 16 | Eduar Carvajal <eduar@zephir-lang.com> | 17 | Vladimir Kolesnikov <vladimir@extrememember.com> | 18 +------------------------------------------------------------------------+ 19 */ 20 21 #ifndef ZEPHIR_KERNEL_OPERATORS_H 22 #define ZEPHIR_KERNEL_OPERATORS_H 23 24 #include <php.h> 25 #include <Zend/zend.h> 26 27 /** Strict comparing */ 28 #define ZEPHIR_IS_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2) || zephir_compare_strict_long(op1, op2 TSRMLS_CC)) 29 #define ZEPHIR_IS_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2) || zephir_compare_strict_double(op1, op2 TSRMLS_CC)) 30 #define ZEPHIR_IS_STRING(op1, op2) zephir_compare_strict_string(op1, op2, strlen(op2)) 31 32 #define ZEPHIR_IS_LONG_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2) 33 #define ZEPHIR_IS_DOUBLE_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2) 34 #define ZEPHIR_IS_STRING_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_STRING && zephir_compare_strict_string(op1, op2, strlen(op2))) 35 #define ZEPHIR_IS_BOOL_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_BOOL && zephir_compare_strict_bool(op1, op2 TSRMLS_CC)) 36 37 /** strict boolean comparison */ 38 #define ZEPHIR_IS_FALSE(var) ((Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var)) || zephir_compare_strict_bool(var, 0 TSRMLS_CC)) 39 #define ZEPHIR_IS_TRUE(var) ((Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var)) || zephir_compare_strict_bool(var, 1 TSRMLS_CC)) 40 41 #define ZEPHIR_IS_FALSE_IDENTICAL(var) (Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var)) 42 #define ZEPHIR_IS_TRUE_IDENTICAL(var) (Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var)) 43 44 #define ZEPHIR_IS_NOT_FALSE(var) (Z_TYPE_P(var) != IS_BOOL || (Z_TYPE_P(var) == IS_BOOL && Z_BVAL_P(var))) 45 #define ZEPHIR_IS_NOT_TRUE(var) (Z_TYPE_P(var) != IS_BOOL || (Z_TYPE_P(var) == IS_BOOL && !Z_BVAL_P(var))) 46 #define ZEPHIR_IS_BOOL(op1, op2) zephir_compare_strict_bool(op1, op2 TSRMLS_CC) 47 #define ZEPHIR_IS_BOOL_VALUE(op1, op2) zephir_compare_strict_bool(op1, op2 TSRMLS_CC) 48 49 /** SQL null empty **/ 50 #define ZEPHIR_IS_EMPTY(var) (Z_TYPE_P(var) == IS_NULL || ZEPHIR_IS_FALSE(var) || (Z_TYPE_P(var) == IS_STRING && !Z_STRLEN_P(var)) || !zend_is_true(var)) 51 #define ZEPHIR_IS_NOT_EMPTY(var) (!ZEPHIR_IS_EMPTY(var)) 52 53 /** Is scalar */ 54 #define ZEPHIR_IS_SCALAR(var) (!ZEPHIR_IS_NOT_SCALAR(var)) 55 #define ZEPHIR_IS_NOT_SCALAR(var) (Z_TYPE_P(var) == IS_NULL || Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT || Z_TYPE_P(var) == IS_RESOURCE) 56 57 /** Equals/Identical */ 58 #define ZEPHIR_IS_EQUAL(op1, op2) zephir_is_equal(op1, op2 TSRMLS_CC) 59 #define ZEPHIR_IS_IDENTICAL(op1, op2) zephir_is_identical(op1, op2 TSRMLS_CC) 60 61 /** Greater/Smaller equals */ 62 #define ZEPHIR_LE(op1, op2) zephir_less_equal(op1, op2 TSRMLS_CC) 63 #define ZEPHIR_LE_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) <= op2) || zephir_less_equal_long(op1, op2 TSRMLS_CC)) 64 #define ZEPHIR_LE_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) <= op2) || zephir_less_equal_double(op1, op2 TSRMLS_CC)) 65 #define ZEPHIR_GE(op1, op2) zephir_greater_equal(op1, op2 TSRMLS_CC) 66 #define ZEPHIR_GE_LONG(op1, op2) zephir_greater_equal_long(op1, op2 TSRMLS_CC) 67 #define ZEPHIR_LT(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_TYPE_P(op2) == IS_LONG) ? Z_LVAL_P(op1) < Z_LVAL_P(op2) : zephir_less(op1, op2 TSRMLS_CC)) 68 #define ZEPHIR_LT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) < op2) || zephir_less_long(op1, op2 TSRMLS_CC)) 69 #define ZEPHIR_LT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) < op2) || zephir_less_double(op1, op2 TSRMLS_CC)) 70 #define ZEPHIR_GT(op1, op2) zephir_greater(op1, op2 TSRMLS_CC) 71 #define ZEPHIR_GT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) > op2) || zephir_greater_long(op1, op2 TSRMLS_CC)) 72 #define ZEPHIR_GT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) > op2) || zephir_greater_double(op1, op2 TSRMLS_CC)) 73 74 #define ZEPHIR_STRING_OFFSET(op1, index) ((index >= 0 && index < Z_STRLEN_P(op1)) ? Z_STRVAL_P(op1)[index] : '\0') 75 76 #define zephir_increment(var) fast_increment_function(var) 77 #define zephir_decrement(var) fast_decrement_function(var) 78 79 void zephir_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy); 80 81 #define zephir_add_function(result, left, right) zephir_add_function_ex(result, left, right TSRMLS_CC) 82 #define zephir_sub_function(result, left, right) fast_sub_function(result, left, right TSRMLS_CC) 83 84 #if PHP_VERSION_ID < 50600 85 void zephir_pow_function_ex(zval *return_value, zval *zbase, zval *zexp TSRMLS_DC); 86 #define zephir_pow_function(result, op1, op2) zephir_pow_function_ex(result, op1, op2 TSRMLS_CC) 87 #else 88 #define zephir_pow_function(result, op1, op2) pow_function(result, op1, op2 TSRMLS_CC) 89 #endif 90 91 /** Operator functions */ 92 int zephir_add_function_ex(zval *result, zval *op1, zval *op2 TSRMLS_DC); 93 int zephir_and_function(zval *result, zval *left, zval *right); 94 void zephir_negate(zval *z TSRMLS_DC); 95 96 /** Bitwise functions */ 97 int zephir_bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); 98 int zephir_bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); 99 int zephir_bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); 100 int zephir_shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); 101 int zephir_shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); 102 103 void zephir_concat_self(zval **left, zval *right TSRMLS_DC); 104 void zephir_concat_self_str(zval **left, const char *right, int right_length TSRMLS_DC); 105 void zephir_concat_self_long(zval **left, const long right TSRMLS_DC); 106 void zephir_concat_self_char(zval **left, unsigned char right TSRMLS_DC); 107 108 /** Strict comparing */ 109 int zephir_compare_strict_string(zval *op1, const char *op2, int op2_length); 110 int zephir_compare_strict_long(zval *op1, long op2 TSRMLS_DC); 111 int zephir_compare_strict_double(zval *op1, double op2 TSRMLS_DC); 112 int zephir_compare_strict_bool(zval *op1, zend_bool op2 TSRMLS_DC); 113 114 void zephir_cast(zval *result, zval *var, zend_uint type); 115 void zephir_convert_to_object(zval *op); 116 long zephir_get_intval_ex(const zval *op); 117 long zephir_get_charval_ex(const zval *op); 118 double zephir_get_doubleval_ex(const zval *op); 119 zend_bool zephir_get_boolval_ex(zval *op); 120 121 int zephir_is_numeric_ex(const zval *op); 122 123 int zephir_is_equal(zval *op1, zval *op2 TSRMLS_DC); 124 int zephir_is_identical(zval *op1, zval *op2 TSRMLS_DC); 125 126 int zephir_less(zval *op1, zval *op2 TSRMLS_DC); 127 int zephir_less_long(zval *op1, long op2 TSRMLS_DC); 128 int zephir_less_double(zval *op1, double op2 TSRMLS_DC); 129 130 int zephir_greater(zval *op1, zval *op2 TSRMLS_DC); 131 int zephir_greater_long(zval *op1, long op2 TSRMLS_DC); 132 int zephir_greater_double(zval *op1, double op2 TSRMLS_DC); 133 134 int zephir_less_equal(zval *op1, zval *op2 TSRMLS_DC); 135 int zephir_less_equal_long(zval *op1, long op2 TSRMLS_DC); 136 137 int zephir_greater_equal(zval *op1, zval *op2 TSRMLS_DC); 138 int zephir_greater_equal_long(zval *op1, long op2 TSRMLS_DC); 139 140 double zephir_safe_div_long_long(long op1, long op2 TSRMLS_DC); 141 double zephir_safe_div_long_double(long op1, double op2 TSRMLS_DC); 142 double zephir_safe_div_double_long(double op1, long op2 TSRMLS_DC); 143 double zephir_safe_div_double_double(double op1, double op2 TSRMLS_DC); 144 double zephir_safe_div_zval_long(zval *op1, long op2 TSRMLS_DC); 145 double zephir_safe_div_zval_double(zval *op1, double op2 TSRMLS_DC); 146 double zephir_safe_div_long_zval(long op1, zval *op2 TSRMLS_DC); 147 double zephir_safe_div_double_zval(double op1, zval *op2 TSRMLS_DC); 148 149 long zephir_safe_mod_long_long(long op1, long op2 TSRMLS_DC); 150 long zephir_safe_mod_long_double(long op1, double op2 TSRMLS_DC); 151 long zephir_safe_mod_double_long(double op1, long op2 TSRMLS_DC); 152 long zephir_safe_mod_double_double(double op1, double op2 TSRMLS_DC); 153 long zephir_safe_mod_zval_long(zval *op1, long op2 TSRMLS_DC); 154 long zephir_safe_mod_zval_double(zval *op1, double op2 TSRMLS_DC); 155 long zephir_safe_mod_long_zval(long op1, zval *op2 TSRMLS_DC); 156 long zephir_safe_mod_double_zval(double op1, zval *op2 TSRMLS_DC); 157 158 #define zephir_get_numberval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_doubleval(z)) 159 #define zephir_get_intval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_intval_ex(z)) 160 #define zephir_get_doubleval(z) (Z_TYPE_P(z) == IS_DOUBLE ? Z_DVAL_P(z) : zephir_get_doubleval_ex(z)) 161 #define zephir_get_boolval(z) (Z_TYPE_P(z) == IS_BOOL ? Z_BVAL_P(z) : zephir_get_boolval_ex(z)) 162 #define zephir_get_charval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_charval_ex(z)) 163 164 #ifndef PHP_WIN32 165 166 #define ZEPHIR_ADD_ASSIGN(z, v) \ 167 { \ 168 zval tmp; \ 169 ZEPHIR_SEPARATE(z); \ 170 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \ 171 Z_LVAL_P(z) += Z_LVAL_P(v); \ 172 } else { \ 173 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \ 174 Z_LVAL_P(z) += Z_DVAL_P(v); \ 175 } else { \ 176 add_function(&tmp, z, v TSRMLS_CC); \ 177 if (Z_TYPE(tmp) == IS_LONG) { \ 178 Z_LVAL_P(z) = Z_LVAL(tmp); \ 179 } else { \ 180 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 181 Z_DVAL_P(z) = Z_DVAL(tmp); \ 182 } \ 183 } \ 184 } \ 185 } \ 186 } 187 188 #define ZEPHIR_SUB_ASSIGN(z, v) \ 189 { \ 190 zval tmp; \ 191 ZEPHIR_SEPARATE(z); \ 192 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \ 193 Z_LVAL_P(z) -= Z_LVAL_P(v); \ 194 } else { \ 195 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \ 196 Z_LVAL_P(z) -= Z_DVAL_P(v); \ 197 } else { \ 198 sub_function(&tmp, z, v TSRMLS_CC); \ 199 if (Z_TYPE(tmp) == IS_LONG) { \ 200 Z_LVAL_P(z) = Z_LVAL(tmp); \ 201 } else { \ 202 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 203 Z_DVAL_P(z) = Z_DVAL(tmp); \ 204 } \ 205 } \ 206 } \ 207 } \ 208 } 209 210 #define ZEPHIR_MUL_ASSIGN(z, v) \ 211 { \ 212 zval tmp; \ 213 ZEPHIR_SEPARATE(z); \ 214 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_LONG) { \ 215 Z_LVAL_P(z) *= Z_LVAL_P(v); \ 216 } else { \ 217 if (Z_TYPE_P(z) == IS_LONG && Z_TYPE_P(v) == IS_DOUBLE) { \ 218 Z_LVAL_P(z) *= Z_DVAL_P(v); \ 219 } else { \ 220 mul_function(&tmp, z, v TSRMLS_CC); \ 221 if (Z_TYPE(tmp) == IS_LONG) { \ 222 Z_LVAL_P(z) = Z_LVAL(tmp); \ 223 } else { \ 224 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 225 Z_DVAL_P(z) = Z_DVAL(tmp); \ 226 } \ 227 } \ 228 } \ 229 } \ 230 } 231 232 #else 233 234 #define ZEPHIR_ADD_ASSIGN(z, v) \ 235 { \ 236 zval tmp; \ 237 ZEPHIR_SEPARATE(z); \ 238 add_function(&tmp, z, v TSRMLS_CC); \ 239 if (Z_TYPE(tmp) == IS_LONG) { \ 240 Z_LVAL_P(z) = Z_LVAL(tmp); \ 241 } else { \ 242 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 243 Z_DVAL_P(z) = Z_DVAL(tmp); \ 244 } \ 245 } \ 246 } 247 248 #define ZEPHIR_SUB_ASSIGN(z, v) \ 249 { \ 250 zval tmp; \ 251 ZEPHIR_SEPARATE(z); \ 252 sub_function(&tmp, z, v TSRMLS_CC); \ 253 if (Z_TYPE(tmp) == IS_LONG) { \ 254 Z_LVAL_P(z) = Z_LVAL(tmp); \ 255 } else { \ 256 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 257 Z_DVAL_P(z) = Z_DVAL(tmp); \ 258 } \ 259 } \ 260 } 261 262 #define ZEPHIR_MUL_ASSIGN(z, v) \ 263 { \ 264 zval tmp; \ 265 ZEPHIR_SEPARATE(z); \ 266 mul_function(&tmp, z, v TSRMLS_CC); \ 267 if (Z_TYPE(tmp) == IS_LONG) { \ 268 Z_LVAL_P(z) = Z_LVAL(tmp); \ 269 } else { \ 270 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 271 Z_DVAL_P(z) = Z_DVAL(tmp); \ 272 } \ 273 } \ 274 } 275 276 #endif 277 278 #define zephir_get_strval(left, right) \ 279 { \ 280 int use_copy_right; \ 281 zval right_tmp; \ 282 if (Z_TYPE_P(right) == IS_STRING) { \ 283 ZEPHIR_CPY_WRT(left, right); \ 284 } else { \ 285 INIT_ZVAL(right_tmp); \ 286 zephir_make_printable_zval(right, &right_tmp, &use_copy_right); \ 287 if (use_copy_right) { \ 288 ZEPHIR_INIT_NVAR(left); \ 289 ZVAL_STRINGL(left, Z_STRVAL_P(&right_tmp), Z_STRLEN_P(&right_tmp), 0); \ 290 } \ 291 } \ 292 } 293 294 #define zephir_get_arrval(returnValue, passValue) \ 295 { \ 296 if (Z_TYPE_P(passValue) == IS_ARRAY) { \ 297 ZEPHIR_CPY_WRT(returnValue, passValue); \ 298 } else { \ 299 ZEPHIR_INIT_NVAR(returnValue); \ 300 array_init_size(returnValue, 0); \ 301 } \ 302 } 303 304 #define zephir_is_numeric(value) (Z_TYPE_P(value) == IS_LONG || Z_TYPE_P(value) == IS_DOUBLE || zephir_is_numeric_ex(value)) 305 306 #define zephir_is_true(value) \ 307 (Z_TYPE_P(value) == IS_NULL ? 0 : \ 308 (Z_TYPE_P(value) == IS_BOOL ? Z_BVAL_P(value) : \ 309 (Z_TYPE_P(value) == IS_LONG ? (Z_LVAL_P(value) ? 1 : 0) : \ 310 zend_is_true(value) \ 311 ) \ 312 ) \ 313 ) 314 315 #endif 316