diff options
Diffstat (limited to 'ext/dom/php_dom.c')
-rw-r--r-- | ext/dom/php_dom.c | 165 |
1 files changed, 73 insertions, 92 deletions
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 538317295d..99d99e236f 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -73,6 +73,9 @@ zend_class_entry *dom_namespace_node_class_entry; zend_object_handlers dom_object_handlers; zend_object_handlers dom_nnodemap_object_handlers; +#if defined(LIBXML_XPATH_ENABLED) +zend_object_handlers dom_xpath_object_handlers; +#endif static HashTable classes; /* {{{ prop handler tables */ @@ -108,6 +111,10 @@ typedef struct _dom_prop_handler { dom_write_t write_func; } dom_prop_handler; +static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) { + return &dom_object_handlers; +} + /* {{{ int dom_node_is_read_only(xmlNodePtr node) */ int dom_node_is_read_only(xmlNodePtr node) { switch (node->type) { @@ -303,7 +310,7 @@ static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_r } /* }}} */ -static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { dom_object *obj = Z_DOMOBJ_P(object); zend_string *member_str = zval_get_string(member TSRMLS_CC); @@ -311,7 +318,7 @@ static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, cons if (!obj->prop_handler || !zend_hash_exists(obj->prop_handler, member_str)) { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC); + retval = std_hnd->get_property_ptr_ptr(object, member, type, cache_slot TSRMLS_CC); } STR_RELEASE(member_str); @@ -320,7 +327,7 @@ static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, cons /* }}} */ /* {{{ dom_read_property */ -zval *dom_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) +zval *dom_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); zend_string *member_str = zval_get_string(member TSRMLS_CC); @@ -342,7 +349,7 @@ zval *dom_read_property(zval *object, zval *member, int type, const zend_literal } } else { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->read_property(object, member, type, key, rv TSRMLS_CC); + retval = std_hnd->read_property(object, member, type, cache_slot, rv TSRMLS_CC); } STR_RELEASE(member_str); @@ -351,7 +358,7 @@ zval *dom_read_property(zval *object, zval *member, int type, const zend_literal /* }}} */ /* {{{ dom_write_property */ -void dom_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +void dom_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); zend_string *member_str = zval_get_string(member TSRMLS_CC); @@ -364,7 +371,7 @@ void dom_write_property(zval *object, zval *member, zval *value, const zend_lite hnd->write_func(obj, value TSRMLS_CC); } else { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); - std_hnd->write_property(object, member, value, key TSRMLS_CC); + std_hnd->write_property(object, member, value, cache_slot TSRMLS_CC); } STR_RELEASE(member_str); @@ -372,7 +379,7 @@ void dom_write_property(zval *object, zval *member, zval *value, const zend_lite /* }}} */ /* {{{ dom_property_exists */ -static int dom_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +static int dom_property_exists(zval *object, zval *member, int check_empty, zend_uint cache_slot TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); zend_string *member_str = zval_get_string(member TSRMLS_CC); @@ -397,7 +404,7 @@ static int dom_property_exists(zval *object, zval *member, int check_empty, cons } } else { zend_object_handlers *std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->has_property(object, member, check_empty, key TSRMLS_CC); + retval = std_hnd->has_property(object, member, check_empty, cache_slot TSRMLS_CC); } STR_RELEASE(member_str); @@ -430,7 +437,7 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC ZVAL_STRING(&object_value, "(object value omitted)"); for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos); - entry = zend_hash_get_current_data_ptr_ex(prop_handlers, &pos); + (entry = zend_hash_get_current_data_ptr_ex(prop_handlers, &pos)) != NULL; zend_hash_move_forward_ex(prop_handlers, &pos)) { zval value; zend_string *string_key; @@ -470,7 +477,7 @@ void *php_dom_export_node(zval *object TSRMLS_DC) /* {{{ */ php_libxml_node_object *intern; xmlNodePtr nodep = NULL; - intern = Z_DOMOBJ_P(object); + intern = (php_libxml_node_object *) Z_DOMOBJ_P(object); if (intern->node) { nodep = intern->node->node; } @@ -492,7 +499,7 @@ PHP_FUNCTION(dom_import_simplexml) return; } - nodeobj = Z_DOMOBJ_P(node); + nodeobj = (php_libxml_node_object *) ((char *) Z_OBJ_P(node) - Z_OBJ_HT_P(node)->offset); nodep = php_libxml_import_node(node TSRMLS_CC); if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) { @@ -504,31 +511,36 @@ PHP_FUNCTION(dom_import_simplexml) } /* }}} */ -zend_object *dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */ -{ - ZEND_ASSERT(0); - /*void *new_object; - dom_object *intern; - dom_object *old_object; - zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); - - obj = &EG(objects_store).object_buckets[handle].bucket.obj; +static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC); - if (obj->clone == NULL) { - php_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(zobject)->name); - } +static zend_object *dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */ +{ + dom_object *intern = Z_DOMOBJ_P(zobject); + dom_object *clone = dom_objects_set_class(intern->std.ce, 0 TSRMLS_CC); - obj->clone(obj->object, &new_object TSRMLS_CC); + clone->std.handlers = dom_get_obj_handlers(TSRMLS_C); + zend_objects_clone_members(&clone->std, &intern->std TSRMLS_CC); - retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); - intern = (dom_object *) new_object; - intern->handle = retval.handle; - retval.handlers = Z_OBJ_HT_P(zobject); + if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) { + xmlNodePtr node = (xmlNodePtr)dom_object_get_node(intern); + if (node != NULL) { + xmlNodePtr cloned_node = xmlDocCopyNode(node, node->doc, 1); + if (cloned_node != NULL) { + /* If we cloned a document then we must create new doc proxy */ + if (cloned_node->doc == node->doc) { + clone->document = intern->document; + } + php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC); + php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone TSRMLS_CC); + if (intern->document != clone->document) { + dom_copy_doc_props(intern->document, clone->document); + } + } - old_object = (dom_object *) obj->object; - zend_objects_clone_members(&intern->std, retval, &old_object->std, intern->handle TSRMLS_CC); + } + } - return retval;*/ + return &clone->std; } /* }}} */ @@ -556,10 +568,6 @@ static const zend_function_entry dom_functions[] = { PHP_FE_END }; -static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) { - return &dom_object_handlers; -} - static const zend_module_dep dom_deps[] = { ZEND_MOD_REQUIRED("libxml") ZEND_MOD_CONFLICTS("domxml") @@ -587,7 +595,11 @@ ZEND_GET_MODULE(dom) void dom_objects_free_storage(zend_object *object TSRMLS_DC); void dom_nnodemap_objects_free_storage(zend_object *object TSRMLS_DC); +static zend_object *dom_objects_store_clone_obj(zval *zobject TSRMLS_DC); static void dom_nnodemap_object_dtor(zend_object *object TSRMLS_DC); +#if defined(LIBXML_XPATH_ENABLED) +void dom_xpath_objects_free_storage(zend_object *object TSRMLS_DC); +#endif /* {{{ PHP_MINIT_FUNCTION(dom) */ PHP_MINIT_FUNCTION(dom) @@ -597,6 +609,7 @@ PHP_MINIT_FUNCTION(dom) memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); dom_object_handlers.offset = XtOffsetOf(dom_object, std); dom_object_handlers.free_obj = dom_objects_free_storage; + dom_object_handlers.clone_obj = dom_objects_store_clone_obj; dom_object_handlers.read_property = dom_read_property; dom_object_handlers.write_property = dom_write_property; dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr; @@ -835,6 +848,10 @@ PHP_MINIT_FUNCTION(dom) REGISTER_DOM_CLASS(ce, "DOMStringExtend", NULL, php_dom_string_extend_class_functions, dom_string_extend_class_entry); #if defined(LIBXML_XPATH_ENABLED) + memcpy(&dom_xpath_object_handlers, &dom_object_handlers, sizeof(zend_object_handlers)); + dom_xpath_object_handlers.offset = XtOffsetOf(dom_xpath_object, dom) + XtOffsetOf(dom_object, std); + dom_xpath_object_handlers.free_obj = dom_xpath_objects_free_storage; + INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions); ce.create_object = dom_xpath_objects_new; dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL TSRMLS_CC); @@ -997,16 +1014,15 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC) #if defined(LIBXML_XPATH_ENABLED) /* {{{ dom_xpath_objects_free_storage */ -void dom_xpath_objects_free_storage(void *object TSRMLS_DC) +void dom_xpath_objects_free_storage(zend_object *object TSRMLS_DC) { - dom_xpath_object *intern = (dom_xpath_object *)object; + dom_xpath_object *intern = php_xpath_obj_from_obj(object); - zend_object_std_dtor(&intern->std TSRMLS_CC); + zend_object_std_dtor(&intern->dom.std TSRMLS_CC); - if (intern->ptr != NULL) { - xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr); - php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC); - intern->ptr = NULL; + if (intern->dom.ptr != NULL) { + xmlXPathFreeContext((xmlXPathContextPtr) intern->dom.ptr); + php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom TSRMLS_CC); } if (intern->registered_phpfunctions) { @@ -1018,8 +1034,6 @@ void dom_xpath_objects_free_storage(void *object TSRMLS_DC) zend_hash_destroy(intern->node_list); FREE_HASHTABLE(intern->node_list); } - - efree(object); } /* }}} */ #endif @@ -1052,9 +1066,9 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml { dom_nnodemap_object *mapptr = (dom_nnodemap_object *) intern->ptr; - if (basenode) { - GC_REFCOUNT(&basenode->std)++; - } + //??? if (basenode) + ZVAL_OBJ(&mapptr->baseobj_zv, &basenode->std); + Z_ADDREF(mapptr->baseobj_zv); mapptr->baseobj = basenode; mapptr->nodetype = ntype; @@ -1066,12 +1080,9 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */ { - zend_class_entry *base_class; - size_t dom_object_size = instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC) - ? sizeof(dom_xpath_object) : sizeof(dom_object); - dom_object *intern = ecalloc(1, dom_object_size + sizeof(zval) * (class_type->default_properties_count - 1)); + dom_object *intern = ecalloc(1, sizeof(dom_object) + sizeof(zval) * (class_type->default_properties_count - 1)); - base_class = class_type; + zend_class_entry *base_class = class_type; while (base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) { base_class = base_class->parent; } @@ -1087,39 +1098,6 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool } /* }}} */ -/* {{{ dom_objects_clone */ -void dom_objects_clone(void *object, void **object_clone TSRMLS_DC) -{ - dom_object *intern = (dom_object *) object; - dom_object *clone; - xmlNodePtr node; - xmlNodePtr cloned_node; - - clone = dom_objects_set_class(intern->std.ce, 0 TSRMLS_CC); - - if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) { - node = (xmlNodePtr)dom_object_get_node((dom_object *) object); - if (node != NULL) { - cloned_node = xmlDocCopyNode(node, node->doc, 1); - if (cloned_node != NULL) { - /* If we cloned a document then we must create new doc proxy */ - if (cloned_node->doc == node->doc) { - clone->document = intern->document; - } - php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC); - php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone TSRMLS_CC); - if (intern->document != clone->document) { - dom_copy_doc_props(intern->document, clone->document); - } - } - - } - } - - *object_clone = (void *) clone; -} -/* }}} */ - /* {{{ dom_objects_new */ zend_object *dom_objects_new(zend_class_entry *class_type TSRMLS_DC) { @@ -1133,16 +1111,18 @@ zend_object *dom_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) */ zend_object *dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) { - dom_xpath_object *intern = (dom_xpath_object *) dom_objects_set_class(class_type, 1 TSRMLS_CC); - intern->registerPhpFunctions = 0; - intern->node_list = NULL; + dom_xpath_object *intern = ecalloc(1, sizeof(dom_xpath_object) + sizeof(zval) * (class_type->default_properties_count - 1)); ALLOC_HASHTABLE(intern->registered_phpfunctions); zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0); - intern->std.handlers = dom_get_obj_handlers(TSRMLS_C); + intern->dom.prop_handler = &dom_xpath_prop_handlers; + intern->dom.std.handlers = &dom_xpath_object_handlers; - return &intern->std; + zend_object_std_init(&intern->dom.std, class_type TSRMLS_CC); + object_properties_init(&intern->dom.std, class_type); + + return &intern->dom.std; } /* }}} */ #endif @@ -1162,8 +1142,8 @@ static void dom_nnodemap_object_dtor(zend_object *object TSRMLS_DC) /* {{{ */ if (objmap->ns) { xmlFree(objmap->ns); } - if (objmap->baseobj) { - OBJ_RELEASE(&objmap->baseobj->std); + if (!ZVAL_IS_UNDEF(&objmap->baseobj_zv)) { + zval_ptr_dtor(&objmap->baseobj_zv); } efree(objmap); intern->ptr = NULL; @@ -1189,6 +1169,7 @@ zend_object *dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC) /* intern = dom_objects_set_class(class_type, 1 TSRMLS_CC); intern->ptr = emalloc(sizeof(dom_nnodemap_object)); objmap = (dom_nnodemap_object *)intern->ptr; + ZVAL_UNDEF(&objmap->baseobj_zv); objmap->baseobj = NULL; objmap->nodetype = 0; objmap->ht = NULL; |