Annotation of embedaddon/php/ext/reflection/php_reflection.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: Timm Friebe <thekid@thekid.de>                              |
                     16:    |          George Schlossnagle <george@omniti.com>                     |
                     17:    |          Andrei Zmievski <andrei@gravitonic.com>                     |
                     18:    |          Marcus Boerger <helly@php.net>                              |
                     19:    |          Johannes Schlueter <johannes@php.net>                       |
                     20:    +----------------------------------------------------------------------+
                     21: */
                     22: 
                     23: /* $Id: php_reflection.c 321634 2012-01-01 13:15:04Z felipe $ */
                     24: 
                     25: #ifdef HAVE_CONFIG_H
                     26: #include "config.h"
                     27: #endif
                     28: 
                     29: #include "php.h"
                     30: #include "php_ini.h"
                     31: #include "php_reflection.h"
                     32: #include "ext/standard/info.h"
                     33: 
                     34: #include "zend.h"
                     35: #include "zend_API.h"
                     36: #include "zend_exceptions.h"
                     37: #include "zend_operators.h"
                     38: #include "zend_constants.h"
                     39: #include "zend_ini.h"
                     40: #include "zend_interfaces.h"
                     41: #include "zend_closures.h"
                     42: 
                     43: /* Undefine "getParameters" macro defined in "main/php3_compat.h" */
                     44: #ifdef getParameters
                     45: # undef getParameters
                     46: #endif
                     47: 
                     48: /* Class entry pointers */
                     49: PHPAPI zend_class_entry *reflector_ptr;
                     50: PHPAPI zend_class_entry *reflection_exception_ptr;
                     51: PHPAPI zend_class_entry *reflection_ptr;
                     52: PHPAPI zend_class_entry *reflection_function_abstract_ptr;
                     53: PHPAPI zend_class_entry *reflection_function_ptr;
                     54: PHPAPI zend_class_entry *reflection_parameter_ptr;
                     55: PHPAPI zend_class_entry *reflection_class_ptr;
                     56: PHPAPI zend_class_entry *reflection_object_ptr;
                     57: PHPAPI zend_class_entry *reflection_method_ptr;
                     58: PHPAPI zend_class_entry *reflection_property_ptr;
                     59: PHPAPI zend_class_entry *reflection_extension_ptr;
                     60: 
                     61: #if MBO_0
                     62: ZEND_BEGIN_MODULE_GLOBALS(reflection)
                     63:        int dummy;
                     64: ZEND_END_MODULE_GLOBALS(reflection)
                     65: 
                     66: #ifdef ZTS
                     67: # define REFLECTION_G(v) \
                     68:        TSRMG(reflection_globals_id, zend_reflection_globals*, v)
                     69: extern int reflection_globals_id;
                     70: #else
                     71: # define REFLECTION_G(v) (reflection_globals.v)
                     72: extern zend_reflection_globals reflectionglobals;
                     73: #endif
                     74: 
                     75: ZEND_DECLARE_MODULE_GLOBALS(reflection)
                     76: #endif /* MBO_0 */
                     77: 
                     78: /* Method macros */
                     79: 
                     80: #define METHOD_NOTSTATIC(ce)                                                                                \
                     81:        if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {                             \
                     82:                php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C));        \
                     83:                return;                                                                                             \
                     84:        }                                                                                                       \
                     85: 
                     86: /* Exception throwing macro */
                     87: #define _DO_THROW(msg)                                                                                      \
                     88:        zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC);                                       \
                     89:        return;                                                                                                 \
                     90: 
                     91: #define RETURN_ON_EXCEPTION                                                                                 \
                     92:        if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) {                            \
                     93:                return;                                                                                             \
                     94:        }
                     95: 
                     96: #define GET_REFLECTION_OBJECT_PTR(target)                                                                   \
                     97:        intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);                       \
                     98:        if (intern == NULL || intern->ptr == NULL) {                                                            \
                     99:                RETURN_ON_EXCEPTION                                                                                 \
                    100:                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object");                    \
                    101:        }                                                                                                       \
                    102:        target = intern->ptr;                                                                                   \
                    103: 
                    104: /* Class constants */
                    105: #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value)                                        \
                    106:        zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
                    107: 
                    108: /* {{{ Smart string functions */
                    109: typedef struct _string {
                    110:        char *string;
                    111:        int len;
                    112:        int alloced;
                    113: } string;
                    114: 
                    115: static void string_init(string *str)
                    116: {
                    117:        str->string = (char *) emalloc(1024);
                    118:        str->len = 1;
                    119:        str->alloced = 1024;
                    120:        *str->string = '\0';
                    121: }
                    122:        
                    123: static string *string_printf(string *str, const char *format, ...)
                    124: {
                    125:        int len;
                    126:        va_list arg;
                    127:        char *s_tmp;
                    128: 
                    129:        va_start(arg, format);
                    130:        len = zend_vspprintf(&s_tmp, 0, format, arg);
                    131:        if (len) {
                    132:                register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
                    133:                if (str->alloced < nlen) {
                    134:                        str->alloced = nlen;
                    135:                        str->string = erealloc(str->string, str->alloced);
                    136:                }
                    137:                memcpy(str->string + str->len - 1, s_tmp, len + 1);
                    138:                str->len += len;
                    139:        }
                    140:        efree(s_tmp);
                    141:        va_end(arg);
                    142:        return str;
                    143: }
                    144: 
                    145: static string *string_write(string *str, char *buf, int len)
                    146: {
                    147:        register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
                    148:        if (str->alloced < nlen) {
                    149:                str->alloced = nlen;
                    150:                str->string = erealloc(str->string, str->alloced);
                    151:        }
                    152:        memcpy(str->string + str->len - 1, buf, len);
                    153:        str->len += len;
                    154:        str->string[str->len - 1] = '\0';
                    155:        return str;
                    156: }
                    157: 
                    158: static string *string_append(string *str, string *append)
                    159: {
                    160:        if (append->len > 1) {
                    161:                string_write(str, append->string, append->len - 1);
                    162:        }
                    163:        return str;
                    164: }
                    165: 
                    166: static void string_free(string *str)
                    167: {
                    168:        efree(str->string);
                    169:        str->len = 0;
                    170:        str->alloced = 0;
                    171:        str->string = NULL;
                    172: }
                    173: /* }}} */
                    174: 
                    175: /* Struct for properties */
                    176: typedef struct _property_reference {
                    177:        zend_class_entry *ce;
                    178:        zend_property_info prop;
                    179: } property_reference;
                    180: 
                    181: /* Struct for parameters */
                    182: typedef struct _parameter_reference {
                    183:        zend_uint offset;
                    184:        zend_uint required;
                    185:        struct _zend_arg_info *arg_info;
                    186:        zend_function *fptr;
                    187: } parameter_reference;
                    188: 
                    189: typedef enum {
                    190:        REF_TYPE_OTHER,      /* Must be 0 */
                    191:        REF_TYPE_FUNCTION,
                    192:        REF_TYPE_PARAMETER,
                    193:        REF_TYPE_PROPERTY,
                    194:        REF_TYPE_DYNAMIC_PROPERTY
                    195: } reflection_type_t;
                    196: 
                    197: /* Struct for reflection objects */
                    198: typedef struct {
                    199:        zend_object zo;
                    200:        void *ptr;
                    201:        reflection_type_t ref_type;
                    202:        zval *obj;
                    203:        zend_class_entry *ce;
                    204:        unsigned int ignore_visibility:1;
                    205: } reflection_object;
                    206: 
                    207: static zend_object_handlers reflection_object_handlers;
                    208: 
                    209: static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC)
                    210: {
                    211:        zval **value;
                    212: 
                    213:        if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
                    214:                RETURN_FALSE;
                    215:        }
                    216: 
                    217:        MAKE_COPY_ZVAL(value, return_value);
                    218: }
                    219: 
                    220: #ifdef ilia_0
                    221: static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value TSRMLS_DC) /* {{{ */
                    222: {
                    223:        zval **value;
                    224: 
                    225:        if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
                    226:                *return_value = NULL;
                    227:        } else {
                    228:                *return_value = *value;
                    229:        }
                    230: }
                    231: /* }}} */
                    232: #endif
                    233: 
                    234: static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC)
                    235: {
                    236:        zend_uint num_interfaces = ++class_entry->num_interfaces;
                    237: 
                    238:        class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces);
                    239:        class_entry->interfaces[num_interfaces - 1] = interface_entry;
                    240: }
                    241: 
                    242: static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
                    243: {
                    244:        if (fptr
                    245:                && fptr->type == ZEND_INTERNAL_FUNCTION
                    246:                && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
                    247:        {
                    248:                zend_function *copy_fptr;
                    249:                copy_fptr = emalloc(sizeof(zend_function));
                    250:                memcpy(copy_fptr, fptr, sizeof(zend_function));
                    251:                copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name);
                    252:                return copy_fptr;
                    253:        } else {
                    254:                /* no copy needed */
                    255:                return fptr;
                    256:        }
                    257: }
                    258: /* }}} */
                    259: 
                    260: static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
                    261: {
                    262:        if (fptr
                    263:                && fptr->type == ZEND_INTERNAL_FUNCTION
                    264:                && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
                    265:        {
                    266:                efree(fptr->internal_function.function_name);
                    267:                efree(fptr);
                    268:        }
                    269: }
                    270: /* }}} */
                    271: 
                    272: static void reflection_free_objects_storage(void *object TSRMLS_DC)
                    273: {
                    274:        reflection_object *intern = (reflection_object *) object;
                    275:        parameter_reference *reference;
                    276:        property_reference *prop_reference;
                    277: 
                    278:        if (intern->ptr) {
                    279:                switch (intern->ref_type) {
                    280:                case REF_TYPE_PARAMETER:
                    281:                        reference = (parameter_reference*)intern->ptr;
                    282:                        _free_function(reference->fptr TSRMLS_CC);
                    283:                        efree(intern->ptr);
                    284:                        break;
                    285:                case REF_TYPE_FUNCTION:
                    286:                        _free_function(intern->ptr TSRMLS_CC);
                    287:                        break;
                    288:                case REF_TYPE_PROPERTY:
                    289:                        efree(intern->ptr);
                    290:                        break;
                    291:                case REF_TYPE_DYNAMIC_PROPERTY:
                    292:                        prop_reference = (property_reference*)intern->ptr;
                    293:                        efree(prop_reference->prop.name);
                    294:                        efree(intern->ptr);
                    295:                        break;
                    296:                case REF_TYPE_OTHER:
                    297:                        break;
                    298:                }
                    299:        }
                    300:        intern->ptr = NULL;
                    301:        if (intern->obj) {
                    302:                zval_ptr_dtor(&intern->obj);
                    303:        }
                    304:        zend_objects_free_object_storage(object TSRMLS_CC);
                    305: }
                    306: 
                    307: static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC)
                    308: {
                    309:        zval tmp;
                    310:        zend_object_value retval;
                    311:        reflection_object *intern;
                    312: 
                    313:        intern = ecalloc(1, sizeof(reflection_object));
                    314:        intern->zo.ce = class_type;
                    315: 
                    316:        zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
                    317:        zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
                    318:        retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC);
                    319:        retval.handlers = &reflection_object_handlers;
                    320:        return retval;
                    321: }
                    322: 
                    323: static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
                    324: {
                    325:        if (!object) {
                    326:                ALLOC_ZVAL(object);
                    327:        }
                    328:        Z_TYPE_P(object) = IS_OBJECT;
                    329:        object_init_ex(object, pce);
                    330:        Z_SET_REFCOUNT_P(object, 1);
                    331:        Z_SET_ISREF_P(object);
                    332:        return object;
                    333: }
                    334: 
                    335: static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
                    336: static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
                    337: static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
                    338: static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
                    339: static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
                    340: 
                    341: /* {{{ _class_string */
                    342: static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC)
                    343: {
                    344:        int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
                    345:        string sub_indent;
                    346:        
                    347:        string_init(&sub_indent);
                    348:        string_printf(&sub_indent, "%s    ", indent);
                    349: 
                    350:        /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
                    351:        if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
                    352:                string_printf(str, "%s%s", indent, ce->doc_comment);
                    353:                string_write(str, "\n", 1);
                    354:        }
                    355: 
                    356:        if (obj) {
                    357:                string_printf(str, "%sObject of class [ ", indent);
                    358:        } else {
                    359:                string_printf(str, "%s%s [ ", indent, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : "Class");
                    360:        }
                    361:        string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
                    362:        if (ce->module) {
                    363:                string_printf(str, ":%s", ce->module->name);
                    364:        }
                    365:        string_printf(str, "> ");
                    366:        if (ce->get_iterator != NULL) {
                    367:                string_printf(str, "<iterateable> ");
                    368:        }
                    369:        if (ce->ce_flags & ZEND_ACC_INTERFACE) {
                    370:                string_printf(str, "interface ");
                    371:        } else {
                    372:                if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
                    373:                        string_printf(str, "abstract ");
                    374:                }
                    375:                if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
                    376:                        string_printf(str, "final ");
                    377:                } 
                    378:                string_printf(str, "class ");
                    379:        }
                    380:        string_printf(str, "%s", ce->name);
                    381:        if (ce->parent) {
                    382:                string_printf(str, " extends %s", ce->parent->name);
                    383:        }
                    384: 
                    385:        if (ce->num_interfaces) {
                    386:                zend_uint i;
                    387: 
                    388:                if (ce->ce_flags & ZEND_ACC_INTERFACE) {
                    389:                        string_printf(str, " extends %s", ce->interfaces[0]->name);
                    390:                } else {
                    391:                        string_printf(str, " implements %s", ce->interfaces[0]->name);
                    392:                }
                    393:                for (i = 1; i < ce->num_interfaces; ++i) {
                    394:                        string_printf(str, ", %s", ce->interfaces[i]->name);
                    395:                }
                    396:        }
                    397:        string_printf(str, " ] {\n");
                    398: 
                    399:        /* The information where a class is declared is only available for user classes */
                    400:        if (ce->type == ZEND_USER_CLASS) {
                    401:                string_printf(str, "%s  @@ %s %d-%d\n", indent, ce->filename,
                    402:                                                ce->line_start, ce->line_end);
                    403:        }
                    404: 
                    405:        /* Constants */
                    406:        if (&ce->constants_table) {
                    407:                zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
                    408:                string_printf(str, "\n");
                    409:                count = zend_hash_num_elements(&ce->constants_table);
                    410:                string_printf(str, "%s  - Constants [%d] {\n", indent, count);
                    411:                if (count > 0) {
                    412:                        HashPosition pos;
                    413:                        zval **value;
                    414:                        char *key;
                    415:                        uint key_len;
                    416:                        ulong num_index;
                    417: 
                    418:                        zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos);
                    419: 
                    420:                        while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) {
                    421:                                zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos);
                    422: 
                    423:                                _const_string(str, key, *value, indent TSRMLS_CC);
                    424:                                zend_hash_move_forward_ex(&ce->constants_table, &pos);
                    425:                        }
                    426:                }
                    427:                string_printf(str, "%s  }\n", indent);
                    428:        }
                    429: 
                    430:        /* Static properties */
                    431:        if (&ce->properties_info) {
                    432:                /* counting static properties */                
                    433:                count = zend_hash_num_elements(&ce->properties_info);
                    434:                if (count > 0) {
                    435:                        HashPosition pos;
                    436:                        zend_property_info *prop;
                    437: 
                    438:                        zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
                    439: 
                    440:                        while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
                    441:                                if(prop->flags & ZEND_ACC_SHADOW) {
                    442:                                        count_shadow_props++;
                    443:                                } else if (prop->flags & ZEND_ACC_STATIC) {
                    444:                                        count_static_props++;
                    445:                                }
                    446:                                zend_hash_move_forward_ex(&ce->properties_info, &pos);
                    447:                        }
                    448:                }
                    449: 
                    450:                /* static properties */         
                    451:                string_printf(str, "\n%s  - Static properties [%d] {\n", indent, count_static_props);
                    452:                if (count_static_props > 0) {
                    453:                        HashPosition pos;
                    454:                        zend_property_info *prop;
                    455: 
                    456:                        zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
                    457: 
                    458:                        while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
                    459:                                if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
                    460:                                        _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
                    461:                                }
                    462: 
                    463:                                zend_hash_move_forward_ex(&ce->properties_info, &pos);
                    464:                        }
                    465:                }
                    466:                string_printf(str, "%s  }\n", indent);
                    467:        }
                    468:        
                    469:        /* Static methods */
                    470:        if (&ce->function_table) {
                    471:                /* counting static methods */           
                    472:                count = zend_hash_num_elements(&ce->function_table);
                    473:                if (count > 0) {
                    474:                        HashPosition pos;
                    475:                        zend_function *mptr;
                    476: 
                    477:                        zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
                    478: 
                    479:                        while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
                    480:                                if (mptr->common.fn_flags & ZEND_ACC_STATIC
                    481:                                        && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
                    482:                                {
                    483:                                        count_static_funcs++;
                    484:                                }
                    485:                                zend_hash_move_forward_ex(&ce->function_table, &pos);
                    486:                        }
                    487:                }
                    488: 
                    489:                /* static methods */            
                    490:                string_printf(str, "\n%s  - Static methods [%d] {", indent, count_static_funcs);
                    491:                if (count_static_funcs > 0) {
                    492:                        HashPosition pos;
                    493:                        zend_function *mptr;
                    494: 
                    495:                        zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
                    496: 
                    497:                        while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
                    498:                                if (mptr->common.fn_flags & ZEND_ACC_STATIC
                    499:                                        && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
                    500:                                {
                    501:                                        string_printf(str, "\n");
                    502:                                        _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
                    503:                                }
                    504:                                zend_hash_move_forward_ex(&ce->function_table, &pos);
                    505:                        }
                    506:                } else {
                    507:                        string_printf(str, "\n");
                    508:                }
                    509:                string_printf(str, "%s  }\n", indent);
                    510:        }
                    511: 
                    512:        /* Default/Implicit properties */
                    513:        if (&ce->properties_info) {
                    514:                count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
                    515:                string_printf(str, "\n%s  - Properties [%d] {\n", indent, count);
                    516:                if (count > 0) {
                    517:                        HashPosition pos;
                    518:                        zend_property_info *prop;
                    519: 
                    520:                        zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
                    521: 
                    522:                        while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
                    523:                                if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
                    524:                                        _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
                    525:                                }
                    526:                                zend_hash_move_forward_ex(&ce->properties_info, &pos);
                    527:                        }
                    528:                }
                    529:                string_printf(str, "%s  }\n", indent);
                    530:        }
                    531: 
                    532:        if (obj && Z_OBJ_HT_P(obj)->get_properties) {
                    533:                string       dyn;
                    534:                HashTable    *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
                    535:                HashPosition pos;
                    536:                zval         **prop;
                    537: 
                    538:                string_init(&dyn);
                    539:                count = 0;
                    540: 
                    541:                if (properties && zend_hash_num_elements(properties)) {
                    542:                        zend_hash_internal_pointer_reset_ex(properties, &pos);
                    543: 
                    544:                        while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
                    545:                                char  *prop_name;
                    546:                                uint  prop_name_size;
                    547:                                ulong index;
                    548: 
                    549:                                if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
                    550:                                        if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
                    551:                                                if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
                    552:                                                        count++;
                    553:                                                        _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);   
                    554:                                                }
                    555:                                        }
                    556:                                        efree(prop_name);
                    557:                                }
                    558:                                zend_hash_move_forward_ex(properties, &pos);
                    559:                        }
                    560:                }
                    561: 
                    562:                string_printf(str, "\n%s  - Dynamic properties [%d] {\n", indent, count);
                    563:                string_append(str, &dyn);
                    564:                string_printf(str, "%s  }\n", indent);
                    565:                string_free(&dyn);
                    566:        }
                    567: 
                    568:        /* Non static methods */
                    569:        if (&ce->function_table) {
                    570:                count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
                    571:                if (count > 0) {
                    572:                        HashPosition pos;
                    573:                        zend_function *mptr;
                    574:                        string dyn;
                    575: 
                    576:                        count = 0;
                    577:                        string_init(&dyn);
                    578:                        zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
                    579: 
                    580:                        while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
                    581:                                if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
                    582:                                        && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
                    583:                                {
                    584:                                        char *key;
                    585:                                        uint key_len;
                    586:                                        ulong num_index;
                    587:                                        uint len = strlen(mptr->common.function_name);
                    588: 
                    589:                                        /* Do not display old-style inherited constructors */
                    590:                                        if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
                    591:                                                || mptr->common.scope == ce
                    592:                                                || zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING
                    593:                                                || zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0)
                    594:                                        {
                    595:                                                zend_function *closure;
                    596:                                                /* see if this is a closure */
                    597:                                                if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                    598:                                                        && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                    599:                                                        && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
                    600:                                                {
                    601:                                                        mptr = closure;
                    602:                                                } else {
                    603:                                                        closure = NULL;
                    604:                                                }
                    605:                                                string_printf(&dyn, "\n");
                    606:                                                _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
                    607:                                                count++;
                    608:                                                _free_function(closure TSRMLS_CC);
                    609:                                        }
                    610:                                }
                    611:                                zend_hash_move_forward_ex(&ce->function_table, &pos);
                    612:                        }
                    613:                        string_printf(str, "\n%s  - Methods [%d] {", indent, count);
                    614:                        if (!count) {
                    615:                                string_printf(str, "\n");
                    616:                        }
                    617:                        string_append(str, &dyn);
                    618:                        string_free(&dyn);
                    619:                } else {
                    620:                        string_printf(str, "\n%s  - Methods [0] {\n", indent);
                    621:                }
                    622:                string_printf(str, "%s  }\n", indent);
                    623:        }
                    624:        
                    625:        string_printf(str, "%s}\n", indent);
                    626:        string_free(&sub_indent);
                    627: }
                    628: /* }}} */
                    629: 
                    630: /* {{{ _const_string */
                    631: static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC)
                    632: {
                    633:        char *type;
                    634:        zval value_copy;
                    635:        int use_copy;
                    636: 
                    637:        type = zend_zval_type_name(value);
                    638: 
                    639:        zend_make_printable_zval(value, &value_copy, &use_copy);
                    640:        if (use_copy) {
                    641:                value = &value_copy;
                    642:        }
                    643: 
                    644:        string_printf(str, "%s    Constant [ %s %s ] { %s }\n",
                    645:                                        indent, type, name, Z_STRVAL_P(value));
                    646: 
                    647:        if (use_copy) {
                    648:                zval_dtor(value);
                    649:        }
                    650: }
                    651: /* }}} */
                    652: 
                    653: /* {{{ _get_recv_opcode */
                    654: static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset)
                    655: {
                    656:        zend_op *op = op_array->opcodes;
                    657:        zend_op *end = op + op_array->last;
                    658: 
                    659:        ++offset;
                    660:        while (op < end) {
                    661:                if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
                    662:                        && op->op1.u.constant.value.lval == (long)offset)
                    663:                {
                    664:                        return op;
                    665:                }
                    666:                ++op;
                    667:        }
                    668:        return NULL;
                    669: }
                    670: /* }}} */
                    671: 
                    672: /* {{{ _parameter_string */
                    673: static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, char* indent TSRMLS_DC)
                    674: {
                    675:        string_printf(str, "Parameter #%d [ ", offset);
                    676:        if (offset >= required) {
                    677:                string_printf(str, "<optional> ");
                    678:        } else {
                    679:                string_printf(str, "<required> ");
                    680:        }
                    681:        if (arg_info->class_name) {
                    682:                string_printf(str, "%s ", arg_info->class_name);
                    683:                if (arg_info->allow_null) {
                    684:                        string_printf(str, "or NULL ");
                    685:                }
                    686:        } else if (arg_info->array_type_hint) {
                    687:                string_printf(str, "array ");
                    688:                if (arg_info->allow_null) {
                    689:                        string_printf(str, "or NULL ");
                    690:                }
                    691:        }
                    692:        if (arg_info->pass_by_reference) {
                    693:                string_write(str, "&", sizeof("&")-1);
                    694:        }
                    695:        if (arg_info->name) {
                    696:                string_printf(str, "$%s", arg_info->name);
                    697:        } else {
                    698:                string_printf(str, "$param%d", offset);
                    699:        }
                    700:        if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
                    701:                zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
                    702:                if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) {
                    703:                        zval *zv, zv_copy;
                    704:                        int use_copy;
                    705:                        string_write(str, " = ", sizeof(" = ")-1);
                    706:                        ALLOC_ZVAL(zv);
                    707:                        *zv = precv->op2.u.constant;
                    708:                        zval_copy_ctor(zv);
                    709:                        INIT_PZVAL(zv);
                    710:                        zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC);
                    711:                        if (Z_TYPE_P(zv) == IS_BOOL) {
                    712:                                if (Z_LVAL_P(zv)) {
                    713:                                        string_write(str, "true", sizeof("true")-1);
                    714:                                } else {
                    715:                                        string_write(str, "false", sizeof("false")-1);
                    716:                                }
                    717:                        } else if (Z_TYPE_P(zv) == IS_NULL) {
                    718:                                string_write(str, "NULL", sizeof("NULL")-1);
                    719:                        } else if (Z_TYPE_P(zv) == IS_STRING) {
                    720:                                string_write(str, "'", sizeof("'")-1);
                    721:                                string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15));
                    722:                                if (Z_STRLEN_P(zv) > 15) {
                    723:                                        string_write(str, "...", sizeof("...")-1);
                    724:                                }
                    725:                                string_write(str, "'", sizeof("'")-1);
                    726:                        } else {
                    727:                                zend_make_printable_zval(zv, &zv_copy, &use_copy);
                    728:                                string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
                    729:                                if (use_copy) {
                    730:                                        zval_dtor(&zv_copy);
                    731:                                }
                    732:                        }
                    733:                        zval_ptr_dtor(&zv);
                    734:                }
                    735:        }
                    736:        string_write(str, " ]", sizeof(" ]")-1);
                    737: }
                    738: /* }}} */
                    739: 
                    740: /* {{{ _function_parameter_string */
                    741: static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
                    742: {
                    743:        struct _zend_arg_info *arg_info = fptr->common.arg_info;
                    744:        zend_uint i, required = fptr->common.required_num_args;
                    745: 
                    746:        if (!arg_info) {
                    747:                return;
                    748:        }
                    749: 
                    750:        string_printf(str, "\n");
                    751:        string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args);
                    752:        for (i = 0; i < fptr->common.num_args; i++) {
                    753:                string_printf(str, "%s  ", indent);
                    754:                _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC);
                    755:                string_write(str, "\n", sizeof("\n")-1);
                    756:                arg_info++;
                    757:        }
                    758:        string_printf(str, "%s}\n", indent);
                    759: }
                    760: /* }}} */
                    761: 
                    762: /* {{{ _function_closure_string */
                    763: static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
                    764: {
                    765:        zend_uint i, count;
                    766:        ulong num_index;
                    767:        char *key;
                    768:        uint key_len;
                    769:        HashTable *static_variables;
                    770:        HashPosition pos;
                    771: 
                    772:        if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
                    773:                return;
                    774:        }
                    775: 
                    776:        static_variables = fptr->op_array.static_variables;
                    777:        count = zend_hash_num_elements(static_variables);
                    778: 
                    779:        if (!count) {
                    780:                return;
                    781:        }
                    782: 
                    783:        string_printf(str, "\n");
                    784:        string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
                    785:        zend_hash_internal_pointer_reset_ex(static_variables, &pos);
                    786:        i = 0;
                    787:        while (i < count) {
                    788:                zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
                    789:                string_printf(str, "%s    Variable #%d [ $%s ]\n", indent, i++, key);
                    790:                zend_hash_move_forward_ex(static_variables, &pos);
                    791:        }
                    792:        string_printf(str, "%s}\n", indent);
                    793: }
                    794: /* }}} */
                    795: 
                    796: /* {{{ _function_string */
                    797: static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
                    798: {
                    799:        string param_indent;
                    800:        zend_function *overwrites;
                    801:        char *lc_name;
                    802:        unsigned int lc_name_len;
                    803: 
                    804:        /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
                    805:         * What's "wrong" is that any whitespace before the doc comment start is 
                    806:         * swallowed, leading to an unaligned comment.
                    807:         */
                    808:        if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
                    809:                string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment);
                    810:        }
                    811: 
                    812:        string_write(str, indent, strlen(indent));
                    813:        string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
                    814:        string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
                    815:        if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
                    816:                string_printf(str, ", deprecated");
                    817:        }
                    818:        if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
                    819:                string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
                    820:        }
                    821: 
                    822:        if (scope && fptr->common.scope) {
                    823:                if (fptr->common.scope != scope) {
                    824:                        string_printf(str, ", inherits %s", fptr->common.scope->name);
                    825:                } else if (fptr->common.scope->parent) {
                    826:                        lc_name_len = strlen(fptr->common.function_name);
                    827:                        lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len);
                    828:                        if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) {
                    829:                                if (fptr->common.scope != overwrites->common.scope) {
                    830:                                        string_printf(str, ", overwrites %s", overwrites->common.scope->name);
                    831:                                }
                    832:                        }
                    833:                        efree(lc_name);
                    834:                }
                    835:        }
                    836:        if (fptr->common.prototype && fptr->common.prototype->common.scope) {
                    837:                string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name);
                    838:        }
                    839:        if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
                    840:                string_printf(str, ", ctor");
                    841:        }
                    842:        if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
                    843:                string_printf(str, ", dtor");
                    844:        }
                    845:        string_printf(str, "> ");
                    846: 
                    847:        if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
                    848:                string_printf(str, "abstract ");
                    849:        }
                    850:        if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
                    851:                string_printf(str, "final ");
                    852:        }
                    853:        if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
                    854:                string_printf(str, "static ");
                    855:        }
                    856: 
                    857:        if (fptr->common.scope) {
                    858:                /* These are mutually exclusive */
                    859:                switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
                    860:                        case ZEND_ACC_PUBLIC:
                    861:                                string_printf(str, "public ");
                    862:                                break;
                    863:                        case ZEND_ACC_PRIVATE:
                    864:                                string_printf(str, "private ");
                    865:                                break;
                    866:                        case ZEND_ACC_PROTECTED:
                    867:                                string_printf(str, "protected ");
                    868:                                break;
                    869:                        default:
                    870:                                string_printf(str, "<visibility error> ");
                    871:                                break;
                    872:                }
                    873:                string_printf(str, "method ");
                    874:        } else {
                    875:                string_printf(str, "function ");
                    876:        }
                    877: 
                    878:        if (fptr->op_array.return_reference) {
                    879:                string_printf(str, "&");
                    880:        }
                    881:        string_printf(str, "%s ] {\n", fptr->common.function_name);
                    882:        /* The information where a function is declared is only available for user classes */
                    883:        if (fptr->type == ZEND_USER_FUNCTION) {
                    884:                string_printf(str, "%s  @@ %s %d - %d\n", indent, 
                    885:                                                fptr->op_array.filename,
                    886:                                                fptr->op_array.line_start,
                    887:                                                fptr->op_array.line_end);
                    888:        }
                    889:        string_init(&param_indent);
                    890:        string_printf(&param_indent, "%s  ", indent);
                    891:        if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
                    892:                _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
                    893:        }
                    894:        _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
                    895:        string_free(&param_indent);
                    896:        string_printf(str, "%s}\n", indent);
                    897: }
                    898: /* }}} */
                    899: 
                    900: /* {{{ _property_string */
                    901: static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC)
                    902: {
                    903:        char *class_name;
                    904: 
                    905:        string_printf(str, "%sProperty [ ", indent);
                    906:        if (!prop) {
                    907:                string_printf(str, "<dynamic> public $%s", prop_name);
                    908:        } else {
                    909:                if (!(prop->flags & ZEND_ACC_STATIC)) {
                    910:                        if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
                    911:                                string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
                    912:                        } else {
                    913:                                string_write(str, "<default> ", sizeof("<default> ") - 1);
                    914:                        }
                    915:                }
                    916:        
                    917:                /* These are mutually exclusive */
                    918:                switch (prop->flags & ZEND_ACC_PPP_MASK) {
                    919:                        case ZEND_ACC_PUBLIC:
                    920:                                string_printf(str, "public ");
                    921:                                break;
                    922:                        case ZEND_ACC_PRIVATE:
                    923:                                string_printf(str, "private ");
                    924:                                break;
                    925:                        case ZEND_ACC_PROTECTED:
                    926:                                string_printf(str, "protected ");
                    927:                                break;
                    928:                }
                    929:                if(prop->flags & ZEND_ACC_STATIC) {
                    930:                        string_printf(str, "static ");
                    931:                }
                    932: 
                    933:                zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
                    934:                string_printf(str, "$%s", prop_name);
                    935:        }
                    936: 
                    937:        string_printf(str, " ]\n");
                    938: }
                    939: /* }}} */
                    940: 
                    941: static int _extension_ini_string(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                    942: {
                    943:        string *str = va_arg(args, string *);
                    944:        char *indent = va_arg(args, char *);
                    945:        int number = va_arg(args, int);
                    946:        char *comma = "";
                    947: 
                    948:        if (number == ini_entry->module_number) {
                    949:                string_printf(str, "    %sEntry [ %s <", indent, ini_entry->name);
                    950:                if (ini_entry->modifiable == ZEND_INI_ALL) {
                    951:                        string_printf(str, "ALL");
                    952:                } else {
                    953:                        if (ini_entry->modifiable & ZEND_INI_USER) {
                    954:                                string_printf(str, "USER");
                    955:                                comma = ",";
                    956:                        }
                    957:                        if (ini_entry->modifiable & ZEND_INI_PERDIR) {
                    958:                                string_printf(str, "%sPERDIR", comma);
                    959:                                comma = ",";
                    960:                        }
                    961:                        if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
                    962:                                string_printf(str, "%sSYSTEM", comma);
                    963:                        }
                    964:                }
                    965: 
                    966:                string_printf(str, "> ]\n");
                    967:                string_printf(str, "    %s  Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : "");
                    968:                if (ini_entry->modified) {
                    969:                        string_printf(str, "    %s  Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : "");
                    970:                }
                    971:                string_printf(str, "    %s}\n", indent);
                    972:        }
                    973:        return ZEND_HASH_APPLY_KEEP;
                    974: }
                    975: 
                    976: static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                    977: {
                    978:        string *str = va_arg(args, string *);
                    979:        char *indent = va_arg(args, char *);
                    980:        struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
                    981:        int *num_classes = va_arg(args, int*);
                    982: 
                    983:        if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
                    984:                string_printf(str, "\n");
                    985:                _class_string(str, *pce, NULL, indent TSRMLS_CC);
                    986:                (*num_classes)++;
                    987:        }
                    988:        return ZEND_HASH_APPLY_KEEP;
                    989: }
                    990: 
                    991: static int _extension_const_string(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                    992: {
                    993:        string *str = va_arg(args, string *);
                    994:        char *indent = va_arg(args, char *);
                    995:        struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
                    996:        int *num_classes = va_arg(args, int*);
                    997: 
                    998:        if (constant->module_number  == module->module_number) {
                    999:                _const_string(str, constant->name, &constant->value, indent TSRMLS_CC);
                   1000:                (*num_classes)++;
                   1001:        }
                   1002:        return ZEND_HASH_APPLY_KEEP;
                   1003: }
                   1004: 
                   1005: /* {{{ _extension_string */
                   1006: static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC)
                   1007: {
                   1008:        string_printf(str, "%sExtension [ ", indent);
                   1009:        if (module->type == MODULE_PERSISTENT) {
                   1010:                string_printf(str, "<persistent>");
                   1011:        }
                   1012:        if (module->type == MODULE_TEMPORARY) {
                   1013:                string_printf(str, "<temporary>" );
                   1014:        }
                   1015:        string_printf(str, " extension #%d %s version %s ] {\n",
                   1016:                                        module->module_number, module->name,
                   1017:                                        (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
                   1018: 
                   1019:        if (module->deps) {
                   1020:                const zend_module_dep* dep = module->deps;
                   1021: 
                   1022:                string_printf(str, "\n  - Dependencies {\n");
                   1023: 
                   1024:                while(dep->name) {
                   1025:                        string_printf(str, "%s    Dependency [ %s (", indent, dep->name);
                   1026:                        
                   1027:                        switch(dep->type) {
                   1028:                        case MODULE_DEP_REQUIRED:
                   1029:                                string_write(str, "Required", sizeof("Required") - 1);
                   1030:                                break;
                   1031:                        case MODULE_DEP_CONFLICTS:
                   1032:                                string_write(str, "Conflicts", sizeof("Conflicts") - 1);
                   1033:                                break;
                   1034:                        case MODULE_DEP_OPTIONAL:
                   1035:                                string_write(str, "Optional", sizeof("Optional") - 1);
                   1036:                                break;
                   1037:                        default:
                   1038:                                string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */
                   1039:                                break;
                   1040:                        }
                   1041: 
                   1042:                        if (dep->rel) { 
                   1043:                                string_printf(str, " %s", dep->rel);
                   1044:                        }
                   1045:                        if (dep->version) {     
                   1046:                                string_printf(str, " %s", dep->version);
                   1047:                        }
                   1048:                        string_write(str, ") ]\n", sizeof(") ]\n") - 1);
                   1049:                        dep++;
                   1050:                }
                   1051:                string_printf(str, "%s  }\n", indent);
                   1052:        }
                   1053: 
                   1054:        {
                   1055:                string str_ini;
                   1056:                string_init(&str_ini);
                   1057:                zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
                   1058:                if (str_ini.len > 1) {
                   1059:                        string_printf(str, "\n  - INI {\n");
                   1060:                        string_append(str, &str_ini);
                   1061:                        string_printf(str, "%s  }\n", indent);
                   1062:                }
                   1063:                string_free(&str_ini);
                   1064:        }
                   1065: 
                   1066:        {
                   1067:                string str_constants;
                   1068:                int num_constants = 0;
                   1069:                
                   1070:                string_init(&str_constants);
                   1071:                zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
                   1072:                if (num_constants) {
                   1073:                        string_printf(str, "\n  - Constants [%d] {\n", num_constants);
                   1074:                        string_append(str, &str_constants);
                   1075:                        string_printf(str, "%s  }\n", indent);
                   1076:                }
                   1077:                string_free(&str_constants);
                   1078:        }
                   1079: 
                   1080:        if (module->functions && module->functions->fname) {
                   1081:                zend_function *fptr;
                   1082:                const zend_function_entry *func = module->functions;
                   1083: 
                   1084:                string_printf(str, "\n  - Functions {\n");
                   1085: 
                   1086:                /* Is there a better way of doing this? */
                   1087:                while (func->fname) {
                   1088:                        int fname_len = strlen(func->fname);
                   1089:                        char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
                   1090:                        
                   1091:                        if (zend_hash_find(EG(function_table), lc_name, fname_len+1, (void**) &fptr) == FAILURE) {
                   1092:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
                   1093:                                func++;
                   1094:                                efree(lc_name);
                   1095:                                continue;
                   1096:                        }
                   1097:                        
                   1098:                        _function_string(str, fptr, NULL, "    " TSRMLS_CC);
                   1099:                        efree(lc_name);
                   1100:                        func++;
                   1101:                }
                   1102:                string_printf(str, "%s  }\n", indent);
                   1103:        }
                   1104:        
                   1105:        {
                   1106:                string str_classes;
                   1107:                string sub_indent;
                   1108:                int num_classes = 0;
                   1109:                
                   1110:                string_init(&sub_indent);
                   1111:                string_printf(&sub_indent, "%s    ", indent);
                   1112:                string_init(&str_classes);
                   1113:                zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) _extension_class_string, 4, &str_classes, sub_indent.string, module, &num_classes);
                   1114:                if (num_classes) {
                   1115:                        string_printf(str, "\n  - Classes [%d] {", num_classes);
                   1116:                        string_append(str, &str_classes);
                   1117:                        string_printf(str, "%s  }\n", indent);
                   1118:                }
                   1119:                string_free(&str_classes);
                   1120:                string_free(&sub_indent);
                   1121:        }
                   1122: 
                   1123:        string_printf(str, "%s}\n", indent);
                   1124: }
                   1125: /* }}} */
                   1126: 
                   1127: /* {{{ _function_check_flag */
                   1128: static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
                   1129: {
                   1130:        reflection_object *intern;
                   1131:        zend_function *mptr;
                   1132: 
                   1133:        if (zend_parse_parameters_none() == FAILURE) {
                   1134:                return;
                   1135:        }
                   1136:        GET_REFLECTION_OBJECT_PTR(mptr);
                   1137:        RETURN_BOOL(mptr->common.fn_flags & mask);
                   1138: }
                   1139: /* }}} */
                   1140: 
                   1141: /* {{{ zend_reflection_class_factory */
                   1142: PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC)
                   1143: {
                   1144:        reflection_object *intern;
                   1145:        zval *name;
                   1146: 
                   1147:        MAKE_STD_ZVAL(name);
                   1148:        ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
                   1149:        reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
                   1150:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1151:        intern->ptr = ce;
                   1152:        intern->ref_type = REF_TYPE_OTHER;
                   1153:        intern->ce = ce;
                   1154:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1155: }
                   1156: /* }}} */
                   1157: 
                   1158: /* {{{ reflection_extension_factory */
                   1159: static void reflection_extension_factory(zval *object, const char *name_str TSRMLS_DC)
                   1160: {
                   1161:        reflection_object *intern;
                   1162:        zval *name;
                   1163:        int name_len = strlen(name_str);
                   1164:        char *lcname;
                   1165:        struct _zend_module_entry *module;
                   1166:        ALLOCA_FLAG(use_heap)
                   1167: 
                   1168:        lcname = do_alloca(name_len + 1, use_heap);
                   1169:        zend_str_tolower_copy(lcname, name_str, name_len);
                   1170:        if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
                   1171:                free_alloca(lcname, use_heap);
                   1172:                return;
                   1173:        }
                   1174:        free_alloca(lcname, use_heap);
                   1175: 
                   1176:        reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
                   1177:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1178:        MAKE_STD_ZVAL(name);
                   1179:        ZVAL_STRINGL(name, module->name, name_len, 1);
                   1180:        intern->ptr = module;
                   1181:        intern->ref_type = REF_TYPE_OTHER;
                   1182:        intern->ce = NULL;
                   1183:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1184: }
                   1185: /* }}} */
                   1186: 
                   1187: /* {{{ reflection_parameter_factory */
                   1188: static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
                   1189: {
                   1190:        reflection_object *intern;
                   1191:        parameter_reference *reference;
                   1192:        zval *name;
                   1193: 
                   1194:        if (closure_object) {
                   1195:                Z_ADDREF_P(closure_object);
                   1196:        }
                   1197:        MAKE_STD_ZVAL(name);
                   1198:        if (arg_info->name) {
                   1199:                ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
                   1200:        } else {
                   1201:                ZVAL_NULL(name);
                   1202:        }
                   1203:        reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
                   1204:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1205:        reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
                   1206:        reference->arg_info = arg_info;
                   1207:        reference->offset = offset;
                   1208:        reference->required = required;
                   1209:        reference->fptr = fptr;
                   1210:        intern->ptr = reference;
                   1211:        intern->ref_type = REF_TYPE_PARAMETER;
                   1212:        intern->ce = fptr->common.scope;
                   1213:        intern->obj = closure_object;
                   1214:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1215: }
                   1216: /* }}} */
                   1217: 
                   1218: /* {{{ reflection_function_factory */
                   1219: static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
                   1220: {
                   1221:        reflection_object *intern;
                   1222:        zval *name;
                   1223: 
                   1224:        if (closure_object) {
                   1225:                Z_ADDREF_P(closure_object);
                   1226:        }
                   1227:        MAKE_STD_ZVAL(name);
                   1228:        ZVAL_STRING(name, function->common.function_name, 1);
                   1229: 
                   1230:        reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
                   1231:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1232:        intern->ptr = function;
                   1233:        intern->ref_type = REF_TYPE_FUNCTION;
                   1234:        intern->ce = NULL;
                   1235:        intern->obj = closure_object;
                   1236:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1237: }
                   1238: /* }}} */
                   1239: 
                   1240: /* {{{ reflection_method_factory */
                   1241: static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
                   1242: {
                   1243:        reflection_object *intern;
                   1244:        zval *name;
                   1245:        zval *classname;
                   1246: 
                   1247:        if (closure_object) {
                   1248:                Z_ADDREF_P(closure_object);
                   1249:        }
                   1250:        MAKE_STD_ZVAL(name);
                   1251:        MAKE_STD_ZVAL(classname);
                   1252:        ZVAL_STRING(name, method->common.function_name, 1);
                   1253:        ZVAL_STRINGL(classname, method->common.scope->name, method->common.scope->name_length, 1);
                   1254:        reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
                   1255:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1256:        intern->ptr = method;
                   1257:        intern->ref_type = REF_TYPE_FUNCTION;
                   1258:        intern->ce = ce;
                   1259:        intern->obj = closure_object;
                   1260:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1261:        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
                   1262: }
                   1263: /* }}} */
                   1264: 
                   1265: /* {{{ reflection_property_factory */
                   1266: static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC)
                   1267: {
                   1268:        reflection_object *intern;
                   1269:        zval *name;
                   1270:        zval *classname;
                   1271:        property_reference *reference;
                   1272:        char *class_name, *prop_name;
                   1273: 
                   1274:        zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
                   1275: 
                   1276:        if (!(prop->flags & ZEND_ACC_PRIVATE)) {
                   1277:                /* we have to search the class hierarchy for this (implicit) public or protected property */
                   1278:                zend_class_entry *tmp_ce = ce, *store_ce = ce;
                   1279:                zend_property_info *tmp_info = NULL;
                   1280: 
                   1281:                while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
                   1282:                        ce = tmp_ce;
                   1283:                        tmp_ce = tmp_ce->parent;
                   1284:                }
                   1285: 
                   1286:                if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
                   1287:                        prop = tmp_info;
                   1288:                } else { /* not found, use initial value */
                   1289:                        ce = store_ce;
                   1290:                }
                   1291:        }
                   1292: 
                   1293:        MAKE_STD_ZVAL(name);
                   1294:        MAKE_STD_ZVAL(classname);
                   1295:        ZVAL_STRING(name, prop_name, 1);
                   1296:        ZVAL_STRINGL(classname, prop->ce->name, prop->ce->name_length, 1);
                   1297: 
                   1298:        reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
                   1299:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1300:        reference = (property_reference*) emalloc(sizeof(property_reference));
                   1301:        reference->ce = ce;
                   1302:        reference->prop = *prop;
                   1303:        intern->ptr = reference;
                   1304:        intern->ref_type = REF_TYPE_PROPERTY;
                   1305:        intern->ce = ce;
                   1306:        intern->ignore_visibility = 0;
                   1307:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1308:        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
                   1309: }
                   1310: /* }}} */
                   1311: 
                   1312: /* {{{ _reflection_export */
                   1313: static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
                   1314: {
                   1315:        zval *reflector_ptr;
                   1316:        zval output, *output_ptr = &output;
                   1317:        zval *argument_ptr, *argument2_ptr;
                   1318:        zval *retval_ptr, **params[2];
                   1319:        int result;
                   1320:        int return_output = 0;
                   1321:        zend_fcall_info fci;
                   1322:        zend_fcall_info_cache fcc;
                   1323:        zval fname;
                   1324: 
                   1325:        if (ctor_argc == 1) {
                   1326:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) {
                   1327:                        return;
                   1328:                }
                   1329:        } else {
                   1330:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
                   1331:                        return;
                   1332:                }
                   1333:        }
                   1334: 
                   1335:        INIT_PZVAL(&output);
                   1336: 
                   1337:        /* Create object */
                   1338:        MAKE_STD_ZVAL(reflector_ptr);
                   1339:        if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) {
                   1340:                _DO_THROW("Could not create reflector");
                   1341:        }
                   1342: 
                   1343:        /* Call __construct() */
                   1344:        params[0] = &argument_ptr;
                   1345:        params[1] = &argument2_ptr;
                   1346: 
                   1347:        fci.size = sizeof(fci);
                   1348:        fci.function_table = NULL;
                   1349:        fci.function_name = NULL;
                   1350:        fci.symbol_table = NULL;
                   1351:        fci.object_ptr = reflector_ptr;
                   1352:        fci.retval_ptr_ptr = &retval_ptr;
                   1353:        fci.param_count = ctor_argc;
                   1354:        fci.params = params;
                   1355:        fci.no_separation = 1;
                   1356: 
                   1357:        fcc.initialized = 1;
                   1358:        fcc.function_handler = ce_ptr->constructor;
                   1359:        fcc.calling_scope = ce_ptr;
                   1360:        fcc.called_scope = Z_OBJCE_P(reflector_ptr);
                   1361:        fcc.object_ptr = reflector_ptr;
                   1362: 
                   1363:        result = zend_call_function(&fci, &fcc TSRMLS_CC);
                   1364:        
                   1365:        if (retval_ptr) {
                   1366:                zval_ptr_dtor(&retval_ptr);
                   1367:        }
                   1368: 
                   1369:        if (EG(exception)) {
                   1370:                zval_ptr_dtor(&reflector_ptr);
                   1371:                return;
                   1372:        }
                   1373:        if (result == FAILURE) {
                   1374:                zval_ptr_dtor(&reflector_ptr);
                   1375:                _DO_THROW("Could not create reflector");
                   1376:        }
                   1377: 
                   1378:        /* Call static reflection::export */
                   1379:        ZVAL_BOOL(&output, return_output);
                   1380:        params[0] = &reflector_ptr;
                   1381:        params[1] = &output_ptr;
                   1382: 
                   1383:        ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0);
                   1384:        fci.function_table = &reflection_ptr->function_table;
                   1385:        fci.function_name = &fname;
                   1386:        fci.object_ptr = NULL;
                   1387:        fci.retval_ptr_ptr = &retval_ptr;
                   1388:        fci.param_count = 2;
                   1389:        fci.params = params;
                   1390:        fci.no_separation = 1;
                   1391: 
                   1392:        result = zend_call_function(&fci, NULL TSRMLS_CC);
                   1393: 
                   1394:        if (result == FAILURE && EG(exception) == NULL) {
                   1395:                zval_ptr_dtor(&reflector_ptr);
                   1396:                zval_ptr_dtor(&retval_ptr);
                   1397:                _DO_THROW("Could not execute reflection::export()");
                   1398:        }
                   1399: 
                   1400:        if (return_output) {
                   1401:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   1402:        } else {
                   1403:                zval_ptr_dtor(&retval_ptr);
                   1404:        }
                   1405: 
                   1406:        /* Destruct reflector which is no longer needed */
                   1407:        zval_ptr_dtor(&reflector_ptr);
                   1408: }
                   1409: /* }}} */
                   1410: 
                   1411: /* {{{ Preventing __clone from being called */
                   1412: ZEND_METHOD(reflection, __clone)
                   1413: {
                   1414:        /* Should never be executable */
                   1415:        _DO_THROW("Cannot clone object using __clone()");
                   1416: }
                   1417: /* }}} */
                   1418: 
                   1419: /* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
                   1420:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   1421: ZEND_METHOD(reflection, export)
                   1422: {
                   1423:        zval *object, fname, *retval_ptr;
                   1424:        int result;
                   1425:        zend_bool return_output = 0;
                   1426: 
                   1427:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
                   1428:                return;
                   1429:        }
                   1430: 
                   1431:        /* Invoke the __toString() method */
                   1432:        ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
                   1433:        result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
                   1434:        zval_dtor(&fname);
                   1435: 
                   1436:        if (result == FAILURE) {
                   1437:                _DO_THROW("Invocation of method __toString() failed");
                   1438:                /* Returns from this function */
                   1439:        }
                   1440: 
                   1441:        if (!retval_ptr) {
                   1442:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
                   1443:                RETURN_FALSE;
                   1444:        }
                   1445: 
                   1446:        if (return_output) {
                   1447:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   1448:        } else {
                   1449:                /* No need for _r variant, return of __toString should always be a string */
                   1450:                zend_print_zval(retval_ptr, 0);
                   1451:                zend_printf("\n");
                   1452:                zval_ptr_dtor(&retval_ptr);
                   1453:        }
                   1454: }
                   1455: /* }}} */
                   1456: 
                   1457: /* {{{ proto public static array Reflection::getModifierNames(int modifiers)
                   1458:    Returns an array of modifier names */
                   1459: ZEND_METHOD(reflection, getModifierNames)
                   1460: {
                   1461:        long modifiers;
                   1462: 
                   1463:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) {
                   1464:                return;
                   1465:        }
                   1466: 
                   1467:        array_init(return_value);
                   1468: 
                   1469:        if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
                   1470:                add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1);
                   1471:        }
                   1472:        if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) {
                   1473:                add_next_index_stringl(return_value, "final", sizeof("final")-1, 1);
                   1474:        }
                   1475:        if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
                   1476:                add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
                   1477:        }
                   1478: 
                   1479:        /* These are mutually exclusive */
                   1480:        switch (modifiers & ZEND_ACC_PPP_MASK) {
                   1481:                case ZEND_ACC_PUBLIC:
                   1482:                        add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
                   1483:                        break;
                   1484:                case ZEND_ACC_PRIVATE:
                   1485:                        add_next_index_stringl(return_value, "private", sizeof("private")-1, 1);
                   1486:                        break;
                   1487:                case ZEND_ACC_PROTECTED:
                   1488:                        add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1);
                   1489:                        break;
                   1490:        }
                   1491: 
                   1492:        if (modifiers & ZEND_ACC_STATIC) {
                   1493:                add_next_index_stringl(return_value, "static", sizeof("static")-1, 1);
                   1494:        }
                   1495: }
                   1496: /* }}} */
                   1497: 
                   1498: /* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
                   1499:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   1500: ZEND_METHOD(reflection_function, export)
                   1501: {
                   1502:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
                   1503: }
                   1504: /* }}} */
                   1505: 
                   1506: /* {{{ proto public void ReflectionFunction::__construct(string name)
                   1507:    Constructor. Throws an Exception in case the given function does not exist */
                   1508: ZEND_METHOD(reflection_function, __construct)
                   1509: {
                   1510:        zval *name;
                   1511:        zval *object;
                   1512:        zval *closure = NULL;
                   1513:        char *lcname;
                   1514:        reflection_object *intern;
                   1515:        zend_function *fptr;
                   1516:        char *name_str;
                   1517:        int name_len;
                   1518: 
                   1519:        object = getThis();
                   1520:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   1521:        if (intern == NULL) {
                   1522:                return;
                   1523:        }
                   1524: 
                   1525:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &closure, zend_ce_closure) == SUCCESS) {
                   1526:                fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC);
                   1527:                Z_ADDREF_P(closure);
                   1528:        } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) {
                   1529:                char *nsname;
                   1530: 
                   1531:                lcname = zend_str_tolower_dup(name_str, name_len);
                   1532: 
                   1533:                /* Ignore leading "\" */
                   1534:                nsname = lcname;
                   1535:                if (lcname[0] == '\\') {
                   1536:                        nsname = &lcname[1];
                   1537:                        name_len--;
                   1538:                }
                   1539:                
                   1540:                if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) {
                   1541:                        efree(lcname);
                   1542:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   1543:                                "Function %s() does not exist", name_str);
                   1544:                        return;
                   1545:                }
                   1546:                efree(lcname);
                   1547:        } else {
                   1548:                return;
                   1549:        }
                   1550: 
                   1551:        MAKE_STD_ZVAL(name);
                   1552:        ZVAL_STRING(name, fptr->common.function_name, 1);
                   1553:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   1554:        intern->ptr = fptr;
                   1555:        intern->ref_type = REF_TYPE_FUNCTION;
                   1556:        intern->obj = closure;
                   1557:        intern->ce = NULL;
                   1558: }
                   1559: /* }}} */
                   1560: 
                   1561: /* {{{ proto public string ReflectionFunction::__toString()
                   1562:    Returns a string representation */
                   1563: ZEND_METHOD(reflection_function, __toString)
                   1564: {
                   1565:        reflection_object *intern;
                   1566:        zend_function *fptr;
                   1567:        string str;
                   1568: 
                   1569:        if (zend_parse_parameters_none() == FAILURE) {
                   1570:                return;
                   1571:        }
                   1572:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1573:        string_init(&str);
                   1574:        _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
                   1575:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   1576: }
                   1577: /* }}} */
                   1578: 
                   1579: /* {{{ proto public string ReflectionFunction::getName()
                   1580:    Returns this function's name */
                   1581: ZEND_METHOD(reflection_function, getName)
                   1582: {
                   1583:        if (zend_parse_parameters_none() == FAILURE) {
                   1584:                return;
                   1585:        }
                   1586:        _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
                   1587: }
                   1588: /* }}} */
                   1589: 
                   1590: /* {{{ proto public bool ReflectionFunction::isClosure()
                   1591:    Returns whether this is a closure */
                   1592: ZEND_METHOD(reflection_function, isClosure)
                   1593: {
                   1594:        reflection_object *intern;
                   1595:        zend_function *fptr;
                   1596: 
                   1597:        if (zend_parse_parameters_none() == FAILURE) {
                   1598:                return;
                   1599:        }
                   1600:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1601:        RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
                   1602: }
                   1603: /* }}} */
                   1604: 
                   1605: /* {{{ proto public bool ReflectionFunction::isInternal()
                   1606:    Returns whether this is an internal function */
                   1607: ZEND_METHOD(reflection_function, isInternal)
                   1608: {
                   1609:        reflection_object *intern;
                   1610:        zend_function *fptr;
                   1611: 
                   1612:        if (zend_parse_parameters_none() == FAILURE) {
                   1613:                return;
                   1614:        }
                   1615:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1616:        RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
                   1617: }
                   1618: /* }}} */
                   1619: 
                   1620: /* {{{ proto public bool ReflectionFunction::isUserDefined()
                   1621:    Returns whether this is an user-defined function */
                   1622: ZEND_METHOD(reflection_function, isUserDefined)
                   1623: {
                   1624:        reflection_object *intern;
                   1625:        zend_function *fptr;
                   1626: 
                   1627:        if (zend_parse_parameters_none() == FAILURE) {
                   1628:                return;
                   1629:        }
                   1630:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1631:        RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
                   1632: }
                   1633: /* }}} */
                   1634: 
                   1635: /* {{{ proto public bool ReflectionFunction::isDisabled()
                   1636:    Returns whether this function has been disabled or not */
                   1637: ZEND_METHOD(reflection_function, isDisabled)
                   1638: {
                   1639:        reflection_object *intern;
                   1640:        zend_function *fptr;
                   1641: 
                   1642:        METHOD_NOTSTATIC(reflection_function_ptr);
                   1643:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1644:        RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
                   1645: }
                   1646: /* }}} */
                   1647: 
                   1648: /* {{{ proto public string ReflectionFunction::getFileName()
                   1649:    Returns the filename of the file this function was declared in */
                   1650: ZEND_METHOD(reflection_function, getFileName)
                   1651: {
                   1652:        reflection_object *intern;
                   1653:        zend_function *fptr;
                   1654: 
                   1655:        if (zend_parse_parameters_none() == FAILURE) {
                   1656:                return;
                   1657:        }
                   1658:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1659:        if (fptr->type == ZEND_USER_FUNCTION) {
                   1660:                RETURN_STRING(fptr->op_array.filename, 1);
                   1661:        }
                   1662:        RETURN_FALSE;
                   1663: }
                   1664: /* }}} */
                   1665: 
                   1666: /* {{{ proto public int ReflectionFunction::getStartLine()
                   1667:    Returns the line this function's declaration starts at */
                   1668: ZEND_METHOD(reflection_function, getStartLine)
                   1669: {
                   1670:        reflection_object *intern;
                   1671:        zend_function *fptr;
                   1672: 
                   1673:        if (zend_parse_parameters_none() == FAILURE) {
                   1674:                return;
                   1675:        }
                   1676:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1677:        if (fptr->type == ZEND_USER_FUNCTION) {
                   1678:                RETURN_LONG(fptr->op_array.line_start);
                   1679:        }
                   1680:        RETURN_FALSE;
                   1681: }
                   1682: /* }}} */
                   1683: 
                   1684: /* {{{ proto public int ReflectionFunction::getEndLine()
                   1685:    Returns the line this function's declaration ends at */
                   1686: ZEND_METHOD(reflection_function, getEndLine)
                   1687: {
                   1688:        reflection_object *intern;
                   1689:        zend_function *fptr;
                   1690: 
                   1691:        if (zend_parse_parameters_none() == FAILURE) {
                   1692:                return;
                   1693:        }
                   1694:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1695:        if (fptr->type == ZEND_USER_FUNCTION) {
                   1696:                RETURN_LONG(fptr->op_array.line_end);
                   1697:        }
                   1698:        RETURN_FALSE;
                   1699: }
                   1700: /* }}} */
                   1701: 
                   1702: /* {{{ proto public string ReflectionFunction::getDocComment()
                   1703:    Returns the doc comment for this function */
                   1704: ZEND_METHOD(reflection_function, getDocComment)
                   1705: {
                   1706:        reflection_object *intern;
                   1707:        zend_function *fptr;
                   1708: 
                   1709:        if (zend_parse_parameters_none() == FAILURE) {
                   1710:                return;
                   1711:        }
                   1712:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1713:        if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
                   1714:                RETURN_STRINGL(fptr->op_array.doc_comment, fptr->op_array.doc_comment_len, 1);
                   1715:        }
                   1716:        RETURN_FALSE;
                   1717: }
                   1718: /* }}} */
                   1719: 
                   1720: /* {{{ proto public array ReflectionFunction::getStaticVariables()
                   1721:    Returns an associative array containing this function's static variables and their values */
                   1722: ZEND_METHOD(reflection_function, getStaticVariables)
                   1723: {
                   1724:        zval *tmp_copy;
                   1725:        reflection_object *intern;
                   1726:        zend_function *fptr;
                   1727:        
                   1728:        if (zend_parse_parameters_none() == FAILURE) {
                   1729:                return;
                   1730:        }
                   1731:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1732: 
                   1733:        /* Return an empty array in case no static variables exist */
                   1734:        array_init(return_value);
                   1735:        if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
                   1736:                zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
                   1737:                zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
                   1738:        }
                   1739: }
                   1740: /* }}} */
                   1741: 
                   1742: /* {{{ proto public mixed ReflectionFunction::invoke([mixed* args])
                   1743:    Invokes the function */
                   1744: ZEND_METHOD(reflection_function, invoke)
                   1745: {
                   1746:        zval *retval_ptr;
                   1747:        zval ***params = NULL;
                   1748:        int result, num_args = 0;
                   1749:        zend_fcall_info fci;
                   1750:        zend_fcall_info_cache fcc;
                   1751:        reflection_object *intern;
                   1752:        zend_function *fptr;
                   1753:        
                   1754:        METHOD_NOTSTATIC(reflection_function_ptr);
                   1755:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1756: 
                   1757:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
                   1758:                return;
                   1759:        }
                   1760: 
                   1761:        fci.size = sizeof(fci);
                   1762:        fci.function_table = NULL;
                   1763:        fci.function_name = NULL;
                   1764:        fci.symbol_table = NULL;
                   1765:        fci.object_ptr = NULL;
                   1766:        fci.retval_ptr_ptr = &retval_ptr;
                   1767:        fci.param_count = num_args;
                   1768:        fci.params = params;
                   1769:        fci.no_separation = 1;
                   1770: 
                   1771:        fcc.initialized = 1;
                   1772:        fcc.function_handler = fptr;
                   1773:        fcc.calling_scope = EG(scope);
                   1774:        fcc.called_scope = NULL;
                   1775:        fcc.object_ptr = NULL;
                   1776: 
                   1777:        result = zend_call_function(&fci, &fcc TSRMLS_CC);
                   1778: 
                   1779:        if (num_args) {
                   1780:                efree(params);
                   1781:        }
                   1782: 
                   1783:        if (result == FAILURE) {
                   1784:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   1785:                        "Invocation of function %s() failed", fptr->common.function_name);
                   1786:                return;
                   1787:        }
                   1788: 
                   1789:        if (retval_ptr) {
                   1790:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   1791:        }
                   1792: }
                   1793: /* }}} */
                   1794: 
                   1795: static int _zval_array_to_c_array(zval **arg, zval ****params TSRMLS_DC) /* {{{ */
                   1796: {
                   1797:        *(*params)++ = arg;
                   1798:        return ZEND_HASH_APPLY_KEEP;
                   1799: } /* }}} */
                   1800: 
                   1801: /* {{{ proto public mixed ReflectionFunction::invokeArgs(array args)
                   1802:    Invokes the function and pass its arguments as array. */
                   1803: ZEND_METHOD(reflection_function, invokeArgs)
                   1804: {
                   1805:        zval *retval_ptr;
                   1806:        zval ***params;
                   1807:        int result;
                   1808:        int argc;
                   1809:        zend_fcall_info fci;
                   1810:        zend_fcall_info_cache fcc;
                   1811:        reflection_object *intern;
                   1812:        zend_function *fptr;
                   1813:        zval *param_array;
                   1814:        
                   1815:        METHOD_NOTSTATIC(reflection_function_ptr);
                   1816:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1817: 
                   1818:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &param_array) == FAILURE) {
                   1819:                return;
                   1820:        }
                   1821: 
                   1822:        argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
                   1823:        
                   1824:        params = safe_emalloc(sizeof(zval **), argc, 0);
                   1825:        zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);    
                   1826:        params -= argc;
                   1827: 
                   1828:        fci.size = sizeof(fci);
                   1829:        fci.function_table = NULL;
                   1830:        fci.function_name = NULL;
                   1831:        fci.symbol_table = NULL;
                   1832:        fci.object_ptr = NULL;
                   1833:        fci.retval_ptr_ptr = &retval_ptr;
                   1834:        fci.param_count = argc;
                   1835:        fci.params = params;
                   1836:        fci.no_separation = 1;
                   1837: 
                   1838:        fcc.initialized = 1;
                   1839:        fcc.function_handler = fptr;
                   1840:        fcc.calling_scope = EG(scope);
                   1841:        fcc.called_scope = NULL;
                   1842:        fcc.object_ptr = NULL;
                   1843: 
                   1844:        result = zend_call_function(&fci, &fcc TSRMLS_CC);
                   1845: 
                   1846:        efree(params);
                   1847: 
                   1848:        if (result == FAILURE) {
                   1849:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   1850:                        "Invocation of function %s() failed", fptr->common.function_name);
                   1851:                return;
                   1852:        }
                   1853: 
                   1854:        if (retval_ptr) {
                   1855:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   1856:        }
                   1857: }
                   1858: /* }}} */
                   1859: 
                   1860: /* {{{ proto public bool ReflectionFunction::returnsReference()
                   1861:    Gets whether this function returns a reference */
                   1862: ZEND_METHOD(reflection_function, returnsReference)
                   1863: {
                   1864:        reflection_object *intern;
                   1865:        zend_function *fptr;
                   1866: 
                   1867:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1868:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1869: 
                   1870:        RETURN_BOOL(fptr->op_array.return_reference);
                   1871: }
                   1872: /* }}} */
                   1873: 
                   1874: /* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
                   1875:    Gets the number of required parameters */
                   1876: ZEND_METHOD(reflection_function, getNumberOfParameters)
                   1877: {
                   1878:        reflection_object *intern;
                   1879:        zend_function *fptr;
                   1880: 
                   1881:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1882:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1883: 
                   1884:        RETURN_LONG(fptr->common.num_args);
                   1885: }
                   1886: /* }}} */
                   1887: 
                   1888: /* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters()
                   1889:    Gets the number of required parameters */
                   1890: ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
                   1891: {
                   1892:        reflection_object *intern;
                   1893:        zend_function *fptr;
                   1894: 
                   1895:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1896:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1897: 
                   1898:        RETURN_LONG(fptr->common.required_num_args);
                   1899: }
                   1900: /* }}} */
                   1901: 
                   1902: /* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
                   1903:    Returns an array of parameter objects for this function */
                   1904: ZEND_METHOD(reflection_function, getParameters)
                   1905: {
                   1906:        reflection_object *intern;
                   1907:        zend_function *fptr;
                   1908:        zend_uint i;
                   1909:        struct _zend_arg_info *arg_info;
                   1910: 
                   1911:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1912:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1913: 
                   1914:        arg_info= fptr->common.arg_info;
                   1915: 
                   1916:        array_init(return_value);
                   1917:        for (i = 0; i < fptr->common.num_args; i++) {
                   1918:                zval *parameter;   
                   1919: 
                   1920:                ALLOC_ZVAL(parameter);
                   1921:                reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
                   1922:                add_next_index_zval(return_value, parameter);
                   1923: 
                   1924:                arg_info++;
                   1925:        }
                   1926: }
                   1927: /* }}} */
                   1928: 
                   1929: /* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
                   1930:    Returns NULL or the extension the function belongs to */
                   1931: ZEND_METHOD(reflection_function, getExtension)
                   1932: {
                   1933:        reflection_object *intern;
                   1934:        zend_function *fptr;
                   1935:        zend_internal_function *internal;
                   1936: 
                   1937:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1938:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1939: 
                   1940:        if (fptr->type != ZEND_INTERNAL_FUNCTION) {
                   1941:                RETURN_NULL();
                   1942:        }
                   1943: 
                   1944:        internal = (zend_internal_function *)fptr;
                   1945:        if (internal->module) {
                   1946:                reflection_extension_factory(return_value, internal->module->name TSRMLS_CC);
                   1947:        } else {
                   1948:                RETURN_NULL();
                   1949:        }
                   1950: }
                   1951: /* }}} */
                   1952: 
                   1953: /* {{{ proto public string|false ReflectionFunction::getExtensionName()
                   1954:    Returns false or the name of the extension the function belongs to */
                   1955: ZEND_METHOD(reflection_function, getExtensionName)
                   1956: {
                   1957:        reflection_object *intern;
                   1958:        zend_function *fptr;
                   1959:        zend_internal_function *internal;
                   1960: 
                   1961:        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
                   1962:        GET_REFLECTION_OBJECT_PTR(fptr);
                   1963: 
                   1964:        if (fptr->type != ZEND_INTERNAL_FUNCTION) {
                   1965:                RETURN_FALSE;
                   1966:        }
                   1967: 
                   1968:        internal = (zend_internal_function *)fptr;
                   1969:        if (internal->module) {
                   1970:                RETURN_STRING(internal->module->name, 1);
                   1971:        } else {
                   1972:                RETURN_FALSE;
                   1973:        }
                   1974: }
                   1975: /* }}} */
                   1976: 
                   1977: /* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
                   1978:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   1979: ZEND_METHOD(reflection_parameter, export)
                   1980: {
                   1981:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
                   1982: }
                   1983: /* }}} */
                   1984: 
                   1985: /* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter)
                   1986:    Constructor. Throws an Exception in case the given method does not exist */
                   1987: ZEND_METHOD(reflection_parameter, __construct)
                   1988: {
                   1989:        parameter_reference *ref;
                   1990:        zval *reference, **parameter;
                   1991:        zval *object;
                   1992:        zval *name;
                   1993:        reflection_object *intern;
                   1994:        zend_function *fptr;
                   1995:        struct _zend_arg_info *arg_info;
                   1996:        int position;
                   1997:        zend_class_entry *ce = NULL;
                   1998:        zend_bool is_closure = 0;
                   1999: 
                   2000:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, &parameter) == FAILURE) {
                   2001:                return;
                   2002:        }
                   2003: 
                   2004:        object = getThis();
                   2005:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   2006:        if (intern == NULL) {
                   2007:                return;
                   2008:        }
                   2009:        
                   2010:        /* First, find the function */
                   2011:        switch (Z_TYPE_P(reference)) {
                   2012:                case IS_STRING: {
                   2013:                                unsigned int lcname_len;
                   2014:                                char *lcname;
                   2015: 
                   2016:                                lcname_len = Z_STRLEN_P(reference);
                   2017:                                lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
                   2018:                                if (zend_hash_find(EG(function_table), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
                   2019:                                        efree(lcname);
                   2020:                                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2021:                                                "Function %s() does not exist", Z_STRVAL_P(reference));
                   2022:                                        return;
                   2023:                                }
                   2024:                                efree(lcname);
                   2025:                        }
                   2026:                        ce = fptr->common.scope;
                   2027:                        break;
                   2028: 
                   2029:                case IS_ARRAY: {
                   2030:                                zval **classref;
                   2031:                                zval **method;
                   2032:                                zend_class_entry **pce;
                   2033:                                unsigned int lcname_len;
                   2034:                                char *lcname;
                   2035:                                
                   2036:                                if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
                   2037:                                        || (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE))
                   2038:                                {
                   2039:                                        _DO_THROW("Expected array($object, $method) or array($classname, $method)");
                   2040:                                        /* returns out of this function */
                   2041:                                }
                   2042: 
                   2043:                                if (Z_TYPE_PP(classref) == IS_OBJECT) {
                   2044:                                        ce = Z_OBJCE_PP(classref);
                   2045:                                } else {
                   2046:                                        convert_to_string_ex(classref);
                   2047:                                        if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
                   2048:                                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2049:                                                                "Class %s does not exist", Z_STRVAL_PP(classref));
                   2050:                                                return;
                   2051:                                        }
                   2052:                                        ce = *pce;
                   2053:                                }
                   2054:                                
                   2055:                                convert_to_string_ex(method);
                   2056:                                lcname_len = Z_STRLEN_PP(method);
                   2057:                                lcname = zend_str_tolower_dup(Z_STRVAL_PP(method), lcname_len);
                   2058:                                if (ce == zend_ce_closure && Z_TYPE_PP(classref) == IS_OBJECT
                   2059:                                        && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   2060:                                        && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                   2061:                                        && (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL)
                   2062:                                {
                   2063:                                        /* nothign to do. don't set is_closure since is the invoke handler,
                   2064:                                           not the closure itself */
                   2065:                                } else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
                   2066:                                        efree(lcname);
                   2067:                                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2068:                                                "Method %s::%s() does not exist", ce->name, Z_STRVAL_PP(method));
                   2069:                                        return;
                   2070:                                }
                   2071:                                efree(lcname);
                   2072:                        }
                   2073:                        break;
                   2074:                
                   2075:                case IS_OBJECT: {
                   2076:                                ce = Z_OBJCE_P(reference);
                   2077:                                
                   2078:                                if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
                   2079:                                        fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC);
                   2080:                                        Z_ADDREF_P(reference);
                   2081:                                        is_closure = 1;
                   2082:                                } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) {
                   2083:                                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2084:                                                "Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME);
                   2085:                                        return;
                   2086:                                }
                   2087:                        }
                   2088:                        break;
                   2089:                        
                   2090:                default:
                   2091:                        _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object");
                   2092:                        /* returns out of this function */
                   2093:        }
                   2094:        
                   2095:        /* Now, search for the parameter */
                   2096:        arg_info = fptr->common.arg_info;
                   2097:        if (Z_TYPE_PP(parameter) == IS_LONG) {
                   2098:                position= Z_LVAL_PP(parameter);
                   2099:                if (position < 0 || (zend_uint)position >= fptr->common.num_args) {
                   2100:                        if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
                   2101:                                if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
                   2102:                                        efree(fptr->common.function_name);
                   2103:                                }
                   2104:                                efree(fptr);
                   2105:                        }
                   2106:                        if (is_closure) {
                   2107:                                zval_ptr_dtor(&reference);
                   2108:                        }
                   2109:                        _DO_THROW("The parameter specified by its offset could not be found");
                   2110:                        /* returns out of this function */
                   2111:                }
                   2112:        } else {
                   2113:                zend_uint i;
                   2114: 
                   2115:                position= -1;
                   2116:                convert_to_string_ex(parameter);
                   2117:                for (i = 0; i < fptr->common.num_args; i++) {
                   2118:                        if (arg_info[i].name && strcmp(arg_info[i].name, Z_STRVAL_PP(parameter)) == 0) {
                   2119:                                position= i;
                   2120:                                break;
                   2121:                        }
                   2122:                }
                   2123:                if (position == -1) {
                   2124:                        if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
                   2125:                                if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
                   2126:                                        efree(fptr->common.function_name);
                   2127:                                }
                   2128:                                efree(fptr);
                   2129:                        }
                   2130:                        if (is_closure) {
                   2131:                                zval_ptr_dtor(&reference);
                   2132:                        }
                   2133:                        _DO_THROW("The parameter specified by its name could not be found");
                   2134:                        /* returns out of this function */
                   2135:                }
                   2136:        }
                   2137:        
                   2138:        MAKE_STD_ZVAL(name);
                   2139:        if (arg_info[position].name) {
                   2140:                ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
                   2141:        } else {
                   2142:                ZVAL_NULL(name);
                   2143:        }
                   2144:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   2145: 
                   2146:        ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
                   2147:        ref->arg_info = &arg_info[position];
                   2148:        ref->offset = (zend_uint)position;
                   2149:        ref->required = fptr->common.required_num_args;
                   2150:        ref->fptr = fptr;
                   2151:        /* TODO: copy fptr */
                   2152:        intern->ptr = ref;
                   2153:        intern->ref_type = REF_TYPE_PARAMETER;
                   2154:        intern->ce = ce;
                   2155:        if (reference && is_closure) {
                   2156:                intern->obj = reference;
                   2157:        }
                   2158: }
                   2159: /* }}} */
                   2160: 
                   2161: /* {{{ proto public string ReflectionParameter::__toString()
                   2162:    Returns a string representation */
                   2163: ZEND_METHOD(reflection_parameter, __toString)
                   2164: {
                   2165:        reflection_object *intern;
                   2166:        parameter_reference *param;
                   2167:        string str;
                   2168: 
                   2169:        if (zend_parse_parameters_none() == FAILURE) {
                   2170:                return;
                   2171:        }
                   2172:        GET_REFLECTION_OBJECT_PTR(param);
                   2173:        string_init(&str);
                   2174:        _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "" TSRMLS_CC);
                   2175:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   2176: }
                   2177: /* }}} */
                   2178: 
                   2179: /* {{{ proto public string ReflectionParameter::getName()
                   2180:    Returns this parameters's name */
                   2181: ZEND_METHOD(reflection_parameter, getName)
                   2182: {
                   2183:        if (zend_parse_parameters_none() == FAILURE) {
                   2184:                return;
                   2185:        }
                   2186:        _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
                   2187: }
                   2188: /* }}} */
                   2189: 
                   2190: /* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction()
                   2191:    Returns the ReflectionFunction for the function of this parameter */
                   2192: ZEND_METHOD(reflection_parameter, getDeclaringFunction)
                   2193: {
                   2194:        reflection_object *intern;
                   2195:        parameter_reference *param;
                   2196: 
                   2197:        if (zend_parse_parameters_none() == FAILURE) {
                   2198:                return;
                   2199:        }
                   2200:        GET_REFLECTION_OBJECT_PTR(param);
                   2201: 
                   2202:        if (!param->fptr->common.scope) {
                   2203:                reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
                   2204:        } else {
                   2205:                reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
                   2206:        }
                   2207: }
                   2208: /* }}} */
                   2209: 
                   2210: /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass()
                   2211:    Returns in which class this parameter is defined (not the typehint of the parameter) */
                   2212: ZEND_METHOD(reflection_parameter, getDeclaringClass)
                   2213: {
                   2214:        reflection_object *intern;
                   2215:        parameter_reference *param;
                   2216: 
                   2217:        if (zend_parse_parameters_none() == FAILURE) {
                   2218:                return;
                   2219:        }
                   2220:        GET_REFLECTION_OBJECT_PTR(param);
                   2221: 
                   2222:        if (param->fptr->common.scope) {
                   2223:                zend_reflection_class_factory(param->fptr->common.scope, return_value TSRMLS_CC);
                   2224:        }       
                   2225: }
                   2226: /* }}} */
                   2227: 
                   2228: /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass()
                   2229:    Returns this parameters's class hint or NULL if there is none */
                   2230: ZEND_METHOD(reflection_parameter, getClass)
                   2231: {
                   2232:        reflection_object *intern;
                   2233:        parameter_reference *param;
                   2234:        zend_class_entry **pce, *ce;
                   2235: 
                   2236:        if (zend_parse_parameters_none() == FAILURE) {
                   2237:                return;
                   2238:        }
                   2239:        GET_REFLECTION_OBJECT_PTR(param);
                   2240: 
                   2241:        if (param->arg_info->class_name) {
                   2242:                /* Class name is stored as a string, we might also get "self" or "parent"
                   2243:                 * - For "self", simply use the function scope. If scope is NULL then
                   2244:                 *   the function is global and thus self does not make any sense
                   2245:                 *
                   2246:                 * - For "parent", use the function scope's parent. If scope is NULL then
                   2247:                 *   the function is global and thus parent does not make any sense.
                   2248:                 *   If the parent is NULL then the class does not extend anything and
                   2249:                 *   thus parent does not make any sense, either.
                   2250:                 *
                   2251:                 * TODO: Think about moving these checks to the compiler or some sort of
                   2252:                 * lint-mode.
                   2253:                 */
                   2254:                if (0 == strncmp(param->arg_info->class_name, "self", sizeof("self")- 1)) {
                   2255:                        ce = param->fptr->common.scope;
                   2256:                        if (!ce) {
                   2257:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2258:                                        "Parameter uses 'self' as type hint but function is not a class member!");
                   2259:                                return;
                   2260:                        }
                   2261:                        pce= &ce;
                   2262:                } else if (0 == strncmp(param->arg_info->class_name, "parent", sizeof("parent")- 1)) {
                   2263:                        ce = param->fptr->common.scope;
                   2264:                        if (!ce) {
                   2265:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2266:                                        "Parameter uses 'parent' as type hint but function is not a class member!");
                   2267:                                return;
                   2268:                        }
                   2269:                        if (!ce->parent) {
                   2270:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2271:                                        "Parameter uses 'parent' as type hint although class does not have a parent!");
                   2272:                                return;
                   2273:                        }
                   2274:                        pce= &ce->parent;
                   2275:                } else if (zend_lookup_class(param->arg_info->class_name, param->arg_info->class_name_len, &pce TSRMLS_CC) == FAILURE) {
                   2276:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2277:                                "Class %s does not exist", param->arg_info->class_name);
                   2278:                        return;
                   2279:                }
                   2280:                zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
                   2281:        }
                   2282: }
                   2283: /* }}} */
                   2284: 
                   2285: /* {{{ proto public bool ReflectionParameter::isArray()
                   2286:    Returns whether parameter MUST be an array */
                   2287: ZEND_METHOD(reflection_parameter, isArray)
                   2288: {
                   2289:        reflection_object *intern;
                   2290:        parameter_reference *param;
                   2291: 
                   2292:        if (zend_parse_parameters_none() == FAILURE) {
                   2293:                return;
                   2294:        }
                   2295:        GET_REFLECTION_OBJECT_PTR(param);
                   2296: 
                   2297:        RETVAL_BOOL(param->arg_info->array_type_hint);
                   2298: }
                   2299: /* }}} */
                   2300: 
                   2301: /* {{{ proto public bool ReflectionParameter::allowsNull()
                   2302:    Returns whether NULL is allowed as this parameters's value */
                   2303: ZEND_METHOD(reflection_parameter, allowsNull)
                   2304: {
                   2305:        reflection_object *intern;
                   2306:        parameter_reference *param;
                   2307: 
                   2308:        if (zend_parse_parameters_none() == FAILURE) {
                   2309:                return;
                   2310:        }
                   2311:        GET_REFLECTION_OBJECT_PTR(param);
                   2312: 
                   2313:        RETVAL_BOOL(param->arg_info->allow_null);
                   2314: }
                   2315: /* }}} */
                   2316: 
                   2317: /* {{{ proto public bool ReflectionParameter::isPassedByReference()
                   2318:    Returns whether this parameters is passed to by reference */
                   2319: ZEND_METHOD(reflection_parameter, isPassedByReference)
                   2320: {
                   2321:        reflection_object *intern;
                   2322:        parameter_reference *param;
                   2323: 
                   2324:        if (zend_parse_parameters_none() == FAILURE) {
                   2325:                return;
                   2326:        }
                   2327:        GET_REFLECTION_OBJECT_PTR(param);
                   2328: 
                   2329:        RETVAL_BOOL(param->arg_info->pass_by_reference);
                   2330: }
                   2331: /* }}} */
                   2332: 
                   2333: /* {{{ proto public bool ReflectionParameter::getPosition()
                   2334:    Returns whether this parameter is an optional parameter */
                   2335: ZEND_METHOD(reflection_parameter, getPosition)
                   2336: {
                   2337:        reflection_object *intern;
                   2338:        parameter_reference *param;
                   2339: 
                   2340:        if (zend_parse_parameters_none() == FAILURE) {
                   2341:                return;
                   2342:        }
                   2343:        GET_REFLECTION_OBJECT_PTR(param);
                   2344: 
                   2345:        RETVAL_LONG(param->offset);
                   2346: }
                   2347: /* }}} */
                   2348: 
                   2349: /* {{{ proto public bool ReflectionParameter::isOptional()
                   2350:    Returns whether this parameter is an optional parameter */
                   2351: ZEND_METHOD(reflection_parameter, isOptional)
                   2352: {
                   2353:        reflection_object *intern;
                   2354:        parameter_reference *param;
                   2355: 
                   2356:        if (zend_parse_parameters_none() == FAILURE) {
                   2357:                return;
                   2358:        }
                   2359:        GET_REFLECTION_OBJECT_PTR(param);
                   2360: 
                   2361:        RETVAL_BOOL(param->offset >= param->required);
                   2362: }
                   2363: /* }}} */
                   2364: 
                   2365: /* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable()
                   2366:    Returns whether the default value of this parameter is available */
                   2367: ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
                   2368: {
                   2369:        reflection_object *intern;
                   2370:        parameter_reference *param;
                   2371:        zend_op *precv;
                   2372: 
                   2373:        if (zend_parse_parameters_none() == FAILURE) {
                   2374:                return;
                   2375:        }
                   2376:        GET_REFLECTION_OBJECT_PTR(param);
                   2377: 
                   2378:        if (param->fptr->type != ZEND_USER_FUNCTION)
                   2379:        {
                   2380:                RETURN_FALSE;
                   2381:        }
                   2382:        if (param->offset < param->required) {
                   2383:                RETURN_FALSE;
                   2384:        }
                   2385:        precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
                   2386:        if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
                   2387:                RETURN_FALSE;
                   2388:        }
                   2389:        RETURN_TRUE;
                   2390: }
                   2391: /* }}} */
                   2392: 
                   2393: /* {{{ proto public bool ReflectionParameter::getDefaultValue()
                   2394:    Returns the default value of this parameter or throws an exception */
                   2395: ZEND_METHOD(reflection_parameter, getDefaultValue)
                   2396: {
                   2397:        reflection_object *intern;
                   2398:        parameter_reference *param;
                   2399:        zend_op *precv;
                   2400: 
                   2401:        if (zend_parse_parameters_none() == FAILURE) {
                   2402:                return;
                   2403:        }
                   2404:        GET_REFLECTION_OBJECT_PTR(param);
                   2405: 
                   2406:        if (param->fptr->type != ZEND_USER_FUNCTION)
                   2407:        {
                   2408:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Cannot determine default value for internal functions");
                   2409:                return;
                   2410:        }
                   2411:        if (param->offset < param->required) {
                   2412:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Parameter is not optional"); 
                   2413:                return;
                   2414:        }
                   2415:        precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
                   2416:        if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2.op_type == IS_UNUSED) {
                   2417:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Internal error"); 
                   2418:                return;
                   2419:        }
                   2420: 
                   2421:        *return_value = precv->op2.u.constant;
                   2422:        INIT_PZVAL(return_value);
                   2423:        if (Z_TYPE_P(return_value) != IS_CONSTANT && Z_TYPE_P(return_value) != IS_CONSTANT_ARRAY) {
                   2424:                zval_copy_ctor(return_value);
                   2425:        }
                   2426:        zval_update_constant_ex(&return_value, (void*)0, param->fptr->common.scope TSRMLS_CC);
                   2427: }
                   2428: /* }}} */
                   2429: 
                   2430: /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
                   2431:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   2432: ZEND_METHOD(reflection_method, export)
                   2433: {
                   2434:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
                   2435: }
                   2436: /* }}} */
                   2437: 
                   2438: /* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name])
                   2439:    Constructor. Throws an Exception in case the given method does not exist */
                   2440: ZEND_METHOD(reflection_method, __construct)
                   2441: {
                   2442:        zval *name, *classname;
                   2443:        zval *object, *orig_obj;
                   2444:        reflection_object *intern;
                   2445:        char *lcname;
                   2446:        zend_class_entry **pce;
                   2447:        zend_class_entry *ce;
                   2448:        zend_function *mptr;
                   2449:        char *name_str, *tmp;
                   2450:        int name_len, tmp_len;
                   2451:        zval ztmp;
                   2452: 
                   2453:        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
                   2454:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
                   2455:                        return;
                   2456:                }
                   2457:                if ((tmp = strstr(name_str, "::")) == NULL) {
                   2458:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Invalid method name %s", name_str); 
                   2459:                        return;
                   2460:                }
                   2461:                classname = &ztmp;
                   2462:                tmp_len = tmp - name_str;
                   2463:                ZVAL_STRINGL(classname, name_str, tmp_len, 1);
                   2464:                name_len = name_len - (tmp_len + 2);
                   2465:                name_str = tmp + 2;
                   2466:                orig_obj = NULL;
                   2467:        } else if (Z_TYPE_P(classname) == IS_OBJECT) {
                   2468:                orig_obj = classname;
                   2469:        } else {
                   2470:                orig_obj = NULL;
                   2471:        }
                   2472: 
                   2473:        object = getThis();
                   2474:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   2475:        if (intern == NULL) {
                   2476:                return;
                   2477:        }
                   2478:        
                   2479:        /* Find the class entry */
                   2480:        switch (Z_TYPE_P(classname)) {
                   2481:                case IS_STRING:
                   2482:                        if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
                   2483:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2484:                                                "Class %s does not exist", Z_STRVAL_P(classname)); 
                   2485:                                if (classname == &ztmp) {
                   2486:                                        zval_dtor(&ztmp);
                   2487:                                }
                   2488:                                return;
                   2489:                        }
                   2490:                        ce = *pce;
                   2491:                        break;
                   2492: 
                   2493:                case IS_OBJECT:
                   2494:                        ce = Z_OBJCE_P(classname);
                   2495:                        break;
                   2496: 
                   2497:                default:
                   2498:                        if (classname == &ztmp) {
                   2499:                                zval_dtor(&ztmp);
                   2500:                        }
                   2501:                        _DO_THROW("The parameter class is expected to be either a string or an object");
                   2502:                        /* returns out of this function */
                   2503:        }
                   2504: 
                   2505:        if (classname == &ztmp) {
                   2506:                zval_dtor(&ztmp);
                   2507:        }
                   2508: 
                   2509:        lcname = zend_str_tolower_dup(name_str, name_len);
                   2510: 
                   2511:        if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   2512:                && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                   2513:                && (mptr = zend_get_closure_invoke_method(orig_obj TSRMLS_CC)) != NULL)
                   2514:        {
                   2515:                /* do nothing, mptr already set */
                   2516:        } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
                   2517:                efree(lcname);
                   2518:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2519:                        "Method %s::%s() does not exist", ce->name, name_str);
                   2520:                return;
                   2521:        }
                   2522:        efree(lcname);
                   2523: 
                   2524:        MAKE_STD_ZVAL(classname);
                   2525:        ZVAL_STRINGL(classname, mptr->common.scope->name, mptr->common.scope->name_length, 1);
                   2526: 
                   2527:        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
                   2528:        
                   2529:        MAKE_STD_ZVAL(name);
                   2530:        ZVAL_STRING(name, mptr->common.function_name, 1);
                   2531:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   2532:        intern->ptr = mptr;
                   2533:        intern->ref_type = REF_TYPE_FUNCTION;
                   2534:        intern->ce = ce;
                   2535: }
                   2536: /* }}} */
                   2537: 
                   2538: /* {{{ proto public string ReflectionMethod::__toString()
                   2539:    Returns a string representation */
                   2540: ZEND_METHOD(reflection_method, __toString)
                   2541: {
                   2542:        reflection_object *intern;
                   2543:        zend_function *mptr;
                   2544:        string str;
                   2545: 
                   2546:        if (zend_parse_parameters_none() == FAILURE) {
                   2547:                return;
                   2548:        }
                   2549:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2550:        string_init(&str);
                   2551:        _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
                   2552:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   2553: }
                   2554: /* }}} */
                   2555: 
                   2556: /* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
                   2557:    Invokes the method. */
                   2558: ZEND_METHOD(reflection_method, invoke)
                   2559: {
                   2560:        zval *retval_ptr;
                   2561:        zval ***params = NULL;
                   2562:        zval *object_ptr;
                   2563:        reflection_object *intern;
                   2564:        zend_function *mptr;
                   2565:        int result, num_args = 0;
                   2566:        zend_fcall_info fci;
                   2567:        zend_fcall_info_cache fcc;
                   2568:        zend_class_entry *obj_ce;
                   2569:        
                   2570:        METHOD_NOTSTATIC(reflection_method_ptr);
                   2571: 
                   2572:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2573: 
                   2574:        if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
                   2575:                 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
                   2576:                 && intern->ignore_visibility == 0)
                   2577:        {
                   2578:                if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
                   2579:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2580:                                "Trying to invoke abstract method %s::%s()", 
                   2581:                                mptr->common.scope->name, mptr->common.function_name);
                   2582:                } else {
                   2583:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2584:                                "Trying to invoke %s method %s::%s() from scope %s", 
                   2585:                                mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
                   2586:                                mptr->common.scope->name, mptr->common.function_name,
                   2587:                                Z_OBJCE_P(getThis())->name);
                   2588:                }
                   2589:                return;
                   2590:        }
                   2591: 
                   2592:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &params, &num_args) == FAILURE) {
                   2593:                return;
                   2594:        }
                   2595:        
                   2596:        /* In case this is a static method, we should'nt pass an object_ptr
                   2597:         * (which is used as calling context aka $this). We can thus ignore the
                   2598:         * first parameter.
                   2599:         *
                   2600:         * Else, we verify that the given object is an instance of the class.
                   2601:         */
                   2602:        if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
                   2603:                object_ptr = NULL;
                   2604:                obj_ce = mptr->common.scope;
                   2605:        } else {
                   2606:                if (Z_TYPE_PP(params[0]) != IS_OBJECT) {
                   2607:                        efree(params);
                   2608:                        _DO_THROW("Non-object passed to Invoke()");
                   2609:                        /* Returns from this function */
                   2610:                }
                   2611: 
                   2612:                obj_ce = Z_OBJCE_PP(params[0]);
                   2613: 
                   2614:                if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
                   2615:                        if (params) {
                   2616:                                efree(params);
                   2617:                        }
                   2618:                        _DO_THROW("Given object is not an instance of the class this method was declared in");
                   2619:                        /* Returns from this function */
                   2620:                }
                   2621:        
                   2622:                object_ptr = *params[0];
                   2623:        }
                   2624:        
                   2625:        fci.size = sizeof(fci);
                   2626:        fci.function_table = NULL;
                   2627:        fci.function_name = NULL;
                   2628:        fci.symbol_table = NULL;
                   2629:        fci.object_ptr = object_ptr;
                   2630:        fci.retval_ptr_ptr = &retval_ptr;
                   2631:        fci.param_count = num_args - 1;
                   2632:        fci.params = params + 1;
                   2633:        fci.no_separation = 1;
                   2634: 
                   2635:        fcc.initialized = 1;
                   2636:        fcc.function_handler = mptr;
                   2637:        fcc.calling_scope = obj_ce;
                   2638:        fcc.called_scope = intern->ce;
                   2639:        fcc.object_ptr = object_ptr;
                   2640: 
                   2641:        result = zend_call_function(&fci, &fcc TSRMLS_CC);
                   2642:        
                   2643:        if (params) {
                   2644:                efree(params);
                   2645:        }
                   2646: 
                   2647:        if (result == FAILURE) {
                   2648:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2649:                        "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
                   2650:                return;
                   2651:        }
                   2652: 
                   2653:        if (retval_ptr) {
                   2654:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   2655:        }
                   2656: }
                   2657: /* }}} */
                   2658: 
                   2659: /* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args)
                   2660:    Invokes the function and pass its arguments as array. */
                   2661: ZEND_METHOD(reflection_method, invokeArgs)
                   2662: {
                   2663:        zval *retval_ptr;
                   2664:        zval ***params;
                   2665:        zval *object;
                   2666:        reflection_object *intern;
                   2667:        zend_function *mptr;
                   2668:        int argc;
                   2669:        int result;
                   2670:        zend_fcall_info fci;
                   2671:        zend_fcall_info_cache fcc;
                   2672:        zend_class_entry *obj_ce;
                   2673:        zval *param_array;
                   2674:        
                   2675:        METHOD_NOTSTATIC(reflection_method_ptr);
                   2676: 
                   2677:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2678: 
                   2679:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!a", &object, &param_array) == FAILURE) {
                   2680:                return;
                   2681:        }
                   2682: 
                   2683:        if ((!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)
                   2684:                 || (mptr->common.fn_flags & ZEND_ACC_ABSTRACT))
                   2685:                 && intern->ignore_visibility == 0)
                   2686:        {
                   2687:                if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
                   2688:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2689:                                "Trying to invoke abstract method %s::%s()", 
                   2690:                                mptr->common.scope->name, mptr->common.function_name);
                   2691:                } else {
                   2692:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2693:                                "Trying to invoke %s method %s::%s() from scope %s", 
                   2694:                                mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
                   2695:                                mptr->common.scope->name, mptr->common.function_name,
                   2696:                                Z_OBJCE_P(getThis())->name);
                   2697:                }
                   2698:                return;
                   2699:        }
                   2700: 
                   2701:        argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
                   2702:        
                   2703:        params = safe_emalloc(sizeof(zval **), argc, 0);
                   2704:        zend_hash_apply_with_argument(Z_ARRVAL_P(param_array), (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);    
                   2705:        params -= argc;
                   2706:        
                   2707:        /* In case this is a static method, we should'nt pass an object_ptr
                   2708:         * (which is used as calling context aka $this). We can thus ignore the
                   2709:         * first parameter.
                   2710:         *
                   2711:         * Else, we verify that the given object is an instance of the class.
                   2712:         */
                   2713:        if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
                   2714:                object = NULL;
                   2715:                obj_ce = mptr->common.scope;
                   2716:        } else {
                   2717:                if (!object) {
                   2718:                        efree(params);
                   2719:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   2720:                                "Trying to invoke non static method %s::%s() without an object", 
                   2721:                                mptr->common.scope->name, mptr->common.function_name);
                   2722:                        return;
                   2723:                }
                   2724:                
                   2725:                obj_ce = Z_OBJCE_P(object);
                   2726: 
                   2727:                if (!instanceof_function(obj_ce, mptr->common.scope TSRMLS_CC)) {
                   2728:                        efree(params);
                   2729:                        _DO_THROW("Given object is not an instance of the class this method was declared in");
                   2730:                        /* Returns from this function */
                   2731:                }
                   2732:        }
                   2733:        
                   2734:        fci.size = sizeof(fci);
                   2735:        fci.function_table = NULL;
                   2736:        fci.function_name = NULL;
                   2737:        fci.symbol_table = NULL;
                   2738:        fci.object_ptr = object;
                   2739:        fci.retval_ptr_ptr = &retval_ptr;
                   2740:        fci.param_count = argc;
                   2741:        fci.params = params;
                   2742:        fci.no_separation = 1;
                   2743: 
                   2744:        fcc.initialized = 1;
                   2745:        fcc.function_handler = mptr;
                   2746:        fcc.calling_scope = obj_ce;
                   2747:        fcc.called_scope = obj_ce;
                   2748:        fcc.object_ptr = object;
                   2749: 
                   2750:        result = zend_call_function(&fci, &fcc TSRMLS_CC);
                   2751:        
                   2752:        efree(params);
                   2753: 
                   2754:        if (result == FAILURE) {
                   2755:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2756:                        "Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
                   2757:                return;
                   2758:        }
                   2759: 
                   2760:        if (retval_ptr) {
                   2761:                COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
                   2762:        }
                   2763: }
                   2764: /* }}} */
                   2765: 
                   2766: /* {{{ proto public bool ReflectionMethod::isFinal()
                   2767:    Returns whether this method is final */
                   2768: ZEND_METHOD(reflection_method, isFinal)
                   2769: {
                   2770:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
                   2771: }
                   2772: /* }}} */
                   2773: 
                   2774: /* {{{ proto public bool ReflectionMethod::isAbstract()
                   2775:    Returns whether this method is abstract */
                   2776: ZEND_METHOD(reflection_method, isAbstract)
                   2777: {
                   2778:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
                   2779: }
                   2780: /* }}} */
                   2781: 
                   2782: /* {{{ proto public bool ReflectionMethod::isPublic()
                   2783:    Returns whether this method is public */
                   2784: ZEND_METHOD(reflection_method, isPublic)
                   2785: {
                   2786:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
                   2787: }
                   2788: /* }}} */
                   2789: 
                   2790: /* {{{ proto public bool ReflectionMethod::isPrivate()
                   2791:    Returns whether this method is private */
                   2792: ZEND_METHOD(reflection_method, isPrivate)
                   2793: {
                   2794:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
                   2795: }
                   2796: /* }}} */
                   2797: 
                   2798: /* {{{ proto public bool ReflectionMethod::isProtected()
                   2799:    Returns whether this method is protected */
                   2800: ZEND_METHOD(reflection_method, isProtected)
                   2801: {
                   2802:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
                   2803: }
                   2804: /* }}} */
                   2805: 
                   2806: /* {{{ proto public bool ReflectionMethod::isStatic()
                   2807:    Returns whether this method is static */
                   2808: ZEND_METHOD(reflection_method, isStatic)
                   2809: {
                   2810:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
                   2811: }
                   2812: /* }}} */
                   2813: 
                   2814: /* {{{ proto public bool ReflectionFunction::isDeprecated()
                   2815:    Returns whether this function is deprecated */
                   2816: ZEND_METHOD(reflection_function, isDeprecated)
                   2817: {
                   2818:        _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
                   2819: }
                   2820: /* }}} */
                   2821: 
                   2822: /* {{{ proto public bool ReflectionFunction::inNamespace()
                   2823:    Returns whether this function is defined in namespace */
                   2824: ZEND_METHOD(reflection_function, inNamespace)
                   2825: {
                   2826:        zval **name;
                   2827:        char *colon;
                   2828: 
                   2829:        if (zend_parse_parameters_none() == FAILURE) {
                   2830:                return;
                   2831:        }
                   2832:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   2833:                RETURN_FALSE;
                   2834:        }
                   2835:        if (Z_TYPE_PP(name) == IS_STRING
                   2836:                && (colon = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   2837:                && colon > Z_STRVAL_PP(name))
                   2838:        {
                   2839:                RETURN_TRUE;
                   2840:        }
                   2841:        RETURN_FALSE;
                   2842: }
                   2843: /* }}} */
                   2844: 
                   2845: /* {{{ proto public string ReflectionFunction::getNamespaceName()
                   2846:    Returns the name of namespace where this function is defined */
                   2847: ZEND_METHOD(reflection_function, getNamespaceName)
                   2848: {
                   2849:        zval **name;
                   2850:        char *backslash;
                   2851: 
                   2852:        if (zend_parse_parameters_none() == FAILURE) {
                   2853:                return;
                   2854:        }
                   2855:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   2856:                RETURN_FALSE;
                   2857:        }
                   2858:        if (Z_TYPE_PP(name) == IS_STRING
                   2859:                && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   2860:                && backslash > Z_STRVAL_PP(name))
                   2861:        {
                   2862:                RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
                   2863:        }
                   2864:        RETURN_EMPTY_STRING();
                   2865: }
                   2866: /* }}} */
                   2867: 
                   2868: /* {{{ proto public string ReflectionFunction::getShortName()
                   2869:    Returns the short name of the function (without namespace part) */
                   2870: ZEND_METHOD(reflection_function, getShortName)
                   2871: {
                   2872:        zval **name;
                   2873:        char *backslash;
                   2874: 
                   2875:        if (zend_parse_parameters_none() == FAILURE) {
                   2876:                return;
                   2877:        }
                   2878:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   2879:                RETURN_FALSE;
                   2880:        }
                   2881:        if (Z_TYPE_PP(name) == IS_STRING
                   2882:                && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   2883:                && backslash > Z_STRVAL_PP(name))
                   2884:        {
                   2885:                RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
                   2886:        }
                   2887:        RETURN_ZVAL(*name, 1, 0);
                   2888: }
                   2889: /* }}} */
                   2890: 
                   2891: /* {{{ proto public bool ReflectionMethod::isConstructor()
                   2892:    Returns whether this method is the constructor */
                   2893: ZEND_METHOD(reflection_method, isConstructor)
                   2894: {
                   2895:        reflection_object *intern;
                   2896:        zend_function *mptr;
                   2897: 
                   2898:        if (zend_parse_parameters_none() == FAILURE) {
                   2899:                return;
                   2900:        }
                   2901:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2902:        /* we need to check if the ctor is the ctor of the class level we we 
                   2903:         * looking at since we might be looking at an inherited old style ctor
                   2904:         * defined in base class. */
                   2905:        RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
                   2906: }
                   2907: /* }}} */
                   2908: 
                   2909: /* {{{ proto public bool ReflectionMethod::isDestructor()
                   2910:    Returns whether this method is static */
                   2911: ZEND_METHOD(reflection_method, isDestructor)
                   2912: {
                   2913:        reflection_object *intern;
                   2914:        zend_function *mptr;
                   2915: 
                   2916:        if (zend_parse_parameters_none() == FAILURE) {
                   2917:                return;
                   2918:        }
                   2919:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2920:        RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
                   2921: }
                   2922: /* }}} */
                   2923: 
                   2924: /* {{{ proto public int ReflectionMethod::getModifiers()
                   2925:    Returns a bitfield of the access modifiers for this method */
                   2926: ZEND_METHOD(reflection_method, getModifiers)
                   2927: {
                   2928:        reflection_object *intern;
                   2929:        zend_function *mptr;
                   2930: 
                   2931:        if (zend_parse_parameters_none() == FAILURE) {
                   2932:                return;
                   2933:        }
                   2934:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2935: 
                   2936:        RETURN_LONG(mptr->common.fn_flags);
                   2937: }
                   2938: /* }}} */
                   2939: 
                   2940: /* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
                   2941:    Get the declaring class */
                   2942: ZEND_METHOD(reflection_method, getDeclaringClass)
                   2943: {
                   2944:        reflection_object *intern;
                   2945:        zend_function *mptr;
                   2946: 
                   2947:        METHOD_NOTSTATIC(reflection_method_ptr);
                   2948:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2949:        
                   2950:        if (zend_parse_parameters_none() == FAILURE) {
                   2951:                return;
                   2952:        }
                   2953: 
                   2954:        zend_reflection_class_factory(mptr->common.scope, return_value TSRMLS_CC);
                   2955: }
                   2956: /* }}} */
                   2957: 
                   2958: /* {{{ proto public ReflectionClass ReflectionMethod::getPrototype()
                   2959:    Get the prototype */
                   2960: ZEND_METHOD(reflection_method, getPrototype)
                   2961: {
                   2962:        reflection_object *intern;
                   2963:        zend_function *mptr;
                   2964: 
                   2965:        METHOD_NOTSTATIC(reflection_method_ptr);
                   2966:        GET_REFLECTION_OBJECT_PTR(mptr);
                   2967:        
                   2968:        if (zend_parse_parameters_none() == FAILURE) {
                   2969:                return;
                   2970:        }
                   2971:        
                   2972:        if (!mptr->common.prototype) {
                   2973:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   2974:                        "Method %s::%s does not have a prototype", intern->ce->name, mptr->common.function_name);
                   2975:                return;
                   2976:        }
                   2977: 
                   2978:        reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC);
                   2979: }
                   2980: /* }}} */
                   2981: 
                   2982: /* {{{ proto public void ReflectionMethod::setAccessible(bool visible)
                   2983:    Sets whether non-public methods can be invoked */
                   2984: ZEND_METHOD(reflection_method, setAccessible)
                   2985: {
                   2986:        reflection_object *intern;
                   2987:        zend_bool visible;
                   2988: 
                   2989:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
                   2990:                return;
                   2991:        }
                   2992: 
                   2993:        intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
                   2994: 
                   2995:        if (intern == NULL) {
                   2996:                return;
                   2997:        }
                   2998: 
                   2999:        intern->ignore_visibility = visible;
                   3000: }
                   3001: /* }}} */
                   3002: 
                   3003: /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
                   3004:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   3005: ZEND_METHOD(reflection_class, export)
                   3006: {
                   3007:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
                   3008: }
                   3009: /* }}} */
                   3010: 
                   3011: /* {{{ reflection_class_object_ctor */
                   3012: static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
                   3013: {
                   3014:        zval *argument;
                   3015:        zval *object;
                   3016:        zval *classname;
                   3017:        reflection_object *intern;
                   3018:        zend_class_entry **ce;
                   3019: 
                   3020:        if (is_object) {
                   3021:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &argument) == FAILURE) {
                   3022:                        return;
                   3023:                }
                   3024:        } else {
                   3025:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/", &argument) == FAILURE) {
                   3026:                        return;
                   3027:                }
                   3028:        }
                   3029: 
                   3030:        object = getThis();
                   3031:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   3032:        if (intern == NULL) {
                   3033:                return;
                   3034:        }
                   3035:        
                   3036:        if (Z_TYPE_P(argument) == IS_OBJECT) {
                   3037:                MAKE_STD_ZVAL(classname);
                   3038:                ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
                   3039:                zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
                   3040:                intern->ptr = Z_OBJCE_P(argument);
                   3041:                if (is_object) {
                   3042:                        intern->obj = argument;
                   3043:                        zval_add_ref(&argument);
                   3044:                }
                   3045:        } else { 
                   3046:                convert_to_string_ex(&argument);
                   3047:                if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
                   3048:                        if (!EG(exception)) {
                   3049:                                zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
                   3050:                        }
                   3051:                        return;
                   3052:                }
                   3053: 
                   3054:                MAKE_STD_ZVAL(classname);
                   3055:                ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
                   3056:                zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
                   3057: 
                   3058:                intern->ptr = *ce;
                   3059:        }
                   3060:        intern->ref_type = REF_TYPE_OTHER;
                   3061: }
                   3062: /* }}} */
                   3063: 
                   3064: /* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException
                   3065:    Constructor. Takes a string or an instance as an argument */
                   3066: ZEND_METHOD(reflection_class, __construct)
                   3067: {
                   3068:        reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
                   3069: }
                   3070: /* }}} */
                   3071: 
                   3072: /* {{{ proto public array ReflectionClass::getStaticProperties()
                   3073:    Returns an associative array containing all static property values of the class */
                   3074: ZEND_METHOD(reflection_class, getStaticProperties)
                   3075: {
                   3076:        reflection_object *intern;
                   3077:        zend_class_entry *ce;
                   3078:        HashPosition pos;
                   3079:        zval **value;
                   3080: 
                   3081:        if (zend_parse_parameters_none() == FAILURE) {
                   3082:                return;
                   3083:        }
                   3084:        
                   3085:        GET_REFLECTION_OBJECT_PTR(ce);
                   3086: 
                   3087:        zend_update_class_constants(ce TSRMLS_CC);
                   3088: 
                   3089:        array_init(return_value);
                   3090: 
                   3091:        zend_hash_internal_pointer_reset_ex(CE_STATIC_MEMBERS(ce), &pos);
                   3092: 
                   3093:        while (zend_hash_get_current_data_ex(CE_STATIC_MEMBERS(ce), (void **) &value, &pos) == SUCCESS) {
                   3094:                uint key_len;
                   3095:                char *key;
                   3096:                ulong num_index;
                   3097: 
                   3098:                if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) {
                   3099:                        char *prop_name, *class_name;
                   3100:                        zval *prop_copy;
                   3101: 
                   3102:                        zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
                   3103: 
                   3104:                        /* filter privates from base classes */
                   3105:                        if (!(class_name && class_name[0] != '*' && strcmp(class_name, ce->name))) {
                   3106:                                /* copy: enforce read only access */
                   3107:                                ALLOC_ZVAL(prop_copy);
                   3108:                                MAKE_COPY_ZVAL(value, prop_copy);
                   3109: 
                   3110:                                add_assoc_zval(return_value, prop_name, prop_copy);
                   3111:                        }
                   3112:                }
                   3113:                zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos);
                   3114:        }
                   3115: }
                   3116: /* }}} */
                   3117: 
                   3118: /* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default])
                   3119:    Returns the value of a static property */
                   3120: ZEND_METHOD(reflection_class, getStaticPropertyValue)
                   3121: {
                   3122:        reflection_object *intern;
                   3123:        zend_class_entry *ce;
                   3124:        char *name;
                   3125:        int name_len;
                   3126:        zval **prop, *def_value = NULL;
                   3127:        
                   3128:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &name, &name_len, &def_value) == FAILURE) {
                   3129:                return;
                   3130:        }
                   3131: 
                   3132:        GET_REFLECTION_OBJECT_PTR(ce);
                   3133: 
                   3134:        zend_update_class_constants(ce TSRMLS_CC);
                   3135:        prop = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
                   3136:        if (!prop) {
                   3137:                if (def_value) {
                   3138:                        RETURN_ZVAL(def_value, 1, 0);
                   3139:                } else {
                   3140:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   3141:                                "Class %s does not have a property named %s", ce->name, name);
                   3142:                }
                   3143:                return;
                   3144:        } else {
                   3145:                RETURN_ZVAL(*prop, 1, 0);
                   3146:        }
                   3147: }
                   3148: /* }}} */
                   3149: 
                   3150: /* {{{ proto public void ReflectionClass::setStaticPropertyValue($name, $value)
                   3151:    Sets the value of a static property */
                   3152: ZEND_METHOD(reflection_class, setStaticPropertyValue)
                   3153: {
                   3154:        reflection_object *intern;
                   3155:        zend_class_entry *ce;
                   3156:        char *name;
                   3157:        int name_len;
                   3158:        zval **variable_ptr, *value;
                   3159:        int refcount;
                   3160:        zend_uchar is_ref;
                   3161:        
                   3162:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &value) == FAILURE) {
                   3163:                return;
                   3164:        }
                   3165: 
                   3166:        GET_REFLECTION_OBJECT_PTR(ce);
                   3167: 
                   3168:        zend_update_class_constants(ce TSRMLS_CC);
                   3169:        variable_ptr = zend_std_get_static_property(ce, name, name_len, 1 TSRMLS_CC);
                   3170:        if (!variable_ptr) {
                   3171:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   3172:                                "Class %s does not have a property named %s", ce->name, name);
                   3173:                return;
                   3174:        }       
                   3175:        refcount = Z_REFCOUNT_PP(variable_ptr);
                   3176:        is_ref = Z_ISREF_PP(variable_ptr);
                   3177:        zval_dtor(*variable_ptr);
                   3178:        **variable_ptr = *value;
                   3179:        zval_copy_ctor(*variable_ptr);
                   3180:        Z_SET_REFCOUNT_PP(variable_ptr, refcount);
                   3181:        Z_SET_ISREF_TO_PP(variable_ptr, is_ref);
                   3182: 
                   3183: }
                   3184: /* }}} */
                   3185: 
                   3186: /* {{{ proto public array ReflectionClass::getDefaultProperties()
                   3187:    Returns an associative array containing copies of all default property values of the class */
                   3188: ZEND_METHOD(reflection_class, getDefaultProperties)
                   3189: {
                   3190:        reflection_object *intern;
                   3191:        zend_class_entry *ce;
                   3192:        int count, i;
                   3193:        HashTable *ht_list[3];
                   3194:        
                   3195:        if (zend_parse_parameters_none() == FAILURE) {
                   3196:                return;
                   3197:        }
                   3198:        GET_REFLECTION_OBJECT_PTR(ce);
                   3199:        array_init(return_value);
                   3200: 
                   3201:        zend_update_class_constants(ce TSRMLS_CC);
                   3202: 
                   3203:        ht_list[0] = CE_STATIC_MEMBERS(ce);
                   3204:        ht_list[1] = &ce->default_properties;
                   3205:        ht_list[2] = NULL;
                   3206: 
                   3207:        for (i = 0; ht_list[i] != NULL; i++) {
                   3208: 
                   3209:                count = zend_hash_num_elements(ht_list[i]);
                   3210:                if (count > 0) {
                   3211:                        HashPosition pos;
                   3212:                        zval **prop;
                   3213: 
                   3214:                        zend_hash_internal_pointer_reset_ex(ht_list[i], &pos);
                   3215:                        while (zend_hash_get_current_data_ex(ht_list[i], (void **) &prop, &pos) == SUCCESS) {
                   3216:                                char *key, *class_name, *prop_name;
                   3217:                                uint key_len;
                   3218:                                ulong num_index;
                   3219:                                zval *prop_copy;
                   3220: 
                   3221:                                zend_hash_get_current_key_ex(ht_list[i], &key, &key_len, &num_index, 0, &pos);
                   3222:                                zend_hash_move_forward_ex(ht_list[i], &pos);
                   3223:                                zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
                   3224:                                if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) {
                   3225:                                        /* filter privates from base classes */
                   3226:                                        continue;
                   3227:                                }
                   3228: 
                   3229:                                /* copy: enforce read only access */
                   3230:                                ALLOC_ZVAL(prop_copy);
                   3231:                                MAKE_COPY_ZVAL(prop, prop_copy);
                   3232: 
                   3233:                                add_assoc_zval(return_value, prop_name, prop_copy);
                   3234:                        }
                   3235:                }
                   3236:        }
                   3237: }
                   3238: /* }}} */
                   3239: 
                   3240: /* {{{ proto public string ReflectionClass::__toString()
                   3241:    Returns a string representation */
                   3242: ZEND_METHOD(reflection_class, __toString)
                   3243: {
                   3244:        reflection_object *intern;
                   3245:        zend_class_entry *ce;
                   3246:        string str;
                   3247: 
                   3248:        if (zend_parse_parameters_none() == FAILURE) {
                   3249:                return;
                   3250:        }
                   3251:        GET_REFLECTION_OBJECT_PTR(ce);
                   3252:        string_init(&str);
                   3253:        _class_string(&str, ce, intern->obj, "" TSRMLS_CC);
                   3254:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   3255: }
                   3256: /* }}} */
                   3257: 
                   3258: /* {{{ proto public string ReflectionClass::getName()
                   3259:    Returns the class' name */
                   3260: ZEND_METHOD(reflection_class, getName)
                   3261: {
                   3262:        if (zend_parse_parameters_none() == FAILURE) {
                   3263:                return;
                   3264:        }
                   3265:        _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
                   3266: }
                   3267: /* }}} */
                   3268: 
                   3269: /* {{{ proto public bool ReflectionClass::isInternal()
                   3270:    Returns whether this class is an internal class */
                   3271: ZEND_METHOD(reflection_class, isInternal)
                   3272: {
                   3273:        reflection_object *intern;
                   3274:        zend_class_entry *ce;
                   3275: 
                   3276:        if (zend_parse_parameters_none() == FAILURE) {
                   3277:                return;
                   3278:        }
                   3279:        GET_REFLECTION_OBJECT_PTR(ce);
                   3280:        RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
                   3281: }
                   3282: /* }}} */
                   3283: 
                   3284: /* {{{ proto public bool ReflectionClass::isUserDefined()
                   3285:    Returns whether this class is user-defined */
                   3286: ZEND_METHOD(reflection_class, isUserDefined)
                   3287: {
                   3288:        reflection_object *intern;
                   3289:        zend_class_entry *ce;
                   3290: 
                   3291:        if (zend_parse_parameters_none() == FAILURE) {
                   3292:                return;
                   3293:        }
                   3294:        GET_REFLECTION_OBJECT_PTR(ce);
                   3295:        RETURN_BOOL(ce->type == ZEND_USER_CLASS);
                   3296: }
                   3297: /* }}} */
                   3298: 
                   3299: /* {{{ proto public string ReflectionClass::getFileName()
                   3300:    Returns the filename of the file this class was declared in */
                   3301: ZEND_METHOD(reflection_class, getFileName)
                   3302: {
                   3303:        reflection_object *intern;
                   3304:        zend_class_entry *ce;
                   3305: 
                   3306:        if (zend_parse_parameters_none() == FAILURE) {
                   3307:                return;
                   3308:        }
                   3309:        GET_REFLECTION_OBJECT_PTR(ce);
                   3310:        if (ce->type == ZEND_USER_CLASS) {
                   3311:                RETURN_STRING(ce->filename, 1);
                   3312:        }
                   3313:        RETURN_FALSE;
                   3314: }
                   3315: /* }}} */
                   3316: 
                   3317: /* {{{ proto public int ReflectionClass::getStartLine()
                   3318:    Returns the line this class' declaration starts at */
                   3319: ZEND_METHOD(reflection_class, getStartLine)
                   3320: {
                   3321:        reflection_object *intern;
                   3322:        zend_class_entry *ce;
                   3323: 
                   3324:        if (zend_parse_parameters_none() == FAILURE) {
                   3325:                return;
                   3326:        }
                   3327:        GET_REFLECTION_OBJECT_PTR(ce);
                   3328:        if (ce->type == ZEND_USER_FUNCTION) {
                   3329:                RETURN_LONG(ce->line_start);
                   3330:        }
                   3331:        RETURN_FALSE;
                   3332: }
                   3333: /* }}} */
                   3334: 
                   3335: /* {{{ proto public int ReflectionClass::getEndLine()
                   3336:    Returns the line this class' declaration ends at */
                   3337: ZEND_METHOD(reflection_class, getEndLine)
                   3338: {
                   3339:        reflection_object *intern;
                   3340:        zend_class_entry *ce;
                   3341: 
                   3342:        if (zend_parse_parameters_none() == FAILURE) {
                   3343:                return;
                   3344:        }
                   3345:        GET_REFLECTION_OBJECT_PTR(ce);
                   3346:        if (ce->type == ZEND_USER_CLASS) {
                   3347:                RETURN_LONG(ce->line_end);
                   3348:        }
                   3349:        RETURN_FALSE;
                   3350: }
                   3351: /* }}} */
                   3352: 
                   3353: /* {{{ proto public string ReflectionClass::getDocComment()
                   3354:    Returns the doc comment for this class */
                   3355: ZEND_METHOD(reflection_class, getDocComment)
                   3356: {
                   3357:        reflection_object *intern;
                   3358:        zend_class_entry *ce;
                   3359: 
                   3360:        if (zend_parse_parameters_none() == FAILURE) {
                   3361:                return;
                   3362:        }
                   3363:        GET_REFLECTION_OBJECT_PTR(ce);
                   3364:        if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
                   3365:                RETURN_STRINGL(ce->doc_comment, ce->doc_comment_len, 1);
                   3366:        }
                   3367:        RETURN_FALSE;
                   3368: }
                   3369: /* }}} */
                   3370: 
                   3371: /* {{{ proto public ReflectionMethod ReflectionClass::getConstructor()
                   3372:    Returns the class' constructor if there is one, NULL otherwise */
                   3373: ZEND_METHOD(reflection_class, getConstructor)
                   3374: {
                   3375:        reflection_object *intern;
                   3376:        zend_class_entry *ce;
                   3377: 
                   3378:        if (zend_parse_parameters_none() == FAILURE) {
                   3379:                return;
                   3380:        }
                   3381:        GET_REFLECTION_OBJECT_PTR(ce);
                   3382: 
                   3383:        if (ce->constructor) {
                   3384:                reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC);
                   3385:        } else {
                   3386:                RETURN_NULL();
                   3387:        }
                   3388: }
                   3389: /* }}} */
                   3390: 
                   3391: /* {{{ proto public bool ReflectionClass::hasMethod(string name)
                   3392:    Returns whether a method exists or not */
                   3393: ZEND_METHOD(reflection_class, hasMethod)
                   3394: {
                   3395:        reflection_object *intern;
                   3396:        zend_class_entry *ce;
                   3397:        char *name, *lc_name; 
                   3398:        int name_len;
                   3399: 
                   3400:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3401:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3402:                return;
                   3403:        }
                   3404: 
                   3405:        GET_REFLECTION_OBJECT_PTR(ce);
                   3406:        lc_name = zend_str_tolower_dup(name, name_len);
                   3407:        if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   3408:                && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
                   3409:                || zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
                   3410:                efree(lc_name);
                   3411:                RETURN_TRUE;
                   3412:        } else {
                   3413:                efree(lc_name);
                   3414:                RETURN_FALSE;
                   3415:        }
                   3416: }
                   3417: /* }}} */
                   3418: 
                   3419: /* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException
                   3420:    Returns the class' method specified by its name */
                   3421: ZEND_METHOD(reflection_class, getMethod)
                   3422: {
                   3423:        reflection_object *intern;
                   3424:        zend_class_entry *ce;
                   3425:        zend_function *mptr;
                   3426:        zval obj_tmp;
                   3427:        char *name, *lc_name; 
                   3428:        int name_len;
                   3429: 
                   3430:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3431:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3432:                return;
                   3433:        }
                   3434: 
                   3435:        GET_REFLECTION_OBJECT_PTR(ce);
                   3436:        lc_name = zend_str_tolower_dup(name, name_len);
                   3437:        if (ce == zend_ce_closure && intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   3438:                && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                   3439:                && (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != NULL)
                   3440:        {
                   3441:                /* don't assign closure_object since we only reflect the invoke handler
                   3442:                   method and not the closure definition itself */
                   3443:                reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
                   3444:                efree(lc_name);
                   3445:        } else if (ce == zend_ce_closure && !intern->obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   3446:                && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                   3447:                && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(&obj_tmp TSRMLS_CC)) != NULL) {
                   3448:                /* don't assign closure_object since we only reflect the invoke handler
                   3449:                   method and not the closure definition itself */
                   3450:                reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
                   3451:                zval_dtor(&obj_tmp);
                   3452:                efree(lc_name);
                   3453:        } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
                   3454:                reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
                   3455:                efree(lc_name);
                   3456:        } else {
                   3457:                efree(lc_name);
                   3458:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   3459:                                "Method %s does not exist", name);
                   3460:                return;
                   3461:        }
                   3462: }
                   3463: /* }}} */
                   3464: 
                   3465: /* {{{ _addmethod */
                   3466: static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, long filter, zval *obj TSRMLS_DC)
                   3467: {
                   3468:        zval *method;
                   3469:        uint len = strlen(mptr->common.function_name);
                   3470:        zend_function *closure;
                   3471: 
                   3472:        if (mptr->common.fn_flags & filter) {
                   3473:                ALLOC_ZVAL(method);
                   3474:                if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
                   3475:                        && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                   3476:                        && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
                   3477:                {
                   3478:                        mptr = closure;
                   3479:                }
                   3480:                /* don't assign closure_object since we only reflect the invoke handler
                   3481:                   method and not the closure definition itself, even if we have a
                   3482:                   closure */
                   3483:                reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC);
                   3484:                add_next_index_zval(retval, method);
                   3485:        }
                   3486: }
                   3487: /* }}} */
                   3488: 
                   3489: /* {{{ _addmethod */
                   3490: static int _addmethod_va(zend_function *mptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   3491: {
                   3492:        zend_class_entry *ce = *va_arg(args, zend_class_entry**);
                   3493:        zval *retval = va_arg(args, zval*);
                   3494:        long filter = va_arg(args, long);
                   3495:        zval *obj = va_arg(args, zval *);
                   3496:        
                   3497:        _addmethod(mptr, ce, retval, filter, obj TSRMLS_CC);
                   3498:        return ZEND_HASH_APPLY_KEEP;
                   3499: }
                   3500: /* }}} */
                   3501: 
                   3502: /* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter])
                   3503:    Returns an array of this class' methods */
                   3504: ZEND_METHOD(reflection_class, getMethods)
                   3505: {
                   3506:        reflection_object *intern;
                   3507:        zend_class_entry *ce;
                   3508:        long filter = 0;
                   3509:        int argc = ZEND_NUM_ARGS();
                   3510: 
                   3511:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3512:        if (argc) {
                   3513:                if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
                   3514:                        return;
                   3515:                }
                   3516:        } else {
                   3517:                /* No parameters given, default to "return all" */
                   3518:                filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
                   3519:        }
                   3520: 
                   3521:        GET_REFLECTION_OBJECT_PTR(ce);
                   3522: 
                   3523:        array_init(return_value);
                   3524:        zend_hash_apply_with_arguments(&ce->function_table TSRMLS_CC, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter, intern->obj);
                   3525:        if (intern->obj && instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
                   3526:                zend_function *closure = zend_get_closure_invoke_method(intern->obj TSRMLS_CC);
                   3527:                if (closure) {
                   3528:                        _addmethod(closure, ce, return_value, filter, intern->obj TSRMLS_CC);
                   3529:                        _free_function(closure TSRMLS_CC);
                   3530:                }
                   3531:        }
                   3532: }
                   3533: /* }}} */
                   3534: 
                   3535: /* {{{ proto public bool ReflectionClass::hasProperty(string name)
                   3536:    Returns whether a property exists or not */
                   3537: ZEND_METHOD(reflection_class, hasProperty)
                   3538: {
                   3539:        reflection_object *intern;
                   3540:        zend_property_info *property_info;
                   3541:        zend_class_entry *ce;
                   3542:        char *name; 
                   3543:        int name_len;
                   3544:        zval *property;
                   3545: 
                   3546:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3547:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3548:                return;
                   3549:        }
                   3550: 
                   3551:        GET_REFLECTION_OBJECT_PTR(ce);
                   3552:        if (zend_hash_find(&ce->properties_info, name, name_len+1, (void **) &property_info) == SUCCESS) {
                   3553:                if (property_info->flags & ZEND_ACC_SHADOW) {
                   3554:                        RETURN_FALSE;
                   3555:                }
                   3556:                RETURN_TRUE;
                   3557:        } else {
                   3558:                if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property)) {
                   3559:                        MAKE_STD_ZVAL(property);
                   3560:                        ZVAL_STRINGL(property, name, name_len, 1);
                   3561:                        if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 2 TSRMLS_CC)) {
                   3562:                                zval_ptr_dtor(&property);
                   3563:                                RETURN_TRUE;
                   3564:                        }
                   3565:                        zval_ptr_dtor(&property);
                   3566:                }
                   3567:                RETURN_FALSE;
                   3568:        }
                   3569: }
                   3570: /* }}} */
                   3571: 
                   3572: /* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException
                   3573:    Returns the class' property specified by its name */
                   3574: ZEND_METHOD(reflection_class, getProperty)
                   3575: {
                   3576:        reflection_object *intern;
                   3577:        zend_class_entry *ce, **pce;
                   3578:        zend_property_info *property_info;
                   3579:        char *name, *tmp, *classname; 
                   3580:        int name_len, classname_len;
                   3581: 
                   3582:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3583:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3584:                return;
                   3585:        }
                   3586: 
                   3587:        GET_REFLECTION_OBJECT_PTR(ce);
                   3588:        if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS) {
                   3589:                if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
                   3590:                        reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
                   3591:                        return;
                   3592:                }
                   3593:        } else if (intern->obj) {
                   3594:                /* Check for dynamic properties */
                   3595:                if (zend_hash_exists(Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC), name, name_len+1)) {
                   3596:                        zend_property_info property_info_tmp;
                   3597:                        property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
                   3598:                        property_info_tmp.name = estrndup(name, name_len);
                   3599:                        property_info_tmp.name_length = name_len;
                   3600:                        property_info_tmp.h = zend_get_hash_value(name, name_len+1);
                   3601:                        property_info_tmp.doc_comment = NULL;
                   3602:                        property_info_tmp.ce = ce;
                   3603: 
                   3604:                        reflection_property_factory(ce, &property_info_tmp, return_value TSRMLS_CC);
                   3605:                        intern = (reflection_object *) zend_object_store_get_object(return_value TSRMLS_CC);
                   3606:                        intern->ref_type = REF_TYPE_DYNAMIC_PROPERTY;
                   3607:                        return;
                   3608:                }
                   3609:        }
                   3610:        if ((tmp = strstr(name, "::")) != NULL) {
                   3611:                classname_len = tmp - name;
                   3612:                classname = zend_str_tolower_dup(name, classname_len);
                   3613:                classname[classname_len] = '\0';
                   3614:                name_len = name_len - (classname_len + 2);
                   3615:                name = tmp + 2;
                   3616: 
                   3617:                if (zend_lookup_class(classname, classname_len, &pce TSRMLS_CC) == FAILURE) {
                   3618:                        if (!EG(exception)) {
                   3619:                                zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", classname);
                   3620:                        }
                   3621:                        efree(classname);
                   3622:                        return;
                   3623:                }
                   3624:                efree(classname);
                   3625: 
                   3626:                if (!instanceof_function(ce, *pce TSRMLS_CC)) {
                   3627:                        zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Fully qualified property name %s::%s does not specify a base class of %s", (*pce)->name, name, ce->name);
                   3628:                        return;
                   3629:                }
                   3630:                ce = *pce;
                   3631: 
                   3632:                if (zend_hash_find(&ce->properties_info, name, name_len + 1, (void**) &property_info) == SUCCESS && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
                   3633:                        reflection_property_factory(ce, property_info, return_value TSRMLS_CC);
                   3634:                        return;
                   3635:                }               
                   3636:        }
                   3637:        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   3638:                        "Property %s does not exist", name);
                   3639: }
                   3640: /* }}} */
                   3641: 
                   3642: /* {{{ _addproperty */
                   3643: static int _addproperty(zend_property_info *pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   3644: {
                   3645:        zval *property;
                   3646:        zend_class_entry *ce = *va_arg(args, zend_class_entry**);
                   3647:        zval *retval = va_arg(args, zval*);
                   3648:        long filter = va_arg(args, long);
                   3649: 
                   3650:        if (pptr->flags & ZEND_ACC_SHADOW) {
                   3651:                return 0;
                   3652:        }
                   3653:        
                   3654:        if (pptr->flags & filter) {
                   3655:                ALLOC_ZVAL(property);
                   3656:                reflection_property_factory(ce, pptr, property TSRMLS_CC);
                   3657:                add_next_index_zval(retval, property);
                   3658:        }
                   3659:        return 0;
                   3660: }
                   3661: /* }}} */
                   3662: 
                   3663: /* {{{ _adddynproperty */
                   3664: static int _adddynproperty(zval **pptr TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   3665: {
                   3666:        zval *property;
                   3667:        zend_class_entry *ce = *va_arg(args, zend_class_entry**);
                   3668:        zval *retval = va_arg(args, zval*), member;
                   3669: 
                   3670:        if (hash_key->arKey[0] == '\0') {
                   3671:                return 0; /* non public cannot be dynamic */
                   3672:        }
                   3673: 
                   3674:        ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0);
                   3675:        if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) {
                   3676:                MAKE_STD_ZVAL(property);
                   3677:                EG(std_property_info).flags = ZEND_ACC_IMPLICIT_PUBLIC;
                   3678:                reflection_property_factory(ce, &EG(std_property_info), property TSRMLS_CC);
                   3679:                add_next_index_zval(retval, property);
                   3680:        }
                   3681:        return 0;
                   3682: }
                   3683: /* }}} */
                   3684: 
                   3685: /* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter])
                   3686:    Returns an array of this class' properties */
                   3687: ZEND_METHOD(reflection_class, getProperties)
                   3688: {
                   3689:        reflection_object *intern;
                   3690:        zend_class_entry *ce;
                   3691:        long filter = 0;
                   3692:        int argc = ZEND_NUM_ARGS();
                   3693: 
                   3694:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3695:        if (argc) {
                   3696:                if (zend_parse_parameters(argc TSRMLS_CC, "|l", &filter) == FAILURE) {
                   3697:                        return;
                   3698:                }
                   3699:        } else {
                   3700:                /* No parameters given, default to "return all" */
                   3701:                filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
                   3702:        }
                   3703: 
                   3704:        GET_REFLECTION_OBJECT_PTR(ce);
                   3705: 
                   3706:        array_init(return_value);
                   3707:        zend_hash_apply_with_arguments(&ce->properties_info TSRMLS_CC, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
                   3708: 
                   3709:        if (intern->obj && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT_P(intern->obj)->get_properties) {
                   3710:                HashTable *properties = Z_OBJ_HT_P(intern->obj)->get_properties(intern->obj TSRMLS_CC);
                   3711:                zend_hash_apply_with_arguments(properties TSRMLS_CC, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
                   3712:        }
                   3713: }
                   3714: /* }}} */
                   3715: 
                   3716: /* {{{ proto public bool ReflectionClass::hasConstant(string name)
                   3717:    Returns whether a constant exists or not */
                   3718: ZEND_METHOD(reflection_class, hasConstant)
                   3719: {
                   3720:        reflection_object *intern;
                   3721:        zend_class_entry *ce;
                   3722:        char *name;
                   3723:        int name_len;
                   3724: 
                   3725:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3726:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3727:                return;
                   3728:        }
                   3729: 
                   3730:        GET_REFLECTION_OBJECT_PTR(ce);
                   3731:        if (zend_hash_exists(&ce->constants_table, name, name_len + 1)) {
                   3732:                RETURN_TRUE;
                   3733:        } else {
                   3734:                RETURN_FALSE;
                   3735:        }
                   3736: }
                   3737: /* }}} */
                   3738: 
                   3739: /* {{{ proto public array ReflectionClass::getConstants()
                   3740:    Returns an associative array containing this class' constants and their values */
                   3741: ZEND_METHOD(reflection_class, getConstants)
                   3742: {
                   3743:        zval *tmp_copy;
                   3744:        reflection_object *intern;
                   3745:        zend_class_entry *ce;
                   3746: 
                   3747:        if (zend_parse_parameters_none() == FAILURE) {
                   3748:                return;
                   3749:        }
                   3750:        GET_REFLECTION_OBJECT_PTR(ce);
                   3751:        array_init(return_value);
                   3752:        zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
                   3753:        zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
                   3754: }
                   3755: /* }}} */
                   3756: 
                   3757: /* {{{ proto public mixed ReflectionClass::getConstant(string name)
                   3758:    Returns the class' constant specified by its name */
                   3759: ZEND_METHOD(reflection_class, getConstant)
                   3760: {
                   3761:        reflection_object *intern;
                   3762:        zend_class_entry *ce;
                   3763:        zval **value;
                   3764:        char *name; 
                   3765:        int name_len;
                   3766: 
                   3767:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3768:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
                   3769:                return;
                   3770:        }
                   3771: 
                   3772:        GET_REFLECTION_OBJECT_PTR(ce);
                   3773:        zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce TSRMLS_CC);
                   3774:        if (zend_hash_find(&ce->constants_table, name, name_len + 1, (void **) &value) == FAILURE) {
                   3775:                RETURN_FALSE;
                   3776:        }
                   3777:        MAKE_COPY_ZVAL(value, return_value);
                   3778: }
                   3779: /* }}} */
                   3780: 
                   3781: /* {{{ _class_check_flag */
                   3782: static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
                   3783: {
                   3784:        reflection_object *intern;
                   3785:        zend_class_entry *ce;
                   3786: 
                   3787:        if (zend_parse_parameters_none() == FAILURE) {
                   3788:                return;
                   3789:        }
                   3790:        GET_REFLECTION_OBJECT_PTR(ce);
                   3791:        RETVAL_BOOL(ce->ce_flags & mask);
                   3792: }
                   3793: /* }}} */
                   3794: 
                   3795: /* {{{ proto public bool ReflectionClass::isInstantiable()
                   3796:    Returns whether this class is instantiable */
                   3797: ZEND_METHOD(reflection_class, isInstantiable)
                   3798: {
                   3799:        reflection_object *intern;
                   3800:        zend_class_entry *ce;
                   3801: 
                   3802:        if (zend_parse_parameters_none() == FAILURE) {
                   3803:                return;
                   3804:        }
                   3805:        GET_REFLECTION_OBJECT_PTR(ce);
                   3806:        if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
                   3807:                RETURN_FALSE;
                   3808:        }
                   3809: 
                   3810:        /* Basically, the class is instantiable. Though, if there is a constructor
                   3811:         * and it is not publicly accessible, it isn't! */
                   3812:        if (!ce->constructor) {
                   3813:                RETURN_TRUE;
                   3814:        }
                   3815: 
                   3816:        RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
                   3817: }
                   3818: /* }}} */
                   3819: 
                   3820: /* {{{ proto public bool ReflectionClass::isInterface()
                   3821:    Returns whether this is an interface or a class */
                   3822: ZEND_METHOD(reflection_class, isInterface)
                   3823: {
                   3824:        _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
                   3825: }
                   3826: /* }}} */
                   3827: 
                   3828: /* {{{ proto public bool ReflectionClass::isFinal()
                   3829:    Returns whether this class is final */
                   3830: ZEND_METHOD(reflection_class, isFinal)
                   3831: {
                   3832:        _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL_CLASS);
                   3833: }
                   3834: /* }}} */
                   3835: 
                   3836: /* {{{ proto public bool ReflectionClass::isAbstract()
                   3837:    Returns whether this class is abstract */
                   3838: ZEND_METHOD(reflection_class, isAbstract)
                   3839: {
                   3840:        _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
                   3841: }
                   3842: /* }}} */
                   3843: 
                   3844: /* {{{ proto public int ReflectionClass::getModifiers()
                   3845:    Returns a bitfield of the access modifiers for this class */
                   3846: ZEND_METHOD(reflection_class, getModifiers)
                   3847: {
                   3848:        reflection_object *intern;
                   3849:        zend_class_entry *ce;
                   3850: 
                   3851:        if (zend_parse_parameters_none() == FAILURE) {
                   3852:                return;
                   3853:        }
                   3854:        GET_REFLECTION_OBJECT_PTR(ce);
                   3855: 
                   3856:        RETURN_LONG(ce->ce_flags);
                   3857: }
                   3858: /* }}} */
                   3859: 
                   3860: /* {{{ proto public bool ReflectionClass::isInstance(stdclass object)
                   3861:    Returns whether the given object is an instance of this class */
                   3862: ZEND_METHOD(reflection_class, isInstance)
                   3863: {
                   3864:        reflection_object *intern;
                   3865:        zend_class_entry *ce;
                   3866:        zval *object;
                   3867: 
                   3868:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3869:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
                   3870:                return;
                   3871:        }
                   3872:        GET_REFLECTION_OBJECT_PTR(ce);  
                   3873:        RETURN_BOOL(HAS_CLASS_ENTRY(*object) && instanceof_function(Z_OBJCE_P(object), ce TSRMLS_CC));
                   3874: }
                   3875: /* }}} */
                   3876: 
                   3877: /* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...)
                   3878:    Returns an instance of this class */
                   3879: ZEND_METHOD(reflection_class, newInstance)
                   3880: {
                   3881:        zval *retval_ptr = NULL;
                   3882:        reflection_object *intern;
                   3883:        zend_class_entry *ce;
                   3884:        
                   3885:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3886:        GET_REFLECTION_OBJECT_PTR(ce);
                   3887: 
                   3888:        /* Run the constructor if there is one */
                   3889:        if (ce->constructor) {
                   3890:                zval ***params = NULL;
                   3891:                int num_args = 0;
                   3892:                zend_fcall_info fci;
                   3893:                zend_fcall_info_cache fcc;
                   3894: 
                   3895:                if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
                   3896:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
                   3897:                        return;
                   3898:                }
                   3899: 
                   3900:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
                   3901:                        if (params) {
                   3902:                                efree(params);
                   3903:                        }
                   3904:                        RETURN_FALSE;
                   3905:                }
                   3906: 
                   3907:                object_init_ex(return_value, ce);
                   3908: 
                   3909:                fci.size = sizeof(fci);
                   3910:                fci.function_table = EG(function_table);
                   3911:                fci.function_name = NULL;
                   3912:                fci.symbol_table = NULL;
                   3913:                fci.object_ptr = return_value;
                   3914:                fci.retval_ptr_ptr = &retval_ptr;
                   3915:                fci.param_count = num_args;
                   3916:                fci.params = params;
                   3917:                fci.no_separation = 1;
                   3918: 
                   3919:                fcc.initialized = 1;
                   3920:                fcc.function_handler = ce->constructor;
                   3921:                fcc.calling_scope = EG(scope);
                   3922:                fcc.called_scope = Z_OBJCE_P(return_value);
                   3923:                fcc.object_ptr = return_value;
                   3924: 
                   3925:                if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                   3926:                        if (params) {
                   3927:                                efree(params);
                   3928:                        }
                   3929:                        if (retval_ptr) {
                   3930:                                zval_ptr_dtor(&retval_ptr);
                   3931:                        }
                   3932:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
                   3933:                        RETURN_NULL();
                   3934:                }
                   3935:                if (retval_ptr) {
                   3936:                        zval_ptr_dtor(&retval_ptr);
                   3937:                }
                   3938:                if (params) {
                   3939:                        efree(params);
                   3940:                }
                   3941:        } else if (!ZEND_NUM_ARGS()) {
                   3942:                object_init_ex(return_value, ce);
                   3943:        } else {
                   3944:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
                   3945:        }
                   3946: }
                   3947: /* }}} */
                   3948: 
                   3949: /* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args])
                   3950:    Returns an instance of this class */
                   3951: ZEND_METHOD(reflection_class, newInstanceArgs)
                   3952: {
                   3953:        zval *retval_ptr = NULL;
                   3954:        reflection_object *intern;
                   3955:        zend_class_entry *ce;
                   3956:        int argc = 0;
                   3957:        HashTable *args;
                   3958:        
                   3959:        
                   3960:        METHOD_NOTSTATIC(reflection_class_ptr);
                   3961:        GET_REFLECTION_OBJECT_PTR(ce);
                   3962: 
                   3963:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
                   3964:                return;
                   3965:        }
                   3966:        if (ZEND_NUM_ARGS() > 0) {
                   3967:                argc = args->nNumOfElements;
                   3968:        }
                   3969:        
                   3970:        /* Run the constructor if there is one */
                   3971:        if (ce->constructor) {
                   3972:                zval ***params = NULL;
                   3973:                zend_fcall_info fci;
                   3974:                zend_fcall_info_cache fcc;
                   3975: 
                   3976:                if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
                   3977:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
                   3978:                        return;
                   3979:                }
                   3980:                
                   3981:                if (argc) {
                   3982:                        params = safe_emalloc(sizeof(zval **), argc, 0);
                   3983:                        zend_hash_apply_with_argument(args, (apply_func_arg_t)_zval_array_to_c_array, &params TSRMLS_CC);       
                   3984:                        params -= argc;
                   3985:                }
                   3986: 
                   3987:                object_init_ex(return_value, ce);
                   3988: 
                   3989:                fci.size = sizeof(fci);
                   3990:                fci.function_table = EG(function_table);
                   3991:                fci.function_name = NULL;
                   3992:                fci.symbol_table = NULL;
                   3993:                fci.object_ptr = return_value;
                   3994:                fci.retval_ptr_ptr = &retval_ptr;
                   3995:                fci.param_count = argc;
                   3996:                fci.params = params;
                   3997:                fci.no_separation = 1;
                   3998: 
                   3999:                fcc.initialized = 1;
                   4000:                fcc.function_handler = ce->constructor;
                   4001:                fcc.calling_scope = EG(scope);
                   4002:                fcc.called_scope = Z_OBJCE_P(return_value);
                   4003:                fcc.object_ptr = return_value;
                   4004: 
                   4005:                if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                   4006:                        if (params) {
                   4007:                                efree(params);
                   4008:                        }
                   4009:                        if (retval_ptr) {
                   4010:                                zval_ptr_dtor(&retval_ptr);
                   4011:                        }
                   4012:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
                   4013:                        RETURN_NULL();
                   4014:                }
                   4015:                if (retval_ptr) {
                   4016:                        zval_ptr_dtor(&retval_ptr);
                   4017:                }
                   4018:                if (params) {
                   4019:                        efree(params);
                   4020:                }
                   4021:        } else if (!ZEND_NUM_ARGS() || !argc) {
                   4022:                object_init_ex(return_value, ce);
                   4023:        } else {
                   4024:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
                   4025:        }
                   4026: }
                   4027: /* }}} */
                   4028: 
                   4029: /* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces()
                   4030:    Returns an array of interfaces this class implements */
                   4031: ZEND_METHOD(reflection_class, getInterfaces)
                   4032: {
                   4033:        reflection_object *intern;
                   4034:        zend_class_entry *ce;
                   4035: 
                   4036:        if (zend_parse_parameters_none() == FAILURE) {
                   4037:                return;
                   4038:        }
                   4039:        GET_REFLECTION_OBJECT_PTR(ce);
                   4040: 
                   4041:        /* Return an empty array if this class implements no interfaces */
                   4042:        array_init(return_value);
                   4043: 
                   4044:        if (ce->num_interfaces) {
                   4045:                zend_uint i;
                   4046: 
                   4047:                for (i=0; i < ce->num_interfaces; i++) {
                   4048:                        zval *interface;
                   4049:                        ALLOC_ZVAL(interface);
                   4050:                        zend_reflection_class_factory(ce->interfaces[i], interface TSRMLS_CC);
                   4051:                        add_assoc_zval_ex(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length + 1, interface);
                   4052:                }
                   4053:        }
                   4054: }
                   4055: /* }}} */
                   4056: 
                   4057: /* {{{ proto public String[] ReflectionClass::getInterfaceNames()
                   4058:    Returns an array of names of interfaces this class implements */
                   4059: ZEND_METHOD(reflection_class, getInterfaceNames)
                   4060: {
                   4061:        reflection_object *intern;
                   4062:        zend_class_entry *ce;
                   4063:        zend_uint i;
                   4064: 
                   4065:        if (zend_parse_parameters_none() == FAILURE) {
                   4066:                return;
                   4067:        }
                   4068:        GET_REFLECTION_OBJECT_PTR(ce);
                   4069: 
                   4070:        /* Return an empty array if this class implements no interfaces */
                   4071:        array_init(return_value);
                   4072: 
                   4073:        for (i=0; i < ce->num_interfaces; i++) {
                   4074:                add_next_index_stringl(return_value, ce->interfaces[i]->name, ce->interfaces[i]->name_length, 1);
                   4075:        }
                   4076: }
                   4077: /* }}} */
                   4078: 
                   4079: /* {{{ proto public ReflectionClass ReflectionClass::getParentClass()
                   4080:    Returns the class' parent class, or, if none exists, FALSE */
                   4081: ZEND_METHOD(reflection_class, getParentClass)
                   4082: {
                   4083:        reflection_object *intern;
                   4084:        zend_class_entry *ce;
                   4085: 
                   4086:        if (zend_parse_parameters_none() == FAILURE) {
                   4087:                return;
                   4088:        }
                   4089:        GET_REFLECTION_OBJECT_PTR(ce);
                   4090:        
                   4091:        if (ce->parent) {
                   4092:                zend_reflection_class_factory(ce->parent, return_value TSRMLS_CC);
                   4093:        } else {
                   4094:                RETURN_FALSE;
                   4095:        }
                   4096: }
                   4097: /* }}} */
                   4098: 
                   4099: /* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
                   4100:    Returns whether this class is a subclass of another class */
                   4101: ZEND_METHOD(reflection_class, isSubclassOf)
                   4102: {
                   4103:        reflection_object *intern, *argument;
                   4104:        zend_class_entry *ce, **pce, *class_ce;
                   4105:        zval *class_name;
                   4106: 
                   4107:        METHOD_NOTSTATIC(reflection_class_ptr);
                   4108:        GET_REFLECTION_OBJECT_PTR(ce);
                   4109: 
                   4110:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &class_name) == FAILURE) {
                   4111:                return;
                   4112:        }
                   4113:        
                   4114:        switch(class_name->type) {
                   4115:                case IS_STRING:
                   4116:                        if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
                   4117:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4118:                                                "Class %s does not exist", Z_STRVAL_P(class_name));
                   4119:                                return;
                   4120:                        }
                   4121:                        class_ce = *pce;
                   4122:                        break;                  
                   4123:                case IS_OBJECT:
                   4124:                        if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr TSRMLS_CC)) {
                   4125:                                argument = (reflection_object *) zend_object_store_get_object(class_name TSRMLS_CC);
                   4126:                                if (argument == NULL || argument->ptr == NULL) {
                   4127:                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
                   4128:                                        /* Bails out */
                   4129:                                }
                   4130:                                class_ce = argument->ptr;
                   4131:                                break;
                   4132:                        }
                   4133:                        /* no break */
                   4134:                default:
                   4135:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4136:                                        "Parameter one must either be a string or a ReflectionClass object");
                   4137:                        return;
                   4138:        }
                   4139: 
                   4140:        RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce TSRMLS_CC)));
                   4141: }
                   4142: /* }}} */
                   4143: 
                   4144: /* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
                   4145:    Returns whether this class is a subclass of another class */
                   4146: ZEND_METHOD(reflection_class, implementsInterface)
                   4147: {
                   4148:        reflection_object *intern, *argument;
                   4149:        zend_class_entry *ce, *interface_ce, **pce;
                   4150:        zval *interface;
                   4151: 
                   4152:        METHOD_NOTSTATIC(reflection_class_ptr);
                   4153:        GET_REFLECTION_OBJECT_PTR(ce);
                   4154: 
                   4155:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &interface) == FAILURE) {
                   4156:                return;
                   4157:        }
                   4158:        
                   4159:        switch(interface->type) {
                   4160:                case IS_STRING:
                   4161:                        if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
                   4162:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4163:                                                "Interface %s does not exist", Z_STRVAL_P(interface));
                   4164:                                return;
                   4165:                        }
                   4166:                        interface_ce = *pce;
                   4167:                        break;                  
                   4168:                case IS_OBJECT:
                   4169:                        if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr TSRMLS_CC)) {
                   4170:                                argument = (reflection_object *) zend_object_store_get_object(interface TSRMLS_CC);
                   4171:                                if (argument == NULL || argument->ptr == NULL) {
                   4172:                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the argument's reflection object");
                   4173:                                        /* Bails out */
                   4174:                                }
                   4175:                                interface_ce = argument->ptr;
                   4176:                                break;
                   4177:                        }
                   4178:                        /* no break */
                   4179:                default:
                   4180:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4181:                                        "Parameter one must either be a string or a ReflectionClass object");
                   4182:                        return;
                   4183:        }
                   4184: 
                   4185:        if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
                   4186:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4187:                                "Interface %s is a Class", interface_ce->name);
                   4188:                return;
                   4189:        }
                   4190:        RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
                   4191: }
                   4192: /* }}} */
                   4193: 
                   4194: /* {{{ proto public bool ReflectionClass::isIterateable()
                   4195:    Returns whether this class is iterateable (can be used inside foreach) */
                   4196: ZEND_METHOD(reflection_class, isIterateable)
                   4197: {
                   4198:        reflection_object *intern;
                   4199:        zend_class_entry *ce;
                   4200:        
                   4201:        if (zend_parse_parameters_none() == FAILURE) {
                   4202:                return;
                   4203:        }
                   4204: 
                   4205:        METHOD_NOTSTATIC(reflection_class_ptr);
                   4206:        GET_REFLECTION_OBJECT_PTR(ce);
                   4207: 
                   4208:        RETURN_BOOL(ce->get_iterator != NULL);
                   4209: }
                   4210: /* }}} */
                   4211: 
                   4212: /* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension()
                   4213:    Returns NULL or the extension the class belongs to */
                   4214: ZEND_METHOD(reflection_class, getExtension)
                   4215: {
                   4216:        reflection_object *intern;
                   4217:        zend_class_entry *ce;
                   4218:        
                   4219:        if (zend_parse_parameters_none() == FAILURE) {
                   4220:                return;
                   4221:        }
                   4222: 
                   4223:        METHOD_NOTSTATIC(reflection_class_ptr);
                   4224:        GET_REFLECTION_OBJECT_PTR(ce);
                   4225: 
                   4226:        if (ce->module) {
                   4227:                reflection_extension_factory(return_value, ce->module->name TSRMLS_CC);
                   4228:        }
                   4229: }
                   4230: /* }}} */
                   4231: 
                   4232: /* {{{ proto public string|false ReflectionClass::getExtensionName()
                   4233:    Returns false or the name of the extension the class belongs to */
                   4234: ZEND_METHOD(reflection_class, getExtensionName)
                   4235: {
                   4236:        reflection_object *intern;
                   4237:        zend_class_entry *ce;
                   4238:        
                   4239:        if (zend_parse_parameters_none() == FAILURE) {
                   4240:                return;
                   4241:        }
                   4242: 
                   4243:        METHOD_NOTSTATIC(reflection_class_ptr);
                   4244:        GET_REFLECTION_OBJECT_PTR(ce);
                   4245: 
                   4246:        if (ce->module) {
                   4247:                RETURN_STRING(ce->module->name, 1);
                   4248:        } else {
                   4249:                RETURN_FALSE;
                   4250:        }
                   4251: }
                   4252: /* }}} */
                   4253: 
                   4254: /* {{{ proto public bool ReflectionClass::inNamespace()
                   4255:    Returns whether this class is defined in namespace */
                   4256: ZEND_METHOD(reflection_class, inNamespace)
                   4257: {
                   4258:        zval **name;
                   4259:        char *colon;
                   4260: 
                   4261:        if (zend_parse_parameters_none() == FAILURE) {
                   4262:                return;
                   4263:        }
                   4264:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   4265:                RETURN_FALSE;
                   4266:        }
                   4267:        if (Z_TYPE_PP(name) == IS_STRING
                   4268:                && (colon = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   4269:                && colon > Z_STRVAL_PP(name))
                   4270:        {
                   4271:                RETURN_TRUE;
                   4272:        }
                   4273:        RETURN_FALSE;
                   4274: }
                   4275: /* }}} */
                   4276: 
                   4277: /* {{{ proto public string ReflectionClass::getNamespaceName()
                   4278:    Returns the name of namespace where this class is defined */
                   4279: ZEND_METHOD(reflection_class, getNamespaceName)
                   4280: {
                   4281:        zval **name;
                   4282:        char *backslash;
                   4283: 
                   4284:        if (zend_parse_parameters_none() == FAILURE) {
                   4285:                return;
                   4286:        }
                   4287:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   4288:                RETURN_FALSE;
                   4289:        }
                   4290:        if (Z_TYPE_PP(name) == IS_STRING
                   4291:                && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   4292:                && backslash > Z_STRVAL_PP(name))
                   4293:        {
                   4294:                RETURN_STRINGL(Z_STRVAL_PP(name), backslash - Z_STRVAL_PP(name), 1);
                   4295:        }
                   4296:        RETURN_EMPTY_STRING();
                   4297: }
                   4298: /* }}} */
                   4299: 
                   4300: /* {{{ proto public string ReflectionClass::getShortName()
                   4301:    Returns the short name of the class (without namespace part) */
                   4302: ZEND_METHOD(reflection_class, getShortName)
                   4303: {
                   4304:        zval **name;
                   4305:        char *backslash;
                   4306: 
                   4307:        if (zend_parse_parameters_none() == FAILURE) {
                   4308:                return;
                   4309:        }
                   4310:        if (zend_hash_find(Z_OBJPROP_P(getThis()), "name", sizeof("name"), (void **) &name) == FAILURE) {
                   4311:                RETURN_FALSE;
                   4312:        }
                   4313:        if (Z_TYPE_PP(name) == IS_STRING
                   4314:                && (backslash = zend_memrchr(Z_STRVAL_PP(name), '\\', Z_STRLEN_PP(name)))
                   4315:                && backslash > Z_STRVAL_PP(name))
                   4316:        {
                   4317:                RETURN_STRINGL(backslash + 1, Z_STRLEN_PP(name) - (backslash - Z_STRVAL_PP(name) + 1), 1);
                   4318:        }
                   4319:        RETURN_ZVAL(*name, 1, 0);
                   4320: }
                   4321: /* }}} */
                   4322: 
                   4323: /* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException
                   4324:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   4325: ZEND_METHOD(reflection_object, export)
                   4326: {
                   4327:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
                   4328: }
                   4329: /* }}} */
                   4330: 
                   4331: /* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException
                   4332:    Constructor. Takes an instance as an argument */
                   4333: ZEND_METHOD(reflection_object, __construct)
                   4334: {
                   4335:        reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
                   4336: }
                   4337: /* }}} */
                   4338: 
                   4339: /* {{{ proto public static mixed ReflectionProperty::export(mixed class, string name [, bool return]) throws ReflectionException
                   4340:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   4341: ZEND_METHOD(reflection_property, export)
                   4342: {
                   4343:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
                   4344: }
                   4345: /* }}} */
                   4346: 
                   4347: /* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
                   4348:    Constructor. Throws an Exception in case the given property does not exist */
                   4349: ZEND_METHOD(reflection_property, __construct)
                   4350: {
                   4351:        zval *propname, *classname;
                   4352:        char *name_str, *class_name, *prop_name;
                   4353:        int name_len, dynam_prop = 0;
                   4354:        zval *object;
                   4355:        reflection_object *intern;
                   4356:        zend_class_entry **pce;
                   4357:        zend_class_entry *ce;
                   4358:        zend_property_info *property_info = NULL;
                   4359:        property_reference *reference;
                   4360: 
                   4361:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
                   4362:                return;
                   4363:        }
                   4364: 
                   4365:        object = getThis();
                   4366:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   4367:        if (intern == NULL) {
                   4368:                return;
                   4369:        }
                   4370:        
                   4371:        /* Find the class entry */
                   4372:        switch (Z_TYPE_P(classname)) {
                   4373:                case IS_STRING:
                   4374:                        if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
                   4375:                                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                   4376:                                                "Class %s does not exist", Z_STRVAL_P(classname)); 
                   4377:                                return;
                   4378:                        }
                   4379:                        ce = *pce;
                   4380:                        break;
                   4381: 
                   4382:                case IS_OBJECT:
                   4383:                        ce = Z_OBJCE_P(classname);
                   4384:                        break;
                   4385:                        
                   4386:                default:
                   4387:                        _DO_THROW("The parameter class is expected to be either a string or an object");
                   4388:                        /* returns out of this function */
                   4389:        }
                   4390: 
                   4391:        if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
                   4392:                /* Check for dynamic properties */
                   4393:                if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
                   4394:                        if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname TSRMLS_CC), name_str, name_len+1)) {
                   4395:                                dynam_prop = 1;
                   4396:                        }
                   4397:                }
                   4398:                if (dynam_prop == 0) {
                   4399:                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Property %s::$%s does not exist", ce->name, name_str);
                   4400:                        return;
                   4401:                }
                   4402:        }
                   4403:        
                   4404:        if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) {
                   4405:                /* we have to search the class hierarchy for this (implicit) public or protected property */
                   4406:                zend_class_entry *tmp_ce = ce;
                   4407:                zend_property_info *tmp_info;
                   4408:                
                   4409:                while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, name_str, name_len + 1, (void **) &tmp_info) != SUCCESS) {
                   4410:                        ce = tmp_ce;
                   4411:                        property_info = tmp_info;
                   4412:                        tmp_ce = tmp_ce->parent;
                   4413:                }
                   4414:        }
                   4415: 
                   4416:        MAKE_STD_ZVAL(classname);       
                   4417:        MAKE_STD_ZVAL(propname);
                   4418:        
                   4419:        if (dynam_prop == 0) {
                   4420:                zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
                   4421:                ZVAL_STRINGL(classname, property_info->ce->name, property_info->ce->name_length, 1);
                   4422:                ZVAL_STRING(propname, prop_name, 1);
                   4423:        } else {
                   4424:                ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);  
                   4425:                ZVAL_STRINGL(propname, name_str, name_len, 1);
                   4426:        }
                   4427:        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
                   4428:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);
                   4429: 
                   4430:        reference = (property_reference*) emalloc(sizeof(property_reference));
                   4431:        if (dynam_prop) {
                   4432:                reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
                   4433:                reference->prop.name = Z_STRVAL_P(propname);
                   4434:                reference->prop.name_length = Z_STRLEN_P(propname);
                   4435:                reference->prop.h = zend_get_hash_value(name_str, name_len+1);
                   4436:                reference->prop.doc_comment = NULL;
                   4437:                reference->prop.ce = ce;
                   4438:        } else {
                   4439:                reference->prop = *property_info;
                   4440:        }
                   4441:        reference->ce = ce;
                   4442:        intern->ptr = reference;
                   4443:        intern->ref_type = REF_TYPE_PROPERTY;
                   4444:        intern->ce = ce;
                   4445:        intern->ignore_visibility = 0;
                   4446: }
                   4447: /* }}} */
                   4448: 
                   4449: /* {{{ proto public string ReflectionProperty::__toString()
                   4450:    Returns a string representation */
                   4451: ZEND_METHOD(reflection_property, __toString)
                   4452: {
                   4453:        reflection_object *intern;
                   4454:        property_reference *ref;
                   4455:        string str;
                   4456: 
                   4457:        if (zend_parse_parameters_none() == FAILURE) {
                   4458:                return;
                   4459:        }
                   4460:        GET_REFLECTION_OBJECT_PTR(ref);
                   4461:        string_init(&str);
                   4462:        _property_string(&str, &ref->prop, NULL, "" TSRMLS_CC);
                   4463:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   4464: }
                   4465: /* }}} */
                   4466: 
                   4467: /* {{{ proto public string ReflectionProperty::getName()
                   4468:    Returns the class' name */
                   4469: ZEND_METHOD(reflection_property, getName)
                   4470: {
                   4471:        if (zend_parse_parameters_none() == FAILURE) {
                   4472:                return;
                   4473:        }
                   4474:        _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
                   4475: }
                   4476: /* }}} */
                   4477: 
                   4478: static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
                   4479: {
                   4480:        reflection_object *intern;
                   4481:        property_reference *ref;
                   4482: 
                   4483:        if (zend_parse_parameters_none() == FAILURE) {
                   4484:                return;
                   4485:        }
                   4486:        GET_REFLECTION_OBJECT_PTR(ref);
                   4487:        RETURN_BOOL(ref->prop.flags & mask);
                   4488: }
                   4489: 
                   4490: /* {{{ proto public bool ReflectionProperty::isPublic()
                   4491:    Returns whether this property is public */
                   4492: ZEND_METHOD(reflection_property, isPublic)
                   4493: {
                   4494:        _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
                   4495: }
                   4496: /* }}} */
                   4497: 
                   4498: /* {{{ proto public bool ReflectionProperty::isPrivate()
                   4499:    Returns whether this property is private */
                   4500: ZEND_METHOD(reflection_property, isPrivate)
                   4501: {
                   4502:        _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
                   4503: }
                   4504: /* }}} */
                   4505: 
                   4506: /* {{{ proto public bool ReflectionProperty::isProtected()
                   4507:    Returns whether this property is protected */
                   4508: ZEND_METHOD(reflection_property, isProtected)
                   4509: {
                   4510:        _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
                   4511: }
                   4512: /* }}} */
                   4513: 
                   4514: /* {{{ proto public bool ReflectionProperty::isStatic()
                   4515:    Returns whether this property is static */
                   4516: ZEND_METHOD(reflection_property, isStatic)
                   4517: {
                   4518:        _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
                   4519: }
                   4520: /* }}} */
                   4521: 
                   4522: /* {{{ proto public bool ReflectionProperty::isDefault()
                   4523:    Returns whether this property is default (declared at compilation time). */
                   4524: ZEND_METHOD(reflection_property, isDefault)
                   4525: {
                   4526:        _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
                   4527: }
                   4528: /* }}} */
                   4529: 
                   4530: /* {{{ proto public int ReflectionProperty::getModifiers()
                   4531:    Returns a bitfield of the access modifiers for this property */
                   4532: ZEND_METHOD(reflection_property, getModifiers)
                   4533: {
                   4534:        reflection_object *intern;
                   4535:        property_reference *ref;
                   4536: 
                   4537:        if (zend_parse_parameters_none() == FAILURE) {
                   4538:                return;
                   4539:        }
                   4540:        GET_REFLECTION_OBJECT_PTR(ref);
                   4541: 
                   4542:        RETURN_LONG(ref->prop.flags);
                   4543: }
                   4544: /* }}} */
                   4545: 
                   4546: /* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
                   4547:    Returns this property's value */
                   4548: ZEND_METHOD(reflection_property, getValue)
                   4549: {
                   4550:        reflection_object *intern;
                   4551:        property_reference *ref;
                   4552:        zval *object, name;
                   4553:        zval **member = NULL, *member_p = NULL;
                   4554: 
                   4555:        METHOD_NOTSTATIC(reflection_property_ptr);
                   4556:        GET_REFLECTION_OBJECT_PTR(ref);
                   4557: 
                   4558:        if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
                   4559:                _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
                   4560:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4561:                        "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
                   4562:                zval_dtor(&name);
                   4563:                return;
                   4564:        }
                   4565: 
                   4566:        if ((ref->prop.flags & ZEND_ACC_STATIC)) {
                   4567:                zend_update_class_constants(intern->ce TSRMLS_CC);
                   4568:                if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &member) == FAILURE) {
                   4569:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
                   4570:                        /* Bails out */
                   4571:                }
                   4572:                MAKE_COPY_ZVAL(member, return_value);
                   4573:        } else {
                   4574:                char *class_name, *prop_name;
                   4575:                
                   4576:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
                   4577:                        return;
                   4578:                }
                   4579:                zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
                   4580:                member_p = zend_read_property(ref->ce, object, prop_name, strlen(prop_name), 1 TSRMLS_CC);
                   4581:                MAKE_COPY_ZVAL(&member_p, return_value);
                   4582:                if (member_p != EG(uninitialized_zval_ptr)) {
                   4583:                        zval_add_ref(&member_p);
                   4584:                        zval_ptr_dtor(&member_p);
                   4585:                }
                   4586:        }
                   4587: }
                   4588: /* }}} */
                   4589: 
                   4590: /* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
                   4591:    Sets this property's value */
                   4592: ZEND_METHOD(reflection_property, setValue)
                   4593: {
                   4594:        reflection_object *intern;
                   4595:        property_reference *ref;
                   4596:        zval **variable_ptr;
                   4597:        zval *object, name;
                   4598:        zval *value;
                   4599:        int setter_done = 0;
                   4600:        zval *tmp;
                   4601:        HashTable *prop_table;
                   4602: 
                   4603:        METHOD_NOTSTATIC(reflection_property_ptr);
                   4604:        GET_REFLECTION_OBJECT_PTR(ref);
                   4605: 
                   4606:        if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
                   4607:                _default_get_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
                   4608:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4609:                        "Cannot access non-public member %s::%s", intern->ce->name, Z_STRVAL(name));
                   4610:                zval_dtor(&name);
                   4611:                return;
                   4612:        }
                   4613: 
                   4614:        if ((ref->prop.flags & ZEND_ACC_STATIC)) {
                   4615:                if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
                   4616:                        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &tmp, &value) == FAILURE) {
                   4617:                                return;
                   4618:                        }
                   4619:                }
                   4620:                zend_update_class_constants(intern->ce TSRMLS_CC);
                   4621:                prop_table = CE_STATIC_MEMBERS(intern->ce);
                   4622: 
                   4623:                if (zend_hash_quick_find(prop_table, ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &variable_ptr) == FAILURE) {
                   4624:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name);
                   4625:                        /* Bails out */
                   4626:                }
                   4627:                if (*variable_ptr == value) {
                   4628:                        setter_done = 1;
                   4629:                } else {
                   4630:                        if (PZVAL_IS_REF(*variable_ptr)) {
                   4631:                                zval_dtor(*variable_ptr);
                   4632:                                (*variable_ptr)->type = value->type;
                   4633:                                (*variable_ptr)->value = value->value;
                   4634:                                if (Z_REFCOUNT_P(value) > 0) {
                   4635:                                        zval_copy_ctor(*variable_ptr);
                   4636:                                }
                   4637:                                setter_done = 1;
                   4638:                        }
                   4639:                }
                   4640:                if (!setter_done) {
                   4641:                        zval **foo;
                   4642: 
                   4643:                        Z_ADDREF_P(value);
                   4644:                        if (PZVAL_IS_REF(value)) {
                   4645:                                SEPARATE_ZVAL(&value);
                   4646:                        }
                   4647:                        zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo);
                   4648:                }
                   4649:        } else {
                   4650:                char *class_name, *prop_name;
                   4651: 
                   4652:                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
                   4653:                        return;
                   4654:                }
                   4655:                zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name);
                   4656:                zend_update_property(ref->ce, object, prop_name, strlen(prop_name), value TSRMLS_CC);
                   4657:        }
                   4658: }
                   4659: /* }}} */
                   4660: 
                   4661: /* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass()
                   4662:    Get the declaring class */
                   4663: ZEND_METHOD(reflection_property, getDeclaringClass)
                   4664: {
                   4665:        reflection_object *intern;
                   4666:        property_reference *ref;
                   4667:        zend_class_entry *tmp_ce, *ce;
                   4668:        zend_property_info *tmp_info;
                   4669:        char *prop_name, *class_name;
                   4670:        int prop_name_len;
                   4671: 
                   4672:        if (zend_parse_parameters_none() == FAILURE) {
                   4673:                return;
                   4674:        }
                   4675:        GET_REFLECTION_OBJECT_PTR(ref);
                   4676: 
                   4677:        if (zend_unmangle_property_name(ref->prop.name, ref->prop.name_length, &class_name, &prop_name) != SUCCESS) {
                   4678:                RETURN_FALSE;
                   4679:        }
                   4680: 
                   4681:        prop_name_len = strlen(prop_name);
                   4682:        ce = tmp_ce = ref->ce;
                   4683:        while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, prop_name_len + 1, (void **) &tmp_info) == SUCCESS) {
                   4684:                if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
                   4685:                        /* it's a private property, so it can't be inherited */
                   4686:                        break;
                   4687:                }
                   4688:                ce = tmp_ce;
                   4689:                if (tmp_ce == tmp_info->ce) {
                   4690:                        /* declared in this class, done */
                   4691:                        break;
                   4692:                }
                   4693:                tmp_ce = tmp_ce->parent;
                   4694:        }
                   4695: 
                   4696:        zend_reflection_class_factory(ce, return_value TSRMLS_CC);
                   4697: }
                   4698: /* }}} */
                   4699: 
                   4700: /* {{{ proto public string ReflectionProperty::getDocComment()
                   4701:    Returns the doc comment for this property */
                   4702: ZEND_METHOD(reflection_property, getDocComment)
                   4703: {
                   4704:        reflection_object *intern;
                   4705:        property_reference *ref;
                   4706: 
                   4707:        if (zend_parse_parameters_none() == FAILURE) {
                   4708:                return;
                   4709:        }
                   4710:        GET_REFLECTION_OBJECT_PTR(ref);
                   4711:        if (ref->prop.doc_comment) {
                   4712:                RETURN_STRINGL(ref->prop.doc_comment, ref->prop.doc_comment_len, 1);
                   4713:        }
                   4714:        RETURN_FALSE;
                   4715: }
                   4716: /* }}} */
                   4717: 
                   4718: /* {{{ proto public int ReflectionProperty::setAccessible(bool visible)
                   4719:    Sets whether non-public properties can be requested */
                   4720: ZEND_METHOD(reflection_property, setAccessible)
                   4721: {
                   4722:        reflection_object *intern;
                   4723:        zend_bool visible;
                   4724: 
                   4725:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &visible) == FAILURE) {
                   4726:                return;
                   4727:        }
                   4728: 
                   4729:        intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
                   4730: 
                   4731:        if (intern == NULL) {
                   4732:                return;
                   4733:        }
                   4734: 
                   4735:        intern->ignore_visibility = visible;
                   4736: }
                   4737: /* }}} */
                   4738: 
                   4739: /* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
                   4740:    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
                   4741: ZEND_METHOD(reflection_extension, export)
                   4742: {
                   4743:        _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
                   4744: }
                   4745: /* }}} */
                   4746: 
                   4747: /* {{{ proto public void ReflectionExtension::__construct(string name)
                   4748:    Constructor. Throws an Exception in case the given extension does not exist */
                   4749: ZEND_METHOD(reflection_extension, __construct)
                   4750: {
                   4751:        zval *name;
                   4752:        zval *object;
                   4753:        char *lcname;
                   4754:        reflection_object *intern;
                   4755:        zend_module_entry *module;
                   4756:        char *name_str;
                   4757:        int name_len;
                   4758:        ALLOCA_FLAG(use_heap)
                   4759: 
                   4760:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
                   4761:                return;
                   4762:        }
                   4763: 
                   4764:        object = getThis();
                   4765:        intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
                   4766:        if (intern == NULL) {
                   4767:                return;
                   4768:        }
                   4769:        lcname = do_alloca(name_len + 1, use_heap);
                   4770:        zend_str_tolower_copy(lcname, name_str, name_len);
                   4771:        if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
                   4772:                free_alloca(lcname, use_heap);
                   4773:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   4774:                        "Extension %s does not exist", name_str);
                   4775:                return;
                   4776:        }
                   4777:        free_alloca(lcname, use_heap);
                   4778:        MAKE_STD_ZVAL(name);
                   4779:        ZVAL_STRING(name, module->name, 1);
                   4780:        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
                   4781:        intern->ptr = module;
                   4782:        intern->ref_type = REF_TYPE_OTHER;
                   4783:        intern->ce = NULL;
                   4784: }
                   4785: /* }}} */
                   4786: 
                   4787: /* {{{ proto public string ReflectionExtension::__toString()
                   4788:    Returns a string representation */
                   4789: ZEND_METHOD(reflection_extension, __toString)
                   4790: {
                   4791:        reflection_object *intern;
                   4792:        zend_module_entry *module;
                   4793:        string str;
                   4794: 
                   4795:        if (zend_parse_parameters_none() == FAILURE) {
                   4796:                return;
                   4797:        }
                   4798:        GET_REFLECTION_OBJECT_PTR(module);
                   4799:        string_init(&str);
                   4800:        _extension_string(&str, module, "" TSRMLS_CC);
                   4801:        RETURN_STRINGL(str.string, str.len - 1, 0);
                   4802: }
                   4803: /* }}} */
                   4804: 
                   4805: /* {{{ proto public string ReflectionExtension::getName()
                   4806:    Returns this extension's name */
                   4807: ZEND_METHOD(reflection_extension, getName)
                   4808: {
                   4809:        if (zend_parse_parameters_none() == FAILURE) {
                   4810:                return;
                   4811:        }
                   4812:        _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
                   4813: }
                   4814: /* }}} */
                   4815: 
                   4816: /* {{{ proto public string ReflectionExtension::getVersion()
                   4817:    Returns this extension's version */
                   4818: ZEND_METHOD(reflection_extension, getVersion)
                   4819: {
                   4820:        reflection_object *intern;
                   4821:        zend_module_entry *module;
                   4822: 
                   4823:        if (zend_parse_parameters_none() == FAILURE) {
                   4824:                return;
                   4825:        }
                   4826:        GET_REFLECTION_OBJECT_PTR(module);
                   4827: 
                   4828:        /* An extension does not necessarily have a version number */
                   4829:        if (module->version == NO_VERSION_YET) {
                   4830:                RETURN_NULL();
                   4831:        } else {
                   4832:                RETURN_STRING(module->version, 1);
                   4833:        }
                   4834: }
                   4835: /* }}} */
                   4836: 
                   4837: /* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions()
                   4838:    Returns an array of this extension's fuctions */
                   4839: ZEND_METHOD(reflection_extension, getFunctions)
                   4840: {
                   4841:        reflection_object *intern;
                   4842:        zend_module_entry *module;
                   4843: 
                   4844:        if (zend_parse_parameters_none() == FAILURE) {
                   4845:                return;
                   4846:        }
                   4847:        GET_REFLECTION_OBJECT_PTR(module);
                   4848: 
                   4849:        array_init(return_value);
                   4850:        if (module->functions) {
                   4851:                zval *function;
                   4852:                zend_function *fptr;
                   4853:                const zend_function_entry *func = module->functions;
                   4854: 
                   4855:                /* Is there a better way of doing this? */
                   4856:                while (func->fname) {
                   4857:                        int fname_len = strlen(func->fname);
                   4858:                        char *lc_name = zend_str_tolower_dup(func->fname, fname_len);
                   4859:                        
                   4860:                        if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) {
                   4861:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
                   4862:                                func++;
                   4863:                                efree(lc_name);
                   4864:                                continue;
                   4865:                        }
                   4866:                        
                   4867:                        ALLOC_ZVAL(function);
                   4868:                        reflection_function_factory(fptr, NULL, function TSRMLS_CC);
                   4869:                        add_assoc_zval_ex(return_value, func->fname, fname_len+1, function);
                   4870:                        func++;
                   4871:                        efree(lc_name);
                   4872:                }
                   4873:        }
                   4874: }
                   4875: /* }}} */
                   4876: 
                   4877: static int _addconstant(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   4878: {
                   4879:        zval *const_val;
                   4880:        zval *retval = va_arg(args, zval*);
                   4881:        int number = va_arg(args, int);
                   4882: 
                   4883:        if (number == constant->module_number) {
                   4884:                ALLOC_ZVAL(const_val);
                   4885:                *const_val = constant->value;
                   4886:                zval_copy_ctor(const_val);
                   4887:                INIT_PZVAL(const_val);
                   4888:                add_assoc_zval_ex(retval, constant->name, constant->name_len, const_val);
                   4889:        }
                   4890:        return 0;
                   4891: }
                   4892: 
                   4893: /* {{{ proto public array ReflectionExtension::getConstants()
                   4894:    Returns an associative array containing this extension's constants and their values */
                   4895: ZEND_METHOD(reflection_extension, getConstants)
                   4896: {
                   4897:        reflection_object *intern;
                   4898:        zend_module_entry *module;
                   4899: 
                   4900:        if (zend_parse_parameters_none() == FAILURE) {
                   4901:                return;
                   4902:        }
                   4903:        GET_REFLECTION_OBJECT_PTR(module);
                   4904: 
                   4905:        array_init(return_value);
                   4906:        zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
                   4907: }
                   4908: /* }}} */
                   4909: 
                   4910: /* {{{ _addinientry */
                   4911: static int _addinientry(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   4912: {
                   4913:        zval *retval = va_arg(args, zval*);
                   4914:        int number = va_arg(args, int);
                   4915: 
                   4916:        if (number == ini_entry->module_number) {
                   4917:                if (ini_entry->value) {
                   4918:                        add_assoc_stringl(retval, ini_entry->name, ini_entry->value, ini_entry->value_length, 1);
                   4919:                } else {
                   4920:                        add_assoc_null(retval, ini_entry->name);
                   4921:                }
                   4922:        }
                   4923:        return ZEND_HASH_APPLY_KEEP;
                   4924: }
                   4925: /* }}} */
                   4926: 
                   4927: /* {{{ proto public array ReflectionExtension::getINIEntries()
                   4928:    Returns an associative array containing this extension's INI entries and their values */
                   4929: ZEND_METHOD(reflection_extension, getINIEntries)
                   4930: {
                   4931:        reflection_object *intern;
                   4932:        zend_module_entry *module;
                   4933: 
                   4934:        if (zend_parse_parameters_none() == FAILURE) {
                   4935:                return;
                   4936:        }
                   4937:        GET_REFLECTION_OBJECT_PTR(module);
                   4938: 
                   4939:        array_init(return_value);
                   4940:        zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
                   4941: }
                   4942: /* }}} */
                   4943: 
                   4944: /* {{{ add_extension_class */
                   4945: static int add_extension_class(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
                   4946: {
                   4947:        zval *class_array = va_arg(args, zval*), *zclass;
                   4948:        struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
                   4949:        int add_reflection_class = va_arg(args, int);
                   4950: 
                   4951:        if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
                   4952:                if (add_reflection_class) {
                   4953:                        ALLOC_ZVAL(zclass);
                   4954:                        zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
                   4955:                        add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass);
                   4956:                } else {
                   4957:                        add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1);
                   4958:                }
                   4959:        }
                   4960:        return ZEND_HASH_APPLY_KEEP;
                   4961: }
                   4962: /* }}} */
                   4963: 
                   4964: /* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses()
                   4965:    Returns an array containing ReflectionClass objects for all classes of this extension */
                   4966: ZEND_METHOD(reflection_extension, getClasses)
                   4967: {
                   4968:        reflection_object *intern;
                   4969:        zend_module_entry *module;
                   4970: 
                   4971:        if (zend_parse_parameters_none() == FAILURE) {
                   4972:                return;
                   4973:        }
                   4974:        GET_REFLECTION_OBJECT_PTR(module);
                   4975: 
                   4976:        array_init(return_value);
                   4977:        zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 1);
                   4978: }
                   4979: /* }}} */
                   4980: 
                   4981: /* {{{ proto public array ReflectionExtension::getClassNames()
                   4982:    Returns an array containing all names of all classes of this extension */
                   4983: ZEND_METHOD(reflection_extension, getClassNames)
                   4984: {
                   4985:        reflection_object *intern;
                   4986:        zend_module_entry *module;
                   4987: 
                   4988:        if (zend_parse_parameters_none() == FAILURE) {
                   4989:                return;
                   4990:        }
                   4991:        GET_REFLECTION_OBJECT_PTR(module);
                   4992: 
                   4993:        array_init(return_value);
                   4994:        zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) add_extension_class, 3, return_value, module, 0);
                   4995: }
                   4996: /* }}} */
                   4997: 
                   4998: /* {{{ proto public array ReflectionExtension::getDependencies()
                   4999:    Returns an array containing all names of all extensions this extension depends on */
                   5000: ZEND_METHOD(reflection_extension, getDependencies)
                   5001: {
                   5002:        reflection_object *intern;
                   5003:        zend_module_entry *module;
                   5004:        const zend_module_dep *dep;
                   5005: 
                   5006:        if (zend_parse_parameters_none() == FAILURE) {
                   5007:                return;
                   5008:        }
                   5009:        GET_REFLECTION_OBJECT_PTR(module);
                   5010:        
                   5011:        array_init(return_value);
                   5012: 
                   5013:        dep = module->deps;
                   5014:        
                   5015:        if (!dep)
                   5016:        {
                   5017:                return;
                   5018:        }
                   5019: 
                   5020:        while(dep->name) {
                   5021:                char *relation;
                   5022:                char *rel_type;
                   5023:                int len;
                   5024:                
                   5025:                switch(dep->type) {
                   5026:                case MODULE_DEP_REQUIRED:
                   5027:                        rel_type = "Required";
                   5028:                        break;
                   5029:                case MODULE_DEP_CONFLICTS:
                   5030:                        rel_type = "Conflicts";
                   5031:                        break;
                   5032:                case MODULE_DEP_OPTIONAL:
                   5033:                        rel_type = "Optional";
                   5034:                        break;
                   5035:                default:
                   5036:                        rel_type = "Error"; /* shouldn't happen */
                   5037:                        break;
                   5038:                }
                   5039: 
                   5040:                len = spprintf(&relation, 0, "%s%s%s%s%s", 
                   5041:                                                rel_type,
                   5042:                                                dep->rel ? " " : "",
                   5043:                                                dep->rel ? dep->rel : "", 
                   5044:                                                dep->version ? " " : "",
                   5045:                                                dep->version ? dep->version : "");
                   5046:                add_assoc_stringl(return_value, dep->name, relation, len, 0);
                   5047:                dep++;
                   5048:        }
                   5049: }
                   5050: /* }}} */
                   5051: 
                   5052: /* {{{ proto public void ReflectionExtension::info() U
                   5053:        Prints phpinfo block for the extension */
                   5054: ZEND_METHOD(reflection_extension, info)
                   5055: {
                   5056:        reflection_object *intern;
                   5057:        zend_module_entry *module;
                   5058: 
                   5059:        if (zend_parse_parameters_none() == FAILURE) {
                   5060:                return;
                   5061:        }
                   5062:        GET_REFLECTION_OBJECT_PTR(module);
                   5063: 
                   5064:        php_info_print_module(module TSRMLS_CC);
                   5065: }
                   5066: /* }}} */
                   5067: 
                   5068: /* {{{ method tables */
                   5069: static const zend_function_entry reflection_exception_functions[] = {
                   5070:        PHP_FE_END
                   5071: };
                   5072: 
                   5073: ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0)
                   5074: ZEND_END_ARG_INFO()
                   5075: 
                   5076: 
                   5077: ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
                   5078:        ZEND_ARG_INFO(0, modifiers)
                   5079: ZEND_END_ARG_INFO()
                   5080: 
                   5081: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
                   5082:        ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
                   5083:        ZEND_ARG_INFO(0, return)
                   5084: ZEND_END_ARG_INFO()
                   5085: 
                   5086: static const zend_function_entry reflection_functions[] = {
                   5087:        ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
                   5088:        ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
                   5089:        PHP_FE_END
                   5090: };
                   5091: 
                   5092: static const zend_function_entry reflector_functions[] = {
                   5093:        ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
                   5094:        ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void)
                   5095:        PHP_FE_END
                   5096: };
                   5097: 
                   5098: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
                   5099:        ZEND_ARG_INFO(0, name)
                   5100:        ZEND_ARG_INFO(0, return)
                   5101: ZEND_END_ARG_INFO()
                   5102: 
                   5103: ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
                   5104:        ZEND_ARG_INFO(0, name)
                   5105: ZEND_END_ARG_INFO()
                   5106: 
                   5107: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
                   5108:        ZEND_ARG_INFO(0, args)
                   5109: ZEND_END_ARG_INFO()
                   5110: 
                   5111: ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
                   5112:        ZEND_ARG_ARRAY_INFO(0, args, 0)
                   5113: ZEND_END_ARG_INFO()
                   5114: 
                   5115: static const zend_function_entry reflection_function_abstract_functions[] = {
                   5116:        ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
                   5117:        PHP_ABSTRACT_ME(reflection_function, __toString, arginfo_reflection__void)
                   5118:        ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0)
                   5119:        ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0)
                   5120:        ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
                   5121:        ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
                   5122:        ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
                   5123:        ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
                   5124:        ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0)
                   5125:        ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0)
                   5126:        ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0)
                   5127:        ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0)
                   5128:        ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0)
                   5129:        ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0)
                   5130:        ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0)
                   5131:        ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0)
                   5132:        ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0)
                   5133:        ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0)
                   5134:        ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0)
                   5135:        ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0)
                   5136:        ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0)
                   5137:        PHP_FE_END
                   5138: };
                   5139: 
                   5140: static const zend_function_entry reflection_function_functions[] = {
                   5141:        ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
                   5142:        ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0)
                   5143:        ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5144:        ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0)
                   5145:        ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
                   5146:        ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
                   5147:        PHP_FE_END
                   5148: };
                   5149: 
                   5150: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
                   5151:        ZEND_ARG_INFO(0, class)
                   5152:        ZEND_ARG_INFO(0, name)
                   5153:        ZEND_ARG_INFO(0, return)
                   5154: ZEND_END_ARG_INFO()
                   5155: 
                   5156: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
                   5157:        ZEND_ARG_INFO(0, class_or_method)
                   5158:        ZEND_ARG_INFO(0, name)
                   5159: ZEND_END_ARG_INFO()
                   5160: 
                   5161: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
                   5162:        ZEND_ARG_INFO(0, object)
                   5163:        ZEND_ARG_INFO(0, args)
                   5164: ZEND_END_ARG_INFO()
                   5165: 
                   5166: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
                   5167:        ZEND_ARG_INFO(0, object)
                   5168:        ZEND_ARG_ARRAY_INFO(0, args, 0)
                   5169: ZEND_END_ARG_INFO()
                   5170: 
                   5171: ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
                   5172:        ZEND_ARG_INFO(0, value)
                   5173: ZEND_END_ARG_INFO()
                   5174: 
                   5175: static const zend_function_entry reflection_method_functions[] = {
                   5176:        ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5177:        ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
                   5178:        ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0)
                   5179:        ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0)
                   5180:        ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0)
                   5181:        ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
                   5182:        ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
                   5183:        ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
                   5184:        ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
                   5185:        ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
                   5186:        ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
                   5187:        ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0)
                   5188:        ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
                   5189:        ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
                   5190:        ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0)
                   5191:        ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0)
                   5192:        ZEND_ME(reflection_property, setAccessible, arginfo_reflection_method_setAccessible, 0)
                   5193:        PHP_FE_END
                   5194: };
                   5195: 
                   5196: 
                   5197: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
                   5198:        ZEND_ARG_INFO(0, argument)
                   5199:        ZEND_ARG_INFO(0, return)
                   5200: ZEND_END_ARG_INFO()
                   5201: 
                   5202: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
                   5203:        ZEND_ARG_INFO(0, argument)
                   5204: ZEND_END_ARG_INFO()
                   5205: 
                   5206: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
                   5207:        ZEND_ARG_INFO(0, name)
                   5208:        ZEND_ARG_INFO(0, default)
                   5209: ZEND_END_ARG_INFO()
                   5210: 
                   5211: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
                   5212:        ZEND_ARG_INFO(0, name)
                   5213:        ZEND_ARG_INFO(0, value)
                   5214: ZEND_END_ARG_INFO()
                   5215: 
                   5216: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
                   5217:        ZEND_ARG_INFO(0, name)
                   5218: ZEND_END_ARG_INFO()
                   5219: 
                   5220: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
                   5221:        ZEND_ARG_INFO(0, name)
                   5222: ZEND_END_ARG_INFO()
                   5223: 
                   5224: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
                   5225:        ZEND_ARG_INFO(0, filter)
                   5226: ZEND_END_ARG_INFO()
                   5227: 
                   5228: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
                   5229:        ZEND_ARG_INFO(0, name)
                   5230: ZEND_END_ARG_INFO()
                   5231: 
                   5232: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
                   5233:        ZEND_ARG_INFO(0, name)
                   5234: ZEND_END_ARG_INFO()
                   5235: 
                   5236: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
                   5237:        ZEND_ARG_INFO(0, filter)
                   5238: ZEND_END_ARG_INFO()
                   5239: 
                   5240: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
                   5241:        ZEND_ARG_INFO(0, name)
                   5242: ZEND_END_ARG_INFO()
                   5243: 
                   5244: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
                   5245:        ZEND_ARG_INFO(0, name)
                   5246: ZEND_END_ARG_INFO()
                   5247: 
                   5248: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
                   5249:        ZEND_ARG_INFO(0, object)
                   5250: ZEND_END_ARG_INFO()
                   5251: 
                   5252: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
                   5253:        ZEND_ARG_INFO(0, args)
                   5254: ZEND_END_ARG_INFO()
                   5255: 
                   5256: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
                   5257:        ZEND_ARG_ARRAY_INFO(0, args, 0)
                   5258: ZEND_END_ARG_INFO()
                   5259: 
                   5260: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
                   5261:        ZEND_ARG_INFO(0, class)
                   5262: ZEND_END_ARG_INFO()
                   5263: 
                   5264: ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
                   5265:        ZEND_ARG_INFO(0, interface)
                   5266: ZEND_END_ARG_INFO()
                   5267: 
                   5268: static const zend_function_entry reflection_class_functions[] = {
                   5269:        ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
                   5270:        ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5271:        ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
                   5272:        ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0)
                   5273:        ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0)
                   5274:        ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0)
                   5275:        ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0)
                   5276:        ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0)
                   5277:        ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0)
                   5278:        ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0)
                   5279:        ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0)
                   5280:        ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0)
                   5281:        ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0)
                   5282:        ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
                   5283:        ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
                   5284:        ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
                   5285:        ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
                   5286:        ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
                   5287:        ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
                   5288:        ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
                   5289:        ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0)
                   5290:        ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
                   5291:        ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0)
                   5292:        ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0)
                   5293:        ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0)
                   5294:        ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
                   5295:        ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
                   5296:        ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
                   5297:        ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
                   5298:        ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
                   5299:        ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
                   5300:        ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0)
                   5301:        ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
                   5302:        ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0)
                   5303:        ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
                   5304:        ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
                   5305:        ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0)
                   5306:        ZEND_ME(reflection_class, isIterateable, arginfo_reflection__void, 0)
                   5307:        ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
                   5308:        ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0)
                   5309:        ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0)
                   5310:        ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0)
                   5311:        ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0)
                   5312:        ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0)
                   5313:        PHP_FE_END
                   5314: };
                   5315: 
                   5316: 
                   5317: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
                   5318:        ZEND_ARG_INFO(0, argument)
                   5319:        ZEND_ARG_INFO(0, return)
                   5320: ZEND_END_ARG_INFO()
                   5321: 
                   5322: ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
                   5323:        ZEND_ARG_INFO(0, argument)
                   5324: ZEND_END_ARG_INFO()
                   5325: 
                   5326: static const zend_function_entry reflection_object_functions[] = {
                   5327:        ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5328:        ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
                   5329:        PHP_FE_END
                   5330: };
                   5331: 
                   5332: 
                   5333: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2)
                   5334:        ZEND_ARG_INFO(0, class)
                   5335:        ZEND_ARG_INFO(0, name)
                   5336:        ZEND_ARG_INFO(0, return)
                   5337: ZEND_END_ARG_INFO()
                   5338: 
                   5339: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2)
                   5340:        ZEND_ARG_INFO(0, class)
                   5341:        ZEND_ARG_INFO(0, name)
                   5342: ZEND_END_ARG_INFO()
                   5343: 
                   5344: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0)
                   5345:        ZEND_ARG_INFO(0, object)
                   5346: ZEND_END_ARG_INFO()
                   5347: 
                   5348: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1)
                   5349:        ZEND_ARG_INFO(0, object)
                   5350:        ZEND_ARG_INFO(0, value)
                   5351: ZEND_END_ARG_INFO()
                   5352: 
                   5353: ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0)
                   5354:        ZEND_ARG_INFO(0, visible)
                   5355: ZEND_END_ARG_INFO()
                   5356: 
                   5357: static const zend_function_entry reflection_property_functions[] = {
                   5358:        ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
                   5359:        ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5360:        ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
                   5361:        ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0)
                   5362:        ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0)
                   5363:        ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
                   5364:        ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
                   5365:        ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0)
                   5366:        ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0)
                   5367:        ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0)
                   5368:        ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0)
                   5369:        ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0)
                   5370:        ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0)
                   5371:        ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0)
                   5372:        ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0)
                   5373:        ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0)
                   5374:        PHP_FE_END
                   5375: };
                   5376: 
                   5377: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
                   5378:        ZEND_ARG_INFO(0, function)
                   5379:        ZEND_ARG_INFO(0, parameter)
                   5380:        ZEND_ARG_INFO(0, return)
                   5381: ZEND_END_ARG_INFO()
                   5382: 
                   5383: ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
                   5384:        ZEND_ARG_INFO(0, function)
                   5385:        ZEND_ARG_INFO(0, parameter)
                   5386: ZEND_END_ARG_INFO()
                   5387: 
                   5388: static const zend_function_entry reflection_parameter_functions[] = {
                   5389:        ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
                   5390:        ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5391:        ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
                   5392:        ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0)
                   5393:        ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0)
                   5394:        ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0)
                   5395:        ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0)
                   5396:        ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
                   5397:        ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
                   5398:        ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
                   5399:        ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
                   5400:        ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
                   5401:        ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
                   5402:        ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
                   5403:        ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
                   5404:        PHP_FE_END
                   5405: };
                   5406: 
                   5407: ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
                   5408:        ZEND_ARG_INFO(0, name)
                   5409:        ZEND_ARG_INFO(0, return)
                   5410: ZEND_END_ARG_INFO()
                   5411: 
                   5412: ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
                   5413:        ZEND_ARG_INFO(0, name)
                   5414: ZEND_END_ARG_INFO()
                   5415: 
                   5416: static const zend_function_entry reflection_extension_functions[] = {
                   5417:        ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
                   5418:        ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
                   5419:        ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
                   5420:        ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0)
                   5421:        ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0)
                   5422:        ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0)
                   5423:        ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0)
                   5424:        ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0)
                   5425:        ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0)
                   5426:        ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0)
                   5427:        ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0)
                   5428:        ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0)
                   5429:        ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0)
                   5430:        PHP_FE_END
                   5431: };
                   5432: /* }}} */
                   5433: 
                   5434: const zend_function_entry reflection_ext_functions[] = { /* {{{ */
                   5435:        PHP_FE_END
                   5436: }; /* }}} */
                   5437: 
                   5438: static zend_object_handlers *zend_std_obj_handlers;
                   5439: 
                   5440: /* {{{ _reflection_write_property */
                   5441: static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
                   5442: {
                   5443:        if ((Z_TYPE_P(member) == IS_STRING)
                   5444:                && zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
                   5445:                && ((Z_STRLEN_P(member) == sizeof("name") - 1  && !memcmp(Z_STRVAL_P(member), "name",  sizeof("name")))
                   5446:                        || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
                   5447:        {
                   5448:                zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
                   5449:                        "Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
                   5450:        }
                   5451:        else
                   5452:        {
                   5453:                zend_std_obj_handlers->write_property(object, member, value TSRMLS_CC);         
                   5454:        }
                   5455: }
                   5456: /* }}} */
                   5457: 
                   5458: PHP_MINIT_FUNCTION(reflection) /* {{{ */
                   5459: {
                   5460:        zend_class_entry _reflection_entry;
                   5461: 
                   5462:        zend_std_obj_handlers = zend_get_std_object_handlers();
                   5463:        memcpy(&reflection_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
                   5464:        reflection_object_handlers.clone_obj = NULL;
                   5465:        reflection_object_handlers.write_property = _reflection_write_property;
                   5466: 
                   5467:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
                   5468:        reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
                   5469: 
                   5470:        INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
                   5471:        reflection_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5472: 
                   5473:        INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
                   5474:        reflector_ptr = zend_register_internal_interface(&_reflection_entry TSRMLS_CC);
                   5475: 
                   5476:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
                   5477:        _reflection_entry.create_object = reflection_objects_new;
                   5478:        reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5479:        reflection_register_implement(reflection_function_abstract_ptr, reflector_ptr TSRMLS_CC);
                   5480:        zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT TSRMLS_CC);
                   5481: 
                   5482:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
                   5483:        _reflection_entry.create_object = reflection_objects_new;
                   5484:        reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
                   5485:        zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5486: 
                   5487:        REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
                   5488: 
                   5489:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
                   5490:        _reflection_entry.create_object = reflection_objects_new;
                   5491:        reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5492:        reflection_register_implement(reflection_parameter_ptr, reflector_ptr TSRMLS_CC);
                   5493:        zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5494: 
                   5495:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
                   5496:        _reflection_entry.create_object = reflection_objects_new;
                   5497:        reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr, NULL TSRMLS_CC);
                   5498:        zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5499:        zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5500: 
                   5501:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
                   5502:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
                   5503:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
                   5504:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
                   5505:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
                   5506:        REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
                   5507: 
                   5508:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
                   5509:        _reflection_entry.create_object = reflection_objects_new;
                   5510:        reflection_class_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5511:        reflection_register_implement(reflection_class_ptr, reflector_ptr TSRMLS_CC);
                   5512:        zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5513: 
                   5514:        REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
                   5515:        REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
                   5516:        REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL_CLASS);
                   5517: 
                   5518:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
                   5519:        _reflection_entry.create_object = reflection_objects_new;
                   5520:        reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr, NULL TSRMLS_CC);
                   5521: 
                   5522:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
                   5523:        _reflection_entry.create_object = reflection_objects_new;
                   5524:        reflection_property_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5525:        reflection_register_implement(reflection_property_ptr, reflector_ptr TSRMLS_CC);
                   5526:        zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5527:        zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5528: 
                   5529:        REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
                   5530:        REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
                   5531:        REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
                   5532:        REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
                   5533: 
                   5534:        INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
                   5535:        _reflection_entry.create_object = reflection_objects_new;
                   5536:        reflection_extension_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
                   5537:        reflection_register_implement(reflection_extension_ptr, reflector_ptr TSRMLS_CC);
                   5538:        zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
                   5539: 
                   5540:        return SUCCESS;
                   5541: } /* }}} */
                   5542: 
                   5543: PHP_MINFO_FUNCTION(reflection) /* {{{ */
                   5544: {
                   5545:        php_info_print_table_start();
                   5546:        php_info_print_table_header(2, "Reflection", "enabled");
                   5547: 
                   5548:        php_info_print_table_row(2, "Version", "$Revision: 321634 $");
                   5549: 
                   5550:        php_info_print_table_end();
                   5551: } /* }}} */
                   5552: 
                   5553: zend_module_entry reflection_module_entry = { /* {{{ */
                   5554:        STANDARD_MODULE_HEADER,
                   5555:        "Reflection",
                   5556:        reflection_ext_functions,
                   5557:        PHP_MINIT(reflection),
                   5558:        NULL,
                   5559:        NULL,
                   5560:        NULL,
                   5561:        PHP_MINFO(reflection),
                   5562:        "$Revision: 321634 $",
                   5563:        STANDARD_MODULE_PROPERTIES
                   5564: }; /* }}} */
                   5565: 
                   5566: /*
                   5567:  * Local variables:
                   5568:  * tab-width: 4
                   5569:  * c-basic-offset: 4
                   5570:  * indent-tabs-mode: t
                   5571:  * End:
                   5572:  * vim600: noet sw=4 ts=4 fdm=marker
                   5573:  */

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