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

Generated by: LCOV version 1.10

Generated at Mon, 26 Jan 2015 14:46:51 +0000 (5 days ago)

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