Merge branch 'PHP-8.4'

* PHP-8.4:
  Destroy temporary module classes in reverse order
This commit is contained in:
Arnaud Le Blanc
2025-03-14 10:51:50 +01:00
4 changed files with 80 additions and 16 deletions

View File

@ -22,6 +22,7 @@
#include "zend.h"
#include "zend_execute.h"
#include "zend_API.h"
#include "zend_hash.h"
#include "zend_modules.h"
#include "zend_extensions.h"
#include "zend_constants.h"
@ -3263,21 +3264,17 @@ ZEND_API zend_result zend_get_module_started(const char *module_name) /* {{{ */
}
/* }}} */
static int clean_module_class(zval *el, void *arg) /* {{{ */
{
zend_class_entry *ce = (zend_class_entry *)Z_PTR_P(el);
int module_number = *(int *)arg;
if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
return ZEND_HASH_APPLY_REMOVE;
} else {
return ZEND_HASH_APPLY_KEEP;
}
}
/* }}} */
static void clean_module_classes(int module_number) /* {{{ */
{
zend_hash_apply_with_argument(EG(class_table), clean_module_class, (void *) &module_number);
/* Child classes may reuse structures from parent classes, so destroy in reverse order. */
Bucket *bucket;
ZEND_HASH_REVERSE_FOREACH_BUCKET(EG(class_table), bucket) {
zend_class_entry *ce = Z_CE(bucket->val);
if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
zend_hash_del_bucket(EG(class_table), bucket);
}
} ZEND_HASH_FOREACH_END();
}
/* }}} */

View File

@ -92,10 +92,22 @@ PHP_METHOD(DlTest, test)
RETURN_STR(retval);
}
PHP_METHOD(DlTestSuperClass, test)
{
ZEND_PARSE_PARAMETERS_NONE();
RETURN_NULL();
}
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(dl_test)
{
zend_class_entry *ce;
register_class_DlTest();
ce = register_class_DlTestSuperClass();
register_class_DlTestSubClass(ce);
register_class_DlTestAliasedClass();
/* Test backwards compatibility */
if (getenv("PHP_DL_TEST_USE_OLD_REGISTER_INI_ENTRIES")) {

View File

@ -5,6 +5,9 @@
* @undocumentable
*/
/** @var int */
const DL_TEST_CONST = 42;
function dl_test_test1(): void {}
function dl_test_test2(string $str = ""): string {}
@ -13,5 +16,13 @@ class DlTest {
public function test(string $str = ""): string {}
}
/** @var int */
const DL_TEST_CONST = 42;
class DlTestSuperClass {
public int $a;
public function test(string $str = ""): string {}
}
class DlTestSubClass extends DlTestSuperClass {
}
class DlTestAliasedClass {
}

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: fa6eadc4164fb7b0d9f7d873d47205bbe5a46cd8 */
* Stub hash: 75bdb57a45060b123fe48003fef43d2af07726e1 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_dl_test_test1, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
@ -10,9 +10,12 @@ ZEND_END_ARG_INFO()
#define arginfo_class_DlTest_test arginfo_dl_test_test2
#define arginfo_class_DlTestSuperClass_test arginfo_dl_test_test2
ZEND_FUNCTION(dl_test_test1);
ZEND_FUNCTION(dl_test_test2);
ZEND_METHOD(DlTest, test);
ZEND_METHOD(DlTestSuperClass, test);
static const zend_function_entry ext_functions[] = {
ZEND_FE(dl_test_test1, arginfo_dl_test_test1)
@ -25,6 +28,11 @@ static const zend_function_entry class_DlTest_methods[] = {
ZEND_FE_END
};
static const zend_function_entry class_DlTestSuperClass_methods[] = {
ZEND_ME(DlTestSuperClass, test, arginfo_class_DlTestSuperClass_test, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
static void register_dl_test_symbols(int module_number)
{
REGISTER_LONG_CONSTANT("DL_TEST_CONST", 42, CONST_PERSISTENT);
@ -39,3 +47,39 @@ static zend_class_entry *register_class_DlTest(void)
return class_entry;
}
static zend_class_entry *register_class_DlTestSuperClass(void)
{
zend_class_entry ce, *class_entry;
INIT_CLASS_ENTRY(ce, "DlTestSuperClass", class_DlTestSuperClass_methods);
class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0);
zval property_a_default_value;
ZVAL_UNDEF(&property_a_default_value);
zend_string *property_a_name = zend_string_init("a", sizeof("a") - 1, 1);
zend_declare_typed_property(class_entry, property_a_name, &property_a_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(property_a_name);
return class_entry;
}
static zend_class_entry *register_class_DlTestSubClass(zend_class_entry *class_entry_DlTestSuperClass)
{
zend_class_entry ce, *class_entry;
INIT_CLASS_ENTRY(ce, "DlTestSubClass", NULL);
class_entry = zend_register_internal_class_with_flags(&ce, class_entry_DlTestSuperClass, 0);
return class_entry;
}
static zend_class_entry *register_class_DlTestAliasedClass(void)
{
zend_class_entry ce, *class_entry;
INIT_CLASS_ENTRY(ce, "DlTestAliasedClass", NULL);
class_entry = zend_register_internal_class_with_flags(&ce, NULL, 0);
return class_entry;
}