source: trunk/processor/hashtable.m4 @ 196

Last change on this file since 196 was 196, checked in by moo, 8 years ago

fix #36, wrong inheriting static class variables

File size: 3.8 KB
Line 
1dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname] [, 4:check_function])
2define(`DEF_HASH_TABLE_FUNC', `
3    DEF_STRUCT_P_FUNC(`HashTable', `$1', `
4        pushdefFUNC_NAME(`$2', `$3')
5        dnl {{{ dasm
6        IFDASM(`
7            Bucket *b;
8            zval *zv;
9            int bufsize = 2;
10            char *buf = emalloc(bufsize);
11            int keysize;
12
13#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
14            DONE(canary)
15#endif
16            DONE(nTableSize)
17            DONE(nTableMask)
18            DONE(nNumOfElements)
19            DONE(nNextFreeElement)
20            DONE(pInternalPointer)
21            DONE(pListHead)
22            DONE(pListTail)
23            DONE(arBuckets)
24            DONE(pDestructor)
25            DONE(persistent)
26            DONE(nApplyCount)
27            DONE(bApplyProtection)
28#if ZEND_DEBUG
29            DONE(inconsistent)
30#endif
31#ifdef IS_UNICODE
32            DONE(unicode)
33#endif
34
35            DISABLECHECK(`
36            for (b = src->pListHead; b != NULL; b = b->pListNext) {
37                ALLOC_INIT_ZVAL(zv);
38                array_init(zv);
39                FUNC_NAME (zv, (($2*)b->pData) TSRMLS_CC);
40                keysize = BUCKET_KEY_SIZE(b) + 2;
41                if (keysize > bufsize) {
42                    do {
43                        bufsize *= 2;
44                    } while (keysize > bufsize);
45                    buf = erealloc(buf, bufsize);
46                }
47                memcpy(buf, BUCKET_KEY(b), keysize);
48                buf[keysize - 2] = buf[keysize - 1] = ""[0];
49                keysize = b->nKeyLength;
50#ifdef IS_UNICODE
51                if (BUCKET_KEY_TYPE(b) == IS_UNICODE) {
52                    if (buf[0] == ""[0] && buf[1] == ""[0]) {
53                        keysize ++;
54                    }
55                } else
56#endif
57                {
58                    if (buf[0] == ""[0]) {
59                        keysize ++;
60                    }
61                }
62                add_u_assoc_zval_ex(dst, BUCKET_KEY_TYPE(b), buf, keysize, zv);
63            }
64            ')
65
66            efree(buf);
67            return; /* no check size */
68        ', `
69        dnl }}}
70        Bucket *b, *pnew = NULL, *prev = NULL;
71        zend_bool first = 1;
72        dnl only used for copy
73        IFCOPY(`uint n;')
74        IFCALCCOPY(`int bucketsize;')
75
76#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
77        IFASM(`dst->canary = zend_hash_canary; DONE(canary)', `
78        dnl elseif
79            IFRESTORE(`dst->canary = zend_hash_canary; DONE(canary)', `
80                dnl else
81                DISPATCH(unsigned int, canary)
82            ')
83        ')
84#endif
85        DISPATCH(uint, nTableSize)
86        DISPATCH(uint, nTableMask)
87        DISPATCH(uint, nNumOfElements)
88        DISPATCH(ulong, nNextFreeElement)
89        IFCOPY(`dst->pInternalPointer = NULL;   /* Used for element traversal */') DONE(pInternalPointer)
90        IFCOPY(`dst->pListHead = NULL;') DONE(pListHead)
91        CALLOC(dst->arBuckets, Bucket*, src->nTableSize)
92        DONE(arBuckets)
93        DISABLECHECK(`
94
95        for (b = src->pListHead; b != NULL; b = b->pListNext) {
96            ifelse(`$4', `', `', `
97                pushdef(`BUCKET', `b')
98                if ($4 == ZEND_HASH_APPLY_REMOVE) {
99                    IFCOPY(`dst->nNumOfElements --;')
100                    continue;
101                }
102                popdef(`BUCKET')
103          ')
104         
105            IFCALCCOPY(`bucketsize = BUCKET_SIZE(b);')
106            ALLOC(pnew, char, bucketsize, , Bucket)
107            IFCOPY(`memcpy(pnew, b, bucketsize);')
108            IFCOPY(`
109                n = b->h & src->nTableMask;
110                /* pnew into hash node chain */
111                pnew->pLast = NULL;
112                if (dst->arBuckets[n]) {
113                    pnew->pNext = dst->arBuckets[n];
114                    pnew->pNext->pLast = pnew;
115                }
116                else {
117                    pnew->pNext = NULL;
118                }
119                dst->arBuckets[n] = pnew;
120            ')
121            if (sizeof(void *) == sizeof($2)) {
122                IFCOPY(`pnew->pData = &pnew->pDataPtr;')
123                dnl no alloc
124                STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `', `$3', ` ')
125            }
126            else {
127                STRUCT_P_EX(`$2', pnew->pData, (($2*)b->pData), `', `$3')
128                IFCOPY(`pnew->pDataPtr = NULL;')
129            }
130
131            if (first) {
132                IFCOPY(`dst->pListHead = pnew;')
133                first = 0;
134            }
135
136            IFCOPY(`
137                /* flat link */
138                pnew->pListLast = prev;
139                pnew->pListNext = NULL;
140                if (prev) {
141                    prev->pListNext = pnew;
142                }
143            ')
144            prev = pnew;
145        }
146        ')
147        IFCOPY(`dst->pListTail = pnew;') DONE(pListTail)
148        IFCOPY(`dst->pDestructor = src->pDestructor;') DONE(pDestructor)
149        DISPATCH(zend_bool, persistent)
150#ifdef IS_UNICODE
151        DISPATCH(zend_bool, unicode)
152#endif
153        DISPATCH(unsigned char, nApplyCount)
154        DISPATCH(zend_bool, bApplyProtection)
155#if ZEND_DEBUG
156        DISPATCH(int, inconsistent)
157#endif
158        ')dnl IFDASM
159        popdef(`FUNC_NAME')
160    ')
161')
Note: See TracBrowser for help on using the repository browser.