1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
29 # include "php_config.h"
37 #include "Zend/zend_interfaces.h"
38 #include "ext/spl/spl_iterators.h"
40 zend_long
psi_zval_count(zval
*zvalue
)
42 /* mimic PHP count() */
46 switch (Z_TYPE_P(zvalue
)) {
54 count
= zend_array_count(Z_ARRVAL_P(zvalue
));
58 if (Z_OBJ_HT_P(zvalue
)->count_elements
) {
59 if (SUCCESS
== Z_OBJ_HT_P(zvalue
)->count_elements(Z_OBJ_P(zvalue
), &count
)) {
64 if (instanceof_function(Z_OBJCE_P(zvalue
), spl_ce_Countable
)) {
65 zend_call_method_with_0_params(Z_OBJ_P(zvalue
), NULL
, NULL
, "count", &retval
);
66 if (Z_TYPE(retval
) != IS_UNDEF
) {
67 count
= zval_get_long(&retval
);
68 zval_ptr_dtor(&retval
);
77 int psi_internal_type(struct psi_impl_type
*type
)
96 zend_internal_arg_info
*psi_internal_arginfo(struct psi_impl
*impl
)
98 size_t i
= 0, argc
= psi_plist_count(impl
->func
->args
);
99 zend_internal_arg_info
*aip
;
100 zend_internal_function_info
*fi
;
101 struct psi_impl_arg
*iarg
;
102 zend_type rtyp
= ZEND_TYPE_INIT_CODE(psi_internal_type(impl
->func
->return_type
), 1, _ZEND_ARG_INFO_FLAGS(impl
->func
->return_reference
, impl
->func
->vararg
));
104 aip
= pecalloc(argc
+ 1 + !!impl
->func
->vararg
, sizeof(*aip
), 1);
106 fi
= (zend_internal_function_info
*) &aip
[0];
107 fi
->required_num_args
= psi_impl_num_min_args(impl
);
110 if (impl
->func
->vararg
) {
111 struct psi_impl_arg
*vararg
= impl
->func
->vararg
;
112 zend_internal_arg_info
*ai
= &aip
[argc
];
113 zend_type atyp
= ZEND_TYPE_INIT_CODE(psi_internal_type(vararg
->type
), 1, _ZEND_ARG_INFO_FLAGS(vararg
->var
->reference
, 1));
115 ai
->name
= &vararg
->var
->name
->val
[1];
119 while (psi_plist_get(impl
->func
->args
, i
++, &iarg
)) {
120 zend_internal_arg_info
*ai
= &aip
[i
];
121 zend_type atyp
= ZEND_TYPE_INIT_CODE(psi_internal_type(iarg
->type
), 1, _ZEND_ARG_INFO_FLAGS(iarg
->var
->reference
, 0));
123 ai
->name
= &iarg
->var
->name
->val
[1];
133 void psi_set_void(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
141 impl_val
*psi_let_void(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
147 * set $ivar = zval(dvar)
149 void psi_set_zval(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
) {
150 RETVAL_ZVAL(ret_val
->ptr
, 1, 0);
154 * let dvar = zval($ivar)
156 impl_val
*psi_let_zval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
158 *to_free
= tmp
->ptr
= emalloc(sizeof(zval
));
159 ZVAL_COPY_VALUE(tmp
->ptr
, zvalue
);
164 * return to_bool(dvar)
166 void psi_set_to_bool(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
168 psi_set_to_int(return_value
, set
, ret_val
, frame
);
169 convert_to_boolean(return_value
);
172 static inline impl_val
*psi_val_boolval(impl_val
*tmp
, token_t real_type
, zend_bool boolval
) {
174 case PSI_T_INT8
: tmp
->i8
= boolval
; break;
175 case PSI_T_UINT8
: tmp
->u8
= boolval
; break;
176 case PSI_T_INT16
: tmp
->i16
= boolval
; break;
177 case PSI_T_UINT16
: tmp
->u16
= boolval
; break;
178 case PSI_T_INT32
: tmp
->i32
= boolval
; break;
179 case PSI_T_UINT32
: tmp
->u32
= boolval
; break;
180 case PSI_T_INT64
: tmp
->i64
= boolval
; break;
181 case PSI_T_UINT64
: tmp
->u64
= boolval
; break;
183 case PSI_T_INT128
: tmp
->i128
= boolval
; break;
184 case PSI_T_UINT128
: tmp
->u128
= boolval
; break;
186 case PSI_T_FLOAT
: tmp
->fval
= boolval
; break;
187 case PSI_T_DOUBLE
: tmp
->dval
= boolval
; break;
188 #ifdef HAVE_LONG_DOUBLE
189 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= boolval
; break;
191 EMPTY_SWITCH_DEFAULT_CASE();
197 * let dvar = boolval($ivar)
199 impl_val
*psi_let_boolval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
202 token_t real_type
= spec
? psi_decl_type_get_real(spec
->type
)->type
: PSI_T_UINT8
;
204 if (ival
&& impl_type
== PSI_T_BOOL
) {
205 boolval
= ival
->zend
.bval
;
207 boolval
= zend_is_true(zvalue
);
210 return psi_val_boolval(tmp
, real_type
, boolval
);
214 * set $ivar = to_int(*dvar)
216 void psi_set_to_int(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
218 struct psi_decl_var
*var
= psi_set_exp_get_decl_var(set
);
219 token_t t
= psi_decl_type_get_real(var
->arg
->type
)->type
;
220 impl_val
*v
= deref_impl_val(ret_val
, var
);
223 case PSI_T_INT8
: RETVAL_LONG(v
->i8
); break;
224 case PSI_T_UINT8
: RETVAL_LONG(v
->u8
); break;
225 case PSI_T_INT16
: RETVAL_LONG(v
->i16
); break;
226 case PSI_T_UINT16
: RETVAL_LONG(v
->u16
); break;
228 case PSI_T_INT32
: RETVAL_LONG(v
->i32
); break;
229 case PSI_T_UINT32
: RETVAL_LONG(v
->u32
); break;
230 case PSI_T_INT64
: RETVAL_LONG(v
->i64
); break;
231 case PSI_T_UINT64
: RETVAL_LONG_DOUBLE_STR(v
->u64
,); break;
233 case PSI_T_INT128
: RETVAL_LONG_DOUBLE_STR(v
->i128
, is_signed
=true); break;
234 case PSI_T_UINT128
: RETVAL_LONG_DOUBLE_STR(v
->u128
,); break;
237 RETVAL_DOUBLE((double) v
->fval
);
238 convert_to_long(return_value
);
241 RETVAL_DOUBLE(v
->dval
);
242 convert_to_long(return_value
);
244 #ifdef HAVE_LONG_DOUBLE
245 case PSI_T_LONG_DOUBLE
:
246 RETVAL_DOUBLE((double) v
->ldval
);
247 convert_to_long(return_value
);
250 EMPTY_SWITCH_DEFAULT_CASE();
254 static inline impl_val
*psi_val_intval(impl_val
*tmp
, token_t real_type
, zend_long intval
) {
256 case PSI_T_INT8
: tmp
->i8
= intval
; break;
257 case PSI_T_UINT8
: tmp
->u8
= intval
; break;
258 case PSI_T_INT16
: tmp
->i16
= intval
; break;
259 case PSI_T_UINT16
: tmp
->u16
= intval
; break;
261 case PSI_T_INT32
: tmp
->i32
= intval
; break;
262 case PSI_T_UINT32
: tmp
->u32
= intval
; break;
263 case PSI_T_INT64
: tmp
->i64
= intval
; break;
264 case PSI_T_UINT64
: tmp
->u64
= intval
; break;
266 case PSI_T_INT128
: tmp
->i128
= intval
; break;
267 case PSI_T_UINT128
: tmp
->u128
= intval
; break;
269 case PSI_T_FLOAT
: tmp
->fval
= intval
; break;
270 case PSI_T_DOUBLE
: tmp
->dval
= intval
; break;
271 #ifdef HAVE_LONG_DOUBLE
272 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= intval
; break;
274 EMPTY_SWITCH_DEFAULT_CASE();
281 static void psi_strto_i128(char *ptr
, char *end
, token_t real_type
, impl_val
*val
) {
282 unsigned __int128 i
= 0;
283 bool oct
= false, hex
= false, sign
= false;
287 } else if (*ptr
== '-') {
290 } else if (*ptr
== '\\') {
296 case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':
310 case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':
320 case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
325 i
+= 10 + (*ptr
- 'a');
327 case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
332 i
+= 10 + (*ptr
- 'A');
336 zend_error(E_WARNING
, "A non well formed numeric value encountered");
343 if (real_type
== PSI_T_UINT128
) {
360 * let dvar = intval($ivar)
362 impl_val
*psi_let_intval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
365 token_t real_type
= spec
? psi_decl_type_get_real(spec
->type
)->type
: PSI_T_INT64
;
368 if (ival
&& impl_type
== PSI_T_INT
) {
369 intval
= ival
->zend
.lval
;
371 } else if ((real_type
== PSI_T_UINT128
|| real_type
== PSI_T_INT128
) &&
372 !((Z_TYPE_P(zvalue
) == IS_TRUE
|| Z_TYPE_P(zvalue
) == IS_FALSE
|| Z_TYPE_P(zvalue
) == IS_LONG
|| Z_TYPE_P(zvalue
) == IS_DOUBLE
|| Z_TYPE_P(zvalue
) == IS_NULL
))) {
373 zend_string
*str
= zval_get_string(zvalue
);
374 psi_strto_i128(str
->val
, str
->val
+ str
->len
, real_type
, tmp
);
375 zend_string_release(str
);
379 intval
= zval_get_long(zvalue
);
382 return psi_val_intval(tmp
, real_type
, intval
);
386 * set $ivar = to_float(dvar)
388 void psi_set_to_float(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
390 struct psi_decl_var
*var
= psi_set_exp_get_decl_var(set
);
391 token_t t
= psi_decl_type_get_real(var
->arg
->type
)->type
;
392 impl_val
*v
= deref_impl_val(ret_val
, var
);
395 case PSI_T_FLOAT
: RETVAL_DOUBLE((double) v
->fval
); break;
396 case PSI_T_DOUBLE
: RETVAL_DOUBLE(v
->dval
); break;
397 #ifdef HAVE_LONG_DOUBLE
398 case PSI_T_LONG_DOUBLE
: RETVAL_DOUBLE((double) v
->ldval
); break;
400 case PSI_T_INT8
: RETVAL_DOUBLE((double) v
->i8
); break;
401 case PSI_T_UINT8
: RETVAL_DOUBLE((double) v
->u8
); break;
402 case PSI_T_INT16
: RETVAL_DOUBLE((double) v
->i16
); break;
403 case PSI_T_UINT16
: RETVAL_DOUBLE((double) v
->u16
); break;
404 case PSI_T_INT32
: RETVAL_DOUBLE((double) v
->i32
); break;
405 case PSI_T_UINT32
: RETVAL_DOUBLE((double) v
->u32
); break;
406 case PSI_T_INT64
: RETVAL_DOUBLE((double) v
->i64
); break;
407 case PSI_T_UINT64
: RETVAL_DOUBLE((double) v
->u64
); break;
409 case PSI_T_INT128
: RETVAL_DOUBLE((double) v
->i128
); break;
410 case PSI_T_UINT128
: RETVAL_DOUBLE((double) v
->u128
); break;
412 EMPTY_SWITCH_DEFAULT_CASE();
416 static inline impl_val
*psi_val_floatval(impl_val
*tmp
, token_t real_type
, double floatval
) {
418 case PSI_T_INT8
: tmp
->i8
= floatval
; break;
419 case PSI_T_UINT8
: tmp
->u8
= floatval
; break;
420 case PSI_T_INT16
: tmp
->i16
= floatval
; break;
421 case PSI_T_UINT16
: tmp
->u16
= floatval
; break;
422 case PSI_T_INT32
: tmp
->i32
= floatval
; break;
423 case PSI_T_UINT32
: tmp
->u32
= floatval
; break;
424 case PSI_T_INT64
: tmp
->i64
= floatval
; break;
425 case PSI_T_UINT64
: tmp
->u64
= floatval
; break;
427 case PSI_T_INT128
: tmp
->i128
= floatval
; break;
428 case PSI_T_UINT128
: tmp
->u128
= floatval
; break;
430 case PSI_T_FLOAT
: tmp
->fval
= floatval
; break;
431 case PSI_T_DOUBLE
: tmp
->dval
= floatval
; break;
432 #ifdef HAVE_LONG_DOUBLE
433 case PSI_T_LONG_DOUBLE
: tmp
->ldval
= floatval
; break;
435 EMPTY_SWITCH_DEFAULT_CASE();
442 * let dvar = floatval($ivar)
444 impl_val
*psi_let_floatval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
447 token_t real_type
= spec
? psi_decl_type_get_real(spec
->type
)->type
: PSI_T_DOUBLE
;
449 if (ival
&& (impl_type
== PSI_T_FLOAT
|| impl_type
== PSI_T_DOUBLE
)) {
450 floatval
= ival
->dval
;
452 floatval
= zval_get_double(zvalue
);
455 return psi_val_floatval(tmp
, real_type
, floatval
);
459 * set $ivar = to_string(dvar)
461 void psi_set_to_string(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
463 struct psi_decl_var
*var
= psi_set_exp_get_decl_var(set
);
464 impl_val
*ptr
= deref_impl_val(ret_val
, var
);
467 if (var
->arg
->var
->array_size
&& var
->arg
->var
->pointer_level
== 1) {
476 RETVAL_EMPTY_STRING();
481 * set $ivar = to_string(dvar, num_exp)
483 void psi_set_to_stringl(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*ret_val
, struct psi_call_frame
*frame
)
485 struct psi_decl_var
*var
= psi_set_exp_get_decl_var(set
);
486 char *str
= deref_impl_val(ret_val
, var
)->ptr
;
489 struct psi_set_exp
*sub_exp
;
491 psi_plist_get(set
->inner
, 0, &sub_exp
);
492 RETVAL_STRINGL(str
, psi_num_exp_get_long(sub_exp
->data
.num
, frame
, NULL
));
494 RETVAL_EMPTY_STRING();
499 * let dvar = strval($ivar)
501 impl_val
*psi_let_strval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
503 if (ival
&& impl_type
== PSI_T_STRING
) {
504 if (ival
->zend
.str
) {
505 tmp
->ptr
= ival
->zend
.str
->val
;
510 zend_string
*zs
= zval_get_string(zvalue
);
511 tmp
->ptr
= estrdup(zs
->val
);
513 zend_string_release(zs
);
520 * let dvar = pathval($ivar)
522 impl_val
*psi_let_pathval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
524 tmp
= psi_let_strval(tmp
, spec
, impl_type
, ival
, zvalue
, to_free
);
525 if (SUCCESS
!= php_check_open_basedir(tmp
->ptr
)) {
528 return *to_free
= NULL
;
534 * let dvar = strlen($ivar)
536 impl_val
*psi_let_strlen(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
538 if (ival
&& impl_type
== PSI_T_STRING
) {
539 if (ival
->zend
.str
) {
540 tmp
->u64
= ival
->zend
.str
->len
;
545 zend_string
*zs
= zval_get_string(zvalue
);
547 zend_string_release(zs
);
551 psi_calc_cast(PSI_T_UINT64
, tmp
, psi_decl_type_get_real(spec
->type
)->type
, tmp
);
557 static impl_val
*iterate(impl_val
*val
, size_t size
, unsigned i
, impl_val
*tmp
)
559 memset(tmp
, 0, sizeof(*tmp
));
560 memcpy(tmp
, ((char *) val
) + size
* i
, size
);
566 * set $ivar = to_array(dvar,
567 * $foo = to_int(d_foo),
568 * $bar = to_string(d_bar),
569 * $baz = to_array(*d_next, ...)
571 void psi_set_to_recursive(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*r_val
, struct psi_call_frame
*frame
) {
572 set
->outer
->data
.func
->handler(return_value
, set
, r_val
, frame
);
576 * set $ivar = to_array(dvar, to_string(*dvar));
578 void psi_set_to_array_simple(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*r_val
, struct psi_call_frame
*frame
)
580 struct psi_set_exp
*sub_exp
;
581 struct psi_decl_var
*var
;
586 array_init(return_value
);
588 var
= psi_set_exp_get_decl_var(set
);
589 ret_val
= deref_impl_val(r_val
, var
);
590 if ((intptr_t) ret_val
<= (intptr_t) 0) {
594 psi_plist_get(set
->inner
, 0, &sub_exp
);
596 size
= psi_decl_arg_get_size(var
->arg
);
597 for (ptr
= ret_val
->ptr
; *(void **) ptr
; ptr
+= size
) {
601 sub_exp
->data
.func
->handler(&ele
, sub_exp
, (void *) ptr
, frame
);
602 add_next_index_zval(return_value
, &ele
);
607 * set $ivar = to_array(dvar, num_exp, to_string(*dvar));
609 void psi_set_to_array_counted(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*r_val
, struct psi_call_frame
*frame
)
611 struct psi_set_exp
*sub_exp
;
612 struct psi_decl_var
*var
;
618 array_init(return_value
);
620 var
= psi_set_exp_get_decl_var(set
);
621 ret_val
= deref_impl_val(r_val
, var
);
622 if ((intptr_t) ret_val
<= (intptr_t) 0) {
626 psi_plist_get(set
->inner
, 0, &sub_exp
);
627 count
= psi_num_exp_get_long(sub_exp
->data
.num
, frame
, NULL
);
628 psi_plist_get(set
->inner
, 1, &sub_exp
);
630 size
= psi_decl_var_get_size(psi_set_exp_get_decl_var(sub_exp
));
631 for (ptr
= (char *) ret_val
; 0 < count
--; ptr
+= size
) {
635 sub_exp
->data
.func
->handler(&ele
, sub_exp
, (void *) &ptr
, frame
);
636 add_next_index_zval(return_value
, &ele
);
643 * set $ivar = to_array(dvar,
644 * $foo = to_int(d_foo),
645 * $bar = to_string(d_bar));
647 void psi_set_to_array(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*r_val
, struct psi_call_frame
*frame
)
649 struct psi_set_exp
*sub_exp
;
650 struct psi_decl_var
*var
;
654 array_init(return_value
);
656 var
= psi_set_exp_get_decl_var(set
);
657 ret_val
= deref_impl_val(r_val
, var
);
658 if ((intptr_t) ret_val
<= (intptr_t) 0) {
662 while (psi_plist_get(set
->inner
, i
++, &sub_exp
)) {
664 struct psi_decl_var
*dvar
= psi_set_exp_get_decl_var(sub_exp
);
665 struct psi_impl_var
*ivar
= psi_set_exp_get_impl_var(sub_exp
);
666 struct psi_call_frame_symbol
*sym
;
668 sym
= psi_call_frame_fetch_symbol(frame
, dvar
);
669 sym
->ptr
= ((char *) ret_val
) + dvar
->arg
->layout
->pos
;
672 psi_set_exp_exec_ex(sub_exp
, &ele
, sym
->ptr
, frame
);
673 add_assoc_zval_ex(return_value
, ivar
->name
->val
+ 1, ivar
->name
->len
- 1, &ele
);
678 * let dvar = count($ivar)
680 impl_val
*psi_let_count(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
682 return psi_val_intval(tmp
, psi_decl_type_get_real(spec
->type
)->type
, psi_zval_count(zvalue
));
686 * set $ivar = to_object(dvar)
688 void psi_set_to_object(zval
*return_value
, struct psi_set_exp
*set
, impl_val
*r_val
, struct psi_call_frame
*frame
)
690 struct psi_decl_var
*var
= psi_set_exp_get_decl_var(set
);
691 impl_val
*ret_val
= deref_impl_val(r_val
, var
);
693 if ((intptr_t) ret_val
->ptr
> (intptr_t) 0) {
694 object_init_ex(return_value
, psi_object_get_class_entry());
695 PSI_OBJ(return_value
, NULL
)->data
= ret_val
->ptr
;
702 * let dvar = objval($ivar)
704 impl_val
*psi_let_objval(impl_val
*tmp
, struct psi_decl_arg
*spec
, token_t impl_type
, impl_val
*ival
, zval
*zvalue
, void **to_free
)
708 if (Z_TYPE_P(zvalue
) != IS_OBJECT
709 || !instanceof_function(Z_OBJCE_P(zvalue
), psi_object_get_class_entry())) {
713 obj
= PSI_OBJ(zvalue
, NULL
);
714 tmp
->ptr
= obj
->data
;