summaryrefslogtreecommitdiff
path: root/Zend/zend_execute_API.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 /Zend/zend_execute_API.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 'Zend/zend_execute_API.c')
-rw-r--r--Zend/zend_execute_API.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 1b48bed125..c5626a0df3 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -861,6 +861,51 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
}
/* }}} */
+ZEND_API void zend_call_known_function(
+ zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
+ uint32_t param_count, zval *params)
+{
+ zval retval;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcic;
+
+ ZEND_ASSERT(fn && "zend_function must be passed!");
+
+ fci.size = sizeof(fci);
+ fci.object = object;
+ fci.retval = retval_ptr ? retval_ptr : &retval;
+ fci.param_count = param_count;
+ fci.params = params;
+ fci.no_separation = 1;
+ ZVAL_UNDEF(&fci.function_name); /* Unused */
+
+ fcic.function_handler = fn;
+ fcic.object = object;
+ fcic.called_scope = called_scope;
+
+ int result = zend_call_function(&fci, &fcic);
+ if (UNEXPECTED(result == FAILURE)) {
+ if (!EG(exception)) {
+ zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
+ fn->common.scope ? ZSTR_VAL(fn->common.scope->name) : "",
+ fn->common.scope ? "::" : "", ZSTR_VAL(fn->common.function_name));
+ }
+ }
+
+ if (!retval_ptr) {
+ zval_ptr_dtor(&retval);
+ }
+}
+
+ZEND_API void zend_call_known_instance_method_with_2_params(
+ zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2)
+{
+ zval params[2];
+ ZVAL_COPY_VALUE(&params[0], param1);
+ ZVAL_COPY_VALUE(&params[1], param2);
+ zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
+}
+
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
{
zend_class_entry *ce = NULL;