Annotation of embedaddon/php/ext/spl/php_spl.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Marcus Boerger <helly@php.net>                              |
                     16:    +----------------------------------------------------------------------+
                     17:  */
                     18: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      20: 
                     21: #ifdef HAVE_CONFIG_H
                     22: #include "config.h"
                     23: #endif
                     24: 
                     25: #include "php.h"
                     26: #include "php_ini.h"
                     27: #include "php_main.h"
                     28: #include "ext/standard/info.h"
                     29: #include "php_spl.h"
                     30: #include "spl_functions.h"
                     31: #include "spl_engine.h"
                     32: #include "spl_array.h"
                     33: #include "spl_directory.h"
                     34: #include "spl_iterators.h"
                     35: #include "spl_exceptions.h"
                     36: #include "spl_observer.h"
                     37: #include "spl_dllist.h"
                     38: #include "spl_fixedarray.h"
                     39: #include "spl_heap.h"
                     40: #include "zend_exceptions.h"
                     41: #include "zend_interfaces.h"
                     42: #include "ext/standard/php_rand.h"
                     43: #include "ext/standard/php_lcg.h"
                     44: #include "main/snprintf.h"
                     45: 
                     46: #ifdef COMPILE_DL_SPL
                     47: ZEND_GET_MODULE(spl)
                     48: #endif
                     49: 
                     50: ZEND_DECLARE_MODULE_GLOBALS(spl)
                     51: 
                     52: #define SPL_DEFAULT_FILE_EXTENSIONS ".inc,.php"
                     53: 
                     54: /* {{{ PHP_GINIT_FUNCTION
                     55:  */
                     56: static PHP_GINIT_FUNCTION(spl)
                     57: {
                     58:        spl_globals->autoload_extensions     = NULL;
                     59:        spl_globals->autoload_extensions_len = 0;
                     60:        spl_globals->autoload_functions      = NULL;
                     61:        spl_globals->autoload_running        = 0;
                     62: }
                     63: /* }}} */
                     64: 
                     65: static zend_class_entry * spl_find_ce_by_name(char *name, int len, zend_bool autoload TSRMLS_DC)
                     66: {
                     67:        zend_class_entry **ce;
                     68:        int found;
                     69: 
                     70:        if (!autoload) {
                     71:                char *lc_name;
                     72:                ALLOCA_FLAG(use_heap)
                     73: 
                     74:                lc_name = do_alloca(len + 1, use_heap);
                     75:                zend_str_tolower_copy(lc_name, name, len);
                     76: 
                     77:                found = zend_hash_find(EG(class_table), lc_name, len +1, (void **) &ce);
                     78:                free_alloca(lc_name, use_heap);
                     79:        } else {
                     80:                found = zend_lookup_class(name, len, &ce TSRMLS_CC);
                     81:        }
                     82:        if (found != SUCCESS) {
                     83:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s does not exist%s", name, autoload ? " and could not be loaded" : "");
                     84:                return NULL;
                     85:        }
                     86:        
                     87:        return *ce;
                     88: }
                     89: 
                     90: /* {{{ proto array class_parents(object instance [, boolean autoload = true])
                     91:  Return an array containing the names of all parent classes */
                     92: PHP_FUNCTION(class_parents)
                     93: {
                     94:        zval *obj;
                     95:        zend_class_entry *parent_class, *ce;
                     96:        zend_bool autoload = 1;
                     97: 
                     98:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &obj, &autoload) == FAILURE) {
                     99:                RETURN_FALSE;
                    100:        }
                    101:        
                    102:        if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) {
                    103:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "object or string expected");
                    104:                RETURN_FALSE;
                    105:        }
                    106:        
                    107:        if (Z_TYPE_P(obj) == IS_STRING) {
                    108:                if (NULL == (ce = spl_find_ce_by_name(Z_STRVAL_P(obj), Z_STRLEN_P(obj), autoload TSRMLS_CC))) {
                    109:                        RETURN_FALSE;
                    110:                }
                    111:        } else {
                    112:                ce = Z_OBJCE_P(obj);
                    113:        }
                    114:        
                    115:        array_init(return_value);
                    116:        parent_class = ce->parent;
                    117:        while (parent_class) {
                    118:                spl_add_class_name(return_value, parent_class, 0, 0 TSRMLS_CC);
                    119:                parent_class = parent_class->parent;
                    120:        }
                    121: }
                    122: /* }}} */
                    123: 
                    124: /* {{{ proto array class_implements(mixed what [, bool autoload ])
                    125:  Return all classes and interfaces implemented by SPL */
                    126: PHP_FUNCTION(class_implements)
                    127: {
                    128:        zval *obj;
                    129:        zend_bool autoload = 1;
                    130:        zend_class_entry *ce;
                    131:        
                    132:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &obj, &autoload) == FAILURE) {
                    133:                RETURN_FALSE;
                    134:        }
                    135:        if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) {
                    136:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "object or string expected");
                    137:                RETURN_FALSE;
                    138:        }
                    139:        
                    140:        if (Z_TYPE_P(obj) == IS_STRING) {
                    141:                if (NULL == (ce = spl_find_ce_by_name(Z_STRVAL_P(obj), Z_STRLEN_P(obj), autoload TSRMLS_CC))) {
                    142:                        RETURN_FALSE;
                    143:                }
                    144:        } else {
                    145:                ce = Z_OBJCE_P(obj);
                    146:        }
                    147:        
                    148:        array_init(return_value);
                    149:        spl_add_interfaces(return_value, ce, 1, ZEND_ACC_INTERFACE TSRMLS_CC);
                    150: }
                    151: /* }}} */
                    152: 
