diff --git a/common.h b/common.h index 941f8c15e0..1e0e8894d4 100644 --- a/common.h +++ b/common.h @@ -13,16 +13,13 @@ typedef smart_str smart_string; #define smart_string_appendl(dest, src, len) smart_str_appendl(dest, src, len) #define ZEND_HASH_FOREACH_VAL(ht, _val) do { \ - zval **_pData; \ HashPosition _hpos; \ for (zend_hash_internal_pointer_reset_ex(ht, &_hpos); \ - zend_hash_get_current_data_ex(ht, (void **) &_pData, &_hpos) == SUCCESS; \ + (_val = zend_hash_get_current_data_ex(ht, &_hpos)) != NULL; \ zend_hash_move_forward_ex(ht, &_hpos) \ - ) { _val = *_pData; + ) -#define ZEND_HASH_FOREACH_END() \ - } \ - } while(0) +#define ZEND_HASH_FOREACH_END() } while(0) static zend_always_inline zval * zend_hash_str_find(const HashTable *ht, const char *key, size_t len) @@ -93,6 +90,32 @@ zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h) return NULL; } +static int (*_zend_hash_get_current_data_ex)(HashTable *, void **, HashPosition *) = &zend_hash_get_current_data_ex; +#define zend_hash_get_current_data_ex(ht, pos) inline_zend_hash_get_current_data_ex(ht, pos) +static zend_always_inline zval * +inline_zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos) +{ + zval **zv; + if (_zend_hash_get_current_data_ex(ht, (void **)&zv, pos) == SUCCESS) { + return *zv; + } + return NULL; +} + +#undef zend_hash_next_index_insert +#define zend_hash_next_index_insert(ht, pData) \ + _zend_hash_next_index_insert(ht, pData ZEND_FILE_LINE_CC) +static zend_always_inline zval * +_zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC) +{ + if (_zend_hash_index_update_or_next_insert(ht, 0, &pData, sizeof(pData), + NULL, HASH_NEXT_INSERT ZEND_FILE_LINE_CC) == SUCCESS + ) { + return pData; + } + return NULL; +} + #undef zend_get_parameters_array #define zend_get_parameters_array(ht, param_count, argument_array) \ inline_zend_get_parameters_array(ht, param_count, argument_array TSRMLS_CC) diff --git a/redis_array_impl.c b/redis_array_impl.c index 0c63262e86..3f2d36d575 100644 --- a/redis_array_impl.c +++ b/redis_array_impl.c @@ -581,7 +581,7 @@ void ra_index_keys(zval *z_pairs, zval *z_redis TSRMLS_DC) { /* Initialize key array */ - zval *z_keys, **z_entry_pp; + zval *z_keys; MAKE_STD_ZVAL(z_keys); HashPosition pos; #if PHP_VERSION_ID > 50300 @@ -592,7 +592,7 @@ ra_index_keys(zval *z_pairs, zval *z_redis TSRMLS_DC) { /* Go through input array and add values to the key array */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z_pairs), &pos); - while (zend_hash_get_current_data_ex(Z_ARRVAL_P(z_pairs), (void **)&z_entry_pp, &pos) == SUCCESS) { + while (zend_hash_get_current_data_ex(Z_ARRVAL_P(z_pairs), &pos) != NULL) { char *key; unsigned int key_len; unsigned long num_key; @@ -602,13 +602,13 @@ ra_index_keys(zval *z_pairs, zval *z_redis TSRMLS_DC) { switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(z_pairs), &key, &key_len, &num_key, 1, &pos)) { case HASH_KEY_IS_STRING: ZVAL_STRINGL(z_new, key, (int)key_len - 1, 0); - zend_hash_next_index_insert(Z_ARRVAL_P(z_keys), &z_new, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(z_keys), z_new); break; case HASH_KEY_IS_LONG: Z_TYPE_P(z_new) = IS_LONG; Z_LVAL_P(z_new) = (long)num_key; - zend_hash_next_index_insert(Z_ARRVAL_P(z_keys), &z_new, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(z_keys), z_new); break; } zend_hash_move_forward_ex(Z_ARRVAL_P(z_pairs), &pos); diff --git a/redis_cluster.c b/redis_cluster.c index f86b80348f..691e459a0d 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -567,7 +567,7 @@ typedef struct clusterKeyValHT { static int get_key_val_ht(redisCluster *c, HashTable *ht, HashPosition *ptr, clusterKeyValHT *kv TSRMLS_DC) { - zval **z_val; + zval *z_val; unsigned int key_len; ulong idx; @@ -593,14 +593,14 @@ static int get_key_val_ht(redisCluster *c, HashTable *ht, HashPosition *ptr, kv->slot = cluster_hash_key(kv->key, kv->key_len); // Now grab our value - if(zend_hash_get_current_data_ex(ht, (void**)&z_val, ptr)==FAILURE) { + if ((z_val = zend_hash_get_current_data_ex(ht, ptr)) == NULL) { zend_throw_exception(redis_cluster_exception_ce, "Internal Zend HashTable error", 0 TSRMLS_CC); return -1; } // Serialize our value if required - kv->val_free = redis_serialize(c->flags,*z_val,&(kv->val),&(kv->val_len) + kv->val_free = redis_serialize(c->flags,z_val,&(kv->val),&(kv->val_len) TSRMLS_CC); // Success @@ -611,9 +611,9 @@ static int get_key_val_ht(redisCluster *c, HashTable *ht, HashPosition *ptr, static int get_key_ht(redisCluster *c, HashTable *ht, HashPosition *ptr, clusterKeyValHT *kv TSRMLS_DC) { - zval **z_key; + zval *z_key; - if(zend_hash_get_current_data_ex(ht, (void**)&z_key, ptr)==FAILURE) { + if ((z_key = zend_hash_get_current_data_ex(ht, ptr)) == NULL) { // Shouldn't happen, but check anyway zend_throw_exception(redis_cluster_exception_ce, "Internal Zend HashTable error", 0 TSRMLS_CC); @@ -621,10 +621,10 @@ static int get_key_ht(redisCluster *c, HashTable *ht, HashPosition *ptr, } // Always want to work with strings - convert_to_string(*z_key); + convert_to_string(z_key); - kv->key = Z_STRVAL_PP(z_key); - kv->key_len = Z_STRLEN_PP(z_key); + kv->key = Z_STRVAL_P(z_key); + kv->key_len = Z_STRLEN_P(z_key); kv->key_free = redis_key_prefix(c->flags, &(kv->key), &(kv->key_len)); // Hash our key @@ -645,7 +645,7 @@ static HashTable *method_args_to_ht(zval *z_args, int argc) { /* Populate our return hash table with our arguments */ for (i = 0; i < argc; i++) { - zend_hash_next_index_insert(ht_ret, &z_args[i], sizeof(zval), NULL); + zend_hash_next_index_insert(ht_ret, &z_args[i]); } /* Return our hash table */ @@ -669,8 +669,8 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, if (!argc) return -1; /* Extract our arguments into an array */ - z_args = emalloc(sizeof(zval)*argc); - if (zend_get_parameters_array(ht, ZEND_NUM_ARGS(), z_args) == FAILURE) { + z_args = ecalloc(argc, sizeof(zval)); + if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) { efree(z_args); return -1; } @@ -688,9 +688,6 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, ht_free = 1; } - /* We no longer need our array args */ - efree(z_args); - /* MGET is readonly, DEL is not */ c->readonly = kw_len == 4 && CLUSTER_IS_ATOMIC(c); @@ -701,6 +698,7 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, // it's the first iteration every time, needlessly zend_hash_internal_pointer_reset_ex(ht_arr, &ptr); if(get_key_ht(c, ht_arr, &ptr, &kv TSRMLS_CC)<0) { + efree(z_args); return -1; } @@ -722,6 +720,7 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, zend_hash_destroy(ht_arr); efree(ht_arr); } + efree(z_args); return -1; } @@ -736,6 +735,7 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, zend_hash_destroy(ht_arr); efree(ht_arr); } + efree(z_args); return -1; } } @@ -752,6 +752,7 @@ static int cluster_mkey_cmd(INTERNAL_FUNCTION_PARAMETERS, char *kw, int kw_len, zend_hash_move_forward_ex(ht_arr, &ptr); } + efree(z_args); // If we've got straggler(s) process them if(mc.argc > 0) { diff --git a/redis_commands.c b/redis_commands.c index 9eb17fd5b8..917d149503 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -1618,12 +1618,12 @@ int redis_hmset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *mem, *val, kbuf[40]; int val_len, val_free; unsigned int mem_len; - zval **z_val; + zval *z_val; // Grab our key, and value for this element in our input ktype = zend_hash_get_current_key_ex(ht_vals, &mem, &mem_len, &idx, 0, &pos); - zend_hash_get_current_data_ex(ht_vals, (void**)&z_val, &pos); + z_val = zend_hash_get_current_data_ex(ht_vals, &pos); // If the hash key is an integer, convert it to a string if(ktype != HASH_KEY_IS_STRING) { @@ -1635,7 +1635,7 @@ int redis_hmset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, } // Serialize value (if directed) - val_free = redis_serialize(redis_sock, *z_val, &val, &val_len TSRMLS_CC); + val_free = redis_serialize(redis_sock, z_val, &val, &val_len TSRMLS_CC); // Append the key and value to our command redis_cmd_append_sstr(&cmdstr, mem, mem_len);