1 | dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname]) |
---|
2 | define(`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 | IFCOPY(`Bucket *first = NULL, *last = NULL;') |
---|
51 | IFRELOCATE(`Bucket *dstBucket = NULL;') |
---|
52 | IFRESTORE(`Bucket *dstBucket = NULL;') |
---|
53 | IFRELOCATE(`uint n;') |
---|
54 | IFRESTORE(`uint n;') |
---|
55 | IFCALCCOPY(`size_t bucketSize;') |
---|
56 | |
---|
57 | #if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT |
---|
58 | IFRESTORE(` |
---|
59 | DST(`canary') = zend_hash_canary; |
---|
60 | DONE(canary) |
---|
61 | ', ` |
---|
62 | PROCESS(unsigned int, canary) |
---|
63 | ') |
---|
64 | #endif |
---|
65 | PROCESS(uint, nTableSize) |
---|
66 | PROCESS(uint, nTableMask) |
---|
67 | PROCESS(uint, nNumOfElements) |
---|
68 | PROCESS(ulong, nNextFreeElement) |
---|
69 | IFCOPY(`DST(`pInternalPointer') = NULL; /* Used for element traversal */') DONE(pInternalPointer) |
---|
70 | #ifdef ZEND_ENGINE_2_4 |
---|
71 | if (SRC(`nTableMask')) { |
---|
72 | #endif |
---|
73 | CALLOC(`DST(`arBuckets')', Bucket*, SRC(`nTableSize')) |
---|
74 | DONE(arBuckets) |
---|
75 | DISABLECHECK(` |
---|
76 | for (srcBucket = PTR_FROM_VIRTUAL_EX(`Bucket', SRC(`pListHead')); srcBucket != NULL; srcBucket = PTR_FROM_VIRTUAL_EX(`Bucket', `srcBucket->pListNext')) { |
---|
77 | IFCALCCOPY(`bucketSize = BUCKET_SIZE(srcBucket);') |
---|
78 | ALLOC(dstBucket, char, bucketSize, , Bucket) |
---|
79 | IFCOPY(` |
---|
80 | #ifdef ZEND_ENGINE_2_4 |
---|
81 | memcpy(dstBucket, srcBucket, BUCKET_HEAD_SIZE(Bucket)); |
---|
82 | if (BUCKET_KEY_SIZE(srcBucket)) { |
---|
83 | memcpy((char *) (dstBucket + 1), srcBucket->arKey, BUCKET_KEY_SIZE(srcBucket)); |
---|
84 | dstBucket->arKey = (const char *) (dstBucket + 1); |
---|
85 | } |
---|
86 | else { |
---|
87 | dstBucket->arKey = NULL; |
---|
88 | } |
---|
89 | #else |
---|
90 | memcpy(dstBucket, srcBucket, bucketSize); |
---|
91 | #endif |
---|
92 | n = srcBucket->h & SRC(`nTableMask'); |
---|
93 | /* dstBucket into hash node chain */ |
---|
94 | dstBucket->pLast = NULL; |
---|
95 | dstBucket->pNext = DST(`arBuckets[n]'); |
---|
96 | if (dstBucket->pNext) { |
---|
97 | dstBucket->pNext->pLast = dstBucket; |
---|
98 | } |
---|
99 | ') |
---|
100 | |
---|
101 | IFDPRINT(` |
---|
102 | INDENT() |
---|
103 | fprintf(stderr, "$2:\""); |
---|
104 | xc_dprint_str_len(BUCKET_KEY_S(srcBucket), BUCKET_KEY_SIZE(srcBucket)); |
---|
105 | fprintf(stderr, "\" %d:h=%lu ", BUCKET_KEY_SIZE(srcBucket), srcBucket->h); |
---|
106 | ') |
---|
107 | if (sizeof(void *) == sizeof($2)) { |
---|
108 | IFCOPY(`dstBucket->pData = &dstBucket->pDataPtr;') |
---|
109 | IFRELOCATE(`srcBucket->pData = &srcBucket->pDataPtr;') |
---|
110 | dnl $6 = ` ' to skip alloc, skip pointer fix |
---|
111 | STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3', ` ') |
---|
112 | RELOCATE_EX(`$2', dstBucket->pData) |
---|
113 | } |
---|
114 | else { |
---|
115 | STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3') |
---|
116 | IFCOPY(`dstBucket->pDataPtr = NULL;') |
---|
117 | } |
---|
118 | |
---|
119 | IFCOPY(` |
---|
120 | if (!first) { |
---|
121 | first = dstBucket; |
---|
122 | } |
---|
123 | |
---|
124 | /* flat link */ |
---|
125 | dstBucket->pListLast = last; |
---|
126 | dstBucket->pListNext = NULL; |
---|
127 | if (last) { |
---|
128 | last->pListNext = dstBucket; |
---|
129 | } |
---|
130 | last = dstBucket; |
---|
131 | |
---|
132 | n = srcBucket->h & SRC(`nTableMask'); |
---|
133 | /* dstBucket into hash node chain */ |
---|
134 | dstBucket->pLast = NULL; |
---|
135 | dstBucket->pNext = DST(`arBuckets[n]'); |
---|
136 | if (dstBucket->pNext) { |
---|
137 | dstBucket->pNext->pLast = dstBucket; |
---|
138 | } |
---|
139 | DST(`arBuckets[n]') = dstBucket; |
---|
140 | ') |
---|
141 | } |
---|
142 | ') dnl DISABLECHECK |
---|
143 | IFCOPY(`DST(`pListHead') = first;') DONE(pListHead) |
---|
144 | IFCOPY(`DST(`pListTail') = dstBucket;') DONE(pListTail) |
---|
145 | |
---|
146 | IFRELOCATE(` |
---|
147 | for (n = 0; n < SRC(`nTableSize'); ++n) { |
---|
148 | if (SRC(`arBuckets[n]')) { |
---|
149 | Bucket *next = PTR_FROM_VIRTUAL_EX(`Bucket', `DST(`arBuckets[n]')'); |
---|
150 | do { |
---|
151 | dstBucket = next; |
---|
152 | next = PTR_FROM_VIRTUAL_EX(`Bucket', `next->pNext'); |
---|
153 | if (dstBucket->pListLast) { |
---|
154 | RELOCATE_EX(Bucket, dstBucket->pListLast) |
---|
155 | } |
---|
156 | if (dstBucket->pListNext) { |
---|
157 | RELOCATE_EX(Bucket, dstBucket->pListNext) |
---|
158 | } |
---|
159 | if (dstBucket->pNext) { |
---|
160 | RELOCATE_EX(Bucket, dstBucket->pNext) |
---|
161 | } |
---|
162 | if (dstBucket->pLast) { |
---|
163 | RELOCATE_EX(Bucket, dstBucket->pLast) |
---|
164 | } |
---|
165 | } while (next); |
---|
166 | |
---|
167 | RELOCATE(Bucket, arBuckets[n]) |
---|
168 | } |
---|
169 | } |
---|
170 | ') |
---|
171 | if (SRC(`nNumOfElements')) { |
---|
172 | RELOCATE(Bucket, pListHead) |
---|
173 | RELOCATE(Bucket, pListTail) |
---|
174 | } |
---|
175 | RELOCATE(Bucket *, arBuckets) |
---|
176 | #ifdef ZEND_ENGINE_2_4 |
---|
177 | } |
---|
178 | else { /* if (SRC(`nTableMask')) */ |
---|
179 | IFCOPY(`DST(`pListHead') = NULL;') DONE(pListHead) |
---|
180 | IFCOPY(`DST(`pListTail') = NULL;') DONE(pListTail) |
---|
181 | DONE(arBuckets) |
---|
182 | } |
---|
183 | #endif |
---|
184 | IFCOPY(`DST(`pDestructor') = SRC(`pDestructor');') DONE(pDestructor) |
---|
185 | PROCESS(zend_bool, persistent) |
---|
186 | #ifdef IS_UNICODE |
---|
187 | PROCESS(zend_bool, unicode) |
---|
188 | #endif |
---|
189 | PROCESS(unsigned char, nApplyCount) |
---|
190 | PROCESS(zend_bool, bApplyProtection) |
---|
191 | #if ZEND_DEBUG |
---|
192 | PROCESS(int, inconsistent) |
---|
193 | #endif |
---|
194 | ')dnl IFDASM |
---|
195 | popdef(`FUNC_NAME') |
---|
196 | ')') |
---|