diff options
author | Nikita Popov <nikic@php.net> | 2014-04-16 15:52:59 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2014-04-16 17:14:34 +0200 |
commit | 39d12294fd2483c4634c16fb54cfe5d8e3356ecf (patch) | |
tree | fdd9353fba236ba4f35f343c58d57745b9b1b922 /ext | |
parent | 54c338acc1cff6d0375d3094af8a75c6d1c3a001 (diff) | |
download | php-git-39d12294fd2483c4634c16fb54cfe5d8e3356ecf.tar.gz |
Mostly fix Dom XPath
Diffstat (limited to 'ext')
-rw-r--r-- | ext/dom/dom_iterators.c | 10 | ||||
-rw-r--r-- | ext/dom/node.c | 4 | ||||
-rw-r--r-- | ext/dom/nodelist.c | 8 | ||||
-rw-r--r-- | ext/dom/php_dom.c | 44 | ||||
-rw-r--r-- | ext/dom/php_dom.h | 10 | ||||
-rw-r--r-- | ext/dom/xpath.c | 27 |
6 files changed, 52 insertions, 51 deletions
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 250e2efab5..22d0ab0ee3 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -197,10 +197,7 @@ static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) if (objmap->nodetype != XML_ENTITY_NODE && objmap->nodetype != XML_NOTATION_NODE) { if (objmap->nodetype == DOM_NODESET) { - zval obj; - ZVAL_OBJ(&obj, &objmap->baseobj->std); - nodeht = HASH_OF(&obj); - + nodeht = HASH_OF(&objmap->baseobj_zv); zend_hash_move_forward(nodeht); if ((entry = zend_hash_get_current_data(nodeht))) { ZVAL_COPY(&iterator->curobj, entry); @@ -275,10 +272,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, i if (objmap->nodetype != XML_ENTITY_NODE && objmap->nodetype != XML_NOTATION_NODE) { if (objmap->nodetype == DOM_NODESET) { - zval obj; - ZVAL_OBJ(&obj, &objmap->baseobj->std); - nodeht = HASH_OF(&obj); - + nodeht = HASH_OF(&objmap->baseobj_zv); zend_hash_internal_pointer_reset(nodeht); if ((entry = zend_hash_get_current_data(nodeht))) { ZVAL_COPY(&iterator->curobj, entry); diff --git a/ext/dom/node.c b/ext/dom/node.c index 920581423e..57669b5069 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -1729,8 +1729,8 @@ static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ zend_string *prefix; ulong idx; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(tmp), - &prefix, &idx, 0, NULL) == HASH_KEY_IS_STRING) { + if (zend_hash_get_current_key(Z_ARRVAL_P(tmp), + &prefix, &idx, 0) == HASH_KEY_IS_STRING) { xmlXPathRegisterNs(ctxp, prefix->val, Z_STRVAL_P(tmpns)); } } diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 323eb9925d..3ef43f2ac7 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -64,9 +64,7 @@ int dom_nodelist_length_read(dom_object *obj, zval *retval TSRMLS_DC) count = xmlHashSize(objmap->ht); } else { if (objmap->nodetype == DOM_NODESET) { - zval obj; - ZVAL_OBJ(&obj, &objmap->baseobj->std); - nodeht = HASH_OF(&obj); + nodeht = HASH_OF(&objmap->baseobj_zv); count = zend_hash_num_elements(nodeht); } else { nodep = dom_object_get_node(objmap->baseobj); @@ -132,9 +130,7 @@ PHP_FUNCTION(dom_nodelist_item) } } else { if (objmap->nodetype == DOM_NODESET) { - zval obj; - ZVAL_OBJ(&obj, &objmap->baseobj->std); - HashTable *nodeht = HASH_OF(&obj); + HashTable *nodeht = HASH_OF(&objmap->baseobj_zv); zval *entry = zend_hash_index_find(nodeht, index); if (entry) { ZVAL_COPY(return_value, entry); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 538317295d..a15cd255b7 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 */ @@ -588,6 +591,9 @@ 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 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) @@ -835,6 +841,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, 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,9 +1007,9 @@ 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); @@ -1018,8 +1028,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 +1060,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 +1074,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; } @@ -1133,14 +1138,16 @@ 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->prop_handler = &dom_xpath_prop_handlers; + intern->std.handlers = &dom_xpath_object_handlers; + + zend_object_std_init(&intern->std, class_type TSRMLS_CC); + object_properties_init(&intern->std, class_type); return &intern->std; } @@ -1162,8 +1169,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 +1196,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; diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 8f6eba12c0..82ba681ff8 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -68,18 +68,24 @@ extern zend_module_entry dom_module_entry; #define DOM_NODESET XML_XINCLUDE_START typedef struct _dom_xpath_object { - zend_object std; void *ptr; php_libxml_ref_obj *document; HashTable *prop_handler; - //??? zend_object_handle handle; int registerPhpFunctions; HashTable *registered_phpfunctions; HashTable *node_list; + zend_object std; } dom_xpath_object; +static inline dom_xpath_object *php_xpath_obj_from_obj(zend_object *obj) { + return (dom_xpath_object*)((char*)(obj) - XtOffsetOf(dom_xpath_object, std)); +} + +#define Z_XPATHOBJ_P(zv) php_xpath_obj_from_obj(Z_OBJ_P((zv))) + typedef struct _dom_nnodemap_object { dom_object *baseobj; + zval baseobj_zv; int nodetype; xmlHashTable *ht; xmlChar *local; diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 21998704fe..de5f244b4d 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -196,7 +196,6 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, if (!zend_make_callable(&fci.function_name, &callable TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable->val); - } else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable->val); /* Push an empty string, so that we at least have an xslt result... */ @@ -213,7 +212,7 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, } GC_REFCOUNT(&retval)++; zend_hash_next_index_insert(intern->node_list, &retval); - obj = Z_DOMOBJ_P(&retval); + obj = Z_XPATHOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_BOOL) { @@ -223,12 +222,13 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { convert_to_string_ex(&retval); - valuePush(ctxt, xmlXPathNewString( Z_STRVAL(retval))); + valuePush(ctxt, xmlXPathNewString(Z_STRVAL(retval))); } zval_ptr_dtor(&retval); } } - STR_FREE(callable); + STR_RELEASE(callable); + zval_dtor(&fci.function_name); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); @@ -275,7 +275,7 @@ PHP_METHOD(domxpath, __construct) RETURN_FALSE; } - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); if (intern != NULL) { oldctx = (xmlXPathContextPtr)intern->ptr; if (oldctx != NULL) { @@ -326,7 +326,7 @@ PHP_FUNCTION(dom_xpath_register_ns) return; } - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); ctxp = (xmlXPathContextPtr) intern->ptr; if (ctxp == NULL) { @@ -343,13 +343,10 @@ PHP_FUNCTION(dom_xpath_register_ns) static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */ { - dom_nnodemap_object *mapptr; + dom_nnodemap_object *mapptr = (dom_nnodemap_object *) intern->ptr; - mapptr = (dom_nnodemap_object *)intern->ptr; - Z_ADDREF_P(baseobj); - mapptr->baseobj = Z_OBJ_P(baseobj); + ZVAL_COPY_VALUE(&mapptr->baseobj_zv, baseobj); mapptr->nodetype = DOM_NODESET; - } /* }}} */ @@ -371,7 +368,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ return; } - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); ctxp = (xmlXPathContextPtr) intern->ptr; if (ctxp == NULL) { @@ -522,7 +519,7 @@ PHP_FUNCTION(dom_xpath_register_php_functions) DOM_GET_THIS(id); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) { - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(array_value)))) { zend_string *str = zval_get_string(entry TSRMLS_CC); @@ -535,13 +532,13 @@ PHP_FUNCTION(dom_xpath_register_php_functions) RETURN_TRUE; } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "S", &name) == SUCCESS) { - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); ZVAL_LONG(&new_string, 1); zend_hash_update(intern->registered_phpfunctions, name, &new_string); intern->registerPhpFunctions = 2; } else { - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); intern->registerPhpFunctions = 1; } |