Skip to content
Merged
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
2 changes: 2 additions & 0 deletions UPGRADING.INTERNALS
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ PHP 8.7 INTERNALS UPGRADE NOTES
This new signature covers the most common parameters used with zend_is_callable_ex().
- Removed zend_hrtime_posix_clock_id. zend_hrtime() always uses CLOCK_MONOTONIC
on POSIX platforms.
- Function pointer signature for interface_gets_implemented has been made void.
Comment thread
TimWolla marked this conversation as resolved.
Implementations are expected to use zend_error_noreturn upon failure.
- Added a new zend_object_copy() function which increases the refcount of
a zend_object* and returns it. Allowing more descriptive code rather than
doing an assignment followed by GC_ADDREF().
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ struct _zend_class_entry {
/* handlers */
union {
zend_object* (*create_object)(zend_class_entry *class_type);
int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type); /* a class implements this interface */
void (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type); /* a class implements this interface */
};
zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref);
zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method);
Expand Down
12 changes: 3 additions & 9 deletions Zend/zend_enum.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,36 +134,30 @@ void zend_verify_enum(const zend_class_entry *ce)
zend_verify_enum_interfaces(ce);
}

static int zend_implement_unit_enum(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_unit_enum(zend_class_entry *interface, zend_class_entry *class_type)
{
if (class_type->ce_flags & ZEND_ACC_ENUM) {
return SUCCESS;
return;
}

zend_error_noreturn(E_ERROR, "Non-enum class %s cannot implement interface %s",
ZSTR_VAL(class_type->name),
ZSTR_VAL(interface->name));

return FAILURE;
}

static int zend_implement_backed_enum(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_backed_enum(zend_class_entry *interface, zend_class_entry *class_type)
{
if (!(class_type->ce_flags & ZEND_ACC_ENUM)) {
zend_error_noreturn(E_ERROR, "Non-enum class %s cannot implement interface %s",
ZSTR_VAL(class_type->name),
ZSTR_VAL(interface->name));
return FAILURE;
}

if (class_type->enum_backing_type == IS_UNDEF) {
zend_error_noreturn(E_ERROR, "Non-backed enum %s cannot implement interface %s",
ZSTR_VAL(class_type->name),
ZSTR_VAL(interface->name));
return FAILURE;
}

return SUCCESS;
}

void zend_register_enum_ce(void)
Expand Down
5 changes: 2 additions & 3 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ ZEND_API void (*zend_throw_exception_hook)(zend_object *ex);
static zend_object_handlers default_exception_handlers;

/* {{{ zend_implement_throwable */
static int zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
{
/* zend_ce_exception and zend_ce_error may not be initialized yet when this is called (e.g when
* implementing Throwable for Exception itself). Perform a manual inheritance check. */
Expand All @@ -71,7 +71,7 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr
}
if (zend_string_equals_literal(root->name, "Exception")
|| zend_string_equals_literal(root->name, "Error")) {
return SUCCESS;
return;
}

bool can_extend = (class_type->ce_flags & ZEND_ACC_ENUM) == 0;
Expand All @@ -83,7 +83,6 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr
zend_get_object_type_uc(class_type),
ZSTR_VAL(class_type->name),
ZSTR_VAL(interface->name));
return FAILURE;
}
/* }}} */

Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -1576,8 +1576,8 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke

static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface) /* {{{ */
{
if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce) == FAILURE) {
zend_error_noreturn(E_CORE_ERROR, "%s %s could not implement interface %s", zend_get_object_type_uc(ce), ZSTR_VAL(ce->name), ZSTR_VAL(iface->name));
if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented) {
iface->interface_gets_implemented(iface, ce);
}
/* This should be prevented by the class lookup logic. */
ZEND_ASSERT(ce != iface);
Expand Down
30 changes: 12 additions & 18 deletions Zend/zend_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,20 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
/* }}} */

