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

Generated by: LCOV version 1.10

Generated at Thu, 13 Jun 2019 04:43:53 +0000 (4 days ago)

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