]> granicus.if.org Git - php/commitdiff
More ZEND_HASH_FOREACH_* related changes
authorDmitry Stogov <dmitry@zend.com>
Fri, 18 Apr 2014 20:08:14 +0000 (00:08 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 18 Apr 2014 20:08:14 +0000 (00:08 +0400)
Zend/zend_hash.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/standard/array.c

index ba0b28bd7b03203a64f37bdb9a3f02088186db32..c770539dd1faf2f0f71eebbd4358e7c42783b7e7 100644 (file)
@@ -533,105 +533,84 @@ static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPositio
 #define zend_hash_get_current_data_ptr(ht) \
        zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
 
-#define ZEND_HASH_FOREACH_VAL(_ht, _val) do { \
+#define ZEND_HASH_FOREACH(_ht, indirect) do { \
                uint _idx; \
-               Bucket *_p; \
                for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _val = &_p->val;
-
-#define ZEND_HASH_FOREACH_VAL_IND(_ht, _val) do { \
-               uint _idx; \
-               Bucket *_p; \
-               zval *_z; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       _z = &_p->val; \
-                       if (Z_TYPE_P(_z) == IS_INDIRECT) { \
+                       Bucket *_p = (_ht)->arData + _idx; \
+                       zval *_z = &_p->val; \
+                       if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
                                _z = Z_INDIRECT_P(_z); \
                        } \
-                       if (Z_TYPE_P(_z) == IS_UNDEF) continue; \
-                       _val = _z;
-
-#define ZEND_HASH_FOREACH_PTR(_ht, _ptr) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _ptr = Z_PTR(_p->val);
-
-#define ZEND_HASH_FOREACH_KEY(_ht, _h, _key) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-               
-#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-                       _val = &_p->val;
-
-#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-                       _val = &_p->val;
+                       if (Z_TYPE_P(_z) == IS_UNDEF) continue;
 
-#define ZEND_HASH_FOREACH_KEY_VAL_IND(_ht, _h, _key, _val) do { \
+#define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
                uint _idx; \
-               Bucket *_p; \
-               zval *_z; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       _z = &_p->val; \
-                       if (Z_TYPE_P(_z) == IS_INDIRECT) { \
+               for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
+                       Bucket *_p = (_ht)->arData + _idx - 1; \
+                       zval *_z = &_p->val; \
+                       if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
                                _z = Z_INDIRECT_P(_z); \
                        } \
-                       if (Z_TYPE_P(_z) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-                       _val = _z;
-
-#define ZEND_HASH_FOREACH_KEY_PTR(_ht, _h, _key, _ptr) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \
-                       _p = (_ht)->arData + _idx; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-                       _ptr = Z_PTR(_p->val);
-
-
-#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \
-               uint _idx; \
-               Bucket *_p; \
-               for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
-                       _p = (_ht)->arData + _idx - 1; \
-                       if (Z_TYPE(_p->val) == IS_UNDEF) continue; \
-                       _h = _p->h; \
-                       _key = _p->key; \
-                       _val = &_p->val;
+                       if (Z_TYPE_P(_z) == IS_UNDEF) continue;
 
 #define ZEND_HASH_FOREACH_END() \
                } \
        } while (0)
        
-
+#define ZEND_HASH_FOREACH_VAL(ht, _val) \
+       ZEND_HASH_FOREACH(ht, 0); \
+       _val = _z;
+
+#define ZEND_HASH_FOREACH_VAL_IND(ht, _val) \
+       ZEND_HASH_FOREACH(ht, 1); \
+       _val = _z;
+
+#define ZEND_HASH_FOREACH_PTR(ht, _ptr) \
+       ZEND_HASH_FOREACH(ht, 0); \
+       _ptr = Z_PTR_P(_z);
+
+#define ZEND_HASH_FOREACH_KEY(ht, _h, _key) \
+       ZEND_HASH_FOREACH(ht, 0); \
+       _h = _p->h; \
+       _key = _p->key;
+               
+#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
+       ZEND_HASH_FOREACH(ht, 0); \
+       _h = _p->h; \
+       _key = _p->key; \
+       _val = _z;
+
+#define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
+       ZEND_HASH_FOREACH(ht, 1); \
+       _h = _p->h; \
+       _key = _p->key; \
+       _val = _z;
+
+#define ZEND_HASH_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
+       ZEND_HASH_FOREACH(ht, 0); \
+       _h = _p->h; \
+       _key = _p->key; \
+       _ptr = Z_PTR_P(_z);
+
+#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val) \
+       ZEND_HASH_REVERSE_FOREACH(ht, 0); \
+       _val = _z;
+
+#define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val) \
+       ZEND_HASH_REVERSE_FOREACH(ht, 1); \
+       _val = _z;
+
+#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
+       ZEND_HASH_REVERSE_FOREACH(ht, 0); \
+       _h = _p->h; \
+       _key = _p->key; \
+       _val = _z;
+
+#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
+       ZEND_HASH_REVERSE_FOREACH(ht, 1); \
+       _h = _p->h; \
+       _key = _p->key; \
+       _val = _z;
 
 #endif                                                 /* ZEND_HASH_H */
 
