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