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: 2291 2587 88.6 %
Date: 2014-09-29 Functions: 192 205 93.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 29 Sep 2014 14:26:28 +0000 (15 hours ago)

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