PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/reflection - php_reflection.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 2505 2773 90.3 %
Date: 2022-01-18 Functions: 237 240 98.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2018 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             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include "php.h"
      28             : #include "php_ini.h"
      29             : #include "php_reflection.h"
      30             : #include "ext/standard/info.h"
      31             : 
      32             : #include "zend.h"
      33             : #include "zend_API.h"
      34             : #include "zend_exceptions.h"
      35             : #include "zend_operators.h"
      36             : #include "zend_constants.h"
      37             : #include "zend_ini.h"
      38             : #include "zend_interfaces.h"
      39             : #include "zend_closures.h"
      40             : #include "zend_generators.h"
      41             : #include "zend_extensions.h"
      42             : #include "zend_builtin_functions.h"
      43             : #include "zend_smart_str.h"
      44             : 
      45             : #define reflection_update_property(object, name, value) do { \
      46             :                 zval member; \
      47             :                 ZVAL_STR(&member, name); \
      48             :                 zend_std_write_property(object, &member, value, NULL); \
      49             :                 Z_TRY_DELREF_P(value); \
      50             :                 zval_ptr_dtor(&member); \
      51             :         } while (0)
      52             : 
      53             : #define reflection_update_property_name(object, value) \
      54             :         reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_NAME), value)
      55             : 
      56             : #define reflection_update_property_class(object, value) \
      57             :         reflection_update_property(object, ZSTR_KNOWN(ZEND_STR_CLASS), value)
      58             : 
      59             : /* Class entry pointers */
      60             : PHPAPI zend_class_entry *reflector_ptr;
      61             : PHPAPI zend_class_entry *reflection_exception_ptr;
      62             : PHPAPI zend_class_entry *reflection_ptr;
      63             : PHPAPI zend_class_entry *reflection_function_abstract_ptr;
      64             : PHPAPI zend_class_entry *reflection_function_ptr;
      65             : PHPAPI zend_class_entry *reflection_generator_ptr;
      66             : PHPAPI zend_class_entry *reflection_parameter_ptr;
      67             : PHPAPI zend_class_entry *reflection_type_ptr;
      68             : PHPAPI zend_class_entry *reflection_named_type_ptr;
      69             : PHPAPI zend_class_entry *reflection_class_ptr;
      70             : PHPAPI zend_class_entry *reflection_object_ptr;
      71             : PHPAPI zend_class_entry *reflection_method_ptr;
      72             : PHPAPI zend_class_entry *reflection_property_ptr;
      73             : PHPAPI zend_class_entry *reflection_class_constant_ptr;
      74             : PHPAPI zend_class_entry *reflection_extension_ptr;
      75             : PHPAPI zend_class_entry *reflection_zend_extension_ptr;
      76             : 
      77             : /* Exception throwing macro */
      78             : #define _DO_THROW(msg)                                                                                      \
      79             :         zend_throw_exception(reflection_exception_ptr, msg, 0);                                       \
      80             :         return;                                                                                                 \
      81             : 
      82             : #define RETURN_ON_EXCEPTION                                                                                 \
      83             :         if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) {                            \
      84             :                 return;                                                                                             \
      85             :         }
      86             : 
      87             : #define GET_REFLECTION_OBJECT()                                                                                         \
      88             :         intern = Z_REFLECTION_P(getThis());                                                                                     \
      89             :         if (intern->ptr == NULL) {                                                            \
      90             :                 RETURN_ON_EXCEPTION                                                                                 \
      91             :                 zend_throw_error(NULL, "Internal error: Failed to retrieve the reflection object");        \
      92             :                 return;                                                                                             \
      93             :         }                                                                                                       \
      94             : 
      95             : #define GET_REFLECTION_OBJECT_PTR(target)                                                                   \
      96             :         GET_REFLECTION_OBJECT()                                                                                                                                                                 \
      97             :         target = intern->ptr;                                                                                   \
      98             : 
      99             : /* Class constants */
     100             : #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value)                                        \
     101             :         zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (zend_long)value);
     102             : 
     103             : /* {{{ Object structure */
     104             : 
     105             : /* Struct for properties */
     106             : typedef struct _property_reference {
     107             :         zend_class_entry *ce;
     108             :         zend_property_info prop;
     109             :         zend_string *unmangled_name;
     110             : } property_reference;
     111             : 
     112             : /* Struct for parameters */
     113             : typedef struct _parameter_reference {
     114             :         uint32_t offset;
     115             :         zend_bool required;
     116             :         struct _zend_arg_info *arg_info;
     117             :         zend_function *fptr;
     118             : } parameter_reference;
     119             : 
     120             : /* Struct for type hints */
     121             : typedef struct _type_reference {
     122             :         struct _zend_arg_info *arg_info;
     123             :         zend_function *fptr;
     124             : } type_reference;
     125             : 
     126             : typedef enum {
     127             :         REF_TYPE_OTHER,      /* Must be 0 */
     128             :         REF_TYPE_FUNCTION,
     129             :         REF_TYPE_GENERATOR,
     130             :         REF_TYPE_PARAMETER,
     131             :         REF_TYPE_TYPE,
     132             :         REF_TYPE_PROPERTY,
     133             :         REF_TYPE_CLASS_CONSTANT
     134             : } reflection_type_t;
     135             : 
     136             : /* Struct for reflection objects */
     137             : typedef struct {
     138             :         zval dummy; /* holder for the second property */
     139             :         zval obj;
     140             :         void *ptr;
     141             :         zend_class_entry *ce;
     142             :         reflection_type_t ref_type;
     143             :         unsigned int ignore_visibility:1;
     144             :         zend_object zo;
     145             : } reflection_object;
     146             : 
     147       11388 : static inline reflection_object *reflection_object_from_obj(zend_object *obj) {
     148       11388 :         return (reflection_object*)((char*)(obj) - XtOffsetOf(reflection_object, zo));
     149             : }
     150             : 
     151             : #define Z_REFLECTION_P(zv)  reflection_object_from_obj(Z_OBJ_P((zv)))
     152             : /* }}} */
     153             : 
     154             : static zend_object_handlers reflection_object_handlers;
     155             : 
     156         701 : static zval *_default_load_name(zval *object) /* {{{ */
     157             : {
     158        1402 :         return zend_hash_find_ex_ind(Z_OBJPROP_P(object), ZSTR_KNOWN(ZEND_STR_NAME), 1);
     159             : }
     160             : /* }}} */
     161             : 
     162         658 : static void _default_get_name(zval *object, zval *return_value) /* {{{ */
     163             : {
     164             :         zval *value;
     165             : 
     166         658 :         if ((value = _default_load_name(object)) == NULL) {
     167           0 :                 RETURN_FALSE;
     168             :         }
     169         658 :         ZVAL_COPY(return_value, value);
     170             : }
     171             : /* }}} */
     172             : 
     173         323 : static zend_function *_copy_function(zend_function *fptr) /* {{{ */
     174             : {
     175         323 :         if (fptr
     176         323 :                 && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
     177             :         {
     178             :                 zend_function *copy_fptr;
     179          19 :                 copy_fptr = emalloc(sizeof(zend_function));
     180          19 :                 memcpy(copy_fptr, fptr, sizeof(zend_function));
     181          38 :                 copy_fptr->internal_function.function_name = zend_string_copy(fptr->internal_function.function_name);
     182          19 :                 return copy_fptr;
     183             :         } else {
     184             :                 /* no copy needed */
     185         304 :                 return fptr;
     186             :         }
     187             : }
     188             : /* }}} */
     189             : 
     190        3110 : static void _free_function(zend_function *fptr) /* {{{ */
     191             : {
     192        3110 :         if (fptr
     193        2382 :                 && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
     194             :         {
     195          37 :                 zend_string_release_ex(fptr->internal_function.function_name, 0);
     196          37 :                 zend_free_trampoline(fptr);
     197             :         }
     198        3110 : }
     199             : /* }}} */
     200             : 
     201        3477 : static void reflection_free_objects_storage(zend_object *object) /* {{{ */
     202             : {
     203        3477 :         reflection_object *intern = reflection_object_from_obj(object);
     204             :         parameter_reference *reference;
     205             :         property_reference *prop_reference;
     206             :         type_reference *typ_reference;
     207             : 
     208        3477 :         if (intern->ptr) {
     209        3387 :                 switch (intern->ref_type) {
     210         284 :                 case REF_TYPE_PARAMETER:
     211         284 :                         reference = (parameter_reference*)intern->ptr;
     212         284 :                         _free_function(reference->fptr);
     213         284 :                         efree(intern->ptr);
     214         284 :                         break;
     215          51 :                 case REF_TYPE_TYPE:
     216          51 :                         typ_reference = (type_reference*)intern->ptr;
     217          51 :                         _free_function(typ_reference->fptr);
     218          51 :                         efree(intern->ptr);
     219          51 :                         break;
     220        2047 :                 case REF_TYPE_FUNCTION:
     221        2047 :                         _free_function(intern->ptr);
     222        2047 :                         break;
     223         248 :                 case REF_TYPE_PROPERTY:
     224         248 :                         prop_reference = (property_reference*)intern->ptr;
     225         248 :                         zend_string_release_ex(prop_reference->unmangled_name, 0);
     226         248 :                         efree(intern->ptr);
     227         248 :                         break;
     228         757 :                 case REF_TYPE_GENERATOR:
     229             :                 case REF_TYPE_CLASS_CONSTANT:
     230             :                 case REF_TYPE_OTHER:
     231         757 :                         break;
     232             :                 }
     233             :         }
     234        3477 :         intern->ptr = NULL;
     235        3477 :         zval_ptr_dtor(&intern->obj);
     236        3477 :         zend_object_std_dtor(object);
     237        3477 : }
     238             : /* }}} */
     239             : 
     240           0 : static HashTable *reflection_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */
     241             : {
     242           0 :         reflection_object *intern = Z_REFLECTION_P(obj);
     243           0 :         *gc_data = &intern->obj;
     244           0 :         *gc_data_count = 1;
     245           0 :         return zend_std_get_properties(obj);
     246             : }
     247             : /* }}} */
     248             : 
     249        3477 : static zend_object *reflection_objects_new(zend_class_entry *class_type) /* {{{ */
     250             : {
     251        3477 :         reflection_object *intern = zend_object_alloc(sizeof(reflection_object), class_type);
     252             : 
     253        3477 :         zend_object_std_init(&intern->zo, class_type);
     254        3477 :         object_properties_init(&intern->zo, class_type);
     255        3477 :         intern->zo.handlers = &reflection_object_handlers;
     256        3477 :         return &intern->zo;
     257             : }
     258             : /* }}} */
     259             : 
     260        2059 : static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{ */
     261             : {
     262        2059 :         object_init_ex(object, pce);
     263        2059 :         return object;
     264             : }
     265             : /* }}} */
     266             : 
     267             : static void _const_string(smart_str *str, char *name, zval *value, char *indent);
     268             : static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent);
     269             : static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent);
     270             : static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char* indent);
     271             : static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent);
     272             : static void _extension_string(smart_str *str, zend_module_entry *module, char *indent);
     273             : static void _zend_extension_string(smart_str *str, zend_extension *extension, char *indent);
     274             : 
     275             : /* {{{ _class_string */
     276          72 : static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent)
     277             : {
     278          72 :         int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
     279          72 :         zend_string *sub_indent = strpprintf(0, "%s    ", indent);
     280             : 
     281             :         /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
     282          72 :         if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
     283           0 :                 smart_str_append_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment));
     284             :                 smart_str_appendc(str, '\n');
     285             :         }
     286             : 
     287         112 :         if (obj && Z_TYPE_P(obj) == IS_OBJECT) {
     288           7 :                 smart_str_append_printf(str, "%sObject of class [ ", indent);
     289             :         } else {
     290          65 :                 char *kind = "Class";
     291          65 :                 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
     292           3 :                         kind = "Interface";
     293          62 :                 } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
     294           2 :                         kind = "Trait";
     295             :                 }
     296          65 :                 smart_str_append_printf(str, "%s%s [ ", indent, kind);
     297             :         }
     298          72 :         smart_str_append_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
     299          72 :         if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) {
     300          39 :                 smart_str_append_printf(str, ":%s", ce->info.internal.module->name);
     301             :         }
     302          72 :         smart_str_append_printf(str, "> ");
     303          72 :         if (ce->get_iterator != NULL) {
     304           0 :                 smart_str_append_printf(str, "<iterateable> ");
     305             :         }
     306          72 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
     307           3 :                 smart_str_append_printf(str, "interface ");
     308          69 :         } else if (ce->ce_flags & ZEND_ACC_TRAIT) {
     309           2 :                 smart_str_append_printf(str, "trait ");
     310             :         } else {
     311          67 :                 if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
     312           3 :                         smart_str_append_printf(str, "abstract ");
     313             :                 }
     314          67 :                 if (ce->ce_flags & ZEND_ACC_FINAL) {
     315           0 :                         smart_str_append_printf(str, "final ");
     316             :                 }
     317          67 :                 smart_str_append_printf(str, "class ");
     318             :         }
     319          72 :         smart_str_append_printf(str, "%s", ZSTR_VAL(ce->name));
     320          72 :         if (ce->parent) {
     321          24 :                 smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->parent->name));
     322             :         }
     323             : 
     324          72 :         if (ce->num_interfaces) {
     325             :                 uint32_t i;
     326             : 
     327          25 :                 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
     328           0 :                         smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name));
     329             :                 } else {
     330          25 :                         smart_str_append_printf(str, " implements %s", ZSTR_VAL(ce->interfaces[0]->name));
     331             :                 }
     332          26 :                 for (i = 1; i < ce->num_interfaces; ++i) {
     333           1 :                         smart_str_append_printf(str, ", %s", ZSTR_VAL(ce->interfaces[i]->name));
     334             :                 }
     335             :         }
     336          72 :         smart_str_append_printf(str, " ] {\n");
     337             : 
     338             :         /* The information where a class is declared is only available for user classes */
     339          72 :         if (ce->type == ZEND_USER_CLASS) {
     340          33 :                 smart_str_append_printf(str, "%s  @@ %s %d-%d\n", indent, ZSTR_VAL(ce->info.user.filename),
     341             :                                                 ce->info.user.line_start, ce->info.user.line_end);
     342             :         }
     343             : 
     344             :         /* Constants */
     345          72 :         smart_str_append_printf(str, "\n");
     346          72 :         count = zend_hash_num_elements(&ce->constants_table);
     347          72 :         smart_str_append_printf(str, "%s  - Constants [%d] {\n", indent, count);
     348          72 :         if (count > 0) {
     349             :                 zend_string *key;
     350             :                 zend_class_constant *c;
     351             : 
     352         112 :                 ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) {
     353          48 :                         _class_const_string(str, ZSTR_VAL(key), c, ZSTR_VAL(sub_indent));
     354          48 :                         if (UNEXPECTED(EG(exception))) {
     355           0 :                                 return;
     356             :                         }
     357             :                 } ZEND_HASH_FOREACH_END();
     358             :         }
     359          72 :         smart_str_append_printf(str, "%s  }\n", indent);
     360             : 
     361             :         /* Static properties */
     362             :         /* counting static properties */
     363          72 :         count = zend_hash_num_elements(&ce->properties_info);
     364          72 :         if (count > 0) {
     365             :                 zend_property_info *prop;
     366             : 
     367         162 :                 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
     368          64 :                         if(prop->flags & ZEND_ACC_SHADOW) {
     369          11 :                                 count_shadow_props++;
     370          53 :                         } else if (prop->flags & ZEND_ACC_STATIC) {
     371           3 :                                 count_static_props++;
     372             :                         }
     373             :                 } ZEND_HASH_FOREACH_END();
     374             :         }
     375             : 
     376             :         /* static properties */
     377          72 :         smart_str_append_printf(str, "\n%s  - Static properties [%d] {\n", indent, count_static_props);
     378          72 :         if (count_static_props > 0) {
     379             :                 zend_property_info *prop;
     380             : 
     381          12 :                 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
     382           5 :                         if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
     383           3 :                                 _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
     384             :                         }
     385             :                 } ZEND_HASH_FOREACH_END();
     386             :         }
     387          72 :         smart_str_append_printf(str, "%s  }\n", indent);
     388             : 
     389             :         /* Static methods */
     390             :         /* counting static methods */
     391          72 :         count = zend_hash_num_elements(&ce->function_table);
     392          72 :         if (count > 0) {
     393             :                 zend_function *mptr;
     394             : 
     395        1597 :                 ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) {
     396         770 :                         if (mptr->common.fn_flags & ZEND_ACC_STATIC
     397          28 :                                 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
     398             :                         {
     399          27 :                                 count_static_funcs++;
     400             :                         }
     401             :                 } ZEND_HASH_FOREACH_END();
     402             :         }
     403             : 
     404             :         /* static methods */
     405          72 :         smart_str_append_printf(str, "\n%s  - Static methods [%d] {", indent, count_static_funcs);
     406          72 :         if (count_static_funcs > 0) {
     407             :                 zend_function *mptr;
     408             : 
     409        1297 :                 ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) {
     410         636 :                         if (mptr->common.fn_flags & ZEND_ACC_STATIC
     411          27 :                                 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
     412             :                         {
     413          27 :                                 smart_str_append_printf(str, "\n");
     414          27 :                                 _function_string(str, mptr, ce, ZSTR_VAL(sub_indent));
     415             :                         }
     416             :                 } ZEND_HASH_FOREACH_END();
     417             :         } else {
     418          47 :                 smart_str_append_printf(str, "\n");
     419             :         }
     420          72 :         smart_str_append_printf(str, "%s  }\n", indent);
     421             : 
     422             :         /* Default/Implicit properties */
     423          72 :         count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
     424          72 :         smart_str_append_printf(str, "\n%s  - Properties [%d] {\n", indent, count);
     425          72 :         if (count > 0) {
     426             :                 zend_property_info *prop;
     427             : 
     428         144 :                 ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
     429          57 :                         if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
     430          50 :                                 _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
     431             :                         }
     432             :                 } ZEND_HASH_FOREACH_END();
     433             :         }
     434          72 :         smart_str_append_printf(str, "%s  }\n", indent);
     435             : 
     436         112 :         if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) {
     437           7 :                 HashTable    *properties = Z_OBJ_HT_P(obj)->get_properties(obj);
     438             :                 zend_string  *prop_name;
     439           7 :                 smart_str prop_str = {0};
     440             : 
     441           7 :                 count = 0;
     442           7 :                 if (properties && zend_hash_num_elements(properties)) {
     443          34 :                         ZEND_HASH_FOREACH_STR_KEY(properties, prop_name) {
     444          14 :                                 if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) { /* skip all private and protected properties */
     445          11 :                                         if (!zend_hash_exists(&ce->properties_info, prop_name)) {
     446           5 :                                                 count++;
     447           5 :                                                 _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent));
     448             :                                         }
     449             :                                 }
     450             :                         } ZEND_HASH_FOREACH_END();
     451             :                 }
     452             : 
     453           7 :                 smart_str_append_printf(str, "\n%s  - Dynamic properties [%d] {\n", indent, count);
     454             :                 smart_str_append_smart_str(str, &prop_str);
     455           7 :                 smart_str_append_printf(str, "%s  }\n", indent);
     456             :                 smart_str_free(&prop_str);
     457             :         }
     458             : 
     459             :         /* Non static methods */
     460          72 :         count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
     461          72 :         if (count > 0) {
     462             :                 zend_function *mptr;
     463             :                 zend_string *key;
     464          55 :                 smart_str method_str = {0};
     465             : 
     466          55 :                 count = 0;
     467        1587 :                 ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
     468         766 :                         if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
     469         742 :                                 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
     470             :                         {
     471         728 :                                 size_t len = ZSTR_LEN(mptr->common.function_name);
     472             : 
     473             :                                 /* Do not display old-style inherited constructors */
     474         728 :                                 if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
     475          25 :                                         || mptr->common.scope == ce
     476           3 :                                         || !key
     477           3 :                                         || zend_binary_strcasecmp(ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(mptr->common.function_name), len) == 0)
     478             :                                 {
     479             :                                         zend_function *closure;
     480             :                                         /* see if this is a closure */
     481         728 :                                         if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
     482           0 :                                                 && memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
     483           0 :                                                 && (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
     484             :                                         {
     485           0 :                                                 mptr = closure;
     486             :                                         } else {
     487         728 :                                                 closure = NULL;
     488             :                                         }
     489             :                                         smart_str_appendc(&method_str, '\n');
     490         728 :                                         _function_string(&method_str, mptr, ce, ZSTR_VAL(sub_indent));
     491         728 :                                         count++;
     492         728 :                                         _free_function(closure);
     493             :                                 }
     494             :                         }
     495             :                 } ZEND_HASH_FOREACH_END();
     496          55 :                 smart_str_append_printf(str, "\n%s  - Methods [%d] {", indent, count);
     497             :                 smart_str_append_smart_str(str, &method_str);
     498          55 :                 if (!count) {
     499           2 :                         smart_str_append_printf(str, "\n");
     500             :                 }
     501             :                 smart_str_free(&method_str);
     502             :         } else {
     503          17 :                 smart_str_append_printf(str, "\n%s  - Methods [0] {\n", indent);
     504             :         }
     505          72 :         smart_str_append_printf(str, "%s  }\n", indent);
     506             : 
     507          72 :         smart_str_append_printf(str, "%s}\n", indent);
     508             :         zend_string_release_ex(sub_indent, 0);
     509             : }
     510             : /* }}} */
     511             : 
     512             : /* {{{ _const_string */
     513          19 : static void _const_string(smart_str *str, char *name, zval *value, char *indent)
     514             : {
     515          19 :         char *type = zend_zval_type_name(value);
     516             : 
     517          19 :         if (Z_TYPE_P(value) == IS_ARRAY) {
     518           0 :                 smart_str_append_printf(str, "%s    Constant [ %s %s ] { Array }\n",
     519             :                                                 indent, type, name);
     520          19 :         } else if (Z_TYPE_P(value) == IS_STRING) {
     521           1 :                 smart_str_append_printf(str, "%s    Constant [ %s %s ] { %s }\n",
     522           1 :                                                 indent, type, name, Z_STRVAL_P(value));
     523             :         } else {
     524             :                 zend_string *tmp_value_str;
     525          18 :                 zend_string *value_str = zval_get_tmp_string(value, &tmp_value_str);
     526          18 :                 smart_str_append_printf(str, "%s    Constant [ %s %s ] { %s }\n",
     527          18 :                                                 indent, type, name, ZSTR_VAL(value_str));
     528          18 :                 zend_tmp_string_release(tmp_value_str);
     529             :         }
     530          19 : }
     531             : /* }}} */
     532             : 
     533             : /* {{{ _class_const_string */
     534          61 : static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char *indent)
     535             : {
     536          61 :         char *visibility = zend_visibility_string(Z_ACCESS_FLAGS(c->value));
     537             :         char *type;
     538             : 
     539          61 :         zval_update_constant_ex(&c->value, c->ce);
     540          61 :         type = zend_zval_type_name(&c->value);
     541             : 
     542         122 :         if (Z_TYPE(c->value) == IS_ARRAY) {
     543           1 :                 smart_str_append_printf(str, "%sConstant [ %s %s %s ] { Array }\n",
     544             :                                                 indent, visibility, type, name);
     545             :         } else {
     546             :                 zend_string *tmp_value_str;
     547         120 :                 zend_string *value_str = zval_get_tmp_string(&c->value, &tmp_value_str);
     548             : 
     549          60 :                 smart_str_append_printf(str, "%sConstant [ %s %s %s ] { %s }\n",
     550          60 :                                                 indent, visibility, type, name, ZSTR_VAL(value_str));
     551             : 
     552          60 :                 zend_tmp_string_release(tmp_value_str);
     553             :         }
     554          61 : }
     555             : /* }}} */
     556             : 
     557             : /* {{{ _get_recv_opcode */
     558         118 : static zend_op* _get_recv_op(zend_op_array *op_array, uint32_t offset)
     559             : {
     560         118 :         zend_op *op = op_array->opcodes;
     561         118 :         zend_op *end = op + op_array->last;
     562             : 
     563         118 :         ++offset;
     564         404 :         while (op < end) {
     565         286 :                 if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT
     566           1 :                     || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == offset)
     567             :                 {
     568         118 :                         return op;
     569             :                 }
     570         168 :                 ++op;
     571             :         }
     572           0 :         return NULL;
     573             : }
     574             : /* }}} */
     575             : 
     576             : /* {{{ _parameter_string */
     577         623 : static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_arg_info *arg_info, uint32_t offset, zend_bool required, char* indent)
     578             : {
     579         623 :         smart_str_append_printf(str, "Parameter #%d [ ", offset);
     580         623 :         if (!required) {
     581         198 :                 smart_str_append_printf(str, "<optional> ");
     582             :         } else {
     583         425 :                 smart_str_append_printf(str, "<required> ");
     584             :         }
     585         623 :         if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
     586           7 :                 smart_str_append_printf(str, "%s ",
     587           7 :                         ZSTR_VAL(ZEND_TYPE_NAME(arg_info->type)));
     588           7 :                 if (ZEND_TYPE_ALLOW_NULL(arg_info->type)) {
     589           1 :                         smart_str_append_printf(str, "or NULL ");
     590             :                 }
     591         616 :         } else if (ZEND_TYPE_IS_CODE(arg_info->type)) {
     592          12 :                 smart_str_append_printf(str, "%s ", zend_get_type_by_const(ZEND_TYPE_CODE(arg_info->type)));
     593          12 :                 if (ZEND_TYPE_ALLOW_NULL(arg_info->type)) {
     594           1 :                         smart_str_append_printf(str, "or NULL ");
     595             :                 }
     596             :         }
     597         623 :         if (arg_info->pass_by_reference) {
     598             :                 smart_str_appendc(str, '&');
     599             :         }
     600         623 :         if (arg_info->is_variadic) {
     601             :                 smart_str_appends(str, "...");
     602             :         }
     603         623 :         if (arg_info->name) {
     604        1246 :                 smart_str_append_printf(str, "$%s",
     605        1204 :                         (fptr->type == ZEND_INTERNAL_FUNCTION &&
     606         581 :                          !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ?
     607             :                         ((zend_internal_arg_info*)arg_info)->name :
     608          44 :                         ZSTR_VAL(arg_info->name));
     609             :         } else {
     610           0 :                 smart_str_append_printf(str, "$param%d", offset);
     611             :         }
     612         623 :         if (fptr->type == ZEND_USER_FUNCTION && !required) {
     613          29 :                 zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
     614          29 :                 if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
     615             :                         zval zv;
     616             : 
     617             :                         smart_str_appends(str, " = ");
     618          28 :                         ZVAL_COPY(&zv, RT_CONSTANT(precv, precv->op2));
     619          28 :                         if (UNEXPECTED(zval_update_constant_ex(&zv, fptr->common.scope) == FAILURE)) {
     620           1 :                                 zval_ptr_dtor(&zv);
     621           1 :                                 return;
     622             :                         }
     623          27 :                         if (Z_TYPE(zv) == IS_TRUE) {
     624             :                                 smart_str_appends(str, "true");
     625          27 :                         } else if (Z_TYPE(zv) == IS_FALSE) {
     626             :                                 smart_str_appends(str, "false");
     627          25 :                         } else if (Z_TYPE(zv) == IS_NULL) {
     628             :                                 smart_str_appends(str, "NULL");
     629          17 :                         } else if (Z_TYPE(zv) == IS_STRING) {
     630             :                                 smart_str_appendc(str, '\'');
     631          12 :                                 smart_str_appendl(str, Z_STRVAL(zv), MIN(Z_STRLEN(zv), 15));
     632          12 :                                 if (Z_STRLEN(zv) > 15) {
     633             :                                         smart_str_appends(str, "...");
     634             :                                 }
     635             :                                 smart_str_appendc(str, '\'');
     636           5 :                         } else if (Z_TYPE(zv) == IS_ARRAY) {
     637             :                                 smart_str_appends(str, "Array");
     638             :                         } else {
     639             :                                 zend_string *tmp_zv_str;
     640           4 :                                 zend_string *zv_str = zval_get_tmp_string(&zv, &tmp_zv_str);
     641             :                                 smart_str_append(str, zv_str);
     642           4 :                                 zend_tmp_string_release(tmp_zv_str);
     643             :                         }
     644          27 :                         zval_ptr_dtor(&zv);
     645             :                 }
     646             :         }
     647             :         smart_str_appends(str, " ]");
     648             : }
     649             : /* }}} */
     650             : 
     651             : /* {{{ _function_parameter_string */
     652         934 : static void _function_parameter_string(smart_str *str, zend_function *fptr, char* indent)
     653             : {
     654         934 :         struct _zend_arg_info *arg_info = fptr->common.arg_info;
     655         934 :         uint32_t i, num_args, num_required = fptr->common.required_num_args;
     656             : 
     657         934 :         if (!arg_info) {
     658          66 :                 return;
     659             :         }
     660             : 
     661         868 :         num_args = fptr->common.num_args;
     662         868 :         if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
     663           0 :                 num_args++;
     664             :         }
     665             :         smart_str_appendc(str, '\n');
     666         868 :         smart_str_append_printf(str, "%s- Parameters [%d] {\n", indent, num_args);
     667        1484 :         for (i = 0; i < num_args; i++) {
     668         616 :                 smart_str_append_printf(str, "%s  ", indent);
     669         616 :                 _parameter_string(str, fptr, arg_info, i, i < num_required, indent);
     670             :                 smart_str_appendc(str, '\n');
     671         616 :                 arg_info++;
     672             :         }
     673         868 :         smart_str_append_printf(str, "%s}\n", indent);
     674             : }
     675             : /* }}} */
     676             : 
     677             : /* {{{ _function_closure_string */
     678           0 : static void _function_closure_string(smart_str *str, zend_function *fptr, char* indent)
     679             : {
     680             :         uint32_t i, count;
     681             :         zend_string *key;
     682             :         HashTable *static_variables;
     683             : 
     684           0 :         if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
     685           0 :                 return;
     686             :         }
     687             : 
     688           0 :         static_variables = fptr->op_array.static_variables;
     689           0 :         count = zend_hash_num_elements(static_variables);
     690             : 
     691           0 :         if (!count) {
     692           0 :                 return;
     693             :         }
     694             : 
     695           0 :         smart_str_append_printf(str, "\n");
     696           0 :         smart_str_append_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
     697           0 :         i = 0;
     698           0 :         ZEND_HASH_FOREACH_STR_KEY(static_variables, key) {
     699           0 :                 smart_str_append_printf(str, "%s    Variable #%d [ $%s ]\n", indent, i++, ZSTR_VAL(key));
     700             :         } ZEND_HASH_FOREACH_END();
     701           0 :         smart_str_append_printf(str, "%s}\n", indent);
     702             : }
     703             : /* }}} */
     704             : 
     705             : /* {{{ _function_string */
     706         934 : static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent)
     707             : {
     708         934 :         smart_str param_indent = {0};
     709             :         zend_function *overwrites;
     710             :         zend_string *lc_name;
     711             : 
     712             :         /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
     713             :          * What's "wrong" is that any whitespace before the doc comment start is
     714             :          * swallowed, leading to an unaligned comment.
     715             :          */
     716         934 :         if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
     717           2 :                 smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment));
     718             :         }
     719             : 
     720         934 :         smart_str_appendl(str, indent, strlen(indent));
     721         934 :         smart_str_append_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
     722         934 :         smart_str_append_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
     723         934 :         if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
     724             :                 smart_str_appends(str, ", deprecated");
     725             :         }
     726         934 :         if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
     727         877 :                 smart_str_append_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
     728             :         }
     729             : 
     730         934 :         if (scope && fptr->common.scope) {
     731         789 :                 if (fptr->common.scope != scope) {
     732         242 :                         smart_str_append_printf(str, ", inherits %s", ZSTR_VAL(fptr->common.scope->name));
     733         547 :                 } else if (fptr->common.scope->parent) {
     734          67 :                         lc_name = zend_string_tolower(fptr->common.function_name);
     735         134 :                         if ((overwrites = zend_hash_find_ptr(&fptr->common.scope->parent->function_table, lc_name)) != NULL) {
     736          17 :                                 if (fptr->common.scope != overwrites->common.scope) {
     737          17 :                                         smart_str_append_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name));
     738             :                                 }
     739             :                         }
     740             :                         zend_string_release_ex(lc_name, 0);
     741             :                 }
     742             :         }
     743         934 :         if (fptr->common.prototype && fptr->common.prototype->common.scope) {
     744          68 :                 smart_str_append_printf(str, ", prototype %s", ZSTR_VAL(fptr->common.prototype->common.scope->name));
     745             :         }
     746         934 :         if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
     747             :                 smart_str_appends(str, ", ctor");
     748             :         }
     749         934 :         if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
     750             :                 smart_str_appends(str, ", dtor");
     751             :         }
     752             :         smart_str_appends(str, "> ");
     753             : 
     754         934 :         if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
     755             :                 smart_str_appends(str, "abstract ");
     756             :         }
     757         934 :         if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
     758             :                 smart_str_appends(str, "final ");
     759             :         }
     760         934 :         if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
     761             :                 smart_str_appends(str, "static ");
     762             :         }
     763             : 
     764         934 :         if (fptr->common.scope) {
     765             :                 /* These are mutually exclusive */
     766         789 :                 switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
     767         756 :                         case ZEND_ACC_PUBLIC:
     768             :                                 smart_str_appends(str, "public ");
     769         756 :                                 break;
     770          28 :                         case ZEND_ACC_PRIVATE:
     771             :                                 smart_str_appends(str, "private ");
     772          28 :                                 break;
     773           5 :                         case ZEND_ACC_PROTECTED:
     774             :                                 smart_str_appends(str, "protected ");
     775           5 :                                 break;
     776           0 :                         default:
     777             :                                 smart_str_appends(str, "<visibility error> ");
     778           0 :                                 break;
     779             :                 }
     780             :                 smart_str_appends(str, "method ");
     781             :         } else {
     782             :                 smart_str_appends(str, "function ");
     783             :         }
     784             : 
     785         934 :         if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
     786             :                 smart_str_appendc(str, '&');
     787             :         }
     788         934 :         smart_str_append_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name));
     789             :         /* The information where a function is declared is only available for user classes */
     790         934 :         if (fptr->type == ZEND_USER_FUNCTION) {
     791         110 :                 smart_str_append_printf(str, "%s  @@ %s %d - %d\n", indent,
     792          55 :                                                 ZSTR_VAL(fptr->op_array.filename),
     793             :                                                 fptr->op_array.line_start,
     794             :                                                 fptr->op_array.line_end);
     795             :         }
     796         934 :         smart_str_append_printf(&param_indent, "%s  ", indent);
     797             :         smart_str_0(&param_indent);
     798         934 :         if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
     799           0 :                 _function_closure_string(str, fptr, ZSTR_VAL(param_indent.s));
     800             :         }
     801         934 :         _function_parameter_string(str, fptr, ZSTR_VAL(param_indent.s));
     802             :         smart_str_free(&param_indent);
     803         934 :         if (fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
     804           2 :                 smart_str_append_printf(str, "  %s- Return [ ", indent);
     805           2 :                 if (ZEND_TYPE_IS_CLASS(fptr->common.arg_info[-1].type)) {
     806           1 :                         smart_str_append_printf(str, "%s ",
     807           1 :                                 ZSTR_VAL(ZEND_TYPE_NAME(fptr->common.arg_info[-1].type)));
     808           1 :                         if (ZEND_TYPE_ALLOW_NULL(fptr->common.arg_info[-1].type)) {
     809             :                                 smart_str_appends(str, "or NULL ");
     810             :                         }
     811           1 :                 } else if (ZEND_TYPE_IS_CODE(fptr->common.arg_info[-1].type)) {
     812           1 :                         smart_str_append_printf(str, "%s ", zend_get_type_by_const(ZEND_TYPE_CODE(fptr->common.arg_info[-1].type)));
     813           1 :                         if (ZEND_TYPE_ALLOW_NULL(fptr->common.arg_info[-1].type)) {
     814             :                                 smart_str_appends(str, "or NULL ");
     815             :                         }
     816             :                 }
     817             :                 smart_str_appends(str, "]\n");
     818             :         }
     819         934 :         smart_str_append_printf(str, "%s}\n", indent);
     820         934 : }
     821             : /* }}} */
     822             : 
     823             : /* {{{ _property_string */
     824          71 : static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent)
     825             : {
     826          71 :         smart_str_append_printf(str, "%sProperty [ ", indent);
     827          71 :         if (!prop) {
     828           5 :                 smart_str_append_printf(str, "<dynamic> public $%s", prop_name);
     829             :         } else {
     830          66 :                 if (!(prop->flags & ZEND_ACC_STATIC)) {
     831          60 :                         if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
     832             :                                 smart_str_appends(str, "<implicit> ");
     833             :                         } else {
     834             :                                 smart_str_appends(str, "<default> ");
     835             :                         }
     836             :                 }
     837             : 
     838             :                 /* These are mutually exclusive */
     839          66 :                 switch (prop->flags & ZEND_ACC_PPP_MASK) {
     840          40 :                         case ZEND_ACC_PUBLIC:
     841             :                                 smart_str_appends(str, "public ");
     842          40 :                                 break;
     843           9 :                         case ZEND_ACC_PRIVATE:
     844             :                                 smart_str_appends(str, "private ");
     845           9 :                                 break;
     846          17 :                         case ZEND_ACC_PROTECTED:
     847             :                                 smart_str_appends(str, "protected ");
     848          17 :                                 break;
     849             :                 }
     850          66 :                 if (prop->flags & ZEND_ACC_STATIC) {
     851             :                         smart_str_appends(str, "static ");
     852             :                 }
     853          66 :                 if (!prop_name) {
     854             :                         const char *class_name;
     855          53 :                         zend_unmangle_property_name(prop->name, &class_name, &prop_name);
     856             :                 }
     857          66 :                 smart_str_append_printf(str, "$%s", prop_name);
     858             :         }
     859             : 
     860             :         smart_str_appends(str, " ]\n");
     861          71 : }
     862             : /* }}} */
     863             : 
     864         811 : static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     865             : {
     866         811 :         zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el);
     867         811 :         smart_str *str = va_arg(args, smart_str *);
     868         811 :         char *indent = va_arg(args, char *);
     869         811 :         int number = va_arg(args, int);
     870         811 :         char *comma = "";
     871             : 
     872         811 :         if (number == ini_entry->module_number) {
     873           3 :                 smart_str_append_printf(str, "    %sEntry [ %s <", indent, ZSTR_VAL(ini_entry->name));
     874           3 :                 if (ini_entry->modifiable == ZEND_INI_ALL) {
     875             :                         smart_str_appends(str, "ALL");
     876             :                 } else {
     877           0 :                         if (ini_entry->modifiable & ZEND_INI_USER) {
     878             :                                 smart_str_appends(str, "USER");
     879           0 :                                 comma = ",";
     880             :                         }
     881           0 :                         if (ini_entry->modifiable & ZEND_INI_PERDIR) {
     882           0 :                                 smart_str_append_printf(str, "%sPERDIR", comma);
     883           0 :                                 comma = ",";
     884             :                         }
     885           0 :                         if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
     886           0 :                                 smart_str_append_printf(str, "%sSYSTEM", comma);
     887             :                         }
     888             :                 }
     889             : 
     890             :                 smart_str_appends(str, "> ]\n");
     891           3 :                 smart_str_append_printf(str, "    %s  Current = '%s'\n", indent, ini_entry->value ? ZSTR_VAL(ini_entry->value) : "");
     892           3 :                 if (ini_entry->modified) {
     893           0 :                         smart_str_append_printf(str, "    %s  Default = '%s'\n", indent, ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : "");
     894             :                 }
     895           3 :                 smart_str_append_printf(str, "    %s}\n", indent);
     896             :         }
     897         811 :         return ZEND_HASH_APPLY_KEEP;
     898             : }
     899             : /* }}} */
     900             : 
     901         594 : static int _extension_class_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     902             : {
     903         594 :         zend_class_entry *ce = (zend_class_entry*)Z_PTR_P(el);
     904         594 :         smart_str *str = va_arg(args, smart_str *);
     905         594 :         char *indent = va_arg(args, char *);
     906         594 :         struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
     907         594 :         int *num_classes = va_arg(args, int*);
     908             : 
     909         594 :         if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) {
     910             :                 /* dump class if it is not an alias */
     911          32 :                 if (!zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) {
     912          32 :                         smart_str_append_printf(str, "\n");
     913          32 :                         _class_string(str, ce, NULL, indent);
     914          32 :                         (*num_classes)++;
     915             :                 }
     916             :         }
     917         594 :         return ZEND_HASH_APPLY_KEEP;
     918             : }
     919             : /* }}} */
     920             : 
     921        8184 : static int _extension_const_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
     922             : {
     923        8184 :         zend_constant *constant = (zend_constant*)Z_PTR_P(el);
     924        8184 :         smart_str *str = va_arg(args, smart_str *);
     925        8184 :         char *indent = va_arg(args, char *);
     926        8184 :         struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
     927        8184 :         int *num_classes = va_arg(args, int*);
     928             : 
     929        8184 :         if (ZEND_CONSTANT_MODULE_NUMBER(constant)  == module->module_number) {
     930          19 :                 _const_string(str, ZSTR_VAL(constant->name), &constant->value, indent);
     931          19 :                 (*num_classes)++;
     932             :         }
     933        8184 :         return ZEND_HASH_APPLY_KEEP;
     934             : }
     935             : /* }}} */
     936             : 
     937           3 : static void _extension_string(smart_str *str, zend_module_entry *module, char *indent) /* {{{ */
     938             : {
     939           3 :         smart_str_append_printf(str, "%sExtension [ ", indent);
     940           3 :         if (module->type == MODULE_PERSISTENT) {
     941             :                 smart_str_appends(str, "<persistent>");
     942             :         }
     943           3 :         if (module->type == MODULE_TEMPORARY) {
     944             :                 smart_str_appends(str, "<temporary>" );
     945             :         }
     946           3 :         smart_str_append_printf(str, " extension #%d %s version %s ] {\n",
     947             :                                         module->module_number, module->name,
     948           3 :                                         (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
     949             : 
     950           3 :         if (module->deps) {
     951           0 :                 const zend_module_dep* dep = module->deps;
     952             : 
     953             :                 smart_str_appends(str, "\n  - Dependencies {\n");
     954             : 
     955           0 :                 while(dep->name) {
     956           0 :                         smart_str_append_printf(str, "%s    Dependency [ %s (", indent, dep->name);
     957             : 
     958           0 :                         switch(dep->type) {
     959           0 :                         case MODULE_DEP_REQUIRED:
     960             :                                 smart_str_appends(str, "Required");
     961           0 :                                 break;
     962           0 :                         case MODULE_DEP_CONFLICTS:
     963             :                                 smart_str_appends(str, "Conflicts");
     964           0 :                                 break;
     965           0 :                         case MODULE_DEP_OPTIONAL:
     966             :                                 smart_str_appends(str, "Optional");
     967           0 :                                 break;
     968           0 :                         default:
     969             :                                 smart_str_appends(str, "Error"); /* shouldn't happen */
     970           0 :                                 break;
     971             :                         }
     972             : 
     973           0 :                         if (dep->rel) {
     974           0 :                                 smart_str_append_printf(str, " %s", dep->rel);
     975             :                         }
     976           0 :                         if (dep->version) {
     977           0 :                                 smart_str_append_printf(str, " %s", dep->version);
     978             :                         }
     979             :                         smart_str_appends(str, ") ]\n");
     980           0 :                         dep++;
     981             :                 }
     982           0 :                 smart_str_append_printf(str, "%s  }\n", indent);
     983             :         }
     984             : 
     985             :         {
     986           3 :                 smart_str str_ini = {0};
     987           3 :                 zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
     988           3 :                 if (smart_str_get_len(&str_ini) > 0) {
     989           1 :                         smart_str_append_printf(str, "\n  - INI {\n");
     990             :                         smart_str_append_smart_str(str, &str_ini);
     991           1 :                         smart_str_append_printf(str, "%s  }\n", indent);
     992             :                 }
     993             :                 smart_str_free(&str_ini);
     994             :         }
     995             : 
     996             :         {
     997           3 :                 smart_str str_constants = {0};
     998           3 :                 int num_constants = 0;
     999             : 
    1000           3 :                 zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
    1001           3 :                 if (num_constants) {
    1002           1 :                         smart_str_append_printf(str, "\n  - Constants [%d] {\n", num_constants);
    1003             :                         smart_str_append_smart_str(str, &str_constants);
    1004           1 :                         smart_str_append_printf(str, "%s  }\n", indent);
    1005             :                 }
    1006             :                 smart_str_free(&str_constants);
    1007             :         }
    1008             : 
    1009             :         {
    1010             :                 zend_function *fptr;
    1011           3 :                 int first = 1;
    1012             : 
    1013       13983 :                 ZEND_HASH_FOREACH_PTR(CG(function_table), fptr) {
    1014        6990 :                         if (fptr->common.type==ZEND_INTERNAL_FUNCTION
    1015        6990 :                                 && fptr->internal_function.module == module) {
    1016          10 :                                 if (first) {
    1017           1 :                                         smart_str_append_printf(str, "\n  - Functions {\n");
    1018           1 :                                         first = 0;
    1019             :                                 }
    1020          10 :                                 _function_string(str, fptr, NULL, "    ");
    1021             :                         }
    1022             :                 } ZEND_HASH_FOREACH_END();
    1023           3 :                 if (!first) {
    1024           1 :                         smart_str_append_printf(str, "%s  }\n", indent);
    1025             :                 }
    1026             :         }
    1027             : 
    1028             :         {
    1029           3 :                 zend_string *sub_indent = strpprintf(0, "%s    ", indent);
    1030           3 :                 smart_str str_classes = {0};
    1031           3 :                 int num_classes = 0;
    1032             : 
    1033           3 :                 zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, ZSTR_VAL(sub_indent), module, &num_classes);
    1034           3 :                 if (num_classes) {
    1035           2 :                         smart_str_append_printf(str, "\n  - Classes [%d] {", num_classes);
    1036             :                         smart_str_append_smart_str(str, &str_classes);
    1037           2 :                         smart_str_append_printf(str, "%s  }\n", indent);
    1038             :                 }
    1039             :                 smart_str_free(&str_classes);
    1040             :                 zend_string_release_ex(sub_indent, 0);
    1041             :         }
    1042             : 
    1043           3 :         smart_str_append_printf(str, "%s}\n", indent);
    1044           3 : }
    1045             : /* }}} */
    1046             : 
    1047           1 : static void _zend_extension_string(smart_str *str, zend_extension *extension, char *indent) /* {{{ */
    1048             : {
    1049           1 :         smart_str_append_printf(str, "%sZend Extension [ %s ", indent, extension->name);
    1050             : 
    1051           1 :         if (extension->version) {
    1052           1 :                 smart_str_append_printf(str, "%s ", extension->version);
    1053             :         }
    1054           1 :         if (extension->copyright) {
    1055           1 :                 smart_str_append_printf(str, "%s ", extension->copyright);
    1056             :         }
    1057           1 :         if (extension->author) {
    1058           1 :                 smart_str_append_printf(str, "by %s ", extension->author);
    1059             :         }
    1060           1 :         if (extension->URL) {
    1061           1 :                 smart_str_append_printf(str, "<%s> ", extension->URL);
    1062             :         }
    1063             : 
    1064             :         smart_str_appends(str, "]\n");
    1065           1 : }
    1066             : /* }}} */
    1067             : 
    1068             : /* {{{ _function_check_flag */
    1069         437 : static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
    1070             : {
    1071             :         reflection_object *intern;
    1072             :         zend_function *mptr;
    1073             : 
    1074         437 :         if (zend_parse_parameters_none() == FAILURE) {
    1075           6 :                 return;
    1076             :         }
    1077         862 :         GET_REFLECTION_OBJECT_PTR(mptr);
    1078         431 :         RETURN_BOOL(mptr->common.fn_flags & mask);
    1079             : }
    1080             : /* }}} */
    1081             : 
    1082             : /* {{{ zend_reflection_class_factory */
    1083         148 : PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object)
    1084             : {
    1085             :         reflection_object *intern;
    1086             :         zval name;
    1087             : 
    1088         296 :         ZVAL_STR_COPY(&name, ce->name);
    1089         148 :         reflection_instantiate(reflection_class_ptr, object);
    1090         148 :         intern = Z_REFLECTION_P(object);
    1091         148 :         intern->ptr = ce;
    1092         148 :         intern->ref_type = REF_TYPE_OTHER;
    1093         148 :         intern->ce = ce;
    1094         444 :         reflection_update_property_name(object, &name);
    1095         148 : }
    1096             : /* }}} */
    1097             : 
    1098             : /* {{{ reflection_extension_factory */
    1099           2 : static void reflection_extension_factory(zval *object, const char *name_str)
    1100             : {
    1101             :         reflection_object *intern;
    1102             :         zval name;
    1103           2 :         size_t name_len = strlen(name_str);
    1104             :         zend_string *lcname;
    1105             :         struct _zend_module_entry *module;
    1106             : 
    1107           2 :         lcname = zend_string_alloc(name_len, 0);
    1108           2 :         zend_str_tolower_copy(ZSTR_VAL(lcname), name_str, name_len);
    1109           2 :         module = zend_hash_find_ptr(&module_registry, lcname);
    1110             :         zend_string_efree(lcname);
    1111           2 :         if (!module) {
    1112           0 :                 return;
    1113             :         }
    1114             : 
    1115           2 :         reflection_instantiate(reflection_extension_ptr, object);
    1116           2 :         intern = Z_REFLECTION_P(object);
    1117           4 :         ZVAL_STRINGL(&name, module->name, name_len);
    1118           2 :         intern->ptr = module;
    1119           2 :         intern->ref_type = REF_TYPE_OTHER;
    1120           2 :         intern->ce = NULL;
    1121           6 :         reflection_update_property_name(object, &name);
    1122             : }
    1123             : /* }}} */
    1124             : 
    1125             : /* {{{ reflection_parameter_factory */
    1126         263 : static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, uint32_t offset, zend_bool required, zval *object)
    1127             : {
    1128             :         reflection_object *intern;
    1129             :         parameter_reference *reference;
    1130             :         zval name;
    1131             : 
    1132         263 :         if (arg_info->name) {
    1133         389 :                 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
    1134         126 :                     !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
    1135         238 :                         ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)->name);
    1136             :                 } else {
    1137         288 :                         ZVAL_STR_COPY(&name, arg_info->name);
    1138             :                 }
    1139             :         } else {
    1140           0 :                 ZVAL_NULL(&name);
    1141             :         }
    1142         263 :         reflection_instantiate(reflection_parameter_ptr, object);
    1143         263 :         intern = Z_REFLECTION_P(object);
    1144         263 :         reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
    1145         263 :         reference->arg_info = arg_info;
    1146         263 :         reference->offset = offset;
    1147         263 :         reference->required = required;
    1148         263 :         reference->fptr = fptr;
    1149         263 :         intern->ptr = reference;
    1150         263 :         intern->ref_type = REF_TYPE_PARAMETER;
    1151         263 :         intern->ce = fptr->common.scope;
    1152         263 :         if (closure_object) {
    1153             :                 Z_ADDREF_P(closure_object);
    1154          16 :                 ZVAL_COPY_VALUE(&intern->obj, closure_object);
    1155             :         }
    1156         789 :         reflection_update_property_name(object, &name);
    1157         263 : }
    1158             : /* }}} */
    1159             : 
    1160             : /* {{{ reflection_type_factory */
    1161          51 : static void reflection_type_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zval *object)
    1162             : {
    1163             :         reflection_object *intern;
    1164             :         type_reference *reference;
    1165             : 
    1166          51 :         reflection_instantiate(reflection_named_type_ptr, object);
    1167          51 :         intern = Z_REFLECTION_P(object);
    1168          51 :         reference = (type_reference*) emalloc(sizeof(type_reference));
    1169          51 :         reference->arg_info = arg_info;
    1170          51 :         reference->fptr = fptr;
    1171          51 :         intern->ptr = reference;
    1172          51 :         intern->ref_type = REF_TYPE_TYPE;
    1173          51 :         intern->ce = fptr->common.scope;
    1174          51 :         if (closure_object) {
    1175             :                 Z_ADDREF_P(closure_object);
    1176          19 :                 ZVAL_COPY_VALUE(&intern->obj, closure_object);
    1177             :         }
    1178          51 : }
    1179             : /* }}} */
    1180             : 
    1181             : /* {{{ reflection_function_factory */
    1182        1084 : static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object)
    1183             : {
    1184             :         reflection_object *intern;
    1185             :         zval name;
    1186             : 
    1187        2176 :         ZVAL_STR_COPY(&name, function->common.function_name);
    1188             : 
    1189        1084 :         reflection_instantiate(reflection_function_ptr, object);
    1190        1084 :         intern = Z_REFLECTION_P(object);
    1191        1084 :         intern->ptr = function;
    1192        1084 :         intern->ref_type = REF_TYPE_FUNCTION;
    1193        1084 :         intern->ce = NULL;
    1194        1084 :         if (closure_object) {
    1195             :                 Z_ADDREF_P(closure_object);
    1196           5 :                 ZVAL_COPY_VALUE(&intern->obj, closure_object);
    1197             :         }
    1198        3252 :         reflection_update_property_name(object, &name);
    1199        1084 : }
    1200             : /* }}} */
    1201             : 
    1202             : /* {{{ reflection_method_factory */
    1203         339 : static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object)
    1204             : {
    1205             :         reflection_object *intern;
    1206             :         zval name;
    1207             :         zval classname;
    1208             : 
    1209         786 :         ZVAL_STR_COPY(&name, (method->common.scope && method->common.scope->trait_aliases)?
    1210             :                         zend_resolve_method_name(ce, method) : method->common.function_name);
    1211         678 :         ZVAL_STR_COPY(&classname, method->common.scope->name);
    1212         339 :         reflection_instantiate(reflection_method_ptr, object);
    1213         339 :         intern = Z_REFLECTION_P(object);
    1214         339 :         intern->ptr = method;
    1215         339 :         intern->ref_type = REF_TYPE_FUNCTION;
    1216         339 :         intern->ce = ce;
    1217         339 :         if (closure_object) {
    1218             :                 Z_ADDREF_P(closure_object);
    1219           0 :                 ZVAL_COPY_VALUE(&intern->obj, closure_object);
    1220             :         }
    1221        1017 :         reflection_update_property_name(object, &name);
    1222        1017 :         reflection_update_property_class(object, &classname);
    1223         339 : }
    1224             : /* }}} */
    1225             : 
    1226             : /* {{{ reflection_property_factory */
    1227         165 : static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object)
    1228             : {
    1229             :         reflection_object *intern;
    1230             :         zval propname;
    1231             :         zval classname;
    1232             :         property_reference *reference;
    1233             : 
    1234         165 :         if (!(prop->flags & ZEND_ACC_PRIVATE)) {
    1235             :                 /* we have to search the class hierarchy for this (implicit) public or protected property */
    1236         132 :                 zend_class_entry *tmp_ce = ce, *store_ce = ce;
    1237         132 :                 zend_property_info *tmp_info = NULL;
    1238             : 
    1239         418 :                 while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, name)) == NULL) {
    1240          19 :                         ce = tmp_ce;
    1241          19 :                         tmp_ce = tmp_ce->parent;
    1242             :                 }
    1243             : 
    1244         132 :                 if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
    1245         115 :                         prop = tmp_info;
    1246             :                 } else { /* not found, use initial value */
    1247          17 :                         ce = store_ce;
    1248             :                 }
    1249             :         }
    1250             : 
    1251         435 :         ZVAL_STR_COPY(&propname, name);
    1252         330 :         ZVAL_STR_COPY(&classname, prop->ce->name);
    1253             : 
    1254         165 :         reflection_instantiate(reflection_property_ptr, object);
    1255         165 :         intern = Z_REFLECTION_P(object);
    1256         165 :         reference = (property_reference*) emalloc(sizeof(property_reference));
    1257         165 :         reference->ce = ce;
    1258         165 :         reference->prop = *prop;
    1259         165 :         reference->unmangled_name = zend_string_copy(name);
    1260         165 :         intern->ptr = reference;
    1261         165 :         intern->ref_type = REF_TYPE_PROPERTY;
    1262         165 :         intern->ce = ce;
    1263         165 :         intern->ignore_visibility = 0;
    1264         495 :         reflection_update_property_name(object, &propname);
    1265         495 :         reflection_update_property_class(object, &classname);
    1266         165 : }
    1267             : /* }}} */
    1268             : 
    1269         104 : static void reflection_property_factory_str(zend_class_entry *ce, const char *name_str, size_t name_len, zend_property_info *prop, zval *object)
    1270             : {
    1271         104 :         zend_string *name = zend_string_init(name_str, name_len, 0);
    1272         104 :         reflection_property_factory(ce, name, prop, object);
    1273             :         zend_string_release(name);
    1274         104 : }
    1275             : 
    1276             : /* {{{ reflection_class_constant_factory */
    1277           7 : static void reflection_class_constant_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object)
    1278             : {
    1279             :         reflection_object *intern;
    1280             :         zval name;
    1281             :         zval classname;
    1282             : 
    1283          14 :         ZVAL_STR_COPY(&name, name_str);
    1284          14 :         ZVAL_STR_COPY(&classname, ce->name);
    1285             : 
    1286           7 :         reflection_instantiate(reflection_class_constant_ptr, object);
    1287           7 :         intern = Z_REFLECTION_P(object);
    1288           7 :         intern->ptr = constant;
    1289           7 :         intern->ref_type = REF_TYPE_CLASS_CONSTANT;
    1290           7 :         intern->ce = constant->ce;
    1291           7 :         intern->ignore_visibility = 0;
    1292          21 :         reflection_update_property_name(object, &name);
    1293          21 :         reflection_update_property_class(object, &classname);
    1294           7 : }
    1295             : /* }}} */
    1296             : 
    1297             : /* {{{ _reflection_export */
    1298          58 : static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
    1299             : {
    1300             :         zval reflector;
    1301             :         zval *argument_ptr, *argument2_ptr;
    1302             :         zval retval, params[2];
    1303             :         int result;
    1304          58 :         int return_output = 0;
    1305             :         zend_fcall_info fci;
    1306             :         zend_fcall_info_cache fcc;
    1307             : 
    1308          58 :         if (ctor_argc == 1) {
    1309          20 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &argument_ptr, &return_output) == FAILURE) {
    1310          11 :                         return;
    1311             :                 }
    1312          20 :                 ZVAL_COPY_VALUE(&params[0], argument_ptr);
    1313          20 :                 ZVAL_NULL(&params[1]);
    1314             :         } else {
    1315          38 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
    1316           4 :                         return;
    1317             :                 }
    1318          34 :                 ZVAL_COPY_VALUE(&params[0], argument_ptr);
    1319          34 :                 ZVAL_COPY_VALUE(&params[1], argument2_ptr);
    1320             :         }
    1321             : 
    1322             :         /* Create object */
    1323          54 :         if (object_and_properties_init(&reflector, ce_ptr, NULL) == FAILURE) {
    1324           0 :                 _DO_THROW("Could not create reflector");
    1325             :         }
    1326             : 
    1327             :         /* Call __construct() */
    1328             : 
    1329          54 :         fci.size = sizeof(fci);
    1330          54 :         ZVAL_UNDEF(&fci.function_name);
    1331          54 :         fci.object = Z_OBJ(reflector);
    1332          54 :         fci.retval = &retval;
    1333          54 :         fci.param_count = ctor_argc;
    1334          54 :         fci.params = params;
    1335          54 :         fci.no_separation = 1;
    1336             : 
    1337          54 :         fcc.function_handler = ce_ptr->constructor;
    1338          54 :         fcc.called_scope = Z_OBJCE(reflector);
    1339          54 :         fcc.object = Z_OBJ(reflector);
    1340             : 
    1341          54 :         result = zend_call_function(&fci, &fcc);
    1342             : 
    1343          54 :         zval_ptr_dtor(&retval);
    1344             : 
    1345          54 :         if (EG(exception)) {
    1346           7 :                 zval_ptr_dtor(&reflector);
    1347           7 :                 return;
    1348             :         }
    1349          47 :         if (result == FAILURE) {
    1350           0 :                 zval_ptr_dtor(&reflector);
    1351           0 :                 _DO_THROW("Could not create reflector");
    1352             :         }
    1353             : 
    1354             :         /* Call static reflection::export */
    1355          47 :         ZVAL_COPY_VALUE(&params[0], &reflector);
    1356          47 :         ZVAL_BOOL(&params[1], return_output);
    1357             : 
    1358          94 :         ZVAL_STRINGL(&fci.function_name, "reflection::export", sizeof("reflection::export") - 1);
    1359          47 :         fci.object = NULL;
    1360          47 :         fci.retval = &retval;
    1361          47 :         fci.param_count = 2;
    1362          47 :         fci.params = params;
    1363          47 :         fci.no_separation = 1;
    1364             : 
    1365          47 :         result = zend_call_function(&fci, NULL);
    1366             : 
    1367          47 :         zval_ptr_dtor(&fci.function_name);
    1368             : 
    1369          47 :         if (result == FAILURE && EG(exception) == NULL) {
    1370           0 :                 zval_ptr_dtor(&reflector);
    1371           0 :                 zval_ptr_dtor(&retval);
    1372           0 :                 _DO_THROW("Could not execute reflection::export()");
    1373             :         }
    1374             : 
    1375          47 :         if (return_output) {
    1376          18 :                 ZVAL_COPY_VALUE(return_value, &retval);
    1377             :         } else {
    1378          29 :                 zval_ptr_dtor(&retval);
    1379             :         }
    1380             : 
    1381             :         /* Destruct reflector which is no longer needed */
    1382          47 :         zval_ptr_dtor(&reflector);
    1383             : }
    1384             : /* }}} */
    1385             : 
    1386             : /* {{{ _reflection_param_get_default_param */
    1387          42 : static parameter_reference *_reflection_param_get_default_param(INTERNAL_FUNCTION_PARAMETERS)
    1388             : {
    1389             :         reflection_object *intern;
    1390             :         parameter_reference *param;
    1391             : 
    1392          84 :         intern = Z_REFLECTION_P(getThis());
    1393          42 :         if (intern->ptr == NULL) {
    1394           0 :                 if (EG(exception) && EG(exception)->ce == reflection_exception_ptr) {
    1395           0 :                         return NULL;
    1396             :                 }
    1397           0 :                 zend_throw_error(NULL, "Internal error: Failed to retrieve the reflection object");
    1398           0 :                 return NULL;
    1399             :         }
    1400             : 
    1401          42 :         param = intern->ptr;
    1402          42 :         if (param->fptr->type != ZEND_USER_FUNCTION) {
    1403           0 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Cannot determine default value for internal functions");
    1404           0 :                 return NULL;
    1405             :         }
    1406             : 
    1407          42 :         return param;
    1408             : }
    1409             : /* }}} */
    1410             : 
    1411             : /* {{{ _reflection_param_get_default_precv */
    1412          42 : static zend_op *_reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAMETERS, parameter_reference *param)
    1413             : {
    1414             :         zend_op *precv;
    1415             : 
    1416          42 :         if (param == NULL) {
    1417           0 :                 return NULL;
    1418             :         }
    1419             : 
    1420          42 :         precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
    1421          42 :         if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
    1422           1 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Internal error: Failed to retrieve the default value");
    1423           1 :                 return NULL;
    1424             :         }
    1425             : 
    1426          41 :         return precv;
    1427             : }
    1428             : /* }}} */
    1429             : 
    1430             : /* {{{ Preventing __clone from being called */
    1431           0 : ZEND_METHOD(reflection, __clone)
    1432             : {
    1433             :         /* Should never be executable */
    1434           0 :         _DO_THROW("Cannot clone object using __clone()");
    1435             : }
    1436             : /* }}} */
    1437             : 
    1438             : /* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
    1439             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    1440         189 : ZEND_METHOD(reflection, export)
    1441             : {
    1442             :         zval *object, fname, retval;
    1443             :         int result;
    1444         189 :         zend_bool return_output = 0;
    1445             : 
    1446         189 :         ZEND_PARSE_PARAMETERS_START(1, 2)
    1447         378 :                 Z_PARAM_OBJECT_OF_CLASS(object, reflector_ptr)
    1448         189 :                 Z_PARAM_OPTIONAL
    1449         236 :                 Z_PARAM_BOOL(return_output)
    1450         189 :         ZEND_PARSE_PARAMETERS_END();
    1451             : 
    1452             :         /* Invoke the __toString() method */
    1453         378 :         ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1);
    1454         189 :         result= call_user_function(NULL, object, &fname, &retval, 0, NULL);
    1455             :         zval_ptr_dtor_str(&fname);
    1456             : 
    1457         189 :         if (result == FAILURE) {
    1458           0 :                 _DO_THROW("Invocation of method __toString() failed");
    1459             :                 /* Returns from this function */
    1460             :         }
    1461             : 
    1462         189 :         if (Z_TYPE(retval) == IS_UNDEF) {
    1463           0 :                 php_error_docref(NULL, E_WARNING, "%s::__toString() did not return anything", ZSTR_VAL(Z_OBJCE_P(object)->name));
    1464           0 :                 RETURN_FALSE;
    1465             :         }
    1466             : 
    1467         189 :         if (return_output) {
    1468          18 :                 ZVAL_COPY_VALUE(return_value, &retval);
    1469             :         } else {
    1470             :                 /* No need for _r variant, return of __toString should always be a string */
    1471         171 :                 zend_print_zval(&retval, 0);
    1472         171 :                 zend_printf("\n");
    1473         171 :                 zval_ptr_dtor(&retval);
    1474             :         }
    1475             : }
    1476             : /* }}} */
    1477             : 
    1478             : /* {{{ proto public static array Reflection::getModifierNames(int modifiers)
    1479             :    Returns an array of modifier names */
    1480          18 : ZEND_METHOD(reflection, getModifierNames)
    1481             : {
    1482             :         zend_long modifiers;
    1483             : 
    1484          18 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &modifiers) == FAILURE) {
    1485           0 :                 return;
    1486             :         }
    1487             : 
    1488          18 :         array_init(return_value);
    1489             : 
    1490          18 :         if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
    1491           3 :                 add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1);
    1492             :         }
    1493          18 :         if (modifiers & ZEND_ACC_FINAL) {
    1494           3 :                 add_next_index_stringl(return_value, "final", sizeof("final")-1);
    1495             :         }
    1496          18 :         if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
    1497           1 :                 add_next_index_stringl(return_value, "public", sizeof("public")-1);
    1498             :         }
    1499             : 
    1500             :         /* These are mutually exclusive */
    1501          18 :         switch (modifiers & ZEND_ACC_PPP_MASK) {
    1502           7 :                 case ZEND_ACC_PUBLIC:
    1503           7 :                         add_next_index_stringl(return_value, "public", sizeof("public")-1);
    1504           7 :                         break;
    1505           2 :                 case ZEND_ACC_PRIVATE:
    1506           2 :                         add_next_index_stringl(return_value, "private", sizeof("private")-1);
    1507           2 :                         break;
    1508           4 :                 case ZEND_ACC_PROTECTED:
    1509           4 :                         add_next_index_stringl(return_value, "protected", sizeof("protected")-1);
    1510           4 :                         break;
    1511             :         }
    1512             : 
    1513          18 :         if (modifiers & ZEND_ACC_STATIC) {
    1514           3 :                 add_next_index_stringl(return_value, "static", sizeof("static")-1);
    1515             :         }
    1516             : }
    1517             : /* }}} */
    1518             : 
    1519             : /* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
    1520             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    1521           2 : ZEND_METHOD(reflection_function, export)
    1522             : {
    1523           2 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
    1524           2 : }
    1525             : /* }}} */
    1526             : 
    1527             : /* {{{ proto public void ReflectionFunction::__construct(string name)
    1528             :    Constructor. Throws an Exception in case the given function does not exist */
    1529         438 : ZEND_METHOD(reflection_function, __construct)
    1530             : {
    1531             :         zval name;
    1532             :         zval *object;
    1533         438 :         zval *closure = NULL;
    1534             :         reflection_object *intern;
    1535             :         zend_function *fptr;
    1536             :         zend_string *fname, *lcname;
    1537             : 
    1538         876 :         object = getThis();
    1539         438 :         intern = Z_REFLECTION_P(object);
    1540             : 
    1541         438 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &closure, zend_ce_closure) == SUCCESS) {
    1542          32 :                 fptr = (zend_function*)zend_get_closure_method_def(closure);
    1543          32 :                 Z_ADDREF_P(closure);
    1544             :         } else {
    1545             :                 ALLOCA_FLAG(use_heap)
    1546             : 
    1547         406 :                 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S", &fname) == FAILURE) {
    1548          11 :                         return;
    1549             :                 }
    1550             : 
    1551         402 :                 if (UNEXPECTED(ZSTR_VAL(fname)[0] == '\\')) {
    1552             :                         /* Ignore leading "\" */
    1553           3 :                         ZSTR_ALLOCA_ALLOC(lcname, ZSTR_LEN(fname) - 1, use_heap);
    1554           1 :                         zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(fname) + 1, ZSTR_LEN(fname) - 1);
    1555           1 :                         fptr = zend_fetch_function(lcname);
    1556           1 :                         ZSTR_ALLOCA_FREE(lcname, use_heap);
    1557             :                 } else {
    1558         401 :                         lcname = zend_string_tolower(fname);
    1559         401 :                         fptr = zend_fetch_function(lcname);
    1560             :                         zend_string_release(lcname);
    1561             :                 }
    1562             : 
    1563         402 :                 if (fptr == NULL) {
    1564           3 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    1565           3 :                                 "Function %s() does not exist", ZSTR_VAL(fname));
    1566           3 :                         return;
    1567             :                 }
    1568             :         }
    1569             : 
    1570         949 :         ZVAL_STR_COPY(&name, fptr->common.function_name);
    1571        1293 :         reflection_update_property_name(object, &name);
    1572         431 :         intern->ptr = fptr;
    1573         431 :         intern->ref_type = REF_TYPE_FUNCTION;
    1574         431 :         if (closure) {
    1575          32 :                 ZVAL_COPY_VALUE(&intern->obj, closure);
    1576             :         } else {
    1577         399 :                 ZVAL_UNDEF(&intern->obj);
    1578             :         }
    1579         431 :         intern->ce = NULL;
    1580             : }
    1581             : /* }}} */
    1582             : 
    1583             : /* {{{ proto public string ReflectionFunction::__toString()
    1584             :    Returns a string representation */
    1585         135 : ZEND_METHOD(reflection_function, __toString)
    1586             : {
    1587             :         reflection_object *intern;
    1588             :         zend_function *fptr;
    1589         135 :         smart_str str = {0};
    1590             : 
    1591         135 :         if (zend_parse_parameters_none() == FAILURE) {
    1592           0 :                 return;
    1593             :         }
    1594         270 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1595         135 :         _function_string(&str, fptr, intern->ce, "");
    1596         405 :         RETURN_STR(smart_str_extract(&str));
    1597             : }
    1598             : /* }}} */
    1599             : 
    1600             : /* {{{ proto public string ReflectionFunction::getName()
    1601             :    Returns this function's name */
    1602         279 : ZEND_METHOD(reflection_function, getName)
    1603             : {
    1604         279 :         if (zend_parse_parameters_none() == FAILURE) {
    1605           1 :                 return;
    1606             :         }
    1607         556 :         _default_get_name(getThis(), return_value);
    1608             : }
    1609             : /* }}} */
    1610             : 
    1611             : /* {{{ proto public bool ReflectionFunction::isClosure()
    1612             :    Returns whether this is a closure */
    1613           2 : ZEND_METHOD(reflection_function, isClosure)
    1614             : {
    1615             :         reflection_object *intern;
    1616             :         zend_function *fptr;
    1617             : 
    1618           2 :         if (zend_parse_parameters_none() == FAILURE) {
    1619           0 :                 return;
    1620             :         }
    1621           4 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1622           2 :         RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
    1623             : }
    1624             : /* }}} */
    1625             : 
    1626             : /* {{{ proto public bool ReflectionFunction::getClosureThis()
    1627             :    Returns this pointer bound to closure */
    1628           4 : ZEND_METHOD(reflection_function, getClosureThis)
    1629             : {
    1630             :         reflection_object *intern;
    1631             :         zval* closure_this;
    1632             : 
    1633           4 :         if (zend_parse_parameters_none() == FAILURE) {
    1634           0 :                 return;
    1635             :         }
    1636           8 :         GET_REFLECTION_OBJECT();
    1637           8 :         if (!Z_ISUNDEF(intern->obj)) {
    1638           4 :                 closure_this = zend_get_closure_this_ptr(&intern->obj);
    1639           4 :                 if (!Z_ISUNDEF_P(closure_this)) {
    1640           2 :                         ZVAL_COPY(return_value, closure_this);
    1641             :                 }
    1642             :         }
    1643             : }
    1644             : /* }}} */
    1645             : 
    1646             : /* {{{ proto public ReflectionClass ReflectionFunction::getClosureScopeClass()
    1647             :    Returns the scope associated to the closure */
    1648           5 : ZEND_METHOD(reflection_function, getClosureScopeClass)
    1649             : {
    1650             :         reflection_object *intern;
    1651             :         const zend_function *closure_func;
    1652             : 
    1653           5 :         if (zend_parse_parameters_none() == FAILURE) {
    1654           0 :                 return;
    1655             :         }
    1656          10 :         GET_REFLECTION_OBJECT();
    1657          10 :         if (!Z_ISUNDEF(intern->obj)) {
    1658           5 :                 closure_func = zend_get_closure_method_def(&intern->obj);
    1659           5 :                 if (closure_func && closure_func->common.scope) {
    1660           4 :                         zend_reflection_class_factory(closure_func->common.scope, return_value);
    1661             :                 }
    1662             :         }
    1663             : }
    1664             : /* }}} */
    1665             : 
    1666             : /* {{{ proto public mixed ReflectionFunction::getClosure()
    1667             :    Returns a dynamically created closure for the function */
    1668          12 : ZEND_METHOD(reflection_function, getClosure)
    1669             : {
    1670             :         reflection_object *intern;
    1671             :         zend_function *fptr;
    1672             : 
    1673          12 :         if (zend_parse_parameters_none() == FAILURE) {
    1674           1 :                 return;
    1675             :         }
    1676          22 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1677             : 
    1678          22 :         if (!Z_ISUNDEF(intern->obj)) {
    1679             :                 /* Closures are immutable objects */
    1680           2 :                 ZVAL_COPY(return_value, &intern->obj);
    1681             :         } else {
    1682           9 :                 zend_create_fake_closure(return_value, fptr, NULL, NULL, NULL);
    1683             :         }
    1684             : }
    1685             : /* }}} */
    1686             : 
    1687             : /* {{{ proto public bool ReflectionFunction::isInternal()
    1688             :    Returns whether this is an internal function */
    1689          76 : ZEND_METHOD(reflection_function, isInternal)
    1690             : {
    1691             :         reflection_object *intern;
    1692             :         zend_function *fptr;
    1693             : 
    1694          76 :         if (zend_parse_parameters_none() == FAILURE) {
    1695           1 :                 return;
    1696             :         }
    1697         150 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1698          75 :         RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION);
    1699             : }
    1700             : /* }}} */
    1701             : 
    1702             : /* {{{ proto public bool ReflectionFunction::isUserDefined()
    1703             :    Returns whether this is a user-defined function */
    1704          76 : ZEND_METHOD(reflection_function, isUserDefined)
    1705             : {
    1706             :         reflection_object *intern;
    1707             :         zend_function *fptr;
    1708             : 
    1709          76 :         if (zend_parse_parameters_none() == FAILURE) {
    1710           1 :                 return;
    1711             :         }
    1712         150 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1713          75 :         RETURN_BOOL(fptr->type == ZEND_USER_FUNCTION);
    1714             : }
    1715             : /* }}} */
    1716             : 
    1717             : /* {{{ proto public bool ReflectionFunction::isDisabled()
    1718             :    Returns whether this function has been disabled or not */
    1719           1 : ZEND_METHOD(reflection_function, isDisabled)
    1720             : {
    1721             :         reflection_object *intern;
    1722             :         zend_function *fptr;
    1723             : 
    1724           2 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1725           1 :         RETURN_BOOL(fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.handler == zif_display_disabled_function);
    1726             : }
    1727             : /* }}} */
    1728             : 
    1729             : /* {{{ proto public string ReflectionFunction::getFileName()
    1730             :    Returns the filename of the file this function was declared in */
    1731          15 : ZEND_METHOD(reflection_function, getFileName)
    1732             : {
    1733             :         reflection_object *intern;
    1734             :         zend_function *fptr;
    1735             : 
    1736          15 :         if (zend_parse_parameters_none() == FAILURE) {
    1737           1 :                 return;
    1738             :         }
    1739          28 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1740          14 :         if (fptr->type == ZEND_USER_FUNCTION) {
    1741          24 :                 RETURN_STR_COPY(fptr->op_array.filename);
    1742             :         }
    1743           2 :         RETURN_FALSE;
    1744             : }
    1745             : /* }}} */
    1746             : 
    1747             : /* {{{ proto public int ReflectionFunction::getStartLine()
    1748             :    Returns the line this function's declaration starts at */
    1749          14 : ZEND_METHOD(reflection_function, getStartLine)
    1750             : {
    1751             :         reflection_object *intern;
    1752             :         zend_function *fptr;
    1753             : 
    1754          14 :         if (zend_parse_parameters_none() == FAILURE) {
    1755           1 :                 return;
    1756             :         }
    1757          26 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1758          13 :         if (fptr->type == ZEND_USER_FUNCTION) {
    1759          11 :                 RETURN_LONG(fptr->op_array.line_start);
    1760             :         }
    1761           2 :         RETURN_FALSE;
    1762             : }
    1763             : /* }}} */
    1764             : 
    1765             : /* {{{ proto public int ReflectionFunction::getEndLine()
    1766             :    Returns the line this function's declaration ends at */
    1767          14 : ZEND_METHOD(reflection_function, getEndLine)
    1768             : {
    1769             :         reflection_object *intern;
    1770             :         zend_function *fptr;
    1771             : 
    1772          14 :         if (zend_parse_parameters_none() == FAILURE) {
    1773           1 :                 return;
    1774             :         }
    1775          26 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1776          13 :         if (fptr->type == ZEND_USER_FUNCTION) {
    1777          11 :                 RETURN_LONG(fptr->op_array.line_end);
    1778             :         }
    1779           2 :         RETURN_FALSE;
    1780             : }
    1781             : /* }}} */
    1782             : 
    1783             : /* {{{ proto public string ReflectionFunction::getDocComment()
    1784             :    Returns the doc comment for this function */
    1785          24 : ZEND_METHOD(reflection_function, getDocComment)
    1786             : {
    1787             :         reflection_object *intern;
    1788             :         zend_function *fptr;
    1789             : 
    1790          24 :         if (zend_parse_parameters_none() == FAILURE) {
    1791           2 :                 return;
    1792             :         }
    1793          44 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1794          22 :         if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
    1795          45 :                 RETURN_STR_COPY(fptr->op_array.doc_comment);
    1796             :         }
    1797           7 :         RETURN_FALSE;
    1798             : }
    1799             : /* }}} */
    1800             : 
    1801             : /* {{{ proto public array ReflectionFunction::getStaticVariables()
    1802             :    Returns an associative array containing this function's static variables and their values */
    1803          75 : ZEND_METHOD(reflection_function, getStaticVariables)
    1804             : {
    1805             :         reflection_object *intern;
    1806             :         zend_function *fptr;
    1807             :         zval *val;
    1808             : 
    1809          75 :         if (zend_parse_parameters_none() == FAILURE) {
    1810           1 :                 return;
    1811             :         }
    1812         148 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1813             : 
    1814             :         /* Return an empty array in case no static variables exist */
    1815          74 :         if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
    1816           8 :                 array_init(return_value);
    1817          16 :                 if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) {
    1818           0 :                         if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
    1819           0 :                                 GC_DELREF(fptr->op_array.static_variables);
    1820             :                         }
    1821           0 :                         fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables);
    1822             :                 }
    1823          32 :                 ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) {
    1824          12 :                         if (UNEXPECTED(zval_update_constant_ex(val, fptr->common.scope) != SUCCESS)) {
    1825           0 :                                 return;
    1826             :                         }
    1827             :                 } ZEND_HASH_FOREACH_END();
    1828           8 :                 zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref);
    1829             :         } else {
    1830          66 :                 ZVAL_EMPTY_ARRAY(return_value);
    1831             :         }
    1832             : }
    1833             : /* }}} */
    1834             : 
    1835             : /* {{{ proto public mixed ReflectionFunction::invoke([mixed* args])
    1836             :    Invokes the function */
    1837           6 : ZEND_METHOD(reflection_function, invoke)
    1838             : {
    1839             :         zval retval;
    1840           6 :         zval *params = NULL;
    1841           6 :         int result, num_args = 0;
    1842             :         zend_fcall_info fci;
    1843             :         zend_fcall_info_cache fcc;
    1844             :         reflection_object *intern;
    1845             :         zend_function *fptr;
    1846             : 
    1847          12 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1848             : 
    1849           6 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &params, &num_args) == FAILURE) {
    1850           0 :                 return;
    1851             :         }
    1852             : 
    1853           6 :         fci.size = sizeof(fci);
    1854           6 :         ZVAL_UNDEF(&fci.function_name);
    1855           6 :         fci.object = NULL;
    1856           6 :         fci.retval = &retval;
    1857           6 :         fci.param_count = num_args;
    1858           6 :         fci.params = params;
    1859           6 :         fci.no_separation = 1;
    1860             : 
    1861           6 :         fcc.function_handler = fptr;
    1862           6 :         fcc.called_scope = NULL;
    1863           6 :         fcc.object = NULL;
    1864             : 
    1865          12 :         if (!Z_ISUNDEF(intern->obj)) {
    1866           1 :                 Z_OBJ_HT(intern->obj)->get_closure(
    1867             :                         &intern->obj, &fcc.called_scope, &fcc.function_handler, &fcc.object);
    1868             :         }
    1869             : 
    1870           6 :         result = zend_call_function(&fci, &fcc);
    1871             : 
    1872           6 :         if (result == FAILURE) {
    1873           0 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    1874           0 :                         "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
    1875           0 :                 return;
    1876             :         }
    1877             : 
    1878           6 :         if (Z_TYPE(retval) != IS_UNDEF) {
    1879           6 :                 if (Z_ISREF(retval)) {
    1880             :                         zend_unwrap_reference(&retval);
    1881             :                 }
    1882           6 :                 ZVAL_COPY_VALUE(return_value, &retval);
    1883             :         }
    1884             : }
    1885             : /* }}} */
    1886             : 
    1887             : /* {{{ proto public mixed ReflectionFunction::invokeArgs(array args)
    1888             :    Invokes the function and pass its arguments as array. */
    1889           4 : ZEND_METHOD(reflection_function, invokeArgs)
    1890             : {
    1891             :         zval retval;
    1892             :         zval *params, *val;
    1893             :         int result;
    1894             :         int i, argc;
    1895             :         zend_fcall_info fci;
    1896             :         zend_fcall_info_cache fcc;
    1897             :         reflection_object *intern;
    1898             :         zend_function *fptr;
    1899             :         zval *param_array;
    1900             : 
    1901           8 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1902             : 
    1903           4 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &param_array) == FAILURE) {
    1904           0 :                 return;
    1905             :         }
    1906             : 
    1907           4 :         argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
    1908             : 
    1909           4 :         params = safe_emalloc(sizeof(zval), argc, 0);
    1910           4 :         argc = 0;
    1911          20 :         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(param_array), val) {
    1912           8 :                 ZVAL_COPY(&params[argc], val);
    1913           8 :                 argc++;
    1914             :         } ZEND_HASH_FOREACH_END();
    1915             : 
    1916           4 :         fci.size = sizeof(fci);
    1917           4 :         ZVAL_UNDEF(&fci.function_name);
    1918           4 :         fci.object = NULL;
    1919           4 :         fci.retval = &retval;
    1920           4 :         fci.param_count = argc;
    1921           4 :         fci.params = params;
    1922           4 :         fci.no_separation = 1;
    1923             : 
    1924           4 :         fcc.function_handler = fptr;
    1925           4 :         fcc.called_scope = NULL;
    1926           4 :         fcc.object = NULL;
    1927             : 
    1928           8 :         if (!Z_ISUNDEF(intern->obj)) {
    1929           0 :                 Z_OBJ_HT(intern->obj)->get_closure(
    1930             :                         &intern->obj, &fcc.called_scope, &fcc.function_handler, &fcc.object);
    1931             :         }
    1932             : 
    1933           4 :         result = zend_call_function(&fci, &fcc);
    1934             : 
    1935          12 :         for (i = 0; i < argc; i++) {
    1936           8 :                 zval_ptr_dtor(&params[i]);
    1937             :         }
    1938           4 :         efree(params);
    1939             : 
    1940           4 :         if (result == FAILURE) {
    1941           0 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    1942           0 :                         "Invocation of function %s() failed", ZSTR_VAL(fptr->common.function_name));
    1943           0 :                 return;
    1944             :         }
    1945             : 
    1946           4 :         if (Z_TYPE(retval) != IS_UNDEF) {
    1947           4 :                 if (Z_ISREF(retval)) {
    1948             :                         zend_unwrap_reference(&retval);
    1949             :                 }
    1950           4 :                 ZVAL_COPY_VALUE(return_value, &retval);
    1951             :         }
    1952             : }
    1953             : /* }}} */
    1954             : 
    1955             : /* {{{ proto public bool ReflectionFunction::returnsReference()
    1956             :    Gets whether this function returns a reference */
    1957          66 : ZEND_METHOD(reflection_function, returnsReference)
    1958             : {
    1959             :         reflection_object *intern;
    1960             :         zend_function *fptr;
    1961             : 
    1962         132 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1963             : 
    1964          66 :         RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
    1965             : }
    1966             : /* }}} */
    1967             : 
    1968             : /* {{{ proto public bool ReflectionFunction::getNumberOfParameters()
    1969             :    Gets the number of parameters */
    1970         105 : ZEND_METHOD(reflection_function, getNumberOfParameters)
    1971             : {
    1972             :         reflection_object *intern;
    1973             :         zend_function *fptr;
    1974             :         uint32_t num_args;
    1975             : 
    1976         210 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1977             : 
    1978         105 :         num_args = fptr->common.num_args;
    1979         105 :         if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
    1980           0 :                 num_args++;
    1981             :         }
    1982             : 
    1983         105 :         RETURN_LONG(num_args);
    1984             : }
    1985             : /* }}} */
    1986             : 
    1987             : /* {{{ proto public bool ReflectionFunction::getNumberOfRequiredParameters()
    1988             :    Gets the number of required parameters */
    1989         286 : ZEND_METHOD(reflection_function, getNumberOfRequiredParameters)
    1990             : {
    1991             :         reflection_object *intern;
    1992             :         zend_function *fptr;
    1993             : 
    1994         572 :         GET_REFLECTION_OBJECT_PTR(fptr);
    1995             : 
    1996         286 :         RETURN_LONG(fptr->common.required_num_args);
    1997             : }
    1998             : /* }}} */
    1999             : 
    2000             : /* {{{ proto public ReflectionParameter[] ReflectionFunction::getParameters()
    2001             :    Returns an array of parameter objects for this function */
    2002         143 : ZEND_METHOD(reflection_function, getParameters)
    2003             : {
    2004             :         reflection_object *intern;
    2005             :         zend_function *fptr;
    2006             :         uint32_t i, num_args;
    2007             :         struct _zend_arg_info *arg_info;
    2008             : 
    2009         286 :         GET_REFLECTION_OBJECT_PTR(fptr);
    2010             : 
    2011         143 :         arg_info= fptr->common.arg_info;
    2012         143 :         num_args = fptr->common.num_args;
    2013         143 :         if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
    2014           5 :                 num_args++;
    2015             :         }
    2016             : 
    2017         143 :         if (!num_args) {
    2018          30 :                 ZVAL_EMPTY_ARRAY(return_value);
    2019          30 :                 return;
    2020             :         }
    2021             : 
    2022         113 :         array_init(return_value);
    2023         376 :         for (i = 0; i < num_args; i++) {
    2024             :                 zval parameter;
    2025             : 
    2026         526 :                 reflection_parameter_factory(
    2027             :                         _copy_function(fptr),
    2028         526 :                         Z_ISUNDEF(intern->obj) ? NULL : &intern->obj,
    2029             :                         arg_info,
    2030             :                         i,
    2031         263 :                         i < fptr->common.required_num_args,
    2032             :                         &parameter
    2033             :                 );
    2034         263 :                 add_next_index_zval(return_value, &parameter);
    2035             : 
    2036         263 :                 arg_info++;
    2037             :         }
    2038             : }
    2039             : /* }}} */
    2040             : 
    2041             : /* {{{ proto public ReflectionExtension|NULL ReflectionFunction::getExtension()
    2042             :    Returns NULL or the extension the function belongs to */
    2043           2 : ZEND_METHOD(reflection_function, getExtension)
    2044             : {
    2045             :         reflection_object *intern;
    2046             :         zend_function *fptr;
    2047             :         zend_internal_function *internal;
    2048             : 
    2049           4 :         GET_REFLECTION_OBJECT_PTR(fptr);
    2050             : 
    2051           2 :         if (fptr->type != ZEND_INTERNAL_FUNCTION) {
    2052           1 :                 RETURN_NULL();
    2053             :         }
    2054             : 
    2055           1 :         internal = (zend_internal_function *)fptr;
    2056           1 :         if (internal->module) {
    2057           1 :                 reflection_extension_factory(return_value, internal->module->name);
    2058             :         } else {
    2059           0 :                 RETURN_NULL();
    2060             :         }
    2061             : }
    2062             : /* }}} */
    2063             : 
    2064             : /* {{{ proto public string|false ReflectionFunction::getExtensionName()
    2065             :    Returns false or the name of the extension the function belongs to */
    2066           3 : ZEND_METHOD(reflection_function, getExtensionName)
    2067             : {
    2068             :         reflection_object *intern;
    2069             :         zend_function *fptr;
    2070             :         zend_internal_function *internal;
    2071             : 
    2072           6 :         GET_REFLECTION_OBJECT_PTR(fptr);
    2073             : 
    2074           3 :         if (fptr->type != ZEND_INTERNAL_FUNCTION) {
    2075           1 :                 RETURN_FALSE;
    2076             :         }
    2077             : 
    2078           2 :         internal = (zend_internal_function *)fptr;
    2079           2 :         if (internal->module) {
    2080           4 :                 RETURN_STRING(internal->module->name);
    2081             :         } else {
    2082           0 :                 RETURN_FALSE;
    2083             :         }
    2084             : }
    2085             : /* }}} */
    2086             : 
    2087             : /* {{{ proto public void ReflectionGenerator::__construct(object Generator) */
    2088           7 : ZEND_METHOD(reflection_generator, __construct)
    2089             : {
    2090             :         zval *generator, *object;
    2091             :         reflection_object *intern;
    2092             :         zend_execute_data *ex;
    2093             : 
    2094          14 :         object = getThis();
    2095           7 :         intern = Z_REFLECTION_P(object);
    2096             : 
    2097           7 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "O", &generator, zend_ce_generator) == FAILURE) {
    2098           1 :                 return;
    2099             :         }
    2100             : 
    2101           7 :         ex = ((zend_generator *) Z_OBJ_P(generator))->execute_data;
    2102           7 :         if (!ex) {
    2103           1 :                 _DO_THROW("Cannot create ReflectionGenerator based on a terminated Generator");
    2104             :                 return;
    2105             :         }
    2106             : 
    2107           6 :         intern->ref_type = REF_TYPE_GENERATOR;
    2108           6 :         ZVAL_COPY(&intern->obj, generator);
    2109           6 :         intern->ce = zend_ce_generator;
    2110             : }
    2111             : /* }}} */
    2112             : 
    2113             : #define REFLECTION_CHECK_VALID_GENERATOR(ex) \
    2114             :         if (!ex) { \
    2115             :                 _DO_THROW("Cannot fetch information from a terminated Generator"); \
    2116             :                 return; \
    2117             :         }
    2118             : 
    2119             : /* {{{ proto public array ReflectionGenerator::getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) */
    2120           7 : ZEND_METHOD(reflection_generator, getTrace)
    2121             : {
    2122           7 :         zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
    2123          14 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2124             :         zend_generator *root_generator;
    2125           7 :         zend_execute_data *ex_backup = EG(current_execute_data);
    2126           7 :         zend_execute_data *ex = generator->execute_data;
    2127           7 :         zend_execute_data *root_prev = NULL, *cur_prev;
    2128             : 
    2129           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &options) == FAILURE) {
    2130           1 :                 return;
    2131             :         }
    2132             : 
    2133           7 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2134             : 
    2135           6 :         root_generator = zend_generator_get_current(generator);
    2136             : 
    2137           6 :         cur_prev = generator->execute_data->prev_execute_data;
    2138           6 :         if (generator == root_generator) {
    2139           3 :                 generator->execute_data->prev_execute_data = NULL;
    2140             :         } else {
    2141           3 :                 root_prev = root_generator->execute_data->prev_execute_data;
    2142           3 :                 generator->execute_fake.prev_execute_data = NULL;
    2143           3 :                 root_generator->execute_data->prev_execute_data = &generator->execute_fake;
    2144             :         }
    2145             : 
    2146           6 :         EG(current_execute_data) = root_generator->execute_data;
    2147           6 :         zend_fetch_debug_backtrace(return_value, 0, options, 0);
    2148           6 :         EG(current_execute_data) = ex_backup;
    2149             : 
    2150           6 :         root_generator->execute_data->prev_execute_data = root_prev;
    2151           6 :         generator->execute_data->prev_execute_data = cur_prev;
    2152             : }
    2153             : /* }}} */
    2154             : 
    2155             : /* {{{ proto public int ReflectionGenerator::getExecutingLine() */
    2156           5 : ZEND_METHOD(reflection_generator, getExecutingLine)
    2157             : {
    2158          10 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2159           5 :         zend_execute_data *ex = generator->execute_data;
    2160             : 
    2161           5 :         if (zend_parse_parameters_none() == FAILURE) {
    2162           0 :                 return;
    2163             :         }
    2164             : 
    2165           5 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2166             : 
    2167           5 :         ZVAL_LONG(return_value, ex->opline->lineno);
    2168             : }
    2169             : /* }}} */
    2170             : 
    2171             : /* {{{ proto public string ReflectionGenerator::getExecutingFile() */
    2172           5 : ZEND_METHOD(reflection_generator, getExecutingFile)
    2173             : {
    2174          10 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2175           5 :         zend_execute_data *ex = generator->execute_data;
    2176             : 
    2177           5 :         if (zend_parse_parameters_none() == FAILURE) {
    2178           0 :                 return;
    2179             :         }
    2180             : 
    2181           5 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2182             : 
    2183          10 :         ZVAL_STR_COPY(return_value, ex->func->op_array.filename);
    2184             : }
    2185             : /* }}} */
    2186             : 
    2187             : /* {{{ proto public ReflectionFunctionAbstract ReflectionGenerator::getFunction() */
    2188           5 : ZEND_METHOD(reflection_generator, getFunction)
    2189             : {
    2190          10 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2191           5 :         zend_execute_data *ex = generator->execute_data;
    2192             : 
    2193           5 :         if (zend_parse_parameters_none() == FAILURE) {
    2194           0 :                 return;
    2195             :         }
    2196             : 
    2197           5 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2198             : 
    2199           5 :         if (ex->func->common.fn_flags & ZEND_ACC_CLOSURE) {
    2200             :                 zval closure;
    2201           3 :                 ZVAL_OBJ(&closure, ZEND_CLOSURE_OBJECT(ex->func));
    2202           3 :                 reflection_function_factory(ex->func, &closure, return_value);
    2203           2 :         } else if (ex->func->op_array.scope) {
    2204           1 :                 reflection_method_factory(ex->func->op_array.scope, ex->func, NULL, return_value);
    2205             :         } else {
    2206           1 :                 reflection_function_factory(ex->func, NULL, return_value);
    2207             :         }
    2208             : }
    2209             : /* }}} */
    2210             : 
    2211             : /* {{{ proto public object ReflectionGenerator::getThis() */
    2212           5 : ZEND_METHOD(reflection_generator, getThis)
    2213             : {
    2214          10 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2215           5 :         zend_execute_data *ex = generator->execute_data;
    2216             : 
    2217           5 :         if (zend_parse_parameters_none() == FAILURE) {
    2218           0 :                 return;
    2219             :         }
    2220             : 
    2221           5 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2222             : 
    2223          10 :         if (Z_TYPE(ex->This) == IS_OBJECT) {
    2224           1 :                 ZVAL_COPY(return_value, &ex->This);
    2225             :         } else {
    2226           4 :                 ZVAL_NULL(return_value);
    2227             :         }
    2228             : }
    2229             : /* }}} */
    2230             : 
    2231             : /* {{{ proto public Generator ReflectionGenerator::getExecutingGenerator() */
    2232           5 : ZEND_METHOD(reflection_generator, getExecutingGenerator)
    2233             : {
    2234          10 :         zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(getThis())->obj);
    2235           5 :         zend_execute_data *ex = generator->execute_data;
    2236             :         zend_generator *current;
    2237             : 
    2238           5 :         if (zend_parse_parameters_none() == FAILURE) {
    2239           0 :                 return;
    2240             :         }
    2241             : 
    2242           5 :         REFLECTION_CHECK_VALID_GENERATOR(ex)
    2243             : 
    2244           5 :         current = zend_generator_get_current(generator);
    2245           5 :         GC_ADDREF(&current->std);
    2246             : 
    2247           5 :         ZVAL_OBJ(return_value, (zend_object *) current);
    2248             : }
    2249             : /* }}} */
    2250             : 
    2251             : /* {{{ proto public static mixed ReflectionParameter::export(mixed function, mixed parameter [, bool return]) throws ReflectionException
    2252             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    2253           8 : ZEND_METHOD(reflection_parameter, export)
    2254             : {
    2255           8 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_parameter_ptr, 2);
    2256           8 : }
    2257             : /* }}} */
    2258             : 
    2259             : /* {{{ proto public void ReflectionParameter::__construct(mixed function, mixed parameter)
    2260             :    Constructor. Throws an Exception in case the given method does not exist */
    2261          31 : ZEND_METHOD(reflection_parameter, __construct)
    2262             : {
    2263             :         parameter_reference *ref;
    2264             :         zval *reference, *parameter;
    2265             :         zval *object;
    2266             :         zval name;
    2267             :         reflection_object *intern;
    2268             :         zend_function *fptr;
    2269             :         struct _zend_arg_info *arg_info;
    2270             :         int position;
    2271             :         uint32_t num_args;
    2272          31 :         zend_class_entry *ce = NULL;
    2273          31 :         zend_bool is_closure = 0;
    2274             : 
    2275          31 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zz", &reference, &parameter) == FAILURE) {
    2276          11 :                 return;
    2277             :         }
    2278             : 
    2279          60 :         object = getThis();
    2280          30 :         intern = Z_REFLECTION_P(object);
    2281             : 
    2282             :         /* First, find the function */
    2283          60 :         switch (Z_TYPE_P(reference)) {
    2284           6 :                 case IS_STRING: {
    2285             :                                 size_t lcname_len;
    2286             :                                 char *lcname;
    2287             : 
    2288           6 :                                 lcname_len = Z_STRLEN_P(reference);
    2289           6 :                                 lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
    2290          12 :                                 if ((fptr = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len)) == NULL) {
    2291           0 :                                         efree(lcname);
    2292           0 :                                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    2293           0 :                                                 "Function %s() does not exist", Z_STRVAL_P(reference));
    2294           0 :                                         return;
    2295             :                                 }
    2296           6 :                                 efree(lcname);
    2297             :                         }
    2298           6 :                         ce = fptr->common.scope;
    2299           6 :                         break;
    2300             : 
    2301          15 :                 case IS_ARRAY: {
    2302             :                                 zval *classref;
    2303             :                                 zval *method;
    2304             :                                 size_t lcname_len;
    2305             :                                 char *lcname;
    2306             : 
    2307          15 :                                 if (((classref =zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL)
    2308          15 :                                         || ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL))
    2309             :                                 {
    2310           0 :                                         _DO_THROW("Expected array($object, $method) or array($classname, $method)");
    2311             :                                         /* returns out of this function */
    2312             :                                 }
    2313             : 
    2314          15 :                                 if (Z_TYPE_P(classref) == IS_OBJECT) {
    2315           8 :                                         ce = Z_OBJCE_P(classref);
    2316             :                                 } else {
    2317           7 :                                         convert_to_string_ex(classref);
    2318           7 :                                         if ((ce = zend_lookup_class(Z_STR_P(classref))) == NULL) {
    2319           1 :                                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    2320           1 :                                                                 "Class %s does not exist", Z_STRVAL_P(classref));
    2321           1 :                                                 return;
    2322             :                                         }
    2323             :                                 }
    2324             : 
    2325          14 :                                 convert_to_string_ex(method);
    2326          14 :                                 lcname_len = Z_STRLEN_P(method);
    2327          14 :                                 lcname = zend_str_tolower_dup(Z_STRVAL_P(method), lcname_len);
    2328          19 :                                 if (ce == zend_ce_closure && Z_TYPE_P(classref) == IS_OBJECT
    2329           5 :                                         && (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    2330           5 :                                         && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
    2331           5 :                                         && (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL)
    2332             :                                 {
    2333             :                                         /* nothing to do. don't set is_closure since is the invoke handler,
    2334             :                                            not the closure itself */
    2335          18 :                                 } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
    2336           2 :                                         efree(lcname);
    2337           2 :                                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    2338           2 :                                                 "Method %s::%s() does not exist", ZSTR_VAL(ce->name), Z_STRVAL_P(method));
    2339           2 :                                         return;
    2340             :                                 }
    2341          12 :                                 efree(lcname);
    2342             :                         }
    2343          12 :                         break;
    2344             : 
    2345           7 :                 case IS_OBJECT: {
    2346           7 :                                 ce = Z_OBJCE_P(reference);
    2347             : 
    2348           7 :                                 if (instanceof_function(ce, zend_ce_closure)) {
    2349           6 :                                         fptr = (zend_function *)zend_get_closure_method_def(reference);
    2350           6 :                                         Z_ADDREF_P(reference);
    2351           6 :                                         is_closure = 1;
    2352           2 :                                 } else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME))) == NULL) {
    2353           1 :                                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    2354           1 :                                                 "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME);
    2355           1 :                                         return;
    2356             :                                 }
    2357             :                         }
    2358           6 :                         break;
    2359             : 
    2360           2 :                 default:
    2361           2 :                         _DO_THROW("The parameter class is expected to be either a string, an array(class, method) or a callable object");
    2362             :                         /* returns out of this function */
    2363             :         }
    2364             : 
    2365             :         /* Now, search for the parameter */
    2366          24 :         arg_info = fptr->common.arg_info;
    2367          24 :         num_args = fptr->common.num_args;
    2368          24 :         if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
    2369           0 :                 num_args++;
    2370             :         }
    2371          48 :         if (Z_TYPE_P(parameter) == IS_LONG) {
    2372          12 :                 position= (int)Z_LVAL_P(parameter);
    2373          12 :                 if (position < 0 || (uint32_t)position >= num_args) {
    2374           1 :                         if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
    2375           0 :                                 if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
    2376           0 :                                         zend_string_release_ex(fptr->common.function_name, 0);
    2377             :                                 }
    2378           0 :                                 zend_free_trampoline(fptr);
    2379             :                         }
    2380           1 :                         if (is_closure) {
    2381           1 :                                 zval_ptr_dtor(reference);
    2382             :                         }
    2383           1 :                         _DO_THROW("The parameter specified by its offset could not be found");
    2384             :                         /* returns out of this function */
    2385             :                 }
    2386             :         } else {
    2387             :                 uint32_t i;
    2388             : 
    2389          12 :                 position= -1;
    2390          24 :                 convert_to_string_ex(parameter);
    2391          17 :                 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
    2392           4 :                     !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
    2393           1 :                         for (i = 0; i < num_args; i++) {
    2394           1 :                                 if (arg_info[i].name) {
    2395           1 :                                         if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, Z_STRVAL_P(parameter)) == 0) {
    2396           1 :                                                 position= i;
    2397           1 :                                                 break;
    2398             :                                         }
    2399             : 
    2400             :                                 }
    2401             :                         }
    2402             :                 } else {
    2403          20 :                         for (i = 0; i < num_args; i++) {
    2404          18 :                                 if (arg_info[i].name) {
    2405          18 :                                         if (strcmp(ZSTR_VAL(arg_info[i].name), Z_STRVAL_P(parameter)) == 0) {
    2406           9 :                                                 position= i;
    2407           9 :                                                 break;
    2408             :                                         }
    2409             :                                 }
    2410             :                         }
    2411             :                 }
    2412          12 :                 if (position == -1) {
    2413           2 :                         if (fptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
    2414           0 :                                 if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
    2415           0 :                                         zend_string_release_ex(fptr->common.function_name, 0);
    2416             :                                 }
    2417           0 :                                 zend_free_trampoline(fptr);
    2418             :                         }
    2419           2 :                         if (is_closure) {
    2420           0 :                                 zval_ptr_dtor(reference);
    2421             :                         }
    2422           2 :                         _DO_THROW("The parameter specified by its name could not be found");
    2423             :                         /* returns out of this function */
    2424             :                 }
    2425             :         }
    2426             : 
    2427          21 :         if (arg_info[position].name) {
    2428          28 :                 if (fptr->type == ZEND_INTERNAL_FUNCTION &&
    2429           7 :                     !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
    2430           4 :                         ZVAL_STRING(&name, ((zend_internal_arg_info*)arg_info)[position].name);
    2431             :                 } else {
    2432          38 :                         ZVAL_STR_COPY(&name, arg_info[position].name);
    2433             :                 }
    2434             :         } else {
    2435           0 :                 ZVAL_NULL(&name);
    2436             :         }
    2437          63 :         reflection_update_property_name(object, &name);
    2438             : 
    2439          21 :         ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
    2440          21 :         ref->arg_info = &arg_info[position];
    2441          21 :         ref->offset = (uint32_t)position;
    2442          21 :         ref->required = position < fptr->common.required_num_args;
    2443          21 :         ref->fptr = fptr;
    2444             :         /* TODO: copy fptr */
    2445          21 :         intern->ptr = ref;
    2446          21 :         intern->ref_type = REF_TYPE_PARAMETER;
    2447          21 :         intern->ce = ce;
    2448          21 :         if (reference && is_closure) {
    2449           5 :                 ZVAL_COPY_VALUE(&intern->obj, reference);
    2450             :         }
    2451             : }
    2452             : /* }}} */
    2453             : 
    2454             : /* {{{ proto public string ReflectionParameter::__toString()
    2455             :    Returns a string representation */
    2456           7 : ZEND_METHOD(reflection_parameter, __toString)
    2457             : {
    2458             :         reflection_object *intern;
    2459             :         parameter_reference *param;
    2460           7 :         smart_str str = {0};
    2461             : 
    2462           7 :         if (zend_parse_parameters_none() == FAILURE) {
    2463           0 :                 return;
    2464             :         }
    2465          14 :         GET_REFLECTION_OBJECT_PTR(param);
    2466           7 :         _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, "");
    2467          21 :         RETURN_STR(smart_str_extract(&str));
    2468             : }
    2469             : 
    2470             : /* }}} */
    2471             : 
    2472             : /* {{{ proto public string ReflectionParameter::getName()
    2473             :    Returns this parameters's name */
    2474         195 : ZEND_METHOD(reflection_parameter, getName)
    2475             : {
    2476         195 :         if (zend_parse_parameters_none() == FAILURE) {
    2477           0 :                 return;
    2478             :         }
    2479         390 :         _default_get_name(getThis(), return_value);
    2480             : }
    2481             : /* }}} */
    2482             : 
    2483             : /* {{{ proto public ReflectionFunction ReflectionParameter::getDeclaringFunction()
    2484             :    Returns the ReflectionFunction for the function of this parameter */
    2485           6 : ZEND_METHOD(reflection_parameter, getDeclaringFunction)
    2486             : {
    2487             :         reflection_object *intern;
    2488             :         parameter_reference *param;
    2489             : 
    2490           6 :         if (zend_parse_parameters_none() == FAILURE) {
    2491           0 :                 return;
    2492             :         }
    2493          12 :         GET_REFLECTION_OBJECT_PTR(param);
    2494             : 
    2495           6 :         if (!param->fptr->common.scope) {
    2496           8 :                 reflection_function_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, return_value);
    2497             :         } else {
    2498           4 :                 reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, return_value);
    2499             :         }
    2500             : }
    2501             : /* }}} */
    2502             : 
    2503             : /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getDeclaringClass()
    2504             :    Returns in which class this parameter is defined (not the type of the parameter) */
    2505          14 : ZEND_METHOD(reflection_parameter, getDeclaringClass)
    2506             : {
    2507             :         reflection_object *intern;
    2508             :         parameter_reference *param;
    2509             : 
    2510          14 :         if (zend_parse_parameters_none() == FAILURE) {
    2511           0 :                 return;
    2512             :         }
    2513          28 :         GET_REFLECTION_OBJECT_PTR(param);
    2514             : 
    2515          14 :         if (param->fptr->common.scope) {
    2516           7 :                 zend_reflection_class_factory(param->fptr->common.scope, return_value);
    2517             :         }
    2518             : }
    2519             : /* }}} */
    2520             : 
    2521             : /* {{{ proto public ReflectionClass|NULL ReflectionParameter::getClass()
    2522             :    Returns this parameters's class hint or NULL if there is none */
    2523          20 : ZEND_METHOD(reflection_parameter, getClass)
    2524             : {
    2525             :         reflection_object *intern;
    2526             :         parameter_reference *param;
    2527             :         zend_class_entry *ce;
    2528             : 
    2529          20 :         if (zend_parse_parameters_none() == FAILURE) {
    2530           0 :                 return;
    2531             :         }
    2532          40 :         GET_REFLECTION_OBJECT_PTR(param);
    2533             : 
    2534          20 :         if (ZEND_TYPE_IS_CLASS(param->arg_info->type)) {
    2535             :                 /* Class name is stored as a string, we might also get "self" or "parent"
    2536             :                  * - For "self", simply use the function scope. If scope is NULL then
    2537             :                  *   the function is global and thus self does not make any sense
    2538             :                  *
    2539             :                  * - For "parent", use the function scope's parent. If scope is NULL then
    2540             :                  *   the function is global and thus parent does not make any sense.
    2541             :                  *   If the parent is NULL then the class does not extend anything and
    2542             :                  *   thus parent does not make any sense, either.
    2543             :                  *
    2544             :                  * TODO: Think about moving these checks to the compiler or some sort of
    2545             :                  * lint-mode.
    2546             :                  */
    2547             :                 zend_string *class_name;
    2548             : 
    2549          12 :                 class_name = ZEND_TYPE_NAME(param->arg_info->type);
    2550          12 :                 if (0 == zend_binary_strcasecmp(ZSTR_VAL(class_name), ZSTR_LEN(class_name), "self", sizeof("self")- 1)) {
    2551           1 :                         ce = param->fptr->common.scope;
    2552           1 :                         if (!ce) {
    2553           0 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    2554             :                                         "Parameter uses 'self' as type hint but function is not a class member!");
    2555           0 :                                 return;
    2556             :                         }
    2557          11 :                 } else if (0 == zend_binary_strcasecmp(ZSTR_VAL(class_name), ZSTR_LEN(class_name), "parent", sizeof("parent")- 1)) {
    2558           0 :                         ce = param->fptr->common.scope;
    2559           0 :                         if (!ce) {
    2560           0 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    2561             :                                         "Parameter uses 'parent' as type hint but function is not a class member!");
    2562           0 :                                 return;
    2563             :                         }
    2564           0 :                         if (!ce->parent) {
    2565           0 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    2566             :                                         "Parameter uses 'parent' as type hint although class does not have a parent!");
    2567           0 :                                 return;
    2568             :                         }
    2569           0 :                         ce = ce->parent;
    2570             :                 } else {
    2571          11 :                         ce = zend_lookup_class(class_name);
    2572          11 :                         if (!ce) {
    2573           2 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    2574           2 :                                         "Class %s does not exist", ZSTR_VAL(class_name));
    2575           2 :                                 return;
    2576             :                         }
    2577             :                 }
    2578          10 :                 zend_reflection_class_factory(ce, return_value);
    2579             :         }
    2580             : }
    2581             : /* }}} */
    2582             : 
    2583             : /* {{{ proto public bool ReflectionParameter::hasType()
    2584             :    Returns whether parameter has a type */
    2585          27 : ZEND_METHOD(reflection_parameter, hasType)
    2586             : {
    2587             :         reflection_object *intern;
    2588             :         parameter_reference *param;
    2589             : 
    2590          27 :         if (zend_parse_parameters_none() == FAILURE) {
    2591           0 :                 return;
    2592             :         }
    2593          54 :         GET_REFLECTION_OBJECT_PTR(param);
    2594             : 
    2595          27 :         RETVAL_BOOL(ZEND_TYPE_IS_SET(param->arg_info->type));
    2596             : }
    2597             : /* }}} */
    2598             : 
    2599             : /* {{{ proto public ReflectionType ReflectionParameter::getType()
    2600             :    Returns the type associated with the parameter */
    2601          30 : ZEND_METHOD(reflection_parameter, getType)
    2602             : {
    2603             :         reflection_object *intern;
    2604             :         parameter_reference *param;
    2605             : 
    2606          30 :         if (zend_parse_parameters_none() == FAILURE) {
    2607           0 :                 return;
    2608             :         }
    2609          60 :         GET_REFLECTION_OBJECT_PTR(param);
    2610             : 
    2611          30 :         if (!ZEND_TYPE_IS_SET(param->arg_info->type)) {
    2612           1 :                 RETURN_NULL();
    2613             :         }
    2614          58 :         reflection_type_factory(_copy_function(param->fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, param->arg_info, return_value);
    2615             : }
    2616             : /* }}} */
    2617             : 
    2618             : /* {{{ proto public bool ReflectionParameter::isArray()
    2619             :    Returns whether parameter MUST be an array */
    2620          94 : ZEND_METHOD(reflection_parameter, isArray)
    2621             : {
    2622             :         reflection_object *intern;
    2623             :         parameter_reference *param;
    2624             : 
    2625          94 :         if (zend_parse_parameters_none() == FAILURE) {
    2626           0 :                 return;
    2627             :         }
    2628         188 :         GET_REFLECTION_OBJECT_PTR(param);
    2629             : 
    2630          94 :         RETVAL_BOOL(ZEND_TYPE_CODE(param->arg_info->type) == IS_ARRAY);
    2631             : }
    2632             : /* }}} */
    2633             : 
    2634             : /* {{{ proto public bool ReflectionParameter::isCallable()
    2635             :    Returns whether parameter MUST be callable */
    2636           3 : ZEND_METHOD(reflection_parameter, isCallable)
    2637             : {
    2638             :         reflection_object *intern;
    2639             :         parameter_reference *param;
    2640             : 
    2641           3 :         if (zend_parse_parameters_none() == FAILURE) {
    2642           0 :                 return;
    2643             :         }
    2644           6 :         GET_REFLECTION_OBJECT_PTR(param);
    2645             : 
    2646           3 :         RETVAL_BOOL(ZEND_TYPE_CODE(param->arg_info->type) == IS_CALLABLE);
    2647             : }
    2648             : /* }}} */
    2649             : 
    2650             : /* {{{ proto public bool ReflectionParameter::allowsNull()
    2651             :    Returns whether NULL is allowed as this parameters's value */
    2652          85 : ZEND_METHOD(reflection_parameter, allowsNull)
    2653             : {
    2654             :         reflection_object *intern;
    2655             :         parameter_reference *param;
    2656             : 
    2657          85 :         if (zend_parse_parameters_none() == FAILURE) {
    2658           0 :                 return;
    2659             :         }
    2660         170 :         GET_REFLECTION_OBJECT_PTR(param);
    2661             : 
    2662          85 :         RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->arg_info->type));
    2663             : }
    2664             : /* }}} */
    2665             : 
    2666             : /* {{{ proto public bool ReflectionParameter::isPassedByReference()
    2667             :    Returns whether this parameters is passed to by reference */
    2668          98 : ZEND_METHOD(reflection_parameter, isPassedByReference)
    2669             : {
    2670             :         reflection_object *intern;
    2671             :         parameter_reference *param;
    2672             : 
    2673          98 :         if (zend_parse_parameters_none() == FAILURE) {
    2674           0 :                 return;
    2675             :         }
    2676         196 :         GET_REFLECTION_OBJECT_PTR(param);
    2677             : 
    2678          98 :         RETVAL_BOOL(param->arg_info->pass_by_reference);
    2679             : }
    2680             : /* }}} */
    2681             : 
    2682             : /* {{{ proto public bool ReflectionParameter::canBePassedByValue()
    2683             :    Returns whether this parameter can be passed by value */
    2684           8 : ZEND_METHOD(reflection_parameter, canBePassedByValue)
    2685             : {
    2686             :         reflection_object *intern;
    2687             :         parameter_reference *param;
    2688             : 
    2689           8 :         if (zend_parse_parameters_none() == FAILURE) {
    2690           0 :                 return;
    2691             :         }
    2692          16 :         GET_REFLECTION_OBJECT_PTR(param);
    2693             : 
    2694             :         /* true if it's ZEND_SEND_BY_VAL or ZEND_SEND_PREFER_REF */
    2695           8 :         RETVAL_BOOL(param->arg_info->pass_by_reference != ZEND_SEND_BY_REF);
    2696             : }
    2697             : /* }}} */
    2698             : 
    2699             : /* {{{ proto public bool ReflectionParameter::getPosition()
    2700             :    Returns whether this parameter is an optional parameter */
    2701           3 : ZEND_METHOD(reflection_parameter, getPosition)
    2702             : {
    2703             :         reflection_object *intern;
    2704             :         parameter_reference *param;
    2705             : 
    2706           3 :         if (zend_parse_parameters_none() == FAILURE) {
    2707           0 :                 return;
    2708             :         }
    2709           6 :         GET_REFLECTION_OBJECT_PTR(param);
    2710             : 
    2711           3 :         RETVAL_LONG(param->offset);
    2712             : }
    2713             : /* }}} */
    2714             : 
    2715             : /* {{{ proto public bool ReflectionParameter::isOptional()
    2716             :    Returns whether this parameter is an optional parameter */
    2717         131 : ZEND_METHOD(reflection_parameter, isOptional)
    2718             : {
    2719             :         reflection_object *intern;
    2720             :         parameter_reference *param;
    2721             : 
    2722         131 :         if (zend_parse_parameters_none() == FAILURE) {
    2723           0 :                 return;
    2724             :         }
    2725         262 :         GET_REFLECTION_OBJECT_PTR(param);
    2726             : 
    2727         131 :         RETVAL_BOOL(!param->required);
    2728             : }
    2729             : /* }}} */
    2730             : 
    2731             : /* {{{ proto public bool ReflectionParameter::isDefaultValueAvailable()
    2732             :    Returns whether the default value of this parameter is available */
    2733         118 : ZEND_METHOD(reflection_parameter, isDefaultValueAvailable)
    2734             : {
    2735             :         reflection_object *intern;
    2736             :         parameter_reference *param;
    2737             :         zend_op *precv;
    2738             : 
    2739         118 :         if (zend_parse_parameters_none() == FAILURE) {
    2740           0 :                 return;
    2741             :         }
    2742         236 :         GET_REFLECTION_OBJECT_PTR(param);
    2743             : 
    2744         118 :         if (param->fptr->type != ZEND_USER_FUNCTION)
    2745             :         {
    2746          71 :                 RETURN_FALSE;
    2747             :         }
    2748             : 
    2749          47 :         precv = _get_recv_op((zend_op_array*)param->fptr, param->offset);
    2750          47 :         if (!precv || precv->opcode != ZEND_RECV_INIT || precv->op2_type == IS_UNUSED) {
    2751          14 :                 RETURN_FALSE;
    2752             :         }
    2753          33 :         RETURN_TRUE;
    2754             : }
    2755             : /* }}} */
    2756             : 
    2757             : /* {{{ proto public bool ReflectionParameter::getDefaultValue()
    2758             :    Returns the default value of this parameter or throws an exception */
    2759          23 : ZEND_METHOD(reflection_parameter, getDefaultValue)
    2760             : {
    2761             :         parameter_reference *param;
    2762             :         zend_op *precv;
    2763             : 
    2764          23 :         if (zend_parse_parameters_none() == FAILURE) {
    2765           0 :                 return;
    2766             :         }
    2767             : 
    2768          23 :         param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    2769          23 :         if (!param) {
    2770           0 :                 return;
    2771             :         }
    2772             : 
    2773          23 :         precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
    2774          23 :         if (!precv) {
    2775           0 :                 return;
    2776             :         }
    2777             : 
    2778          23 :         ZVAL_COPY(return_value, RT_CONSTANT(precv, precv->op2));
    2779          23 :         if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
    2780          10 :                 zval_update_constant_ex(return_value, param->fptr->common.scope);
    2781             :         }
    2782             : }
    2783             : /* }}} */
    2784             : 
    2785             : /* {{{ proto public bool ReflectionParameter::isDefaultValueConstant()
    2786             :    Returns whether the default value of this parameter is constant */
    2787          10 : ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
    2788             : {
    2789             :         zend_op *precv;
    2790             :         parameter_reference *param;
    2791             : 
    2792          10 :         if (zend_parse_parameters_none() == FAILURE) {
    2793           0 :                 return;
    2794             :         }
    2795             : 
    2796          10 :         param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    2797          10 :         if (!param) {
    2798           0 :                 RETURN_FALSE;
    2799             :         }
    2800             : 
    2801          10 :         precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
    2802          20 :         if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
    2803           8 :                 zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
    2804             : 
    2805           8 :                 if (ast->kind == ZEND_AST_CONSTANT
    2806           0 :                  || ast->kind == ZEND_AST_CONSTANT_CLASS) {
    2807           8 :                         RETURN_TRUE;
    2808             :                 }
    2809             :         }
    2810             : 
    2811           2 :         RETURN_FALSE;
    2812             : }
    2813             : /* }}} */
    2814             : 
    2815             : /* {{{ proto public mixed ReflectionParameter::getDefaultValueConstantName()
    2816             :    Returns the default value's constant name if default value is constant or null */
    2817           9 : ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
    2818             : {
    2819             :         zend_op *precv;
    2820             :         parameter_reference *param;
    2821             : 
    2822           9 :         if (zend_parse_parameters_none() == FAILURE) {
    2823           0 :                 return;
    2824             :         }
    2825             : 
    2826           9 :         param = _reflection_param_get_default_param(INTERNAL_FUNCTION_PARAM_PASSTHRU);
    2827           9 :         if (!param) {
    2828           0 :                 return;
    2829             :         }
    2830             : 
    2831           9 :         precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
    2832          17 :         if (precv && Z_TYPE_P(RT_CONSTANT(precv, precv->op2)) == IS_CONSTANT_AST) {
    2833           8 :                 zend_ast *ast = Z_ASTVAL_P(RT_CONSTANT(precv, precv->op2));
    2834             : 
    2835           8 :                 if (ast->kind == ZEND_AST_CONSTANT) {
    2836          32 :                         RETURN_STR_COPY(zend_ast_get_constant_name(ast));
    2837           0 :                 } else if (ast->kind == ZEND_AST_CONSTANT_CLASS) {
    2838           0 :                         RETURN_STRINGL("__CLASS__", sizeof("__CLASS__")-1);
    2839             :                 }
    2840             :         }
    2841             : }
    2842             : /* }}} */
    2843             : 
    2844             : /* {{{ proto public bool ReflectionParameter::isVariadic()
    2845             :    Returns whether this parameter is a variadic parameter */
    2846           4 : ZEND_METHOD(reflection_parameter, isVariadic)
    2847             : {
    2848             :         reflection_object *intern;
    2849             :         parameter_reference *param;
    2850             : 
    2851           4 :         if (zend_parse_parameters_none() == FAILURE) {
    2852           0 :                 return;
    2853             :         }
    2854           8 :         GET_REFLECTION_OBJECT_PTR(param);
    2855             : 
    2856           4 :         RETVAL_BOOL(param->arg_info->is_variadic);
    2857             : }
    2858             : /* }}} */
    2859             : 
    2860             : /* {{{ proto public bool ReflectionType::allowsNull()
    2861             :   Returns whether parameter MAY be null */
    2862          20 : ZEND_METHOD(reflection_type, allowsNull)
    2863             : {
    2864             :         reflection_object *intern;
    2865             :         type_reference *param;
    2866             : 
    2867          20 :         if (zend_parse_parameters_none() == FAILURE) {
    2868           0 :                 return;
    2869             :         }
    2870          40 :         GET_REFLECTION_OBJECT_PTR(param);
    2871             : 
    2872          20 :         RETVAL_BOOL(ZEND_TYPE_ALLOW_NULL(param->arg_info->type));
    2873             : }
    2874             : /* }}} */
    2875             : 
    2876             : /* {{{ proto public bool ReflectionType::isBuiltin()
    2877             :   Returns whether parameter is a builtin type */
    2878          26 : ZEND_METHOD(reflection_type, isBuiltin)
    2879             : {
    2880             :         reflection_object *intern;
    2881             :         type_reference *param;
    2882             : 
    2883          26 :         if (zend_parse_parameters_none() == FAILURE) {
    2884           0 :                 return;
    2885             :         }
    2886          52 :         GET_REFLECTION_OBJECT_PTR(param);
    2887             : 
    2888          26 :         RETVAL_BOOL(ZEND_TYPE_IS_CODE(param->arg_info->type));
    2889             : }
    2890             : /* }}} */
    2891             : 
    2892             : /* {{{ reflection_type_name */
    2893          55 : static zend_string *reflection_type_name(type_reference *param) {
    2894          55 :         if (ZEND_TYPE_IS_CLASS(param->arg_info->type)) {
    2895          54 :                 return zend_string_copy(ZEND_TYPE_NAME(param->arg_info->type));
    2896             :         } else {
    2897          28 :                 char *name = zend_get_type_by_const(ZEND_TYPE_CODE(param->arg_info->type));
    2898          56 :                 return zend_string_init(name, strlen(name), 0);
    2899             :         }
    2900             : }
    2901             : /* }}} */
    2902             : 
    2903             : /* {{{ proto public string ReflectionType::__toString()
    2904             :    Return the text of the type hint */
    2905          11 : ZEND_METHOD(reflection_type, __toString)
    2906             : {
    2907             :         reflection_object *intern;
    2908             :         type_reference *param;
    2909             : 
    2910          11 :         if (zend_parse_parameters_none() == FAILURE) {
    2911           0 :                 return;
    2912             :         }
    2913          22 :         GET_REFLECTION_OBJECT_PTR(param);
    2914             : 
    2915          22 :         RETURN_STR(reflection_type_name(param));
    2916             : }
    2917             : /* }}} */
    2918             : 
    2919             : /* {{{ proto public string ReflectionNamedType::getName()
    2920             :  Return the text of the type hint */
    2921          44 : ZEND_METHOD(reflection_named_type, getName)
    2922             : {
    2923             :         reflection_object *intern;
    2924             :         type_reference *param;
    2925             : 
    2926          44 :         if (zend_parse_parameters_none() == FAILURE) {
    2927           0 :                 return;
    2928             :         }
    2929          88 :         GET_REFLECTION_OBJECT_PTR(param);
    2930             : 
    2931          88 :         RETURN_STR(reflection_type_name(param));
    2932             : }
    2933             : /* }}} */
    2934             : 
    2935             : /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException
    2936             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    2937           8 : ZEND_METHOD(reflection_method, export)
    2938             : {
    2939           8 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_method_ptr, 2);
    2940           8 : }
    2941             : /* }}} */
    2942             : 
    2943             : /* {{{ proto public void ReflectionMethod::__construct(mixed class_or_method [, string name])
    2944             :    Constructor. Throws an Exception in case the given method does not exist */
    2945         219 : ZEND_METHOD(reflection_method, __construct)
    2946             : {
    2947             :         zval name, *classname;
    2948             :         zval *object, *orig_obj;
    2949             :         reflection_object *intern;
    2950             :         char *lcname;
    2951             :         zend_class_entry *ce;
    2952             :         zend_function *mptr;
    2953             :         char *name_str, *tmp;
    2954             :         size_t name_len, tmp_len;
    2955             :         zval ztmp;
    2956             : 
    2957         219 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "zs", &classname, &name_str, &name_len) == FAILURE) {
    2958          53 :                 if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
    2959          31 :                         return;
    2960             :                 }
    2961             : 
    2962          48 :                 if ((tmp = strstr(name_str, "::")) == NULL) {
    2963           5 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    2964             :                                 "Invalid method name %s", name_str);
    2965           5 :                         return;
    2966             :                 }
    2967          43 :                 classname = &ztmp;
    2968          43 :                 tmp_len = tmp - name_str;
    2969          86 :                 ZVAL_STRINGL(classname, name_str, tmp_len);
    2970          43 :                 name_len = name_len - (tmp_len + 2);
    2971          43 :                 name_str = tmp + 2;
    2972          43 :                 orig_obj = NULL;
    2973         332 :         } else if (Z_TYPE_P(classname) == IS_OBJECT) {
    2974          15 :                 orig_obj = classname;
    2975             :         } else {
    2976         151 :                 orig_obj = NULL;
    2977             :         }
    2978             : 
    2979         418 :         object = getThis();
    2980         209 :         intern = Z_REFLECTION_P(object);
    2981             : 
    2982             :         /* Find the class entry */
    2983         418 :         switch (Z_TYPE_P(classname)) {
    2984         191 :                 case IS_STRING:
    2985         191 :                         if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
    2986          10 :                                 if (!EG(exception)) {
    2987           9 :                                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    2988           9 :                                                         "Class %s does not exist", Z_STRVAL_P(classname));
    2989             :                                 }
    2990          10 :                                 if (classname == &ztmp) {
    2991             :                                         zval_ptr_dtor_str(&ztmp);
    2992             :                                 }
    2993          10 :                                 return;
    2994             :                         }
    2995         181 :                         break;
    2996             : 
    2997          15 :                 case IS_OBJECT:
    2998          15 :                         ce = Z_OBJCE_P(classname);
    2999          15 :                         break;
    3000             : 
    3001           3 :                 default:
    3002           3 :                         if (classname == &ztmp) {
    3003             :                                 zval_ptr_dtor_str(&ztmp);
    3004             :                         }
    3005           3 :                         _DO_THROW("The parameter class is expected to be either a string or an object");
    3006             :                         /* returns out of this function */
    3007             :         }
    3008             : 
    3009         196 :         if (classname == &ztmp) {
    3010             :                 zval_ptr_dtor_str(&ztmp);
    3011             :         }
    3012             : 
    3013         196 :         lcname = zend_str_tolower_dup(name_str, name_len);
    3014             : 
    3015         196 :         if (ce == zend_ce_closure && orig_obj && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    3016           9 :                 && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
    3017           9 :                 && (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
    3018             :         {
    3019             :                 /* do nothing, mptr already set */
    3020         374 :         } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
    3021           3 :                 efree(lcname);
    3022           6 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3023           3 :                         "Method %s::%s() does not exist", ZSTR_VAL(ce->name), name_str);
    3024           3 :                 return;
    3025             :         }
    3026         193 :         efree(lcname);
    3027             : 
    3028         386 :         ZVAL_STR_COPY(&name, mptr->common.scope->name);
    3029         579 :         reflection_update_property_class(object, &name);
    3030         508 :         ZVAL_STR_COPY(&name, mptr->common.function_name);
    3031         579 :         reflection_update_property_name(object, &name);
    3032         193 :         intern->ptr = mptr;
    3033         193 :         intern->ref_type = REF_TYPE_FUNCTION;
    3034         193 :         intern->ce = ce;
    3035             : }
    3036             : /* }}} */
    3037             : 
    3038             : /* {{{ proto public string ReflectionMethod::__toString()
    3039             :    Returns a string representation */
    3040          34 : ZEND_METHOD(reflection_method, __toString)
    3041             : {
    3042             :         reflection_object *intern;
    3043             :         zend_function *mptr;
    3044          34 :         smart_str str = {0};
    3045             : 
    3046          34 :         if (zend_parse_parameters_none() == FAILURE) {
    3047           0 :                 return;
    3048             :         }
    3049          68 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3050          34 :         _function_string(&str, mptr, intern->ce, "");
    3051         102 :         RETURN_STR(smart_str_extract(&str));
    3052             : }
    3053             : /* }}} */
    3054             : 
    3055             : /* {{{ proto public mixed ReflectionMethod::getClosure([mixed object])
    3056             :    Invokes the function */
    3057          18 : ZEND_METHOD(reflection_method, getClosure)
    3058             : {
    3059             :         reflection_object *intern;
    3060             :         zval *obj;
    3061             :         zend_function *mptr;
    3062             : 
    3063          39 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3064             : 
    3065          18 :         if (mptr->common.fn_flags & ZEND_ACC_STATIC)  {
    3066           5 :                 zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL);
    3067             :         } else {
    3068          13 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &obj) == FAILURE) {
    3069           2 :                         return;
    3070             :                 }
    3071             : 
    3072          11 :                 if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope)) {
    3073           1 :                         _DO_THROW("Given object is not an instance of the class this method was declared in");
    3074             :                         /* Returns from this function */
    3075             :                 }
    3076             : 
    3077             :                 /* This is an original closure object and __invoke is to be called. */
    3078          11 :                 if (Z_OBJCE_P(obj) == zend_ce_closure &&
    3079           1 :                         (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))
    3080             :                 {
    3081           2 :                         ZVAL_COPY(return_value, obj);
    3082             :                 } else {
    3083           9 :                         zend_create_fake_closure(return_value, mptr, mptr->common.scope, Z_OBJCE_P(obj), obj);
    3084             :                 }
    3085             :         }
    3086             : }
    3087             : /* }}} */
    3088             : 
    3089             : /* {{{ reflection_method_invoke */
    3090          72 : static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
    3091             : {
    3092             :         zval retval;
    3093          72 :         zval *params = NULL, *val, *object;
    3094             :         reflection_object *intern;
    3095             :         zend_function *mptr;
    3096          72 :         int i, argc = 0, result;
    3097             :         zend_fcall_info fci;
    3098             :         zend_fcall_info_cache fcc;
    3099             :         zend_class_entry *obj_ce;
    3100             :         zval *param_array;
    3101             : 
    3102         173 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3103             : 
    3104          72 :         if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3105           4 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3106             :                         "Trying to invoke abstract method %s::%s()",
    3107           4 :                         ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
    3108           4 :                 return;
    3109             :         }
    3110             : 
    3111          68 :         if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
    3112          10 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3113             :                         "Trying to invoke %s method %s::%s() from scope %s",
    3114          10 :                         mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
    3115          10 :                         ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name),
    3116          20 :                         ZSTR_VAL(Z_OBJCE_P(getThis())->name));
    3117          10 :                 return;
    3118             :         }
    3119             : 
    3120          58 :         if (variadic) {
    3121          33 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!*", &object, &params, &argc) == FAILURE) {
    3122           4 :                         return;
    3123             :                 }
    3124             :         } else {
    3125          25 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o!a", &object, &param_array) == FAILURE) {
    3126           7 :                         return;
    3127             :                 }
    3128             : 
    3129          18 :                 argc = zend_hash_num_elements(Z_ARRVAL_P(param_array));
    3130             : 
    3131          18 :                 params = safe_emalloc(sizeof(zval), argc, 0);
    3132          18 :                 argc = 0;
    3133          48 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(param_array), val) {
    3134          15 :                         ZVAL_COPY(&params[argc], val);
    3135          15 :                         argc++;
    3136             :                 } ZEND_HASH_FOREACH_END();
    3137             :         }
    3138             : 
    3139             :         /* In case this is a static method, we should'nt pass an object_ptr
    3140             :          * (which is used as calling context aka $this). We can thus ignore the
    3141             :          * first parameter.
    3142             :          *
    3143             :          * Else, we verify that the given object is an instance of the class.
    3144             :          */
    3145          47 :         if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
    3146          14 :                 object = NULL;
    3147          14 :                 obj_ce = mptr->common.scope;
    3148             :         } else {
    3149          33 :                 if (!object) {
    3150           1 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    3151             :                                 "Trying to invoke non static method %s::%s() without an object",
    3152           1 :                                 ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
    3153           1 :                         return;
    3154             :                 }
    3155             : 
    3156          32 :                 obj_ce = Z_OBJCE_P(object);
    3157             : 
    3158          32 :                 if (!instanceof_function(obj_ce, mptr->common.scope)) {
    3159           3 :                         if (!variadic) {
    3160           1 :                                 efree(params);
    3161             :                         }
    3162           3 :                         _DO_THROW("Given object is not an instance of the class this method was declared in");
    3163             :                         /* Returns from this function */
    3164             :                 }
    3165             :         }
    3166             : 
    3167          43 :         fci.size = sizeof(fci);
    3168          43 :         ZVAL_UNDEF(&fci.function_name);
    3169          43 :         fci.object = object ? Z_OBJ_P(object) : NULL;
    3170          43 :         fci.retval = &retval;
    3171          43 :         fci.param_count = argc;
    3172          43 :         fci.params = params;
    3173          43 :         fci.no_separation = 1;
    3174             : 
    3175          43 :         fcc.function_handler = mptr;
    3176          43 :         fcc.called_scope = intern->ce;
    3177          43 :         fcc.object = object ? Z_OBJ_P(object) : NULL;
    3178             : 
    3179             :         /*
    3180             :          * Copy the zend_function when calling via handler (e.g. Closure::__invoke())
    3181             :          */
    3182          43 :         if ((mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
    3183           3 :                 fcc.function_handler = _copy_function(mptr);
    3184             :         }
    3185             : 
    3186          43 :         result = zend_call_function(&fci, &fcc);
    3187             : 
    3188          43 :         if (!variadic) {
    3189          32 :                 for (i = 0; i < argc; i++) {
    3190          15 :                         zval_ptr_dtor(&params[i]);
    3191             :                 }
    3192          17 :                 efree(params);
    3193             :         }
    3194             : 
    3195          43 :         if (result == FAILURE) {
    3196           0 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3197           0 :                         "Invocation of method %s::%s() failed", ZSTR_VAL(mptr->common.scope->name), ZSTR_VAL(mptr->common.function_name));
    3198           0 :                 return;
    3199             :         }
    3200             : 
    3201          43 :         if (Z_TYPE(retval) != IS_UNDEF) {
    3202          37 :                 if (Z_ISREF(retval)) {
    3203             :                         zend_unwrap_reference(&retval);
    3204             :                 }
    3205          37 :                 ZVAL_COPY_VALUE(return_value, &retval);
    3206             :         }
    3207             : }
    3208             : /* }}} */
    3209             : 
    3210             : /* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
    3211             :    Invokes the method. */
    3212          40 : ZEND_METHOD(reflection_method, invoke)
    3213             : {
    3214          40 :         reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    3215          40 : }
    3216             : /* }}} */
    3217             : 
    3218             : /* {{{ proto public mixed ReflectionMethod::invokeArgs(mixed object, array args)
    3219             :    Invokes the function and pass its arguments as array. */
    3220          32 : ZEND_METHOD(reflection_method, invokeArgs)
    3221             : {
    3222          32 :         reflection_method_invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    3223          32 : }
    3224             : /* }}} */
    3225             : 
    3226             : /* {{{ proto public bool ReflectionMethod::isFinal()
    3227             :    Returns whether this method is final */
    3228          71 : ZEND_METHOD(reflection_method, isFinal)
    3229             : {
    3230          71 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
    3231          71 : }
    3232             : /* }}} */
    3233             : 
    3234             : /* {{{ proto public bool ReflectionMethod::isAbstract()
    3235             :    Returns whether this method is abstract */
    3236          72 : ZEND_METHOD(reflection_method, isAbstract)
    3237             : {
    3238          72 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ABSTRACT);
    3239          72 : }
    3240             : /* }}} */
    3241             : 
    3242             : /* {{{ proto public bool ReflectionMethod::isPublic()
    3243             :    Returns whether this method is public */
    3244          71 : ZEND_METHOD(reflection_method, isPublic)
    3245             : {
    3246          71 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC);
    3247          71 : }
    3248             : /* }}} */
    3249             : 
    3250             : /* {{{ proto public bool ReflectionMethod::isPrivate()
    3251             :    Returns whether this method is private */
    3252          71 : ZEND_METHOD(reflection_method, isPrivate)
    3253             : {
    3254          71 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
    3255          71 : }
    3256             : /* }}} */
    3257             : 
    3258             : /* {{{ proto public bool ReflectionMethod::isProtected()
    3259             :    Returns whether this method is protected */
    3260          71 : ZEND_METHOD(reflection_method, isProtected)
    3261             : {
    3262          71 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
    3263          71 : }
    3264             : /* }}} */
    3265             : 
    3266             : /* {{{ proto public bool ReflectionMethod::isStatic()
    3267             :    Returns whether this method is static */
    3268          71 : ZEND_METHOD(reflection_method, isStatic)
    3269             : {
    3270          71 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
    3271          71 : }
    3272             : /* }}} */
    3273             : 
    3274             : /* {{{ proto public bool ReflectionFunction::isDeprecated()
    3275             :    Returns whether this function is deprecated */
    3276           1 : ZEND_METHOD(reflection_function, isDeprecated)
    3277             : {
    3278           1 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
    3279           1 : }
    3280             : /* }}} */
    3281             : 
    3282             : /* {{{ proto public bool ReflectionFunction::isGenerator()
    3283             :    Returns whether this function is a generator */
    3284           6 : ZEND_METHOD(reflection_function, isGenerator)
    3285             : {
    3286           6 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_GENERATOR);
    3287           6 : }
    3288             : /* }}} */
    3289             : 
    3290             : /* {{{ proto public bool ReflectionFunction::isVariadic()
    3291             :    Returns whether this function is variadic */
    3292           3 : ZEND_METHOD(reflection_function, isVariadic)
    3293             : {
    3294           3 :         _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_VARIADIC);
    3295           3 : }
    3296             : /* }}} */
    3297             : 
    3298             : /* {{{ proto public bool ReflectionFunction::inNamespace()
    3299             :    Returns whether this function is defined in namespace */
    3300           2 : ZEND_METHOD(reflection_function, inNamespace)
    3301             : {
    3302             :         zval *name;
    3303             :         const char *backslash;
    3304             : 
    3305           2 :         if (zend_parse_parameters_none() == FAILURE) {
    3306           0 :                 return;
    3307             :         }
    3308           4 :         if ((name = _default_load_name(getThis())) == NULL) {
    3309           0 :                 RETURN_FALSE;
    3310             :         }
    3311           2 :         if (Z_TYPE_P(name) == IS_STRING
    3312           4 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    3313           1 :                 && backslash > Z_STRVAL_P(name))
    3314             :         {
    3315           1 :                 RETURN_TRUE;
    3316             :         }
    3317           1 :         RETURN_FALSE;
    3318             : }
    3319             : /* }}} */
    3320             : 
    3321             : /* {{{ proto public string ReflectionFunction::getNamespaceName()
    3322             :    Returns the name of namespace where this function is defined */
    3323           2 : ZEND_METHOD(reflection_function, getNamespaceName)
    3324             : {
    3325             :         zval *name;
    3326             :         const char *backslash;
    3327             : 
    3328           2 :         if (zend_parse_parameters_none() == FAILURE) {
    3329           0 :                 return;
    3330             :         }
    3331           4 :         if ((name = _default_load_name(getThis())) == NULL) {
    3332           0 :                 RETURN_FALSE;
    3333             :         }
    3334           2 :         if (Z_TYPE_P(name) == IS_STRING
    3335           4 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    3336           1 :                 && backslash > Z_STRVAL_P(name))
    3337             :         {
    3338           2 :                 RETURN_STRINGL(Z_STRVAL_P(name), backslash - Z_STRVAL_P(name));
    3339             :         }
    3340           1 :         RETURN_EMPTY_STRING();
    3341             : }
    3342             : /* }}} */
    3343             : 
    3344             : /* {{{ proto public string ReflectionFunction::getShortName()
    3345             :    Returns the short name of the function (without namespace part) */
    3346           3 : ZEND_METHOD(reflection_function, getShortName)
    3347             : {
    3348             :         zval *name;
    3349             :         const char *backslash;
    3350             : 
    3351           3 :         if (zend_parse_parameters_none() == FAILURE) {
    3352           0 :                 return;
    3353             :         }
    3354           6 :         if ((name = _default_load_name(getThis())) == NULL) {
    3355           0 :                 RETURN_FALSE;
    3356             :         }
    3357           3 :         if (Z_TYPE_P(name) == IS_STRING
    3358           6 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    3359           1 :                 && backslash > Z_STRVAL_P(name))
    3360             :         {
    3361           2 :                 RETURN_STRINGL(backslash + 1, Z_STRLEN_P(name) - (backslash - Z_STRVAL_P(name) + 1));
    3362             :         }
    3363           4 :         ZVAL_COPY_DEREF(return_value, name);
    3364             : }
    3365             : /* }}} */
    3366             : 
    3367             : /* {{{ proto public bool ReflectionFunctionAbstract:hasReturnType()
    3368             :    Return whether the function has a return type */
    3369           7 : ZEND_METHOD(reflection_function, hasReturnType)
    3370             : {
    3371             :         reflection_object *intern;
    3372             :         zend_function *fptr;
    3373             : 
    3374           7 :         if (zend_parse_parameters_none() == FAILURE) {
    3375           0 :                 return;
    3376             :         }
    3377             : 
    3378          14 :         GET_REFLECTION_OBJECT_PTR(fptr);
    3379             : 
    3380           7 :         RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE);
    3381             : }
    3382             : /* }}} */
    3383             : 
    3384             : /* {{{ proto public string ReflectionFunctionAbstract::getReturnType()
    3385             :    Returns the return type associated with the function */
    3386          23 : ZEND_METHOD(reflection_function, getReturnType)
    3387             : {
    3388             :         reflection_object *intern;
    3389             :         zend_function *fptr;
    3390             : 
    3391          23 :         if (zend_parse_parameters_none() == FAILURE) {
    3392           0 :                 return;
    3393             :         }
    3394             : 
    3395          46 :         GET_REFLECTION_OBJECT_PTR(fptr);
    3396             : 
    3397          23 :         if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
    3398           1 :                 RETURN_NULL();
    3399             :         }
    3400             : 
    3401          44 :         reflection_type_factory(_copy_function(fptr), Z_ISUNDEF(intern->obj)? NULL : &intern->obj, &fptr->common.arg_info[-1], return_value);
    3402             : }
    3403             : /* }}} */
    3404             : 
    3405             : /* {{{ proto public bool ReflectionMethod::isConstructor()
    3406             :    Returns whether this method is the constructor */
    3407          90 : ZEND_METHOD(reflection_method, isConstructor)
    3408             : {
    3409             :         reflection_object *intern;
    3410             :         zend_function *mptr;
    3411             : 
    3412          90 :         if (zend_parse_parameters_none() == FAILURE) {
    3413           1 :                 return;
    3414             :         }
    3415         178 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3416             :         /* we need to check if the ctor is the ctor of the class level we we
    3417             :          * looking at since we might be looking at an inherited old style ctor
    3418             :          * defined in base class. */
    3419          89 :         RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_CTOR && intern->ce->constructor && intern->ce->constructor->common.scope == mptr->common.scope);
    3420             : }
    3421             : /* }}} */
    3422             : 
    3423             : /* {{{ proto public bool ReflectionMethod::isDestructor()
    3424             :    Returns whether this method is static */
    3425          71 : ZEND_METHOD(reflection_method, isDestructor)
    3426             : {
    3427             :         reflection_object *intern;
    3428             :         zend_function *mptr;
    3429             : 
    3430          71 :         if (zend_parse_parameters_none() == FAILURE) {
    3431           1 :                 return;
    3432             :         }
    3433         140 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3434          70 :         RETURN_BOOL(mptr->common.fn_flags & ZEND_ACC_DTOR);
    3435             : }
    3436             : /* }}} */
    3437             : 
    3438             : /* {{{ proto public int ReflectionMethod::getModifiers()
    3439             :    Returns a bitfield of the access modifiers for this method */
    3440         114 : ZEND_METHOD(reflection_method, getModifiers)
    3441             : {
    3442             :         reflection_object *intern;
    3443             :         zend_function *mptr;
    3444         114 :         uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_IMPLICIT_PUBLIC
    3445             :                 | ZEND_ACC_STATIC | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL;
    3446             : 
    3447         114 :         if (zend_parse_parameters_none() == FAILURE) {
    3448           2 :                 return;
    3449             :         }
    3450         224 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3451             : 
    3452         112 :         RETURN_LONG((mptr->common.fn_flags & keep_flags));
    3453             : }
    3454             : /* }}} */
    3455             : 
    3456             : /* {{{ proto public ReflectionClass ReflectionMethod::getDeclaringClass()
    3457             :    Get the declaring class */
    3458          14 : ZEND_METHOD(reflection_method, getDeclaringClass)
    3459             : {
    3460             :         reflection_object *intern;
    3461             :         zend_function *mptr;
    3462             : 
    3463          28 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3464             : 
    3465          14 :         if (zend_parse_parameters_none() == FAILURE) {
    3466           0 :                 return;
    3467             :         }
    3468             : 
    3469          14 :         zend_reflection_class_factory(mptr->common.scope, return_value);
    3470             : }
    3471             : /* }}} */
    3472             : 
    3473             : /* {{{ proto public ReflectionClass ReflectionMethod::getPrototype()
    3474             :    Get the prototype */
    3475           2 : ZEND_METHOD(reflection_method, getPrototype)
    3476             : {
    3477             :         reflection_object *intern;
    3478             :         zend_function *mptr;
    3479             : 
    3480           4 :         GET_REFLECTION_OBJECT_PTR(mptr);
    3481             : 
    3482           2 :         if (zend_parse_parameters_none() == FAILURE) {
    3483           0 :                 return;
    3484             :         }
    3485             : 
    3486           2 :         if (!mptr->common.prototype) {
    3487           1 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3488           1 :                         "Method %s::%s does not have a prototype", ZSTR_VAL(intern->ce->name), ZSTR_VAL(mptr->common.function_name));
    3489           1 :                 return;
    3490             :         }
    3491             : 
    3492           1 :         reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value);
    3493             : }
    3494             : /* }}} */
    3495             : 
    3496             : /* {{{ proto public void ReflectionMethod::setAccessible(bool visible)
    3497             :    Sets whether non-public methods can be invoked */
    3498           5 : ZEND_METHOD(reflection_method, setAccessible)
    3499             : {
    3500             :         reflection_object *intern;
    3501             :         zend_bool visible;
    3502             : 
    3503           5 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
    3504           0 :                 return;
    3505             :         }
    3506             : 
    3507          10 :         intern = Z_REFLECTION_P(getThis());
    3508             : 
    3509           5 :         intern->ignore_visibility = visible;
    3510             : }
    3511             : /* }}} */
    3512             : 
    3513             : /* {{{ proto public void ReflectionClassConstant::__construct(mixed class, string name)
    3514             :    Constructor. Throws an Exception in case the given class constant does not exist */
    3515          15 : ZEND_METHOD(reflection_class_constant, __construct)
    3516             : {
    3517             :         zval *classname, *object, name, cname;
    3518             :         zend_string *constname;
    3519             :         reflection_object *intern;
    3520             :         zend_class_entry *ce;
    3521          15 :         zend_class_constant *constant = NULL;
    3522             : 
    3523          15 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zS", &classname, &constname) == FAILURE) {
    3524           1 :                 return;
    3525             :         }
    3526             : 
    3527          30 :         object = getThis();
    3528          15 :         intern = Z_REFLECTION_P(object);
    3529             : 
    3530             :         /* Find the class entry */
    3531          30 :         switch (Z_TYPE_P(classname)) {
    3532          11 :                 case IS_STRING:
    3533          11 :                         if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
    3534           0 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3535           0 :                                                 "Class %s does not exist", Z_STRVAL_P(classname));
    3536           0 :                                 return;
    3537             :                         }
    3538          11 :                         break;
    3539             : 
    3540           4 :                 case IS_OBJECT:
    3541           4 :                         ce = Z_OBJCE_P(classname);
    3542           4 :                         break;
    3543             : 
    3544           0 :                 default:
    3545           0 :                         _DO_THROW("The parameter class is expected to be either a string or an object");
    3546             :                         /* returns out of this function */
    3547             :         }
    3548             : 
    3549          30 :         if ((constant = zend_hash_find_ptr(&ce->constants_table, constname)) == NULL) {
    3550           1 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class Constant %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(constname));
    3551           1 :                 return;
    3552             :         }
    3553             : 
    3554          28 :         ZVAL_STR_COPY(&name, constname);
    3555          28 :         ZVAL_STR_COPY(&cname, ce->name);
    3556             : 
    3557          14 :         intern->ptr = constant;
    3558          14 :         intern->ref_type = REF_TYPE_CLASS_CONSTANT;
    3559          14 :         intern->ce = constant->ce;
    3560          14 :         intern->ignore_visibility = 0;
    3561          42 :         reflection_update_property_name(object, &name);
    3562          42 :         reflection_update_property_class(object, &cname);
    3563             : }
    3564             : /* }}} */
    3565             : 
    3566             : /* {{{ proto public string ReflectionClassConstant::__toString()
    3567             :    Returns a string representation */
    3568          13 : ZEND_METHOD(reflection_class_constant, __toString)
    3569             : {
    3570             :         reflection_object *intern;
    3571             :         zend_class_constant *ref;
    3572          13 :         smart_str str = {0};
    3573             :         zval name;
    3574             : 
    3575          13 :         if (zend_parse_parameters_none() == FAILURE) {
    3576           0 :                 return;
    3577             :         }
    3578          26 :         GET_REFLECTION_OBJECT_PTR(ref);
    3579          26 :         _default_get_name(getThis(), &name);
    3580          13 :         _class_const_string(&str, Z_STRVAL(name), ref, "");
    3581          13 :         zval_ptr_dtor(&name);
    3582          39 :         RETURN_STR(smart_str_extract(&str));
    3583             : }
    3584             : /* }}} */
    3585             : 
    3586             : /* {{{ proto public string ReflectionClassConstant::getName()
    3587             :    Returns the constant' name */
    3588          10 : ZEND_METHOD(reflection_class_constant, getName)
    3589             : {
    3590          10 :         if (zend_parse_parameters_none() == FAILURE) {
    3591           0 :                 return;
    3592             :         }
    3593          20 :         _default_get_name(getThis(), return_value);
    3594             : }
    3595             : /* }}} */
    3596             : 
    3597          12 : static void _class_constant_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */
    3598             : {
    3599             :         reflection_object *intern;
    3600             :         zend_class_constant *ref;
    3601             : 
    3602          12 :         if (zend_parse_parameters_none() == FAILURE) {
    3603           0 :                 return;
    3604             :         }
    3605          24 :         GET_REFLECTION_OBJECT_PTR(ref);
    3606          12 :         RETURN_BOOL(Z_ACCESS_FLAGS(ref->value) & mask);
    3607             : }
    3608             : /* }}} */
    3609             : 
    3610             : /* {{{ proto public bool ReflectionClassConstant::isPublic()
    3611             :    Returns whether this constant is public */
    3612           4 : ZEND_METHOD(reflection_class_constant, isPublic)
    3613             : {
    3614           4 :         _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
    3615           4 : }
    3616             : /* }}} */
    3617             : 
    3618             : /* {{{ proto public bool ReflectionClassConstant::isPrivate()
    3619             :    Returns whether this constant is private */
    3620           4 : ZEND_METHOD(reflection_class_constant, isPrivate)
    3621             : {
    3622           4 :         _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
    3623           4 : }
    3624             : /* }}} */
    3625             : 
    3626             : /* {{{ proto public bool ReflectionClassConstant::isProtected()
    3627             :    Returns whether this constant is protected */
    3628           4 : ZEND_METHOD(reflection_class_constant, isProtected)
    3629             : {
    3630           4 :         _class_constant_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
    3631           4 : }
    3632             : /* }}} */
    3633             : 
    3634             : /* {{{ proto public int ReflectionClassConstant::getModifiers()
    3635             :    Returns a bitfield of the access modifiers for this constant */
    3636           4 : ZEND_METHOD(reflection_class_constant, getModifiers)
    3637             : {
    3638             :         reflection_object *intern;
    3639             :         zend_class_constant *ref;
    3640             : 
    3641           4 :         if (zend_parse_parameters_none() == FAILURE) {
    3642           0 :                 return;
    3643             :         }
    3644           8 :         GET_REFLECTION_OBJECT_PTR(ref);
    3645             : 
    3646           4 :         RETURN_LONG(Z_ACCESS_FLAGS(ref->value));
    3647             : }
    3648             : /* }}} */
    3649             : 
    3650             : /* {{{ proto public mixed ReflectionClassConstant::getValue()
    3651             :    Returns this constant's value */
    3652           5 : ZEND_METHOD(reflection_class_constant, getValue)
    3653             : {
    3654             :         reflection_object *intern;
    3655             :         zend_class_constant *ref;
    3656             : 
    3657           5 :         if (zend_parse_parameters_none() == FAILURE) {
    3658           0 :                 return;
    3659             :         }
    3660          10 :         GET_REFLECTION_OBJECT_PTR(ref);
    3661             : 
    3662           6 :         ZVAL_COPY_OR_DUP(return_value, &ref->value);
    3663           5 :         if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
    3664           1 :                 zval_update_constant_ex(return_value, ref->ce);
    3665             :         }
    3666             : }
    3667             : /* }}} */
    3668             : 
    3669             : /* {{{ proto public ReflectionClass ReflectionClassConstant::getDeclaringClass()
    3670             :    Get the declaring class */
    3671           4 : ZEND_METHOD(reflection_class_constant, getDeclaringClass)
    3672             : {
    3673             :         reflection_object *intern;
    3674             :         zend_class_constant *ref;
    3675             : 
    3676           4 :         if (zend_parse_parameters_none() == FAILURE) {
    3677           0 :                 return;
    3678             :         }
    3679           8 :         GET_REFLECTION_OBJECT_PTR(ref);
    3680             : 
    3681           4 :         zend_reflection_class_factory(ref->ce, return_value);
    3682             : }
    3683             : /* }}} */
    3684             : 
    3685             : /* {{{ proto public string ReflectionClassConstant::getDocComment()
    3686             :    Returns the doc comment for this constant */
    3687          10 : ZEND_METHOD(reflection_class_constant, getDocComment)
    3688             : {
    3689             :         reflection_object *intern;
    3690             :         zend_class_constant *ref;
    3691             : 
    3692          10 :         if (zend_parse_parameters_none() == FAILURE) {
    3693           0 :                 return;
    3694             :         }
    3695          20 :         GET_REFLECTION_OBJECT_PTR(ref);
    3696          10 :         if (ref->doc_comment) {
    3697          18 :                 RETURN_STR_COPY(ref->doc_comment);
    3698             :         }
    3699           4 :         RETURN_FALSE;
    3700             : }
    3701             : /* }}} */
    3702             : 
    3703             : /* {{{ proto public static mixed ReflectionClass::export(mixed argument [, bool return]) throws ReflectionException
    3704             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    3705          11 : ZEND_METHOD(reflection_class, export)
    3706             : {
    3707          11 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_ptr, 1);
    3708          11 : }
    3709             : /* }}} */
    3710             : 
    3711             : /* {{{ reflection_class_object_ctor */
    3712         579 : static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
    3713             : {
    3714             :         zval *argument;
    3715             :         zval *object;
    3716             :         zval classname;
    3717             :         reflection_object *intern;
    3718             :         zend_class_entry *ce;
    3719             : 
    3720         579 :         if (is_object) {
    3721         109 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &argument) == FAILURE) {
    3722          24 :                         return;
    3723             :                 }
    3724             :         } else {
    3725         470 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &argument) == FAILURE) {
    3726           2 :                         return;
    3727             :                 }
    3728             :         }
    3729             : 
    3730        1140 :         object = getThis();
    3731         570 :         intern = Z_REFLECTION_P(object);
    3732             : 
    3733        1140 :         if (Z_TYPE_P(argument) == IS_OBJECT) {
    3734         252 :                 ZVAL_STR_COPY(&classname, Z_OBJCE_P(argument)->name);
    3735         378 :                 reflection_update_property_name(object, &classname);
    3736         126 :                 intern->ptr = Z_OBJCE_P(argument);
    3737         126 :                 if (is_object) {
    3738         102 :                         ZVAL_COPY(&intern->obj, argument);
    3739             :                 }
    3740             :         } else {
    3741         892 :                 convert_to_string_ex(argument);
    3742         444 :                 if ((ce = zend_lookup_class(Z_STR_P(argument))) == NULL) {
    3743           8 :                         if (!EG(exception)) {
    3744           8 :                                 zend_throw_exception_ex(reflection_exception_ptr, -1, "Class %s does not exist", Z_STRVAL_P(argument));
    3745             :                         }
    3746           8 :                         return;
    3747             :                 }
    3748             : 
    3749         872 :                 ZVAL_STR_COPY(&classname, ce->name);
    3750        1308 :                 reflection_update_property_name(object, &classname);
    3751             : 
    3752         436 :                 intern->ptr = ce;
    3753             :         }
    3754         562 :         intern->ref_type = REF_TYPE_OTHER;
    3755             : }
    3756             : /* }}} */
    3757             : 
    3758             : /* {{{ proto public void ReflectionClass::__construct(mixed argument) throws ReflectionException
    3759             :    Constructor. Takes a string or an instance as an argument */
    3760         470 : ZEND_METHOD(reflection_class, __construct)
    3761             : {
    3762         470 :         reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    3763         470 : }
    3764             : /* }}} */
    3765             : 
    3766             : /* {{{ add_class_vars */
    3767          37 : static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value)
    3768             : {
    3769             :         zend_property_info *prop_info;
    3770             :         zval *prop, prop_copy;
    3771             :         zend_string *key;
    3772             : 
    3773         623 :         ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
    3774         317 :                 if (((prop_info->flags & ZEND_ACC_SHADOW) &&
    3775         293 :                      prop_info->ce != ce) ||
    3776         332 :                     ((prop_info->flags & ZEND_ACC_PROTECTED) &&
    3777         332 :                      !zend_check_protected(prop_info->ce, ce)) ||
    3778         309 :                     ((prop_info->flags & ZEND_ACC_PRIVATE) &&
    3779          40 :                      prop_info->ce != ce)) {
    3780          24 :                         continue;
    3781             :                 }
    3782         269 :                 prop = NULL;
    3783         269 :                 if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
    3784          57 :                         prop = &ce->default_static_members_table[prop_info->offset];
    3785          57 :                         ZVAL_DEINDIRECT(prop);
    3786         212 :                 } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
    3787          65 :                         prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
    3788             :                 }
    3789         269 :                 if (!prop) {
    3790         147 :                         continue;
    3791             :                 }
    3792             : 
    3793             :                 /* copy: enforce read only access */
    3794         122 :                 ZVAL_DEREF(prop);
    3795         123 :                 ZVAL_COPY_OR_DUP(&prop_copy, prop);
    3796             : 
    3797             :                 /* this is necessary to make it able to work with default array
    3798             :                 * properties, returned to user */
    3799         122 :                 if (Z_TYPE(prop_copy) == IS_CONSTANT_AST) {
    3800           0 :                         if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) {
    3801           0 :                                 return;
    3802             :                         }
    3803             :                 }
    3804             : 
    3805         122 :                 zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy);
    3806             :         } ZEND_HASH_FOREACH_END();
    3807             : }
    3808             : /* }}} */
    3809             : 
    3810             : /* {{{ proto public array ReflectionClass::getStaticProperties()
    3811             :    Returns an associative array containing all static property values of the class */
    3812          17 : ZEND_METHOD(reflection_class, getStaticProperties)
    3813             : {
    3814             :         reflection_object *intern;
    3815             :         zend_class_entry *ce;
    3816             : 
    3817          17 :         if (zend_parse_parameters_none() == FAILURE) {
    3818           4 :                 return;
    3819             :         }
    3820             : 
    3821          26 :         GET_REFLECTION_OBJECT_PTR(ce);
    3822             : 
    3823          13 :         if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
    3824           0 :                 return;
    3825             :         }
    3826             : 
    3827          13 :         array_init(return_value);
    3828          13 :         add_class_vars(ce, 1, return_value);
    3829             : }
    3830             : /* }}} */
    3831             : 
    3832             : /* {{{ proto public mixed ReflectionClass::getStaticPropertyValue(string name [, mixed default])
    3833             :    Returns the value of a static property */
    3834          22 : ZEND_METHOD(reflection_class, getStaticPropertyValue)
    3835             : {
    3836             :         reflection_object *intern;
    3837             :         zend_class_entry *ce;
    3838             :         zend_string *name;
    3839          22 :         zval *prop, *def_value = NULL;
    3840             : 
    3841          22 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &name, &def_value) == FAILURE) {
    3842          16 :                 return;
    3843             :         }
    3844             : 
    3845          38 :         GET_REFLECTION_OBJECT_PTR(ce);
    3846             : 
    3847          19 :         if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
    3848           0 :                 return;
    3849             :         }
    3850          19 :         prop = zend_std_get_static_property(ce, name, 1);
    3851          19 :         if (!prop) {
    3852          10 :                 if (def_value) {
    3853           2 :                         ZVAL_COPY(return_value, def_value);
    3854             :                 } else {
    3855           8 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    3856           8 :                                 "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    3857             :                 }
    3858          10 :                 return;
    3859             :         } else {
    3860          18 :                 ZVAL_COPY_DEREF(return_value, prop);
    3861             :         }
    3862             : }
    3863             : /* }}} */
    3864             : 
    3865             : /* {{{ proto public void ReflectionClass::setStaticPropertyValue(string $name, mixed $value)
    3866             :    Sets the value of a static property */
    3867          11 : ZEND_METHOD(reflection_class, setStaticPropertyValue)
    3868             : {
    3869             :         reflection_object *intern;
    3870             :         zend_class_entry *ce;
    3871             :         zend_string *name;
    3872             :         zval *variable_ptr, *value;
    3873             : 
    3874          11 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) {
    3875          11 :                 return;
    3876             :         }
    3877             : 
    3878          14 :         GET_REFLECTION_OBJECT_PTR(ce);
    3879             : 
    3880           7 :         if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
    3881           0 :                 return;
    3882             :         }
    3883           7 :         variable_ptr = zend_std_get_static_property(ce, name, 1);
    3884           7 :         if (!variable_ptr) {
    3885           3 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    3886           3 :                                 "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    3887           3 :                 return;
    3888             :         }
    3889           4 :         ZVAL_DEREF(variable_ptr);
    3890           4 :         zval_ptr_dtor(variable_ptr);
    3891           4 :         ZVAL_COPY(variable_ptr, value);
    3892             : }
    3893             : /* }}} */
    3894             : 
    3895             : /* {{{ proto public array ReflectionClass::getDefaultProperties()
    3896             :    Returns an associative array containing copies of all default property values of the class */
    3897          16 : ZEND_METHOD(reflection_class, getDefaultProperties)
    3898             : {
    3899             :         reflection_object *intern;
    3900             :         zend_class_entry *ce;
    3901             : 
    3902          16 :         if (zend_parse_parameters_none() == FAILURE) {
    3903           4 :                 return;
    3904             :         }
    3905          24 :         GET_REFLECTION_OBJECT_PTR(ce);
    3906          12 :         array_init(return_value);
    3907          12 :         if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
    3908           0 :                 return;
    3909             :         }
    3910          12 :         add_class_vars(ce, 1, return_value);
    3911          12 :         add_class_vars(ce, 0, return_value);
    3912             : }
    3913             : /* }}} */
    3914             : 
    3915             : /* {{{ proto public string ReflectionClass::__toString()
    3916             :    Returns a string representation */
    3917          40 : ZEND_METHOD(reflection_class, __toString)
    3918             : {
    3919             :         reflection_object *intern;
    3920             :         zend_class_entry *ce;
    3921          40 :         smart_str str = {0};
    3922             : 
    3923          40 :         if (zend_parse_parameters_none() == FAILURE) {
    3924           0 :                 return;
    3925             :         }
    3926          80 :         GET_REFLECTION_OBJECT_PTR(ce);
    3927          40 :         _class_string(&str, ce, &intern->obj, "");
    3928         120 :         RETURN_STR(smart_str_extract(&str));
    3929             : }
    3930             : /* }}} */
    3931             : 
    3932             : /* {{{ proto public string ReflectionClass::getName()
    3933             :    Returns the class' name */
    3934          75 : ZEND_METHOD(reflection_class, getName)
    3935             : {
    3936          75 :         if (zend_parse_parameters_none() == FAILURE) {
    3937           5 :                 return;
    3938             :         }
    3939         140 :         _default_get_name(getThis(), return_value);
    3940             : }
    3941             : /* }}} */
    3942             : 
    3943             : /* {{{ proto public bool ReflectionClass::isInternal()
    3944             :    Returns whether this class is an internal class */
    3945          18 : ZEND_METHOD(reflection_class, isInternal)
    3946             : {
    3947             :         reflection_object *intern;
    3948             :         zend_class_entry *ce;
    3949             : 
    3950          18 :         if (zend_parse_parameters_none() == FAILURE) {
    3951           4 :                 return;
    3952             :         }
    3953          28 :         GET_REFLECTION_OBJECT_PTR(ce);
    3954          14 :         RETURN_BOOL(ce->type == ZEND_INTERNAL_CLASS);
    3955             : }
    3956             : /* }}} */
    3957             : 
    3958             : /* {{{ proto public bool ReflectionClass::isUserDefined()
    3959             :    Returns whether this class is user-defined */
    3960          18 : ZEND_METHOD(reflection_class, isUserDefined)
    3961             : {
    3962             :         reflection_object *intern;
    3963             :         zend_class_entry *ce;
    3964             : 
    3965          18 :         if (zend_parse_parameters_none() == FAILURE) {
    3966           4 :                 return;
    3967             :         }
    3968          28 :         GET_REFLECTION_OBJECT_PTR(ce);
    3969          14 :         RETURN_BOOL(ce->type == ZEND_USER_CLASS);
    3970             : }
    3971             : /* }}} */
    3972             : 
    3973             : /* {{{ proto public bool ReflectionClass::isAnonymous()
    3974             :    Returns whether this class is anonymous */
    3975           2 : ZEND_METHOD(reflection_class, isAnonymous)
    3976             : {
    3977             :         reflection_object *intern;
    3978             :         zend_class_entry *ce;
    3979             : 
    3980           2 :         if (zend_parse_parameters_none() == FAILURE) {
    3981           0 :                 return;
    3982             :         }
    3983           4 :         GET_REFLECTION_OBJECT_PTR(ce);
    3984           2 :         RETURN_BOOL(ce->ce_flags & ZEND_ACC_ANON_CLASS);
    3985             : }
    3986             : /* }}} */
    3987             : 
    3988             : /* {{{ proto public string ReflectionClass::getFileName()
    3989             :    Returns the filename of the file this class was declared in */
    3990          10 : ZEND_METHOD(reflection_class, getFileName)
    3991             : {
    3992             :         reflection_object *intern;
    3993             :         zend_class_entry *ce;
    3994             : 
    3995          10 :         if (zend_parse_parameters_none() == FAILURE) {
    3996           4 :                 return;
    3997             :         }
    3998          12 :         GET_REFLECTION_OBJECT_PTR(ce);
    3999           6 :         if (ce->type == ZEND_USER_CLASS) {
    4000           8 :                 RETURN_STR_COPY(ce->info.user.filename);
    4001             :         }
    4002           2 :         RETURN_FALSE;
    4003             : }
    4004             : /* }}} */
    4005             : 
    4006             : /* {{{ proto public int ReflectionClass::getStartLine()
    4007             :    Returns the line this class' declaration starts at */
    4008          12 : ZEND_METHOD(reflection_class, getStartLine)
    4009             : {
    4010             :         reflection_object *intern;
    4011             :         zend_class_entry *ce;
    4012             : 
    4013          12 :         if (zend_parse_parameters_none() == FAILURE) {
    4014           4 :                 return;
    4015             :         }
    4016          16 :         GET_REFLECTION_OBJECT_PTR(ce);
    4017           8 :         if (ce->type == ZEND_USER_CLASS) {
    4018           6 :                 RETURN_LONG(ce->info.user.line_start);
    4019             :         }
    4020           2 :         RETURN_FALSE;
    4021             : }
    4022             : /* }}} */
    4023             : 
    4024             : /* {{{ proto public int ReflectionClass::getEndLine()
    4025             :    Returns the line this class' declaration ends at */
    4026          10 : ZEND_METHOD(reflection_class, getEndLine)
    4027             : {
    4028             :         reflection_object *intern;
    4029             :         zend_class_entry *ce;
    4030             : 
    4031          10 :         if (zend_parse_parameters_none() == FAILURE) {
    4032           4 :                 return;
    4033             :         }
    4034          12 :         GET_REFLECTION_OBJECT_PTR(ce);
    4035           6 :         if (ce->type == ZEND_USER_CLASS) {
    4036           4 :                 RETURN_LONG(ce->info.user.line_end);
    4037             :         }
    4038           2 :         RETURN_FALSE;
    4039             : }
    4040             : /* }}} */
    4041             : 
    4042             : /* {{{ proto public string ReflectionClass::getDocComment()
    4043             :    Returns the doc comment for this class */
    4044          17 : ZEND_METHOD(reflection_class, getDocComment)
    4045             : {
    4046             :         reflection_object *intern;
    4047             :         zend_class_entry *ce;
    4048             : 
    4049          17 :         if (zend_parse_parameters_none() == FAILURE) {
    4050           4 :                 return;
    4051             :         }
    4052          26 :         GET_REFLECTION_OBJECT_PTR(ce);
    4053          13 :         if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
    4054          21 :                 RETURN_STR_COPY(ce->info.user.doc_comment);
    4055             :         }
    4056           6 :         RETURN_FALSE;
    4057             : }
    4058             : /* }}} */
    4059             : 
    4060             : /* {{{ proto public ReflectionMethod ReflectionClass::getConstructor()
    4061             :    Returns the class' constructor if there is one, NULL otherwise */
    4062          37 : ZEND_METHOD(reflection_class, getConstructor)
    4063             : {
    4064             :         reflection_object *intern;
    4065             :         zend_class_entry *ce;
    4066             : 
    4067          37 :         if (zend_parse_parameters_none() == FAILURE) {
    4068           8 :                 return;
    4069             :         }
    4070          58 :         GET_REFLECTION_OBJECT_PTR(ce);
    4071             : 
    4072          29 :         if (ce->constructor) {
    4073          24 :                 reflection_method_factory(ce, ce->constructor, NULL, return_value);
    4074             :         } else {
    4075           5 :                 RETURN_NULL();
    4076             :         }
    4077             : }
    4078             : /* }}} */
    4079             : 
    4080             : /* {{{ proto public bool ReflectionClass::hasMethod(string name)
    4081             :    Returns whether a method exists or not */
    4082          42 : ZEND_METHOD(reflection_class, hasMethod)
    4083             : {
    4084             :         reflection_object *intern;
    4085             :         zend_class_entry *ce;
    4086             :         char *name, *lc_name;
    4087             :         size_t name_len;
    4088             : 
    4089          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
    4090           4 :                 return;
    4091             :         }
    4092             : 
    4093          76 :         GET_REFLECTION_OBJECT_PTR(ce);
    4094          38 :         lc_name = zend_str_tolower_dup(name, name_len);
    4095          38 :         if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    4096           3 :                 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
    4097          35 :                 || zend_hash_str_exists(&ce->function_table, lc_name, name_len)) {
    4098          27 :                 efree(lc_name);
    4099          27 :                 RETURN_TRUE;
    4100             :         } else {
    4101          11 :                 efree(lc_name);
    4102          11 :                 RETURN_FALSE;
    4103             :         }
    4104             : }
    4105             : /* }}} */
    4106             : 
    4107             : /* {{{ proto public ReflectionMethod ReflectionClass::getMethod(string name) throws ReflectionException
    4108             :    Returns the class' method specified by its name */
    4109          62 : ZEND_METHOD(reflection_class, getMethod)
    4110             : {
    4111             :         reflection_object *intern;
    4112             :         zend_class_entry *ce;
    4113             :         zend_function *mptr;
    4114             :         zval obj_tmp;
    4115             :         char *name, *lc_name;
    4116             :         size_t name_len;
    4117             : 
    4118          62 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
    4119          18 :                 return;
    4120             :         }
    4121             : 
    4122         116 :         GET_REFLECTION_OBJECT_PTR(ce);
    4123          58 :         lc_name = zend_str_tolower_dup(name, name_len);
    4124          63 :         if (ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    4125           2 :                 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
    4126           2 :                 && (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL)
    4127             :         {
    4128             :                 /* don't assign closure_object since we only reflect the invoke handler
    4129             :                    method and not the closure definition itself */
    4130           2 :                 reflection_method_factory(ce, mptr, NULL, return_value);
    4131           2 :                 efree(lc_name);
    4132          59 :         } else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    4133           3 :                 && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
    4134           3 :                 && object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
    4135             :                 /* don't assign closure_object since we only reflect the invoke handler
    4136             :                    method and not the closure definition itself */
    4137           3 :                 reflection_method_factory(ce, mptr, NULL, return_value);
    4138           3 :                 zval_ptr_dtor(&obj_tmp);
    4139           3 :                 efree(lc_name);
    4140         106 :         } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lc_name, name_len)) != NULL) {
    4141          43 :                 reflection_method_factory(ce, mptr, NULL, return_value);
    4142          43 :                 efree(lc_name);
    4143             :         } else {
    4144          10 :                 efree(lc_name);
    4145          10 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    4146             :                                 "Method %s does not exist", name);
    4147          10 :                 return;
    4148             :         }
    4149             : }
    4150             : /* }}} */
    4151             : 
    4152             : /* {{{ _addmethod */
    4153         283 : static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, zend_long filter)
    4154             : {
    4155         283 :         if (mptr->common.fn_flags & filter) {
    4156             :                 zval method;
    4157         263 :                 reflection_method_factory(ce, mptr, NULL, &method);
    4158         263 :                 add_next_index_zval(retval, &method);
    4159             :         }
    4160         283 : }
    4161             : /* }}} */
    4162             : 
    4163             : /* {{{ _addmethod */
    4164         281 : static int _addmethod_va(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
    4165             : {
    4166         281 :         zend_function *mptr = (zend_function*)Z_PTR_P(el);
    4167         281 :         zend_class_entry *ce = *va_arg(args, zend_class_entry**);
    4168         281 :         zval *retval = va_arg(args, zval*);
    4169         281 :         long filter = va_arg(args, long);
    4170             : 
    4171         281 :         _addmethod(mptr, ce, retval, filter);
    4172         281 :         return ZEND_HASH_APPLY_KEEP;
    4173             : }
    4174             : /* }}} */
    4175             : 
    4176             : /* {{{ proto public ReflectionMethod[] ReflectionClass::getMethods([long $filter])
    4177             :    Returns an array of this class' methods */
    4178          41 : ZEND_METHOD(reflection_class, getMethods)
    4179             : {
    4180             :         reflection_object *intern;
    4181             :         zend_class_entry *ce;
    4182          41 :         zend_long filter = 0;
    4183          41 :         zend_bool filter_is_null = 1;
    4184             : 
    4185          41 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) {
    4186           4 :                 return;
    4187             :         }
    4188             : 
    4189          39 :         if (filter_is_null) {
    4190          34 :                 filter = ZEND_ACC_PPP_MASK | ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL | ZEND_ACC_STATIC;
    4191             :         }
    4192             : 
    4193          78 :         GET_REFLECTION_OBJECT_PTR(ce);
    4194             : 
    4195          39 :         array_init(return_value);
    4196          39 :         zend_hash_apply_with_arguments(&ce->function_table, (apply_func_args_t) _addmethod_va, 4, &ce, return_value, filter);
    4197             : 
    4198          39 :         if (instanceof_function(ce, zend_ce_closure)) {
    4199           4 :                 zend_bool has_obj = Z_TYPE(intern->obj) != IS_UNDEF;
    4200             :                 zval obj_tmp;
    4201             :                 zend_object *obj;
    4202           2 :                 if (!has_obj) {
    4203           1 :                         object_init_ex(&obj_tmp, ce);
    4204           1 :                         obj = Z_OBJ(obj_tmp);
    4205             :                 } else {
    4206           1 :                         obj = Z_OBJ(intern->obj);
    4207             :                 }
    4208           2 :                 zend_function *closure = zend_get_closure_invoke_method(obj);
    4209           2 :                 if (closure) {
    4210           2 :                         _addmethod(closure, ce, return_value, filter);
    4211             :                 }
    4212           2 :                 if (!has_obj) {
    4213           1 :                         zval_ptr_dtor(&obj_tmp);
    4214             :                 }
    4215             :         }
    4216             : }
    4217             : /* }}} */
    4218             : 
    4219             : /* {{{ proto public bool ReflectionClass::hasProperty(string name)
    4220             :    Returns whether a property exists or not */
    4221          43 : ZEND_METHOD(reflection_class, hasProperty)
    4222             : {
    4223             :         reflection_object *intern;
    4224             :         zend_property_info *property_info;
    4225             :         zend_class_entry *ce;
    4226             :         zend_string *name;
    4227             :         zval property;
    4228             : 
    4229          43 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
    4230           4 :                 return;
    4231             :         }
    4232             : 
    4233          78 :         GET_REFLECTION_OBJECT_PTR(ce);
    4234          78 :         if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
    4235          20 :                 if (property_info->flags & ZEND_ACC_SHADOW) {
    4236           2 :                         RETURN_FALSE;
    4237             :                 }
    4238          18 :                 RETURN_TRUE;
    4239             :         } else {
    4240          38 :                 if (Z_TYPE(intern->obj) != IS_UNDEF && Z_OBJ_HANDLER(intern->obj, has_property)) {
    4241           4 :                         ZVAL_STR_COPY(&property, name);
    4242           2 :                         if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) {
    4243           0 :                                 zval_ptr_dtor(&property);
    4244           0 :                                 RETURN_TRUE;
    4245             :                         }
    4246           2 :                         zval_ptr_dtor(&property);
    4247             :                 }
    4248          19 :                 RETURN_FALSE;
    4249             :         }
    4250             : }
    4251             : /* }}} */
    4252             : 
    4253             : /* {{{ proto public ReflectionProperty ReflectionClass::getProperty(string name) throws ReflectionException
    4254             :    Returns the class' property specified by its name */
    4255         110 : ZEND_METHOD(reflection_class, getProperty)
    4256             : {
    4257             :         reflection_object *intern;
    4258             :         zend_class_entry *ce, *ce2;
    4259             :         zend_property_info *property_info;
    4260             :         zend_string *name, *classname;
    4261             :         char *tmp, *str_name;
    4262             :         size_t classname_len, str_name_len;
    4263             : 
    4264         110 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
    4265          88 :                 return;
    4266             :         }
    4267             : 
    4268         212 :         GET_REFLECTION_OBJECT_PTR(ce);
    4269         212 :         if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
    4270          50 :                 if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
    4271          44 :                         reflection_property_factory(ce, name, property_info, return_value);
    4272          44 :                         return;
    4273             :                 }
    4274         112 :         } else if (Z_TYPE(intern->obj) != IS_UNDEF) {
    4275             :                 /* Check for dynamic properties */
    4276           5 :                 if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(&intern->obj), name)) {
    4277             :                         zend_property_info property_info_tmp;
    4278           5 :                         property_info_tmp.flags = ZEND_ACC_IMPLICIT_PUBLIC;
    4279           5 :                         property_info_tmp.name = name;
    4280           5 :                         property_info_tmp.doc_comment = NULL;
    4281           5 :                         property_info_tmp.ce = ce;
    4282             : 
    4283           5 :                         reflection_property_factory(ce, name, &property_info_tmp, return_value);
    4284           5 :                         return;
    4285             :                 }
    4286             :         }
    4287          57 :         str_name = ZSTR_VAL(name);
    4288          57 :         if ((tmp = strstr(ZSTR_VAL(name), "::")) != NULL) {
    4289          33 :                 classname_len = tmp - ZSTR_VAL(name);
    4290          33 :                 classname = zend_string_alloc(classname_len, 0);
    4291          33 :                 zend_str_tolower_copy(ZSTR_VAL(classname), ZSTR_VAL(name), classname_len);
    4292          33 :                 ZSTR_VAL(classname)[classname_len] = '\0';
    4293          33 :                 str_name_len = ZSTR_LEN(name) - (classname_len + 2);
    4294          33 :                 str_name = tmp + 2;
    4295             : 
    4296          33 :                 ce2 = zend_lookup_class(classname);
    4297          33 :                 if (!ce2) {
    4298           3 :                         if (!EG(exception)) {
    4299           3 :                                 zend_throw_exception_ex(reflection_exception_ptr, -1, "Class %s does not exist", ZSTR_VAL(classname));
    4300             :                         }
    4301             :                         zend_string_release_ex(classname, 0);
    4302           3 :                         return;
    4303             :                 }
    4304             :                 zend_string_release_ex(classname, 0);
    4305             : 
    4306          30 :                 if (!instanceof_function(ce, ce2)) {
    4307           8 :                         zend_throw_exception_ex(reflection_exception_ptr, -1, "Fully qualified property name %s::%s does not specify a base class of %s", ZSTR_VAL(ce2->name), str_name, ZSTR_VAL(ce->name));
    4308           8 :                         return;
    4309             :                 }
    4310          22 :                 ce = ce2;
    4311             : 
    4312          44 :                 if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
    4313          20 :                         reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value);
    4314          20 :                         return;
    4315             :                 }
    4316             :         }
    4317          26 :         zend_throw_exception_ex(reflection_exception_ptr, 0,
    4318             :                         "Property %s does not exist", str_name);
    4319             : }
    4320             : /* }}} */
    4321             : 
    4322             : /* {{{ _addproperty */
    4323         107 : static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
    4324             : {
    4325             :         zval property;
    4326         107 :         zend_property_info *pptr = (zend_property_info*)Z_PTR_P(el);
    4327         107 :         zend_class_entry *ce = *va_arg(args, zend_class_entry**);
    4328         107 :         zval *retval = va_arg(args, zval*);
    4329         107 :         long filter = va_arg(args, long);
    4330             : 
    4331         107 :         if (pptr->flags      & ZEND_ACC_SHADOW) {
    4332           3 :                 return 0;
    4333             :         }
    4334             : 
    4335         104 :         if (pptr->flags      & filter) {
    4336             :                 const char *class_name, *prop_name;
    4337             :                 size_t prop_name_len;
    4338          84 :                 zend_unmangle_property_name_ex(pptr->name, &class_name, &prop_name, &prop_name_len);
    4339          84 :                 reflection_property_factory_str(ce, prop_name, prop_name_len, pptr, &property);
    4340          84 :                 add_next_index_zval(retval, &property);
    4341             :         }
    4342         104 :         return 0;
    4343             : }
    4344             : /* }}} */
    4345             : 
    4346             : /* {{{ _adddynproperty */
    4347          18 : static int _adddynproperty(zval *ptr, int num_args, va_list args, zend_hash_key *hash_key)
    4348             : {
    4349             :         zval property;
    4350          18 :         zend_class_entry *ce = *va_arg(args, zend_class_entry**);
    4351          18 :         zval *retval = va_arg(args, zval*);
    4352             : 
    4353             :         /* under some circumstances, the properties hash table may contain numeric
    4354             :          * properties (e.g. when casting from array). This is a WONT FIX bug, at
    4355             :          * least for the moment. Ignore these */
    4356          18 :         if (hash_key->key == NULL) {
    4357           1 :                 return 0;
    4358             :         }
    4359             : 
    4360          17 :         if (ZSTR_VAL(hash_key->key)[0] == '\0') {
    4361           2 :                 return 0; /* non public cannot be dynamic */
    4362             :         }
    4363             : 
    4364          15 :         if (zend_get_property_info(ce, hash_key->key, 1) == NULL) {
    4365             :                 zend_property_info property_info;
    4366             : 
    4367          12 :                 property_info.doc_comment = NULL;
    4368          12 :                 property_info.flags = ZEND_ACC_IMPLICIT_PUBLIC;
    4369          12 :                 property_info.name = hash_key->key;
    4370          12 :                 property_info.ce = ce;
    4371          12 :                 property_info.offset = -1;
    4372          12 :                 reflection_property_factory(ce, hash_key->key, &property_info, &property);
    4373          12 :                 add_next_index_zval(retval, &property);
    4374             :         }
    4375          15 :         return 0;
    4376             : }
    4377             : /* }}} */
    4378             : 
    4379             : /* {{{ proto public ReflectionProperty[] ReflectionClass::getProperties([long $filter])
    4380             :    Returns an array of this class' properties */
    4381          33 : ZEND_METHOD(reflection_class, getProperties)
    4382             : {
    4383             :         reflection_object *intern;
    4384             :         zend_class_entry *ce;
    4385          33 :         zend_long filter = 0;
    4386          33 :         zend_bool filter_is_null = 1;
    4387             : 
    4388          33 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l!", &filter, &filter_is_null) == FAILURE) {
    4389           4 :                 return;
    4390             :         }
    4391             :         
    4392          31 :         if (filter_is_null) {
    4393          24 :                 filter = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC;
    4394             :         }
    4395             : 
    4396          62 :         GET_REFLECTION_OBJECT_PTR(ce);
    4397             : 
    4398          31 :         array_init(return_value);
    4399          31 :         zend_hash_apply_with_arguments(&ce->properties_info, (apply_func_args_t) _addproperty, 3, &ce, return_value, filter);
    4400             : 
    4401          62 :         if (Z_TYPE(intern->obj) != IS_UNDEF && (filter & ZEND_ACC_PUBLIC) != 0 && Z_OBJ_HT(intern->obj)->get_properties) {
    4402          10 :                 HashTable *properties = Z_OBJ_HT(intern->obj)->get_properties(&intern->obj);
    4403          10 :                 zend_hash_apply_with_arguments(properties, (apply_func_args_t) _adddynproperty, 2, &ce, return_value);
    4404             :         }
    4405             : }
    4406             : /* }}} */
    4407             : 
    4408             : /* {{{ proto public bool ReflectionClass::hasConstant(string name)
    4409             :    Returns whether a constant exists or not */
    4410          17 : ZEND_METHOD(reflection_class, hasConstant)
    4411             : {
    4412             :         reflection_object *intern;
    4413             :         zend_class_entry *ce;
    4414             :         zend_string *name;
    4415             : 
    4416          17 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
    4417           4 :                 return;
    4418             :         }
    4419             : 
    4420          26 :         GET_REFLECTION_OBJECT_PTR(ce);
    4421          13 :         if (zend_hash_exists(&ce->constants_table, name)) {
    4422           4 :                 RETURN_TRUE;
    4423             :         } else {
    4424           9 :                 RETURN_FALSE;
    4425             :         }
    4426             : }
    4427             : /* }}} */
    4428             : 
    4429             : /* {{{ proto public array ReflectionClass::getConstants()
    4430             :    Returns an associative array containing this class' constants and their values */
    4431          33 : ZEND_METHOD(reflection_class, getConstants)
    4432             : {
    4433             :         reflection_object *intern;
    4434             :         zend_class_entry *ce;
    4435             :         zend_string *key;
    4436             :         zend_class_constant *c;
    4437             :         zval val;
    4438             : 
    4439          33 :         if (zend_parse_parameters_none() == FAILURE) {
    4440          13 :                 return;
    4441             :         }
    4442          54 :         GET_REFLECTION_OBJECT_PTR(ce);
    4443          27 :         array_init(return_value);
    4444         900 :         ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) {
    4445         437 :                 if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) {
    4446           1 :                         zend_array_destroy(Z_ARRVAL_P(return_value));
    4447           1 :                         RETURN_NULL();
    4448             :                 }
    4449         436 :                 ZVAL_COPY_OR_DUP(&val, &c->value);
    4450         436 :                 zend_hash_add_new(Z_ARRVAL_P(return_value), key, &val);
    4451             :         } ZEND_HASH_FOREACH_END();
    4452             : }
    4453             : /* }}} */
    4454             : 
    4455             : /* {{{ proto public array ReflectionClass::getReflectionConstants()
    4456             :    Returns an associative array containing this class' constants as ReflectionClassConstant objects */
    4457           1 : ZEND_METHOD(reflection_class, getReflectionConstants)
    4458             : {
    4459             :         reflection_object *intern;
    4460             :         zend_class_entry *ce;
    4461             :         zend_string *name;
    4462             :         zend_class_constant *constant;
    4463             : 
    4464           1 :         if (zend_parse_parameters_none() == FAILURE) {
    4465           0 :                 return;
    4466             :         }
    4467           2 :         GET_REFLECTION_OBJECT_PTR(ce);
    4468           1 :         array_init(return_value);
    4469          13 :         ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) {
    4470             :                 zval class_const;
    4471           6 :                 reflection_class_constant_factory(ce, name, constant, &class_const);
    4472           6 :                 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const);
    4473             :         } ZEND_HASH_FOREACH_END();
    4474             : }
    4475             : /* }}} */
    4476             : 
    4477             : /* {{{ proto public mixed ReflectionClass::getConstant(string name)
    4478             :    Returns the class' constant specified by its name */
    4479          44 : ZEND_METHOD(reflection_class, getConstant)
    4480             : {
    4481             :         reflection_object *intern;
    4482             :         zend_class_entry *ce;
    4483             :         zend_class_constant *c;
    4484             :         zend_string *name;
    4485             : 
    4486          44 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
    4487          38 :                 return;
    4488             :         }
    4489             : 
    4490          72 :         GET_REFLECTION_OBJECT_PTR(ce);
    4491         142 :         ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
    4492          53 :                 if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) {
    4493           0 :                         return;
    4494             :                 }
    4495             :         } ZEND_HASH_FOREACH_END();
    4496          72 :         if ((c = zend_hash_find_ptr(&ce->constants_table, name)) == NULL) {
    4497          22 :                 RETURN_FALSE;
    4498             :         }
    4499          14 :         ZVAL_COPY_OR_DUP(return_value, &c->value);
    4500             : }
    4501             : /* }}} */
    4502             : 
    4503             : /* {{{ proto public mixed ReflectionClass::getReflectionConstant(string name)
    4504             :    Returns the class' constant as ReflectionClassConstant objects */
    4505           2 : ZEND_METHOD(reflection_class, getReflectionConstant)
    4506             : {
    4507             :         reflection_object *intern;
    4508             :         zend_class_entry *ce;
    4509             :         zend_class_constant *constant;
    4510             :         zend_string *name;
    4511             : 
    4512           5 :         GET_REFLECTION_OBJECT_PTR(ce);
    4513           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
    4514           0 :                 return;
    4515             :         }
    4516             : 
    4517           4 :         if ((constant = zend_hash_find_ptr(&ce->constants_table, name)) == NULL) {
    4518           1 :                 RETURN_FALSE;
    4519             :         }
    4520           1 :         reflection_class_constant_factory(ce, name, constant, return_value);
    4521             : }
    4522             : /* }}} */
    4523             : 
    4524             : /* {{{ _class_check_flag */
    4525          43 : static void _class_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
    4526             : {
    4527             :         reflection_object *intern;
    4528             :         zend_class_entry *ce;
    4529             : 
    4530          43 :         if (zend_parse_parameters_none() == FAILURE) {
    4531           3 :                 return;
    4532             :         }
    4533          80 :         GET_REFLECTION_OBJECT_PTR(ce);
    4534          40 :         RETVAL_BOOL(ce->ce_flags & mask);
    4535             : }
    4536             : /* }}} */
    4537             : 
    4538             : /* {{{ proto public bool ReflectionClass::isInstantiable()
    4539             :    Returns whether this class is instantiable */
    4540          56 : ZEND_METHOD(reflection_class, isInstantiable)
    4541             : {
    4542             :         reflection_object *intern;
    4543             :         zend_class_entry *ce;
    4544             : 
    4545          56 :         if (zend_parse_parameters_none() == FAILURE) {
    4546           4 :                 return;
    4547             :         }
    4548         104 :         GET_REFLECTION_OBJECT_PTR(ce);
    4549          52 :         if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
    4550           8 :                 RETURN_FALSE;
    4551             :         }
    4552             : 
    4553             :         /* Basically, the class is instantiable. Though, if there is a constructor
    4554             :          * and it is not publicly accessible, it isn't! */
    4555          44 :         if (!ce->constructor) {
    4556          29 :                 RETURN_TRUE;
    4557             :         }
    4558             : 
    4559          15 :         RETURN_BOOL(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC);
    4560             : }
    4561             : /* }}} */
    4562             : 
    4563             : /* {{{ proto public bool ReflectionClass::isCloneable()
    4564             :    Returns whether this class is cloneable */
    4565          16 : ZEND_METHOD(reflection_class, isCloneable)
    4566             : {
    4567             :         reflection_object *intern;
    4568             :         zend_class_entry *ce;
    4569             :         zval obj;
    4570             : 
    4571          16 :         if (zend_parse_parameters_none() == FAILURE) {
    4572          11 :                 return;
    4573             :         }
    4574          32 :         GET_REFLECTION_OBJECT_PTR(ce);
    4575          16 :         if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) {
    4576           4 :                 RETURN_FALSE;
    4577             :         }
    4578          24 :         if (!Z_ISUNDEF(intern->obj)) {
    4579           6 :                 if (ce->clone) {
    4580           1 :                         RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
    4581             :                 } else {
    4582           5 :                         RETURN_BOOL(Z_OBJ_HANDLER(intern->obj, clone_obj) != NULL);
    4583             :                 }
    4584             :         } else {
    4585           6 :                 if (ce->clone) {
    4586           1 :                         RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC);
    4587             :                 } else {
    4588           5 :                         if (UNEXPECTED(object_init_ex(&obj, ce) != SUCCESS)) {
    4589           0 :                                 return;
    4590             :                         }
    4591             :                         /* We're not calling the constructor, so don't call the destructor either. */
    4592           5 :                         zend_object_store_ctor_failed(Z_OBJ(obj));
    4593           5 :                         RETVAL_BOOL(Z_OBJ_HANDLER(obj, clone_obj) != NULL);
    4594           5 :                         zval_ptr_dtor(&obj);
    4595             :                 }
    4596             :         }
    4597             : }
    4598             : /* }}} */
    4599             : 
    4600             : /* {{{ proto public bool ReflectionClass::isInterface()
    4601             :    Returns whether this is an interface or a class */
    4602          13 : ZEND_METHOD(reflection_class, isInterface)
    4603             : {
    4604          13 :         _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE);
    4605          13 : }
    4606             : /* }}} */
    4607             : 
    4608             : /* {{{ proto public bool ReflectionClass::isTrait()
    4609             :    Returns whether this is a trait */
    4610           5 : ZEND_METHOD(reflection_class, isTrait)
    4611             : {
    4612           5 :         _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT);
    4613           5 : }
    4614             : /* }}} */
    4615             : 
    4616             : /* {{{ proto public bool ReflectionClass::isFinal()
    4617             :    Returns whether this class is final */
    4618          12 : ZEND_METHOD(reflection_class, isFinal)
    4619             : {
    4620          12 :         _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
    4621          12 : }
    4622             : /* }}} */
    4623             : 
    4624             : /* {{{ proto public bool ReflectionClass::isAbstract()
    4625             :    Returns whether this class is abstract */
    4626          13 : ZEND_METHOD(reflection_class, isAbstract)
    4627             : {
    4628          13 :         _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
    4629          13 : }
    4630             : /* }}} */
    4631             : 
    4632             : /* {{{ proto public int ReflectionClass::getModifiers()
    4633             :    Returns a bitfield of the access modifiers for this class */
    4634          21 : ZEND_METHOD(reflection_class, getModifiers)
    4635             : {
    4636             :         reflection_object *intern;
    4637             :         zend_class_entry *ce;
    4638          21 :         uint32_t keep_flags = ZEND_ACC_FINAL
    4639             :                 | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    4640             : 
    4641          21 :         if (zend_parse_parameters_none() == FAILURE) {
    4642           1 :                 return;
    4643             :         }
    4644          40 :         GET_REFLECTION_OBJECT_PTR(ce);
    4645             : 
    4646          20 :         RETURN_LONG((ce->ce_flags & keep_flags));
    4647             : }
    4648             : /* }}} */
    4649             : 
    4650             : /* {{{ proto public bool ReflectionClass::isInstance(stdclass object)
    4651             :    Returns whether the given object is an instance of this class */
    4652          59 : ZEND_METHOD(reflection_class, isInstance)
    4653             : {
    4654             :         reflection_object *intern;
    4655             :         zend_class_entry *ce;
    4656             :         zval *object;
    4657             : 
    4658          59 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
    4659          14 :                 return;
    4660             :         }
    4661          90 :         GET_REFLECTION_OBJECT_PTR(ce);
    4662          45 :         RETURN_BOOL(instanceof_function(Z_OBJCE_P(object), ce));
    4663             : }
    4664             : /* }}} */
    4665             : 
    4666             : /* {{{ proto public stdclass ReflectionClass::newInstance(mixed* args, ...)
    4667             :    Returns an instance of this class */
    4668          53 : ZEND_METHOD(reflection_class, newInstance)
    4669             : {
    4670             :         zval retval;
    4671             :         reflection_object *intern;
    4672             :         zend_class_entry *ce, *old_scope;
    4673             :         zend_function *constructor;
    4674             : 
    4675         109 :         GET_REFLECTION_OBJECT_PTR(ce);
    4676             : 
    4677          53 :         if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) {
    4678           1 :                 return;
    4679             :         }
    4680             : 
    4681          52 :         old_scope = EG(fake_scope);
    4682          52 :         EG(fake_scope) = ce;
    4683          52 :         constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
    4684          52 :         EG(fake_scope) = old_scope;
    4685             : 
    4686             :         /* Run the constructor if there is one */
    4687          52 :         if (constructor) {
    4688          25 :                 zval *params = NULL;
    4689          25 :                 int ret, i, num_args = 0;
    4690             :                 zend_fcall_info fci;
    4691             :                 zend_fcall_info_cache fcc;
    4692             : 
    4693          25 :                 if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
    4694           2 :                         zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
    4695           2 :                         zval_ptr_dtor(return_value);
    4696           4 :                         RETURN_NULL();
    4697             :                 }
    4698             : 
    4699          23 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "*", &params, &num_args) == FAILURE) {
    4700           0 :                         zval_ptr_dtor(return_value);
    4701           0 :                         RETURN_FALSE;
    4702             :                 }
    4703             : 
    4704          55 :                 for (i = 0; i < num_args; i++) {
    4705          32 :                         Z_TRY_ADDREF(params[i]);
    4706             :                 }
    4707             : 
    4708          23 :                 fci.size = sizeof(fci);
    4709          23 :                 ZVAL_UNDEF(&fci.function_name);
    4710          23 :                 fci.object = Z_OBJ_P(return_value);
    4711          23 :                 fci.retval = &retval;
    4712          23 :                 fci.param_count = num_args;
    4713          23 :                 fci.params = params;
    4714          23 :                 fci.no_separation = 1;
    4715             : 
    4716          23 :                 fcc.function_handler = constructor;
    4717          23 :                 fcc.called_scope = Z_OBJCE_P(return_value);
    4718          23 :                 fcc.object = Z_OBJ_P(return_value);
    4719             : 
    4720          23 :                 ret = zend_call_function(&fci, &fcc);
    4721          23 :                 zval_ptr_dtor(&retval);
    4722          55 :                 for (i = 0; i < num_args; i++) {
    4723          32 :                         zval_ptr_dtor(&params[i]);
    4724             :                 }
    4725             : 
    4726          23 :                 if (EG(exception)) {
    4727           3 :                         zend_object_store_ctor_failed(Z_OBJ_P(return_value));
    4728             :                 }
    4729          23 :                 if (ret == FAILURE) {
    4730           0 :                         php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
    4731           0 :                         zval_ptr_dtor(return_value);
    4732           0 :                         RETURN_NULL();
    4733             :                 }
    4734          27 :         } else if (ZEND_NUM_ARGS()) {
    4735           3 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
    4736             :         }
    4737             : }
    4738             : /* }}} */
    4739             : 
    4740             : /* {{{ proto public stdclass ReflectionClass::newInstanceWithoutConstructor()
    4741             :    Returns an instance of this class without invoking its constructor */
    4742           5 : ZEND_METHOD(reflection_class, newInstanceWithoutConstructor)
    4743             : {
    4744             :         reflection_object *intern;
    4745             :         zend_class_entry *ce;
    4746             : 
    4747          10 :         GET_REFLECTION_OBJECT_PTR(ce);
    4748             : 
    4749           5 :         if (ce->create_object != NULL && ce->ce_flags & ZEND_ACC_FINAL) {
    4750           2 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ZSTR_VAL(ce->name));
    4751           2 :                 return;
    4752             :         }
    4753             : 
    4754           3 :         object_init_ex(return_value, ce);
    4755             : }
    4756             : /* }}} */
    4757             : 
    4758             : /* {{{ proto public stdclass ReflectionClass::newInstanceArgs([array args])
    4759             :    Returns an instance of this class */
    4760          19 : ZEND_METHOD(reflection_class, newInstanceArgs)
    4761             : {
    4762             :         zval retval, *val;
    4763             :         reflection_object *intern;
    4764             :         zend_class_entry *ce, *old_scope;
    4765          19 :         int ret, i, argc = 0;
    4766             :         HashTable *args;
    4767             :         zend_function *constructor;
    4768             : 
    4769          40 :         GET_REFLECTION_OBJECT_PTR(ce);
    4770             : 
    4771          19 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|h", &args) == FAILURE) {
    4772           0 :                 return;
    4773             :         }
    4774             : 
    4775          19 :         if (ZEND_NUM_ARGS() > 0) {
    4776          12 :                 argc = args->nNumOfElements;
    4777             :         }
    4778             : 
    4779          19 :         if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) {
    4780           0 :                 return;
    4781             :         }
    4782             : 
    4783          19 :         old_scope = EG(fake_scope);
    4784          19 :         EG(fake_scope) = ce;
    4785          19 :         constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
    4786          19 :         EG(fake_scope) = old_scope;
    4787             : 
    4788             :         /* Run the constructor if there is one */
    4789          19 :         if (constructor) {
    4790          15 :                 zval *params = NULL;
    4791             :                 zend_fcall_info fci;
    4792             :                 zend_fcall_info_cache fcc;
    4793             : 
    4794          15 :                 if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
    4795           2 :                         zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
    4796           2 :                         zval_ptr_dtor(return_value);
    4797           4 :                         RETURN_NULL();
    4798             :                 }
    4799             : 
    4800          13 :                 if (argc) {
    4801           7 :                         params = safe_emalloc(sizeof(zval), argc, 0);
    4802           7 :                         argc = 0;
    4803          35 :                         ZEND_HASH_FOREACH_VAL(args, val) {
    4804          14 :                                 ZVAL_COPY(&params[argc], val);
    4805          14 :                                 argc++;
    4806             :                         } ZEND_HASH_FOREACH_END();
    4807             :                 }
    4808             : 
    4809          13 :                 fci.size = sizeof(fci);
    4810          13 :                 ZVAL_UNDEF(&fci.function_name);
    4811          13 :                 fci.object = Z_OBJ_P(return_value);
    4812          13 :                 fci.retval = &retval;
    4813          13 :                 fci.param_count = argc;
    4814          13 :                 fci.params = params;
    4815          13 :                 fci.no_separation = 1;
    4816             : 
    4817          13 :                 fcc.function_handler = constructor;
    4818          13 :                 fcc.called_scope = Z_OBJCE_P(return_value);
    4819          13 :                 fcc.object = Z_OBJ_P(return_value);
    4820             : 
    4821          13 :                 ret = zend_call_function(&fci, &fcc);
    4822          13 :                 zval_ptr_dtor(&retval);
    4823          13 :                 if (params) {
    4824          21 :                         for (i = 0; i < argc; i++) {
    4825          14 :                                 zval_ptr_dtor(&params[i]);
    4826             :                         }
    4827           7 :                         efree(params);
    4828             :                 }
    4829             : 
    4830          13 :                 if (EG(exception)) {
    4831           3 :                         zend_object_store_ctor_failed(Z_OBJ_P(return_value));
    4832             :                 }
    4833          13 :                 if (ret == FAILURE) {
    4834           0 :                         zval_ptr_dtor(&retval);
    4835           0 :                         php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
    4836           0 :                         zval_ptr_dtor(return_value);
    4837           0 :                         RETURN_NULL();
    4838             :                 }
    4839           4 :         } else if (argc) {
    4840           2 :                 zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
    4841             :         }
    4842             : }
    4843             : /* }}} */
    4844             : 
    4845             : /* {{{ proto public ReflectionClass[] ReflectionClass::getInterfaces()
    4846             :    Returns an array of interfaces this class implements */
    4847          25 : ZEND_METHOD(reflection_class, getInterfaces)
    4848             : {
    4849             :         reflection_object *intern;
    4850             :         zend_class_entry *ce;
    4851             : 
    4852          25 :         if (zend_parse_parameters_none() == FAILURE) {
    4853           4 :                 return;
    4854             :         }
    4855          42 :         GET_REFLECTION_OBJECT_PTR(ce);
    4856             : 
    4857          21 :         if (ce->num_interfaces) {
    4858             :                 uint32_t i;
    4859             : 
    4860          13 :                 array_init(return_value);
    4861          58 :                 for (i=0; i < ce->num_interfaces; i++) {
    4862             :                         zval interface;
    4863          45 :                         zend_reflection_class_factory(ce->interfaces[i], &interface);
    4864          45 :                         zend_hash_update(Z_ARRVAL_P(return_value), ce->interfaces[i]->name, &interface);
    4865             :                 }
    4866             :         } else {
    4867           8 :                 ZVAL_EMPTY_ARRAY(return_value);
    4868             :         }
    4869             : }
    4870             : /* }}} */
    4871             : 
    4872             : /* {{{ proto public String[] ReflectionClass::getInterfaceNames()
    4873             :    Returns an array of names of interfaces this class implements */
    4874           1 : ZEND_METHOD(reflection_class, getInterfaceNames)
    4875             : {
    4876             :         reflection_object *intern;
    4877             :         zend_class_entry *ce;
    4878             :         uint32_t i;
    4879             : 
    4880           1 :         if (zend_parse_parameters_none() == FAILURE) {
    4881           0 :                 return;
    4882             :         }
    4883           2 :         GET_REFLECTION_OBJECT_PTR(ce);
    4884             : 
    4885           1 :         if (!ce->num_interfaces) {
    4886             :                 /* Return an empty array if this class implements no interfaces */
    4887           0 :                 ZVAL_EMPTY_ARRAY(return_value);
    4888           0 :                 return;
    4889             :         }
    4890             : 
    4891           1 :         array_init(return_value);
    4892             : 
    4893           3 :         for (i=0; i < ce->num_interfaces; i++) {
    4894           4 :                 add_next_index_str(return_value, zend_string_copy(ce->interfaces[i]->name));
    4895             :         }
    4896             : }
    4897             : /* }}} */
    4898             : 
    4899             : /* {{{ proto public ReflectionClass[] ReflectionClass::getTraits()
    4900             :    Returns an array of traits used by this class */
    4901           4 : ZEND_METHOD(reflection_class, getTraits)
    4902             : {
    4903             :         reflection_object *intern;
    4904             :         zend_class_entry *ce;
    4905             :         uint32_t i;
    4906             : 
    4907           4 :         if (zend_parse_parameters_none() == FAILURE) {
    4908           0 :                 return;
    4909             :         }
    4910           8 :         GET_REFLECTION_OBJECT_PTR(ce);
    4911             : 
    4912           4 :         if (!ce->num_traits) {
    4913           1 :                 ZVAL_EMPTY_ARRAY(return_value);
    4914           1 :                 return;
    4915             :         }
    4916             : 
    4917           3 :         array_init(return_value);
    4918             : 
    4919           8 :         for (i=0; i < ce->num_traits; i++) {
    4920             :                 zval trait;
    4921           5 :                 zend_reflection_class_factory(ce->traits[i], &trait);
    4922           5 :                 zend_hash_update(Z_ARRVAL_P(return_value), ce->traits[i]->name, &trait);
    4923             :         }
    4924             : }
    4925             : /* }}} */
    4926             : 
    4927             : /* {{{ proto public String[] ReflectionClass::getTraitNames()
    4928             :    Returns an array of names of traits used by this class */
    4929           3 : ZEND_METHOD(reflection_class, getTraitNames)
    4930             : {
    4931             :         reflection_object *intern;
    4932             :         zend_class_entry *ce;
    4933             :         uint32_t i;
    4934             : 
    4935           3 :         if (zend_parse_parameters_none() == FAILURE) {
    4936           0 :                 return;
    4937             :         }
    4938           6 :         GET_REFLECTION_OBJECT_PTR(ce);
    4939             : 
    4940           3 :         if (!ce->num_traits) {
    4941           1 :                 ZVAL_EMPTY_ARRAY(return_value);
    4942           1 :                 return;
    4943             :         }
    4944             : 
    4945           2 :         array_init(return_value);
    4946             : 
    4947           5 :         for (i=0; i < ce->num_traits; i++) {
    4948           6 :                 add_next_index_str(return_value, zend_string_copy(ce->traits[i]->name));
    4949             :         }
    4950             : }
    4951             : /* }}} */
    4952             : 
    4953             : /* {{{ proto public array ReflectionClass::getTraitAliases()
    4954             :    Returns an array of trait aliases */
    4955           6 : ZEND_METHOD(reflection_class, getTraitAliases)
    4956             : {
    4957             :         reflection_object *intern;
    4958             :         zend_class_entry *ce;
    4959             : 
    4960           6 :         if (zend_parse_parameters_none() == FAILURE) {
    4961           0 :                 return;
    4962             :         }
    4963          12 :         GET_REFLECTION_OBJECT_PTR(ce);
    4964             : 
    4965             : 
    4966           6 :         if (ce->trait_aliases) {
    4967           4 :                 uint32_t i = 0;
    4968             : 
    4969           4 :                 array_init(return_value);
    4970          14 :                 while (ce->trait_aliases[i]) {
    4971             :                         zend_string *mname;
    4972           6 :                         zend_trait_method_reference *cur_ref = &ce->trait_aliases[i]->trait_method;
    4973             : 
    4974           6 :                         if (ce->trait_aliases[i]->alias) {
    4975             : 
    4976          10 :                                 mname = zend_string_alloc(ZSTR_LEN(cur_ref->class_name) + ZSTR_LEN(cur_ref->method_name) + 2, 0);
    4977           5 :                                 snprintf(ZSTR_VAL(mname), ZSTR_LEN(mname) + 1, "%s::%s", ZSTR_VAL(cur_ref->class_name), ZSTR_VAL(cur_ref->method_name));
    4978           5 :                                 add_assoc_str_ex(return_value, ZSTR_VAL(ce->trait_aliases[i]->alias), ZSTR_LEN(ce->trait_aliases[i]->alias), mname);
    4979             :                         }
    4980           6 :                         i++;
    4981             :                 }
    4982             :         } else {
    4983           2 :                 ZVAL_EMPTY_ARRAY(return_value);
    4984             :         }
    4985             : }
    4986             : /* }}} */
    4987             : 
    4988             : /* {{{ proto public ReflectionClass ReflectionClass::getParentClass()
    4989             :    Returns the class' parent class, or, if none exists, FALSE */
    4990          10 : ZEND_METHOD(reflection_class, getParentClass)
    4991             : {
    4992             :         reflection_object *intern;
    4993             :         zend_class_entry *ce;
    4994             : 
    4995          10 :         if (zend_parse_parameters_none() == FAILURE) {
    4996           3 :                 return;
    4997             :         }
    4998          14 :         GET_REFLECTION_OBJECT_PTR(ce);
    4999             : 
    5000           7 :         if (ce->parent) {
    5001           2 :                 zend_reflection_class_factory(ce->parent, return_value);
    5002             :         } else {
    5003           5 :                 RETURN_FALSE;
    5004             :         }
    5005             : }
    5006             : /* }}} */
    5007             : 
    5008             : /* {{{ proto public bool ReflectionClass::isSubclassOf(string|ReflectionClass class)
    5009             :    Returns whether this class is a subclass of another class */
    5010         123 : ZEND_METHOD(reflection_class, isSubclassOf)
    5011             : {
    5012             :         reflection_object *intern, *argument;
    5013             :         zend_class_entry *ce, *class_ce;
    5014             :         zval *class_name;
    5015             : 
    5016         246 :         GET_REFLECTION_OBJECT_PTR(ce);
    5017             : 
    5018         123 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &class_name) == FAILURE) {
    5019           8 :                 return;
    5020             :         }
    5021             : 
    5022         230 :         switch (Z_TYPE_P(class_name)) {
    5023          49 :                 case IS_STRING:
    5024          49 :                         if ((class_ce = zend_lookup_class(Z_STR_P(class_name))) == NULL) {
    5025           4 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5026           4 :                                                 "Class %s does not exist", Z_STRVAL_P(class_name));
    5027           4 :                                 return;
    5028             :                         }
    5029          45 :                         break;
    5030          62 :                 case IS_OBJECT:
    5031          62 :                         if (instanceof_function(Z_OBJCE_P(class_name), reflection_class_ptr)) {
    5032          62 :                                 argument = Z_REFLECTION_P(class_name);
    5033          62 :                                 if (argument->ptr == NULL) {
    5034           0 :                                         zend_throw_error(NULL, "Internal error: Failed to retrieve the argument's reflection object");
    5035           0 :                                         return;
    5036             :                                 }
    5037          62 :                                 class_ce = argument->ptr;
    5038          62 :                                 break;
    5039             :                         }
    5040             :                         /* no break */
    5041             :                 default:
    5042           4 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    5043             :                                         "Parameter one must either be a string or a ReflectionClass object");
    5044           4 :                         return;
    5045             :         }
    5046             : 
    5047         107 :         RETURN_BOOL((ce != class_ce && instanceof_function(ce, class_ce)));
    5048             : }
    5049             : /* }}} */
    5050             : 
    5051             : /* {{{ proto public bool ReflectionClass::implementsInterface(string|ReflectionClass interface_name)
    5052             :    Returns whether this class is a subclass of another class */
    5053          57 : ZEND_METHOD(reflection_class, implementsInterface)
    5054             : {
    5055             :         reflection_object *intern, *argument;
    5056             :         zend_class_entry *ce, *interface_ce;
    5057             :         zval *interface;
    5058             : 
    5059         114 :         GET_REFLECTION_OBJECT_PTR(ce);
    5060             : 
    5061          57 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &interface) == FAILURE) {
    5062           2 :                 return;
    5063             :         }
    5064             : 
    5065         110 :         switch (Z_TYPE_P(interface)) {
    5066          28 :                 case IS_STRING:
    5067          28 :                         if ((interface_ce = zend_lookup_class(Z_STR_P(interface))) == NULL) {
    5068           2 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5069           2 :                                                 "Interface %s does not exist", Z_STRVAL_P(interface));
    5070           2 :                                 return;
    5071             :                         }
    5072          26 :                         break;
    5073          25 :                 case IS_OBJECT:
    5074          25 :                         if (instanceof_function(Z_OBJCE_P(interface), reflection_class_ptr)) {
    5075          25 :                                 argument = Z_REFLECTION_P(interface);
    5076          25 :                                 if (argument->ptr == NULL) {
    5077           0 :                                         zend_throw_error(NULL, "Internal error: Failed to retrieve the argument's reflection object");
    5078           0 :                                         return;
    5079             :                                 }
    5080          25 :                                 interface_ce = argument->ptr;
    5081          25 :                                 break;
    5082             :                         }
    5083             :                         /* no break */
    5084             :                 default:
    5085           2 :                         zend_throw_exception_ex(reflection_exception_ptr, 0,
    5086             :                                         "Parameter one must either be a string or a ReflectionClass object");
    5087           2 :                         return;
    5088             :         }
    5089             : 
    5090          51 :         if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
    5091          31 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5092          31 :                                 "%s is not an interface", ZSTR_VAL(interface_ce->name));
    5093          31 :                 return;
    5094             :         }
    5095          20 :         RETURN_BOOL(instanceof_function(ce, interface_ce));
    5096             : }
    5097             : /* }}} */
    5098             : 
    5099             : /* {{{ proto public bool ReflectionClass::isIterable()
    5100             :    Returns whether this class is iterable (can be used inside foreach) */
    5101          27 : ZEND_METHOD(reflection_class, isIterable)
    5102             : {
    5103             :         reflection_object *intern;
    5104             :         zend_class_entry *ce;
    5105             : 
    5106          27 :         if (zend_parse_parameters_none() == FAILURE) {
    5107           7 :                 return;
    5108             :         }
    5109             : 
    5110          40 :         GET_REFLECTION_OBJECT_PTR(ce);
    5111             : 
    5112          20 :         if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS |
    5113             :                             ZEND_ACC_TRAIT     | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
    5114           5 :                 RETURN_FALSE;
    5115             :         }
    5116             : 
    5117          15 :         RETURN_BOOL(ce->get_iterator || instanceof_function(ce, zend_ce_traversable));
    5118             : }
    5119             : /* }}} */
    5120             : 
    5121             : /* {{{ proto public ReflectionExtension|NULL ReflectionClass::getExtension()
    5122             :    Returns NULL or the extension the class belongs to */
    5123           2 : ZEND_METHOD(reflection_class, getExtension)
    5124             : {
    5125             :         reflection_object *intern;
    5126             :         zend_class_entry *ce;
    5127             : 
    5128           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5129           0 :                 return;
    5130             :         }
    5131             : 
    5132           4 :         GET_REFLECTION_OBJECT_PTR(ce);
    5133             : 
    5134           2 :         if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
    5135           1 :                 reflection_extension_factory(return_value, ce->info.internal.module->name);
    5136             :         }
    5137             : }
    5138             : /* }}} */
    5139             : 
    5140             : /* {{{ proto public string|false ReflectionClass::getExtensionName()
    5141             :    Returns false or the name of the extension the class belongs to */
    5142           6 : ZEND_METHOD(reflection_class, getExtensionName)
    5143             : {
    5144             :         reflection_object *intern;
    5145             :         zend_class_entry *ce;
    5146             : 
    5147           6 :         if (zend_parse_parameters_none() == FAILURE) {
    5148           0 :                 return;
    5149             :         }
    5150             : 
    5151          12 :         GET_REFLECTION_OBJECT_PTR(ce);
    5152             : 
    5153           6 :         if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
    5154          10 :                 RETURN_STRING(ce->info.internal.module->name);
    5155             :         } else {
    5156           1 :                 RETURN_FALSE;
    5157             :         }
    5158             : }
    5159             : /* }}} */
    5160             : 
    5161             : /* {{{ proto public bool ReflectionClass::inNamespace()
    5162             :    Returns whether this class is defined in namespace */
    5163           2 : ZEND_METHOD(reflection_class, inNamespace)
    5164             : {
    5165             :         zval *name;
    5166             :         const char *backslash;
    5167             : 
    5168           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5169           0 :                 return;
    5170             :         }
    5171           4 :         if ((name = _default_load_name(getThis())) == NULL) {
    5172           0 :                 RETURN_FALSE;
    5173             :         }
    5174           2 :         if (Z_TYPE_P(name) == IS_STRING
    5175           4 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    5176           1 :                 && backslash > Z_STRVAL_P(name))
    5177             :         {
    5178           1 :                 RETURN_TRUE;
    5179             :         }
    5180           1 :         RETURN_FALSE;
    5181             : }
    5182             : /* }}} */
    5183             : 
    5184             : /* {{{ proto public string ReflectionClass::getNamespaceName()
    5185             :    Returns the name of namespace where this class is defined */
    5186           2 : ZEND_METHOD(reflection_class, getNamespaceName)
    5187             : {
    5188             :         zval *name;
    5189             :         const char *backslash;
    5190             : 
    5191           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5192           0 :                 return;
    5193             :         }
    5194           4 :         if ((name = _default_load_name(getThis())) == NULL) {
    5195           0 :                 RETURN_FALSE;
    5196             :         }
    5197           2 :         if (Z_TYPE_P(name) == IS_STRING
    5198           4 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    5199           1 :                 && backslash > Z_STRVAL_P(name))
    5200             :         {
    5201           2 :                 RETURN_STRINGL(Z_STRVAL_P(name), backslash - Z_STRVAL_P(name));
    5202             :         }
    5203           1 :         RETURN_EMPTY_STRING();
    5204             : }
    5205             : /* }}} */
    5206             : 
    5207             : /* {{{ proto public string ReflectionClass::getShortName()
    5208             :    Returns the short name of the class (without namespace part) */
    5209           2 : ZEND_METHOD(reflection_class, getShortName)
    5210             : {
    5211             :         zval *name;
    5212             :         const char *backslash;
    5213             : 
    5214           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5215           0 :                 return;
    5216             :         }
    5217           4 :         if ((name = _default_load_name(getThis())) == NULL) {
    5218           0 :                 RETURN_FALSE;
    5219             :         }
    5220           2 :         if (Z_TYPE_P(name) == IS_STRING
    5221           4 :                 && (backslash = zend_memrchr(Z_STRVAL_P(name), '\\', Z_STRLEN_P(name)))
    5222           1 :                 && backslash > Z_STRVAL_P(name))
    5223             :         {
    5224           2 :                 RETURN_STRINGL(backslash + 1, Z_STRLEN_P(name) - (backslash - Z_STRVAL_P(name) + 1));
    5225             :         }
    5226           2 :         ZVAL_COPY_DEREF(return_value, name);
    5227             : }
    5228             : /* }}} */
    5229             : 
    5230             : /* {{{ proto public static mixed ReflectionObject::export(mixed argument [, bool return]) throws ReflectionException
    5231             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    5232           4 : ZEND_METHOD(reflection_object, export)
    5233             : {
    5234           4 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_object_ptr, 1);
    5235           4 : }
    5236             : /* }}} */
    5237             : 
    5238             : /* {{{ proto public void ReflectionObject::__construct(mixed argument) throws ReflectionException
    5239             :    Constructor. Takes an instance as an argument */
    5240         109 : ZEND_METHOD(reflection_object, __construct)
    5241             : {
    5242         109 :         reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    5243         109 : }
    5244             : /* }}} */
    5245             : 
    5246             : /* {{{ proto public static mixed ReflectionProperty::export(mixed class, string name [, bool return]) throws ReflectionException
    5247             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    5248          14 : ZEND_METHOD(reflection_property, export)
    5249             : {
    5250          14 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_property_ptr, 2);
    5251          14 : }
    5252             : /* }}} */
    5253             : 
    5254             : /* {{{ proto public static mixed ReflectionClassConstant::export(mixed class, string name [, bool return]) throws ReflectionException
    5255             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    5256           8 : ZEND_METHOD(reflection_class_constant, export)
    5257             : {
    5258           8 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_class_constant_ptr, 2);
    5259           8 : }
    5260             : /* }}} */
    5261             : 
    5262             : /* {{{ proto public void ReflectionProperty::__construct(mixed class, string name)
    5263             :    Constructor. Throws an Exception in case the given property does not exist */
    5264          99 : ZEND_METHOD(reflection_property, __construct)
    5265             : {
    5266             :         zval propname, cname, *classname;
    5267             :         zend_string *name;
    5268          99 :         int dynam_prop = 0;
    5269             :         zval *object;
    5270             :         reflection_object *intern;
    5271             :         zend_class_entry *ce;
    5272          99 :         zend_property_info *property_info = NULL;
    5273             :         property_reference *reference;
    5274             : 
    5275          99 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "zS", &classname, &name) == FAILURE) {
    5276          19 :                 return;
    5277             :         }
    5278             : 
    5279         192 :         object = getThis();
    5280          96 :         intern = Z_REFLECTION_P(object);
    5281             : 
    5282             :         /* Find the class entry */
    5283         192 :         switch (Z_TYPE_P(classname)) {
    5284          81 :                 case IS_STRING:
    5285          81 :                         if ((ce = zend_lookup_class(Z_STR_P(classname))) == NULL) {
    5286           3 :                                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5287           3 :                                                 "Class %s does not exist", Z_STRVAL_P(classname));
    5288           3 :                                 return;
    5289             :                         }
    5290          78 :                         break;
    5291             : 
    5292          13 :                 case IS_OBJECT:
    5293          13 :                         ce = Z_OBJCE_P(classname);
    5294          13 :                         break;
    5295             : 
    5296           2 :                 default:
    5297           2 :                         _DO_THROW("The parameter class is expected to be either a string or an object");
    5298             :                         /* returns out of this function */
    5299             :         }
    5300             : 
    5301         182 :         if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) == NULL || (property_info->flags & ZEND_ACC_SHADOW)) {
    5302             :                 /* Check for dynamic properties */
    5303          18 :                 if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
    5304           4 :                         if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name)) {
    5305           3 :                                 dynam_prop = 1;
    5306             :                         }
    5307             :                 }
    5308          11 :                 if (dynam_prop == 0) {
    5309           8 :                         zend_throw_exception_ex(reflection_exception_ptr, 0, "Property %s::$%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    5310           8 :                         return;
    5311             :                 }
    5312             :         }
    5313             : 
    5314          83 :         if (dynam_prop == 0 && (property_info->flags & ZEND_ACC_PRIVATE) == 0) {
    5315             :                 /* we have to search the class hierarchy for this (implicit) public or protected property */
    5316          64 :                 zend_class_entry *tmp_ce = ce;
    5317             :                 zend_property_info *tmp_info;
    5318             : 
    5319         192 :                 while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, name)) == NULL) {
    5320           0 :                         ce = tmp_ce;
    5321           0 :                         property_info = tmp_info;
    5322           0 :                         tmp_ce = tmp_ce->parent;
    5323             :                 }
    5324             :         }
    5325             : 
    5326          83 :         if (dynam_prop == 0) {
    5327         160 :                 ZVAL_STR_COPY(&cname, property_info->ce->name);
    5328             :         } else {
    5329           6 :                 ZVAL_STR_COPY(&cname, ce->name);
    5330             :         }
    5331         249 :         reflection_update_property_class(object, &cname);
    5332             : 
    5333         178 :         ZVAL_STR_COPY(&propname, name);
    5334         249 :         reflection_update_property_name(object, &propname);
    5335             : 
    5336          83 :         reference = (property_reference*) emalloc(sizeof(property_reference));
    5337          83 :         if (dynam_prop) {
    5338           3 :                 reference->prop.flags = ZEND_ACC_IMPLICIT_PUBLIC;
    5339           3 :                 reference->prop.name = name;
    5340           3 :                 reference->prop.doc_comment = NULL;
    5341           3 :                 reference->prop.ce = ce;
    5342             :         } else {
    5343          80 :                 reference->prop = *property_info;
    5344             :         }
    5345          83 :         reference->ce = ce;
    5346         166 :         reference->unmangled_name = zend_string_copy(name);
    5347          83 :         intern->ptr = reference;
    5348          83 :         intern->ref_type = REF_TYPE_PROPERTY;
    5349          83 :         intern->ce = ce;
    5350          83 :         intern->ignore_visibility = 0;
    5351             : }
    5352             : /* }}} */
    5353             : 
    5354             : /* {{{ proto public string ReflectionProperty::__toString()
    5355             :    Returns a string representation */
    5356          13 : ZEND_METHOD(reflection_property, __toString)
    5357             : {
    5358             :         reflection_object *intern;
    5359             :         property_reference *ref;
    5360          13 :         smart_str str = {0};
    5361             : 
    5362          13 :         if (zend_parse_parameters_none() == FAILURE) {
    5363           0 :                 return;
    5364             :         }
    5365          26 :         GET_REFLECTION_OBJECT_PTR(ref);
    5366          13 :         _property_string(&str, &ref->prop, ZSTR_VAL(ref->unmangled_name), "");
    5367          39 :         RETURN_STR(smart_str_extract(&str));
    5368             : }
    5369             : /* }}} */
    5370             : 
    5371             : /* {{{ proto public string ReflectionProperty::getName()
    5372             :    Returns the class' name */
    5373          92 : ZEND_METHOD(reflection_property, getName)
    5374             : {
    5375          92 :         if (zend_parse_parameters_none() == FAILURE) {
    5376           1 :                 return;
    5377             :         }
    5378         182 :         _default_get_name(getThis(), return_value);
    5379             : }
    5380             : /* }}} */
    5381             : 
    5382         232 : static void _property_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask) /* {{{ */
    5383             : {
    5384             :         reflection_object *intern;
    5385             :         property_reference *ref;
    5386             : 
    5387         232 :         if (zend_parse_parameters_none() == FAILURE) {
    5388           6 :                 return;
    5389             :         }
    5390         452 :         GET_REFLECTION_OBJECT_PTR(ref);
    5391         226 :         RETURN_BOOL(ref->prop.flags & mask);
    5392             : }
    5393             : /* }}} */
    5394             : 
    5395             : /* {{{ proto public bool ReflectionProperty::isPublic()
    5396             :    Returns whether this property is public */
    5397          49 : ZEND_METHOD(reflection_property, isPublic)
    5398             : {
    5399          49 :         _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC);
    5400          49 : }
    5401             : /* }}} */
    5402             : 
    5403             : /* {{{ proto public bool ReflectionProperty::isPrivate()
    5404             :    Returns whether this property is private */
    5405          43 : ZEND_METHOD(reflection_property, isPrivate)
    5406             : {
    5407          43 :         _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PRIVATE);
    5408          43 : }
    5409             : /* }}} */
    5410             : 
    5411             : /* {{{ proto public bool ReflectionProperty::isProtected()
    5412             :    Returns whether this property is protected */
    5413          44 : ZEND_METHOD(reflection_property, isProtected)
    5414             : {
    5415          44 :         _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROTECTED);
    5416          44 : }
    5417             : /* }}} */
    5418             : 
    5419             : /* {{{ proto public bool ReflectionProperty::isStatic()
    5420             :    Returns whether this property is static */
    5421          44 : ZEND_METHOD(reflection_property, isStatic)
    5422             : {
    5423          44 :         _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_STATIC);
    5424          44 : }
    5425             : /* }}} */
    5426             : 
    5427             : /* {{{ proto public bool ReflectionProperty::isDefault()
    5428             :    Returns whether this property is default (declared at compilation time). */
    5429          52 : ZEND_METHOD(reflection_property, isDefault)
    5430             : {
    5431          52 :         _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ~ZEND_ACC_IMPLICIT_PUBLIC);
    5432          52 : }
    5433             : /* }}} */
    5434             : 
    5435             : /* {{{ proto public int ReflectionProperty::getModifiers()
    5436             :    Returns a bitfield of the access modifiers for this property */
    5437          55 : ZEND_METHOD(reflection_property, getModifiers)
    5438             : {
    5439             :         reflection_object *intern;
    5440             :         property_reference *ref;
    5441          55 :         uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_IMPLICIT_PUBLIC | ZEND_ACC_STATIC;
    5442             : 
    5443          55 :         if (zend_parse_parameters_none() == FAILURE) {
    5444           1 :                 return;
    5445             :         }
    5446         108 :         GET_REFLECTION_OBJECT_PTR(ref);
    5447             : 
    5448          54 :         RETURN_LONG((ref->prop.flags & keep_flags));
    5449             : }
    5450             : /* }}} */
    5451             : 
    5452             : /* {{{ proto public mixed ReflectionProperty::getValue([stdclass object])
    5453             :    Returns this property's value */
    5454          83 : ZEND_METHOD(reflection_property, getValue)
    5455             : {
    5456             :         reflection_object *intern;
    5457             :         property_reference *ref;
    5458             :         zval *object, *name;
    5459          83 :         zval *member_p = NULL;
    5460             : 
    5461         199 :         GET_REFLECTION_OBJECT_PTR(ref);
    5462             : 
    5463          83 :         if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
    5464          58 :                 name = _default_load_name(getThis());
    5465          29 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5466          29 :                         "Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
    5467          29 :                 return;
    5468             :         }
    5469             : 
    5470          54 :         if (ref->prop.flags & ZEND_ACC_STATIC) {
    5471          21 :                 member_p = zend_read_static_property_ex(ref->ce, ref->unmangled_name, 0);
    5472          21 :                 if (member_p) {
    5473          42 :                         ZVAL_COPY_DEREF(return_value, member_p);
    5474             :                 }
    5475             :         } else {
    5476             :                 zval rv;
    5477             : 
    5478          33 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
    5479           7 :                         return;
    5480             :                 }
    5481             : 
    5482          30 :                 if (!instanceof_function(Z_OBJCE_P(object), ref->prop.ce)) {
    5483           1 :                         _DO_THROW("Given object is not an instance of the class this property was declared in");
    5484             :                         /* Returns from this function */
    5485             :                 }
    5486             : 
    5487          29 :                 member_p = zend_read_property_ex(ref->ce, object, ref->unmangled_name, 0, &rv);
    5488          29 :                 if (member_p != &rv) {
    5489          56 :                         ZVAL_COPY_DEREF(return_value, member_p);
    5490             :                 } else {
    5491           1 :                         if (Z_ISREF_P(member_p)) {
    5492             :                                 zend_unwrap_reference(member_p);
    5493             :                         }
    5494           1 :                         ZVAL_COPY_VALUE(return_value, member_p);
    5495             :                 }
    5496             :         }
    5497             : }
    5498             : /* }}} */
    5499             : 
    5500             : /* {{{ proto public void ReflectionProperty::setValue([stdclass object,] mixed value)
    5501             :    Sets this property's value */
    5502          28 : ZEND_METHOD(reflection_property, setValue)
    5503             : {
    5504             :         reflection_object *intern;
    5505             :         property_reference *ref;
    5506             :         zval *object, *name;
    5507             :         zval *value;
    5508             :         zval *tmp;
    5509             : 
    5510          63 :         GET_REFLECTION_OBJECT_PTR(ref);
    5511             : 
    5512          28 :         if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
    5513           2 :                 name = _default_load_name(getThis());
    5514           1 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5515           1 :                         "Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
    5516           1 :                 return;
    5517             :         }
    5518             : 
    5519          27 :         if (ref->prop.flags & ZEND_ACC_STATIC) {
    5520          13 :                 if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) {
    5521           7 :                         if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) {
    5522           2 :                                 return;
    5523             :                         }
    5524             :                 }
    5525             : 
    5526          11 :                 zend_update_static_property_ex(ref->ce, ref->unmangled_name, value);
    5527             :         } else {
    5528          14 :                 if (zend_parse_parameters(ZEND_NUM_ARGS(), "oz", &object, &value) == FAILURE) {
    5529           4 :                         return;
    5530             :                 }
    5531             : 
    5532          10 :                 zend_update_property_ex(ref->ce, object, ref->unmangled_name, value);
    5533             :         }
    5534             : }
    5535             : /* }}} */
    5536             : 
    5537             : /* {{{ proto public ReflectionClass ReflectionProperty::getDeclaringClass()
    5538             :    Get the declaring class */
    5539          26 : ZEND_METHOD(reflection_property, getDeclaringClass)
    5540             : {
    5541             :         reflection_object *intern;
    5542             :         property_reference *ref;
    5543             :         zend_class_entry *tmp_ce, *ce;
    5544             :         zend_property_info *tmp_info;
    5545             : 
    5546          26 :         if (zend_parse_parameters_none() == FAILURE) {
    5547           1 :                 return;
    5548             :         }
    5549          50 :         GET_REFLECTION_OBJECT_PTR(ref);
    5550             : 
    5551          25 :         ce = tmp_ce = ref->ce;
    5552          91 :         while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) {
    5553          33 :                 if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
    5554             :                         /* it's a private property, so it can't be inherited */
    5555             :                         break;
    5556             :                 }
    5557          26 :                 ce = tmp_ce;
    5558          26 :                 if (tmp_ce == tmp_info->ce) {
    5559             :                         /* declared in this class, done */
    5560          18 :                         break;
    5561             :                 }
    5562           8 :                 tmp_ce = tmp_ce->parent;
    5563             :         }
    5564             : 
    5565          25 :         zend_reflection_class_factory(ce, return_value);
    5566             : }
    5567             : /* }}} */
    5568             : 
    5569             : /* {{{ proto public string ReflectionProperty::getDocComment()
    5570             :    Returns the doc comment for this property */
    5571          28 : ZEND_METHOD(reflection_property, getDocComment)
    5572             : {
    5573             :         reflection_object *intern;
    5574             :         property_reference *ref;
    5575             : 
    5576          28 :         if (zend_parse_parameters_none() == FAILURE) {
    5577           4 :                 return;
    5578             :         }
    5579          48 :         GET_REFLECTION_OBJECT_PTR(ref);
    5580          24 :         if (ref->prop.doc_comment) {
    5581          42 :                 RETURN_STR_COPY(ref->prop.doc_comment);
    5582             :         }
    5583          10 :         RETURN_FALSE;
    5584             : }
    5585             : /* }}} */
    5586             : 
    5587             : /* {{{ proto public int ReflectionProperty::setAccessible(bool visible)
    5588             :    Sets whether non-public properties can be requested */
    5589          13 : ZEND_METHOD(reflection_property, setAccessible)
    5590             : {
    5591             :         reflection_object *intern;
    5592             :         zend_bool visible;
    5593             : 
    5594          13 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "b", &visible) == FAILURE) {
    5595           0 :                 return;
    5596             :         }
    5597             : 
    5598          26 :         intern = Z_REFLECTION_P(getThis());
    5599             : 
    5600          13 :         intern->ignore_visibility = visible;
    5601             : }
    5602             : /* }}} */
    5603             : 
    5604             : /* {{{ proto public static mixed ReflectionExtension::export(string name [, bool return]) throws ReflectionException
    5605             :    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    5606           2 : ZEND_METHOD(reflection_extension, export)
    5607             : {
    5608           2 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_extension_ptr, 1);
    5609           2 : }
    5610             : /* }}} */
    5611             : 
    5612             : /* {{{ proto public void ReflectionExtension::__construct(string name)
    5613             :    Constructor. Throws an Exception in case the given extension does not exist */
    5614          27 : ZEND_METHOD(reflection_extension, __construct)
    5615             : {
    5616             :         zval name;
    5617             :         zval *object;
    5618             :         char *lcname;
    5619             :         reflection_object *intern;
    5620             :         zend_module_entry *module;
    5621             :         char *name_str;
    5622             :         size_t name_len;
    5623             :         ALLOCA_FLAG(use_heap)
    5624             : 
    5625          27 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
    5626           8 :                 return;
    5627             :         }
    5628             : 
    5629          48 :         object = getThis();
    5630          24 :         intern = Z_REFLECTION_P(object);
    5631          24 :         lcname = do_alloca(name_len + 1, use_heap);
    5632          24 :         zend_str_tolower_copy(lcname, name_str, name_len);
    5633          48 :         if ((module = zend_hash_str_find_ptr(&module_registry, lcname, name_len)) == NULL) {
    5634           2 :                 free_alloca(lcname, use_heap);
    5635           2 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5636             :                         "Extension %s does not exist", name_str);
    5637           2 :                 return;
    5638             :         }
    5639          22 :         free_alloca(lcname, use_heap);
    5640          44 :         ZVAL_STRING(&name, module->name);
    5641          66 :         reflection_update_property_name(object, &name);
    5642          22 :         intern->ptr = module;
    5643          22 :         intern->ref_type = REF_TYPE_OTHER;
    5644          22 :         intern->ce = NULL;
    5645             : }
    5646             : /* }}} */
    5647             : 
    5648             : /* {{{ proto public string ReflectionExtension::__toString()
    5649             :    Returns a string representation */
    5650           3 : ZEND_METHOD(reflection_extension, __toString)
    5651             : {
    5652             :         reflection_object *intern;
    5653             :         zend_module_entry *module;
    5654           3 :         smart_str str = {0};
    5655             : 
    5656           3 :         if (zend_parse_parameters_none() == FAILURE) {
    5657           0 :                 return;
    5658             :         }
    5659           6 :         GET_REFLECTION_OBJECT_PTR(module);
    5660           3 :         _extension_string(&str, module, "");
    5661           9 :         RETURN_STR(smart_str_extract(&str));
    5662             : }
    5663             : /* }}} */
    5664             : 
    5665             : /* {{{ proto public string ReflectionExtension::getName()
    5666             :    Returns this extension's name */
    5667           1 : ZEND_METHOD(reflection_extension, getName)
    5668             : {
    5669           1 :         if (zend_parse_parameters_none() == FAILURE) {
    5670           0 :                 return;
    5671             :         }
    5672           2 :         _default_get_name(getThis(), return_value);
    5673             : }
    5674             : /* }}} */
    5675             : 
    5676             : /* {{{ proto public string ReflectionExtension::getVersion()
    5677             :    Returns this extension's version */
    5678           2 : ZEND_METHOD(reflection_extension, getVersion)
    5679             : {
    5680             :         reflection_object *intern;
    5681             :         zend_module_entry *module;
    5682             : 
    5683           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5684           0 :                 return;
    5685             :         }
    5686           4 :         GET_REFLECTION_OBJECT_PTR(module);
    5687             : 
    5688             :         /* An extension does not necessarily have a version number */
    5689           2 :         if (module->version == NO_VERSION_YET) {
    5690           0 :                 RETURN_NULL();
    5691             :         } else {
    5692           4 :                 RETURN_STRING(module->version);
    5693             :         }
    5694             : }
    5695             : /* }}} */
    5696             : 
    5697             : /* {{{ proto public ReflectionFunction[] ReflectionExtension::getFunctions()
    5698             :    Returns an array of this extension's functions */
    5699           2 : ZEND_METHOD(reflection_extension, getFunctions)
    5700             : {
    5701             :         reflection_object *intern;
    5702             :         zend_module_entry *module;
    5703             :         zval function;
    5704             :         zend_function *fptr;
    5705             : 
    5706           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5707           0 :                 return;
    5708             :         }
    5709           4 :         GET_REFLECTION_OBJECT_PTR(module);
    5710             : 
    5711           2 :         array_init(return_value);
    5712        9330 :         ZEND_HASH_FOREACH_PTR(CG(function_table), fptr) {
    5713        4664 :                 if (fptr->common.type==ZEND_INTERNAL_FUNCTION
    5714        4664 :                         && fptr->internal_function.module == module) {
    5715        1076 :                         reflection_function_factory(fptr, NULL, &function);
    5716        1076 :                         zend_hash_update(Z_ARRVAL_P(return_value), fptr->common.function_name, &function);
    5717             :                 }
    5718             :         } ZEND_HASH_FOREACH_END();
    5719             : }
    5720             : /* }}} */
    5721             : 
    5722        2729 : static int _addconstant(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
    5723             : {
    5724             :         zval const_val;
    5725        2729 :         zend_constant *constant = (zend_constant*)Z_PTR_P(el);
    5726        2729 :         zval *retval = va_arg(args, zval*);
    5727        2729 :         int number = va_arg(args, int);
    5728             : 
    5729        2729 :         if (number == ZEND_CONSTANT_MODULE_NUMBER(constant)) {
    5730         369 :                 ZVAL_COPY_OR_DUP(&const_val, &constant->value);
    5731         369 :                 zend_hash_update(Z_ARRVAL_P(retval), constant->name, &const_val);
    5732             :         }
    5733        2729 :         return 0;
    5734             : }
    5735             : /* }}} */
    5736             : 
    5737             : /* {{{ proto public array ReflectionExtension::getConstants()
    5738             :    Returns an associative array containing this extension's constants and their values */
    5739           1 : ZEND_METHOD(reflection_extension, getConstants)
    5740             : {
    5741             :         reflection_object *intern;
    5742             :         zend_module_entry *module;
    5743             : 
    5744           1 :         if (zend_parse_parameters_none() == FAILURE) {
    5745           0 :                 return;
    5746             :         }
    5747           2 :         GET_REFLECTION_OBJECT_PTR(module);
    5748             : 
    5749           1 :         array_init(return_value);
    5750           1 :         zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _addconstant, 2, return_value, module->module_number);
    5751             : }
    5752             : /* }}} */
    5753             : 
    5754             : /* {{{ _addinientry */
    5755         281 : static int _addinientry(zval *el, int num_args, va_list args, zend_hash_key *hash_key)
    5756             : {
    5757         281 :         zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el);
    5758         281 :         zval *retval = va_arg(args, zval*);
    5759         281 :         int number = va_arg(args, int);
    5760             : 
    5761         281 :         if (number == ini_entry->module_number) {
    5762          14 :                 if (ini_entry->value) {
    5763             :                         zval zv;
    5764             : 
    5765          24 :                         ZVAL_STR_COPY(&zv, ini_entry->value);
    5766          12 :                         zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &zv);
    5767             :                 } else {
    5768           2 :                         zend_symtable_update(Z_ARRVAL_P(retval), ini_entry->name, &EG(uninitialized_zval));
    5769             :                 }
    5770             :         }
    5771         281 :         return ZEND_HASH_APPLY_KEEP;
    5772             : }
    5773             : /* }}} */
    5774             : 
    5775             : /* {{{ proto public array ReflectionExtension::getINIEntries()
    5776             :    Returns an associative array containing this extension's INI entries and their values */
    5777           1 : ZEND_METHOD(reflection_extension, getINIEntries)
    5778             : {
    5779             :         reflection_object *intern;
    5780             :         zend_module_entry *module;
    5781             : 
    5782           1 :         if (zend_parse_parameters_none() == FAILURE) {
    5783           0 :                 return;
    5784             :         }
    5785           2 :         GET_REFLECTION_OBJECT_PTR(module);
    5786             : 
    5787           1 :         array_init(return_value);
    5788           1 :         zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _addinientry, 2, return_value, module->module_number);
    5789             : }
    5790             : /* }}} */
    5791             : 
    5792             : /* {{{ add_extension_class */
    5793         792 : static int add_extension_class(zval *zv, int num_args, va_list args, zend_hash_key *hash_key)
    5794             : {
    5795         792 :         zend_class_entry *ce = Z_PTR_P(zv);
    5796         792 :         zval *class_array = va_arg(args, zval*), zclass;
    5797         792 :         struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
    5798         792 :         int add_reflection_class = va_arg(args, int);
    5799             : 
    5800         792 :         if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) {
    5801             :                 zend_string *name;
    5802             : 
    5803          36 :                 if (zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) {
    5804             :                         /* This is an class alias, use alias name */
    5805           0 :                         name = hash_key->key;
    5806             :                 } else {
    5807             :                         /* Use class name */
    5808          36 :                         name = ce->name;
    5809             :                 }
    5810          36 :                 if (add_reflection_class) {
    5811          32 :                         zend_reflection_class_factory(ce, &zclass);
    5812          32 :                         zend_hash_update(Z_ARRVAL_P(class_array), name, &zclass);
    5813             :                 } else {
    5814           4 :                         add_next_index_str(class_array, zend_string_copy(name));
    5815             :                 }
    5816             :         }
    5817         792 :         return ZEND_HASH_APPLY_KEEP;
    5818             : }
    5819             : /* }}} */
    5820             : 
    5821             : /* {{{ proto public ReflectionClass[] ReflectionExtension::getClasses()
    5822             :    Returns an array containing ReflectionClass objects for all classes of this extension */
    5823           2 : ZEND_METHOD(reflection_extension, getClasses)
    5824             : {
    5825             :         reflection_object *intern;
    5826             :         zend_module_entry *module;
    5827             : 
    5828           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5829           0 :                 return;
    5830             :         }
    5831           4 :         GET_REFLECTION_OBJECT_PTR(module);
    5832             : 
    5833           2 :         array_init(return_value);
    5834           2 :         zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 1);
    5835             : }
    5836             : /* }}} */
    5837             : 
    5838             : /* {{{ proto public array ReflectionExtension::getClassNames()
    5839             :    Returns an array containing all names of all classes of this extension */
    5840           2 : ZEND_METHOD(reflection_extension, getClassNames)
    5841             : {
    5842             :         reflection_object *intern;
    5843             :         zend_module_entry *module;
    5844             : 
    5845           2 :         if (zend_parse_parameters_none() == FAILURE) {
    5846           0 :                 return;
    5847             :         }
    5848           4 :         GET_REFLECTION_OBJECT_PTR(module);
    5849             : 
    5850           2 :         array_init(return_value);
    5851           2 :         zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) add_extension_class, 3, return_value, module, 0);
    5852             : }
    5853             : /* }}} */
    5854             : 
    5855             : /* {{{ proto public array ReflectionExtension::getDependencies()
    5856             :    Returns an array containing all names of all extensions this extension depends on */
    5857           3 : ZEND_METHOD(reflection_extension, getDependencies)
    5858             : {
    5859             :         reflection_object *intern;
    5860             :         zend_module_entry *module;
    5861             :         const zend_module_dep *dep;
    5862             : 
    5863           3 :         if (zend_parse_parameters_none() == FAILURE) {
    5864           0 :                 return;
    5865             :         }
    5866           6 :         GET_REFLECTION_OBJECT_PTR(module);
    5867             : 
    5868           3 :         dep = module->deps;
    5869             : 
    5870           3 :         if (!dep)
    5871             :         {
    5872           0 :                 ZVAL_EMPTY_ARRAY(return_value);
    5873           0 :                 return;
    5874             :         }
    5875             : 
    5876           3 :         array_init(return_value);
    5877          10 :         while(dep->name) {
    5878             :                 zend_string *relation;
    5879             :                 char *rel_type;
    5880           4 :                 size_t len = 0;
    5881             : 
    5882           4 :                 switch(dep->type) {
    5883           2 :                         case MODULE_DEP_REQUIRED:
    5884           2 :                                 rel_type = "Required";
    5885           2 :                                 len += sizeof("Required") - 1;
    5886           2 :                                 break;
    5887           1 :                         case MODULE_DEP_CONFLICTS:
    5888           1 :                                 rel_type = "Conflicts";
    5889           1 :                                 len += sizeof("Conflicts") - 1;
    5890           1 :                                 break;
    5891           1 :                         case MODULE_DEP_OPTIONAL:
    5892           1 :                                 rel_type = "Optional";
    5893           1 :                                 len += sizeof("Optional") - 1;
    5894           1 :                                 break;
    5895           0 :                         default:
    5896           0 :                                 rel_type = "Error"; /* shouldn't happen */
    5897           0 :                                 len += sizeof("Error") - 1;
    5898           0 :                                 break;
    5899             :                 }
    5900             : 
    5901           4 :                 if (dep->rel) {
    5902           0 :                         len += strlen(dep->rel) + 1;
    5903             :                 }
    5904             : 
    5905           4 :                 if (dep->version) {
    5906           0 :                         len += strlen(dep->version) + 1;
    5907             :                 }
    5908             : 
    5909           4 :                 relation = zend_string_alloc(len, 0);
    5910          16 :                 snprintf(ZSTR_VAL(relation), ZSTR_LEN(relation) + 1, "%s%s%s%s%s",
    5911             :                                                 rel_type,
    5912           4 :                                                 dep->rel ? " " : "",
    5913           4 :                                                 dep->rel ? dep->rel : "",
    5914           4 :                                                 dep->version ? " " : "",
    5915           4 :                                                 dep->version ? dep->version : "");
    5916           4 :                 add_assoc_str(return_value, dep->name, relation);
    5917           4 :                 dep++;
    5918             :         }
    5919             : }
    5920             : /* }}} */
    5921             : 
    5922             : /* {{{ proto public void ReflectionExtension::info()
    5923             :        Prints phpinfo block for the extension */
    5924           3 : ZEND_METHOD(reflection_extension, info)
    5925             : {
    5926             :         reflection_object *intern;
    5927             :         zend_module_entry *module;
    5928             : 
    5929           3 :         if (zend_parse_parameters_none() == FAILURE) {
    5930           0 :                 return;
    5931             :         }
    5932           6 :         GET_REFLECTION_OBJECT_PTR(module);
    5933             : 
    5934           3 :         php_info_print_module(module);
    5935             : }
    5936             : /* }}} */
    5937             : 
    5938             : /* {{{ proto public bool ReflectionExtension::isPersistent()
    5939             :        Returns whether this extension is persistent */
    5940           1 : ZEND_METHOD(reflection_extension, isPersistent)
    5941             : {
    5942             :         reflection_object *intern;
    5943             :     zend_module_entry *module;
    5944             : 
    5945           1 :     if (zend_parse_parameters_none() == FAILURE) {
    5946           0 :                 return;
    5947             :         }
    5948           2 :         GET_REFLECTION_OBJECT_PTR(module);
    5949             : 
    5950           1 :         RETURN_BOOL(module->type == MODULE_PERSISTENT);
    5951             : }
    5952             : /* }}} */
    5953             : 
    5954             : /* {{{ proto public bool ReflectionExtension::isTemporary()
    5955             :        Returns whether this extension is temporary */
    5956           1 : ZEND_METHOD(reflection_extension, isTemporary)
    5957             : {
    5958             :         reflection_object *intern;
    5959             :         zend_module_entry *module;
    5960             : 
    5961           1 :         if (zend_parse_parameters_none() == FAILURE) {
    5962           0 :                 return;
    5963             :         }
    5964           2 :         GET_REFLECTION_OBJECT_PTR(module);
    5965             : 
    5966           1 :         RETURN_BOOL(module->type == MODULE_TEMPORARY);
    5967             : }
    5968             : /* }}} */
    5969             : 
    5970             : /* {{{ proto public static mixed ReflectionZendExtension::export(string name [, bool return]) throws ReflectionException
    5971             :  *    Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
    5972           1 : ZEND_METHOD(reflection_zend_extension, export)
    5973             : {
    5974           1 :         _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_zend_extension_ptr, 1);
    5975           1 : }
    5976             : /* }}} */
    5977             : 
    5978             : /* {{{ proto public void ReflectionZendExtension::__construct(string name)
    5979             :        Constructor. Throws an Exception in case the given Zend extension does not exist */
    5980           3 : ZEND_METHOD(reflection_zend_extension, __construct)
    5981             : {
    5982             :         zval name;
    5983             :         zval *object;
    5984             :         reflection_object *intern;
    5985             :         zend_extension *extension;
    5986             :         char *name_str;
    5987             :         size_t name_len;
    5988             : 
    5989           3 :         if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "s", &name_str, &name_len) == FAILURE) {
    5990           1 :                 return;
    5991             :         }
    5992             : 
    5993           6 :         object = getThis();
    5994           3 :         intern = Z_REFLECTION_P(object);
    5995             : 
    5996           3 :         extension = zend_get_extension(name_str);
    5997           3 :         if (!extension) {
    5998           1 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    5999             :                                 "Zend Extension %s does not exist", name_str);
    6000           1 :                 return;
    6001             :         }
    6002           4 :         ZVAL_STRING(&name, extension->name);
    6003           6 :         reflection_update_property_name(object, &name);
    6004           2 :         intern->ptr = extension;
    6005           2 :         intern->ref_type = REF_TYPE_OTHER;
    6006           2 :         intern->ce = NULL;
    6007             : }
    6008             : /* }}} */
    6009             : 
    6010             : /* {{{ proto public string ReflectionZendExtension::__toString()
    6011             :        Returns a string representation */
    6012           1 : ZEND_METHOD(reflection_zend_extension, __toString)
    6013             : {
    6014             :         reflection_object *intern;
    6015             :         zend_extension *extension;
    6016           1 :         smart_str str = {0};
    6017             : 
    6018           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6019           0 :                 return;
    6020             :         }
    6021           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6022           1 :         _zend_extension_string(&str, extension, "");
    6023           3 :         RETURN_STR(smart_str_extract(&str));
    6024             : }
    6025             : /* }}} */
    6026             : 
    6027             : /* {{{ proto public string ReflectionZendExtension::getName()
    6028             :        Returns the name of this Zend extension */
    6029           1 : ZEND_METHOD(reflection_zend_extension, getName)
    6030             : {
    6031             :         reflection_object *intern;
    6032             :         zend_extension *extension;
    6033             : 
    6034           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6035           0 :                 return;
    6036             :         }
    6037           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6038             : 
    6039           2 :         RETURN_STRING(extension->name);
    6040             : }
    6041             : /* }}} */
    6042             : 
    6043             : /* {{{ proto public string ReflectionZendExtension::getVersion()
    6044             :        Returns the version information of this Zend extension */
    6045           1 : ZEND_METHOD(reflection_zend_extension, getVersion)
    6046             : {
    6047             :         reflection_object *intern;
    6048             :         zend_extension *extension;
    6049             : 
    6050           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6051           0 :                 return;
    6052             :         }
    6053           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6054             : 
    6055           1 :         if (extension->version) {
    6056           2 :                 RETURN_STRING(extension->version);
    6057             :         } else {
    6058           0 :                 RETURN_EMPTY_STRING();
    6059             :         }
    6060             : }
    6061             : /* }}} */
    6062             : 
    6063             : /* {{{ proto public void ReflectionZendExtension::getAuthor()
    6064             :  * Returns the name of this Zend extension's author */
    6065           1 : ZEND_METHOD(reflection_zend_extension, getAuthor)
    6066             : {
    6067             :         reflection_object *intern;
    6068             :         zend_extension *extension;
    6069             : 
    6070           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6071           0 :                 return;
    6072             :         }
    6073           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6074             : 
    6075           1 :         if (extension->author) {
    6076           2 :                 RETURN_STRING(extension->author);
    6077             :         } else {
    6078           0 :                 RETURN_EMPTY_STRING();
    6079             :         }
    6080             : }
    6081             : /* }}} */
    6082             : 
    6083             : /* {{{ proto public void ReflectionZendExtension::getURL()
    6084             :        Returns this Zend extension's URL*/
    6085           1 : ZEND_METHOD(reflection_zend_extension, getURL)
    6086             : {
    6087             :         reflection_object *intern;
    6088             :         zend_extension *extension;
    6089             : 
    6090           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6091           0 :                 return;
    6092             :         }
    6093           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6094             : 
    6095           1 :         if (extension->URL) {
    6096           2 :                 RETURN_STRING(extension->URL);
    6097             :         } else {
    6098           0 :                 RETURN_EMPTY_STRING();
    6099             :         }
    6100             : }
    6101             : /* }}} */
    6102             : 
    6103             : /* {{{ proto public void ReflectionZendExtension::getCopyright()
    6104             :        Returns this Zend extension's copyright information */
    6105           1 : ZEND_METHOD(reflection_zend_extension, getCopyright)
    6106             : {
    6107             :         reflection_object *intern;
    6108             :         zend_extension *extension;
    6109             : 
    6110           1 :         if (zend_parse_parameters_none() == FAILURE) {
    6111           0 :                 return;
    6112             :         }
    6113           2 :         GET_REFLECTION_OBJECT_PTR(extension);
    6114             : 
    6115           1 :         if (extension->copyright) {
    6116           2 :                 RETURN_STRING(extension->copyright);
    6117             :         } else {
    6118           0 :                 RETURN_EMPTY_STRING();
    6119             :         }
    6120             : }
    6121             : /* }}} */
    6122             : 
    6123             : /* {{{ method tables */
    6124             : static const zend_function_entry reflection_exception_functions[] = {
    6125             :         PHP_FE_END
    6126             : };
    6127             : 
    6128             : ZEND_BEGIN_ARG_INFO(arginfo_reflection__void, 0)
    6129             : ZEND_END_ARG_INFO()
    6130             : 
    6131             : 
    6132             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_getModifierNames, 0)
    6133             :         ZEND_ARG_INFO(0, modifiers)
    6134             : ZEND_END_ARG_INFO()
    6135             : 
    6136             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_export, 0, 0, 1)
    6137             :         ZEND_ARG_OBJ_INFO(0, reflector, Reflector, 0)
    6138             :         ZEND_ARG_INFO(0, return)
    6139             : ZEND_END_ARG_INFO()
    6140             : 
    6141             : static const zend_function_entry reflection_functions[] = {
    6142             :         ZEND_ME(reflection, getModifierNames, arginfo_reflection_getModifierNames, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
    6143             :         ZEND_ME(reflection, export, arginfo_reflection_export, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
    6144             :         PHP_FE_END
    6145             : };
    6146             : 
    6147             : static const zend_function_entry reflector_functions[] = {
    6148             :         ZEND_FENTRY(export, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC)
    6149             :         ZEND_ABSTRACT_ME(reflector, __toString, arginfo_reflection__void)
    6150             :         PHP_FE_END
    6151             : };
    6152             : 
    6153             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_export, 0, 0, 1)
    6154             :         ZEND_ARG_INFO(0, name)
    6155             :         ZEND_ARG_INFO(0, return)
    6156             : ZEND_END_ARG_INFO()
    6157             : 
    6158             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0)
    6159             :         ZEND_ARG_INFO(0, name)
    6160             : ZEND_END_ARG_INFO()
    6161             : 
    6162             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0)
    6163             :         ZEND_ARG_INFO(0, args)
    6164             : ZEND_END_ARG_INFO()
    6165             : 
    6166             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invokeArgs, 0)
    6167             :         ZEND_ARG_ARRAY_INFO(0, args, 0)
    6168             : ZEND_END_ARG_INFO()
    6169             : 
    6170             : static const zend_function_entry reflection_function_abstract_functions[] = {
    6171             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6172             :         ZEND_ME(reflection_function, inNamespace, arginfo_reflection__void, 0)
    6173             :         ZEND_ME(reflection_function, isClosure, arginfo_reflection__void, 0)
    6174             :         ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
    6175             :         ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
    6176             :         ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
    6177             :         ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0)
    6178             :         ZEND_ME(reflection_function, isVariadic, arginfo_reflection__void, 0)
    6179             :         ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0)
    6180             :         ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0)
    6181             :         ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
    6182             :         ZEND_ME(reflection_function, getEndLine, arginfo_reflection__void, 0)
    6183             :         ZEND_ME(reflection_function, getExtension, arginfo_reflection__void, 0)
    6184             :         ZEND_ME(reflection_function, getExtensionName, arginfo_reflection__void, 0)
    6185             :         ZEND_ME(reflection_function, getFileName, arginfo_reflection__void, 0)
    6186             :         ZEND_ME(reflection_function, getName, arginfo_reflection__void, 0)
    6187             :         ZEND_ME(reflection_function, getNamespaceName, arginfo_reflection__void, 0)
    6188             :         ZEND_ME(reflection_function, getNumberOfParameters, arginfo_reflection__void, 0)
    6189             :         ZEND_ME(reflection_function, getNumberOfRequiredParameters, arginfo_reflection__void, 0)
    6190             :         ZEND_ME(reflection_function, getParameters, arginfo_reflection__void, 0)
    6191             :         ZEND_ME(reflection_function, getShortName, arginfo_reflection__void, 0)
    6192             :         ZEND_ME(reflection_function, getStartLine, arginfo_reflection__void, 0)
    6193             :         ZEND_ME(reflection_function, getStaticVariables, arginfo_reflection__void, 0)
    6194             :         ZEND_ME(reflection_function, returnsReference, arginfo_reflection__void, 0)
    6195             :         ZEND_ME(reflection_function, hasReturnType, arginfo_reflection__void, 0)
    6196             :         ZEND_ME(reflection_function, getReturnType, arginfo_reflection__void, 0)
    6197             :         PHP_FE_END
    6198             : };
    6199             : 
    6200             : static const zend_function_entry reflection_function_functions[] = {
    6201             :         ZEND_ME(reflection_function, __construct, arginfo_reflection_function___construct, 0)
    6202             :         ZEND_ME(reflection_function, __toString, arginfo_reflection__void, 0)
    6203             :         ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6204             :         ZEND_ME(reflection_function, isDisabled, arginfo_reflection__void, 0)
    6205             :         ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
    6206             :         ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
    6207             :         ZEND_ME(reflection_function, getClosure, arginfo_reflection__void, 0)
    6208             :         PHP_FE_END
    6209             : };
    6210             : 
    6211             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_generator___construct, 0)
    6212             :         ZEND_ARG_INFO(0, generator)
    6213             : ZEND_END_ARG_INFO()
    6214             : 
    6215             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_generator_trace, 0, 0, 0)
    6216             :         ZEND_ARG_INFO(0, options)
    6217             : ZEND_END_ARG_INFO()
    6218             : 
    6219             : static const zend_function_entry reflection_generator_functions[] = {
    6220             :         ZEND_ME(reflection_generator, __construct, arginfo_reflection_generator___construct, 0)
    6221             :         ZEND_ME(reflection_generator, getExecutingLine, arginfo_reflection__void, 0)
    6222             :         ZEND_ME(reflection_generator, getExecutingFile, arginfo_reflection__void, 0)
    6223             :         ZEND_ME(reflection_generator, getTrace, arginfo_reflection_generator_trace, 0)
    6224             :         ZEND_ME(reflection_generator, getFunction, arginfo_reflection__void, 0)
    6225             :         ZEND_ME(reflection_generator, getThis, arginfo_reflection__void, 0)
    6226             :         ZEND_ME(reflection_generator, getExecutingGenerator, arginfo_reflection__void, 0)
    6227             :         PHP_FE_END
    6228             : };
    6229             : 
    6230             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method_export, 0, 0, 2)
    6231             :         ZEND_ARG_INFO(0, class)
    6232             :         ZEND_ARG_INFO(0, name)
    6233             :         ZEND_ARG_INFO(0, return)
    6234             : ZEND_END_ARG_INFO()
    6235             : 
    6236             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_method___construct, 0, 0, 1)
    6237             :         ZEND_ARG_INFO(0, class_or_method)
    6238             :         ZEND_ARG_INFO(0, name)
    6239             : ZEND_END_ARG_INFO()
    6240             : 
    6241             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invoke, 0)
    6242             :         ZEND_ARG_INFO(0, object)
    6243             :         ZEND_ARG_INFO(0, args)
    6244             : ZEND_END_ARG_INFO()
    6245             : 
    6246             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_invokeArgs, 0)
    6247             :         ZEND_ARG_INFO(0, object)
    6248             :         ZEND_ARG_ARRAY_INFO(0, args, 0)
    6249             : ZEND_END_ARG_INFO()
    6250             : 
    6251             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_setAccessible, 0)
    6252             :         ZEND_ARG_INFO(0, value)
    6253             : ZEND_END_ARG_INFO()
    6254             : 
    6255             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_method_getClosure, 0)
    6256             :         ZEND_ARG_INFO(0, object)
    6257             : ZEND_END_ARG_INFO()
    6258             : 
    6259             : static const zend_function_entry reflection_method_functions[] = {
    6260             :         ZEND_ME(reflection_method, export, arginfo_reflection_method_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6261             :         ZEND_ME(reflection_method, __construct, arginfo_reflection_method___construct, 0)
    6262             :         ZEND_ME(reflection_method, __toString, arginfo_reflection__void, 0)
    6263             :         ZEND_ME(reflection_method, isPublic, arginfo_reflection__void, 0)
    6264             :         ZEND_ME(reflection_method, isPrivate, arginfo_reflection__void, 0)
    6265             :         ZEND_ME(reflection_method, isProtected, arginfo_reflection__void, 0)
    6266             :         ZEND_ME(reflection_method, isAbstract, arginfo_reflection__void, 0)
    6267             :         ZEND_ME(reflection_method, isFinal, arginfo_reflection__void, 0)
    6268             :         ZEND_ME(reflection_method, isStatic, arginfo_reflection__void, 0)
    6269             :         ZEND_ME(reflection_method, isConstructor, arginfo_reflection__void, 0)
    6270             :         ZEND_ME(reflection_method, isDestructor, arginfo_reflection__void, 0)
    6271             :         ZEND_ME(reflection_method, getClosure, arginfo_reflection_method_getClosure, 0)
    6272             :         ZEND_ME(reflection_method, getModifiers, arginfo_reflection__void, 0)
    6273             :         ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
    6274             :         ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
    6275             :         ZEND_ME(reflection_method, getDeclaringClass, arginfo_reflection__void, 0)
    6276             :         ZEND_ME(reflection_method, getPrototype, arginfo_reflection__void, 0)
    6277             :         ZEND_ME(reflection_method, setAccessible, arginfo_reflection_method_setAccessible, 0)
    6278             :         PHP_FE_END
    6279             : };
    6280             : 
    6281             : 
    6282             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_export, 0, 0, 1)
    6283             :         ZEND_ARG_INFO(0, argument)
    6284             :         ZEND_ARG_INFO(0, return)
    6285             : ZEND_END_ARG_INFO()
    6286             : 
    6287             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class___construct, 0)
    6288             :         ZEND_ARG_INFO(0, argument)
    6289             : ZEND_END_ARG_INFO()
    6290             : 
    6291             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getStaticPropertyValue, 0, 0, 1)
    6292             :         ZEND_ARG_INFO(0, name)
    6293             :         ZEND_ARG_INFO(0, default)
    6294             : ZEND_END_ARG_INFO()
    6295             : 
    6296             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_setStaticPropertyValue, 0)
    6297             :         ZEND_ARG_INFO(0, name)
    6298             :         ZEND_ARG_INFO(0, value)
    6299             : ZEND_END_ARG_INFO()
    6300             : 
    6301             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasMethod, 0)
    6302             :         ZEND_ARG_INFO(0, name)
    6303             : ZEND_END_ARG_INFO()
    6304             : 
    6305             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getMethod, 0)
    6306             :         ZEND_ARG_INFO(0, name)
    6307             : ZEND_END_ARG_INFO()
    6308             : 
    6309             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getMethods, 0, 0, 0)
    6310             :         ZEND_ARG_INFO(0, filter)
    6311             : ZEND_END_ARG_INFO()
    6312             : 
    6313             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasProperty, 0)
    6314             :         ZEND_ARG_INFO(0, name)
    6315             : ZEND_END_ARG_INFO()
    6316             : 
    6317             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getProperty, 0)
    6318             :         ZEND_ARG_INFO(0, name)
    6319             : ZEND_END_ARG_INFO()
    6320             : 
    6321             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_getProperties, 0, 0, 0)
    6322             :         ZEND_ARG_INFO(0, filter)
    6323             : ZEND_END_ARG_INFO()
    6324             : 
    6325             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_hasConstant, 0)
    6326             :         ZEND_ARG_INFO(0, name)
    6327             : ZEND_END_ARG_INFO()
    6328             : 
    6329             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_getConstant, 0)
    6330             :         ZEND_ARG_INFO(0, name)
    6331             : ZEND_END_ARG_INFO()
    6332             : 
    6333             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isInstance, 0)
    6334             :         ZEND_ARG_INFO(0, object)
    6335             : ZEND_END_ARG_INFO()
    6336             : 
    6337             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstance, 0)
    6338             :         ZEND_ARG_INFO(0, args)
    6339             : ZEND_END_ARG_INFO()
    6340             : 
    6341             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_newInstanceWithoutConstructor, 0)
    6342             : ZEND_END_ARG_INFO()
    6343             : 
    6344             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_newInstanceArgs, 0, 0, 0)
    6345             :         ZEND_ARG_ARRAY_INFO(0, args, 0)
    6346             : ZEND_END_ARG_INFO()
    6347             : 
    6348             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_isSubclassOf, 0)
    6349             :         ZEND_ARG_INFO(0, class)
    6350             : ZEND_END_ARG_INFO()
    6351             : 
    6352             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_class_implementsInterface, 0)
    6353             :         ZEND_ARG_INFO(0, interface)
    6354             : ZEND_END_ARG_INFO()
    6355             : 
    6356             : static const zend_function_entry reflection_class_functions[] = {
    6357             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6358             :         ZEND_ME(reflection_class, export, arginfo_reflection_class_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6359             :         ZEND_ME(reflection_class, __construct, arginfo_reflection_class___construct, 0)
    6360             :         ZEND_ME(reflection_class, __toString, arginfo_reflection__void, 0)
    6361             :         ZEND_ME(reflection_class, getName, arginfo_reflection__void, 0)
    6362             :         ZEND_ME(reflection_class, isInternal, arginfo_reflection__void, 0)
    6363             :         ZEND_ME(reflection_class, isUserDefined, arginfo_reflection__void, 0)
    6364             :         ZEND_ME(reflection_class, isAnonymous, arginfo_reflection__void, 0)
    6365             :         ZEND_ME(reflection_class, isInstantiable, arginfo_reflection__void, 0)
    6366             :         ZEND_ME(reflection_class, isCloneable, arginfo_reflection__void, 0)
    6367             :         ZEND_ME(reflection_class, getFileName, arginfo_reflection__void, 0)
    6368             :         ZEND_ME(reflection_class, getStartLine, arginfo_reflection__void, 0)
    6369             :         ZEND_ME(reflection_class, getEndLine, arginfo_reflection__void, 0)
    6370             :         ZEND_ME(reflection_class, getDocComment, arginfo_reflection__void, 0)
    6371             :         ZEND_ME(reflection_class, getConstructor, arginfo_reflection__void, 0)
    6372             :         ZEND_ME(reflection_class, hasMethod, arginfo_reflection_class_hasMethod, 0)
    6373             :         ZEND_ME(reflection_class, getMethod, arginfo_reflection_class_getMethod, 0)
    6374             :         ZEND_ME(reflection_class, getMethods, arginfo_reflection_class_getMethods, 0)
    6375             :         ZEND_ME(reflection_class, hasProperty, arginfo_reflection_class_hasProperty, 0)
    6376             :         ZEND_ME(reflection_class, getProperty, arginfo_reflection_class_getProperty, 0)
    6377             :         ZEND_ME(reflection_class, getProperties, arginfo_reflection_class_getProperties, 0)
    6378             :         ZEND_ME(reflection_class, hasConstant, arginfo_reflection_class_hasConstant, 0)
    6379             :         ZEND_ME(reflection_class, getConstants, arginfo_reflection__void, 0)
    6380             :         ZEND_ME(reflection_class, getReflectionConstants, arginfo_reflection__void, 0)
    6381             :         ZEND_ME(reflection_class, getConstant, arginfo_reflection_class_getConstant, 0)
    6382             :         ZEND_ME(reflection_class, getReflectionConstant, arginfo_reflection_class_getConstant, 0)
    6383             :         ZEND_ME(reflection_class, getInterfaces, arginfo_reflection__void, 0)
    6384             :         ZEND_ME(reflection_class, getInterfaceNames, arginfo_reflection__void, 0)
    6385             :         ZEND_ME(reflection_class, isInterface, arginfo_reflection__void, 0)
    6386             :         ZEND_ME(reflection_class, getTraits, arginfo_reflection__void, 0)
    6387             :         ZEND_ME(reflection_class, getTraitNames, arginfo_reflection__void, 0)
    6388             :         ZEND_ME(reflection_class, getTraitAliases, arginfo_reflection__void, 0)
    6389             :         ZEND_ME(reflection_class, isTrait, arginfo_reflection__void, 0)
    6390             :         ZEND_ME(reflection_class, isAbstract, arginfo_reflection__void, 0)
    6391             :         ZEND_ME(reflection_class, isFinal, arginfo_reflection__void, 0)
    6392             :         ZEND_ME(reflection_class, getModifiers, arginfo_reflection__void, 0)
    6393             :         ZEND_ME(reflection_class, isInstance, arginfo_reflection_class_isInstance, 0)
    6394             :         ZEND_ME(reflection_class, newInstance, arginfo_reflection_class_newInstance, 0)
    6395             :         ZEND_ME(reflection_class, newInstanceWithoutConstructor, arginfo_reflection_class_newInstanceWithoutConstructor, 0)
    6396             :         ZEND_ME(reflection_class, newInstanceArgs, arginfo_reflection_class_newInstanceArgs, 0)
    6397             :         ZEND_ME(reflection_class, getParentClass, arginfo_reflection__void, 0)
    6398             :         ZEND_ME(reflection_class, isSubclassOf, arginfo_reflection_class_isSubclassOf, 0)
    6399             :         ZEND_ME(reflection_class, getStaticProperties, arginfo_reflection__void, 0)
    6400             :         ZEND_ME(reflection_class, getStaticPropertyValue, arginfo_reflection_class_getStaticPropertyValue, 0)
    6401             :         ZEND_ME(reflection_class, setStaticPropertyValue, arginfo_reflection_class_setStaticPropertyValue, 0)
    6402             :         ZEND_ME(reflection_class, getDefaultProperties, arginfo_reflection__void, 0)
    6403             :         ZEND_ME(reflection_class, isIterable, arginfo_reflection__void, 0)
    6404             :         ZEND_MALIAS(reflection_class, isIterateable, isIterable, arginfo_reflection__void, 0)
    6405             :         ZEND_ME(reflection_class, implementsInterface, arginfo_reflection_class_implementsInterface, 0)
    6406             :         ZEND_ME(reflection_class, getExtension, arginfo_reflection__void, 0)
    6407             :         ZEND_ME(reflection_class, getExtensionName, arginfo_reflection__void, 0)
    6408             :         ZEND_ME(reflection_class, inNamespace, arginfo_reflection__void, 0)
    6409             :         ZEND_ME(reflection_class, getNamespaceName, arginfo_reflection__void, 0)
    6410             :         ZEND_ME(reflection_class, getShortName, arginfo_reflection__void, 0)
    6411             :         PHP_FE_END
    6412             : };
    6413             : 
    6414             : 
    6415             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_object_export, 0, 0, 1)
    6416             :         ZEND_ARG_INFO(0, argument)
    6417             :         ZEND_ARG_INFO(0, return)
    6418             : ZEND_END_ARG_INFO()
    6419             : 
    6420             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_object___construct, 0)
    6421             :         ZEND_ARG_INFO(0, argument)
    6422             : ZEND_END_ARG_INFO()
    6423             : 
    6424             : static const zend_function_entry reflection_object_functions[] = {
    6425             :         ZEND_ME(reflection_object, export, arginfo_reflection_object_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6426             :         ZEND_ME(reflection_object, __construct, arginfo_reflection_object___construct, 0)
    6427             :         PHP_FE_END
    6428             : };
    6429             : 
    6430             : 
    6431             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_export, 0, 0, 2)
    6432             :         ZEND_ARG_INFO(0, class)
    6433             :         ZEND_ARG_INFO(0, name)
    6434             :         ZEND_ARG_INFO(0, return)
    6435             : ZEND_END_ARG_INFO()
    6436             : 
    6437             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property___construct, 0, 0, 2)
    6438             :         ZEND_ARG_INFO(0, class)
    6439             :         ZEND_ARG_INFO(0, name)
    6440             : ZEND_END_ARG_INFO()
    6441             : 
    6442             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_getValue, 0, 0, 0)
    6443             :         ZEND_ARG_INFO(0, object)
    6444             : ZEND_END_ARG_INFO()
    6445             : 
    6446             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_property_setValue, 0, 0, 1)
    6447             :         ZEND_ARG_INFO(0, object)
    6448             :         ZEND_ARG_INFO(0, value)
    6449             : ZEND_END_ARG_INFO()
    6450             : 
    6451             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_property_setAccessible, 0)
    6452             :         ZEND_ARG_INFO(0, visible)
    6453             : ZEND_END_ARG_INFO()
    6454             : 
    6455             : static const zend_function_entry reflection_property_functions[] = {
    6456             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6457             :         ZEND_ME(reflection_property, export, arginfo_reflection_property_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6458             :         ZEND_ME(reflection_property, __construct, arginfo_reflection_property___construct, 0)
    6459             :         ZEND_ME(reflection_property, __toString, arginfo_reflection__void, 0)
    6460             :         ZEND_ME(reflection_property, getName, arginfo_reflection__void, 0)
    6461             :         ZEND_ME(reflection_property, getValue, arginfo_reflection_property_getValue, 0)
    6462             :         ZEND_ME(reflection_property, setValue, arginfo_reflection_property_setValue, 0)
    6463             :         ZEND_ME(reflection_property, isPublic, arginfo_reflection__void, 0)
    6464             :         ZEND_ME(reflection_property, isPrivate, arginfo_reflection__void, 0)
    6465             :         ZEND_ME(reflection_property, isProtected, arginfo_reflection__void, 0)
    6466             :         ZEND_ME(reflection_property, isStatic, arginfo_reflection__void, 0)
    6467             :         ZEND_ME(reflection_property, isDefault, arginfo_reflection__void, 0)
    6468             :         ZEND_ME(reflection_property, getModifiers, arginfo_reflection__void, 0)
    6469             :         ZEND_ME(reflection_property, getDeclaringClass, arginfo_reflection__void, 0)
    6470             :         ZEND_ME(reflection_property, getDocComment, arginfo_reflection__void, 0)
    6471             :         ZEND_ME(reflection_property, setAccessible, arginfo_reflection_property_setAccessible, 0)
    6472             :         PHP_FE_END
    6473             : };
    6474             : 
    6475             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_constant_export, 0, 0, 2)
    6476             :         ZEND_ARG_INFO(0, class)
    6477             :         ZEND_ARG_INFO(0, name)
    6478             :         ZEND_ARG_INFO(0, return)
    6479             : ZEND_END_ARG_INFO()
    6480             : 
    6481             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_class_constant___construct, 0, 0, 2)
    6482             :         ZEND_ARG_INFO(0, class)
    6483             :         ZEND_ARG_INFO(0, name)
    6484             : ZEND_END_ARG_INFO()
    6485             : 
    6486             : static const zend_function_entry reflection_class_constant_functions[] = {
    6487             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6488             :         ZEND_ME(reflection_class_constant, export, arginfo_reflection_class_constant_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6489             :         ZEND_ME(reflection_class_constant, __construct, arginfo_reflection_class_constant___construct, 0)
    6490             :         ZEND_ME(reflection_class_constant, __toString, arginfo_reflection__void, 0)
    6491             :         ZEND_ME(reflection_class_constant, getName, arginfo_reflection__void, 0)
    6492             :         ZEND_ME(reflection_class_constant, getValue, arginfo_reflection__void, 0)
    6493             :         ZEND_ME(reflection_class_constant, isPublic, arginfo_reflection__void, 0)
    6494             :         ZEND_ME(reflection_class_constant, isPrivate, arginfo_reflection__void, 0)
    6495             :         ZEND_ME(reflection_class_constant, isProtected, arginfo_reflection__void, 0)
    6496             :         ZEND_ME(reflection_class_constant, getModifiers, arginfo_reflection__void, 0)
    6497             :         ZEND_ME(reflection_class_constant, getDeclaringClass, arginfo_reflection__void, 0)
    6498             :         ZEND_ME(reflection_class_constant, getDocComment, arginfo_reflection__void, 0)
    6499             :         PHP_FE_END
    6500             : };
    6501             : 
    6502             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_parameter_export, 0, 0, 2)
    6503             :         ZEND_ARG_INFO(0, function)
    6504             :         ZEND_ARG_INFO(0, parameter)
    6505             :         ZEND_ARG_INFO(0, return)
    6506             : ZEND_END_ARG_INFO()
    6507             : 
    6508             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_parameter___construct, 0)
    6509             :         ZEND_ARG_INFO(0, function)
    6510             :         ZEND_ARG_INFO(0, parameter)
    6511             : ZEND_END_ARG_INFO()
    6512             : 
    6513             : static const zend_function_entry reflection_parameter_functions[] = {
    6514             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6515             :         ZEND_ME(reflection_parameter, export, arginfo_reflection_parameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6516             :         ZEND_ME(reflection_parameter, __construct, arginfo_reflection_parameter___construct, 0)
    6517             :         ZEND_ME(reflection_parameter, __toString, arginfo_reflection__void, 0)
    6518             :         ZEND_ME(reflection_parameter, getName, arginfo_reflection__void, 0)
    6519             :         ZEND_ME(reflection_parameter, isPassedByReference, arginfo_reflection__void, 0)
    6520             :         ZEND_ME(reflection_parameter, canBePassedByValue, arginfo_reflection__void, 0)
    6521             :         ZEND_ME(reflection_parameter, getDeclaringFunction, arginfo_reflection__void, 0)
    6522             :         ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
    6523             :         ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
    6524             :         ZEND_ME(reflection_parameter, hasType, arginfo_reflection__void, 0)
    6525             :         ZEND_ME(reflection_parameter, getType, arginfo_reflection__void, 0)
    6526             :         ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
    6527             :         ZEND_ME(reflection_parameter, isCallable, arginfo_reflection__void, 0)
    6528             :         ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
    6529             :         ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
    6530             :         ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)
    6531             :         ZEND_ME(reflection_parameter, isDefaultValueAvailable, arginfo_reflection__void, 0)
    6532             :         ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0)
    6533             :         ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0)
    6534             :         ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0)
    6535             :         ZEND_ME(reflection_parameter, isVariadic, arginfo_reflection__void, 0)
    6536             :         PHP_FE_END
    6537             : };
    6538             : 
    6539             : static const zend_function_entry reflection_type_functions[] = {
    6540             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6541             :         ZEND_ME(reflection_type, allowsNull, arginfo_reflection__void, 0)
    6542             :         ZEND_ME(reflection_type, isBuiltin, arginfo_reflection__void, 0)
    6543             :         /* ReflectionType::__toString() is deprecated, but we currently do not mark it as such
    6544             :          * due to bad interaction with the PHPUnit error handler and exceptions in __toString().
    6545             :          * See PR2137. */
    6546             :         ZEND_ME(reflection_type, __toString, arginfo_reflection__void, 0)
    6547             :         PHP_FE_END
    6548             : };
    6549             : 
    6550             : static const zend_function_entry reflection_named_type_functions[] = {
    6551             :         ZEND_ME(reflection_named_type, getName, arginfo_reflection__void, 0)
    6552             :         PHP_FE_END
    6553             : };
    6554             : 
    6555             : ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_extension_export, 0, 0, 1)
    6556             :         ZEND_ARG_INFO(0, name)
    6557             :         ZEND_ARG_INFO(0, return)
    6558             : ZEND_END_ARG_INFO()
    6559             : 
    6560             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_extension___construct, 0)
    6561             :         ZEND_ARG_INFO(0, name)
    6562             : ZEND_END_ARG_INFO()
    6563             : 
    6564             : static const zend_function_entry reflection_extension_functions[] = {
    6565             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6566             :         ZEND_ME(reflection_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6567             :         ZEND_ME(reflection_extension, __construct, arginfo_reflection_extension___construct, 0)
    6568             :         ZEND_ME(reflection_extension, __toString, arginfo_reflection__void, 0)
    6569             :         ZEND_ME(reflection_extension, getName, arginfo_reflection__void, 0)
    6570             :         ZEND_ME(reflection_extension, getVersion, arginfo_reflection__void, 0)
    6571             :         ZEND_ME(reflection_extension, getFunctions, arginfo_reflection__void, 0)
    6572             :         ZEND_ME(reflection_extension, getConstants, arginfo_reflection__void, 0)
    6573             :         ZEND_ME(reflection_extension, getINIEntries, arginfo_reflection__void, 0)
    6574             :         ZEND_ME(reflection_extension, getClasses, arginfo_reflection__void, 0)
    6575             :         ZEND_ME(reflection_extension, getClassNames, arginfo_reflection__void, 0)
    6576             :         ZEND_ME(reflection_extension, getDependencies, arginfo_reflection__void, 0)
    6577             :         ZEND_ME(reflection_extension, info, arginfo_reflection__void, 0)
    6578             :         ZEND_ME(reflection_extension, isPersistent, arginfo_reflection__void, 0)
    6579             :         ZEND_ME(reflection_extension, isTemporary, arginfo_reflection__void, 0)
    6580             :         PHP_FE_END
    6581             : };
    6582             : 
    6583             : ZEND_BEGIN_ARG_INFO(arginfo_reflection_zend_extension___construct, 0)
    6584             :         ZEND_ARG_INFO(0, name)
    6585             : ZEND_END_ARG_INFO()
    6586             : 
    6587             : static const zend_function_entry reflection_zend_extension_functions[] = {
    6588             :         ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
    6589             :         ZEND_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
    6590             :         ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_zend_extension___construct, 0)
    6591             :         ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0)
    6592             :         ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0)
    6593             :         ZEND_ME(reflection_zend_extension, getVersion, arginfo_reflection__void, 0)
    6594             :         ZEND_ME(reflection_zend_extension, getAuthor, arginfo_reflection__void, 0)
    6595             :         ZEND_ME(reflection_zend_extension, getURL, arginfo_reflection__void, 0)
    6596             :         ZEND_ME(reflection_zend_extension, getCopyright, arginfo_reflection__void, 0)
    6597             :         PHP_FE_END
    6598             : };
    6599             : /* }}} */
    6600             : 
    6601             : static const zend_function_entry reflection_ext_functions[] = { /* {{{ */
    6602             :         PHP_FE_END
    6603             : }; /* }}} */
    6604             : 
    6605             : /* {{{ _reflection_write_property */
    6606           5 : static void _reflection_write_property(zval *object, zval *member, zval *value, void **cache_slot)
    6607             : {
    6608           5 :         if ((Z_TYPE_P(member) == IS_STRING)
    6609           5 :                 && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STR_P(member))
    6610           3 :                 && ((Z_STRLEN_P(member) == sizeof("name") - 1  && !memcmp(Z_STRVAL_P(member), "name",  sizeof("name")))
    6611           2 :                         || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class")))))
    6612             :         {
    6613           2 :                 zend_throw_exception_ex(reflection_exception_ptr, 0,
    6614           2 :                         "Cannot set read-only property %s::$%s", ZSTR_VAL(Z_OBJCE_P(object)->name), Z_STRVAL_P(member));
    6615             :         }
    6616             :         else
    6617             :         {
    6618           3 :                 zend_std_write_property(object, member, value, cache_slot);
    6619             :         }
    6620           5 : }
    6621             : /* }}} */
    6622             : 
    6623       26000 : PHP_MINIT_FUNCTION(reflection) /* {{{ */
    6624             : {
    6625             :         zend_class_entry _reflection_entry;
    6626             : 
    6627       26000 :         memcpy(&reflection_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
    6628       26000 :         reflection_object_handlers.offset = XtOffsetOf(reflection_object, zo);
    6629       26000 :         reflection_object_handlers.free_obj = reflection_free_objects_storage;
    6630       26000 :         reflection_object_handlers.clone_obj = NULL;
    6631       26000 :         reflection_object_handlers.write_property = _reflection_write_property;
    6632       26000 :         reflection_object_handlers.get_gc = reflection_get_gc;
    6633             : 
    6634       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions);
    6635       26000 :         reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_ce_exception);
    6636             : 
    6637       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "Reflection", reflection_functions);
    6638       26000 :         reflection_ptr = zend_register_internal_class(&_reflection_entry);
    6639             : 
    6640       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions);
    6641       26000 :         reflector_ptr = zend_register_internal_interface(&_reflection_entry);
    6642             : 
    6643       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions);
    6644       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6645       26000 :         reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry);
    6646       26000 :         zend_class_implements(reflection_function_abstract_ptr, 1, reflector_ptr);
    6647       26000 :         zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT);
    6648             : 
    6649       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions);
    6650       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6651       26000 :         reflection_function_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr);
    6652       26000 :         zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6653             : 
    6654       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
    6655             : 
    6656       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionGenerator", reflection_generator_functions);
    6657       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6658       26000 :         reflection_generator_ptr = zend_register_internal_class(&_reflection_entry);
    6659             : 
    6660       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
    6661       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6662       26000 :         reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry);
    6663       26000 :         zend_class_implements(reflection_parameter_ptr, 1, reflector_ptr);
    6664       26000 :         zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6665             : 
    6666       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions);
    6667       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6668       26000 :         reflection_type_ptr = zend_register_internal_class(&_reflection_entry);
    6669             : 
    6670       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionNamedType", reflection_named_type_functions);
    6671       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6672       26000 :         reflection_named_type_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_type_ptr);
    6673             : 
    6674       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionMethod", reflection_method_functions);
    6675       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6676       26000 :         reflection_method_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_function_abstract_ptr);
    6677       26000 :         zend_declare_property_string(reflection_method_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6678       26000 :         zend_declare_property_string(reflection_method_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC);
    6679             : 
    6680       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_STATIC", ZEND_ACC_STATIC);
    6681       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PUBLIC", ZEND_ACC_PUBLIC);
    6682       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PROTECTED", ZEND_ACC_PROTECTED);
    6683       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_PRIVATE", ZEND_ACC_PRIVATE);
    6684       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_ABSTRACT", ZEND_ACC_ABSTRACT);
    6685       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(method, "IS_FINAL", ZEND_ACC_FINAL);
    6686             : 
    6687       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions);
    6688       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6689       26000 :         reflection_class_ptr = zend_register_internal_class(&_reflection_entry);
    6690       26000 :         zend_class_implements(reflection_class_ptr, 1, reflector_ptr);
    6691       26000 :         zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6692             : 
    6693       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_IMPLICIT_ABSTRACT", ZEND_ACC_IMPLICIT_ABSTRACT_CLASS);
    6694       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_EXPLICIT_ABSTRACT", ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
    6695       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(class, "IS_FINAL", ZEND_ACC_FINAL);
    6696             : 
    6697       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionObject", reflection_object_functions);
    6698       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6699       26000 :         reflection_object_ptr = zend_register_internal_class_ex(&_reflection_entry, reflection_class_ptr);
    6700             : 
    6701       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions);
    6702       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6703       26000 :         reflection_property_ptr = zend_register_internal_class(&_reflection_entry);
    6704       26000 :         zend_class_implements(reflection_property_ptr, 1, reflector_ptr);
    6705       26000 :         zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6706       26000 :         zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC);
    6707             : 
    6708       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClassConstant", reflection_class_constant_functions);
    6709       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6710       26000 :         reflection_class_constant_ptr = zend_register_internal_class(&_reflection_entry);
    6711       26000 :         zend_class_implements(reflection_class_constant_ptr, 1, reflector_ptr);
    6712       26000 :         zend_declare_property_string(reflection_class_constant_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6713       26000 :         zend_declare_property_string(reflection_class_constant_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC);
    6714             : 
    6715       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_STATIC", ZEND_ACC_STATIC);
    6716       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PUBLIC", ZEND_ACC_PUBLIC);
    6717       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PROTECTED", ZEND_ACC_PROTECTED);
    6718       26000 :         REGISTER_REFLECTION_CLASS_CONST_LONG(property, "IS_PRIVATE", ZEND_ACC_PRIVATE);
    6719             : 
    6720       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions);
    6721       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6722       26000 :         reflection_extension_ptr = zend_register_internal_class(&_reflection_entry);
    6723       26000 :         zend_class_implements(reflection_extension_ptr, 1, reflector_ptr);
    6724       26000 :         zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6725             : 
    6726       26000 :         INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions);
    6727       26000 :         _reflection_entry.create_object = reflection_objects_new;
    6728       26000 :         reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry);
    6729       26000 :         zend_class_implements(reflection_zend_extension_ptr, 1, reflector_ptr);
    6730       26000 :         zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC);
    6731             : 
    6732       26000 :         return SUCCESS;
    6733             : } /* }}} */
    6734             : 
    6735         151 : PHP_MINFO_FUNCTION(reflection) /* {{{ */
    6736             : {
    6737         151 :         php_info_print_table_start();
    6738         151 :         php_info_print_table_row(2, "Reflection", "enabled");
    6739         151 :         php_info_print_table_end();
    6740         151 : } /* }}} */
    6741             : 
    6742             : zend_module_entry reflection_module_entry = { /* {{{ */
    6743             :         STANDARD_MODULE_HEADER,
    6744             :         "Reflection",
    6745             :         reflection_ext_functions,
    6746             :         PHP_MINIT(reflection),
    6747             :         NULL,
    6748             :         NULL,
    6749             :         NULL,
    6750             :         PHP_MINFO(reflection),
    6751             :         PHP_REFLECTION_VERSION,
    6752             :         STANDARD_MODULE_PROPERTIES
    6753             : }; /* }}} */
    6754             : 
    6755             : /*
    6756             :  * Local variables:
    6757             :  * tab-width: 4
    6758             :  * c-basic-offset: 4
    6759             :  * indent-tabs-mode: t
    6760             :  * End:
    6761             :  * vim600: noet sw=4 ts=4 fdm=marker
    6762             :  */

Generated by: LCOV version 1.10

Generated at Wed, 19 Jan 2022 00:14:21 +0000 (3 days ago)

Copyright © 2005-2022 The PHP Group
All rights reserved.