2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
19 #include "php_pq_object.h"
21 void *php_pq_object_create(zend_class_entry
*ce
, void *intern
, size_t obj_size
, zend_object_handlers
*oh
, HashTable
*ph
)
23 php_pq_object_t
*o
= ecalloc(1, obj_size
+ zend_object_properties_size(ce
));
25 zend_object_std_init(&o
->zo
, ce
);
26 object_properties_init(&o
->zo
, ce
);
31 zend_hash_init(&o
->gc
, 0, NULL
, NULL
, 0);
36 void php_pq_object_dtor(zend_object
*o
)
38 php_pq_object_t
*obj
= PHP_PQ_OBJ(NULL
, o
);
40 zend_hash_destroy(&obj
->gc
);
41 zend_object_std_dtor(o
);
44 void php_pq_object_to_zval(void *o
, zval
*zv
)
46 php_pq_object_t
*obj
= o
;
48 ZVAL_OBJ(zv
, &obj
->zo
);
52 void php_pq_object_to_zval_no_addref(void *o
, zval
*zv
)
54 php_pq_object_t
*obj
= o
;
56 ZVAL_OBJ(zv
, &obj
->zo
);
59 void php_pq_object_addref(void *o
)
61 php_pq_object_t
*obj
= o
;
65 ++GC_REFCOUNT(&obj
->zo
);
69 void php_pq_object_delref(void *o
)
71 php_pq_object_t
*obj
= o
;
74 /* this should gc immediately */
75 ZVAL_OBJ(&tmp
, &obj
->zo
);
79 struct apply_pi_to_ht_arg
{
81 php_pq_object_t
*pq_obj
;
85 static int apply_pi_to_ht(zval
*p
, void *a
)
87 zend_property_info
*pi
= Z_PTR_P(p
);
88 struct apply_pi_to_ht_arg
*arg
= a
;
91 php_pq_object_prophandler_t
*handler
;
93 if ((handler
= zend_hash_find_ptr(arg
->pq_obj
->prophandler
, pi
->name
)) && handler
->gc
) {
94 zval member
, return_value
;
96 ZVAL_STR(&member
, pi
->name
);
97 ZVAL_ARR(&return_value
, arg
->ht
);
98 handler
->gc(arg
->pq_obj
, &return_value
);
101 zval tmp_prop
, *property
= NULL
;
103 property
= php_pq_object_read_prop_80(&arg
->pq_obj
->zo
, pi
->name
, BP_VAR_R
, NULL
, &tmp_prop
);
104 zend_hash_update(arg
->ht
, pi
->name
, property
);
107 return ZEND_HASH_APPLY_KEEP
;
110 HashTable
*php_pq_object_debug_info_80(zend_object
*object
, int *temp
)
112 struct apply_pi_to_ht_arg arg
= {NULL
};
115 ALLOC_HASHTABLE(arg
.ht
);
116 ZEND_INIT_SYMTABLE(arg
.ht
);
118 arg
.pq_obj
= PHP_PQ_OBJ(NULL
, object
);
121 zend_hash_apply_with_argument(&arg
.pq_obj
->zo
.ce
->properties_info
, apply_pi_to_ht
, &arg
);
125 HashTable
*php_pq_object_debug_info_70(zval
*object
, int *temp
)
127 return php_pq_object_debug_info_80(Z_OBJ_P(object
), temp
);
130 HashTable
*php_pq_object_properties_80(zend_object
*object
)
132 struct apply_pi_to_ht_arg arg
= {NULL
};
134 arg
.ht
= zend_get_std_object_handlers()->get_properties(object
);
135 arg
.pq_obj
= PHP_PQ_OBJ(NULL
, object
);
138 zend_hash_apply_with_argument(&arg
.pq_obj
->zo
.ce
->properties_info
, apply_pi_to_ht
, &arg
);
143 HashTable
*php_pq_object_properties_70(zval
*object
)
145 return php_pq_object_properties_80(Z_OBJ_P(object
));
148 HashTable
*php_pq_object_get_gc_80(zend_object
*object
, zval
**table
, int *n
)
150 struct apply_pi_to_ht_arg arg
= {NULL
};
152 arg
.pq_obj
= PHP_PQ_OBJ(NULL
, object
);
153 arg
.ht
= &arg
.pq_obj
->gc
;
156 zend_hash_clean(arg
.ht
);
157 zend_hash_copy(arg
.ht
, zend_std_get_properties(object
), NULL
);
158 zend_hash_apply_with_argument(&arg
.pq_obj
->zo
.ce
->properties_info
, apply_pi_to_ht
, &arg
);
165 HashTable
*php_pq_object_get_gc_70(zval
*object
, zval
**table
, int *n
)
167 return php_pq_object_get_gc_80(Z_OBJ_P(object
), table
, n
);
170 zend_class_entry
*ancestor(zend_class_entry
*ce
)
178 zval
*php_pq_object_read_prop_80(zend_object
*object
, zend_string
*member
, int type
, void **cache_slot
, zval
*tmp
)
180 php_pq_object_t
*obj
= PHP_PQ_OBJ(NULL
, object
);
181 php_pq_object_prophandler_t
*handler
;
182 zval
*return_value
= NULL
;
184 return_value
= zend_get_std_object_handlers()->read_property(object
, member
, type
, cache_slot
, tmp
);
187 php_error(E_RECOVERABLE_ERROR
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
->val
);
188 } else if (!(handler
= zend_hash_find_ptr(obj
->prophandler
, member
)) || !handler
->read
) {
189 /* default handler */
190 } else if (type
!= BP_VAR_R
) {
191 php_error(E_WARNING
, "Cannot access %s properties by reference or array key/index", ancestor(obj
->zo
.ce
)->name
->val
);
193 handler
->read(obj
, tmp
);
194 zend_get_std_object_handlers()->write_property(object
, member
, tmp
, cache_slot
);
204 zval
*php_pq_object_read_prop_74(zval
*object
, zval
*member
, int type
, void **cache_slot
, zval
*tmp
)
206 zend_string
*member_str
= zval_get_string(member
);
207 zval
*return_value
= php_pq_object_read_prop_80(Z_OBJ_P(object
), member_str
, type
, cache_slot
, tmp
);
208 zend_string_release(member_str
);
211 void php_pq_object_read_prop_70(zval
*object
, zval
*member
, int type
, void **cache_slot
, zval
*tmp
)
213 (void) php_pq_object_read_prop_74(object
, member
, type
, cache_slot
, tmp
);
216 zval
*php_pq_object_write_prop_80(zend_object
*object
, zend_string
*member
, zval
*value
, void **cache_slot
)
218 php_pq_object_t
*obj
= PHP_PQ_OBJ(NULL
, object
);
219 php_pq_object_prophandler_t
*handler
;
222 php_error(E_RECOVERABLE_ERROR
, "%s not initialized", ancestor(obj
->zo
.ce
)->name
->val
);
223 zend_get_std_object_handlers()->write_property(object
, member
, value
, cache_slot
);
224 } else if ((handler
= zend_hash_find_ptr(obj
->prophandler
, member
))) {
225 if (handler
->write
) {
226 handler
->write(obj
, value
);
229 zend_get_std_object_handlers()->write_property(object
, member
, value
, cache_slot
);
233 zval
*php_pq_object_write_prop_74(zval
*object
, zval
*member
, zval
*value
, void **cache_slot
)
235 zend_string
*member_str
= zval_get_string(member
);
236 zval
*return_value
= php_pq_object_write_prop_80(Z_OBJ_P(object
), member_str
, value
, cache_slot
);
237 zend_string_release(member_str
);
240 void php_pq_object_write_prop_70(zval
*object
, zval
*member
, zval
*value
, void **cache_slot
)
242 (void) php_pq_object_write_prop_74(object
, member
, value
, cache_slot
);
245 zval
*php_pq_object_get_prop_ptr_null_80(zend_object
*object
, zend_string
*member
, int type
, void **cache_slot
)
249 zval
*php_pq_object_get_prop_ptr_null_70(zval
*object
, zval
*member
, int type
, void **cache_slot
)
254 void php_pq_object_prophandler_dtor(zval
*zv
) {
255 pefree(Z_PTR_P(zv
), 1);