1 2 /* 3 +------------------------------------------------------------------------+ 4 | Zephir Language | 5 +------------------------------------------------------------------------+ 6 | Copyright (c) 2011-2017 Phalcon 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 #include "kernel/main.h" 27 28 #define zephir_make_printable_zval(expr, expr_copy) zend_make_printable_zval(expr, expr_copy); 29 30 /** Strict comparing */ 31 #define ZEPHIR_IS_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2) || zephir_compare_strict_long(op1, op2)) 32 #define ZEPHIR_IS_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2) || zephir_compare_strict_double(op1, op2)) 33 #define ZEPHIR_IS_STRING(op1, op2) zephir_compare_strict_string(op1, op2, strlen(op2)) 34 35 #define ZEPHIR_IS_LONG_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) == op2) 36 #define ZEPHIR_IS_DOUBLE_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) == op2) 37 #define ZEPHIR_IS_STRING_IDENTICAL(op1, op2) (Z_TYPE_P(op1) == IS_STRING && zephir_compare_strict_string(op1, op2, strlen(op2))) 38 #define ZEPHIR_IS_BOOL_IDENTICAL(op1, op2) ((Z_TYPE_P(op1) == IS_FALSE || Z_TYPE_P(op1) == IS_TRUE) && zephir_compare_strict_bool(op1, op2)) 39 40 /** strict boolean comparison */ 41 #define ZEPHIR_IS_FALSE(var) ((Z_TYPE_P(var) == IS_FALSE) || zephir_compare_strict_bool(var, 0)) 42 #define ZEPHIR_IS_TRUE(var) ((Z_TYPE_P(var) == IS_TRUE) || zephir_compare_strict_bool(var, 1)) 43 #define ZEPHIR_IS_FALSE_IDENTICAL(var) (Z_TYPE_P(var) == IS_FALSE) 44 #define ZEPHIR_IS_TRUE_IDENTICAL(var) (Z_TYPE_P(var) == IS_TRUE) 45 46 #define ZEPHIR_IS_NOT_FALSE(var) ((Z_TYPE_P(var) != IS_TRUE && Z_TYPE_P(var) != IS_FALSE) || Z_TYPE_P(var) == IS_TRUE) 47 #define ZEPHIR_IS_NOT_TRUE(var) ((Z_TYPE_P(var) != IS_TRUE && Z_TYPE_P(var) != IS_FALSE) || Z_TYPE_P(var) == IS_FALSE) 48 #define ZEPHIR_IS_BOOL(op1, op2) zephir_compare_strict_bool(op1, op2) 49 #define ZEPHIR_IS_BOOL_VALUE(op1, op2) zephir_compare_strict_bool(op1, op2) 50 51 /** SQL null empty **/ 52 #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)) 53 #define ZEPHIR_IS_NOT_EMPTY(var) (!ZEPHIR_IS_EMPTY(var)) 54 55 /** Is scalar */ 56 #define ZEPHIR_IS_SCALAR(var) (!ZEPHIR_IS_NOT_SCALAR(var)) 57 #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) 58 59 /** Equals/Identical */ 60 #define ZEPHIR_IS_EQUAL(op1, op2) zephir_is_equal(op1, op2) 61 #define ZEPHIR_IS_IDENTICAL(op1, op2) zephir_is_identical(op1, op2) 62 63 /** Greater/Smaller equals */ 64 #define ZEPHIR_LE(op1, op2) zephir_less_equal(op1, op2) 65 #define ZEPHIR_LE_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) <= op2) || zephir_less_equal_long(op1, op2)) 66 #define ZEPHIR_LE_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) <= op2) || zephir_less_equal_double(op1, op2)) 67 #define ZEPHIR_GE(op1, op2) zephir_greater_equal(op1, op2) 68 #define ZEPHIR_GE_LONG(op1, op2) zephir_greater_equal_long(op1, op2) 69 #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)) 70 #define ZEPHIR_LT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) < op2) || zephir_less_long(op1, op2)) 71 #define ZEPHIR_LT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) < op2) || zephir_less_double(op1, op2)) 72 #define ZEPHIR_GT(op1, op2) zephir_greater(op1, op2) 73 #define ZEPHIR_GT_LONG(op1, op2) ((Z_TYPE_P(op1) == IS_LONG && Z_LVAL_P(op1) > op2) || zephir_greater_long(op1, op2)) 74 #define ZEPHIR_GT_DOUBLE(op1, op2) ((Z_TYPE_P(op1) == IS_DOUBLE && Z_DVAL_P(op1) > op2) || zephir_greater_double(op1, op2)) 75 76 #define ZEPHIR_STRING_OFFSET(op1, index) ((index >= 0 && index < Z_STRLEN_P(op1)) ? Z_STRVAL_P(op1)[index] : '\0') 77 78 /* concatenation */ 79 void zephir_concat_self(zval *left, zval *right); 80 void zephir_concat_self_str(zval *left, const char *right, int right_length); 81 void zephir_concat_self_long(zval *left, const long right); 82 void zephir_concat_self_char(zval *left, unsigned char right); 83 84 /** Strict comparing */ 85 int zephir_compare_strict_string(zval *op1, const char *op2, int op2_length); 86 int zephir_compare_strict_long(zval *op1, long op2); 87 88 /** Operator functions */ 89 int zephir_add_function_ex(zval *result, zval *op1, zval *op2); 90 int zephir_and_function(zval *result, zval *left, zval *right); 91 void zephir_negate(zval *z); 92 93 /** Bitwise functions */ 94 int zephir_bitwise_and_function(zval *result, zval *op1, zval *op2); 95 int zephir_bitwise_or_function(zval *result, zval *op1, zval *op2); 96 int zephir_bitwise_xor_function(zval *result, zval *op1, zval *op2); 97 int zephir_shift_left_function(zval *result, zval *op1, zval *op2); 98 int zephir_shift_right_function(zval *result, zval *op1, zval *op2); 99 100 /** Strict comparing */ 101 int zephir_compare_strict_string(zval *op1, const char *op2, int op2_length); 102 int zephir_compare_strict_long(zval *op1, long op2); 103 int zephir_compare_strict_double(zval *op1, double op2); 104 int zephir_compare_strict_bool(zval *op1, zend_bool op2); 105 106 void zephir_cast(zval *result, zval *var, uint32_t type); 107 void zephir_convert_to_object(zval *op); 108 long zephir_get_intval_ex(const zval *op); 109 long zephir_get_charval_ex(const zval *op); 110 double zephir_get_doubleval_ex(const zval *op); 111 zend_bool zephir_get_boolval_ex(zval *op); 112 113 int zephir_is_numeric_ex(const zval *op); 114 115 int zephir_is_equal(zval *op1, zval *op2); 116 int zephir_is_identical(zval *op1, zval *op2); 117 118 int zephir_less(zval *op1, zval *op2); 119 int zephir_less_long(zval *op1, long op2); 120 int zephir_less_double(zval *op1, double op2); 121 122 int zephir_greater(zval *op1, zval *op2); 123 int zephir_greater_long(zval *op1, long op2); 124 int zephir_greater_double(zval *op1, double op2); 125 126 int zephir_less_equal(zval *op1, zval *op2); 127 int zephir_less_equal_long(zval *op1, long op2); 128 129 int zephir_greater_equal(zval *op1, zval *op2); 130 int zephir_greater_equal_long(zval *op1, long op2); 131 132 double zephir_safe_div_long_long(long op1, long op2); 133 double zephir_safe_div_long_double(long op1, double op2); 134 double zephir_safe_div_double_long(double op1, long op2); 135 double zephir_safe_div_double_double(double op1, double op2); 136 double zephir_safe_div_zval_long(zval *op1, long op2); 137 double zephir_safe_div_zval_double(zval *op1, double op2); 138 double zephir_safe_div_long_zval(long op1, zval *op2); 139 double zephir_safe_div_double_zval(double op1, zval *op2); 140 141 long zephir_safe_mod_long_long(long op1, long op2); 142 long zephir_safe_mod_long_double(long op1, double op2); 143 long zephir_safe_mod_double_long(double op1, long op2); 144 long zephir_safe_mod_double_double(double op1, double op2); 145 long zephir_safe_mod_zval_long(zval *op1, long op2); 146 long zephir_safe_mod_zval_double(zval *op1, double op2); 147 long zephir_safe_mod_long_zval(long op1, zval *op2); 148 long zephir_safe_mod_double_zval(double op1, zval *op2); 149 150 #define zephir_get_numberval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_doubleval(z)) 151 #define zephir_get_intval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_intval_ex(z)) 152 #define zephir_get_doubleval(z) (Z_TYPE_P(z) == IS_DOUBLE ? Z_DVAL_P(z) : zephir_get_doubleval_ex(z)) 153 #define zephir_get_boolval(z) (Z_TYPE_P(z) == IS_TRUE ? 1 : (Z_TYPE_P(z) == IS_FALSE ? 0 : zephir_get_boolval_ex(z))) 154 #define zephir_get_charval(z) (Z_TYPE_P(z) == IS_LONG ? Z_LVAL_P(z) : zephir_get_charval_ex(z)) 155 156 #define zephir_add_function(result, left, right) fast_add_function(result, left, right) 157 #define zephir_sub_function(result, left, right) sub_function(result, left, right) 158 #define zephir_pow_function(result, op1, op2) pow_function(result, op1, op2) 159 #define zephir_increment(var) increment_function(var) 160 #define zephir_decrement(var) decrement_function(var) 161 162 #define ZEPHIR_ADD_ASSIGN(z, v) \ 163 { \ 164 zval tmp; \ 165 ZEPHIR_SEPARATE(z); \ 166 add_function(&tmp, z, v); \ 167 if (Z_TYPE(tmp) == IS_LONG) { \ 168 Z_LVAL_P(z) = Z_LVAL(tmp); \ 169 } else { \ 170 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 171 Z_DVAL_P(z) = Z_DVAL(tmp); \ 172 } \ 173 } \ 174 } 175 176 #define ZEPHIR_SUB_ASSIGN(z, v) \ 177 { \ 178 zval tmp; \ 179 ZEPHIR_SEPARATE(z); \ 180 sub_function(&tmp, z, v); \ 181 if (Z_TYPE(tmp) == IS_LONG) { \ 182 Z_LVAL_P(z) = Z_LVAL(tmp); \ 183 } else { \ 184 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 185 Z_DVAL_P(z) = Z_DVAL(tmp); \ 186 } \ 187 } \ 188 } 189 190 #define ZEPHIR_MUL_ASSIGN(z, v) \ 191 { \ 192 zval tmp; \ 193 ZEPHIR_SEPARATE(z); \ 194 mul_function(&tmp, z, v); \ 195 if (Z_TYPE(tmp) == IS_LONG) { \ 196 Z_LVAL_P(z) = Z_LVAL(tmp); \ 197 } else { \ 198 if (Z_TYPE(tmp) == IS_DOUBLE) { \ 199 Z_DVAL_P(z) = Z_DVAL(tmp); \ 200 } \ 201 } \ 202 } 203 204 205 #define zephir_get_strval(left, right) \ 206 { \ 207 int use_copy_right; \ 208 zval right_tmp; \ 209 if (Z_TYPE_P(right) == IS_STRING) { \ 210 ZEPHIR_CPY_WRT(left, right); \ 211 } else { \ 212 use_copy_right = zephir_make_printable_zval(right, &right_tmp); \ 213 if (use_copy_right) { \ 214 ZEPHIR_INIT_NVAR(left); \ 215 ZVAL_STRINGL(left, Z_STRVAL(right_tmp), Z_STRLEN(right_tmp)); \ 216 zval_ptr_dtor(&right_tmp); \ 217 } \ 218 } \ 219 } 220 221 #define zephir_get_arrval(returnValue, passValue) \ 222 { \ 223 if (Z_TYPE_P(passValue) == IS_ARRAY) { \ 224 ZEPHIR_CPY_WRT(returnValue, passValue); \ 225 } else if (Z_ISNULL_P(passValue) || Z_ISUNDEF_P(passValue)) { \ 226 ZEPHIR_INIT_NVAR(returnValue); \ 227 array_init_size(returnValue, 0); \ 228 } else { \ 229 convert_to_array(passValue); \ 230 ZEPHIR_CPY_WRT(returnValue, passValue); \ 231 } \ 232 } 233 234 #define zephir_is_numeric(value) (Z_TYPE_P(value) == IS_LONG || Z_TYPE_P(value) == IS_DOUBLE || zephir_is_numeric_ex(value)) 235 236 #define zephir_is_true(value) \ 237 (Z_TYPE_P(value) == IS_TRUE ? 1 : \ 238 (Z_TYPE_P(value) == IS_FALSE ? 0 : \ 239 (Z_TYPE_P(value) == IS_NULL ? 0 : \ 240 (Z_TYPE_P(value) == IS_LONG ? (Z_LVAL_P(value) ? 1 : 0) : \ 241 zend_is_true(value) \ 242 ) \ 243 ) \ 244 ) \ 245 ) 246 247 248 #endif 249