index d6723fbd5aeb17281390b21abaaa7e308c79c1f0..e3b58bcea8840758bc5c098fdd56514b40cff8f8 100644 (file)
@@ -3112,19 +3112,14 @@ ZEND_VM_C_LABEL(send_again):
        switch (Z_TYPE_P(args)) {
                case IS_ARRAY: {
                        HashTable *ht = Z_ARRVAL_P(args);
-                       HashPosition pos;
                        zval *arg;
+                       zend_string *name;
+                       zend_ulong index;
 
                        ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
 
-                       for (zend_hash_internal_pointer_reset_ex(ht, &pos);
-                            (arg = zend_hash_get_current_data_ex(ht, &pos)) != NULL;
-                            zend_hash_move_forward_ex(ht, &pos), ++arg_num
-                       ) {
-                               zend_string *name;
-                               zend_ulong index;
-
-                               if (zend_hash_get_current_key_ex(ht, &name, &index, 0, &pos) == HASH_KEY_IS_STRING) {
+                       ZEND_HASH_FOREACH_KEY_VAL(ht, index, name, arg) {
+                               if (name) {
                                        zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys");
                                        FREE_OP1();
                                        CHECK_EXCEPTION();
@@ -3142,7 +3137,9 @@ ZEND_VM_C_LABEL(send_again):
 
                                zend_vm_stack_push(arg TSRMLS_CC);
                                EX(call)->num_additional_args++;
-                       }
+                               arg_num++;
+                       } ZEND_HASH_FOREACH_END();
+
                        break;
                }
                case IS_OBJECT: {
index 9217e1113bcde24e93974461b3fb30b3afc16d18..482ea3109deb466997536b58a607e3a40af95caf 100644 (file)
@@ -720,19 +720,14 @@ send_again:
        switch (Z_TYPE_P(args)) {
                case IS_ARRAY: {
                        HashTable *ht = Z_ARRVAL_P(args);
-                       HashPosition pos;
                        zval *arg;
+                       zend_string *name;
+                       zend_ulong index;
 
                        ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht));
 
-                       for (zend_hash_internal_pointer_reset_ex(ht, &pos);
-                            (arg = zend_hash_get_current_data_ex(ht, &pos)) != NULL;
-                            zend_hash_move_forward_ex(ht, &pos), ++arg_num
-                       ) {
-                               zend_string *name;
-                               zend_ulong index;
-
-                               if (zend_hash_get_current_key_ex(ht, &name, &index, 0, &pos) == HASH_KEY_IS_STRING) {
+                       ZEND_HASH_FOREACH_KEY_VAL(ht, index, name, arg) {
+                               if (name) {
                                        zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys");
                                        FREE_OP(free_op1);
                                        CHECK_EXCEPTION();
@@ -750,7 +745,9 @@ send_again:
 
                                zend_vm_stack_push(arg TSRMLS_CC);
                                EX(call)->num_additional_args++;
-                       }
+                               arg_num++;
+                       } ZEND_HASH_FOREACH_END();
+
                        break;
                }
                case IS_OBJECT: {
index d5799196d256c5c8f2df4227e5295da87ab8ecd6..03c77fea80a68fd18e70c153b545bb3077127906 100644 (file)
@@ -1975,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);