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

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

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