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 /Zend/zend_interfaces.c | |
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 'Zend/zend_interfaces.c')
-rw-r--r-- | Zend/zend_interfaces.c | 61 |
1 files changed, 16 insertions, 45 deletions
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 6ad81c0805..2a6d70dc58 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -32,12 +32,10 @@ ZEND_API zend_class_entry *zend_ce_stringable; /* {{{ zend_call_method Only returns the returned zval if retval_ptr != NULL */ -ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2) +ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, uint32_t param_count, zval* arg1, zval* arg2) { - int result; - zend_fcall_info fci; - zend_fcall_info_cache fcic; - zval retval; + zend_function *fn; + zend_class_entry *called_scope; zval params[2]; if (param_count > 0) { @@ -47,68 +45,43 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z ZVAL_COPY_VALUE(¶ms[1], arg2); } - 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 */ - if (!obj_ce) { obj_ce = object ? object->ce : NULL; } if (!fn_proxy || !*fn_proxy) { if (EXPECTED(obj_ce)) { - fcic.function_handler = zend_hash_str_find_ptr( + fn = zend_hash_str_find_ptr( &obj_ce->function_table, function_name, function_name_len); - if (UNEXPECTED(fcic.function_handler == NULL)) { + if (UNEXPECTED(fn == NULL)) { /* error at c-level */ zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name); } } else { - fcic.function_handler = zend_fetch_function_str(function_name, function_name_len); - if (UNEXPECTED(fcic.function_handler == NULL)) { + fn = zend_fetch_function_str(function_name, function_name_len); + if (UNEXPECTED(fn == NULL)) { /* error at c-level */ zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name); } } if (fn_proxy) { - *fn_proxy = fcic.function_handler; + *fn_proxy = fn; } } else { - fcic.function_handler = *fn_proxy; + fn = *fn_proxy; } if (object) { - fcic.called_scope = object->ce; + called_scope = object->ce; } else { - zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data)); - + called_scope = zend_get_called_scope(EG(current_execute_data)); if (obj_ce && (!called_scope || !instanceof_function(called_scope, obj_ce))) { - fcic.called_scope = obj_ce; - } else { - fcic.called_scope = called_scope; + called_scope = obj_ce; } } - fcic.object = object; - result = zend_call_function(&fci, &fcic); - if (result == FAILURE) { - /* error at c-level */ - if (!obj_ce) { - obj_ce = object ? object->ce : NULL; - } - if (!EG(exception)) { - zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", function_name); - } - } - if (!retval_ptr) { - zval_ptr_dtor(&retval); - return NULL; - } + zend_call_known_function(fn, object, called_scope, retval_ptr, param_count, params); return retval_ptr; } /* }}} */ @@ -390,8 +363,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *b zval retval; int result; - zend_call_method_with_0_params(Z_OBJ_P(object), ce, &ce->serialize_func, "serialize", &retval); - + zend_call_known_instance_method_with_0_params(ce->serialize_func, Z_OBJ_P(object), &retval); if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) { result = FAILURE; @@ -430,9 +402,8 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns } ZVAL_STRINGL(&zdata, (char*)buf, buf_len); - - zend_call_method_with_1_params(Z_OBJ_P(object), ce, &ce->unserialize_func, "unserialize", NULL, &zdata); - + zend_call_known_instance_method_with_1_params( + ce->unserialize_func, Z_OBJ_P(object), NULL, &zdata); zval_ptr_dtor(&zdata); if (EG(exception)) { |