/* {{{ zend_implement_traversable */
static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type)
{
/* Abstract class can implement Traversable only, in which case the extending class must
* implement Iterator or IteratorAggregate. */
if (class_type->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
return SUCCESS;
return;
}

/* Check that class_type implements at least one of 'IteratorAggregate' or 'Iterator' */
if (class_type->num_interfaces) {
ZEND_ASSERT(class_type->ce_flags & ZEND_ACC_RESOLVED_INTERFACES);
for (uint32_t i = 0; i < class_type->num_interfaces; i++) {
if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
return SUCCESS;
return;
}
}
}
Expand All @@ -279,12 +279,11 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
ZSTR_VAL(zend_ce_traversable->name),
ZSTR_VAL(zend_ce_iterator->name),
ZSTR_VAL(zend_ce_aggregate->name));
return FAILURE;
}
/* }}} */

/* {{{ zend_implement_aggregate */
static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type)
{
if (zend_class_implements_interface(class_type, zend_ce_iterator)) {
zend_error_noreturn(E_ERROR,
Expand All @@ -309,24 +308,23 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
/* get_iterator was explicitly assigned for an internal class. */
if (!class_type->parent || class_type->parent->get_iterator != class_type->get_iterator) {
ZEND_ASSERT(class_type->type == ZEND_INTERNAL_CLASS);
return SUCCESS;
return;
}

/* The getIterator() method has not been overwritten, use inherited get_iterator(). */
if (funcs_ptr->zf_new_iterator->common.scope != class_type) {
return SUCCESS;
return;
}

/* getIterator() has been overwritten, switch to zend_user_it_get_new_iterator. */
}

class_type->get_iterator = zend_user_it_get_new_iterator;
return SUCCESS;
}
/* }}} */

/* {{{ zend_implement_iterator */
static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type)
{
if (zend_class_implements_interface(class_type, zend_ce_aggregate)) {
zend_error_noreturn(E_ERROR,
Expand Down Expand Up @@ -358,7 +356,7 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
if (!class_type->parent || class_type->parent->get_iterator != class_type->get_iterator) {
/* get_iterator was explicitly assigned for an internal class. */
ZEND_ASSERT(class_type->type == ZEND_INTERNAL_CLASS);
return SUCCESS;
return;
}

/* None of the Iterator methods have been overwritten, use inherited get_iterator(). */
Expand All @@ -367,20 +365,19 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
funcs_ptr->zf_key->common.scope != class_type &&
funcs_ptr->zf_current->common.scope != class_type &&
funcs_ptr->zf_next->common.scope != class_type) {
return SUCCESS;
return;
}

/* One of the Iterator methods has been overwritten,
* switch to zend_user_it_get_iterator. */
}

class_type->get_iterator = zend_user_it_get_iterator;
return SUCCESS;
}
/* }}} */

/* {{{ zend_implement_arrayaccess */
static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type)
{
ZEND_ASSERT(!class_type->arrayaccess_funcs_ptr && "ArrayAccess funcs already set?");
zend_class_arrayaccess_funcs *funcs_ptr = class_type->type == ZEND_INTERNAL_CLASS
Expand All @@ -396,8 +393,6 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
&class_type->function_table, "offsetset", sizeof("offsetset") - 1);
funcs_ptr->zf_offsetunset = zend_hash_str_find_ptr(
&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1);

return SUCCESS;
}
/* }}} */

Expand Down Expand Up @@ -460,12 +455,12 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns
/* }}} */

/* {{{ zend_implement_serializable */
static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type)
static void zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type)
{
if (class_type->parent
&& (class_type->parent->serialize || class_type->parent->unserialize)
&& !zend_class_implements_interface(class_type->parent, zend_ce_serializable)) {
return FAILURE;
zend_error_noreturn(E_CORE_ERROR, "%s %s could not implement interface %s", zend_get_object_type_uc(class_type), ZSTR_VAL(class_type->name), ZSTR_VAL(interface->name));
}
if (!class_type->serialize) {
class_type->serialize = zend_user_serialize;
Expand All @@ -481,7 +476,6 @@ static int zend_implement_serializable(zend_class_entry *interface, zend_class_e
"During inheritance of %s, while implementing Serializable", ZSTR_VAL(class_type->name));
}
}
return SUCCESS;
}
/* }}}*/

