|
|
|
@ -61,6 +61,7 @@ struct _xc_processor_t {
|
|
|
|
|
HashTable strings;
|
|
|
|
|
HashTable zvalptrs;
|
|
|
|
|
zend_bool reference; /* enable if to deal with reference */
|
|
|
|
|
zend_bool have_references;
|
|
|
|
|
const xc_entry_t *xce_src;
|
|
|
|
|
const xc_entry_t *xce_dst;
|
|
|
|
|
const zend_class_entry *cache_ce;
|
|
|
|
@ -260,49 +261,7 @@ dnl FIXME: handle common.function_name here
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
static int xc_hash_static_member_check(xc_processor_t *processor, Bucket *b TSRMLS_DC) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
const zend_class_entry *src = processor->active_class_entry_src;
|
|
|
|
|
if (src->parent) {
|
|
|
|
|
zval **parentzv;
|
|
|
|
|
if (zend_u_hash_quick_find(CE_STATIC_MEMBERS(src->parent), BUCKET_KEY_TYPE(b), ZSTR(BUCKET_KEY_S(b)), b->nKeyLength, b->h, (void **) &parentzv) == SUCCESS) {
|
|
|
|
|
zval **zv = (zval **) b->pData;
|
|
|
|
|
if (*parentzv == *zv) {
|
|
|
|
|
return ZEND_HASH_APPLY_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ZEND_HASH_APPLY_KEEP;
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
/* fix static members on restore */
|
|
|
|
|
static void inherit_static_prop(zval **p) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
/* already set */
|
|
|
|
|
#if 0
|
|
|
|
|
(*p)->refcount++;
|
|
|
|
|
(*p)->is_ref = 1;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
static void xc_fix_static_members(xc_processor_t *processor, zend_class_entry *dst TSRMLS_DC) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
zend_hash_merge(&dst->default_static_members, &dst->parent->default_static_members, (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
#endif
|
|
|
|
|
int xc_hash_reset_zval_refcount_applyer(void *pDest TSRMLS_DC) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
zval **zv = (zval **) pDest;
|
|
|
|
|
ZVAL_REFCOUNT(*zv) = 1;
|
|
|
|
|
return ZEND_HASH_APPLY_KEEP;
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
static void xc_hash_reset_zval_refcount(HashTable *hash TSRMLS_DC) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
zend_hash_apply(hash, xc_hash_reset_zval_refcount_applyer TSRMLS_CC);
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
/* {{{ call op_array ctor handler */
|
|
|
|
|
extern zend_bool xc_have_op_array_ctor;
|
|
|
|
|
static void xc_zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
|
|
|
|
@ -319,9 +278,7 @@ xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC) {
|
|
|
|
|
xc_processor_t processor;
|
|
|
|
|
|
|
|
|
|
memset(&processor, 0, sizeof(processor));
|
|
|
|
|
if (src->type == XC_TYPE_VAR) {
|
|
|
|
|
processor.reference = 1;
|
|
|
|
|
}
|
|
|
|
|
processor.reference = 1;
|
|
|
|
|
|
|
|
|
|
IFASSERT(`xc_stack_init(&processor.allocsizes);')
|
|
|
|
|
|
|
|
|
@ -342,6 +299,7 @@ xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC) {
|
|
|
|
|
zend_hash_destroy(&processor.strings);
|
|
|
|
|
}
|
|
|
|
|
src->size = processor.size;
|
|
|
|
|
src->have_references = processor.have_references;
|
|
|
|
|
|
|
|
|
|
IFASSERT(`xc_stack_reverse(&processor.allocsizes);')
|
|
|
|
|
/* store {{{ */
|
|
|
|
@ -393,23 +351,36 @@ xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *s
|
|
|
|
|
|
|
|
|
|
memset(&processor, 0, sizeof(processor));
|
|
|
|
|
processor.readonly_protection = readonly_protection;
|
|
|
|
|
if (src->have_references) {
|
|
|
|
|
processor.reference = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (processor.reference) {
|
|
|
|
|
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
|
|
|
|
|
}
|
|
|
|
|
xc_restore_xc_entry_t(&processor, dst, src TSRMLS_CC);
|
|
|
|
|
if (processor.reference) {
|
|
|
|
|
zend_hash_destroy(&processor.zvalptrs);
|
|
|
|
|
}
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
/* export: zval *xc_processor_restore_zval(zval *dst, const zval *src TSRMLS_DC); :export {{{ */
|
|
|
|
|
zval *xc_processor_restore_zval(zval *dst, const zval *src TSRMLS_DC) {
|
|
|
|
|
/* export: zval *xc_processor_restore_zval(zval *dst, const zval *src, zend_bool have_references TSRMLS_DC); :export {{{ */
|
|
|
|
|
zval *xc_processor_restore_zval(zval *dst, const zval *src, zend_bool have_references TSRMLS_DC) {
|
|
|
|
|
xc_processor_t processor;
|
|
|
|
|
|
|
|
|
|
memset(&processor, 0, sizeof(processor));
|
|
|
|
|
processor.reference = 1;
|
|
|
|
|
processor.reference = have_references;
|
|
|
|
|
|
|
|
|
|
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
|
|
|
|
|
dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
|
|
|
|
|
zend_hash_add(&processor.zvalptrs, (char *)src, sizeof(src), (void*)&dst, sizeof(dst), NULL);
|
|
|
|
|
if (processor.reference) {
|
|
|
|
|
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
|
|
|
|
|
dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
|
|
|
|
|
zend_hash_add(&processor.zvalptrs, (char *)src, sizeof(src), (void*)&dst, sizeof(dst), NULL);
|
|
|
|
|
}
|
|
|
|
|
xc_restore_zval(&processor, dst, src TSRMLS_CC);
|
|
|
|
|
zend_hash_destroy(&processor.zvalptrs);
|
|
|
|
|
if (processor.reference) {
|
|
|
|
|
zend_hash_destroy(&processor.zvalptrs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|