summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c92
1 files changed, 65 insertions, 27 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index f6367cdb4e..dc76d2fe0f 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2014 The PHP Group |
+ | Copyright (c) 1997-2015 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 |
@@ -1007,9 +1007,12 @@ static int _extension_class_string(zend_class_entry **pce TSRMLS_DC, int num_arg
int *num_classes = va_arg(args, int*);
if (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) {
- string_printf(str, "\n");
- _class_string(str, *pce, NULL, indent TSRMLS_CC);
- (*num_classes)++;
+ /* dump class if it is not an alias */
+ if (!zend_binary_strcasecmp((*pce)->name, (*pce)->name_length, hash_key->arKey, hash_key->nKeyLength-1)) {
+ string_printf(str, "\n");
+ _class_string(str, *pce, NULL, indent TSRMLS_CC);
+ (*num_classes)++;
+ }
}
return ZEND_HASH_APPLY_KEEP;
}
@@ -3084,6 +3087,14 @@ ZEND_METHOD(reflection_function, isDeprecated)
}
/* }}} */
+/* {{{ proto public bool ReflectionFunction::isGenerator()
+ Returns whether this function is a generator */
+ZEND_METHOD(reflection_function, isGenerator)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_GENERATOR);
+}
+/* }}} */
+
/* {{{ proto public bool ReflectionFunction::inNamespace()
Returns whether this function is defined in namespace */
ZEND_METHOD(reflection_function, inNamespace)
@@ -4182,32 +4193,40 @@ ZEND_METHOD(reflection_class, newInstance)
{
zval *retval_ptr = NULL;
reflection_object *intern;
- zend_class_entry *ce;
+ zend_class_entry *ce, *old_scope;
+ zend_function *constructor;
METHOD_NOTSTATIC(reflection_class_ptr);
GET_REFLECTION_OBJECT_PTR(ce);
+ object_init_ex(return_value, ce);
+
+ old_scope = EG(scope);
+ EG(scope) = ce;
+ constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC);
+ EG(scope) = old_scope;
+
/* Run the constructor if there is one */
- if (ce->constructor) {
+ if (constructor) {
zval ***params = NULL;
int num_args = 0;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
- if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
- return;
+ zval_dtor(return_value);
+ RETURN_NULL();
}
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
if (params) {
efree(params);
}
+ zval_dtor(return_value);
RETURN_FALSE;
}
- object_init_ex(return_value, ce);
-
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
@@ -4219,7 +4238,7 @@ ZEND_METHOD(reflection_class, newInstance)
fci.no_separation = 1;
fcc.initialized = 1;
- fcc.function_handler = ce->constructor;
+ fcc.function_handler = constructor;
fcc.calling_scope = EG(scope);
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object_ptr = return_value;
@@ -4232,6 +4251,7 @@ ZEND_METHOD(reflection_class, newInstance)
zval_ptr_dtor(&retval_ptr);
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ zval_dtor(return_value);
RETURN_NULL();
}
if (retval_ptr) {
@@ -4240,9 +4260,7 @@ ZEND_METHOD(reflection_class, newInstance)
if (params) {
efree(params);
}
- } else if (!ZEND_NUM_ARGS()) {
- object_init_ex(return_value, ce);
- } else {
+ } else if (ZEND_NUM_ARGS()) {
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);
}
}
@@ -4272,9 +4290,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
{
zval *retval_ptr = NULL;
reflection_object *intern;
- zend_class_entry *ce;
+ zend_class_entry *ce, *old_scope;
int argc = 0;
HashTable *args;
+ zend_function *constructor;
METHOD_NOTSTATIC(reflection_class_ptr);
@@ -4283,19 +4302,28 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
return;
}
+
if (ZEND_NUM_ARGS() > 0) {
argc = args->nNumOfElements;
}
+ object_init_ex(return_value, ce);
+
+ old_scope = EG(scope);
+ EG(scope) = ce;
+ constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC);
+ EG(scope) = old_scope;
+
/* Run the constructor if there is one */
- if (ce->constructor) {
+ if (constructor) {
zval ***params = NULL;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
- if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
- return;
+ zval_dtor(return_value);
+ RETURN_NULL();
}
if (argc) {
@@ -4304,8 +4332,6 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
params -= argc;
}
- object_init_ex(return_value, ce);
-
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
@@ -4317,7 +4343,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
fci.no_separation = 1;
fcc.initialized = 1;
- fcc.function_handler = ce->constructor;
+ fcc.function_handler = constructor;
fcc.calling_scope = EG(scope);
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object_ptr = return_value;
@@ -4330,6 +4356,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
zval_ptr_dtor(&retval_ptr);
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ zval_dtor(return_value);
RETURN_NULL();
}
if (retval_ptr) {
@@ -4338,9 +4365,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
if (params) {
efree(params);
}
- } else if (!ZEND_NUM_ARGS() || !argc) {
- object_init_ex(return_value, ce);
- } else {
+ } else if (argc) {
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);
}
}
@@ -5338,12 +5363,24 @@ static int add_extension_class(zend_class_entry **pce TSRMLS_DC, int num_args, v
int add_reflection_class = va_arg(args, int);
if (((*pce)->type == ZEND_INTERNAL_CLASS) && (*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, module->name)) {
+ const char *name;
+ int nlen;
+
+ if (zend_binary_strcasecmp((*pce)->name, (*pce)->name_length, hash_key->arKey, hash_key->nKeyLength-1)) {
+ /* This is an class alias, use alias name */
+ name = hash_key->arKey;
+ nlen = hash_key->nKeyLength-1;
+ } else {
+ /* Use class name */
+ name = (*pce)->name;
+ nlen = (*pce)->name_length;
+ }
if (add_reflection_class) {
ALLOC_ZVAL(zclass);
zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
- add_assoc_zval_ex(class_array, (*pce)->name, (*pce)->name_length + 1, zclass);
+ add_assoc_zval_ex(class_array, name, nlen+1, zclass);
} else {
- add_next_index_stringl(class_array, (*pce)->name, (*pce)->name_length, 1);
+ add_next_index_stringl(class_array, name, nlen, 1);
}
}
return ZEND_HASH_APPLY_KEEP;
@@ -5683,6 +5720,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = {
ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
@@ -6023,7 +6061,7 @@ ZEND_END_ARG_INFO()
static const zend_function_entry reflection_zend_extension_functions[] = {
ZEND_ME(reflection, __clone, arginfo_reflection__void, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
ZEND_ME(reflection_zend_extension, export, arginfo_reflection_extension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
- ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_extension___construct, 0)
+ ZEND_ME(reflection_zend_extension, __construct, arginfo_reflection_zend_extension___construct, 0)
ZEND_ME(reflection_zend_extension, __toString, arginfo_reflection__void, 0)
ZEND_ME(reflection_zend_extension, getName, arginfo_reflection__void, 0)
ZEND_ME(reflection_zend_extension, getVersion, arginfo_reflection__void, 0)