source: trunk/processor/hashtable.m4 @ 1471

Last change on this file since 1471 was 1471, checked in by moo, 13 months ago

relocate: rename marcos to relocate

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname])
2define(`DEF_HASH_TABLE_FUNC', `DEF_STRUCT_P_FUNC(`HashTable', `$1', `
3    pushdefFUNC_NAME(`$2', `$3')
4    dnl {{{ dasm
5    IFDASM(`
6        const Bucket *srcBucket;
7        zval *zv;
8        int bufsize = 2;
9        char *buf = emalloc(bufsize);
10        int keysize;
11
12        define(`AUTOCHECK_SKIP')
13        IFAUTOCHECK(`xc_autocheck_skip = 1;')
14
15        DISABLECHECK(`
16        for (srcBucket = SRC(`pListHead'); srcBucket != NULL; srcBucket = srcBucket->pListNext) {
17            ALLOC_INIT_ZVAL(zv);
18            array_init(zv);
19            FUNC_NAME (dasm, zv, (($2*)srcBucket->pData) TSRMLS_CC);
20            keysize = BUCKET_KEY_SIZE(srcBucket) + 2;
21            if (keysize > bufsize) {
22                do {
23                    bufsize *= 2;
24                } while (keysize > bufsize);
25                buf = erealloc(buf, bufsize);
26            }
27            memcpy(buf, BUCKET_KEY_S(srcBucket), keysize);
28            buf[keysize - 2] = buf[keysize - 1] = ""[0];
29            keysize = srcBucket->nKeyLength;
30#ifdef IS_UNICODE
31            if (BUCKET_KEY_TYPE(srcBucket) == IS_UNICODE) {
32                if (buf[0] == ""[0] && buf[1] == ""[0]) {
33                    keysize ++;
34                }
35            } else
36#endif
37            {
38                if (buf[0] == ""[0]) {
39                    keysize ++;
40                }
41            }
42            add_u_assoc_zval_ex(dst, BUCKET_KEY_TYPE(srcBucket), ZSTR(buf), keysize, zv);
43        }
44        ')
45
46        efree(buf);
47    ', ` dnl IFDASM else
48    dnl }}}
49    Bucket *srcBucket;
50    IFRELOCATE(`Bucket *next;')
51    IFRELOCATE(`Bucket *dstBucket = NULL;')
52    IFCOPY(`Bucket *dstBucket = NULL, *first = NULL, *last = NULL;')
53    dnl only used for copy
54    IFCOPY(`uint n;')
55    IFRELOCATE(`uint n;')
56    IFCALCCOPY(`size_t bucketSize;')
57
58#if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
59    IFRESTORE(`
60        DST(`canary') = zend_hash_canary;
61        DONE(canary)
62    ', `
63        PROCESS(unsigned int, canary)
64    ')
65#endif
66    PROCESS(uint, nTableSize)
67    PROCESS(uint, nTableMask)
68    PROCESS(uint, nNumOfElements)
69    PROCESS(ulong, nNextFreeElement)
70    IFCOPY(`DST(`pInternalPointer') = NULL; /* Used for element traversal */') DONE(pInternalPointer)
71#ifdef ZEND_ENGINE_2_4
72    if (SRC(`nTableMask')) {
73#endif
74        CALLOC(`DST(`arBuckets')', Bucket*, SRC(`nTableSize'))
75        DONE(arBuckets)
76        DISABLECHECK(`
77        for (srcBucket = UNRELOCATED_EX(`Bucket', SRC(`pListHead')); srcBucket != NULL; srcBucket = UNRELOCATED_EX(`Bucket', `srcBucket->pListNext')) {
78            IFCALCCOPY(`bucketSize = BUCKET_SIZE(srcBucket);')
79            ALLOC(dstBucket, char, bucketSize, , Bucket)
80            IFCOPY(`
81#ifdef ZEND_ENGINE_2_4
82                memcpy(dstBucket, srcBucket, BUCKET_HEAD_SIZE(Bucket));
83                if (BUCKET_KEY_SIZE(srcBucket)) {
84                    memcpy((char *) (dstBucket + 1), srcBucket->arKey, BUCKET_KEY_SIZE(srcBucket));
85                    dstBucket->arKey = (const char *) (dstBucket + 1);
86                }
87                else {
88                    dstBucket->arKey = NULL;
89                }
90#else
91                memcpy(dstBucket, srcBucket, bucketSize);
92#endif
93                n = srcBucket->h & SRC(`nTableMask');
94                /* dstBucket into hash node chain */
95                dstBucket->pLast = NULL;
96                dstBucket->pNext = DST(`arBuckets[n]');
97                if (dstBucket->pNext) {
98                    dstBucket->pNext->pLast = dstBucket;
99                }
100            ')
101
102            IFDPRINT(`
103                INDENT()
104                fprintf(stderr, "$2:\"");
105                xc_dprint_str_len(BUCKET_KEY_S(srcBucket), BUCKET_KEY_SIZE(srcBucket));
106                fprintf(stderr, "\" %d:h=%lu ", BUCKET_KEY_SIZE(srcBucket), srcBucket->h);
107            ')
108            if (sizeof(void *) == sizeof($2)) {
109                IFCOPY(`dstBucket->pData = &dstBucket->pDataPtr;')
110                IFRELOCATE(`srcBucket->pData = &srcBucket->pDataPtr;')
111                dnl $6 = ` ' to skip alloc, skip pointer fix
112                STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3', ` ')
113                RELOCATE_EX(`$2', dstBucket->pData)
114            }
115            else {
116                STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3')
117                IFCOPY(`dstBucket->pDataPtr = NULL;')
118            }
119
120            IFCOPY(`
121                if (!first) {
122                    first = dstBucket;
123                }
124
125                /* flat link */
126                dstBucket->pListLast = last;
127                dstBucket->pListNext = NULL;
128                if (last) {
129                    last->pListNext = dstBucket;
130                }
131                last = dstBucket;
132
133                n = srcBucket->h & SRC(`nTableMask');
134                /* dstBucket into hash node chain */
135                dstBucket->pLast = NULL;
136                dstBucket->pNext = DST(`arBuckets[n]');
137                if (dstBucket->pNext) {
138                    dstBucket->pNext->pLast = dstBucket;
139                }
140                DST(`arBuckets[n]') = dstBucket;
141            ')
142        }
143        ') dnl DISABLECHECK
144        IFCOPY(`DST(`pListHead') = first;') DONE(pListHead)
145        IFCOPY(`DST(`pListTail') = dstBucket;') DONE(pListTail)
146
147        IFRELOCATE(`
148        for (n = 0; n < SRC(`nTableSize'); ++n) {
149            if (SRC(`arBuckets[n]')) {
150                next = UNRELOCATED_EX(`Bucket', `DST(`arBuckets[n]')');
151                do {
152                        dstBucket = next;
153                        next = UNRELOCATED_EX(`Bucket', `next->pNext');
154                        if (dstBucket->pListLast) {
155                            RELOCATE_EX(Bucket, dstBucket->pListLast)
156                        }
157                        if (dstBucket->pListNext) {
158                            RELOCATE_EX(Bucket, dstBucket->pListNext)
159                        }
160                        if (dstBucket->pNext) {
161                            RELOCATE_EX(Bucket, dstBucket->pNext)
162                        }
163                        if (dstBucket->pLast) {
164                            RELOCATE_EX(Bucket, dstBucket->pLast)
165                        }
166                } while (next);
167
168                RELOCATE(Bucket, arBuckets[n])
169            }
170        }
171        ')
172        RELOCATE(Bucket, pListHead)
173        RELOCATE(Bucket, pListTail)
174        RELOCATE(Bucket *, arBuckets)
175#ifdef ZEND_ENGINE_2_4
176    }
177    else { /* if (SRC(`nTableMask')) */
178        IFCOPY(`DST(`pListHead') = NULL;') DONE(pListHead)
179        IFCOPY(`DST(`pListTail') = NULL;') DONE(pListTail)
180        DONE(arBuckets)
181    }
182#endif
183    IFCOPY(`DST(`pDestructor') = SRC(`pDestructor');') DONE(pDestructor)
184    PROCESS(zend_bool, persistent)
185#ifdef IS_UNICODE
186    PROCESS(zend_bool, unicode)
187#endif
188    PROCESS(unsigned char, nApplyCount)
189    PROCESS(zend_bool, bApplyProtection)
190#if ZEND_DEBUG
191    PROCESS(int, inconsistent)
192#endif
193    ')dnl IFDASM
194    popdef(`FUNC_NAME')
195')')
Note: See TracBrowser for help on using the repository browser.