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

Generated by: LCOV version 1.10

Generated at Sun, 01 Mar 2015 23:22:32 +0000 (4 days ago)

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