Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,37 @@ ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *f

ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache);

/* Call the provided zend_function with the given params.
* If retval_ptr is NULL, the return value is discarded.
* If object is NULL, this must be a free function or static call.
* called_scope must be provided for instance and static method calls. */
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);

/* Call the provided zend_function instance method on an object. */
static zend_always_inline void zend_call_known_instance_method(
zend_function *fn, zend_object *object, zval *retval_ptr,
uint32_t param_count, zval *params)
{
zend_call_known_function(fn, object, object->ce, retval_ptr, param_count, params);
}

static zend_always_inline void zend_call_known_instance_method_with_0_params(
zend_function *fn, zend_object *object, zval *retval_ptr)
{
zend_call_known_instance_method(fn, object, retval_ptr, 0, NULL);
}

static zend_always_inline void zend_call_known_instance_method_with_1_params(
zend_function *fn, zend_object *object, zval *retval_ptr, zval *param)
{
zend_call_known_instance_method(fn, object, retval_ptr, 1, param);
}

ZEND_API void zend_call_known_instance_method_with_2_params(
zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2);

ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...);

ZEND_API int zend_delete_global_variable(zend_string *name);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
zend_string *str, *file = NULL;
zend_long line = 0;

zend_call_method_with_0_params(Z_OBJ(exception), ce_exception, &ex->ce->__tostring, "__tostring", &tmp);
zend_call_known_instance_method_with_0_params(ex->ce->__tostring, Z_OBJ(exception), &tmp);
if (!EG(exception)) {
if (Z_TYPE(tmp) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ZSTR_VAL(ce_exception->name));
Expand Down
45 changes: 45 additions & 0 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 (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;
Expand Down
59 changes: 15 additions & 44 deletions Zend/zend_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ ZEND_API zend_class_entry *zend_ce_stringable;
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)
{
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) {
Expand All @@ -47,68 +45,43 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
ZVAL_COPY_VALUE(&params[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;
}
/* }}} */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
return object->handlers->get_properties(object);
}

zend_call_method_with_0_params(object, ce, &ce->__debugInfo, ZEND_DEBUGINFO_FUNC_NAME, &retval);
zend_call_known_instance_method_with_0_params(ce->__debugInfo, object, &retval);
if (Z_TYPE(retval) == IS_ARRAY) {
if (!Z_REFCOUNTED(retval)) {
*is_temp = 1;
Expand Down Expand Up @@ -1801,7 +1801,7 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj,
if (ce->__tostring) {
zval retval;
GC_ADDREF(readobj);
zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval);
zend_call_known_instance_method_with_0_params(ce->__tostring, readobj, &retval);
zend_object_release(readobj);
if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
ZVAL_COPY_VALUE(writeobj, &retval);
Expand Down
6 changes: 4 additions & 2 deletions ext/intl/calendar/calendar_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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",
Expand Down
3 changes: 2 additions & 1 deletion ext/intl/timezone/timezone_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
22 changes: 11 additions & 11 deletions ext/phar/phar_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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)) {
Expand All @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -2256,7 +2256,7 @@ static zend_object *phar_rename_archive(phar_archive_data **sphar, char *ext) /*

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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
3 changes: 2 additions & 1 deletion sapi/cli/php_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,8 @@ static int do_cli(int argc, char **argv) /* {{{ */

memset(&execute_data, 0, sizeof(zend_execute_data));
EG(current_execute_data) = &execute_data;
zend_call_method_with_1_params(Z_OBJ(ref), pce, &pce->constructor, "__construct", NULL, &arg);
zend_call_known_instance_method_with_1_params(
pce->constructor, Z_OBJ(ref), NULL, &arg);

if (EG(exception)) {
zval tmp, *msg, rv;
Expand Down
2 changes: 1 addition & 1 deletion sapi/phpdbg/phpdbg_prompt.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ static inline void phpdbg_handle_exception(void) /* {{{ */
EG(exception) = NULL;

ZVAL_OBJ(&zv, ex);
zend_call_method_with_0_params(ex, ex->ce, &ex->ce->__tostring, "__tostring", &tmp);
zend_call_known_instance_method_with_0_params(ex->ce->__tostring, ex, &tmp);
file = zval_get_string(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("file"), 1, &rv));
line = zval_get_long(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("line"), 1, &rv));

Expand Down