f204753bfbf9190c13a0eb96f5bea4769a46f5b1
11 void psi_to_void(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
16 void psi_to_zval(zval
*return_value
, set_value
*set
, impl_val
*ret_val
) {
17 RETVAL_ZVAL(ret_val
->ptr
, 1, 0);
20 impl_val
*psi_let_zval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
22 *to_free
= tmp
->ptr
= emalloc(sizeof(zval
));
23 ZVAL_COPY_VALUE(tmp
->ptr
, iarg
->_zv
);
27 void psi_to_bool(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
29 psi_to_int(return_value
, set
, ret_val
);
30 convert_to_boolean(return_value
);
33 static inline impl_val
*psi_val_boolval(impl_val
*tmp
, token_t real_type
, zend_bool boolval
) {
35 case PSI_T_INT8
: tmp
->i8
= boolval
; break;
36 case PSI_T_UINT8
: tmp
->u8
= boolval
; break;
37 case PSI_T_INT16
: tmp
->i16
= boolval
; break;
38 case PSI_T_UINT16
: tmp
->u16
= boolval
; break;
39 case PSI_T_INT32
: tmp
->i32
= boolval
; break;
40 case PSI_T_UINT32
: tmp
->u32
= boolval
; break;
41 case PSI_T_INT64
: tmp
->i64
= boolval
; break;
42 case PSI_T_UINT64
: tmp
->u64
= boolval
; break;
43 case PSI_T_FLOAT
: tmp
->fval
= boolval
; break;
44 case PSI_T_DOUBLE
: tmp
->dval
= boolval
; break;
45 #ifdef HAVE_LONG_DOUBLE
46 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= boolval
; break;
48 EMPTY_SWITCH_DEFAULT_CASE();
53 impl_val
*psi_let_boolval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
56 token_t real_type
= type
? real_decl_type(type
)->type
: PSI_T_UINT8
;
58 if (iarg
->type
->type
== PSI_T_BOOL
) {
59 boolval
= iarg
->val
.zend
.bval
;
61 boolval
= zend_is_true(iarg
->_zv
);
64 return psi_val_boolval(tmp
, real_type
, boolval
);
67 # define RETVAL_LONG_U64(V) \
68 if (V > ZEND_LONG_MAX) { \
70 RETVAL_STRING(zend_print_ulong_to_buf(&d[22], V)); \
75 void psi_to_int(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
77 decl_var
*var
= set
->vars
->vars
[0];
78 token_t t
= real_decl_type(var
->arg
->type
)->type
;
79 impl_val
*v
= deref_impl_val(ret_val
, var
);
82 case PSI_T_INT8
: RETVAL_LONG(v
->i8
); break;
83 case PSI_T_UINT8
: RETVAL_LONG(v
->u8
); break;
84 case PSI_T_INT16
: RETVAL_LONG(v
->i16
); break;
85 case PSI_T_UINT16
: RETVAL_LONG(v
->u16
); break;
86 case PSI_T_INT32
: RETVAL_LONG(v
->i32
); break;
87 case PSI_T_UINT32
: RETVAL_LONG(v
->u32
); break;
88 case PSI_T_INT64
: RETVAL_LONG(v
->i64
); break;
89 case PSI_T_UINT64
: RETVAL_LONG_U64(v
->u64
); break;
90 case PSI_T_FLOAT
: RETVAL_DOUBLE((double) v
->fval
); break;
91 case PSI_T_DOUBLE
: RETVAL_DOUBLE(v
->dval
); break;
92 #ifdef HAVE_LONG_DOUBLE
93 case PSI_T_LONG_DOUBLE
: RETVAL_DOUBLE((double) v
->ldval
); break;
95 EMPTY_SWITCH_DEFAULT_CASE();
98 convert_to_long(return_value
);
101 static inline impl_val
*psi_val_intval(impl_val
*tmp
, token_t real_type
, zend_long intval
) {
103 case PSI_T_INT8
: tmp
->i8
= intval
; break;
104 case PSI_T_UINT8
: tmp
->u8
= intval
; break;
105 case PSI_T_INT16
: tmp
->i16
= intval
; break;
106 case PSI_T_UINT16
: tmp
->u16
= intval
; break;
107 case PSI_T_INT32
: tmp
->i32
= intval
; break;
108 case PSI_T_UINT32
: tmp
->u32
= intval
; break;
109 case PSI_T_INT
: tmp
->ival
= intval
; break;
110 case PSI_T_INT64
: tmp
->i64
= intval
; break;
111 case PSI_T_UINT64
: tmp
->u64
= intval
; break;
112 case PSI_T_FLOAT
: tmp
->fval
= intval
; break;
113 case PSI_T_DOUBLE
: tmp
->dval
= intval
; break;
114 #ifdef HAVE_LONG_DOUBLE
115 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= intval
; break;
117 EMPTY_SWITCH_DEFAULT_CASE();
123 impl_val
*psi_let_intval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
126 token_t real_type
= type
? real_decl_type(type
)->type
: PSI_T_INT
;
128 if (iarg
->type
->type
== PSI_T_INT
) {
129 intval
= iarg
->val
.zend
.lval
;
131 intval
= zval_get_long(iarg
->_zv
);
134 return psi_val_intval(tmp
, real_type
, intval
);
137 void psi_to_double(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
139 decl_var
*var
= set
->vars
->vars
[0];
140 token_t t
= real_decl_type(var
->arg
->type
)->type
;
141 impl_val
*v
= deref_impl_val(ret_val
, var
);
144 case PSI_T_FLOAT
: RETVAL_DOUBLE((double) v
->fval
); break;
145 case PSI_T_DOUBLE
: RETVAL_DOUBLE(v
->dval
); break;
146 #ifdef HAVE_LONG_DOUBLE
147 case PSI_T_LONG_DOUBLE
: RETVAL_DOUBLE((double) v
->ldval
); break;
149 case PSI_T_INT8
: RETVAL_DOUBLE((double) v
->i8
); break;
150 case PSI_T_UINT8
: RETVAL_DOUBLE((double) v
->u8
); break;
151 case PSI_T_INT16
: RETVAL_DOUBLE((double) v
->i16
); break;
152 case PSI_T_UINT16
: RETVAL_DOUBLE((double) v
->u16
); break;
153 case PSI_T_INT32
: RETVAL_DOUBLE((double) v
->i32
); break;
154 case PSI_T_UINT32
: RETVAL_DOUBLE((double) v
->u32
); break;
155 case PSI_T_INT64
: RETVAL_DOUBLE((double) v
->i64
); break;
156 case PSI_T_UINT64
: RETVAL_DOUBLE((double) v
->u64
); break;
157 EMPTY_SWITCH_DEFAULT_CASE();
161 static inline impl_val
*psi_val_floatval(impl_val
*tmp
, token_t real_type
, double floatval
) {
163 case PSI_T_INT8
: tmp
->i8
= floatval
; break;
164 case PSI_T_UINT8
: tmp
->u8
= floatval
; break;
165 case PSI_T_INT16
: tmp
->i16
= floatval
; break;
166 case PSI_T_UINT16
: tmp
->u16
= floatval
; break;
167 case PSI_T_INT32
: tmp
->i32
= floatval
; break;
168 case PSI_T_UINT32
: tmp
->u32
= floatval
; break;
169 case PSI_T_INT64
: tmp
->i64
= floatval
; break;
170 case PSI_T_UINT64
: tmp
->u64
= floatval
; break;
171 case PSI_T_FLOAT
: tmp
->fval
= floatval
; break;
172 case PSI_T_DOUBLE
: tmp
->dval
= floatval
; break;
173 #ifdef HAVE_LONG_DOUBLE
174 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= floatval
; break;
176 EMPTY_SWITCH_DEFAULT_CASE();
182 impl_val
*psi_let_floatval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
185 token_t real_type
= type
? real_decl_type(type
)->type
: PSI_T_DOUBLE
;
187 if (iarg
->type
->type
== PSI_T_FLOAT
|| iarg
->type
->type
== PSI_T_DOUBLE
) {
188 floatval
= iarg
->val
.dval
;
190 floatval
= zval_get_double(iarg
->_zv
);
193 return psi_val_floatval(tmp
, real_type
, floatval
);
196 void psi_to_string(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
199 decl_var
*var
= set
->vars
->vars
[0];
200 token_t t
= real_decl_type(var
->arg
->type
)->type
;
203 case PSI_T_FLOAT
: RETVAL_DOUBLE((double) deref_impl_val(ret_val
, var
)->fval
); break;
204 case PSI_T_DOUBLE
: RETVAL_DOUBLE(deref_impl_val(ret_val
, var
)->dval
); break;
205 #ifdef HAVE_LONG_DOUBLE
206 case PSI_T_LONG_DOUBLE
: RETVAL_DOUBLE((double) deref_impl_val(ret_val
, var
)->ldval
); break;
209 if (!var
->arg
->var
->pointer_level
) {
210 RETVAL_STRINGL(&ret_val
->cval
, 1);
212 ret_val
= deref_impl_val(ret_val
, var
);
213 if (var
->arg
->var
->array_size
) {
214 str
= (char *) ret_val
;
220 zend_long n
= psi_long_num_exp(set
->num
, set
->outer
.val
);
221 RETVAL_STRINGL(str
, n
);
226 RETVAL_EMPTY_STRING();
232 convert_to_string(return_value
);
235 impl_val
*psi_let_strval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
237 if (iarg
->type
->type
== PSI_T_STRING
) {
238 if (iarg
->val
.zend
.str
) {
239 tmp
->ptr
= estrndup(iarg
->val
.zend
.str
->val
, iarg
->val
.zend
.str
->len
);
245 zend_string
*zs
= zval_get_string(iarg
->_zv
);
246 tmp
->ptr
= estrdup(zs
->val
);
248 zend_string_release(zs
);
254 impl_val
*psi_let_pathval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
256 tmp
= psi_let_strval(tmp
, type
, iarg
, to_free
);
257 if (SUCCESS
!= php_check_open_basedir(tmp
->ptr
)) {
259 return *to_free
= NULL
;
264 impl_val
*psi_let_strlen(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
266 if (iarg
->type
->type
== PSI_T_STRING
) {
267 if (iarg
->val
.zend
.str
) {
268 tmp
->lval
= iarg
->val
.zend
.str
->len
;
273 zend_string
*zs
= zval_get_string(iarg
->_zv
);
275 zend_string_release(zs
);
281 static impl_val
*iterate(impl_val
*val
, size_t size
, unsigned i
, impl_val
*tmp
)
283 memset(tmp
, 0, sizeof(*tmp
));
284 memcpy(tmp
, ((void*) val
) + size
* i
, size
);
288 void psi_from_zval_ex(impl_val
**ptr
, decl_arg
*spec
, token_t cast
, zval
*zv
, void **tmp
)
290 decl_type
*real
= real_decl_type(spec
->type
);
291 impl_val
*val
= *ptr
;
293 switch (real
->type
) {
298 val
->i8
= zval_get_long(zv
);
301 val
->u8
= zval_get_long(zv
);
304 val
->i16
= zval_get_long(zv
);
307 val
->u16
= zval_get_long(zv
);
310 val
->i32
= zval_get_long(zv
);
313 val
->u32
= zval_get_long(zv
);
316 val
->i64
= zval_get_long(zv
);
319 val
->u64
= zval_get_long(zv
);
322 val
->fval
= zval_get_double(zv
);
325 val
->dval
= zval_get_double(zv
);
327 #ifdef HAVE_LONG_DOUBLE
328 case PSI_T_LONG_DOUBLE
:
329 val
->ldval
= zval_get_double(zv
);
333 val
->ival
= zval_get_long(zv
);
336 *tmp
= *ptr
= psi_array_to_struct(real
->strct
, HASH_OF(zv
));
341 void psi_from_zval(impl_val
*mem
, decl_arg
*spec
, zval
*zv
, void **tmp
)
343 decl_type
*type
= real_decl_type(spec
->type
);
345 switch (type
->type
) {
347 mem
->fval
= (float) zval_get_double(zv
);
350 mem
->dval
= zval_get_double(zv
);
355 if (spec
->var
->pointer_level
) {
356 zend_string
*zs
= zval_get_string(zv
);
357 *tmp
= mem
->ptr
= estrndup(zs
->val
, zs
->len
);
358 zend_string_release(zs
);
363 mem
->zend
.lval
= zval_get_long(zv
);
368 void *psi_array_to_struct(decl_struct
*s
, HashTable
*arr
)
371 char *mem
= ecalloc(1, s
->size
+ s
->args
->count
* sizeof(void *));
373 if (arr
) for (i
= 0; i
< s
->args
->count
; ++i
) {
374 decl_arg
*darg
= s
->args
->args
[i
];
375 zval
*entry
= zend_hash_str_find_ind(arr
, darg
->var
->name
, strlen(darg
->var
->name
));
381 memset(&tmp
, 0, sizeof(tmp
));
382 psi_from_zval(&val
, darg
, entry
, &tmp
);
383 memcpy(mem
+ darg
->layout
->pos
, &val
, darg
->layout
->len
);
385 ((void **)(mem
+ s
->size
))[j
++] = tmp
;
392 void psi_to_recursive(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
394 set
->outer
.set
->func
->handler(return_value
, set
, r_val
);
397 void psi_to_array(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
400 decl_var
*var
= set
->vars
->vars
[0];
401 token_t t
= real_decl_type(var
->arg
->type
)->type
;
402 impl_val tmp
, *ret_val
= deref_impl_val(r_val
, var
);
404 if ((intptr_t) ret_val
<= (intptr_t) 0) {
408 array_init(return_value
);
410 if (t
== PSI_T_STRUCT
) {
411 // decl_struct *s = real_decl_type(var->arg->type)->strct;
413 if (set
->inner
&& set
->inner
->count
) {
414 /* explicit member casts */
415 for (i
= 0; i
< set
->inner
->count
; ++i
) {
416 set_value
*sub_set
= set
->inner
->vals
[i
];
417 decl_var
*sub_var
= sub_set
->vars
->vars
[0];
419 sub_set
->outer
.val
= ret_val
;
422 impl_val
*tmp
= NULL
, *val
;
425 val
= struct_member_ref(sub_var
->arg
, ret_val
, &tmp
);
426 sub_set
->func
->handler(&ztmp
, sub_set
, val
);
427 add_assoc_zval(return_value
, sub_var
->name
, &ztmp
);
438 if (var
->arg
->var
->array_size
) {
439 /* to_array(foo[NUMBER]) */
440 for (i
= 0; i
< var
->arg
->var
->array_size
; ++i
) {
441 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
> 1 ? PSI_T_POINTER
: t
);
442 impl_val
*ptr
= iterate(ret_val
, size
, i
, &tmp
);
447 ZVAL_DOUBLE(&ele
, (double) ptr
->fval
);
450 ZVAL_DOUBLE(&ele
, ptr
->dval
);
453 ZVAL_LONG(&ele
, ptr
->lval
);
457 add_next_index_zval(return_value
, &ele
);
460 } else if (set
->num
) {
461 /* to_array(arr_var, num_expr, to_int(*arr_var)) */
464 zend_long i
, n
= psi_long_num_exp(set
->num
, set
->outer
.val
);
465 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
? PSI_T_POINTER
: t
);
466 set_value
*sub_set
= set
->inner
->vals
[0];
468 sub_set
->outer
.val
= set
->outer
.val
;
469 for (i
= 0; i
< n
; ++i
) {
470 ptr
= (char *) ret_val
->ptr
+ i
* size
;
471 sub_set
->func
->handler(&ele
, sub_set
, (void *) ptr
);
472 add_next_index_zval(return_value
, &ele
);
475 /* to_array(arr_var, to_int(*arr_var)) */
477 char *ptr
= ret_val
->ptr
;
478 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
? PSI_T_POINTER
: t
);
479 set_value
*sub_set
= set
->inner
->vals
[0];
481 sub_set
->outer
.val
= set
->outer
.val
;
482 while (*(void **) ptr
) {
483 sub_set
->func
->handler(&ele
, sub_set
, (void *) ptr
);
484 add_next_index_zval(return_value
, &ele
);
490 impl_val
*psi_let_arrval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
492 decl_type
*real
= real_decl_type(type
);
495 if (iarg
->type
->type
!= PSI_T_ARRAY
) {
496 SEPARATE_ARG_IF_REF(iarg
->_zv
);
497 convert_to_array(iarg
->_zv
);
499 arr
= HASH_OF(iarg
->_zv
);
501 switch (real
->type
) {
503 *to_free
= tmp
= psi_array_to_struct(real
->strct
, arr
);
505 EMPTY_SWITCH_DEFAULT_CASE();
511 void psi_to_object(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
513 decl_var
*var
= set
->vars
->vars
[0];
514 impl_val
*ret_val
= deref_impl_val(r_val
, var
);
517 if ((intptr_t) ret_val
->ptr
> (intptr_t) 0) {
518 object_init_ex(return_value
, psi_object_get_class_entry());
519 obj
= PSI_OBJ(return_value
, NULL
);
520 obj
->data
= ret_val
->ptr
;
526 impl_val
*psi_let_objval(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
)
530 if (Z_TYPE_P(iarg
->_zv
) != IS_OBJECT
531 || !instanceof_function(Z_OBJCE_P(iarg
->_zv
), psi_object_get_class_entry())) {
535 obj
= PSI_OBJ(iarg
->_zv
, NULL
);
536 tmp
->ptr
= obj
->data
;