1.1.1.2   misho     153: /* {{{ proto array class_uses(mixed what [, bool autoload ])
                    154:  Return all traits used by a class. */
                    155: PHP_FUNCTION(class_uses)
                    156: {
                    157:        zval *obj;
                    158:        zend_bool autoload = 1;
                    159:        zend_class_entry *ce;
                    160:        
                    161:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &obj, &autoload) == FAILURE) {
                    162:                RETURN_FALSE;
                    163:        }
                    164:        if (Z_TYPE_P(obj) != IS_OBJECT && Z_TYPE_P(obj) != IS_STRING) {
                    165:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "object or string expected");
                    166:                RETURN_FALSE;
                    167:        }
                    168:        
                    169:        if (Z_TYPE_P(obj) == IS_STRING) {
                    170:                if (NULL == (ce = spl_find_ce_by_name(Z_STRVAL_P(obj), Z_STRLEN_P(obj), autoload TSRMLS_CC))) {
                    171:                        RETURN_FALSE;
                    172:                }
                    173:        } else {
                    174:                ce = Z_OBJCE_P(obj);
                    175:        }
                    176:        
                    177:        array_init(return_value);
                    178:        spl_add_traits(return_value, ce, 1, ZEND_ACC_TRAIT TSRMLS_CC);
                    179: }
                    180: /* }}} */
                    181: 
1.1       misho     182: #define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \
                    183:        spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags TSRMLS_CC)
                    184: 
                    185: #define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \
                    186:        SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \
                    187:        SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags); \
                    188:        SPL_ADD_CLASS(ArrayObject, z_list, sub, allow, ce_flags); \
                    189:        SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags); \
                    190:        SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \
                    191:        SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \
1.1.1.2   misho     192:        SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags); \
1.1       misho     193:        SPL_ADD_CLASS(Countable, z_list, sub, allow, ce_flags); \
                    194:        SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
                    195:        SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \
                    196:        SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \
                    197:        SPL_ADD_CLASS(FilesystemIterator, z_list, sub, allow, ce_flags); \
                    198:        SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \
                    199:        SPL_ADD_CLASS(GlobIterator, z_list, sub, allow, ce_flags); \
                    200:        SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \
                    201:        SPL_ADD_CLASS(InvalidArgumentException, z_list, sub, allow, ce_flags); \
                    202:        SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \
                    203:        SPL_ADD_CLASS(LengthException, z_list, sub, allow, ce_flags); \
                    204:        SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \
                    205:        SPL_ADD_CLASS(LogicException, z_list, sub, allow, ce_flags); \
                    206:        SPL_ADD_CLASS(MultipleIterator, z_list, sub, allow, ce_flags); \
                    207:        SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \
                    208:        SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags); \
                    209:        SPL_ADD_CLASS(OutOfBoundsException, z_list, sub, allow, ce_flags); \
                    210:        SPL_ADD_CLASS(OutOfRangeException, z_list, sub, allow, ce_flags); \
                    211:        SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags); \
                    212:        SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \
                    213:        SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \
                    214:        SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \
                    215:        SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags); \
