summaryrefslogtreecommitdiff
path: root/ext
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
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')
-rw-r--r--ext/intl/calendar/calendar_methods.cpp6
-rw-r--r--ext/intl/timezone/timezone_class.cpp3
-rw-r--r--ext/phar/phar_object.c22
-rw-r--r--ext/reflection/php_reflection.c84
4 files changed, 26 insertions, 89 deletions
diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp
index 45fe97d509..186c2597f4 100644
--- a/ext/intl/calendar/calendar_methods.cpp
+++ b/ext/intl/calendar/calendar_methods.cpp
@@ -1016,7 +1016,8 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time)
if (!(Z_TYPE_P(zv_arg) == IS_OBJECT && instanceof_function(
Z_OBJCE_P(zv_arg), php_date_get_date_ce()))) {
object_init_ex(&zv_tmp, php_date_get_date_ce());
- zend_call_method_with_1_params(Z_OBJ(zv_tmp), NULL, &Z_OBJCE(zv_tmp)->constructor, "__construct", NULL, zv_arg);
+ zend_call_known_instance_method_with_1_params(
+ Z_OBJCE(zv_tmp)->constructor, Z_OBJ(zv_tmp), NULL, zv_arg);
zv_datetime = &zv_tmp;
if (EG(exception)) {
zend_object_store_ctor_failed(Z_OBJ(zv_tmp));
@@ -1130,7 +1131,8 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
/* Finally, instantiate object and call constructor */
object_init_ex(return_value, php_date_get_date_ce());
- zend_call_method_with_2_params(Z_OBJ_P(return_value), NULL, &Z_OBJCE_P(return_value)->constructor, "__construct", NULL, &ts_zval, timezone_zval);
+ zend_call_known_instance_method_with_2_params(
+ Z_OBJCE_P(return_value)->constructor, Z_OBJ_P(return_value), NULL, &ts_zval, timezone_zval);
if (EG(exception)) {
intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
"intlcal_to_date_time: DateTime constructor has thrown exception",
diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp
index b3d447f5d5..63d5b05746 100644
--- a/ext/intl/timezone/timezone_class.cpp
+++ b/ext/intl/timezone/timezone_class.cpp
@@ -96,7 +96,8 @@ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone,
goto error;
}
ZVAL_STR(&arg, u8str);
- zend_call_method_with_1_params(Z_OBJ_P(ret), NULL, &Z_OBJCE_P(ret)->constructor, "__construct", NULL, &arg);
+ zend_call_known_instance_method_with_1_params(
+ Z_OBJCE_P(ret)->constructor, Z_OBJ_P(ret), NULL, &arg);
if (EG(exception)) {
spprintf(&message, 0,
"%s: DateTimeZone constructor threw exception", func);
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 351d342c53..d273e1d519 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1242,8 +1242,8 @@ PHP_METHOD(Phar, __construct)
ZVAL_STRINGL(&arg1, fname, fname_len);
ZVAL_LONG(&arg2, flags);
- zend_call_method_with_2_params(Z_OBJ_P(zobj), Z_OBJCE_P(zobj),
- &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2);
+ zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor,
+ Z_OBJ_P(zobj), NULL, &arg1, &arg2);
zval_ptr_dtor(&arg1);
@@ -1764,8 +1764,8 @@ PHP_METHOD(Phar, buildFromDirectory)
ZVAL_STRINGL(&arg, dir, dir_len);
ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
- zend_call_method_with_2_params(Z_OBJ(iter), spl_ce_RecursiveDirectoryIterator,
- &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
+ zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor,
+ Z_OBJ(iter), NULL, &arg, &arg2);
zval_ptr_dtor(&arg);
if (EG(exception)) {
@@ -1780,8 +1780,8 @@ PHP_METHOD(Phar, buildFromDirectory)
RETURN_THROWS();
}
- zend_call_method_with_1_params(Z_OBJ(iteriter), spl_ce_RecursiveIteratorIterator,
- &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, &iter);
+ zend_call_known_instance_method_with_1_params(spl_ce_RecursiveIteratorIterator->constructor,
+ Z_OBJ(iteriter), NULL, &iter);
if (EG(exception)) {
zval_ptr_dtor(&iter);
@@ -1803,8 +1803,8 @@ PHP_METHOD(Phar, buildFromDirectory)
ZVAL_STRINGL(&arg2, regex, regex_len);
- zend_call_method_with_2_params(Z_OBJ(regexiter), spl_ce_RegexIterator,
- &spl_ce_RegexIterator->constructor, "__construct", NULL, &iteriter, &arg2);
+ zend_call_known_instance_method_with_2_params(spl_ce_RegexIterator->constructor,
+ Z_OBJ(regexiter), NULL, &iteriter, &arg2);
zval_ptr_dtor(&arg2);
}
@@ -2256,7 +2256,7 @@ its_ok:
ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len);
- zend_call_method_with_1_params(Z_OBJ(ret), ce, &ce->constructor, "__construct", NULL, &arg1);
+ zend_call_known_instance_method_with_1_params(ce->constructor, Z_OBJ(ret), NULL, &arg1);
zval_ptr_dtor(&arg1);
return Z_OBJ(ret);
}
@@ -4539,8 +4539,8 @@ PHP_METHOD(PharFileInfo, __construct)
ZVAL_STRINGL(&arg1, fname, fname_len);
- zend_call_method_with_1_params(Z_OBJ_P(zobj), Z_OBJCE_P(zobj),
- &spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1);
+ zend_call_known_instance_method_with_1_params(spl_ce_SplFileInfo->constructor,
+ Z_OBJ_P(zobj), NULL, &arg1);
zval_ptr_dtor(&arg1);
}
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;
}
/* }}} */