diff options
author | Xinchen Hui <laruence@gmail.com> | 2014-04-21 14:14:00 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2014-04-21 14:14:00 +0800 |
commit | e48b9ad197b4ec6ac72e75538453cc350d0a41f4 (patch) | |
tree | f5ded37abc65e64e270b6f1ac264db9bc603f949 /ext | |
parent | cf7e703813e065fec7a8a5caa7aff4b70d3455b8 (diff) | |
parent | 54d9ad53f4797733b41bf2c65bd2c2cb5a1938b6 (diff) | |
download | php-git-e48b9ad197b4ec6ac72e75538453cc350d0a41f4.tar.gz |
Merge branch 'refactoring2' of github.com:zendtech/php into refactoring2
Diffstat (limited to 'ext')
39 files changed, 661 insertions, 891 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 634f08afa7..06c131014e 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -633,10 +633,10 @@ static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC); static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC); static HashTable *date_object_get_gc_timezone(zval *object, zval **table, int *n TSRMLS_DC); -zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC); -void date_interval_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); -static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC); -static void date_period_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC); +zval *date_interval_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC); +void date_interval_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC); +static zval *date_period_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC); +static void date_period_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC); /* {{{ Module struct */ zend_module_entry date_module_entry = { @@ -3947,7 +3947,7 @@ static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *forma } /* }}} */ /* {{{ date_interval_read_property */ -zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) +zval *date_interval_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) { php_interval_obj *obj; zval *retval; @@ -3959,13 +3959,13 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; - key = NULL; + cache_slot = -1; } obj = Z_PHPINTERVAL_P(object); if (!obj->initialized) { - retval = (zend_get_std_object_handlers())->read_property(object, member, type, key, rv TSRMLS_CC); + retval = (zend_get_std_object_handlers())->read_property(object, member, type, cache_slot, rv TSRMLS_CC); if (member == &tmp_member) { zval_dtor(member); } @@ -3987,7 +3987,7 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze GET_VALUE_FROM_STRUCT(invert, "invert"); GET_VALUE_FROM_STRUCT(days, "days"); /* didn't find any */ - retval = (zend_get_std_object_handlers())->read_property(object, member, type, key, rv TSRMLS_CC); + retval = (zend_get_std_object_handlers())->read_property(object, member, type, cache_slot, rv TSRMLS_CC); if (member == &tmp_member) { zval_dtor(member); @@ -4013,7 +4013,7 @@ zval *date_interval_read_property(zval *object, zval *member, int type, const ze /* }}} */ /* {{{ date_interval_write_property */ -void date_interval_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +void date_interval_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { php_interval_obj *obj; zval tmp_member, tmp_value; @@ -4023,13 +4023,13 @@ void date_interval_write_property(zval *object, zval *member, zval *value, const zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; - key = NULL; + cache_slot = -1; } obj = Z_PHPINTERVAL_P(object); if (!obj->initialized) { - (zend_get_std_object_handlers())->write_property(object, member, value, key TSRMLS_CC); + (zend_get_std_object_handlers())->write_property(object, member, value, cache_slot TSRMLS_CC); if (member == &tmp_member) { zval_dtor(member); } @@ -4051,7 +4051,7 @@ void date_interval_write_property(zval *object, zval *member, zval *value, const SET_VALUE_FROM_STRUCT(s, "s"); SET_VALUE_FROM_STRUCT(invert, "invert"); /* didn't find any */ - (zend_get_std_object_handlers())->write_property(object, member, value, key TSRMLS_CC); + (zend_get_std_object_handlers())->write_property(object, member, value, cache_slot TSRMLS_CC); } while(0); if (member == &tmp_member) { @@ -4930,7 +4930,7 @@ PHP_METHOD(DatePeriod, __wakeup) /* }}} */ /* {{{ date_period_read_property */ -static zval *date_period_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) +static zval *date_period_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) { zval *zv; if (type != BP_VAR_IS && type != BP_VAR_R) { @@ -4939,7 +4939,7 @@ static zval *date_period_read_property(zval *object, zval *member, int type, con Z_OBJPROP_P(object); /* build properties hash table */ - zv = std_object_handlers.read_property(object, member, type, key, rv TSRMLS_CC); + zv = std_object_handlers.read_property(object, member, type, cache_slot, rv TSRMLS_CC); if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJ_HANDLER_P(zv, clone_obj)) { /* defensive copy */ //??? MAKE_STD_ZVAL(zv); @@ -4951,7 +4951,7 @@ static zval *date_period_read_property(zval *object, zval *member, int type, con /* }}} */ /* {{{ date_period_write_property */ -static void date_period_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void date_period_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Writing to DatePeriod properties is unsupported"); } 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..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; diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 8f6eba12c0..628a19e978 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -68,18 +68,22 @@ 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; + dom_object dom; } 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, dom) - XtOffsetOf(dom_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..08bb8603a5 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -159,7 +159,7 @@ static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, node->parent = nsparent; node->ns = curns; } - php_dom_create_object(node, &child, (dom_object *)intern TSRMLS_CC); + php_dom_create_object(node, &child, &intern->dom TSRMLS_CC); add_next_index_zval(&fci.params[i], &child); } } @@ -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,11 +275,11 @@ PHP_METHOD(domxpath, __construct) RETURN_FALSE; } - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); if (intern != NULL) { - oldctx = (xmlXPathContextPtr)intern->ptr; + oldctx = (xmlXPathContextPtr)intern->dom.ptr; if (oldctx != NULL) { - php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC); + php_libxml_decrement_doc_ref((php_libxml_node_object *) &intern->dom TSRMLS_CC); xmlXPathFreeContext(oldctx); } @@ -290,10 +290,10 @@ PHP_METHOD(domxpath, __construct) (const xmlChar *) "http://php.net/xpath", dom_xpath_ext_function_object_php); - intern->ptr = ctx; + intern->dom.ptr = ctx; ctx->userData = (void *)intern; - intern->document = docobj->document; - php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC); + intern->dom.document = docobj->document; + php_libxml_increment_doc_ref((php_libxml_node_object *) &intern->dom, docp TSRMLS_CC); } } /* }}} end DOMXPath::__construct */ @@ -326,9 +326,9 @@ PHP_FUNCTION(dom_xpath_register_ns) return; } - intern = Z_DOMOBJ_P(id); + intern = Z_XPATHOBJ_P(id); - ctxp = (xmlXPathContextPtr) intern->ptr; + ctxp = (xmlXPathContextPtr) intern->dom.ptr; if (ctxp == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context"); RETURN_FALSE; @@ -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,9 +368,9 @@ 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; + ctxp = (xmlXPathContextPtr) intern->dom.ptr; if (ctxp == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context"); RETURN_FALSE; @@ -466,7 +463,7 @@ static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ node->parent = nsparent; node->ns = curns; } - php_dom_create_object(node, &child, (dom_object *)intern TSRMLS_CC); + php_dom_create_object(node, &child, &intern->dom TSRMLS_CC); add_next_index_zval(&retval, &child); } } @@ -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; } diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 705045eee4..cfa339fe24 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -86,6 +86,7 @@ ZEND_GET_MODULE(libxml) /* {{{ function prototypes */ static PHP_MINIT_FUNCTION(libxml); static PHP_RINIT_FUNCTION(libxml); +static PHP_RSHUTDOWN_FUNCTION(libxml); static PHP_MSHUTDOWN_FUNCTION(libxml); static PHP_MINFO_FUNCTION(libxml); static int php_libxml_post_deactivate(); @@ -138,7 +139,7 @@ zend_module_entry libxml_module_entry = { PHP_MINIT(libxml), /* extension-wide startup function */ PHP_MSHUTDOWN(libxml), /* extension-wide shutdown function */ PHP_RINIT(libxml), /* per-request startup function */ - NULL, /* per-request shutdown function */ + PHP_RSHUTDOWN(libxml), /* per-request shutdown function */ PHP_MINFO(libxml), /* information function */ NO_VERSION_YET, PHP_MODULE_GLOBALS(libxml), /* globals descriptor */ @@ -588,7 +589,7 @@ static xmlParserInputPtr _php_libxml_external_entity_loader(const char *URL, if (context->memb == NULL) { \ add_assoc_null_ex(ctxzv, #memb, sizeof(#memb) - 1); \ } else { \ - add_assoc_string_ex(ctxzv, #memb, sizeof(#memb - 1), \ + add_assoc_string_ex(ctxzv, #memb, sizeof(#memb) - 1, \ (char *)context->memb); \ } @@ -862,6 +863,12 @@ static PHP_RINIT_FUNCTION(libxml) return SUCCESS; } +static PHP_RSHUTDOWN_FUNCTION(libxml) +{ + _php_libxml_destroy_fci(&LIBXML(entity_loader).fci, &LIBXML(entity_loader).object); + + return SUCCESS; +} static PHP_MSHUTDOWN_FUNCTION(libxml) { @@ -898,8 +905,6 @@ static int php_libxml_post_deactivate() } xmlResetLastError(); - _php_libxml_destroy_fci(&LIBXML(entity_loader).fci, &LIBXML(entity_loader).object); - return SUCCESS; } @@ -1152,7 +1157,7 @@ PHP_LIBXML_API xmlNodePtr php_libxml_import_node(zval *object TSRMLS_DC) while (ce->parent != NULL) { ce = ce->parent; } - if ((export_hnd = zend_hash_find_ptr(&php_libxml_exports, ce->name)) == SUCCESS) { + if ((export_hnd = zend_hash_find_ptr(&php_libxml_exports, ce->name))) { node = export_hnd->export_func(object TSRMLS_CC); } } diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt index 51ab777052..938229ff86 100644 --- a/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt +++ b/ext/libxml/tests/libxml_set_external_entity_loader_basic.phpt @@ -31,6 +31,7 @@ var_dump($dd->validate()); echo "Done.\n"; +?> --EXPECT-- string(10) "-//FOO/BAR" string(25) "http://example.com/foobar" diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 86db53f1da..2260af80bc 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -683,7 +683,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, /* T = CAST(X, String), ECHO(T) => NOP, ECHO(X) */ if ((opline->opcode == ZEND_ECHO || opline->opcode == ZEND_PRINT) && - ZEND_OP1_TYPE(opline) == IS_TMP_VAR && + ZEND_OP1_TYPE(opline) & (IS_TMP_VAR|IS_VAR) && VAR_SOURCE(opline->op1) && VAR_SOURCE(opline->op1)->opcode == ZEND_CAST && VAR_SOURCE(opline->op1)->extended_value == IS_STRING) { @@ -785,20 +785,23 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, * IS_EQ(FALSE, X) => BOOL_NOT(X) * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X) * IS_NOT_EQ(FALSE, X) => BOOL(X) + * CASE(TRUE, X) => BOOL(X) + * CASE(FALSE, X) => BOOL_NOT(X) */ if (opline->opcode == ZEND_IS_EQUAL || - opline->opcode == ZEND_IS_NOT_EQUAL) { + opline->opcode == ZEND_IS_NOT_EQUAL || + opline->opcode == ZEND_CASE) { if (ZEND_OP1_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_BOOL) { opline->opcode = - ((opline->opcode == ZEND_IS_EQUAL) == Z_LVAL(ZEND_OP1_LITERAL(opline)))? + ((opline->opcode != ZEND_IS_NOT_EQUAL) == Z_LVAL(ZEND_OP1_LITERAL(opline)))? ZEND_BOOL : ZEND_BOOL_NOT; COPY_NODE(opline->op1, opline->op2); SET_UNUSED(opline->op2); } else if (ZEND_OP2_TYPE(opline) == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_BOOL) { opline->opcode = - ((opline->opcode == ZEND_IS_EQUAL) == Z_LVAL(ZEND_OP2_LITERAL(opline)))? + ((opline->opcode != ZEND_IS_NOT_EQUAL) == Z_LVAL(ZEND_OP2_LITERAL(opline)))? ZEND_BOOL : ZEND_BOOL_NOT; SET_UNUSED(opline->op2); } @@ -1118,6 +1121,10 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, opline->opcode = ZEND_CONCAT; literal_dtor(&ZEND_OP2_LITERAL(src)); /* will take care of empty_string too */ MAKE_NOP(src); +//??? This optimization can't work anymore because ADD_VAR returns IS_TMP_VAR +//??? and ZEND_CAST returns IS_VAR. +//??? BTW: it wan't used for long time, because we don't use INIT_STRING +#if 0 } else if (opline->opcode == ZEND_ADD_VAR && ZEND_OP1_TYPE(opline) == IS_TMP_VAR && VAR_SOURCE(opline->op1) && @@ -1130,11 +1137,12 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, MAKE_NOP(src); opline->opcode = ZEND_CAST; opline->extended_value = IS_STRING; +#endif } else if ((opline->opcode == ZEND_ADD_STRING || opline->opcode == ZEND_ADD_CHAR || opline->opcode == ZEND_ADD_VAR || opline->opcode == ZEND_CONCAT) && - ZEND_OP1_TYPE(opline) == IS_TMP_VAR && + ZEND_OP1_TYPE(opline) == (IS_TMP_VAR|IS_VAR) && VAR_SOURCE(opline->op1) && VAR_SOURCE(opline->op1)->opcode == ZEND_CAST && VAR_SOURCE(opline->op1)->extended_value == IS_STRING) { diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 1905e66136..6c3bf41ec3 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -63,7 +63,7 @@ static void optimizer_literal_obj_info(literal_info *info, * In general it's also possible to do it for any CV variable as well, * but it would require complex dataflow and/or type analysis. */ - if (Z_TYPE(op_array->literals[constant].constant) == IS_STRING && + if (Z_TYPE(op_array->literals[constant]) == IS_STRING && op_type == IS_UNUSED) { LITERAL_INFO_OBJ(constant, kind, 1, slots, related, op_array->this_var); } else { @@ -285,10 +285,10 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) for (i = 0; i < op_array->last_literal; i++) { if (!info[i].flags) { /* unsed literal */ - zval_dtor(&op_array->literals[i].constant); + zval_dtor(&op_array->literals[i]); continue; } - switch (Z_TYPE(op_array->literals[i].constant)) { + switch (Z_TYPE(op_array->literals[i])) { case IS_NULL: if (l_null < 0) { l_null = j; @@ -301,7 +301,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) map[i] = l_null; break; case IS_BOOL: - if (Z_LVAL(op_array->literals[i].constant)) { + if (Z_LVAL(op_array->literals[i])) { if (l_true < 0) { l_true = j; if (i != j) { @@ -324,11 +324,11 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) } break; case IS_LONG: - if ((pos = (int)zend_hash_index_find_ptr(&hash, Z_LVAL(op_array->literals[i].constant))) != 0) { + if ((pos = (int)zend_hash_index_find_ptr(&hash, Z_LVAL(op_array->literals[i]))) != 0) { map[i] = pos - 1; } else { map[i] = j; - zend_hash_index_update_ptr(&hash, Z_LVAL(op_array->literals[i].constant), (void*)j + 1); + zend_hash_index_update_ptr(&hash, Z_LVAL(op_array->literals[i]), (void*)j + 1); if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; @@ -337,11 +337,11 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) } break; case IS_DOUBLE: - if ((pos = (int)zend_hash_str_find_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double))) != 0) { + if ((pos = (int)zend_hash_str_find_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double))) != 0) { map[i] = pos - 1; } else { map[i] = j; - zend_hash_str_add_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i].constant), sizeof(double), (void*)j + 1); + zend_hash_str_add_ptr(&hash, (char*)&Z_DVAL(op_array->literals[i]), sizeof(double), (void*)j + 1); if (i != j) { op_array->literals[j] = op_array->literals[i]; info[j] = info[i]; @@ -353,37 +353,37 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) case IS_CONSTANT: if (info[i].flags & LITERAL_MAY_MERGE) { if (info[i].flags & LITERAL_EX_OBJ) { - int key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i].constant); + int key_len = MAX_LENGTH_OF_LONG + sizeof("->") + Z_STRLEN(op_array->literals[i]); key = STR_ALLOC(key_len, 0); - key->len = snprintf(key->val, key->len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i].constant)); + key->len = snprintf(key->val, key->len-1, "%d->%s", info[i].u.num, Z_STRVAL(op_array->literals[i])); } else if (info[i].flags & LITERAL_EX_CLASS) { int key_len; - zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num].constant; - key_len = Z_STRLEN_P(class_name) + sizeof("::") + Z_STRLEN(op_array->literals[i].constant); + zval *class_name = &op_array->literals[(info[i].u.num < i) ? map[info[i].u.num] : info[i].u.num]; + key_len = Z_STRLEN_P(class_name) + sizeof("::") + Z_STRLEN(op_array->literals[i]); key = STR_ALLOC(key_len, 0); memcpy(key->val, Z_STRVAL_P(class_name), Z_STRLEN_P(class_name)); memcpy(key->val + Z_STRLEN_P(class_name), "::", sizeof("::") - 1); memcpy(key->val + Z_STRLEN_P(class_name) + sizeof("::") - 1, - Z_STRVAL(op_array->literals[i].constant), - Z_STRLEN(op_array->literals[i].constant) + 1); + Z_STRVAL(op_array->literals[i]), + Z_STRLEN(op_array->literals[i]) + 1); } else { - key = STR_INIT(Z_STRVAL(op_array->literals[i].constant), Z_STRLEN(op_array->literals[i].constant), 0); + key = STR_INIT(Z_STRVAL(op_array->literals[i]), Z_STRLEN(op_array->literals[i]), 0); } key->h = zend_hash_func(key->val, key->len); key->h += info[i].flags; } if ((info[i].flags & LITERAL_MAY_MERGE) && (pos = (int)zend_hash_find_ptr(&hash, key)) != 0 && - Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[pos-1].constant) && + Z_TYPE(op_array->literals[i]) == Z_TYPE(op_array->literals[pos-1]) && info[i].flags == info[pos-1].flags) { STR_RELEASE(key); map[i] = pos - 1; - zval_dtor(&op_array->literals[i].constant); + zval_dtor(&op_array->literals[i]); n = LITERAL_NUM_RELATED(info[i].flags); while (n > 1) { i++; - zval_dtor(&op_array->literals[i].constant); + zval_dtor(&op_array->literals[i]); n--; } } else { @@ -404,7 +404,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC) //??? } //??? } if (LITERAL_NUM_SLOTS(info[i].flags)) { - op_array->literals[j].cache_slot = cache_slots; + Z_CACHE_SLOT(op_array->literals[j]) = cache_slots; cache_slots += LITERAL_NUM_SLOTS(info[i].flags); } j++; diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index d7461b5908..f9ae14290f 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -25,7 +25,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script case ZEND_INIT_NS_FCALL_BY_NAME: if (ZEND_OP2_TYPE(opline) == IS_CONST) { zend_function *func; - zval *function_name = &op_array->literals[opline->op2.constant + 1].constant; + zval *function_name = &op_array->literals[opline->op2.constant + 1]; if ((func = zend_hash_find_ptr(&script->function_table, Z_STR_P(function_name))) != NULL) { call_stack[call].func = func; @@ -53,10 +53,10 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script opline->opcode = ZEND_DO_FCALL; ZEND_OP1_TYPE(opline) = IS_CONST; opline->op1.constant = fcall->op2.constant + 1; - op_array->literals[fcall->op2.constant + 1].cache_slot = op_array->literals[fcall->op2.constant].cache_slot; + Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { - literal_dtor(&op_array->literals[fcall->op2.constant + 2].constant); + literal_dtor(&op_array->literals[fcall->op2.constant + 2]); } MAKE_NOP(fcall); } else if (opline->extended_value == 0 && @@ -69,7 +69,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script opline->opcode = ZEND_DO_FCALL; ZEND_OP1_TYPE(opline) = IS_CONST; opline->op1.constant = fcall->op2.constant + 1; - op_array->literals[fcall->op2.constant + 1].cache_slot = op_array->literals[fcall->op2.constant].cache_slot; + Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); MAKE_NOP(fcall); } diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 9edff53d39..207b8d0e61 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -102,7 +102,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); - replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); + if (opline->result_type == IS_TMP_VAR) { + replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); + } else /* if (opline->result_type == IS_VAR) */ { + replace_var_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); + } } else if (opline->extended_value == IS_BOOL) { /* T = CAST(X, IS_BOOL) => T = BOOL(X) */ opline->opcode = ZEND_BOOL; @@ -270,7 +274,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { ce = op_array->scope; } else { if ((ce = zend_hash_find_ptr(EG(class_table), - Z_STR(op_array->literals[opline->op1.constant + 1].constant))) == NULL || + Z_STR(op_array->literals[opline->op1.constant + 1]))) == NULL || (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->type != MODULE_PERSISTENT) || (ce->type == ZEND_USER_CLASS && diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index f92c866e41..0498bcba07 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -109,9 +109,9 @@ int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC) { int i = op_array->last_literal; op_array->last_literal++; - op_array->literals = (zend_literal*)erealloc(op_array->literals, op_array->last_literal * sizeof(zend_literal)); - ZVAL_COPY_VALUE(&op_array->literals[i].constant, zv); - op_array->literals[i].cache_slot = -1; + op_array->literals = (zval*)erealloc(op_array->literals, op_array->last_literal * sizeof(zval)); + ZVAL_COPY_VALUE(&op_array->literals[i], zv); + Z_CACHE_SLOT(op_array->literals[i]) = -1; //??? Z_SET_REFCOUNT(op_array->literals[i].constant, 2); //??? Z_SET_ISREF(op_array->literals[i].constant); return i; @@ -171,10 +171,10 @@ static void update_op1_const(zend_op_array *op_array, opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline))); //??? Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); - op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++; zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - STR_HASH_VAL(Z_STR(op_array->literals[opline->op1.constant+1].constant)); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op1.constant+1])); //??? op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1); break; case ZEND_DO_FCALL: @@ -182,7 +182,7 @@ static void update_op1_const(zend_op_array *op_array, opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); STR_HASH_VAL(Z_STR(ZEND_OP1_LITERAL(opline))); //??? Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); - op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++; break; default: opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); @@ -223,17 +223,17 @@ static void update_op2_const(zend_op_array *op_array, case ZEND_ISSET_ISEMPTY_VAR: case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: - op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++; zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1].constant)); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1])); //??? op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); break; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val TSRMLS_CC); - STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1].constant)); + STR_HASH_VAL(Z_STR(op_array->literals[opline->op2.constant+1])); //??? op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); /* break missing intentionally */ /*case ZEND_FETCH_CONSTANT:*/ @@ -250,7 +250,7 @@ static void update_op2_const(zend_op_array *op_array, case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: case ZEND_ISSET_ISEMPTY_PROP_OBJ: - op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot; op_array->last_cache_slot += 2; break; case ZEND_ASSIGN_ADD: @@ -265,7 +265,7 @@ static void update_op2_const(zend_op_array *op_array, case ZEND_ASSIGN_BW_AND: case ZEND_ASSIGN_BW_XOR: if (opline->extended_value == ZEND_ASSIGN_OBJ) { - op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot; op_array->last_cache_slot += 2; } break; @@ -307,7 +307,7 @@ check_numeric: if (numeric) { zval_dtor(val); ZVAL_LONG(val, index); - op_array->literals[opline->op2.constant].constant = *val; + op_array->literals[opline->op2.constant] = *val; } } break; @@ -488,10 +488,10 @@ static void zend_accel_optimize(zend_op_array *op_array, while (opline < end) { #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (opline->op1_type == IS_CONST) { - opline->op1.constant = opline->op1.literal - op_array->literals; + opline->op1.constant = opline->op1.zv - op_array->literals; } if (opline->op2_type == IS_CONST) { - opline->op2.constant = opline->op2.literal - op_array->literals; + opline->op2.constant = opline->op2.zv - op_array->literals; } #endif switch (opline->opcode) { @@ -529,10 +529,10 @@ static void zend_accel_optimize(zend_op_array *op_array, while (opline < end) { #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (opline->op1_type == IS_CONST) { - opline->op1.zv = &op_array->literals[opline->op1.constant].constant; + opline->op1.zv = &op_array->literals[opline->op1.constant]; } if (opline->op2_type == IS_CONST) { - opline->op2.zv = &op_array->literals[opline->op2.constant].constant; + opline->op2.zv = &op_array->literals[opline->op2.constant]; } #endif switch (opline->opcode) { diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 192b2ec6d0..9db5739a10 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -351,11 +351,11 @@ zend_string *accel_new_interned_string(zend_string *str TSRMLS_DC); # define ZEND_OP1_TYPE(opline) (opline)->op1_type # define ZEND_OP1(opline) (opline)->op1 # define ZEND_OP1_CONST(opline) (*(opline)->op1.zv) -# define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant].constant +# define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant] # define ZEND_OP2_TYPE(opline) (opline)->op2_type # define ZEND_OP2(opline) (opline)->op2 # define ZEND_OP2_CONST(opline) (*(opline)->op2.zv) -# define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant].constant +# define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant] # define ZEND_DONE_PASS_TWO(op_array) (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0) # define ZEND_CE_FILENAME(ce) (ce)->info.user.filename # define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 08051b47ee..51051dd6ce 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -409,7 +409,6 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) q->key = NULL; } else { q->key = zend_clone_str(p->key TSRMLS_CC); - GC_FLAGS(q->key) = GC_FLAGS(p->key); } /* Copy data */ diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index eea260d53e..ca8835c2ed 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -179,7 +179,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc int has_jmp = 0; #endif #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - zend_literal *orig_literals = NULL; + zval *orig_literals = NULL; #endif if (op_array->type != ZEND_USER_FUNCTION) { @@ -228,12 +228,12 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc ZEND_ASSERT(orig_literals != NULL); op_array->literals = orig_literals; } else { - zend_literal *p = zend_accel_memdup(op_array->literals, sizeof(zend_literal) * op_array->last_literal); - zend_literal *end = p + op_array->last_literal; + zval *p = zend_accel_memdup(op_array->literals, sizeof(zval) * op_array->last_literal); + zval *end = p + op_array->last_literal; orig_literals = op_array->literals; op_array->literals = p; while (p < end) { - zend_persist_zval(&p->constant TSRMLS_CC); + zend_persist_zval(p TSRMLS_CC); p++; } efree(orig_literals); diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index b9cf4240c1..20e6b083c4 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -156,7 +156,6 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC) static uint zend_persist_op_array_calc_ex(zend_op_array *op_array TSRMLS_DC) { - zend_op *opline, *end; START_SIZE(); if (op_array->type != ZEND_USER_FUNCTION) { @@ -181,11 +180,11 @@ static uint zend_persist_op_array_calc_ex(zend_op_array *op_array TSRMLS_DC) #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (op_array->literals) { - zend_literal *p = op_array->literals; - zend_literal *end = p + op_array->last_literal; - ADD_DUP_SIZE(op_array->literals, sizeof(zend_literal) * op_array->last_literal); + zval *p = op_array->literals; + zval *end = p + op_array->last_literal; + ADD_DUP_SIZE(op_array->literals, sizeof(zval) * op_array->last_literal); while (p < end) { - ADD_SIZE(zend_persist_zval_calc(&p->constant TSRMLS_CC)); + ADD_SIZE(zend_persist_zval_calc(p TSRMLS_CC)); p++; } } diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a38c5cdebd..724b667bde 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1250,14 +1250,12 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* Duplicate subject string for repeated replacement */ subject_value = STR_INIT(Z_STRVAL_P(subject), Z_STRLEN_P(subject), 0); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex)); - replace_value = replace; if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); /* For each entry in the regex array, get the entry */ - while ((regex_entry = zend_hash_get_current_data(Z_ARRVAL_P(regex))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) { /* Make sure we're dealing with strings. */ convert_to_string_ex(regex_entry); @@ -1293,8 +1291,7 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub return NULL; } - zend_hash_move_forward(Z_ARRVAL_P(regex)); - } + } ZEND_HASH_FOREACH_END(); zval_ptr_dtor(&tmp_subject); return subject_value; @@ -1365,32 +1362,24 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl /* if subject is an array */ if (Z_TYPE_P(subject) == IS_ARRAY) { array_init(return_value); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(subject)); /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ - while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) { old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key(Z_ARRVAL_P(subject), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: + if (string_key) { add_assoc_str_ex(return_value, string_key->val, string_key->len, result); - break; - - case HASH_KEY_IS_LONG: + } else { add_index_str(return_value, num_key, result); - break; } } else { STR_FREE(result); } } - - zend_hash_move_forward(Z_ARRVAL_P(subject)); - } + } ZEND_HASH_FOREACH_END(); } else { /* if subject is not an array */ old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { @@ -1781,8 +1770,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return PCRE_G(error_code) = PHP_PCRE_NO_ERROR; /* Go through the input array */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { zval subject, *ref_entry = entry; if (Z_ISREF_P(entry)) { @@ -1818,15 +1806,10 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } /* Add to return array */ - switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); - break; - - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); + } else { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); } } @@ -1834,9 +1817,8 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return zval_dtor(&subject); } - zend_hash_move_forward(Z_ARRVAL_P(input)); - } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); + } ZEND_HASH_FOREACH_END(); + /* Clean up */ efree(offsets); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 9aea15c882..d2a6790d6b 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -44,7 +44,7 @@ #define reflection_update_property(object, name, value) do { \ zval member; \ ZVAL_STRINGL(&member, name, sizeof(name)-1); \ - zend_std_write_property(object, &member, value, NULL TSRMLS_CC); \ + zend_std_write_property(object, &member, value, -1 TSRMLS_CC); \ if (Z_REFCOUNTED_P(value)) Z_DELREF_P(value); \ zval_ptr_dtor(&member); \ } while (0) @@ -1800,7 +1800,8 @@ ZEND_METHOD(reflection_function, getFileName) } GET_REFLECTION_OBJECT_PTR(fptr); if (fptr->type == ZEND_USER_FUNCTION) { - RETURN_STR(STR_COPY(fptr->op_array.filename)); +// TODO: we have to duplicate it, becaise it may be in opcache SHM ??? + RETURN_STR(STR_DUP(fptr->op_array.filename, 0)); } RETURN_FALSE; } @@ -1854,7 +1855,8 @@ ZEND_METHOD(reflection_function, getDocComment) } GET_REFLECTION_OBJECT_PTR(fptr); if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { - RETURN_STR(STR_COPY(fptr->op_array.doc_comment)); +// TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? + RETURN_STR(STR_DUP(fptr->op_array.doc_comment, 0)); } RETURN_FALSE; } @@ -3428,7 +3430,7 @@ ZEND_METHOD(reflection_class, getStaticPropertyValue) GET_REFLECTION_OBJECT_PTR(ce); zend_update_class_constants(ce TSRMLS_CC); - prop = zend_std_get_static_property(ce, name, 1, NULL TSRMLS_CC); + prop = zend_std_get_static_property(ce, name, 1, -1 TSRMLS_CC); if (!prop) { if (def_value) { RETURN_ZVAL(def_value, 1, 0); @@ -3461,7 +3463,7 @@ ZEND_METHOD(reflection_class, setStaticPropertyValue) GET_REFLECTION_OBJECT_PTR(ce); zend_update_class_constants(ce TSRMLS_CC); - variable_ptr = zend_std_get_static_property(ce, name, 1, NULL TSRMLS_CC); + variable_ptr = zend_std_get_static_property(ce, name, 1, -1 TSRMLS_CC); if (!variable_ptr) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a property named %s", ce->name->val, name->val); @@ -3566,7 +3568,8 @@ ZEND_METHOD(reflection_class, getFileName) } GET_REFLECTION_OBJECT_PTR(ce); if (ce->type == ZEND_USER_CLASS) { - RETURN_STR(STR_COPY(ce->info.user.filename)); +// TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? + RETURN_STR(STR_DUP(ce->info.user.filename, 0)); } RETURN_FALSE; } @@ -3813,7 +3816,7 @@ ZEND_METHOD(reflection_class, hasProperty) } else { if (Z_TYPE(intern->obj) != IS_UNDEF && Z_OBJ_HANDLER(intern->obj, has_property)) { ZVAL_STR(&property, STR_COPY(name)); - if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, 0 TSRMLS_CC)) { + if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, -1 TSRMLS_CC)) { zval_ptr_dtor(&property); RETURN_TRUE; } @@ -6065,7 +6068,7 @@ const zend_function_entry reflection_ext_functions[] = { /* {{{ */ static zend_object_handlers *zend_std_obj_handlers; /* {{{ _reflection_write_property */ -static void _reflection_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void _reflection_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { if ((Z_TYPE_P(member) == IS_STRING) && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STR_P(member)) @@ -6077,7 +6080,7 @@ static void _reflection_write_property(zval *object, zval *member, zval *value, } else { - zend_std_obj_handlers->write_property(object, member, value, key TSRMLS_CC); + zend_std_obj_handlers->write_property(object, member, value, cache_slot TSRMLS_CC); } } /* }}} */ diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 95225d1472..1c6a20c352 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -382,7 +382,7 @@ static zval *sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, z /* {{{ sxe_property_read() */ -static zval *sxe_property_read(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) +static zval *sxe_property_read(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) { return sxe_prop_dim_read(object, member, 1, 0, type, rv TSRMLS_CC); } @@ -666,7 +666,7 @@ next_iter: /* {{{ sxe_property_write() */ -static void sxe_property_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void sxe_property_write(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { sxe_prop_dim_write(object, member, value, 1, 0, NULL TSRMLS_CC); } @@ -680,7 +680,7 @@ static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_D } /* }}} */ -static zval *sxe_property_get_adr(zval *object, zval *member, int fetch_type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval *sxe_property_get_adr(zval *object, zval *member, int fetch_type, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { php_sxe_object *sxe; xmlNodePtr node; @@ -832,7 +832,7 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend /* {{{ sxe_property_exists() */ -static int sxe_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +static int sxe_property_exists(zval *object, zval *member, int check_empty, zend_uint cache_slot TSRMLS_DC) { return sxe_prop_dim_exists(object, member, check_empty, 1, 0 TSRMLS_CC); } @@ -957,7 +957,7 @@ next_iter: /* {{{ sxe_property_delete() */ -static void sxe_property_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) +static void sxe_property_delete(zval *object, zval *member, zend_uint cache_slot TSRMLS_DC) { sxe_prop_dim_delete(object, member, 1, 0 TSRMLS_CC); } @@ -971,7 +971,7 @@ static void sxe_dimension_delete(zval *object, zval *offset TSRMLS_DC) } /* }}} */ -static inline zend_string * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) /* {{{ */ +static inline zend_string *sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine TSRMLS_DC) /* {{{ */ { xmlChar *tmp = xmlNodeListGetString(doc, list, inLine); zend_string *res; @@ -1085,7 +1085,7 @@ static HashTable *sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ test = sxe->iter.name && sxe->iter.type == SXE_ITER_ATTRLIST; while (attr) { if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr)attr, sxe->iter.nsprefix, sxe->iter.isprefix)) { - ZVAL_STR(&value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1)); + ZVAL_STR(&value, sxe_xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1 TSRMLS_CC)); namelen = xmlStrlen(attr->name); if (ZVAL_IS_UNDEF(&zattr)) { array_init(&zattr); @@ -1103,7 +1103,7 @@ static HashTable *sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ if (node && sxe->iter.type != SXE_ITER_ATTRLIST) { if (node->type == XML_ATTRIBUTE_NODE) { - ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node->children, 1)); + ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node->children, 1 TSRMLS_CC)); zend_hash_next_index_insert(rv, &value); node = NULL; } else if (sxe->iter.type != SXE_ITER_CHILD) { @@ -1128,7 +1128,7 @@ static HashTable *sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ const xmlChar *cur = node->content; if (*cur != 0) { - ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node, 1)); + ZVAL_STR(&value, sxe_xmlNodeListGetString(node->doc, node, 1 TSRMLS_CC)); zend_hash_next_index_insert(rv, &value); } goto next_iter; @@ -2384,7 +2384,7 @@ PHP_FUNCTION(simplexml_import_dom) return; } - object = (php_libxml_node_object *)Z_SXEOBJ_P(node); + object = (php_libxml_node_object *) ((char *) Z_OBJ_P(node) - Z_OBJ_HT_P(node)->offset); nodep = php_libxml_import_node(node TSRMLS_CC); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 3d744af3a8..208f9de7a6 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -845,35 +845,35 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* } /* }}} */ -static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) /* {{{ */ +static zval *spl_array_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(object); if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 - && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { + && !std_object_handlers.has_property(object, member, 2, cache_slot TSRMLS_CC)) { return spl_array_read_dimension(object, member, type, rv TSRMLS_CC); } - return std_object_handlers.read_property(object, member, type, key, rv TSRMLS_CC); + return std_object_handlers.read_property(object, member, type, cache_slot, rv TSRMLS_CC); } /* }}} */ -static void spl_array_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */ +static void spl_array_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(object); if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 - && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { + && !std_object_handlers.has_property(object, member, 2, cache_slot TSRMLS_CC)) { spl_array_write_dimension(object, member, value TSRMLS_CC); return; } - std_object_handlers.write_property(object, member, value, key TSRMLS_CC); + std_object_handlers.write_property(object, member, value, cache_slot TSRMLS_CC); } /* }}} */ -static zval *spl_array_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval *spl_array_get_property_ptr_ptr(zval *object, zval *member, int type, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(object); if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 - && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { + && !std_object_handlers.has_property(object, member, 2, cache_slot TSRMLS_CC)) { return spl_array_get_dimension_ptr(1, object, member, type TSRMLS_CC); } //!!! FIXME @@ -881,28 +881,28 @@ static zval *spl_array_get_property_ptr_ptr(zval *object, zval *member, int type return NULL; } /* }}} */ -static int spl_array_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */ +static int spl_array_has_property(zval *object, zval *member, int has_set_exists, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(object); if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 - && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { + && !std_object_handlers.has_property(object, member, 2, cache_slot TSRMLS_CC)) { return spl_array_has_dimension(object, member, has_set_exists TSRMLS_CC); } - return std_object_handlers.has_property(object, member, has_set_exists, key TSRMLS_CC); + return std_object_handlers.has_property(object, member, has_set_exists, cache_slot TSRMLS_CC); } /* }}} */ -static void spl_array_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ +static void spl_array_unset_property(zval *object, zval *member, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { spl_array_object *intern = Z_SPLARRAY_P(object); if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0 - && !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) { + && !std_object_handlers.has_property(object, member, 2, cache_slot TSRMLS_CC)) { spl_array_unset_dimension(object, member TSRMLS_CC); spl_array_rewind(intern TSRMLS_CC); /* because deletion might invalidate position */ return; } - std_object_handlers.unset_property(object, member, key TSRMLS_CC); + std_object_handlers.unset_property(object, member, cache_slot TSRMLS_CC); } /* }}} */ static int spl_array_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 0400332dc4..9c80be4aaa 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -653,7 +653,7 @@ static HashTable *spl_filesystem_object_get_debug_info(zval *object, int *is_tem } /* }}} */ -zend_function *spl_filesystem_object_get_method_check(zend_object **object, zend_string *method, const struct _zend_literal *key TSRMLS_DC) /* {{{ */ +zend_function *spl_filesystem_object_get_method_check(zend_object **object, zend_string *method, const zval *key TSRMLS_DC) /* {{{ */ { spl_filesystem_object *fsobj = spl_filesystem_from_obj(*object); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index a227b82ffd..7bc67ec300 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -828,7 +828,7 @@ SPL_METHOD(RecursiveIteratorIterator, getMaxDepth) } } /* }}} */ -static union _zend_function *spl_recursive_it_get_method(zend_object **zobject, zend_string *method, const zend_literal *key TSRMLS_DC) +static union _zend_function *spl_recursive_it_get_method(zend_object **zobject, zend_string *method, const zval *key TSRMLS_DC) { union _zend_function *function_handler; spl_recursive_it_object *object = spl_recursive_it_from_obj(*zobject); @@ -1272,7 +1272,7 @@ static int spl_dual_it_gets_implemented(zend_class_entry *interface, zend_class_ } #endif -static union _zend_function *spl_dual_it_get_method(zend_object **object, zend_string *method, const zend_literal *key TSRMLS_DC) +static union _zend_function *spl_dual_it_get_method(zend_object **object, zend_string *method, const zval *key TSRMLS_DC) { union _zend_function *function_handler; spl_dual_it_object *intern; diff --git a/ext/standard/array.c b/ext/standard/array.c index 20ad3d9986..03c77fea80 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -281,17 +281,12 @@ static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */ cnt = zend_hash_num_elements(Z_ARRVAL_P(array)); if (mode == COUNT_RECURSIVE) { - HashPosition pos; - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - (element = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), element) { Z_ARRVAL_P(array)->nApplyCount++; ZVAL_DEREF(element); cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC); Z_ARRVAL_P(array)->nApplyCount--; - } + } ZEND_HASH_FOREACH_END(); } } @@ -1218,7 +1213,8 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ *array, /* array to check in */ *entry, /* pointer to array entry */ res; /* comparison result */ - HashPosition pos; /* hash iterator */ + ulong num_idx; + zend_string *str_idx; zend_bool strict = 0; /* strict comparison or not */ int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; @@ -1230,19 +1226,21 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ is_equal_func = is_identical_function; } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { is_equal_func(&res, value, entry TSRMLS_CC); if (Z_LVAL(res)) { if (behavior == 0) { RETURN_TRUE; } else { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), return_value, &pos); + if (str_idx) { + RETVAL_STR(STR_COPY(str_idx)); + } else { + RETVAL_LONG(num_idx); + } return; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); RETURN_FALSE; } @@ -1324,9 +1322,8 @@ PHP_FUNCTION(extract) zval *entry, data; zend_string *var_name; ulong num_key; - int var_exists, key_type, count = 0; + int var_exists, count = 0; int extract_refs = 0; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { return; @@ -1364,26 +1361,15 @@ PHP_FUNCTION(extract) SEPARATE_ARG_IF_REF(var_array); } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(var_array), num_key, var_name, entry) { zval final_name; - if (Z_TYPE_P(entry) == IS_INDIRECT) { - entry = Z_INDIRECT_P(entry); - if (Z_TYPE_P(entry) == IS_UNDEF) { - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); - continue; - } - } - ZVAL_NULL(&final_name); - - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &num_key, 0, &pos); var_exists = 0; - if (key_type == HASH_KEY_IS_STRING) { + if (var_name) { var_exists = zend_hash_exists_ind(&EG(active_symbol_table)->ht, var_name); - } else if (key_type == HASH_KEY_IS_LONG && (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID)) { + } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) { zval num; ZVAL_LONG(&num, num_key); @@ -1391,7 +1377,6 @@ PHP_FUNCTION(extract) php_prefix_varname(&final_name, prefix, Z_STRVAL(num), Z_STRLEN(num), 1 TSRMLS_CC); zval_dtor(&num); } else { - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); continue; } @@ -1469,9 +1454,7 @@ PHP_FUNCTION(extract) count++; } zval_dtor(&final_name); - - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); - } + } ZEND_HASH_FOREACH_END(); if (!extract_refs) { zval_ptr_dtor(var_array); @@ -1492,8 +1475,6 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } } else if (Z_TYPE_P(entry) == IS_ARRAY) { - HashPosition pos; - if ((Z_ARRVAL_P(entry)->nApplyCount > 1)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); return; @@ -1501,18 +1482,9 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu Z_ARRVAL_P(entry)->nApplyCount++; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); - while ((value_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) != NULL) { - if (Z_TYPE_P(value_ptr) == IS_INDIRECT) { - value_ptr = Z_INDIRECT_P(value_ptr); - if (Z_TYPE_P(value_ptr) == IS_UNDEF) { - zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); - continue; - } - } + ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(entry), value_ptr) { php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); - } + } ZEND_HASH_FOREACH_END(); Z_ARRVAL_P(entry)->nApplyCount--; } } @@ -1592,7 +1564,6 @@ PHP_FUNCTION(array_fill) PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az", &keys, &val) == FAILURE) { return; @@ -1601,8 +1572,7 @@ PHP_FUNCTION(array_fill_keys) /* Initialize return array */ array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(keys))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) { ZVAL_DEREF(entry); if (Z_TYPE_P(entry) == IS_LONG) { zval_add_ref(val); @@ -1623,9 +1593,7 @@ PHP_FUNCTION(array_fill_keys) zval_dtor(&key); } } - - zend_hash_move_forward_ex(Z_ARRVAL_P(keys), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2007,21 +1975,34 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end) /* Get the first or last value and copy it into the return value */ if (off_the_end) { zend_hash_internal_pointer_end(Z_ARRVAL_P(stack)); + while (1) { + val = zend_hash_get_current_data(Z_ARRVAL_P(stack)); + if (!val) { + return; + } else if (Z_TYPE_P(val) == IS_INDIRECT) { + val = Z_INDIRECT_P(val); + if (Z_TYPE_P(val) == IS_UNDEF) { + zend_hash_move_backwards(Z_ARRVAL_P(stack)); + continue; + } + } + break; + } } else { zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack)); - } - while (1) { - val = zend_hash_get_current_data(Z_ARRVAL_P(stack)); - if (!val) { - return; - } else if (Z_TYPE_P(val) == IS_INDIRECT) { - val = Z_INDIRECT_P(val); - if (Z_TYPE_P(val) == IS_UNDEF) { - zend_hash_move_forward(Z_ARRVAL_P(stack)); - continue; + while (1) { + val = zend_hash_get_current_data(Z_ARRVAL_P(stack)); + if (!val) { + return; + } else if (Z_TYPE_P(val) == IS_INDIRECT) { + val = Z_INDIRECT_P(val); + if (Z_TYPE_P(val) == IS_UNDEF) { + zend_hash_move_forward(Z_ARRVAL_P(stack)); + continue; + } } + break; } - break; } RETVAL_ZVAL_FAST(val); @@ -2209,7 +2190,6 @@ PHP_FUNCTION(array_slice) pos; /* Current position in the array */ zend_string *string_key; ulong num_key; - HashPosition hpos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|zb", &input, &offset, &z_length, &preserve_keys) == FAILURE) { return; @@ -2250,33 +2230,28 @@ PHP_FUNCTION(array_slice) /* Start at the beginning and go until we hit offset */ pos = 0; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &hpos); - while (pos < offset && (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &hpos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { pos++; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &hpos); - } - - /* Copy elements from input array to the one that's returned */ - while (pos < offset + length && (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &hpos)) != NULL) { + if (pos <= offset) { + continue; + } + if (pos > offset + length) { + break; + } + /* Copy elements from input array to the one that's returned */ zval_add_ref(entry); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &hpos)) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); - break; - - case HASH_KEY_IS_LONG: - if (preserve_keys) { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); - } else { - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); - } - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + } else { + if (preserve_keys) { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + } else { + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + } } - pos++; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &hpos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2285,87 +2260,80 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS zval *src_entry, *dest_entry; zend_string *string_key; ulong num_key; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(src, &pos); - while ((src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL) { - switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) { - zval *src_zval = src_entry; - zval *dest_zval = dest_entry; - HashTable *thash; - zval tmp; + + ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { + if (string_key) { + if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) { + zval *src_zval = src_entry; + zval *dest_zval = dest_entry; + HashTable *thash; + zval tmp; - ZVAL_DEREF(src_zval); - ZVAL_DEREF(dest_zval); - thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; - if ((thash && thash->nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); - return 0; - } + ZVAL_DEREF(src_zval); + ZVAL_DEREF(dest_zval); + thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; + if ((thash && thash->nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); + return 0; + } - if (Z_ISREF_P(dest_entry)) { - if (Z_REFCOUNT_P(dest_entry) == 1) { - ZVAL_UNREF(dest_entry); - } else { - Z_DELREF_P(dest_entry); - ZVAL_DUP(dest_entry, dest_zval); - } - dest_zval = dest_entry; + if (Z_ISREF_P(dest_entry)) { + if (Z_REFCOUNT_P(dest_entry) == 1) { + ZVAL_UNREF(dest_entry); } else { - SEPARATE_ZVAL(dest_zval); + Z_DELREF_P(dest_entry); + ZVAL_DUP(dest_entry, dest_zval); } + dest_zval = dest_entry; + } else { + SEPARATE_ZVAL(dest_zval); + } - if (Z_TYPE_P(dest_zval) == IS_NULL) { - convert_to_array_ex(dest_zval); - add_next_index_null(dest_zval); - } else { - convert_to_array_ex(dest_zval); - } - ZVAL_UNDEF(&tmp); - if (Z_TYPE_P(src_zval) == IS_OBJECT) { - ZVAL_DUP(&tmp, src_zval); - convert_to_array(&tmp); - src_zval = &tmp; + if (Z_TYPE_P(dest_zval) == IS_NULL) { + convert_to_array_ex(dest_zval); + add_next_index_null(dest_zval); + } else { + convert_to_array_ex(dest_zval); + } + ZVAL_UNDEF(&tmp); + if (Z_TYPE_P(src_zval) == IS_OBJECT) { + ZVAL_DUP(&tmp, src_zval); + convert_to_array(&tmp); + src_zval = &tmp; + } + if (Z_TYPE_P(src_zval) == IS_ARRAY) { + if (thash) { + thash->nApplyCount++; } - if (Z_TYPE_P(src_zval) == IS_ARRAY) { - if (thash) { - thash->nApplyCount++; - } - if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { - if (thash) { - thash->nApplyCount--; - } - return 0; - } + if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { if (thash) { thash->nApplyCount--; } - } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); + return 0; + } + if (thash) { + thash->nApplyCount--; } - zval_ptr_dtor(&tmp); } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_update(dest, string_key, src_entry); + zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); } - break; - - case HASH_KEY_IS_LONG: + zval_ptr_dtor(&tmp); + } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_next_index_insert(dest, src_entry); - break; + zend_hash_update(dest, string_key, src_entry); + } + } else { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + zend_hash_next_index_insert(dest, src_entry); } - zend_hash_move_forward_ex(src, &pos); - } + } ZEND_HASH_FOREACH_END(); return 1; } /* }}} */ @@ -2375,44 +2343,36 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC zval *src_entry, *dest_entry, *src_zval, *dest_zval; zend_string *string_key; ulong num_key; - HashPosition pos; - - for (zend_hash_internal_pointer_reset_ex(src, &pos); - (src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL; - zend_hash_move_forward_ex(src, &pos)) { + ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { src_zval = src_entry; ZVAL_DEREF(src_zval); - switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (Z_TYPE_P(src_zval) != IS_ARRAY || - (dest_entry = zend_hash_find(dest, string_key)) == NULL || - (Z_TYPE_P(dest_entry) != IS_ARRAY && - (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { - - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_update(dest, string_key, src_entry); + if (string_key) { + if (Z_TYPE_P(src_zval) != IS_ARRAY || + (dest_entry = zend_hash_find(dest, string_key)) == NULL || + (Z_TYPE_P(dest_entry) != IS_ARRAY && + (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { - continue; + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); } - break; - - case HASH_KEY_IS_LONG: - if (Z_TYPE_P(src_zval) != IS_ARRAY || - (dest_entry = zend_hash_index_find(dest, num_key)) == NULL || - (Z_TYPE_P(dest_entry) != IS_ARRAY && - (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { + zend_hash_update(dest, string_key, src_entry); - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_index_update(dest, num_key, src_entry); + continue; + } + } else { + if (Z_TYPE_P(src_zval) != IS_ARRAY || + (dest_entry = zend_hash_index_find(dest, num_key)) == NULL || + (Z_TYPE_P(dest_entry) != IS_ARRAY && + (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { - continue; + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); } - break; + zend_hash_index_update(dest, num_key, src_entry); + + continue; + } } dest_zval = dest_entry; @@ -2435,7 +2395,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC } Z_ARRVAL_P(dest_zval)->nApplyCount--; Z_ARRVAL_P(src_zval)->nApplyCount--; - } + } ZEND_HASH_FOREACH_END(); return 1; } @@ -2526,7 +2486,8 @@ PHP_FUNCTION(array_keys) new_val; /* New value */ int add_key; /* Flag to indicate whether a key should be added */ zend_bool strict = 0; /* do strict comparison */ - HashPosition pos; + ulong num_idx; + zend_string *str_idx; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zb", &input, &search_value, &strict) == FAILURE) { @@ -2546,20 +2507,21 @@ PHP_FUNCTION(array_keys) add_key = 1; /* Go through input array and add keys to the return array */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_idx, str_idx, entry) { if (search_value != NULL) { is_equal_func(&res, search_value, entry TSRMLS_CC); add_key = zval_is_true(&res); } if (add_key) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), &new_val, &pos); + if (str_idx) { + ZVAL_STR(&new_val, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&new_val, num_idx); + } zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2569,7 +2531,6 @@ PHP_FUNCTION(array_values) { zval *input, /* Input array */ *entry; /* An entry in the input array */ - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -2579,12 +2540,10 @@ PHP_FUNCTION(array_values) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input))); /* Go through input array and add values to the return array */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { zval_add_ref(entry); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2596,7 +2555,6 @@ PHP_FUNCTION(array_count_values) *entry, /* An entry in the input array */ *tmp; HashTable *myht; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -2607,8 +2565,7 @@ PHP_FUNCTION(array_count_values) /* Go through input array and add values to the return array */ myht = Z_ARRVAL_P(input); - zend_hash_internal_pointer_reset_ex(myht, &pos); - while ((entry = zend_hash_get_current_data_ex(myht, &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(myht, entry) { if (Z_TYPE_P(entry) == IS_LONG) { if ((tmp = zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_P(entry))) == NULL) { zval data; @@ -2628,9 +2585,7 @@ PHP_FUNCTION(array_count_values) } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!"); } - - zend_hash_move_forward_ex(myht, &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2666,7 +2621,6 @@ PHP_FUNCTION(array_column) { zval *zcolumn = NULL, *zkey = NULL, *data; HashTable *arr_hash; - HashPosition pointer; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hz!|z!", &arr_hash, &zcolumn, &zkey) == FAILURE) { return; @@ -2678,9 +2632,7 @@ PHP_FUNCTION(array_column) } array_init(return_value); - for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); - (data = zend_hash_get_current_data_ex(arr_hash, &pointer)) != NULL; - zend_hash_move_forward_ex(arr_hash, &pointer)) { + ZEND_HASH_FOREACH_VAL(arr_hash, data) { zval *zcolval, *zkeyval = NULL; HashTable *ht; @@ -2726,7 +2678,7 @@ PHP_FUNCTION(array_column) } else { add_next_index_zval(return_value, zcolval); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2739,7 +2691,6 @@ PHP_FUNCTION(array_reverse) zend_string *string_key; ulong num_key; zend_bool preserve_keys = 0; /* whether to preserve keys */ - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &input, &preserve_keys) == FAILURE) { return; @@ -2748,26 +2699,19 @@ PHP_FUNCTION(array_reverse) /* Initialize return array */ array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input))); - zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_REVERSE_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { zval_add_ref(entry); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); - break; - - case HASH_KEY_IS_LONG: - if (preserve_keys) { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); - } else { - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); - } - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + } else { + if (preserve_keys) { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + } else { + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + } } - - zend_hash_move_backwards_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2844,7 +2788,8 @@ PHP_FUNCTION(array_pad) PHP_FUNCTION(array_flip) { zval *array, *entry, data; - HashPosition pos; + ulong num_idx; + zend_string *str_idx; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { return; @@ -2852,21 +2797,25 @@ PHP_FUNCTION(array_flip) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), &data, &pos); - + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (Z_TYPE_P(entry) == IS_LONG) { + if (str_idx) { + ZVAL_STR(&data, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&data, num_idx); + } zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); } else if (Z_TYPE_P(entry) == IS_STRING) { + if (str_idx) { + ZVAL_STR(&data, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&data, num_idx); + } zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } else { - zval_ptr_dtor(&data); /* will free also zval structure */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only flip STRING and INTEGER values!"); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2879,7 +2828,6 @@ PHP_FUNCTION(array_change_key_case) zend_string *new_key; ulong num_key; long change_to_upper=0; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &change_to_upper) == FAILURE) { return; @@ -2887,28 +2835,22 @@ PHP_FUNCTION(array_change_key_case) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { zval_add_ref(entry); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); - break; - case HASH_KEY_IS_STRING: - new_key = STR_INIT(string_key->val, string_key->len, 0); - if (change_to_upper) { - php_strtoupper(new_key->val, new_key->len); - } else { - php_strtolower(new_key->val, new_key->len); - } - zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); - STR_RELEASE(new_key); - break; + if (!string_key) { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + } else { + new_key = STR_INIT(string_key->val, string_key->len, 0); + if (change_to_upper) { + php_strtoupper(new_key->val, new_key->len); + } else { + php_strtolower(new_key->val, new_key->len); + } + zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); + STR_RELEASE(new_key); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4116,10 +4058,9 @@ PHP_FUNCTION(array_rand) { zval *input; long randval, num_req = 1; - int num_avail, key_type; + int num_avail; zend_string *string_key; ulong num_key; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &input, &num_req) == FAILURE) { return; @@ -4140,22 +4081,24 @@ PHP_FUNCTION(array_rand) } /* We can't use zend_hash_index_find() because the array may have string keys or gaps. */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT) { + ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(input), num_key, string_key) { + if (!num_req) { + break; + } randval = php_rand(TSRMLS_C); if ((double) (randval / (PHP_RAND_MAX + 1.0)) < (double) num_req / (double) num_avail) { /* If we are returning a single result, just do it. */ if (Z_TYPE_P(return_value) != IS_ARRAY) { - if (key_type == HASH_KEY_IS_STRING) { + if (string_key) { RETURN_STR(STR_COPY(string_key)); } else { RETURN_LONG(num_key); } } else { /* Append the result to the return value. */ - if (key_type == HASH_KEY_IS_STRING) { + if (string_key) { add_next_index_str(return_value, STR_COPY(string_key)); } else { add_next_index_long(return_value, num_key); @@ -4164,8 +4107,7 @@ PHP_FUNCTION(array_rand) num_req--; } num_avail--; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4176,7 +4118,6 @@ PHP_FUNCTION(array_sum) zval *input, *entry, entry_n; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -4184,17 +4125,14 @@ PHP_FUNCTION(array_sum) ZVAL_LONG(return_value, 0); - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) { continue; } ZVAL_DUP(&entry_n, entry); convert_scalar_to_number(&entry_n TSRMLS_CC); fast_add_function(return_value, return_value, &entry_n TSRMLS_CC); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4205,7 +4143,6 @@ PHP_FUNCTION(array_product) zval *input, *entry, entry_n; - HashPosition pos; double dval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { @@ -4217,10 +4154,7 @@ PHP_FUNCTION(array_product) return; } - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) { continue; } @@ -4237,7 +4171,7 @@ PHP_FUNCTION(array_product) convert_to_double(return_value); convert_to_double(&entry_n); Z_DVAL_P(return_value) *= Z_DVAL(entry_n); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4253,7 +4187,6 @@ PHP_FUNCTION(array_reduce) zend_fcall_info fci; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; zval *initial = NULL; - HashPosition pos; HashTable *htbl; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af|z", &input, &fci, &fci_cache, &initial) == FAILURE) { @@ -4280,8 +4213,7 @@ PHP_FUNCTION(array_reduce) fci.param_count = 2; fci.no_separation = 0; - zend_hash_internal_pointer_reset_ex(htbl, &pos); - while ((operand = zend_hash_get_current_data_ex(htbl, &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(htbl, operand) { ZVAL_COPY_VALUE(&args[0], &result); ZVAL_COPY_VALUE(&args[1], operand); fci.params = args; @@ -4293,8 +4225,8 @@ PHP_FUNCTION(array_reduce) php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback"); return; } - zend_hash_move_forward_ex(htbl, &pos); - } + } ZEND_HASH_FOREACH_END(); + RETVAL_ZVAL(&result, 1, 1); } /* }}} */ @@ -4313,7 +4245,6 @@ PHP_FUNCTION(array_filter) zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; ulong num_key; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fl", &array, &fci, &fci_cache, &use_type) == FAILURE) { return; @@ -4331,32 +4262,23 @@ PHP_FUNCTION(array_filter) fci.param_count = 1; } - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - (operand = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) - ) { - int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos); - + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, operand) { if (have_callback) { if (use_type) { /* Set up the key */ - switch (key_type) { - case HASH_KEY_IS_LONG: - if (use_type == ARRAY_FILTER_USE_BOTH) { - fci.param_count = 2; - ZVAL_LONG(&args[1], num_key); - } else if (use_type == ARRAY_FILTER_USE_KEY) { - ZVAL_LONG(&args[0], num_key); - } - break; - - case HASH_KEY_IS_STRING: - if (use_type == ARRAY_FILTER_USE_BOTH) { - ZVAL_STR(&args[1], STR_COPY(string_key)); - } else if (use_type == ARRAY_FILTER_USE_KEY) { - ZVAL_STR(&args[0], STR_COPY(string_key)); - } - break; + if (!string_key) { + if (use_type == ARRAY_FILTER_USE_BOTH) { + fci.param_count = 2; + ZVAL_LONG(&args[1], num_key); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_LONG(&args[0], num_key); + } + } else { + if (use_type == ARRAY_FILTER_USE_BOTH) { + ZVAL_STR(&args[1], STR_COPY(string_key)); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_STR(&args[0], STR_COPY(string_key)); + } } } if (use_type != ARRAY_FILTER_USE_KEY) { @@ -4392,16 +4314,12 @@ PHP_FUNCTION(array_filter) } zval_add_ref(operand); - switch (key_type) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand); - break; - - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand); - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand); + } else { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4584,7 +4502,6 @@ PHP_FUNCTION(array_chunk) zval *input = NULL; zval chunk; zval *entry; - HashPosition pos; if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) { return; @@ -4604,8 +4521,8 @@ PHP_FUNCTION(array_chunk) array_init_size(return_value, ((num_in - 1) / size) + 1); ZVAL_UNDEF(&chunk); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) { /* If new chunk, create and initialize it. */ if (Z_TYPE(chunk) == IS_UNDEF) { array_init_size(&chunk, size); @@ -4615,14 +4532,10 @@ PHP_FUNCTION(array_chunk) zval_add_ref(entry); if (preserve_keys) { - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &num_key, 0, &pos); - switch (key_type) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL(chunk), str_key, entry); - break; - default: - add_index_zval(&chunk, num_key, entry); - break; + if (str_key) { + zend_hash_update(Z_ARRVAL(chunk), str_key, entry); + } else { + add_index_zval(&chunk, num_key, entry); } } else { add_next_index_zval(&chunk, entry); @@ -4634,9 +4547,7 @@ PHP_FUNCTION(array_chunk) add_next_index_zval(return_value, &chunk); ZVAL_UNDEF(&chunk); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); /* Add the final chunk if there is one. */ if (Z_TYPE(chunk) != IS_UNDEF) { diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 9d6878817e..bf9a5a94db 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4281,11 +4281,8 @@ PHP_FUNCTION(getopt) * and a trailing NULL */ argv = (char **) safe_emalloc(sizeof(char *), (argc + 1), 0); - /* Reset the array indexes. */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(args)); - /* Iterate over the hash to construct the argv array. */ - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(args))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), entry) { zval arg, *arg_ptr = entry; if (Z_TYPE_P(entry) != IS_STRING) { @@ -4299,9 +4296,7 @@ PHP_FUNCTION(getopt) if (arg_ptr != entry) { zval_dtor(&arg); } - - zend_hash_move_forward(Z_ARRVAL_P(args)); - } + } ZEND_HASH_FOREACH_END(); /* The C Standard requires argv[argc] to be NULL - this might * keep some getopt implementations happy. */ @@ -4327,11 +4322,8 @@ PHP_FUNCTION(getopt) memset(opts, 0, count * sizeof(opt_struct)); - /* Reset the array indexes. */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p_longopts)); - /* Iterate over the hash to construct the argv array. */ - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(p_longopts))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(p_longopts), entry) { zval arg, *arg_ptr = entry; if (Z_TYPE_P(entry) != IS_STRING) { @@ -4357,9 +4349,7 @@ PHP_FUNCTION(getopt) if (arg_ptr != entry) { zval_dtor(&arg); } - - zend_hash_move_forward(Z_ARRVAL_P(p_longopts)); - } + } ZEND_HASH_FOREACH_END(); } else { opts = (opt_struct*) erealloc(opts, sizeof(opt_struct) * (len + 1)); orig_opts = opts; @@ -4877,13 +4867,10 @@ PHP_FUNCTION(call_user_method_array) num_elems = zend_hash_num_elements(params_ar); method_args = (zval *) safe_emalloc(sizeof(zval), num_elems, 0); - for (zend_hash_internal_pointer_reset(params_ar); - (zv = zend_hash_get_current_data(params_ar)) != NULL; - zend_hash_move_forward(params_ar) - ) { + ZEND_HASH_FOREACH_VAL(params_ar, zv) { ZVAL_COPY_VALUE(&method_args[element], zv); element++; - } + } ZEND_HASH_FOREACH_END(); if (call_user_function_ex(EG(function_table), object, callback, &retval, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { diff --git a/ext/standard/file.c b/ext/standard/file.c index 536cdfb269..75197463a1 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -647,10 +647,8 @@ PHP_FUNCTION(file_put_contents) if (zend_hash_num_elements(Z_ARRVAL_P(data))) { int bytes_written; zval *tmp; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos); - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(data), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), tmp) { if (Z_TYPE_P(tmp) != IS_STRING) { SEPARATE_ZVAL(tmp); convert_to_string(tmp); @@ -668,8 +666,7 @@ PHP_FUNCTION(file_put_contents) break; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos); - } + } ZEND_HASH_FOREACH_END(); } break; @@ -1084,10 +1081,11 @@ PHPAPI PHP_FUNCTION(fgetss) size_t actual_len, retval_len; char *buf = NULL, *retval; php_stream *stream; + zend_string *allowed = NULL; char *allowed_tags=NULL; int allowed_tags_len=0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ls", &fd, &bytes, &allowed_tags, &allowed_tags_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|lS", &fd, &bytes, &allowed) == FAILURE) { RETURN_FALSE; } @@ -1112,8 +1110,24 @@ PHPAPI PHP_FUNCTION(fgetss) RETURN_FALSE; } + if (allowed != NULL) { +// TODO: reimplement to avoid reallocation ??? + if (IS_INTERNED(allowed)) { + allowed_tags = estrndup(allowed->val, allowed->len); + allowed_tags_len = allowed->len; + } else { + allowed_tags = allowed->val; + allowed_tags_len = allowed->len; + } + } + retval_len = php_strip_tags(retval, actual_len, &stream->fgetss_state, allowed_tags, allowed_tags_len); +// TODO: reimplement to avoid reallocation ??? + if (allowed && IS_INTERNED(allowed)) { + efree(allowed_tags); + } + // TODO: avoid reallocation ??? RETVAL_STRINGL(retval, retval_len); efree(retval); @@ -1865,11 +1879,9 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en int count, i = 0, ret; zval *field_tmp = NULL, field; smart_str csvline = {0}; - HashPosition pos; count = zend_hash_num_elements(Z_ARRVAL_P(fields)); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos); - while ((field_tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), field_tmp) { ZVAL_COPY_VALUE(&field, field_tmp); if (Z_TYPE(field) != IS_STRING) { @@ -1910,12 +1922,10 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en if (++i != count) { smart_str_appendl(&csvline, &delimiter, 1); } - zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos); - if (Z_TYPE_P(field_tmp) != IS_STRING) { zval_dtor(&field); } - } + } ZEND_HASH_FOREACH_END(); smart_str_appendc(&csvline, '\n'); smart_str_0(&csvline); diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 55737c97af..6897cde094 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -258,17 +258,14 @@ static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zv if (filterparams != NULL) { if (Z_TYPE_P(filterparams) == IS_ARRAY) { - HashPosition pos; zval *tmp; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(filterparams), &pos); - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(filterparams), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(filterparams), tmp) { convert_to_string_ex(tmp); smart_str_appendc(&tags_ss, '<'); smart_str_appendl(&tags_ss, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); smart_str_appendc(&tags_ss, '>'); - zend_hash_move_forward_ex(Z_ARRVAL_P(filterparams), &pos); - } + } ZEND_HASH_FOREACH_END(); smart_str_0(&tags_ss); } else { /* FIXME: convert_to_* may clutter zvals and lead it into segfault ? */ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 2e6e2f672b..622fbfbb3f 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -404,12 +404,10 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) newargs = (zval *)safe_emalloc(argc, sizeof(zval), 0); ZVAL_COPY_VALUE(&newargs[0], z_format); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array)); - (zv = zend_hash_get_current_data(Z_ARRVAL_P(array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(array))) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), zv) { ZVAL_COPY_VALUE(&newargs[i], zv); i++; - } + } ZEND_HASH_FOREACH_END(); args = newargs; format_offset = 0; } diff --git a/ext/standard/http.c b/ext/standard/http.c index 46af753ecc..b839a4cb97 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -33,7 +33,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, { zend_string *key = NULL; char *newprefix, *p, *prop_name; - int arg_sep_len, key_type, newprefix_len, prop_len; + int arg_sep_len, newprefix_len, prop_len; ulong idx; zval *zdata = NULL, copyzval; @@ -54,10 +54,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } arg_sep_len = strlen(arg_sep); - for (zend_hash_internal_pointer_reset(ht); - (key_type = zend_hash_get_current_key(ht, &key, &idx, 0)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward(ht) - ) { + ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, zdata) { /* handling for private & protected object properties */ if (key) { if (key->val[0] == '\0' && type != NULL) { @@ -78,18 +75,8 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, prop_len = 0; } - if ((zdata = zend_hash_get_current_data(ht)) == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); - return FAILURE; - } - if (Z_TYPE_P(zdata) == IS_INDIRECT) { - zdata = Z_INDIRECT_P(zdata); - if (Z_TYPE_P(zdata) == IS_UNDEF) { - continue; - } - } if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { - if (key_type == HASH_KEY_IS_STRING) { + if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); @@ -160,7 +147,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); - if (key_type == HASH_KEY_IS_STRING) { + if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); @@ -230,7 +217,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } } } - } + } ZEND_HASH_FOREACH_END(); return SUCCESS; } diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 9e7a906ce2..7ac15a69ca 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -237,12 +237,9 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *s, *p; if (Z_TYPE_P(tmpzval) == IS_ARRAY) { - HashPosition pos; zval *tmpheader = NULL; - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpzval), &pos); - NULL != (tmpheader = zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpzval), &pos)); - zend_hash_move_forward_ex(Z_ARRVAL_P(tmpzval), &pos)) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmpzval), tmpheader) { if (Z_TYPE_P(tmpheader) == IS_STRING) { s = Z_STRVAL_P(tmpheader); do { @@ -266,7 +263,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } - } + } ZEND_HASH_FOREACH_END(); } else if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval)) { s = Z_STRVAL_P(tmpzval); do { @@ -423,19 +420,15 @@ finish: tmp = NULL; if (Z_TYPE_P(tmpzval) == IS_ARRAY) { - HashPosition pos; zval *tmpheader = NULL; smart_str tmpstr = {0}; - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpzval), &pos); - NULL != (tmpheader = zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpzval), &pos)); - zend_hash_move_forward_ex(Z_ARRVAL_P(tmpzval), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmpzval), tmpheader) { if (Z_TYPE_P(tmpheader) == IS_STRING) { smart_str_appendl(&tmpstr, Z_STRVAL_P(tmpheader), Z_STRLEN_P(tmpheader)); smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1); } - } + } ZEND_HASH_FOREACH_END(); smart_str_0(&tmpstr); /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */ if (tmpstr.s) { diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index c017edff89..0a08ad4929 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -49,7 +49,7 @@ static void incomplete_class_message(zval *object, int error_type TSRMLS_DC) } /* }}} */ -static zval *incomplete_class_get_property(zval *object, zval *member, int type, const zend_literal *key, zval *rv TSRMLS_DC) /* {{{ */ +static zval *incomplete_class_get_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) /* {{{ */ { incomplete_class_message(object, E_NOTICE TSRMLS_CC); @@ -61,33 +61,33 @@ static zval *incomplete_class_get_property(zval *object, zval *member, int type, } /* }}} */ -static void incomplete_class_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */ +static void incomplete_class_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { incomplete_class_message(object, E_NOTICE TSRMLS_CC); } /* }}} */ -static zval *incomplete_class_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval *incomplete_class_get_property_ptr_ptr(zval *object, zval *member, int type, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { incomplete_class_message(object, E_NOTICE TSRMLS_CC); return &EG(error_zval); } /* }}} */ -static void incomplete_class_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ +static void incomplete_class_unset_property(zval *object, zval *member, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { incomplete_class_message(object, E_NOTICE TSRMLS_CC); } /* }}} */ -static int incomplete_class_has_property(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) /* {{{ */ +static int incomplete_class_has_property(zval *object, zval *member, int check_empty, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { incomplete_class_message(object, E_NOTICE TSRMLS_CC); return 0; } /* }}} */ -static union _zend_function *incomplete_class_get_method(zend_object **object, zend_string *method, const zend_literal *key TSRMLS_DC) /* {{{ */ +static union _zend_function *incomplete_class_get_method(zend_object **object, zend_string *method, const zval *key TSRMLS_DC) /* {{{ */ { zval zobject; diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index c18077a2d5..d5eb85d371 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -85,7 +85,6 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent uint cnt, l, sizeenv=0, el_len; ulong num_key; HashTable *target_hash; - HashPosition pos; memset(&env, 0, sizeof(env)); @@ -109,10 +108,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } /* first, we have to get the size of all the elements in the hash */ - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - (element = zend_hash_get_current_data_ex(target_hash, &pos)) != NULL; - zend_hash_move_forward_ex(target_hash, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { convert_to_string_ex(element); el_len = Z_STRLEN_P(element); if (el_len == 0) { @@ -121,25 +117,20 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent sizeenv += el_len+1; - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { - continue; - } - sizeenv += string_key->len + 2; - break; + if (string_key) { + if (string_key->len == 0) { + continue; + } + sizeenv += string_key->len + 2; } - } + } ZEND_HASH_FOREACH_END(); #ifndef PHP_WIN32 ep = env.envarray = (char **) pecalloc(cnt + 1, sizeof(char *), is_persistent); #endif p = env.envp = (char *) pecalloc(sizeenv + 4, 1, is_persistent); - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - (element = zend_hash_get_current_data_ex(target_hash, &pos)) != NULL; - zend_hash_move_forward_ex(target_hash, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { convert_to_string_ex(element); el_len = Z_STRLEN_P(element); @@ -148,40 +139,34 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } data = Z_STRVAL_P(element); - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { - continue; - } - l = string_key->len + el_len + 2; - memcpy(p, string_key->val, string_key->len); - strncat(p, "=", 1); - strncat(p, data, el_len); + if (string_key) { + if (string_key->len == 0) { + continue; + } + + l = string_key->len + el_len + 2; + memcpy(p, string_key->val, string_key->len); + strncat(p, "=", 1); + strncat(p, data, el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += l; - break; - case HASH_KEY_IS_LONG: - memcpy(p,data,el_len); + p += l; + } else { + memcpy(p,data,el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += el_len + 1; - break; - case HASH_KEY_NON_EXISTENT: - break; + p += el_len + 1; } - } + } ZEND_HASH_FOREACH_END(); assert((uint)(p - env.envp) <= sizeenv); - zend_hash_internal_pointer_reset_ex(target_hash, &pos); - return env; } /* }}} */ @@ -442,7 +427,8 @@ PHP_FUNCTION(proc_open) int ndesc = 0; int i; zval *descitem = NULL; - HashPosition pos; + zend_string *str_index; + ulong nindex; struct php_proc_open_descriptor_item descriptors[PHP_PROC_OPEN_MAX_DESCRIPTORS]; #ifdef PHP_WIN32 PROCESS_INFORMATION pi; @@ -519,15 +505,9 @@ PHP_FUNCTION(proc_open) #endif /* walk the descriptor spec and set up files/pipes */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(descriptorspec), &pos); - while ((descitem = zend_hash_get_current_data_ex(Z_ARRVAL_P(descriptorspec), &pos)) != NULL) { - zend_string *str_index; - ulong nindex; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(descriptorspec), nindex, str_index, descitem) { zval *ztype; - str_index = NULL; - zend_hash_get_current_key_ex(Z_ARRVAL_P(descriptorspec), &str_index, &nindex, 0, &pos); - if (str_index) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor spec must be an integer indexed array"); goto exit_fail; @@ -685,10 +665,9 @@ PHP_FUNCTION(proc_open) } } - zend_hash_move_forward_ex(Z_ARRVAL_P(descriptorspec), &pos); if (++ndesc == PHP_PROC_OPEN_MAX_DESCRIPTORS) break; - } + } ZEND_HASH_FOREACH_END(); #ifdef PHP_WIN32 if (cwd == NULL) { diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index e668b973b4..c39a9f3310 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -555,14 +555,10 @@ PHP_FUNCTION(stream_get_transports) } if ((stream_xport_hash = php_stream_xport_get_hash())) { - HashPosition pos; array_init(return_value); - zend_hash_internal_pointer_reset_ex(stream_xport_hash, &pos); - while (zend_hash_get_current_key_ex(stream_xport_hash, - &stream_xport, &num_key, 0, &pos) == HASH_KEY_IS_STRING) { + ZEND_HASH_FOREACH_KEY(stream_xport_hash, num_key, stream_xport) { add_next_index_str(return_value, STR_COPY(stream_xport)); - zend_hash_move_forward_ex(stream_xport_hash, &pos); - } + } ZEND_HASH_FOREACH_END(); } else { RETURN_FALSE; } @@ -583,15 +579,12 @@ PHP_FUNCTION(stream_get_wrappers) } if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) { - HashPosition pos; array_init(return_value); - for (zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos); - (key_flags = zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) { - if (key_flags == HASH_KEY_IS_STRING) { - add_next_index_str(return_value, STR_COPY(stream_protocol)); - } - } + ZEND_HASH_FOREACH_KEY(url_stream_wrappers_hash, num_key, stream_protocol) { + if (key_flags == HASH_KEY_IS_STRING) { + add_next_index_str(return_value, STR_COPY(stream_protocol)); + } + } ZEND_HASH_FOREACH_END(); } else { RETURN_FALSE; } @@ -610,10 +603,7 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t return 0; } - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ @@ -639,7 +629,8 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t } cnt++; } - } + } ZEND_HASH_FOREACH_END(); + return cnt ? 1 : 0; } @@ -648,6 +639,8 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) zval *elem, *dest_elem, new_array; php_stream *stream; int ret = 0; + zend_string *key; + ulong num_ind; if (Z_TYPE_P(stream_array) != IS_ARRAY) { return 0; @@ -655,26 +648,12 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) ZVAL_NEW_ARR(&new_array); zend_hash_init(Z_ARRVAL(new_array), zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - zend_hash_has_more_elements(Z_ARRVAL_P(stream_array)) == SUCCESS; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - - int type; - zend_string *key; - ulong num_ind; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ int tmp_fd; - - type = zend_hash_get_current_key(Z_ARRVAL_P(stream_array), - &key, &num_ind, 0); - if (type == HASH_KEY_NON_EXISTENT || - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) == NULL) { - continue; /* should not happen */ - } - php_stream_from_zval_no_verify(stream, elem); if (stream == NULL) { continue; @@ -689,9 +668,9 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) php_socket_t this_fd = (php_socket_t)tmp_fd; if (PHP_SAFE_FD_ISSET(this_fd, fds)) { - if (type == HASH_KEY_IS_LONG) { + if (!key) { dest_elem = zend_hash_index_update(Z_ARRVAL(new_array), num_ind, elem); - } else { /* HASH_KEY_IS_STRING */ + } else { dest_elem = zend_hash_update(Z_ARRVAL(new_array), key, elem); } @@ -702,14 +681,13 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) continue; } } - } + } ZEND_HASH_FOREACH_END(); /* destroy old array and add new one */ zend_hash_destroy(Z_ARRVAL_P(stream_array)); GC_REMOVE_FROM_BUFFER(Z_ARR_P(stream_array)); efree(Z_ARR_P(stream_array)); - zend_hash_internal_pointer_reset(Z_ARRVAL(new_array)); Z_ARR_P(stream_array) = Z_ARR(new_array); return ret; @@ -727,10 +705,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) ZVAL_NEW_ARR(&new_array); zend_hash_init(Z_ARRVAL(new_array), zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { php_stream_from_zval_no_verify(stream, elem); if (stream == NULL) { continue; @@ -749,14 +724,12 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) ret++; continue; } - } + } ZEND_HASH_FOREACH_END(); if (ret > 0) { /* destroy old array and add new one */ zend_hash_destroy(Z_ARRVAL_P(stream_array)); efree(Z_ARR_P(stream_array)); - - zend_hash_internal_pointer_reset(Z_ARRVAL(new_array)); Z_ARR_P(stream_array) = Z_ARR(new_array); } else { zend_hash_destroy(Z_ARRVAL(new_array)); @@ -911,31 +884,24 @@ static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) static int parse_context_options(php_stream_context *context, zval *options TSRMLS_DC) { - HashPosition pos, opos; zval *wval, *oval; zend_string *wkey, *okey; int ret = SUCCESS; ulong num_key; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(options), &pos); - while (NULL != (wval = zend_hash_get_current_data_ex(Z_ARRVAL_P(options), &pos))) { - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(options), &wkey, &num_key, 0, &pos) - && Z_TYPE_P(wval) == IS_ARRAY) { - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(wval), &opos); - while (NULL != (oval = zend_hash_get_current_data_ex(Z_ARRVAL_P(wval), &opos))) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), num_key, wkey, wval) { + if (wkey && Z_TYPE_P(wval) == IS_ARRAY) { - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(wval), &okey, &num_key, 0, &opos)) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(wval), num_key, okey, oval) { + if (okey) { php_stream_context_set_option(context, wkey->val, okey->val, oval); } - zend_hash_move_forward_ex(Z_ARRVAL_P(wval), &opos); - } + } ZEND_HASH_FOREACH_END(); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "options should have the form [\"wrappername\"][\"optionname\"] = $value"); } - zend_hash_move_forward_ex(Z_ARRVAL_P(options), &pos); - } + } ZEND_HASH_FOREACH_END(); return ret; } diff --git a/ext/standard/string.c b/ext/standard/string.c index 290fa21879..a1ea1cbf45 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1121,7 +1121,6 @@ PHP_FUNCTION(explode) PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) { zval *tmp; - HashPosition pos; smart_str implstr = {0}; int numelems, i = 0; zval tmp_val; @@ -1133,9 +1132,7 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) RETURN_EMPTY_STRING(); } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); - - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) { again: switch (Z_TYPE_P(tmp)) { case IS_STRING: @@ -1191,8 +1188,8 @@ again: if (++i != numelems) { smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); } - zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); - } + } ZEND_HASH_FOREACH_END(); + smart_str_0(&implstr); if (implstr.s) { @@ -2871,56 +2868,49 @@ static void php_strtr_free_strp(void *strp) static PATNREPL *php_strtr_array_prepare_repls(int slen, HashTable *pats, zend_llist **allocs, int *outsize) { PATNREPL *patterns; - HashPosition hpos; zval *entry; int num_pats = zend_hash_num_elements(pats), - i; + i = 0; + zend_string *string_key; + ulong num_key; patterns = safe_emalloc(num_pats, sizeof(*patterns), 0); *allocs = emalloc(sizeof **allocs); zend_llist_init(*allocs, sizeof(zend_string*), &php_strtr_free_strp, 0); - for (i = 0, zend_hash_internal_pointer_reset_ex(pats, &hpos); - (entry = zend_hash_get_current_data_ex(pats, &hpos)) != NULL; - zend_hash_move_forward_ex(pats, &hpos)) { - zend_string *string_key; - ulong num_key; + ZEND_HASH_FOREACH_KEY_VAL(pats, num_key, string_key, entry) { zval tzv; - switch (zend_hash_get_current_key_ex(pats, &string_key, &num_key, 0, &hpos)) { - case HASH_KEY_IS_LONG: { + if (!string_key) { char buf[MAX_LENGTH_OF_LONG]; int len = snprintf(buf, sizeof(buf), "%ld", num_key); string_key = STR_INIT(buf, len, 0); zend_llist_add_element(*allocs, &string_key); - /* break missing intentionally */ - } - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { /* empty string given as pattern */ - efree(patterns); - zend_llist_destroy(*allocs); - efree(*allocs); - *allocs = NULL; - return NULL; - } - if (string_key->len > slen) { /* this pattern can never match */ - continue; - } - - if (Z_TYPE_P(entry) != IS_STRING) { - ZVAL_DUP(&tzv, entry); - convert_to_string(&tzv); - entry = &tzv; - zend_llist_add_element(*allocs, &Z_STR_P(entry)); - } + } + if (string_key->len == 0) { /* empty string given as pattern */ + efree(patterns); + zend_llist_destroy(*allocs); + efree(*allocs); + *allocs = NULL; + return NULL; + } + if (string_key->len > slen) { /* this pattern can never match */ + continue; + } - S(&patterns[i].pat) = string_key->val; - L(&patterns[i].pat) = string_key->len; - S(&patterns[i].repl) = Z_STRVAL_P(entry); - L(&patterns[i].repl) = Z_STRLEN_P(entry); - i++; + if (Z_TYPE_P(entry) != IS_STRING) { + ZVAL_DUP(&tzv, entry); + convert_to_string(&tzv); + entry = &tzv; + zend_llist_add_element(*allocs, &Z_STR_P(entry)); } - } + + S(&patterns[i].pat) = string_key->val; + L(&patterns[i].pat) = string_key->len; + S(&patterns[i].repl) = Z_STRVAL_P(entry); + L(&patterns[i].repl) = Z_STRLEN_P(entry); + i++; + } ZEND_HASH_FOREACH_END(); *outsize = i; return patterns; @@ -3826,8 +3816,6 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval *subjec /* Duplicate subject string for repeated replacement */ ZVAL_DUP(result, subject); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(search)); - if (Z_TYPE_P(replace) == IS_ARRAY) { zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); } else { @@ -3837,12 +3825,11 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval *subjec } /* For each entry in the search array, get the entry */ - while ((search_entry = zend_hash_get_current_data(Z_ARRVAL_P(search))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(search), search_entry) { /* Make sure we're dealing with strings. */ SEPARATE_ZVAL(search_entry); convert_to_string(search_entry); if (Z_STRLEN_P(search_entry) == 0) { - zend_hash_move_forward(Z_ARRVAL_P(search)); if (Z_TYPE_P(replace) == IS_ARRAY) { zend_hash_move_forward(Z_ARRVAL_P(replace)); } @@ -3891,9 +3878,7 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval *subjec zval_ptr_dtor(&tmp_subject); return; } - - zend_hash_move_forward(Z_ARRVAL_P(search)); - } + } ZEND_HASH_FOREACH_END(); } else { if (Z_STRLEN_P(search) == 1) { php_char_to_str_ex(Z_STRVAL_P(subject), @@ -4283,12 +4268,23 @@ PHP_FUNCTION(strip_tags) /* To maintain a certain BC, we allow anything for the second parameter and return original string */ if (allow != NULL) { convert_to_string_ex(allow); - allowed_tags = Z_STRVAL_P(allow); - allowed_tags_len = Z_STRLEN_P(allow); +// TODO: reimplement to avoid reallocation ??? + if (IS_INTERNED(Z_STR_P(allow))) { + allowed_tags = estrndup(Z_STRVAL_P(allow), Z_STRLEN_P(allow)); + allowed_tags_len = Z_STRLEN_P(allow); + } else { + allowed_tags = Z_STRVAL_P(allow); + allowed_tags_len = Z_STRLEN_P(allow); + } } buf = STR_INIT(str, str_len, 0); buf->len = php_strip_tags_ex(buf->val, str_len, NULL, allowed_tags, allowed_tags_len, 0); + +// TODO: reimplement to avoid reallocation ??? + if (allow && IS_INTERNED(Z_STR_P(allow))) { + efree(allowed_tags); + } RETURN_STR(buf); } /* }}} */ diff --git a/ext/standard/type.c b/ext/standard/type.c index 3feac632d8..c4fdbc87e3 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -387,14 +387,16 @@ PHP_FUNCTION(is_callable) check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY; } if (ZEND_NUM_ARGS() > 2) { - if (callable_name) { - ZVAL_DEREF(callable_name); - } + ZVAL_DEREF(callable_name); retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error TSRMLS_CC); zval_dtor(callable_name); //??? is it necessary to be consistent with old PHP ("\0" support) - name->len = strlen(name->val); - ZVAL_STR(callable_name, name); + if (UNEXPECTED(name->len) != strlen(name->val)) { + ZVAL_STRINGL(callable_name, name->val, strlen(name->val)); + STR_RELEASE(name); + } else { + ZVAL_STR(callable_name, name); + } } else { retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error TSRMLS_CC); } diff --git a/ext/standard/url.c b/ext/standard/url.c index fc49dc3264..c7149dd9f3 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -694,7 +694,6 @@ PHP_FUNCTION(get_headers) php_stream_context *context; php_stream *stream; zval *prev_val, *hdr = NULL, *h; - HashPosition pos; HashTable *hashT; long format = 0; @@ -726,10 +725,8 @@ PHP_FUNCTION(get_headers) hashT = HASH_OF(&stream->wrapperdata); } - zend_hash_internal_pointer_reset_ex(hashT, &pos); - while ((hdr = zend_hash_get_current_data_ex(hashT, &pos)) != NULL) { - if (!hdr || Z_TYPE_P(hdr) != IS_STRING) { - zend_hash_move_forward_ex(hashT, &pos); + ZEND_HASH_FOREACH_VAL(hashT, hdr) { + if (Z_TYPE_P(hdr) != IS_STRING) { continue; } if (!format) { @@ -759,8 +756,7 @@ no_name_header: goto no_name_header; } } - zend_hash_move_forward_ex(hashT, &pos); - } + } ZEND_HASH_FOREACH_END(); php_stream_close(stream); } diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 44b96e3bdd..762b65387a 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -248,7 +248,7 @@ php_stream_filter_status_t userfilter_filter( * keeping a reference to the stream resource here would prevent it * from being destroyed properly */ ZVAL_STRINGL(&zpropname, "stream", sizeof("stream")-1); - Z_OBJ_HANDLER_P(obj, unset_property)(obj, &zpropname, 0 TSRMLS_CC); + Z_OBJ_HANDLER_P(obj, unset_property)(obj, &zpropname, -1 TSRMLS_CC); zval_ptr_dtor(&zpropname); zval_ptr_dtor(&args[3]); @@ -543,12 +543,11 @@ PHP_FUNCTION(stream_get_filters) filters_hash = php_get_stream_filters_hash(); if (filters_hash) { - for(zend_hash_internal_pointer_reset(filters_hash); - (key_flags = zend_hash_get_current_key(filters_hash, &filter_name, &num_key, 0)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward(filters_hash)) - if (key_flags == HASH_KEY_IS_STRING) { - add_next_index_str(return_value, STR_COPY(filter_name)); - } + ZEND_HASH_FOREACH_VAL(filters_hash, key_flags) { + if (key_flags == HASH_KEY_IS_STRING) { + add_next_index_str(return_value, STR_COPY(filter_name)); + } + } ZEND_HASH_FOREACH_END(); } /* It's okay to return an empty array if no filters are registered */ } diff --git a/ext/standard/var.c b/ext/standard/var.c index 3f669dbda1..a4e556abdc 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -717,27 +717,18 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt zend_string *key; zval *d, *name; ulong index; - HashPosition pos; int i; zval nval, *nvalp; - HashTable *propers; + HashTable *propers, *ht; ZVAL_NULL(&nval); nvalp = &nval; - zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos); - - for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) { - i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, &index, 0, &pos); - - if (i == HASH_KEY_NON_EXISTENT) { - break; - } - + ht = HASH_OF(retval_ptr); + ZEND_HASH_FOREACH_KEY_VAL(ht, index, key, name) { if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) { continue; } - name = zend_hash_get_current_data_ex(HASH_OF(retval_ptr), &pos); if (Z_TYPE_P(name) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize."); @@ -802,7 +793,7 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC); } } - } + } ZEND_HASH_FOREACH_END(); } smart_str_appendc(buf, '}'); } @@ -954,32 +945,17 @@ again: zend_string *key; zval *data; ulong index; - HashPosition pos; - - zend_hash_internal_pointer_reset_ex(myht, &pos); - for (;; zend_hash_move_forward_ex(myht, &pos)) { - data = zend_hash_get_current_data_ex(myht, &pos); - if (!data) { - break; - } else if (Z_TYPE_P(data) == IS_INDIRECT) { - data = Z_INDIRECT_P(data); - if (Z_TYPE_P(data) == IS_UNDEF) { - continue; - } - } - i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos); + ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { + if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) { continue; } - switch (i) { - case HASH_KEY_IS_LONG: - php_var_serialize_long(buf, index); - break; - case HASH_KEY_IS_STRING: - php_var_serialize_string(buf, key->val, key->len); - break; + if (!key) { + php_var_serialize_long(buf, index); + } else { + php_var_serialize_string(buf, key->val, key->len); } /* we should still add element even if it's not OK, @@ -997,7 +973,7 @@ again: Z_ARRVAL_P(data)->nApplyCount--; } } - } + } ZEND_HASH_FOREACH_END(); } smart_str_appendc(buf, '}'); return; |