1.1.1.2   misho     216:        SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, sub, allow, ce_flags); \
1.1       misho     217:        SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \
                    218:        SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \
                    219:        SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \
                    220:        SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \
                    221:        SPL_ADD_CLASS(RecursiveRegexIterator, z_list, sub, allow, ce_flags); \
                    222:        SPL_ADD_CLASS(RecursiveTreeIterator, z_list, sub, allow, ce_flags); \
                    223:        SPL_ADD_CLASS(RegexIterator, z_list, sub, allow, ce_flags); \
                    224:        SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \
                    225:        SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags); \
                    226:        SPL_ADD_CLASS(SplDoublyLinkedList, z_list, sub, allow, ce_flags); \
                    227:        SPL_ADD_CLASS(SplFileInfo, z_list, sub, allow, ce_flags); \
                    228:        SPL_ADD_CLASS(SplFileObject, z_list, sub, allow, ce_flags); \
                    229:        SPL_ADD_CLASS(SplFixedArray, z_list, sub, allow, ce_flags); \
                    230:        SPL_ADD_CLASS(SplHeap, z_list, sub, allow, ce_flags); \
                    231:        SPL_ADD_CLASS(SplMinHeap, z_list, sub, allow, ce_flags); \
                    232:        SPL_ADD_CLASS(SplMaxHeap, z_list, sub, allow, ce_flags); \
                    233:        SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags); \
                    234:        SPL_ADD_CLASS(SplObserver, z_list, sub, allow, ce_flags); \
                    235:        SPL_ADD_CLASS(SplPriorityQueue, z_list, sub, allow, ce_flags); \
                    236:        SPL_ADD_CLASS(SplQueue, z_list, sub, allow, ce_flags); \
                    237:        SPL_ADD_CLASS(SplStack, z_list, sub, allow, ce_flags); \
                    238:        SPL_ADD_CLASS(SplSubject, z_list, sub, allow, ce_flags); \
                    239:        SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags); \
                    240:        SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \
                    241:        SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags); \
                    242: 
                    243: /* {{{ proto array spl_classes()
                    244:  Return an array containing the names of all clsses and interfaces defined in SPL */
                    245: PHP_FUNCTION(spl_classes)
                    246: {
                    247:        array_init(return_value);
                    248:        
                    249:        SPL_LIST_CLASSES(return_value, 0, 0, 0)
                    250: }
                    251: /* }}} */
                    252: 
                    253: static int spl_autoload(const char *class_name, const char * lc_name, int class_name_len, const char * file_extension TSRMLS_DC) /* {{{ */
                    254: {
                    255:        char *class_file;
                    256:        int class_file_len;
                    257:        int dummy = 1;
                    258:        zend_file_handle file_handle;
                    259:        zend_op_array *new_op_array;
                    260:        zval *result = NULL;
                    261:        int ret;
                    262: 
                    263:        class_file_len = spprintf(&class_file, 0, "%s%s", lc_name, file_extension);
                    264: 
                    265: #if DEFAULT_SLASH != '\\'
                    266:        {
                    267:                char *ptr = class_file;
                    268:                char *end = ptr + class_file_len;
                    269:                
                    270:                while ((ptr = memchr(ptr, '\\', (end - ptr))) != NULL) {
                    271:                        *ptr = DEFAULT_SLASH;
                    272:                }
                    273:        }
                    274: #endif
                    275: 
1.1.1.2   misho     276:        ret = php_stream_open_for_zend_ex(class_file, &file_handle, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
1.1       misho     277: 
                    278:        if (ret == SUCCESS) {
                    279:                if (!file_handle.opened_path) {
                    280:                        file_handle.opened_path = estrndup(class_file, class_file_len);
                    281:                }
                    282:                if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
                    283:                        new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
                    284:                        zend_destroy_file_handle(&file_handle TSRMLS_CC);
                    285:                } else {
                    286:                        new_op_array = NULL;
                    287:                        zend_file_handle_dtor(&file_handle TSRMLS_CC);
                    288:                }
                    289:                if (new_op_array) {
                    290:                        EG(return_value_ptr_ptr) = &result;
                    291:                        EG(active_op_array) = new_op_array;
                    292:                        if (!EG(active_symbol_table)) {
                    293:                                zend_rebuild_symbol_table(TSRMLS_C);
                    294:                        }
                    295: 
                    296:                        zend_execute(new_op_array TSRMLS_CC);
                    297:        
                    298:                        destroy_op_array(new_op_array TSRMLS_CC);
                    299:                        efree(new_op_array);
                    300:                        if (!EG(exception)) {
                    301:                                if (EG(return_value_ptr_ptr)) {
                    302:                                        zval_ptr_dtor(EG(return_value_ptr_ptr));
                    303:                                }
                    304:                        }
                    305: 
                    306:                        efree(class_file);
                    307:                        return zend_hash_exists(EG(class_table), (char*)lc_name, class_name_len+1);
                    308:                }
                    309:        }
                    310:        efree(class_file);
                    311:        return 0;
                    312: } /* }}} */
                    313: 
                    314: /* {{{ proto void spl_autoload(string class_name [, string file_extensions])
                    315:  Default implementation for __autoload() */
                    316: PHP_FUNCTION(spl_autoload)
                    317: {
                    318:        char *class_name, *lc_name, *file_exts = SPL_G(autoload_extensions);
                    319:        int class_name_len, file_exts_len = SPL_G(autoload_extensions_len), found = 0;
                    320:        char *copy, *pos1, *pos2;
                    321:        zval **original_return_value = EG(return_value_ptr_ptr);
                    322:        zend_op **original_opline_ptr = EG(opline_ptr);
                    323:        zend_op_array *original_active_op_array = EG(active_op_array);
                    324:        
                    325:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &class_name, &class_name_len, &file_exts, &file_exts_len) == FAILURE) {
                    326:                RETURN_FALSE;
                    327:        }
                    328: 
                    329:        if (file_exts == NULL) { /* autoload_extensions is not intialzed, set to defaults */
                    330:                copy = pos1 = estrndup(SPL_DEFAULT_FILE_EXTENSIONS, sizeof(SPL_DEFAULT_FILE_EXTENSIONS)-1);
                    331:        } else {
                    332:                copy = pos1 = estrndup(file_exts, file_exts_len);
                    333:        }
                    334:        lc_name = zend_str_tolower_dup(class_name, class_name_len);
                    335:        while(pos1 && *pos1 && !EG(exception)) {
                    336:                EG(return_value_ptr_ptr) = original_return_value;
                    337:                EG(opline_ptr) = original_opline_ptr;
                    338:                EG(active_op_array) = original_active_op_array;
                    339:                pos2 = strchr(pos1, ',');
                    340:                if (pos2) *pos2 = '\0';
                    341:                if (spl_autoload(class_name, lc_name, class_name_len, pos1 TSRMLS_CC)) {
                    342:                        found = 1;
                    343:                        break; /* loaded */
                    344:                }
                    345:                pos1 = pos2 ? pos2 + 1 : NULL;
                    346:        }
                    347:        efree(lc_name);
                    348:        if (copy) {
                    349:                efree(copy);
                    350:        }
                    351: 
                    352:        EG(return_value_ptr_ptr) = original_return_value;
                    353:        EG(opline_ptr) = original_opline_ptr;
                    354:        EG(active_op_array) = original_active_op_array;
                    355: 
                    356:        if (!found && !SPL_G(autoload_running)) {
                    357:                /* For internal errors, we generate E_ERROR, for direct calls an exception is thrown.
                    358:                 * The "scope" is determined by an opcode, if it is ZEND_FETCH_CLASS we know function was called indirectly by
                    359:                 * the Zend engine.
                    360:                 */
                    361:                if (active_opline->opcode != ZEND_FETCH_CLASS) {
                    362:                        zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Class %s could not be loaded", class_name);
                    363:                } else {
                    364:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be loaded", class_name);
                    365:                }
                    366:        }
                    367: } /* }}} */
                    368: 
                    369: /* {{{ proto string spl_autoload_extensions([string file_extensions])
                    370:  Register and return default file extensions for spl_autoload */
                    371: PHP_FUNCTION(spl_autoload_extensions)
                    372: {
                    373:        char *file_exts = NULL;
                    374:        int file_exts_len;
                    375: 
                    376:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &file_exts, &file_exts_len) == FAILURE) {
                    377:                return;
                    378:        }
                    379:        if (file_exts) {
                    380:                if (SPL_G(autoload_extensions)) {
                    381:                        efree(SPL_G(autoload_extensions));
                    382:                }
                    383:                SPL_G(autoload_extensions) = estrndup(file_exts, file_exts_len);
                    384:                SPL_G(autoload_extensions_len) = file_exts_len;
                    385:        }
                    386: 
                    387:        if (SPL_G(autoload_extensions) == NULL) {
                    388:                RETURN_STRINGL(SPL_DEFAULT_FILE_EXTENSIONS, sizeof(SPL_DEFAULT_FILE_EXTENSIONS) - 1, 1);
                    389:        } else {
                    390:                RETURN_STRINGL(SPL_G(autoload_extensions), SPL_G(autoload_extensions_len), 1);
                    391:        }
                    392: } /* }}} */
                    393: 
                    394: typedef struct {
                    395:        zend_function *func_ptr;
                    396:        zval *obj;
                    397:        zval *closure;
                    398:        zend_class_entry *ce;
                    399: } autoload_func_info;
                    400: 
                    401: static void autoload_func_info_dtor(autoload_func_info *alfi)
                    402: {
                    403:        if (alfi->obj) {
                    404:                zval_ptr_dtor(&alfi->obj);
                    405:        }
                    406:        if (alfi->closure) {
                    407:                zval_ptr_dtor(&alfi->closure);
                    408:        }
                    409: }
                    410: 
                    411: /* {{{ proto void spl_autoload_call(string class_name)
                    412:  Try all registerd autoload function to load the requested class */
                    413: PHP_FUNCTION(spl_autoload_call)
                    414: {
                    415:        zval *class_name, *retval = NULL;
                    416:        int class_name_len;
                    417:        char *func_name, *lc_name;
                    418:        uint func_name_len;
                    419:        ulong dummy;
                    420:        HashPosition function_pos;
                    421:        autoload_func_info *alfi;
                    422: 
                    423:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE || Z_TYPE_P(class_name) != IS_STRING) {
                    424:                return;
                    425:        }
                    426: 
                    427:        if (SPL_G(autoload_functions)) {
                    428:                int l_autoload_running = SPL_G(autoload_running);
                    429:                SPL_G(autoload_running) = 1;
                    430:                class_name_len = Z_STRLEN_P(class_name);
                    431:                lc_name = zend_str_tolower_dup(Z_STRVAL_P(class_name), class_name_len);
                    432:                zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
                    433:                while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
                    434:                        zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &func_name_len, &dummy, 0, &function_pos);
                    435:                        zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
                    436:                        zend_call_method(alfi->obj ? &alfi->obj : NULL, alfi->ce, &alfi->func_ptr, func_name, func_name_len, &retval, 1, class_name, NULL TSRMLS_CC);
                    437:                        zend_exception_save(TSRMLS_C);
                    438:                        if (retval) {
                    439:                                zval_ptr_dtor(&retval);
                    440:                                retval = NULL;
                    441:                        }
                    442:                        if (zend_hash_exists(EG(class_table), lc_name, class_name_len + 1)) {
                    443:                                break;
                    444:                        }
                    445:                        zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
                    446:                }
                    447:                zend_exception_restore(TSRMLS_C);
                    448:                efree(lc_name);
                    449:                SPL_G(autoload_running) = l_autoload_running;
                    450:        } else {
                    451:                /* do not use or overwrite &EG(autoload_func) here */
                    452:                zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload", NULL, class_name);
                    453:        }
                    454: } /* }}} */
                    455: 
                    456: #define HT_MOVE_TAIL_TO_HEAD(ht)                                                       \
                    457:        (ht)->pListTail->pListNext = (ht)->pListHead;                   \
                    458:        (ht)->pListHead = (ht)->pListTail;                                              \
                    459:        (ht)->pListTail = (ht)->pListHead->pListLast;                   \
                    460:        (ht)->pListHead->pListNext->pListLast = (ht)->pListHead;\
                    461:        (ht)->pListTail->pListNext = NULL;                                              \
                    462:        (ht)->pListHead->pListLast = NULL;
                    463: 
                    464: /* {{{ proto bool spl_autoload_register([mixed autoload_function = "spl_autoload" [, throw = true [, prepend]]])
                    465:  Register given function as __autoload() implementation */
                    466: PHP_FUNCTION(spl_autoload_register)
                    467: {
                    468:        char *func_name, *error = NULL;
                    469:        int  func_name_len;
                    470:        char *lc_name = NULL;
                    471:        zval *zcallable = NULL;
                    472:        zend_bool do_throw = 1;
                    473:        zend_bool prepend  = 0;
                    474:        zend_function *spl_func_ptr;
                    475:        autoload_func_info alfi;
                    476:        zval *obj_ptr;
                    477:        zend_fcall_info_cache fcc;
                    478: 
                    479:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|zbb", &zcallable, &do_throw, &prepend) == FAILURE) {
                    480:                return;
                    481:        }
                    482: 
                    483:        if (ZEND_NUM_ARGS()) {
                    484:                if (Z_TYPE_P(zcallable) == IS_STRING) {
                    485:                        if (Z_STRLEN_P(zcallable) == sizeof("spl_autoload_call") - 1) {
                    486:                                if (!zend_binary_strcasecmp(Z_STRVAL_P(zcallable), sizeof("spl_autoload_call"), "spl_autoload_call", sizeof("spl_autoload_call"))) {
                    487:                                        if (do_throw) {
                    488:                                                zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function spl_autoload_call() cannot be registered");
                    489:                                        }
                    490:                                        RETURN_FALSE;
                    491:                                }
                    492:                        }
                    493:                }
                    494:        
                    495:                if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_STRICT, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
                    496:                        alfi.ce = fcc.calling_scope;
                    497:                        alfi.func_ptr = fcc.function_handler;
                    498:                        obj_ptr = fcc.object_ptr;
                    499:                        if (Z_TYPE_P(zcallable) == IS_ARRAY) {
                    500:                                if (!obj_ptr && alfi.func_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
                    501:                                        if (do_throw) {
                    502:                                                zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array specifies a non static method but no object (%s)", error);
                    503:                                        }
                    504:                                        if (error) {
                    505:                                                efree(error);
                    506:                                        }
                    507:                                        efree(func_name);
                    508:                                        RETURN_FALSE;
                    509:                                }
                    510:                                else if (do_throw) {
                    511:                                        zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Passed array does not specify %s %smethod (%s)", alfi.func_ptr ? "a callable" : "an existing", !obj_ptr ? "static " : "", error);
                    512:                                }
                    513:                                if (error) {
                    514:                                        efree(error);
                    515:                                }
                    516:                                efree(func_name);
                    517:                                RETURN_FALSE;
                    518:                        } else if (Z_TYPE_P(zcallable) == IS_STRING) {
                    519:                                if (do_throw) {
                    520:                                        zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Function '%s' not %s (%s)", func_name, alfi.func_ptr ? "callable" : "found", error);
                    521:                                }
                    522:                                if (error) {
                    523:                                        efree(error);
                    524:                                }
                    525:                                efree(func_name);
                    526:                                RETURN_FALSE;
                    527:                        } else {
                    528:                                if (do_throw) {
                    529:                                        zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Illegal value passed (%s)", error);
                    530:                                }
                    531:                                if (error) {
                    532:                                        efree(error);
                    533:                                }
                    534:                                efree(func_name);
                    535:                                RETURN_FALSE;
                    536:                        }
                    537:                }
                    538:                alfi.closure = NULL;
                    539:                alfi.ce = fcc.calling_scope;
                    540:                alfi.func_ptr = fcc.function_handler;
                    541:                obj_ptr = fcc.object_ptr;
                    542:                if (error) {
                    543:                        efree(error);
                    544:                }
                    545:        
                    546:                lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
                    547:                zend_str_tolower_copy(lc_name, func_name, func_name_len);
                    548:                efree(func_name);
                    549: 
                    550:                if (Z_TYPE_P(zcallable) == IS_OBJECT) {
                    551:                        alfi.closure = zcallable;
                    552:                        Z_ADDREF_P(zcallable);
                    553: 
                    554:                        lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
                    555:                        memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable),
                    556:                                sizeof(zend_object_handle));
                    557:                        func_name_len += sizeof(zend_object_handle);
                    558:                        lc_name[func_name_len] = '\0';
                    559:                }
                    560: 
                    561:                if (SPL_G(autoload_functions) && zend_hash_exists(SPL_G(autoload_functions), (char*)lc_name, func_name_len+1)) {
                    562:                        if (alfi.closure) {
                    563:                                Z_DELREF_P(zcallable);
                    564:                        }
                    565:                        goto skip;
                    566:                }
                    567: 
                    568:                if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
                    569:                        /* add object id to the hash to ensure uniqueness, for more reference look at bug #40091 */
                    570:                        lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
                    571:                        memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
                    572:                        func_name_len += sizeof(zend_object_handle);
                    573:                        lc_name[func_name_len] = '\0';
                    574:                        alfi.obj = obj_ptr;
                    575:                        Z_ADDREF_P(alfi.obj);
                    576:                } else {
                    577:                        alfi.obj = NULL;
                    578:                }
                    579: 
                    580:                if (!SPL_G(autoload_functions)) {
                    581:                        ALLOC_HASHTABLE(SPL_G(autoload_functions));
                    582:                        zend_hash_init(SPL_G(autoload_functions), 1, NULL, (dtor_func_t) autoload_func_info_dtor, 0);
                    583:                }
                    584: 
                    585:                zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr);
                    586: 
                    587:                if (EG(autoload_func) == spl_func_ptr) { /* registered already, so we insert that first */
                    588:                        autoload_func_info spl_alfi;
                    589: 
                    590:                        spl_alfi.func_ptr = spl_func_ptr;
                    591:                        spl_alfi.obj = NULL;
                    592:                        spl_alfi.ce = NULL;
                    593:                        spl_alfi.closure = NULL;
                    594:                        zend_hash_add(SPL_G(autoload_functions), "spl_autoload", sizeof("spl_autoload"), &spl_alfi, sizeof(autoload_func_info), NULL);
                    595:                        if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
                    596:                                /* Move the newly created element to the head of the hashtable */
                    597:                                HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions));
                    598:                        }
                    599:                }
                    600: 
