]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.6'
authorXinchen Hui <laruence@php.net>
Fri, 13 Mar 2015 17:01:02 +0000 (01:01 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 13 Mar 2015 17:01:02 +0000 (01:01 +0800)
Conflicts:
ext/spl/spl_observer.c

1  2 
ext/spl/spl_observer.c

index ae35f8aec21a74245ea36f85ea3a0d4baa48ad2e,56d1a16ac00386bd339f8b89296b4d22102241df..e727b9e4939074b577f8e0a2bfdaa36d590bf239
@@@ -80,13 -80,15 +80,15 @@@ PHPAPI zend_class_entry     *spl_ce_Mul
  PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
  
  typedef struct _spl_SplObjectStorage { /* {{{ */
 -      zend_object       std;
        HashTable         storage;
 -      long              index;
 +      zend_long         index;
        HashPosition      pos;
 -      long              flags;
 +      zend_long         flags;
        zend_function    *fptr_get_hash;
        HashTable        *debug_info;
 -      zval            **gcdata;
 -      long              gcdata_num;
++      zval             *gcdata;
++      size_t            gcdata_num;
 +      zend_object       std;
  } spl_SplObjectStorage; /* }}} */
  
  /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
@@@ -114,17 -109,32 +116,22 @@@ void spl_SplObjectStorage_free_storage(
                zend_hash_destroy(intern->debug_info);
                efree(intern->debug_info);
        }
 -      efree(object);
+       if (intern->gcdata != NULL) {
+               efree(intern->gcdata);
+       }
  } /* }}} */
  
 -static char *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this,  zval *obj, int *hash_len_ptr TSRMLS_DC) {
 +static zend_string *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this, zval *obj) {
        if (intern->fptr_get_hash) {
 -              zval *rv;
 -              zend_call_method_with_1_params(&this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj);
 -              if (rv) {
 -                      if (Z_TYPE_P(rv) == IS_STRING) {
 -                              int hash_len = Z_STRLEN_P(rv);
 -                              char *hash = emalloc((hash_len+1)*sizeof(char));
 -                              strncpy(hash, Z_STRVAL_P(rv), hash_len);
 -                              hash[hash_len] = 0;
 -
 -                              zval_ptr_dtor(&rv);
 -                              if (hash_len_ptr) {
 -                                      *hash_len_ptr = hash_len;
 -                              }
 -                              return hash;
 +              zval rv;
 +              zend_call_method_with_1_params(this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj);
 +              if (!Z_ISUNDEF(rv)) {
 +                      if (Z_TYPE(rv) == IS_STRING) {
 +                              return Z_STR(rv);
                        } else {
 -                              zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0 TSRMLS_CC);
 +                              zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0);
  
                                zval_ptr_dtor(&rv);
                                return NULL;
@@@ -350,41 -366,30 +356,27 @@@ static HashTable* spl_object_storage_de
  }
  /* }}} */
  
- /* overriden for garbage collection
-  * This is very hacky */
+ /* overriden for garbage collection */
 -static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
 +static HashTable *spl_object_storage_get_gc(zval *obj, zval **table, int *n) /* {{{ */
  {
 -      long i = 0;
 -      spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
++      int i = 0;
 +      spl_SplObjectStorage *intern = Z_SPLOBJSTORAGE_P(obj);
        spl_SplObjectStorageElement *element;
-       HashTable *props;
-       zval *gcdata_arr, tmp;
-       props = std_object_handlers.get_properties(obj);
-       *table = NULL;
-       *n = 0;
 -      HashPosition pos;
  
-       /* clean \x00gcdata, as it may be out of date */
-       if ((gcdata_arr = zend_hash_str_find(props, "\x00gcdata", sizeof("\x00gcdata") - 1)) != NULL) {
-               zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
-       }
-       if (gcdata_arr == NULL) {
-               array_init(&tmp);
-               /* don't decrease refcount of members when destroying */
-               Z_ARRVAL_P(&tmp)->pDestructor = NULL;
-               /* name starts with \x00 to make tampering in user-land more difficult */
-               zend_hash_str_add(props, "\x00gcdata", sizeof("\x00gcdata") - 1, &tmp);
-               gcdata_arr = &tmp;
+       if (intern->storage.nNumOfElements > intern->gcdata_num) {
+               intern->gcdata_num = intern->storage.nNumOfElements * 2;
 -              intern->gcdata = (zval**)erealloc(intern->gcdata, sizeof(zval*) * intern->gcdata_num);
++              intern->gcdata = (zval*)erealloc(intern->gcdata, sizeof(zval) * intern->gcdata_num);
        }
  
 -      zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
 -      while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
 -              intern->gcdata[i++] = element->obj;
 -              intern->gcdata[i++] = element->inf;
 -              zend_hash_move_forward_ex(&intern->storage, &pos);
 -      }
 +      ZEND_HASH_FOREACH_PTR(&intern->storage, element) {
-               add_next_index_zval(gcdata_arr, &element->obj);
-               add_next_index_zval(gcdata_arr, &element->inf);
++              ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->obj);
++              ZVAL_COPY_VALUE(&intern->gcdata[i++], &element->inf);
 +      } ZEND_HASH_FOREACH_END();
  
-       return props;
+       *table = intern->gcdata;
+       *n = i;
+       return std_object_handlers.get_properties(obj TSRMLS_CC);
  }
  /* }}} */
  
@@@ -769,10 -785,12 +761,10 @@@ SPL_METHOD(SplObjectStorage, serialize
  
        /* members */
        smart_str_appendl(&buf, "m:", 2);
 -      INIT_PZVAL(&members);
 -      Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC);
 -      Z_TYPE(members) = IS_ARRAY;
 -      pmembers = &members;
 -      php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */
 +      ZVAL_ARR(&members, zend_array_dup(zend_std_get_properties(getThis())));
-       zend_hash_str_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata") - 1);
 +      php_var_serialize(&buf, &members, &var_hash); /* finishes the string */
 +      zval_ptr_dtor(&members);
  
        /* done */
        PHP_VAR_SERIALIZE_DESTROY(var_hash);