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