/ext/reflection/php_reflection.c
C | 5559 lines | 4223 code | 737 blank | 599 comment | 1019 complexity | 7204d8e86ad231fc5b03c4f8607f18b6 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- /*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2011 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.01 of the PHP license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.php.net/license/3_01.txt |
- | If you did not receive a copy of the PHP license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@php.net so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Timm Friebe <thekid@thekid.de> |
- | George Schlossnagle <george@omniti.com> |
- | Andrei Zmievski <andrei@gravitonic.com> |
- | Marcus Boerger <helly@php.net> |
- | Johannes Schlueter <johannes@php.net> |
- +----------------------------------------------------------------------+
- */
- /* $Id: php_reflection.c 307971 2011-02-03 12:45:30Z cataphract $ */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "php.h"
- #include "php_ini.h"
- #include "php_reflection.h"
- #include "ext/standard/info.h"
- #include "zend.h"
- #include "zend_API.h"
- #include "zend_exceptions.h"
- #include "zend_operators.h"
- #include "zend_constants.h"
- #include "zend_ini.h"
- #include "zend_interfaces.h"
- #include "zend_closures.h"
- /* Undefine "getParameters" macro defined in "main/php3_compat.h" */
- #ifdef getParameters
- # undef getParameters
- #endif
- /* Class entry pointers */
- PHPAPI zend_class_entry *reflector_ptr;
- PHPAPI zend_class_entry *reflection_exception_ptr;
- PHPAPI zend_class_entry *reflection_ptr;
- PHPAPI zend_class_entry *reflection_function_abstract_ptr;
- PHPAPI zend_class_entry *reflection_function_ptr;
- PHPAPI zend_class_entry *reflection_parameter_ptr;
- PHPAPI zend_class_entry *reflection_class_ptr;
- PHPAPI zend_class_entry *reflection_object_ptr;
- PHPAPI zend_class_entry *reflection_method_ptr;
- PHPAPI zend_class_entry *reflection_property_ptr;
- PHPAPI zend_class_entry *reflection_extension_ptr;
- #if MBO_0
- ZEND_BEGIN_MODULE_GLOBALS(reflection)
- int dummy;
- ZEND_END_MODULE_GLOBALS(reflection)
- #ifdef ZTS
- # define REFLECTION_G(v) \
- TSRMG(reflection_globals_id, zend_reflection_globals*, v)
- extern int reflection_globals_id;
- #else
- # define REFLECTION_G(v) (reflection_globals.v)
- extern zend_reflection_globals reflectionglobals;
- #endif
- ZEND_DECLARE_MODULE_GLOBALS(reflection)
- #endif /* MBO_0 */
- /* Method macros */
- #define METHOD_NOTSTATIC(ce) \
- if (!this_ptr || !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) { \
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
- return; \
- } \
- /* Exception throwing macro */
- #define _DO_THROW(msg) \
- zend_throw_exception(reflection_exception_ptr, msg, 0 TSRMLS_CC); \
- return; \
- #define RETURN_ON_EXCEPTION \
- if (EG(exception) && Z_OBJCE_P(EG(exception)) == reflection_exception_ptr) { \
- return; \
- }
- #define GET_REFLECTION_OBJECT_PTR(target) \
- intern = (reflection_object *) zend_object_store_get_object(getThis() TSRMLS_CC); \
- if (intern == NULL || intern->ptr == NULL) { \
- RETURN_ON_EXCEPTION \
- php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Failed to retrieve the reflection object"); \
- } \
- target = intern->ptr; \
- /* Class constants */
- #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \
- zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
- /* {{{ Smart string functions */
- typedef struct _string {
- char *string;
- int len;
- int alloced;
- } string;
- static void string_init(string *str)
- {
- str->string = (char *) emalloc(1024);
- str->len = 1;
- str->alloced = 1024;
- *str->string = '\0';
- }
-
- static string *string_printf(string *str, const char *format, ...)
- {
- int len;
- va_list arg;
- char *s_tmp;
- va_start(arg, format);
- len = zend_vspprintf(&s_tmp, 0, format, arg);
- if (len) {
- register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
- if (str->alloced < nlen) {
- str->alloced = nlen;
- str->string = erealloc(str->string, str->alloced);
- }
- memcpy(str->string + str->len - 1, s_tmp, len + 1);
- str->len += len;
- }
- efree(s_tmp);
- va_end(arg);
- return str;
- }
- static string *string_write(string *str, char *buf, int len)
- {
- register int nlen = (str->len + len + (1024 - 1)) & ~(1024 - 1);
- if (str->alloced < nlen) {
- str->alloced = nlen;
- str->string = erealloc(str->string, str->alloced);
- }
- memcpy(str->string + str->len - 1, buf, len);
- str->len += len;
- str->string[str->len - 1] = '\0';
- return str;
- }
- static string *string_append(string *str, string *append)
- {
- if (append->len > 1) {
- string_write(str, append->string, append->len - 1);
- }
- return str;
- }
- static void string_free(string *str)
- {
- efree(str->string);
- str->len = 0;
- str->alloced = 0;
- str->string = NULL;
- }
- /* }}} */
- /* Struct for properties */
- typedef struct _property_reference {
- zend_class_entry *ce;
- zend_property_info prop;
- } property_reference;
- /* Struct for parameters */
- typedef struct _parameter_reference {
- zend_uint offset;
- zend_uint required;
- struct _zend_arg_info *arg_info;
- zend_function *fptr;
- } parameter_reference;
- typedef enum {
- REF_TYPE_OTHER, /* Must be 0 */
- REF_TYPE_FUNCTION,
- REF_TYPE_PARAMETER,
- REF_TYPE_PROPERTY,
- REF_TYPE_DYNAMIC_PROPERTY
- } reflection_type_t;
- /* Struct for reflection objects */
- typedef struct {
- zend_object zo;
- void *ptr;
- reflection_type_t ref_type;
- zval *obj;
- zend_class_entry *ce;
- unsigned int ignore_visibility:1;
- } reflection_object;
- static zend_object_handlers reflection_object_handlers;
- static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC)
- {
- zval **value;
- if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
- RETURN_FALSE;
- }
- MAKE_COPY_ZVAL(value, return_value);
- }
- #ifdef ilia_0
- static void _default_lookup_entry(zval *object, char *name, int name_len, zval **return_value TSRMLS_DC) /* {{{ */
- {
- zval **value;
- if (zend_hash_find(Z_OBJPROP_P(object), name, name_len, (void **) &value) == FAILURE) {
- *return_value = NULL;
- } else {
- *return_value = *value;
- }
- }
- /* }}} */
- #endif
- static void reflection_register_implement(zend_class_entry *class_entry, zend_class_entry *interface_entry TSRMLS_DC)
- {
- zend_uint num_interfaces = ++class_entry->num_interfaces;
- class_entry->interfaces = (zend_class_entry **) realloc(class_entry->interfaces, sizeof(zend_class_entry *) * num_interfaces);
- class_entry->interfaces[num_interfaces - 1] = interface_entry;
- }
- static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
- {
- if (fptr
- && fptr->type == ZEND_INTERNAL_FUNCTION
- && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
- {
- zend_function *copy_fptr;
- copy_fptr = emalloc(sizeof(zend_function));
- memcpy(copy_fptr, fptr, sizeof(zend_function));
- copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name);
- return copy_fptr;
- } else {
- /* no copy needed */
- return fptr;
- }
- }
- /* }}} */
- static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
- {
- if (fptr
- && fptr->type == ZEND_INTERNAL_FUNCTION
- && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
- {
- efree(fptr->internal_function.function_name);
- efree(fptr);
- }
- }
- /* }}} */
- static void reflection_free_objects_storage(void *object TSRMLS_DC)
- {
- reflection_object *intern = (reflection_object *) object;
- parameter_reference *reference;
- property_reference *prop_reference;
- if (intern->ptr) {
- switch (intern->ref_type) {
- case REF_TYPE_PARAMETER:
- reference = (parameter_reference*)intern->ptr;
- _free_function(reference->fptr TSRMLS_CC);
- efree(intern->ptr);
- break;
- case REF_TYPE_FUNCTION:
- _free_function(intern->ptr TSRMLS_CC);
- break;
- case REF_TYPE_PROPERTY:
- efree(intern->ptr);
- break;
- case REF_TYPE_DYNAMIC_PROPERTY:
- prop_reference = (property_reference*)intern->ptr;
- efree(prop_reference->prop.name);
- efree(intern->ptr);
- break;
- case REF_TYPE_OTHER:
- break;
- }
- }
- intern->ptr = NULL;
- if (intern->obj) {
- zval_ptr_dtor(&intern->obj);
- }
- zend_objects_free_object_storage(object TSRMLS_CC);
- }
- static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC)
- {
- zval tmp;
- zend_object_value retval;
- reflection_object *intern;
- intern = ecalloc(1, sizeof(reflection_object));
- intern->zo.ce = class_type;
- zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
- zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
- retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC);
- retval.handlers = &reflection_object_handlers;
- return retval;
- }
- static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
- {
- if (!object) {
- ALLOC_ZVAL(object);
- }
- Z_TYPE_P(object) = IS_OBJECT;
- object_init_ex(object, pce);
- Z_SET_REFCOUNT_P(object, 1);
- Z_SET_ISREF_P(object);
- return object;
- }
- static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
- static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
- static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
- static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
- static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
- /* {{{ _class_string */
- static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC)
- {
- int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0;
- string sub_indent;
-
- string_init(&sub_indent);
- string_printf(&sub_indent, "%s ", indent);
- /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */
- if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
- string_printf(str, "%s%s", indent, ce->doc_comment);
- string_write(str, "\n", 1);
- }
- if (obj) {
- string_printf(str, "%sObject of class [ ", indent);
- } else {
- string_printf(str, "%s%s [ ", indent, (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : "Class");
- }
- string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal");
- if (ce->module) {
- string_printf(str, ":%s", ce->module->name);
- }
- string_printf(str, "> ");
- if (ce->get_iterator != NULL) {
- string_printf(str, "<iterateable> ");
- }
- if (ce->ce_flags & ZEND_ACC_INTERFACE) {
- string_printf(str, "interface ");
- } else {
- if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
- string_printf(str, "abstract ");
- }
- if (ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
- string_printf(str, "final ");
- }
- string_printf(str, "class ");
- }
- string_printf(str, "%s", ce->name);
- if (ce->parent) {
- string_printf(str, " extends %s", ce->parent->name);
- }
- if (ce->num_interfaces) {
- zend_uint i;
- if (ce->ce_flags & ZEND_ACC_INTERFACE) {
- string_printf(str, " extends %s", ce->interfaces[0]->name);
- } else {
- string_printf(str, " implements %s", ce->interfaces[0]->name);
- }
- for (i = 1; i < ce->num_interfaces; ++i) {
- string_printf(str, ", %s", ce->interfaces[i]->name);
- }
- }
- string_printf(str, " ] {\n");
- /* The information where a class is declared is only available for user classes */
- if (ce->type == ZEND_USER_CLASS) {
- string_printf(str, "%s @@ %s %d-%d\n", indent, ce->filename,
- ce->line_start, ce->line_end);
- }
- /* Constants */
- if (&ce->constants_table) {
- zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
- string_printf(str, "\n");
- count = zend_hash_num_elements(&ce->constants_table);
- string_printf(str, "%s - Constants [%d] {\n", indent, count);
- if (count > 0) {
- HashPosition pos;
- zval **value;
- char *key;
- uint key_len;
- ulong num_index;
- zend_hash_internal_pointer_reset_ex(&ce->constants_table, &pos);
- while (zend_hash_get_current_data_ex(&ce->constants_table, (void **) &value, &pos) == SUCCESS) {
- zend_hash_get_current_key_ex(&ce->constants_table, &key, &key_len, &num_index, 0, &pos);
- _const_string(str, key, *value, indent TSRMLS_CC);
- zend_hash_move_forward_ex(&ce->constants_table, &pos);
- }
- }
- string_printf(str, "%s }\n", indent);
- }
- /* Static properties */
- if (&ce->properties_info) {
- /* counting static properties */
- count = zend_hash_num_elements(&ce->properties_info);
- if (count > 0) {
- HashPosition pos;
- zend_property_info *prop;
- zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
- while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
- if(prop->flags & ZEND_ACC_SHADOW) {
- count_shadow_props++;
- } else if (prop->flags & ZEND_ACC_STATIC) {
- count_static_props++;
- }
- zend_hash_move_forward_ex(&ce->properties_info, &pos);
- }
- }
- /* static properties */
- string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props);
- if (count_static_props > 0) {
- HashPosition pos;
- zend_property_info *prop;
- zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
- while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
- if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
- _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
- }
- zend_hash_move_forward_ex(&ce->properties_info, &pos);
- }
- }
- string_printf(str, "%s }\n", indent);
- }
-
- /* Static methods */
- if (&ce->function_table) {
- /* counting static methods */
- count = zend_hash_num_elements(&ce->function_table);
- if (count > 0) {
- HashPosition pos;
- zend_function *mptr;
- zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
- while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
- if (mptr->common.fn_flags & ZEND_ACC_STATIC
- && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
- {
- count_static_funcs++;
- }
- zend_hash_move_forward_ex(&ce->function_table, &pos);
- }
- }
- /* static methods */
- string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs);
- if (count_static_funcs > 0) {
- HashPosition pos;
- zend_function *mptr;
- zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
- while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
- if (mptr->common.fn_flags & ZEND_ACC_STATIC
- && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
- {
- string_printf(str, "\n");
- _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
- }
- zend_hash_move_forward_ex(&ce->function_table, &pos);
- }
- } else {
- string_printf(str, "\n");
- }
- string_printf(str, "%s }\n", indent);
- }
- /* Default/Implicit properties */
- if (&ce->properties_info) {
- count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props;
- string_printf(str, "\n%s - Properties [%d] {\n", indent, count);
- if (count > 0) {
- HashPosition pos;
- zend_property_info *prop;
- zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
- while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop, &pos) == SUCCESS) {
- if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
- _property_string(str, prop, NULL, sub_indent.string TSRMLS_CC);
- }
- zend_hash_move_forward_ex(&ce->properties_info, &pos);
- }
- }
- string_printf(str, "%s }\n", indent);
- }
- if (obj && Z_OBJ_HT_P(obj)->get_properties) {
- string dyn;
- HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
- HashPosition pos;
- zval **prop;
- string_init(&dyn);
- count = 0;
- if (properties && zend_hash_num_elements(properties)) {
- zend_hash_internal_pointer_reset_ex(properties, &pos);
- while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
- char *prop_name;
- uint prop_name_size;
- ulong index;
- if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) {
- if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */
- if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) {
- count++;
- _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC);
- }
- }
- efree(prop_name);
- }
- zend_hash_move_forward_ex(properties, &pos);
- }
- }
- string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count);
- string_append(str, &dyn);
- string_printf(str, "%s }\n", indent);
- string_free(&dyn);
- }
- /* Non static methods */
- if (&ce->function_table) {
- count = zend_hash_num_elements(&ce->function_table) - count_static_funcs;
- if (count > 0) {
- HashPosition pos;
- zend_function *mptr;
- string dyn;
- count = 0;
- string_init(&dyn);
- zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
- while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
- if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0
- && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
- {
- char *key;
- uint key_len;
- ulong num_index;
- uint len = strlen(mptr->common.function_name);
- /* Do not display old-style inherited constructors */
- if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0
- || mptr->common.scope == ce
- || zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING
- || zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0)
- {
- zend_function *closure;
- /* see if this is a closure */
- if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
- && memcmp(mptr->common.function_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
- && (closure = zend_get_closure_invoke_method(obj TSRMLS_CC)) != NULL)
- {
- mptr = closure;
- } else {
- closure = NULL;
- }
- string_printf(&dyn, "\n");
- _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
- count++;
- _free_function(closure TSRMLS_CC);
- }
- }
- zend_hash_move_forward_ex(&ce->function_table, &pos);
- }
- string_printf(str, "\n%s - Methods [%d] {", indent, count);
- if (!count) {
- string_printf(str, "\n");
- }
- string_append(str, &dyn);
- string_free(&dyn);
- } else {
- string_printf(str, "\n%s - Methods [0] {\n", indent);
- }
- string_printf(str, "%s }\n", indent);
- }
-
- string_printf(str, "%s}\n", indent);
- string_free(&sub_indent);
- }
- /* }}} */
- /* {{{ _const_string */
- static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC)
- {
- char *type;
- zval value_copy;
- int use_copy;
- type = zend_zval_type_name(value);
- zend_make_printable_zval(value, &value_copy, &use_copy);
- if (use_copy) {
- value = &value_copy;
- }
- string_printf(str, "%s Constant [ %s %s ] { %s }\n",
- indent, type, name, Z_STRVAL_P(value));
- if (use_copy) {
- zval_dtor(value);
- }
- }
- /* }}} */
- /* {{{ _get_recv_opcode */
- static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset)
- {
- zend_op *op = op_array->opcodes;
- zend_op *end = op + op_array->last;
- ++offset;
- while (op < end) {
- if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
- && op->op1.u.constant.value.lval == (long)offset)
- {
- return op;
- }
- ++op;
- }
- return NULL;
- }
- /* }}} */
- /* {{{ _parameter_string */
- 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)
- {
- string_printf(str, "Parameter #%d [ ", offset);
- if (offset >= required) {
- string_printf(str, "<optional> ");
- } else {
- string_printf(str, "<required> ");
- }
- if (arg_info->class_name) {
- string_printf(str, "%s ", arg_info->class_name);
- if (arg_info->allow_null) {
- string_printf(str, "or NULL ");
- }
- } else if (arg_info->array_type_hint) {
- string_printf(str, "array ");
- if (arg_info->allow_null) {
- string_printf(str, "or NULL ");
- }
- }
- if (arg_info->pass_by_reference) {
- string_write(str, "&", sizeof("&")-1);
- }
- if (arg_info->name) {
- string_printf(str, "$%s", arg_info->name);
- } else {
- string_printf(str, "$param%d", offset);
- }
- if (fptr->type == ZEND_USER_FUNCTION && offset >= required) {
- zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
- if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2.op_type != IS_UNUSED) {
- zval *zv, zv_copy;
- int use_copy;
- string_write(str, " = ", sizeof(" = ")-1);
- ALLOC_ZVAL(zv);
- *zv = precv->op2.u.constant;
- zval_copy_ctor(zv);
- INIT_PZVAL(zv);
- zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC);
- if (Z_TYPE_P(zv) == IS_BOOL) {
- if (Z_LVAL_P(zv)) {
- string_write(str, "true", sizeof("true")-1);
- } else {
- string_write(str, "false", sizeof("false")-1);
- }
- } else if (Z_TYPE_P(zv) == IS_NULL) {
- string_write(str, "NULL", sizeof("NULL")-1);
- } else if (Z_TYPE_P(zv) == IS_STRING) {
- string_write(str, "'", sizeof("'")-1);
- string_write(str, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 15));
- if (Z_STRLEN_P(zv) > 15) {
- string_write(str, "...", sizeof("...")-1);
- }
- string_write(str, "'", sizeof("'")-1);
- } else {
- zend_make_printable_zval(zv, &zv_copy, &use_copy);
- string_write(str, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
- if (use_copy) {
- zval_dtor(&zv_copy);
- }
- }
- zval_ptr_dtor(&zv);
- }
- }
- string_write(str, " ]", sizeof(" ]")-1);
- }
- /* }}} */
- /* {{{ _function_parameter_string */
- static void _function_parameter_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
- {
- struct _zend_arg_info *arg_info = fptr->common.arg_info;
- zend_uint i, required = fptr->common.required_num_args;
- if (!arg_info) {
- return;
- }
- string_printf(str, "\n");
- string_printf(str, "%s- Parameters [%d] {\n", indent, fptr->common.num_args);
- for (i = 0; i < fptr->common.num_args; i++) {
- string_printf(str, "%s ", indent);
- _parameter_string(str, fptr, arg_info, i, required, indent TSRMLS_CC);
- string_write(str, "\n", sizeof("\n")-1);
- arg_info++;
- }
- string_printf(str, "%s}\n", indent);
- }
- /* }}} */
- /* {{{ _function_closure_string */
- static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
- {
- zend_uint i, count;
- ulong num_index;
- char *key;
- uint key_len;
- HashTable *static_variables;
- HashPosition pos;
- if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
- return;
- }
- static_variables = fptr->op_array.static_variables;
- count = zend_hash_num_elements(static_variables);
- if (!count) {
- return;
- }
- string_printf(str, "\n");
- string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
- zend_hash_internal_pointer_reset_ex(static_variables, &pos);
- i = 0;
- while (i < count) {
- zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
- string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, key);
- zend_hash_move_forward_ex(static_variables, &pos);
- }
- string_printf(str, "%s}\n", indent);
- }
- /* }}} */
- /* {{{ _function_string */
- static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
- {
- string param_indent;
- zend_function *overwrites;
- char *lc_name;
- unsigned int lc_name_len;
- /* TBD: Repair indenting of doc comment (or is this to be done in the parser?)
- * What's "wrong" is that any whitespace before the doc comment start is
- * swallowed, leading to an unaligned comment.
- */
- if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
- string_printf(str, "%s%s\n", indent, fptr->op_array.doc_comment);
- }
- string_write(str, indent, strlen(indent));
- string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
- string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
- if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
- string_printf(str, ", deprecated");
- }
- if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
- string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
- }
- if (scope && fptr->common.scope) {
- if (fptr->common.scope != scope) {
- string_printf(str, ", inherits %s", fptr->common.scope->name);
- } else if (fptr->common.scope->parent) {
- lc_name_len = strlen(fptr->common.function_name);
- lc_name = zend_str_tolower_dup(fptr->common.function_name, lc_name_len);
- if (zend_hash_find(&fptr->common.scope->parent->function_table, lc_name, lc_name_len + 1, (void**) &overwrites) == SUCCESS) {
- if (fptr->common.scope != overwrites->common.scope) {
- string_printf(str, ", overwrites %s", overwrites->common.scope->name);
- }
- }
- efree(lc_name);
- }
- }
- if (fptr->common.prototype && fptr->common.prototype->common.scope) {
- string_printf(str, ", prototype %s", fptr->common.prototype->common.scope->name);
- }
- if (fptr->common.fn_flags & ZEND_ACC_CTOR) {
- string_printf(str, ", ctor");
- }
- if (fptr->common.fn_flags & ZEND_ACC_DTOR) {
- string_printf(str, ", dtor");
- }
- string_printf(str, "> ");
- if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
- string_printf(str, "abstract ");
- }
- if (fptr->common.fn_flags & ZEND_ACC_FINAL) {
- string_printf(str, "final ");
- }
- if (fptr->common.fn_flags & ZEND_ACC_STATIC) {
- string_printf(str, "static ");
- }
- if (fptr->common.scope) {
- /* These are mutually exclusive */
- switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PUBLIC:
- string_printf(str, "public ");
- break;
- case ZEND_ACC_PRIVATE:
- string_printf(str, "private ");
- break;
- case ZEND_ACC_PROTECTED:
- string_printf(str, "protected ");
- break;
- default:
- string_printf(str, "<visibility error> ");
- break;
- }
- string_printf(str, "method ");
- } else {
- string_printf(str, "function ");
- }
- if (fptr->op_array.return_reference) {
- string_printf(str, "&");
- }
- string_printf(str, "%s ] {\n", fptr->common.function_name);
- /* The information where a function is declared is only available for user classes */
- if (fptr->type == ZEND_USER_FUNCTION) {
- string_printf(str, "%s @@ %s %d - %d\n", indent,
- fptr->op_array.filename,
- fptr->op_array.line_start,
- fptr->op_array.line_end);
- }
- string_init(¶m_indent);
- string_printf(¶m_indent, "%s ", indent);
- if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
- _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
- }
- _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
- string_free(¶m_indent);
- string_printf(str, "%s}\n", indent);
- }
- /* }}} */
- /* {{{ _property_string */
- static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC)
- {
- char *class_name;
- string_printf(str, "%sProperty [ ", indent);
- if (!prop) {
- string_printf(str, "<dynamic> public $%s", prop_name);
- } else {
- if (!(prop->flags & ZEND_ACC_STATIC)) {
- if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
- string_write(str, "<implicit> ", sizeof("<implicit> ") - 1);
- } else {
- string_write(str, "<default> ", sizeof("<default> ") - 1);
- }
- }
-
- /* These are mutually exclusive */
- switch (prop->flags & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PUBLIC:
- string_printf(str, "public ");
- break;
- case ZEND_ACC_PRIVATE:
- string_printf(str, "private ");
- break;
- case ZEND_ACC_PROTECTED:
- string_printf(str, "protected ");
- break;
- }
- if(prop->flags & ZEND_ACC_STATIC) {
- string_printf(str, "static ");
- }
- zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
- string_printf(str, "$%s", prop_name);
- }
- string_printf(str, " ]\n");
- }
- /* }}} */
- static int _extension_ini_string(zend_ini_entry *ini_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
- {
- string *str = va_arg(args, string *);
- char *indent = va_arg(args, char *);
- int number = va_arg(args, int);
- char *comma = "";
- if (number == ini_entry->module_number) {
- string_printf(str, " %sEntry [ %s <", indent, ini_entry->name);
- if (ini_entry->modifiable == ZEND_INI_ALL) {
- string_printf(str, "ALL");
- } else {
- if (ini_entry->modifiable & ZEND_INI_USER) {
- string_printf(str, "USER");
- comma = ",";
- }
- if (ini_entry->modifiable & ZEND_INI_PERDIR) {
- string_printf(str, "%sPERDIR", comma);
- comma = ",";
- }
- if (ini_entry->modifiable & ZEND_INI_SYSTEM) {
- string_printf(str, "%sSYSTEM", comma);
- }
- }
- string_printf(str, "> ]\n");
- string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ini_entry->value : "");
- if (ini_entry->modified) {
- string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ini_entry->orig_value : "");
- }
- string_printf(str, " %s}\n", indent);
- }
- return ZEND_HASH_APPLY_KEEP;
- }
- static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
- {
- string *str = va_arg(args, string *);
- char *indent = va_arg(args, char *);
- struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
- int *num_classes = va_arg(args, int*);
- if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
- string_printf(str, "\n");
- _class_string(str, *pce, NULL, indent TSRMLS_CC);
- (*num_classes)++;
- }
- return ZEND_HASH_APPLY_KEEP;
- }
- static int _extension_const_string(zend_constant *constant TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
- {
- string *str = va_arg(args, string *);
- char *indent = va_arg(args, char *);
- struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*);
- int *num_classes = va_arg(args, int*);
- if (constant->module_number == module->module_number) {
- _const_string(str, constant->name, &constant->value, indent TSRMLS_CC);
- (*num_classes)++;
- }
- return ZEND_HASH_APPLY_KEEP;
- }
- /* {{{ _extension_string */
- static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC)
- {
- string_printf(str, "%sExtension [ ", indent);
- if (module->type == MODULE_PERSISTENT) {
- string_printf(str, "<persistent>");
- }
- if (module->type == MODULE_TEMPORARY) {
- string_printf(str, "<temporary>" );
- }
- string_printf(str, " extension #%d %s version %s ] {\n",
- module->module_number, module->name,
- (module->version == NO_VERSION_YET) ? "<no_version>" : module->version);
- if (module->deps) {
- const zend_module_dep* dep = module->deps;
- string_printf(str, "\n - Dependencies {\n");
- while(dep->name) {
- string_printf(str, "%s Dependency [ %s (", indent, dep->name);
-
- switch(dep->type) {
- case MODULE_DEP_REQUIRED:
- string_write(str, "Required", sizeof("Required") - 1);
- break;
- case MODULE_DEP_CONFLICTS:
- string_write(str, "Conflicts", sizeof("Conflicts") - 1);
- break;
- case MODULE_DEP_OPTIONAL:
- string_write(str, "Optional", sizeof("Optional") - 1);
- break;
- default:
- string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */
- break;
- }
- if (dep->rel) {
- string_printf(str, " %s", dep->rel);
- }
- if (dep->version) {
- string_printf(str, " %s", dep->version);
- }
- string_write(str, ") ]\n", sizeof(") ]\n") - 1);
- dep++;
- }
- string_printf(str, "%s }\n", indent);
- }
- {
- string str_ini;
- string_init(&str_ini);
- zend_hash_apply_with_arguments(EG(ini_directives) TSRMLS_CC, (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number);
- if (str_ini.len > 1) {
- string_printf(str, "\n - INI {\n");
- string_append(str, &str_ini);
- string_printf(str, "%s }\n", indent);
- }
- string_free(&str_ini);
- }
- {
- string str_constants;
- int num_constants = 0;
-
- string_init(&str_constants);
- zend_hash_apply_with_arguments(EG(zend_constants) TSRMLS_CC, (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants);
- if (num_constants) {
- string_printf(str, "\n - Constants [%d] {\n", num_constants);
- string_append(str, &str_constants);
- string_printf(str, "%s }\n", indent);
- }
- string_free(&str_constants);
- }
- if (module->functions && module->functions->fname) {
- zend_function *fptr;
- const zend_function_entry *func = module->functions;
- string_printf(str, "\n - Functions {\n");
- /* Is there a better way of doing this? */
- while (func->fname) {
- if (zend_hash_find(EG(function_table), func->fname, strlen(func->fname) + 1, (void**) &fptr) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname);
- func++;
- continue;
- }
-
- _function_string(str, fptr, NULL, " " TSRMLS_CC);
- func++;
- }
- string_printf(str, "%s }\n", indent);
- }
-
- {
- string str_classes;
- string sub_indent;
- int num_classes = 0;
-
- string_init(&sub_indent);
- string_printf(&sub_indent, "%s ", indent);
- string_init(&str_classes);
- 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);
- if (num_classes) {
- string_printf(str, "\n - Classes [%d] {", num_classes);
- string_append(str, &str_classes);
- string_printf(str, "%s }\n", indent);
- }
- string_free(&str_classes);
- string_free(&sub_indent);
- }
- string_printf(str, "%s}\n", indent);
- }
- /* }}} */
- /* {{{ _function_check_flag */
- static void _function_check_flag(INTERNAL_FUNCTION_PARAMETERS, int mask)
- {
- reflection_object *intern;
- zend_function *mptr;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
- GET_REFLECTION_OBJECT_PTR(mptr);
- RETURN_BOOL(mptr->common.fn_flags & mask);
- }
- /* }}} */
- /* {{{ zend_reflection_class_factory */
- PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC)
- {
- reflection_object *intern;
- zval *name;
- MAKE_STD_ZVAL(name);
- ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
- reflection_instantiate(reflection_class_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- intern->ptr = ce;
- intern->ref_type = REF_TYPE_OTHER;
- intern->ce = ce;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ reflection_extension_factory */
- static void reflection_extension_factory(zval *object, const char *name_str TSRMLS_DC)
- {
- reflection_object *intern;
- zval *name;
- int name_len = strlen(name_str);
- char *lcname;
- struct _zend_module_entry *module;
- ALLOCA_FLAG(use_heap)
- lcname = do_alloca(name_len + 1, use_heap);
- zend_str_tolower_copy(lcname, name_str, name_len);
- if (zend_hash_find(&module_registry, lcname, name_len + 1, (void **)&module) == FAILURE) {
- free_alloca(lcname, use_heap);
- return;
- }
- free_alloca(lcname, use_heap);
- reflection_instantiate(reflection_extension_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- MAKE_STD_ZVAL(name);
- ZVAL_STRINGL(name, module->name, name_len, 1);
- intern->ptr = module;
- intern->ref_type = REF_TYPE_OTHER;
- intern->ce = NULL;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ reflection_parameter_factory */
- 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)
- {
- reflection_object *intern;
- parameter_reference *reference;
- zval *name;
- if (closure_object) {
- Z_ADDREF_P(closure_object);
- }
- MAKE_STD_ZVAL(name);
- if (arg_info->name) {
- ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
- } else {
- ZVAL_NULL(name);
- }
- reflection_instantiate(reflection_parameter_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- reference = (parameter_reference*) emalloc(sizeof(parameter_reference));
- reference->arg_info = arg_info;
- reference->offset = offset;
- reference->required = required;
- reference->fptr = fptr;
- intern->ptr = reference;
- intern->ref_type = REF_TYPE_PARAMETER;
- intern->ce = fptr->common.scope;
- intern->obj = closure_object;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ reflection_function_factory */
- static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
- {
- reflection_object *intern;
- zval *name;
- if (closure_object) {
- Z_ADDREF_P(closure_object);
- }
- MAKE_STD_ZVAL(name);
- ZVAL_STRING(name, function->common.function_name, 1);
- reflection_instantiate(reflection_function_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- intern->ptr = function;
- intern->ref_type = REF_TYPE_FUNCTION;
- intern->ce = NULL;
- intern->obj = closure_object;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ reflection_method_factory */
- static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
- {
- reflection_object *intern;
- zval *name;
- zval *classname;
- if (closure_object) {
- Z_ADDREF_P(closure_object);
- }
- MAKE_STD_ZVAL(name);
- MAKE_STD_ZVAL(classname);
- ZVAL_STRING(name, method->common.function_name, 1);
- ZVAL_STRINGL(classname, method->common.scope->name, method->common.scope->name_length, 1);
- reflection_instantiate(reflection_method_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- intern->ptr = method;
- intern->ref_type = REF_TYPE_FUNCTION;
- intern->ce = ce;
- intern->obj = closure_object;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ reflection_property_factory */
- static void reflection_property_factory(zend_class_entry *ce, zend_property_info *prop, zval *object TSRMLS_DC)
- {
- reflection_object *intern;
- zval *name;
- zval *classname;
- property_reference *reference;
- char *class_name, *prop_name;
- zend_unmangle_property_name(prop->name, prop->name_length, &class_name, &prop_name);
- if (!(prop->flags & ZEND_ACC_PRIVATE)) {
- /* we have to search the class hierarchy for this (implicit) public or protected property */
- zend_class_entry *tmp_ce = ce, *store_ce = ce;
- zend_property_info *tmp_info = NULL;
- while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) {
- ce = tmp_ce;
- tmp_ce = tmp_ce->parent;
- }
- if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
- prop = tmp_info;
- } else { /* not found, use initial value */
- ce = store_ce;
- }
- }
- MAKE_STD_ZVAL(name);
- MAKE_STD_ZVAL(classname);
- ZVAL_STRING(name, prop_name, 1);
- ZVAL_STRINGL(classname, prop->ce->name, prop->ce->name_length, 1);
- reflection_instantiate(reflection_property_ptr, object TSRMLS_CC);
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- reference = (property_reference*) emalloc(sizeof(property_reference));
- reference->ce = ce;
- reference->prop = *prop;
- intern->ptr = reference;
- intern->ref_type = REF_TYPE_PROPERTY;
- intern->ce = ce;
- intern->ignore_visibility = 0;
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
- }
- /* }}} */
- /* {{{ _reflection_export */
- static void _reflection_export(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_ptr, int ctor_argc)
- {
- zval *reflector_ptr;
- zval output, *output_ptr = &output;
- zval *argument_ptr, *argument2_ptr;
- zval *retval_ptr, **params[2];
- int result;
- int return_output = 0;
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
- zval fname;
- if (ctor_argc == 1) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &argument_ptr, &return_output) == FAILURE) {
- return;
- }
- } else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &argument_ptr, &argument2_ptr, &return_output) == FAILURE) {
- return;
- }
- }
- INIT_PZVAL(&output);
- /* Create object */
- MAKE_STD_ZVAL(reflector_ptr);
- if (object_and_properties_init(reflector_ptr, ce_ptr, NULL) == FAILURE) {
- _DO_THROW("Could not create reflector");
- }
- /* Call __construct() */
- params[0] = &argument_ptr;
- params[1] = &argument2_ptr;
- fci.size = sizeof(fci);
- fci.function_table = NULL;
- fci.function_name = NULL;
- fci.symbol_table = NULL;
- fci.object_ptr = reflector_ptr;
- fci.retval_ptr_ptr = &retval_ptr;
- fci.param_count = ctor_argc;
- fci.params = params;
- fci.no_separation = 1;
- fcc.initialized = 1;
- fcc.function_handler = ce_ptr->constructor;
- fcc.calling_scope = ce_ptr;
- fcc.called_scope = Z_OBJCE_P(reflector_ptr);
- fcc.object_ptr = reflector_ptr;
- result = zend_call_function(&fci, &fcc TSRMLS_CC);
-
- if (retval_ptr) {
- zval_ptr_dtor(&retval_ptr);
- }
- if (EG(exception)) {
- zval_ptr_dtor(&reflector_ptr);
- return;
- }
- if (result == FAILURE) {
- zval_ptr_dtor(&reflector_ptr);
- _DO_THROW("Could not create reflector");
- }
- /* Call static reflection::export */
- ZVAL_BOOL(&output, return_output);
- params[0] = &reflector_ptr;
- params[1] = &output_ptr;
- ZVAL_STRINGL(&fname, "reflection::export", sizeof("reflection::export") - 1, 0);
- fci.function_table = &reflection_ptr->function_table;
- fci.function_name = &fname;
- fci.object_ptr = NULL;
- fci.retval_ptr_ptr = &retval_ptr;
- fci.param_count = 2;
- fci.params = params;
- fci.no_separation = 1;
- result = zend_call_function(&fci, NULL TSRMLS_CC);
- if (result == FAILURE && EG(exception) == NULL) {
- zval_ptr_dtor(&reflector_ptr);
- zval_ptr_dtor(&retval_ptr);
- _DO_THROW("Could not execute reflection::export()");
- }
- if (return_output) {
- COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
- } else {
- zval_ptr_dtor(&retval_ptr);
- }
- /* Destruct reflector which is no longer needed */
- zval_ptr_dtor(&reflector_ptr);
- }
- /* }}} */
- /* {{{ Preventing __clone from being called */
- ZEND_METHOD(reflection, __clone)
- {
- /* Should never be executable */
- _DO_THROW("Cannot clone object using __clone()");
- }
- /* }}} */
- /* {{{ proto public static mixed Reflection::export(Reflector r [, bool return])
- Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
- ZEND_METHOD(reflection, export)
- {
- zval *object, fname, *retval_ptr;
- int result;
- zend_bool return_output = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|b", &object, reflector_ptr, &return_output) == FAILURE) {
- return;
- }
- /* Invoke the __toString() method */
- ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring") - 1, 1);
- result= call_user_function_ex(NULL, &object, &fname, &retval_ptr, 0, NULL, 0, NULL TSRMLS_CC);
- zval_dtor(&fname);
- if (result == FAILURE) {
- _DO_THROW("Invocation of method __toString() failed");
- /* Returns from this function */
- }
- if (!retval_ptr) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
- RETURN_FALSE;
- }
- if (return_output) {
- COPY_PZVAL_TO_ZVAL(*return_value, retval_ptr);
- } else {
- /* No need for _r variant, return of __toString should always be a string */
- zend_print_zval(retval_ptr, 0);
- zend_printf("\n");
- zval_ptr_dtor(&retval_ptr);
- }
- }
- /* }}} */
- /* {{{ proto public static array Reflection::getModifierNames(int modifiers)
- Returns an array of modifier names */
- ZEND_METHOD(reflection, getModifierNames)
- {
- long modifiers;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &modifiers) == FAILURE) {
- return;
- }
- array_init(return_value);
- if (modifiers & (ZEND_ACC_ABSTRACT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
- add_next_index_stringl(return_value, "abstract", sizeof("abstract")-1, 1);
- }
- if (modifiers & (ZEND_ACC_FINAL | ZEND_ACC_FINAL_CLASS)) {
- add_next_index_stringl(return_value, "final", sizeof("final")-1, 1);
- }
- if (modifiers & ZEND_ACC_IMPLICIT_PUBLIC) {
- add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
- }
- /* These are mutually exclusive */
- switch (modifiers & ZEND_ACC_PPP_MASK) {
- case ZEND_ACC_PUBLIC:
- add_next_index_stringl(return_value, "public", sizeof("public")-1, 1);
- break;
- case ZEND_ACC_PRIVATE:
- add_next_index_stringl(return_value, "private", sizeof("private")-1, 1);
- break;
- case ZEND_ACC_PROTECTED:
- add_next_index_stringl(return_value, "protected", sizeof("protected")-1, 1);
- break;
- }
- if (modifiers & ZEND_ACC_STATIC) {
- add_next_index_stringl(return_value, "static", sizeof("static")-1, 1);
- }
- }
- /* }}} */
- /* {{{ proto public static mixed ReflectionFunction::export(string name [, bool return])
- Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */
- ZEND_METHOD(reflection_function, export)
- {
- _reflection_export(INTERNAL_FUNCTION_PARAM_PASSTHRU, reflection_function_ptr, 1);
- }
- /* }}} */
- /* {{{ proto public void ReflectionFunction::__construct(string name)
- Constructor. Throws an Exception in case the given function does not exist */
- ZEND_METHOD(reflection_function, __construct)
- {
- zval *name;
- zval *object;
- zval *closure = NULL;
- char *lcname;
- reflection_object *intern;
- zend_function *fptr;
- char *name_str;
- int name_len;
- object = getThis();
- intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
- if (intern == NULL) {
- return;
- }
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "O", &closure, zend_ce_closure) == SUCCESS) {
- fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC);
- Z_ADDREF_P(closure);
- } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) {
- char *nsname;
- lcname = zend_str_tolower_dup(name_str, name_len);
- /* Ignore leading "\" */
- nsname = lcname;
- if (lcname[0] == '\\') {
- nsname = &lcname[1];
- name_len--;
- }
-
- if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) {
- efree(lcname);
- zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Function %s() does not exist", name_str);
- return;
- }
- efree(lcname);
- } else {
- return;
- }
- MAKE_STD_ZVAL(name);
- ZVAL_STRING(name, fptr->common.function_name, 1);
- zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
- intern->ptr = fptr;
- intern->ref_type = REF_TYPE_FUNCTION;
- intern->obj = closure;
- intern->ce = NULL;
- }
- /* }}} */
- /* {{{ proto public string ReflectionFunction::__toString()
- Returns a string representation */
- ZEND_METHOD(reflection_function, __toString)
- {
- reflection_object *intern;
- zend_function *fptr;
- string str;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
- GET_REFLECTION_OBJECT_PTR(fptr);
- string_init(&str);
- _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
- RETURN_STRINGL(str.string, str.len - 1, 0);
- }
- /* }}} */
- /* {{{ proto public string ReflectionFunction::getName()
- Returns this function's name */
- ZEND_METHOD(reflection_function, getName)
- {
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
- _default_get_entry(getThis(), "name", sizeof("name"), return_value TSRMLS_CC);
- }
- /* }}} */
- /* {{{ proto public bool ReflectionFunction::isClosure()
- Returns whether this is a closure */
- ZEND_METHOD(reflection_function, isClosure)
- {
- reflection_object *intern;
- zend_function *fptr;
- if (…
Large files files are truncated, but you can click here to view the full file