diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-08 17:10:24 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-09 16:21:54 +0200 |
commit | 257dbb04501391e0ac57e66aebe2e4d25dcc5c91 (patch) | |
tree | 2ea10373c366bc81468d3172ed49fb4860741a90 /ext | |
parent | bcada03f48b242930ded84d66c1f0b826176f696 (diff) | |
download | php-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.cpp | 6 | ||||
-rw-r--r-- | ext/intl/timezone/timezone_class.cpp | 3 | ||||
-rw-r--r-- | ext/phar/phar_object.c | 22 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 84 |
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(¶ms[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(¶ms[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; } /* }}} */ |