summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-06-08 17:10:24 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-06-09 16:21:54 +0200
commit257dbb04501391e0ac57e66aebe2e4d25dcc5c91 (patch)
tree2ea10373c366bc81468d3172ed49fb4860741a90 /ext/reflection/php_reflection.c
parentbcada03f48b242930ded84d66c1f0b826176f696 (diff)
downloadphp-git-257dbb04501391e0ac57e66aebe2e4d25dcc5c91.tar.gz
Add zend_call_known_function() API family
This adds the following APIs: void zend_call_known_function( zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr, int param_count, zval *params); void zend_call_known_instance_method( zend_function *fn, zend_object *object, zval *retval_ptr, int param_count, zval *params); void zend_call_known_instance_method_with_0_params( zend_function *fn, zend_object *object, zval *retval_ptr); void zend_call_known_instance_method_with_1_params( zend_function *fn, zend_object *object, zval *retval_ptr, zval *param); void zend_call_known_instance_method_with_2_params( zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2); These are used to perform a call if you already have the zend_function you want to call. zend_call_known_function() is the base API, the rest are just really thin wrappers around it for the common case of instance method calls. Closes GH-5692.
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c84
1 files changed, 9 insertions, 75 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index e7296b8008..1f29ff59e4 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -4754,7 +4754,6 @@ ZEND_METHOD(ReflectionClass, isInstance)
Returns an instance of this class */
ZEND_METHOD(ReflectionClass, newInstance)
{
- zval retval;
reflection_object *intern;
zend_class_entry *ce, *old_scope;
zend_function *constructor;
@@ -4773,9 +4772,7 @@ ZEND_METHOD(ReflectionClass, newInstance)
/* Run the constructor if there is one */
if (constructor) {
zval *params = NULL;
- int ret, i, num_args = 0;
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
+ int i, num_args = 0;
if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
@@ -4792,20 +4789,8 @@ ZEND_METHOD(ReflectionClass, newInstance)
Z_TRY_ADDREF(params[i]);
}
- fci.size = sizeof(fci);
- ZVAL_UNDEF(&fci.function_name);
- fci.object = Z_OBJ_P(return_value);
- fci.retval = &retval;
- fci.param_count = num_args;
- fci.params = params;
- fci.no_separation = 1;
-
- fcc.function_handler = constructor;
- fcc.called_scope = Z_OBJCE_P(return_value);
- fcc.object = Z_OBJ_P(return_value);
+ zend_call_known_instance_method(constructor, Z_OBJ_P(return_value), NULL, num_args, params);
- ret = zend_call_function(&fci, &fcc);
- zval_ptr_dtor(&retval);
for (i = 0; i < num_args; i++) {
zval_ptr_dtor(&params[i]);
}
@@ -4813,11 +4798,6 @@ ZEND_METHOD(ReflectionClass, newInstance)
if (EG(exception)) {
zend_object_store_ctor_failed(Z_OBJ_P(return_value));
}
- if (ret == FAILURE) {
- php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
- zval_ptr_dtor(return_value);
- RETURN_NULL();
- }
} else if (ZEND_NUM_ARGS()) {
zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
}
@@ -4851,10 +4831,10 @@ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor)
Returns an instance of this class */
ZEND_METHOD(ReflectionClass, newInstanceArgs)
{
- zval retval, *val;
+ zval *val;
reflection_object *intern;
zend_class_entry *ce, *old_scope;
- int ret, i, argc = 0;
+ int i, argc = 0;
HashTable *args;
zend_function *constructor;
@@ -4880,8 +4860,6 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
/* Run the constructor if there is one */
if (constructor) {
zval *params = NULL;
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
@@ -4898,20 +4876,8 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
} ZEND_HASH_FOREACH_END();
}
- fci.size = sizeof(fci);
- ZVAL_UNDEF(&fci.function_name);
- fci.object = Z_OBJ_P(return_value);
- fci.retval = &retval;
- fci.param_count = argc;
- fci.params = params;
- fci.no_separation = 1;
+ zend_call_known_instance_method(constructor, Z_OBJ_P(return_value), NULL, argc, params);
- fcc.function_handler = constructor;
- fcc.called_scope = Z_OBJCE_P(return_value);
- fcc.object = Z_OBJ_P(return_value);
-
- ret = zend_call_function(&fci, &fcc);
- zval_ptr_dtor(&retval);
if (params) {
for (i = 0; i < argc; i++) {
zval_ptr_dtor(&params[i]);
@@ -4922,12 +4888,6 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
if (EG(exception)) {
zend_object_store_ctor_failed(Z_OBJ_P(return_value));
}
- if (ret == FAILURE) {
- zval_ptr_dtor(&retval);
- php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
- zval_ptr_dtor(return_value);
- RETURN_NULL();
- }
} else if (argc) {
zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
}
@@ -6487,15 +6447,7 @@ ZEND_METHOD(ReflectionAttribute, getArguments)
static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zval *args, uint32_t argc) /* {{{ */
{
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
-
- zend_function *ctor;
- zval retval;
- int ret;
-
- ctor = ce->constructor;
-
+ zend_function *ctor = ce->constructor;
ZEND_ASSERT(ctor != NULL);
if (!(ctor->common.fn_flags & ZEND_ACC_PUBLIC)) {
@@ -6503,31 +6455,13 @@ static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zv
return FAILURE;
}
- fci.size = sizeof(fci);
- ZVAL_UNDEF(&fci.function_name);
- fci.object = obj;
- fci.retval = &retval;
- fci.params = args;
- fci.param_count = argc;
- fci.no_separation = 1;
-
- fcc.function_handler = ctor;
- fcc.called_scope = ce;
- fcc.object = obj;
-
- ret = zend_call_function(&fci, &fcc);
-
+ zend_call_known_instance_method(ctor, obj, NULL, argc, args);
if (EG(exception)) {
zend_object_store_ctor_failed(obj);
+ return FAILURE;
}
- zval_ptr_dtor(&retval);
-
- if (ret != SUCCESS) {
- zend_throw_error(NULL, "Failed to invoke constructor of attribute class '%s'", ZSTR_VAL(ce->name));
- }
-
- return EG(exception) ? FAILURE : SUCCESS;
+ return SUCCESS;
}
/* }}} */