1.1.1.2   misho     601:                if (zend_hash_add(SPL_G(autoload_functions), lc_name, func_name_len+1, &alfi.func_ptr, sizeof(autoload_func_info), NULL) == FAILURE) {
                    602:                        if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
                    603:                                Z_DELREF_P(alfi.obj);
                    604:                        }                               
                    605:                        if (alfi.closure) {
                    606:                                Z_DELREF_P(alfi.closure);
                    607:                        }
                    608:                }
1.1       misho     609:                if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
                    610:                        /* Move the newly created element to the head of the hashtable */
                    611:                        HT_MOVE_TAIL_TO_HEAD(SPL_G(autoload_functions));
                    612:                }
                    613: skip:
                    614:                efree(lc_name);
                    615:        }
                    616: 
                    617:        if (SPL_G(autoload_functions)) {
                    618:                zend_hash_find(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call"), (void **) &EG(autoload_func));
                    619:        } else {
                    620:                zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &EG(autoload_func));
                    621:        }
                    622:        RETURN_TRUE;
                    623: } /* }}} */
                    624: 
                    625: /* {{{ proto bool spl_autoload_unregister(mixed autoload_function)
                    626:  Unregister given function as __autoload() implementation */
                    627: PHP_FUNCTION(spl_autoload_unregister)
                    628: {
                    629:        char *func_name, *error = NULL;
                    630:        int func_name_len;
                    631:        char *lc_name = NULL;
                    632:        zval *zcallable;
                    633:        int success = FAILURE;
                    634:        zend_function *spl_func_ptr;
                    635:        zval *obj_ptr;
                    636:        zend_fcall_info_cache fcc;
                    637: 
                    638:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zcallable) == FAILURE) {
                    639:                return;
                    640:        }
                    641: 
                    642:        if (!zend_is_callable_ex(zcallable, NULL, IS_CALLABLE_CHECK_SYNTAX_ONLY, &func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
                    643:                zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Unable to unregister invalid function (%s)", error);
                    644:                if (error) {
                    645:                        efree(error);
                    646:                }
                    647:                if (func_name) {
                    648:                        efree(func_name);
                    649:                }
                    650:                RETURN_FALSE;
                    651:        }
                    652:        obj_ptr = fcc.object_ptr;
                    653:        if (error) {
                    654:                efree(error);
                    655:        }
                    656: 
                    657:        lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1);
                    658:        zend_str_tolower_copy(lc_name, func_name, func_name_len);
                    659:        efree(func_name);
                    660: 
                    661:        if (Z_TYPE_P(zcallable) == IS_OBJECT) {
                    662:                lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
                    663:                memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable),
                    664:                        sizeof(zend_object_handle));
                    665:                func_name_len += sizeof(zend_object_handle);
                    666:                lc_name[func_name_len] = '\0';
                    667:        }
                    668: 
                    669:        if (SPL_G(autoload_functions)) {
                    670:                if (func_name_len == sizeof("spl_autoload_call")-1 && !strcmp(lc_name, "spl_autoload_call")) {
                    671:                        /* remove all */
                    672:                        zend_hash_destroy(SPL_G(autoload_functions));
                    673:                        FREE_HASHTABLE(SPL_G(autoload_functions));
                    674:                        SPL_G(autoload_functions) = NULL;
                    675:                        EG(autoload_func) = NULL;
                    676:                        success = SUCCESS;
                    677:                } else {
                    678:                        /* remove specific */
                    679:                        success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1);
                    680:                        if (success != SUCCESS && obj_ptr) {
                    681:                                lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle));
                    682:                                memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle));
                    683:                                func_name_len += sizeof(zend_object_handle);
                    684:                                lc_name[func_name_len] = '\0';
                    685:                                success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1);
                    686:                        }
                    687:                }
                    688:        } else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(lc_name, "spl_autoload")) {
                    689:                /* register single spl_autoload() */
                    690:                zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr);
                    691: 
                    692:                if (EG(autoload_func) == spl_func_ptr) {
                    693:                        success = SUCCESS;
                    694:                        EG(autoload_func) = NULL;
                    695:                }
                    696:        }
                    697: 
                    698:        efree(lc_name);
                    699:        RETURN_BOOL(success == SUCCESS);
                    700: } /* }}} */
                    701: 
                    702: /* {{{ proto false|array spl_autoload_functions()
                    703:  Return all registered __autoload() functionns */
                    704: PHP_FUNCTION(spl_autoload_functions)
                    705: {
                    706:        zend_function *fptr;
                    707:        HashPosition function_pos;
                    708:        autoload_func_info *alfi;
                    709: 
                    710:        if (zend_parse_parameters_none() == FAILURE) {
                    711:                return;
                    712:        }
                    713:        
                    714:        if (!EG(autoload_func)) {
                    715:                if (zend_hash_find(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME), (void **) &fptr) == SUCCESS) {
                    716:                        array_init(return_value);
                    717:                        add_next_index_stringl(return_value, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)-1, 1);
                    718:                        return;
                    719:                }
                    720:                RETURN_FALSE;
                    721:        }
                    722: 
                    723:        zend_hash_find(EG(function_table), "spl_autoload_call", sizeof("spl_autoload_call"), (void **) &fptr);
                    724: 
                    725:        if (EG(autoload_func) == fptr) {
                    726:                array_init(return_value);
                    727:                zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos);
                    728:                while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) {
                    729:                        zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos);
                    730:                        if (alfi->closure) {
                    731:                                Z_ADDREF_P(alfi->closure);
                    732:                                add_next_index_zval(return_value, alfi->closure);
                    733:                        } else if (alfi->func_ptr->common.scope) {
                    734:                                zval *tmp;
                    735:                                MAKE_STD_ZVAL(tmp);
                    736:                                array_init(tmp);
                    737: 
                    738:                                if (alfi->obj) {
                    739:                                        Z_ADDREF_P(alfi->obj);
                    740:                                        add_next_index_zval(tmp, alfi->obj);
                    741:                                } else {
                    742:                                        add_next_index_string(tmp, alfi->ce->name, 1);
                    743:                                }
                    744:                                add_next_index_string(tmp, alfi->func_ptr->common.function_name, 1);
                    745:                                add_next_index_zval(return_value, tmp);
                    746:                        } else
                    747:                                add_next_index_string(return_value, alfi->func_ptr->common.function_name, 1);
                    748: 
                    749:                        zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
                    750:                }
                    751:                return;
                    752:        }
                    753: 
                    754:        array_init(return_value);
                    755:        add_next_index_string(return_value, EG(autoload_func)->common.function_name, 1);
                    756: } /* }}} */
                    757: 
                    758: /* {{{ proto string spl_object_hash(object obj)
                    759:  Return hash id for given object */
                    760: PHP_FUNCTION(spl_object_hash)
                    761: {
                    762:        zval *obj;
                    763:        char* hash;
                    764: 
                    765:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
                    766:                return;
                    767:        }
                    768:        
                    769:        hash = emalloc(33);
                    770:        php_spl_object_hash(obj, hash TSRMLS_CC);
                    771:        
                    772:        RETVAL_STRING(hash, 0);
                    773: }
                    774: /* }}} */
                    775: 
                    776: PHPAPI void php_spl_object_hash(zval *obj, char *result TSRMLS_DC) /* {{{*/
                    777: {
                    778:        intptr_t hash_handle, hash_handlers;
                    779:        char *hex;
                    780: 
                    781:        if (!SPL_G(hash_mask_init)) {
                    782:                if (!BG(mt_rand_is_seeded)) {
                    783:                        php_mt_srand(GENERATE_SEED() TSRMLS_CC);
                    784:                }
                    785: 
                    786:                SPL_G(hash_mask_handle)   = (intptr_t)(php_mt_rand(TSRMLS_C) >> 1);
                    787:                SPL_G(hash_mask_handlers) = (intptr_t)(php_mt_rand(TSRMLS_C) >> 1);
                    788:                SPL_G(hash_mask_init) = 1;
                    789:        }
                    790: 
                    791:        hash_handle   = SPL_G(hash_mask_handle)^(intptr_t)Z_OBJ_HANDLE_P(obj);
                    792:        hash_handlers = SPL_G(hash_mask_handlers)^(intptr_t)Z_OBJ_HT_P(obj);
                    793: 
                    794:        spprintf(&hex, 32, "%016x%016x", hash_handle, hash_handlers);
                    795: 
                    796:        strlcpy(result, hex, 33);
                    797:        efree(hex);
                    798: }
                    799: /* }}} */
                    800: 
                    801: int spl_build_class_list_string(zval **entry, char **list TSRMLS_DC) /* {{{ */
                    802: {
                    803:        char *res;
                    804:        
                    805:        spprintf(&res, 0, "%s, %s", *list, Z_STRVAL_PP(entry));
                    806:        efree(*list);
                    807:        *list = res;
                    808:        return ZEND_HASH_APPLY_KEEP;
                    809: } /* }}} */
                    810: 
                    811: /* {{{ PHP_MINFO(spl)
                    812:  */
                    813: PHP_MINFO_FUNCTION(spl)
                    814: {
                    815:        zval list;
                    816:        char *strg;
                    817: 
                    818:        php_info_print_table_start();
                    819:        php_info_print_table_header(2, "SPL support",        "enabled");
                    820: 
                    821:        INIT_PZVAL(&list);
                    822:        array_init(&list);
                    823:        SPL_LIST_CLASSES(&list, 0, 1, ZEND_ACC_INTERFACE)
                    824:        strg = estrdup("");
                    825:        zend_hash_apply_with_argument(Z_ARRVAL_P(&list), (apply_func_arg_t)spl_build_class_list_string, &strg TSRMLS_CC);
                    826:        zval_dtor(&list);
                    827:        php_info_print_table_row(2, "Interfaces", strg + 2);
                    828:        efree(strg);
                    829: 
                    830:        INIT_PZVAL(&list);
                    831:        array_init(&list);
                    832:        SPL_LIST_CLASSES(&list, 0, -1, ZEND_ACC_INTERFACE)
                    833:        strg = estrdup("");
                    834:        zend_hash_apply_with_argument(Z_ARRVAL_P(&list), (apply_func_arg_t)spl_build_class_list_string, &strg TSRMLS_CC);
                    835:        zval_dtor(&list);
                    836:        php_info_print_table_row(2, "Classes", strg + 2);
                    837:        efree(strg);
                    838: 
                    839:        php_info_print_table_end();
                    840: }
                    841: /* }}} */
                    842: 
                    843: /* {{{ arginfo */
                    844: ZEND_BEGIN_ARG_INFO_EX(arginfo_iterator_to_array, 0, 0, 1)
                    845:        ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
                    846:        ZEND_ARG_INFO(0, use_keys)
                    847: ZEND_END_ARG_INFO();
                    848: 
                    849: ZEND_BEGIN_ARG_INFO(arginfo_iterator, 0)
                    850:        ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
                    851: ZEND_END_ARG_INFO();
                    852: 
                    853: ZEND_BEGIN_ARG_INFO_EX(arginfo_iterator_apply, 0, 0, 2)
                    854:        ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
                    855:        ZEND_ARG_INFO(0, function)
                    856:        ZEND_ARG_ARRAY_INFO(0, args, 1)
                    857: ZEND_END_ARG_INFO();
                    858: 
                    859: ZEND_BEGIN_ARG_INFO_EX(arginfo_class_parents, 0, 0, 1)
                    860:        ZEND_ARG_INFO(0, instance)
                    861:        ZEND_ARG_INFO(0, autoload)
                    862: ZEND_END_ARG_INFO()
                    863: 
                    864: ZEND_BEGIN_ARG_INFO_EX(arginfo_class_implements, 0, 0, 1)
                    865:        ZEND_ARG_INFO(0, what)
                    866:        ZEND_ARG_INFO(0, autoload)
                    867: ZEND_END_ARG_INFO()
                    868: 
