11 void psi_to_void(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
16 void psi_to_bool(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
18 psi_to_int(return_value
, set
, ret_val
);
19 convert_to_boolean(return_value
);
22 void psi_to_int(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
24 decl_var
*var
= set
->vars
->vars
[0];
25 token_t t
= real_decl_type(var
->arg
->type
)->type
;
26 impl_val
*v
= deref_impl_val(ret_val
, var
);
30 RETVAL_DOUBLE((double) v
->fval
);
31 convert_to_long(return_value
);
34 RETVAL_DOUBLE(v
->dval
);
35 convert_to_long(return_value
);
53 #if UINT32_MAX >= ZEND_LONG_MAX
54 if (v
->u32
> ZEND_LONG_MAX
) {
57 RETVAL_STRING(zend_print_ulong_to_buf(&d
[10], v
->u32
));
61 #if UINT32_MAX >= ZEND_LONG_MAX
69 if (v
->u64
> ZEND_LONG_MAX
) {
72 RETVAL_STRING(zend_print_ulong_to_buf(&d
[22], v
->u64
));
77 EMPTY_SWITCH_DEFAULT_CASE();
81 void psi_to_double(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
83 decl_var
*var
= set
->vars
->vars
[0];
84 token_t t
= real_decl_type(var
->arg
->type
)->type
;
85 impl_val
*v
= deref_impl_val(ret_val
, var
);
89 RETVAL_DOUBLE((double) v
->fval
);
92 RETVAL_DOUBLE(v
->dval
);
94 #ifdef HAVE_LONG_DOUBLE
95 case PSI_T_LONG_DOUBLE
:
96 RETVAL_DOUBLE((double) v
->ldval
);
100 RETVAL_DOUBLE((double) v
->i8
);
103 RETVAL_DOUBLE((double) v
->u8
);
106 RETVAL_DOUBLE((double) v
->i16
);
109 RETVAL_DOUBLE((double) v
->u16
);
112 RETVAL_DOUBLE((double) v
->i32
);
115 RETVAL_DOUBLE((double) v
->u32
);
118 RETVAL_DOUBLE((double) v
->i64
);
121 RETVAL_DOUBLE((double) v
->u64
);
123 EMPTY_SWITCH_DEFAULT_CASE();
127 void psi_to_string(zval
*return_value
, set_value
*set
, impl_val
*ret_val
)
130 decl_var
*var
= set
->vars
->vars
[0];
131 token_t t
= real_decl_type(var
->arg
->type
)->type
;
135 RETVAL_DOUBLE((double) deref_impl_val(ret_val
, var
)->fval
);
138 RETVAL_DOUBLE(deref_impl_val(ret_val
, var
)->dval
);
140 #ifdef HAVE_LONG_DOUBLE
141 case PSI_T_LONG_DOUBLE
:
142 RETVAL_DOUBLE((double) deref_impl_val(ret_val
, var
)->ldval
);
146 if (!var
->arg
->var
->pointer_level
) {
147 RETVAL_STRINGL(&ret_val
->cval
, 1);
149 ret_val
= deref_impl_val(ret_val
, var
);
150 if (var
->arg
->var
->array_size
) {
151 str
= (char *) ret_val
;
157 zend_long n
= psi_long_num_exp(set
->num
, set
->outer
.val
);
158 RETVAL_STRINGL(str
, n
);
163 RETVAL_EMPTY_STRING();
168 convert_to_string(return_value
);
172 static impl_val
*iterate(impl_val
*val
, size_t size
, unsigned i
, impl_val
*tmp
)
174 memset(tmp
, 0, sizeof(*tmp
));
175 memcpy(tmp
, ((void*) val
) + size
* i
, size
);
179 void psi_from_zval(impl_val
*mem
, decl_arg
*spec
, zval
*zv
, void **tmp
)
181 decl_type
*type
= real_decl_type(spec
->type
);
183 switch (type
->type
) {
185 mem
->fval
= (float) zval_get_double(zv
);
188 mem
->dval
= zval_get_double(zv
);
193 if (spec
->var
->pointer_level
) {
194 zend_string
*zs
= zval_get_string(zv
);
195 *tmp
= mem
->ptr
= estrndup(zs
->val
, zs
->len
);
196 zend_string_release(zs
);
201 mem
->zend
.lval
= zval_get_long(zv
);
206 void *psi_array_to_struct(decl_struct
*s
, HashTable
*arr
)
209 char *mem
= ecalloc(1, s
->size
+ s
->args
->count
* sizeof(void *));
211 if (arr
) for (i
= 0; i
< s
->args
->count
; ++i
) {
212 decl_arg
*darg
= s
->args
->args
[i
];
213 zval
*entry
= zend_hash_str_find_ind(arr
, darg
->var
->name
, strlen(darg
->var
->name
));
219 memset(&tmp
, 0, sizeof(tmp
));
220 psi_from_zval(&val
, darg
, entry
, &tmp
);
221 memcpy(mem
+ darg
->layout
->pos
, &val
, darg
->layout
->len
);
223 ((void **)(mem
+ s
->size
))[j
++] = tmp
;
230 void psi_to_recursive(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
232 set
->outer
.set
->func
->handler(return_value
, set
, r_val
);
235 void psi_to_array(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
238 decl_var
*var
= set
->vars
->vars
[0];
239 token_t t
= real_decl_type(var
->arg
->type
)->type
;
240 impl_val tmp
, *ret_val
= deref_impl_val(r_val
, var
);
242 if ((intptr_t) ret_val
<= (intptr_t) 0) {
246 array_init(return_value
);
248 if (t
== PSI_T_STRUCT
) {
249 // decl_struct *s = real_decl_type(var->arg->type)->strct;
252 /* explicit member casts */
253 for (i
= 0; i
< set
->count
; ++i
) {
254 set_value
*sub_set
= set
->inner
[i
];
255 decl_var
*sub_var
= sub_set
->vars
->vars
[0];
257 sub_set
->outer
.val
= ret_val
;
260 impl_val
*tmp
= NULL
, *val
;
263 val
= struct_member_ref(sub_var
->arg
, ret_val
, &tmp
);
264 sub_set
->func
->handler(&ztmp
, sub_set
, val
);
265 add_assoc_zval(return_value
, sub_var
->name
, &ztmp
);
276 if (var
->arg
->var
->array_size
) {
277 /* to_array(foo[NUMBER]) */
278 for (i
= 0; i
< var
->arg
->var
->array_size
; ++i
) {
279 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
> 1 ? PSI_T_POINTER
: t
);
280 impl_val
*ptr
= iterate(ret_val
, size
, i
, &tmp
);
285 ZVAL_DOUBLE(&ele
, (double) ptr
->fval
);
288 ZVAL_DOUBLE(&ele
, ptr
->dval
);
291 ZVAL_LONG(&ele
, ptr
->lval
);
295 add_next_index_zval(return_value
, &ele
);
298 } else if (set
->num
) {
299 /* to_array(arr_var, num_expr, to_int(*arr_var)) */
302 zend_long i
, n
= psi_long_num_exp(set
->num
, set
->outer
.val
);
303 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
? PSI_T_POINTER
: t
);
304 set_value
*sub_set
= set
->inner
[0];
306 sub_set
->outer
.val
= set
->outer
.val
;
307 for (i
= 0; i
< n
; ++i
) {
308 ptr
= (char *) ret_val
->ptr
+ i
* size
;
309 sub_set
->func
->handler(&ele
, sub_set
, (void *) ptr
);
310 add_next_index_zval(return_value
, &ele
);
313 /* to_array(arr_var, to_int(*arr_var)) */
315 char *ptr
= ret_val
->ptr
;
316 size_t size
= psi_t_size(var
->arg
->var
->pointer_level
? PSI_T_POINTER
: t
);
317 set_value
*sub_set
= set
->inner
[0];
319 sub_set
->outer
.val
= set
->outer
.val
;
320 while (*(void **) ptr
) {
321 sub_set
->func
->handler(&ele
, sub_set
, (void *) ptr
);
322 add_next_index_zval(return_value
, &ele
);
328 void psi_to_object(zval
*return_value
, set_value
*set
, impl_val
*r_val
)
330 decl_var
*var
= set
->vars
->vars
[0];
331 impl_val
*ret_val
= deref_impl_val(r_val
, var
);
334 if ((intptr_t) ret_val
->ptr
> (intptr_t) 0) {
335 object_init_ex(return_value
, psi_object_get_class_entry());
336 obj
= PSI_OBJ(return_value
, NULL
);
337 obj
->data
= ret_val
->ptr
;