Store hash table entry directly in dom_nnodemap_object

Splits the purpose of the baseobj_zv: now no longer either is an array
or an object. Stores the hash table pointer directly, if used.
This commit is contained in:
Niels Dossche 2025-06-21 23:13:04 +02:00
parent 8736342782
commit 479e9be45d
5 changed files with 20 additions and 19 deletions

View file

@ -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) static zend_long dom_map_get_nodeset_length(dom_nnodemap_object *map)
{ {
HashTable *nodeht = Z_ARRVAL(map->baseobj_zv); return zend_hash_num_elements(map->array);
return zend_hash_num_elements(nodeht);
} }
static zend_long dom_map_get_prop_length(dom_nnodemap_object *map) 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) 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(map->array, index);
zval *entry = zend_hash_index_find(nodeht, index);
if (entry) { if (entry) {
RETURN_COPY(entry); RETURN_COPY(entry);
} else { } else {
@ -294,7 +292,7 @@ void php_dom_create_obj_map(dom_object *basenode, dom_object *intern, xmlHashTab
ZEND_ASSERT(basenode != NULL); ZEND_ASSERT(basenode != NULL);
ZVAL_OBJ_COPY(&mapptr->baseobj_zv, &basenode->std); GC_ADDREF(&basenode->std);
xmlDocPtr doc = basenode->document ? basenode->document->ptr : NULL; xmlDocPtr doc = basenode->document ? basenode->document->ptr : NULL;

View file

@ -30,10 +30,10 @@ typedef struct php_dom_obj_map_handler {
typedef struct dom_nnodemap_object { typedef struct dom_nnodemap_object {
dom_object *baseobj; dom_object *baseobj;
zval baseobj_zv;
zend_long cached_length; zend_long cached_length;
union { union {
xmlHashTable *ht; xmlHashTable *ht;
HashTable *array;
struct { struct {
xmlChar *local; xmlChar *local;
zend_string *local_lower; zend_string *local_lower;
@ -47,6 +47,7 @@ typedef struct dom_nnodemap_object {
const php_dom_obj_map_handler *handler; const php_dom_obj_map_handler *handler;
bool release_local; bool release_local;
bool release_ns; bool release_ns;
bool release_array;
} dom_nnodemap_object; } 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); 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);

View file

@ -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); object_init_ex(return_value, dom_modern_nodelist_class_entry);
dom_object *ret_obj = Z_DOMOBJ_P(return_value); dom_object *ret_obj = Z_DOMOBJ_P(return_value);
dom_nnodemap_object *mapptr = (dom_nnodemap_object *) ret_obj->ptr; 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; mapptr->handler = &php_dom_obj_map_nodeset;
} }
} }

View file

@ -1545,8 +1545,11 @@ void dom_nnodemap_objects_free_storage(zend_object *object) /* {{{ */
if (objmap->local_lower) { if (objmap->local_lower) {
zend_string_release(objmap->local_lower); zend_string_release(objmap->local_lower);
} }
if (!Z_ISUNDEF(objmap->baseobj_zv)) { if (objmap->release_array) {
zval_ptr_dtor(&objmap->baseobj_zv); zend_array_release(objmap->array);
}
if (objmap->baseobj) {
OBJ_RELEASE(&objmap->baseobj->std);
} }
xmlDictFree(objmap->dict); xmlDictFree(objmap->dict);
efree(objmap); efree(objmap);

View file

@ -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) /* {{{ */ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern) /* {{{ */
{ {
zval *context = NULL; zval *context = NULL;
@ -335,6 +326,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type, bool modern)
{ {
xmlNodeSetPtr nodesetp; xmlNodeSetPtr nodesetp;
zval retval; zval retval;
bool release_array = false;
if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval) && nodesetp->nodeNr) { if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval) && nodesetp->nodeNr) {
array_init_size(&retval, 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); add_next_index_zval(&retval, &child);
} }
release_array = true;
} else { } else {
ZVAL_EMPTY_ARRAY(&retval); ZVAL_EMPTY_ARRAY(&retval);
} }
object_init_ex(return_value, dom_get_nodelist_ce(modern)); object_init_ex(return_value, dom_get_nodelist_ce(modern));
nodeobj = Z_DOMOBJ_P(return_value); 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; break;
} }