source: trunk/processor/hashtable.m4 @ 1446

Last change on this file since 1446 was 1446, checked in by moo, 9 months ago

update relocate

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