1.1.1.2   misho     869: ZEND_BEGIN_ARG_INFO_EX(arginfo_class_uses, 0, 0, 1)
                    870:        ZEND_ARG_INFO(0, what)
                    871:        ZEND_ARG_INFO(0, autoload)
                    872: ZEND_END_ARG_INFO()
                    873: 
                    874: 
1.1       misho     875: ZEND_BEGIN_ARG_INFO(arginfo_spl_classes, 0)
                    876: ZEND_END_ARG_INFO()
                    877: 
                    878: ZEND_BEGIN_ARG_INFO(arginfo_spl_autoload_functions, 0)
                    879: ZEND_END_ARG_INFO()
                    880: 
                    881: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload, 0, 0, 1)
                    882:        ZEND_ARG_INFO(0, class_name)
                    883:        ZEND_ARG_INFO(0, file_extensions)
                    884: ZEND_END_ARG_INFO()
                    885: 
                    886: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_extensions, 0, 0, 0)
                    887:        ZEND_ARG_INFO(0, file_extensions)
                    888: ZEND_END_ARG_INFO()
                    889: 
                    890: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_call, 0, 0, 1)
                    891:        ZEND_ARG_INFO(0, class_name)
                    892: ZEND_END_ARG_INFO()
                    893: 
                    894: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_register, 0, 0, 0)
                    895:        ZEND_ARG_INFO(0, autoload_function)
                    896: ZEND_END_ARG_INFO()
                    897: 
                    898: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_autoload_unregister, 0, 0, 1)
                    899:        ZEND_ARG_INFO(0, autoload_function)
                    900: ZEND_END_ARG_INFO()
                    901: 
                    902: ZEND_BEGIN_ARG_INFO_EX(arginfo_spl_object_hash, 0, 0, 1)
                    903:        ZEND_ARG_INFO(0, obj)
                    904: ZEND_END_ARG_INFO()
                    905: /* }}} */
                    906: 
                    907: /* {{{ spl_functions
                    908:  */
                    909: const zend_function_entry spl_functions[] = {
                    910:        PHP_FE(spl_classes,             arginfo_spl_classes)
                    911:        PHP_FE(spl_autoload,            arginfo_spl_autoload)
                    912:        PHP_FE(spl_autoload_extensions, arginfo_spl_autoload_extensions)
                    913:        PHP_FE(spl_autoload_register,   arginfo_spl_autoload_register)
                    914:        PHP_FE(spl_autoload_unregister, arginfo_spl_autoload_unregister)
                    915:        PHP_FE(spl_autoload_functions,  arginfo_spl_autoload_functions)
                    916:        PHP_FE(spl_autoload_call,       arginfo_spl_autoload_call)
                    917:        PHP_FE(class_parents,           arginfo_class_parents)
                    918:        PHP_FE(class_implements,        arginfo_class_implements)
1.1.1.2   misho     919:        PHP_FE(class_uses,              arginfo_class_uses)
1.1       misho     920:        PHP_FE(spl_object_hash,         arginfo_spl_object_hash)
                    921: #ifdef SPL_ITERATORS_H
                    922:        PHP_FE(iterator_to_array,       arginfo_iterator_to_array)
                    923:        PHP_FE(iterator_count,          arginfo_iterator)
                    924:        PHP_FE(iterator_apply,          arginfo_iterator_apply)
                    925: #endif /* SPL_ITERATORS_H */
                    926:        PHP_FE_END
                    927: };
                    928: /* }}} */
                    929: 
                    930: /* {{{ PHP_MINIT_FUNCTION(spl)
                    931:  */
                    932: PHP_MINIT_FUNCTION(spl)
                    933: {
                    934:        PHP_MINIT(spl_exceptions)(INIT_FUNC_ARGS_PASSTHRU);
                    935:        PHP_MINIT(spl_iterators)(INIT_FUNC_ARGS_PASSTHRU);
                    936:        PHP_MINIT(spl_array)(INIT_FUNC_ARGS_PASSTHRU);
                    937:        PHP_MINIT(spl_directory)(INIT_FUNC_ARGS_PASSTHRU);
                    938:        PHP_MINIT(spl_dllist)(INIT_FUNC_ARGS_PASSTHRU);
                    939:        PHP_MINIT(spl_heap)(INIT_FUNC_ARGS_PASSTHRU);
                    940:        PHP_MINIT(spl_fixedarray)(INIT_FUNC_ARGS_PASSTHRU);
                    941:        PHP_MINIT(spl_observer)(INIT_FUNC_ARGS_PASSTHRU);
                    942: 
                    943:        return SUCCESS;
                    944: }
                    945: /* }}} */
                    946: 
                    947: PHP_RINIT_FUNCTION(spl) /* {{{ */
                    948: {
                    949:        SPL_G(autoload_extensions) = NULL;
                    950:        SPL_G(autoload_extensions_len) = 0;
                    951:        SPL_G(autoload_functions) = NULL;
                    952:        SPL_G(hash_mask_init) = 0;
                    953:        return SUCCESS;
                    954: } /* }}} */
                    955: 
                    956: PHP_RSHUTDOWN_FUNCTION(spl) /* {{{ */
                    957: {
                    958:        if (SPL_G(autoload_extensions)) {
                    959:                efree(SPL_G(autoload_extensions));
                    960:                SPL_G(autoload_extensions) = NULL;
                    961:                SPL_G(autoload_extensions_len) = 0;
                    962:        }
                    963:        if (SPL_G(autoload_functions)) {
                    964:                zend_hash_destroy(SPL_G(autoload_functions));
                    965:                FREE_HASHTABLE(SPL_G(autoload_functions));
                    966:                SPL_G(autoload_functions) = NULL;
                    967:        }
                    968:        if (SPL_G(hash_mask_init)) {
                    969:                SPL_G(hash_mask_init) = 0;
                    970:        }
                    971:        return SUCCESS;
                    972: } /* }}} */
                    973: 
                    974: /* {{{ spl_module_entry
                    975:  */
                    976: zend_module_entry spl_module_entry = {
                    977:        STANDARD_MODULE_HEADER,
                    978:        "SPL",
                    979:        spl_functions,
                    980:        PHP_MINIT(spl),
                    981:        NULL,
                    982:        PHP_RINIT(spl),
                    983:        PHP_RSHUTDOWN(spl),
                    984:        PHP_MINFO(spl),
                    985:        "0.2",
                    986:        PHP_MODULE_GLOBALS(spl),
                    987:        PHP_GINIT(spl),
                    988:        NULL,
                    989:        NULL,
                    990:        STANDARD_MODULE_PROPERTIES_EX
                    991: };
                    992: /* }}} */
                    993: 
                    994: /*
                    995:  * Local variables:
                    996:  * tab-width: 4
                    997:  * c-basic-offset: 4
                    998:  * End:
                    999:  * vim600: fdm=marker
                   1000:  * vim: noet sw=4 ts=4
                   1001:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>