diff --git a/ext/dom/obj_map.c b/ext/dom/obj_map.c index c92a5834f3c..12407a56011 100644 --- a/ext/dom/obj_map.c +++ b/ext/dom/obj_map.c @@ -55,8 +55,7 @@ static zend_long dom_map_get_xmlht_length(dom_nnodemap_object *map) static zend_long dom_map_get_nodeset_length(dom_nnodemap_object *map) { - HashTable *nodeht = Z_ARRVAL(map->baseobj_zv); - return zend_hash_num_elements(nodeht); + return zend_hash_num_elements(map->array); } static zend_long dom_map_get_prop_length(dom_nnodemap_object *map) @@ -132,8 +131,7 @@ static void dom_map_get_notation_item(dom_nnodemap_object *map, zend_long index, static void dom_map_get_nodeset_item(dom_nnodemap_object *map, zend_long index, zval *return_value) { - HashTable *nodeht = Z_ARRVAL(map->baseobj_zv); - zval *entry = zend_hash_index_find(nodeht, index); + zval *entry = zend_hash_index_find(map->array, index); if (entry) { RETURN_COPY(entry); } else { @@ -294,7 +292,7 @@ void php_dom_create_obj_map(dom_object *basenode, dom_object *intern, xmlHashTab ZEND_ASSERT(basenode != NULL); - ZVAL_OBJ_COPY(&mapptr->baseobj_zv, &basenode->std); + GC_ADDREF(&basenode->std); xmlDocPtr doc = basenode->document ? basenode->document->ptr : NULL; diff --git a/ext/dom/obj_map.h b/ext/dom/obj_map.h index 49357995642..e1de9addd98 100644 --- a/ext/dom/obj_map.h +++ b/ext/dom/obj_map.h @@ -30,10 +30,10 @@ typedef struct php_dom_obj_map_handler { typedef struct dom_nnodemap_object { dom_object *baseobj; - zval baseobj_zv; zend_long cached_length; union { xmlHashTable *ht; + HashTable *array; struct { xmlChar *local; zend_string *local_lower; @@ -47,6 +47,7 @@ typedef struct dom_nnodemap_object { const php_dom_obj_map_handler *handler; bool release_local; bool release_ns; + bool release_array; } dom_nnodemap_object; void php_dom_create_obj_map(dom_object *basenode, dom_object *intern, xmlHashTablePtr ht, zend_string *local, zend_string *ns, const php_dom_obj_map_handler *handler); diff --git a/ext/dom/parentnode/css_selectors.c b/ext/dom/parentnode/css_selectors.c index b9d2edee723..4f77359835c 100644 --- a/ext/dom/parentnode/css_selectors.c +++ b/ext/dom/parentnode/css_selectors.c @@ -249,7 +249,8 @@ void dom_parent_node_query_selector_all(xmlNodePtr thisp, dom_object *intern, zv object_init_ex(return_value, dom_modern_nodelist_class_entry); dom_object *ret_obj = Z_DOMOBJ_P(return_value); dom_nnodemap_object *mapptr = (dom_nnodemap_object *) ret_obj->ptr; - ZVAL_ARR(&mapptr->baseobj_zv, list); + mapptr->array = list; + mapptr->release_array = true; mapptr->handler = &php_dom_obj_map_nodeset; } } diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index e71e4e259c3..6e85ea887e4 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1545,8 +1545,11 @@ void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */ if (objmap->local_lower) { zend_string_release(objmap->local_lower); } - if (!Z_ISUNDEF(objmap->baseobj_zv)) { - zval_ptr_dtor(&objmap->baseobj_zv); + if (objmap->release_array) { + zend_array_release(objmap->array); + } + if (objmap->baseobj) { + OBJ_RELEASE(&objmap->baseobj->std); } xmlDictFree(objmap->dict); efree(objmap); diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index ebf61f10e80..21baa59ffed 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -234,15 +234,6 @@ PHP_METHOD(DOMXPath, registerNamespace) } /* }}} */ -static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */ -{ - dom_nnodemap_object *mapptr = (dom_nnodemap_object *) intern->ptr; - - ZVAL_COPY_VALUE(&mapptr->baseobj_zv, baseobj); - mapptr->handler = &php_dom_obj_map_nodeset; -} -/* }}} */ - static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) /* {{{ */ { zval *context = NULL; @@ -335,6 +326,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) { xmlNodeSetPtr nodesetp; zval retval; + bool release_array = false; if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval) && nodesetp->nodeNr) { array_init_size(&retval, nodesetp->nodeNr); @@ -369,12 +361,18 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) } add_next_index_zval(&retval, &child); } + release_array = true; } else { ZVAL_EMPTY_ARRAY(&retval); } + object_init_ex(return_value, dom_get_nodelist_ce(modern)); nodeobj = Z_DOMOBJ_P(return_value); - dom_xpath_iter(&retval, nodeobj); + dom_nnodemap_object *mapptr = nodeobj->ptr; + + mapptr->array = Z_ARR(retval); + mapptr->release_array = release_array; + mapptr->handler = &php_dom_obj_map_nodeset; break; }