0e21ec59bf041e15b343a865beb7421c04da4dcc
4 # include "php_config.h"
12 static inline int psi_calc_num_exp_value(num_exp
*exp
, impl_val
*strct
, impl_val
*res
) {
13 impl_val
*ref
, *tmp
= NULL
;
17 switch (is_numeric_string(exp
->u
.numb
, strlen(exp
->u
.numb
), (zend_long
*) res
, (double *) res
, 0)) {
26 switch (exp
->u
.cnst
->type
->type
) {
28 res
->i64
= zend_get_constant_str(exp
->u
.cnst
->name
, strlen(exp
->u
.cnst
->name
))->value
.lval
;
31 res
->dval
= zend_get_constant_str(exp
->u
.cnst
->name
, strlen(exp
->u
.cnst
->name
))->value
.dval
;
39 return psi_calc_num_exp(exp
->u
.enm
->num
?: &exp
->u
.enm
->inc
, NULL
, res
);
44 ref
= struct_member_ref(exp
->u
.dvar
->arg
, strct
, &tmp
);
46 ref
= exp
->u
.dvar
->arg
->let
;
48 switch (real_decl_type(exp
->u
.dvar
->arg
->type
)->type
) {
57 memcpy(res
, deref_impl_val(ref
, exp
->u
.dvar
), sizeof(*res
));
61 return real_decl_type(exp
->u
.dvar
->arg
->type
)->type
;
65 memcpy(res
, deref_impl_val(ref
, exp
->u
.dvar
), sizeof(*res
));
69 return real_decl_type(exp
->u
.dvar
->arg
->type
)->type
;
71 EMPTY_SWITCH_DEFAULT_CASE();
75 EMPTY_SWITCH_DEFAULT_CASE();
80 int psi_calc_num_exp(num_exp
*exp
, impl_val
*strct
, impl_val
*res
) {
82 int num_type
= psi_calc_num_exp_value(exp
, strct
, &num
);
86 int tmp_type
= psi_calc_num_exp(exp
->operand
, strct
, &tmp
);
88 return exp
->calculator(num_type
, &num
, tmp_type
, &tmp
, res
);
91 memcpy(res
, &num
, sizeof(*res
));
99 #define PSI_CALC_OP(var) do { \
100 const char *fmt = "calc %" PRI##var ", %" PRI##var ": %" PRI##var "\n"; \
101 res->var = PSI_CALC(v1->var, v2->var); \
102 if (!res->var && (v1->var || v2->var)) fprintf(stderr, fmt, v1->var, v2->var, res->var); \
104 #define PSI_CALC_OP2(vres, var1, var2) do { \
105 const char *fmt = "calc %" PRI##var1 ", %" PRI##var2 ": %" PRI##vres "\n"; \
106 res->vres = PSI_CALC(v1->var1, v2->var2); \
107 if (!res->vres && (v1->var1 || v2->var2)) fprintf(stderr, fmt, v1->var1, v2->var2, res->vres); \
110 #ifdef HAVE_LONG_DOUBLE
111 #define PSI_CALC_NO_LD
112 #define PSI_CALC_OP_LD PSI_CALC_OP(ldval)
113 #define PSI_CALC_OP2_LD2(var1) PSI_CALC_OP2(ldval, var1, ldval)
114 #define PSI_CALC_OP2_LD1(var2) PSI_CALC_OP2(ldval, ldval, var2)
116 #define PSI_CALC_NO_LD abort()
117 #define PSI_CALC_OP_LD PSI_CALC_NO_LD
118 #define PSI_CALC_OP2_LD2(var) PSI_CALC_NO_LD
119 #define PSI_CALC_OP2_LD1(var) PSI_CALC_NO_LD
122 #define PSI_CALC_FN(op) int psi_calc_##op(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res) \
126 case PSI_T_FLOAT: PSI_CALC_OP(fval); break; \
127 case PSI_T_DOUBLE: PSI_CALC_OP(dval); break; \
128 case PSI_T_LONG_DOUBLE: PSI_CALC_OP_LD; break; \
129 case PSI_T_INT8: PSI_CALC_OP(i8); break; \
130 case PSI_T_UINT8: PSI_CALC_OP(u8); break; \
131 case PSI_T_INT16: PSI_CALC_OP(i16); break; \
132 case PSI_T_UINT16: PSI_CALC_OP(u16); break; \
133 case PSI_T_INT32: PSI_CALC_OP(i32); break; \
134 case PSI_T_UINT32: PSI_CALC_OP(u32); break; \
135 case PSI_T_INT64: PSI_CALC_OP(i64); break; \
136 case PSI_T_UINT64: PSI_CALC_OP(u64); break; \
137 EMPTY_SWITCH_DEFAULT_CASE(); \
140 } else if (t1 == PSI_T_DOUBLE) { \
142 case PSI_T_LONG_DOUBLE: PSI_CALC_OP2_LD2(dval); return t2; \
143 case PSI_T_FLOAT: PSI_CALC_OP2(dval, dval, fval); break; \
144 case PSI_T_INT8: PSI_CALC_OP2(dval, dval, i8); break; \
145 case PSI_T_UINT8: PSI_CALC_OP2(dval, dval, u8); break; \
146 case PSI_T_INT16: PSI_CALC_OP2(dval, dval, i16); break; \
147 case PSI_T_UINT16: PSI_CALC_OP2(dval, dval, u16); break; \
148 case PSI_T_INT32: PSI_CALC_OP2(dval, dval, i32); break; \
149 case PSI_T_UINT32: PSI_CALC_OP2(dval, dval, u32); break; \
150 case PSI_T_INT64: PSI_CALC_OP2(dval, dval, i64); break; \
151 case PSI_T_UINT64: PSI_CALC_OP2(dval, dval, u64); break; \
152 EMPTY_SWITCH_DEFAULT_CASE(); \
155 } else if (t2 == PSI_T_DOUBLE) { \
157 case PSI_T_LONG_DOUBLE: PSI_CALC_OP2_LD1(dval); return t1; \
158 case PSI_T_FLOAT: PSI_CALC_OP2(dval, fval, dval); break; \
159 case PSI_T_INT8: PSI_CALC_OP2(dval, i8, dval); break; \
160 case PSI_T_UINT8: PSI_CALC_OP2(dval, u8, dval); break; \
161 case PSI_T_INT16: PSI_CALC_OP2(dval, i16, dval); break; \
162 case PSI_T_UINT16: PSI_CALC_OP2(dval, u16, dval); break; \
163 case PSI_T_INT32: PSI_CALC_OP2(dval, i32, dval); break; \
164 case PSI_T_UINT32: PSI_CALC_OP2(dval, u32, dval); break; \
165 case PSI_T_INT64: PSI_CALC_OP2(dval, i64, dval); break; \
166 case PSI_T_UINT64: PSI_CALC_OP2(dval, u64, dval); break; \
167 EMPTY_SWITCH_DEFAULT_CASE(); \
170 } else if (t1 == PSI_T_LONG_DOUBLE) { \
173 case PSI_T_DOUBLE: PSI_CALC_OP2_LD1(dval); break; \
174 case PSI_T_FLOAT: PSI_CALC_OP2_LD1(fval); break; \
175 case PSI_T_INT8: PSI_CALC_OP2_LD1(i8); break; \
176 case PSI_T_UINT8: PSI_CALC_OP2_LD1(u8); break; \
177 case PSI_T_INT16: PSI_CALC_OP2_LD1(i16); break; \
178 case PSI_T_UINT16: PSI_CALC_OP2_LD1(u16); break; \
179 case PSI_T_INT32: PSI_CALC_OP2_LD1(i32); break; \
180 case PSI_T_UINT32: PSI_CALC_OP2_LD1(u32); break; \
181 case PSI_T_INT64: PSI_CALC_OP2_LD1(i64); break; \
182 case PSI_T_UINT64: PSI_CALC_OP2_LD1(u64); break; \
183 EMPTY_SWITCH_DEFAULT_CASE(); \
186 } else if (t2 == PSI_T_LONG_DOUBLE) { \
189 case PSI_T_DOUBLE: PSI_CALC_OP2_LD2(dval); break; \
190 case PSI_T_FLOAT: PSI_CALC_OP2_LD2(fval); break; \
191 case PSI_T_INT8: PSI_CALC_OP2_LD2(i8); break; \
192 case PSI_T_UINT8: PSI_CALC_OP2_LD2(u8); break; \
193 case PSI_T_INT16: PSI_CALC_OP2_LD2(i16); break; \
194 case PSI_T_UINT16: PSI_CALC_OP2_LD2(u16); break; \
195 case PSI_T_INT32: PSI_CALC_OP2_LD2(i32); break; \
196 case PSI_T_UINT32: PSI_CALC_OP2_LD2(u32); break; \
197 case PSI_T_INT64: PSI_CALC_OP2_LD2(i64); break; \
198 case PSI_T_UINT64: PSI_CALC_OP2_LD2(u64); break; \
199 EMPTY_SWITCH_DEFAULT_CASE(); \
202 } else if (t1 == PSI_T_FLOAT) { \
204 case PSI_T_LONG_DOUBLE: PSI_CALC_OP2_LD2(fval); return t2; \
205 case PSI_T_DOUBLE: PSI_CALC_OP2(dval, fval, dval); return t2; \
206 case PSI_T_INT8: PSI_CALC_OP2(fval, fval, i8); break; \
207 case PSI_T_UINT8: PSI_CALC_OP2(fval, fval, u8); break; \
208 case PSI_T_INT16: PSI_CALC_OP2(fval, fval, i16); break; \
209 case PSI_T_UINT16: PSI_CALC_OP2(fval, fval, u16); break; \
210 case PSI_T_INT32: PSI_CALC_OP2(fval, fval, i32); break; \
211 case PSI_T_UINT32: PSI_CALC_OP2(fval, fval, u32); break; \
212 case PSI_T_INT64: PSI_CALC_OP2(fval, fval, i64); break; \
213 case PSI_T_UINT64: PSI_CALC_OP2(fval, fval, u64); break; \
214 EMPTY_SWITCH_DEFAULT_CASE(); \
217 } else if (t2 == PSI_T_FLOAT) { \
219 case PSI_T_LONG_DOUBLE: PSI_CALC_OP2_LD1(fval); return t1; \
220 case PSI_T_DOUBLE: PSI_CALC_OP2(dval, dval, fval); return t1; \
221 case PSI_T_INT8: PSI_CALC_OP2(fval, i8, fval); break; \
222 case PSI_T_UINT8: PSI_CALC_OP2(fval, u8, fval); break; \
223 case PSI_T_INT16: PSI_CALC_OP2(fval, i16, fval); break; \
224 case PSI_T_UINT16: PSI_CALC_OP2(fval, u16, fval); break; \
225 case PSI_T_INT32: PSI_CALC_OP2(fval, i32, fval); break; \
226 case PSI_T_UINT32: PSI_CALC_OP2(fval, u32, fval); break; \
227 case PSI_T_INT64: PSI_CALC_OP2(fval, i64, fval); break; \
228 case PSI_T_UINT64: PSI_CALC_OP2(fval, u64, fval); break; \
229 EMPTY_SWITCH_DEFAULT_CASE(); \
233 int64_t sval1 = v1->i64, sval2 = v2->i64; \
234 uint64_t uval1 = v1->u64, uval2 = v2->u64; \
236 case PSI_T_INT8: sval1 >>= 8; \
237 case PSI_T_INT16: sval1 >>= 8; \
238 case PSI_T_INT32: sval1 >>= 8; \
241 case PSI_T_INT8: sval2 >>= 8; \
242 case PSI_T_INT16: sval2 >>= 8; \
243 case PSI_T_INT32: sval2 >>= 8; \
245 res->i64 = PSI_CALC(sval1 , sval2); \
246 return PSI_T_INT64; \
247 case PSI_T_UINT8: uval2 >>= 8; \
248 case PSI_T_UINT16: uval2 >>= 8; \
249 case PSI_T_UINT32: uval2 >>= 8; \
251 res->i64 = PSI_CALC(sval1, uval2); \
252 return PSI_T_INT64; \
255 case PSI_T_UINT8: uval1 >>= 8; \
256 case PSI_T_UINT16: uval1 >>= 8; \
257 case PSI_T_UINT32: uval1 >>= 8; \
260 case PSI_T_INT8: sval2 >>= 8; \
261 case PSI_T_INT16: sval2 >>= 8; \
262 case PSI_T_INT32: sval2 >>= 8; \
264 res->i64 = PSI_CALC(uval1, sval2); \
265 return PSI_T_INT64; \
266 case PSI_T_UINT8: uval2 >>= 8; \
267 case PSI_T_UINT16: uval2 >>= 8; \
268 case PSI_T_UINT32: uval2 >>= 8; \
270 res->u64 = PSI_CALC(uval1, uval2); \
271 return PSI_T_UINT64; \
281 #define PSI_CALC(var1, var2) (var1) + (var2)
284 #define PSI_CALC(var1, var2) (var1) * (var2)
287 #define PSI_CALC(var1, var2) (var1) - (var2)
290 #define PSI_CALC(var1, var2) (var1) / (var2)