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: 2381 2720 87.5 %
Date: 2015-05-21 Functions: 203 216 94.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:59:02 +0000 (4 days ago)

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