Expand Down
2 changes: 0 additions & 2 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,6 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
}

zend_error_noreturn(E_ERROR, ZEND_DEBUGINFO_FUNC_NAME "() must return an array");

return NULL; /* Compilers are dumb and don't understand that noreturn means that the function does NOT need a return value... */
}
/* }}} */

Expand Down
4 changes: 1 addition & 3 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -1703,16 +1703,14 @@ static zend_object_iterator *date_object_period_get_iterator(zend_class_entry *c
return (zend_object_iterator*)iterator;
} /* }}} */

static int implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor) /* {{{ */
static void implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor) /* {{{ */
{
if (implementor->type == ZEND_USER_CLASS &&
!instanceof_function(implementor, date_ce_date) &&
!instanceof_function(implementor, date_ce_immutable)
) {
zend_error_noreturn(E_ERROR, "DateTimeInterface can't be implemented by user classes");
}

return SUCCESS;
} /* }}} */

static int date_interval_has_property(zend_object *object, zend_string *name, int type, void **cache_slot) /* {{{ */
Expand Down
7 changes: 3 additions & 4 deletions ext/json/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ PHP_JSON_API zend_class_entry *php_json_exception_ce;

PHP_JSON_API ZEND_DECLARE_MODULE_GLOBALS(json)

static int php_json_implement_json_serializable(zend_class_entry *interface, zend_class_entry *class_type)
static void php_json_implement_json_serializable(zend_class_entry *interface, zend_class_entry *class_type)
{
class_type->ce_flags |= ZEND_ACC_USE_GUARDS;
return SUCCESS;
}

/* {{{ MINIT */
Expand Down Expand Up @@ -182,11 +181,11 @@ static const char *php_json_get_error_msg(php_json_error_code error_code) /* {{{
static zend_string *php_json_get_error_msg_with_location(const php_json_error_details *details) /* {{{ */
{
const char *base_msg = php_json_get_error_msg(details->code);

if (details->line > 0 && details->column > 0) {
return zend_strpprintf(0, "%s near location %" PRIu64 ":%" PRIu64, base_msg, details->line, details->column);
}

return zend_string_init(base_msg, strlen(base_msg), 0);
}
/* }}} */
Expand Down
3 changes: 1 addition & 2 deletions ext/session/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -2954,7 +2954,7 @@ static bool session_interfaces_include(const zend_class_entry *ce, const zend_cl
return false;
}

static int session_handler_interface_gets_implemented(zend_class_entry *self, zend_class_entry *class) {
static void session_handler_interface_gets_implemented(zend_class_entry *self, zend_class_entry *class) {
if (!zend_hash_str_exists(&class->function_table, ZEND_STRL("create_sid"))
&& !session_interfaces_include(class, php_session_id_iface_entry)) {
zend_error(E_WARNING,
Expand All @@ -2967,7 +2967,6 @@ static int session_handler_interface_gets_implemented(zend_class_entry *self, ze
"Class %s implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0",
ZSTR_VAL(class->name));
}
return SUCCESS;
}

static PHP_MINIT_FUNCTION(session)
Expand Down
5 changes: 1 addition & 4 deletions ext/standard/io_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,11 @@ static php_poll_handle_ops php_stream_poll_handle_ops = {
};

/* Handle interface internal only */
static int php_stream_poll_handle_implement_interface(zend_class_entry *interface, zend_class_entry *implementor)
static void php_stream_poll_handle_implement_interface(zend_class_entry *interface, zend_class_entry *implementor)
{
if (implementor->type == ZEND_USER_CLASS) {
zend_error_noreturn(E_ERROR, "Io\\Poll\\Handle cannot be implemented by user classes");
return FAILURE;
}

return SUCCESS;
}

/* Object Creation Functions */
Expand Down
Loading