Skip to content

Commit 185a146

Browse files
committed
Merge branch 'PHP-8.1'
2 parents c414c5f + 070012d commit 185a146

8 files changed

+482
-7
lines changed

Zend/zend.c

+16
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,22 @@ static void function_copy_ctor(zval *zv) /* {{{ */
665665
}
666666
func->common.arg_info = new_arg_info + 1;
667667
}
668+
if (old_func->common.attributes) {
669+
zend_attribute *old_attr;
670+
671+
func->common.attributes = NULL;
672+
673+
ZEND_HASH_PACKED_FOREACH_PTR(old_func->common.attributes, old_attr) {
674+
uint32_t i;
675+
zend_attribute *attr;
676+
677+
attr = zend_add_attribute(&func->common.attributes, old_attr->name, old_attr->argc, old_attr->flags, old_attr->offset, old_attr->lineno);
678+
679+
for (i = 0 ; i < old_attr->argc; i++) {
680+
ZVAL_DUP(&attr->args[i].value, &old_attr->args[i].value);
681+
}
682+
} ZEND_HASH_FOREACH_END();
683+
}
668684
}
669685
/* }}} */
670686

Zend/zend_attributes.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ ZEND_API bool zend_is_attribute_repeated(HashTable *attributes, zend_attribute *
205205
static void attr_free(zval *v)
206206
{
207207
zend_attribute *attr = Z_PTR_P(v);
208+
bool persistent = attr->flags & ZEND_ATTRIBUTE_PERSISTENT;
208209

209210
zend_string_release(attr->name);
210211
zend_string_release(attr->lcname);
@@ -213,10 +214,14 @@ static void attr_free(zval *v)
213214
if (attr->args[i].name) {
214215
zend_string_release(attr->args[i].name);
215216
}
216-
zval_ptr_dtor(&attr->args[i].value);
217+
if (persistent) {
218+
zval_internal_ptr_dtor(&attr->args[i].value);
219+
} else {
220+
zval_ptr_dtor(&attr->args[i].value);
221+
}
217222
}
218223

219-
pefree(attr, attr->flags & ZEND_ATTRIBUTE_PERSISTENT);
224+
pefree(attr, persistent);
220225
}
221226

222227
ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_string *name, uint32_t argc, uint32_t flags, uint32_t offset, uint32_t lineno)

Zend/zend_opcode.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ ZEND_API void zend_function_dtor(zval *zv)
156156
/* For methods this will be called explicitly. */
157157
if (!function->common.scope) {
158158
zend_free_internal_arg_info(&function->internal_function);
159+
160+
if (function->common.attributes) {
161+
zend_hash_release(function->common.attributes);
162+
function->common.attributes = NULL;
163+
}
159164
}
160165

161166
if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
@@ -433,11 +438,17 @@ ZEND_API void destroy_zend_class(zval *zv)
433438
zend_hash_destroy(&ce->properties_info);
434439
zend_string_release_ex(ce->name, 1);
435440

436-
/* TODO: eliminate this loop for classes without functions with arg_info */
441+
/* TODO: eliminate this loop for classes without functions with arg_info / attributes */
437442
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
438-
if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) &&
439-
fn->common.scope == ce) {
440-
zend_free_internal_arg_info(&fn->internal_function);
443+
if (fn->common.scope == ce) {
444+
if (fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) {
445+
zend_free_internal_arg_info(&fn->internal_function);
446+
}
447+
448+
if (fn->common.attributes) {
449+
zend_hash_release(fn->common.attributes);
450+
fn->common.attributes = NULL;
451+
}
441452
}
442453
} ZEND_HASH_FOREACH_END();
443454

ext/zend_test/test.c

+113
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ static zend_class_entry *zend_test_class;
3737
static zend_class_entry *zend_test_child_class;
3838
static zend_class_entry *zend_test_trait;
3939
static zend_class_entry *zend_test_attribute;
40+
static zend_class_entry *zend_test_parameter_attribute;
41+
static zend_class_entry *zend_test_class_with_method_with_parameter_attribute;
42+
static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute;
4043
static zend_class_entry *zend_test_ns_foo_class;
4144
static zend_class_entry *zend_test_ns2_foo_class;
4245
static zend_class_entry *zend_test_ns2_ns_foo_class;
@@ -313,6 +316,17 @@ static ZEND_FUNCTION(namespaced_func)
313316
RETURN_TRUE;
314317
}
315318

319+
static ZEND_FUNCTION(zend_test_parameter_with_attribute)
320+
{
321+
zend_string *parameter;
322+
323+
ZEND_PARSE_PARAMETERS_START(1, 1)
324+
Z_PARAM_STR(parameter)
325+
ZEND_PARSE_PARAMETERS_END();
326+
327+
RETURN_LONG(1);
328+
}
329+
316330
static zend_object *zend_test_class_new(zend_class_entry *class_type)
317331
{
318332
zend_object *obj = zend_objects_new(class_type);
@@ -425,6 +439,50 @@ static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method)
425439
ZEND_PARSE_PARAMETERS_NONE();
426440
}
427441

442+
static ZEND_METHOD(ZendTestParameterAttribute, __construct)
443+
{
444+
zend_string *parameter;
445+
446+
ZEND_PARSE_PARAMETERS_START(1, 1)
447+
Z_PARAM_STR(parameter)
448+
ZEND_PARSE_PARAMETERS_END();
449+
450+
ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter);
451+
}
452+
453+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override)
454+
{
455+
zend_string *parameter;
456+
457+
ZEND_PARSE_PARAMETERS_START(1, 1)
458+
Z_PARAM_STR(parameter)
459+
ZEND_PARSE_PARAMETERS_END();
460+
461+
RETURN_LONG(2);
462+
}
463+
464+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override)
465+
{
466+
zend_string *parameter;
467+
468+
ZEND_PARSE_PARAMETERS_START(1, 1)
469+
Z_PARAM_STR(parameter)
470+
ZEND_PARSE_PARAMETERS_END();
471+
472+
RETURN_LONG(3);
473+
}
474+
475+
static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override)
476+
{
477+
zend_string *parameter;
478+
479+
ZEND_PARSE_PARAMETERS_START(1, 1)
480+
Z_PARAM_STR(parameter)
481+
ZEND_PARSE_PARAMETERS_END();
482+
483+
RETURN_LONG(4);
484+
}
485+
428486
PHP_INI_BEGIN()
429487
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
430488
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
@@ -460,6 +518,61 @@ PHP_MINIT_FUNCTION(zend_test)
460518
attr->validator = zend_attribute_validate_zendtestattribute;
461519
}
462520

521+
zend_test_parameter_attribute = register_class_ZendTestParameterAttribute();
522+
zend_internal_attribute_register(zend_test_parameter_attribute, ZEND_ATTRIBUTE_TARGET_PARAMETER);
523+
524+
{
525+
zend_attribute *attr;
526+
527+
attr = zend_add_parameter_attribute(
528+
zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1),
529+
0,
530+
zend_test_parameter_attribute->name,
531+
1
532+
);
533+
534+
ZVAL_PSTRING(&attr->args[0].value, "value1");
535+
}
536+
537+
zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute();
538+
539+
{
540+
zend_attribute *attr;
541+
542+
attr = zend_add_parameter_attribute(
543+
zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1),
544+
0,
545+
zend_test_parameter_attribute->name,
546+
1
547+
);
548+
549+
ZVAL_PSTRING(&attr->args[0].value, "value2");
550+
551+
attr = zend_add_parameter_attribute(
552+
zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
553+
0,
554+
zend_test_parameter_attribute->name,
555+
1
556+
);
557+
558+
ZVAL_PSTRING(&attr->args[0].value, "value3");
559+
}
560+
561+
zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute);
562+
563+
{
564+
zend_attribute *attr;
565+
566+
attr = zend_add_parameter_attribute(
567+
zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
568+
0,
569+
zend_test_parameter_attribute->name,
570+
1
571+
);
572+
573+
ZVAL_PSTRING(&attr->args[0].value, "value4");
574+
}
575+
463576
zend_test_ns_foo_class = register_class_ZendTestNS_Foo();
464577
zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo();
465578
zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo();

ext/zend_test/test.stub.php

+17
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ final class ZendTestAttribute {
4545

4646
}
4747

48+
final class ZendTestParameterAttribute {
49+
public string $parameter;
50+
51+
public function __construct(string $parameter) {}
52+
}
53+
54+
class ZendTestClassWithMethodWithParameterAttribute {
55+
final public function no_override(string $parameter): int {}
56+
public function override(string $parameter): int {}
57+
}
58+
59+
class ZendTestChildClassWithMethodWithParameterAttribute extends ZendTestClassWithMethodWithParameterAttribute {
60+
public function override(string $parameter): int {}
61+
}
62+
4863
enum ZendTestUnitEnum {
4964
case Foo;
5065
case Bar;
@@ -92,6 +107,8 @@ function zend_weakmap_remove(object $object): bool {}
92107
function zend_weakmap_dump(): array {}
93108

94109
function zend_get_unit_enum(): ZendTestUnitEnum {}
110+
111+
function zend_test_parameter_with_attribute(#[ZendTestParameterAttribute] string $parameter): int {}
95112
}
96113

97114
namespace ZendTestNS {

ext/zend_test/test_arginfo.h

+77-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 7326163f8ce5340c12e74af72d47a8926eb39786 */
2+
* Stub hash: af5d698b35753ac9f852688644d6844ba0914b2b */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
55
ZEND_END_ARG_INFO()
@@ -71,6 +71,10 @@ ZEND_END_ARG_INFO()
7171
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0)
7272
ZEND_END_ARG_INFO()
7373

74+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_parameter_with_attribute, 0, 1, IS_LONG, 0)
75+
ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0)
76+
ZEND_END_ARG_INFO()
77+
7478
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0)
7579
ZEND_END_ARG_INFO()
7680

@@ -91,6 +95,16 @@ ZEND_END_ARG_INFO()
9195

9296
#define arginfo_class__ZendTestTrait_testMethod arginfo_ZendTestNS2_ZendSubNS_namespaced_func
9397

98+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestParameterAttribute___construct, 0, 0, 1)
99+
ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0)
100+
ZEND_END_ARG_INFO()
101+
102+
#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override arginfo_zend_test_parameter_with_attribute
103+
104+
#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute
105+
106+
#define arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute
107+
94108
#define arginfo_class_ZendTestNS_Foo_method arginfo_zend_test_void_return
95109

96110
#define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return
@@ -116,13 +130,18 @@ static ZEND_FUNCTION(zend_weakmap_attach);
116130
static ZEND_FUNCTION(zend_weakmap_remove);
117131
static ZEND_FUNCTION(zend_weakmap_dump);
118132
static ZEND_FUNCTION(zend_get_unit_enum);
133+
static ZEND_FUNCTION(zend_test_parameter_with_attribute);
119134
static ZEND_FUNCTION(namespaced_func);
120135
static ZEND_METHOD(_ZendTestClass, is_object);
121136
static ZEND_METHOD(_ZendTestClass, __toString);
122137
static ZEND_METHOD(_ZendTestClass, returnsStatic);
123138
static ZEND_METHOD(_ZendTestClass, returnsThrowable);
124139
static ZEND_METHOD(_ZendTestChildClass, returnsThrowable);
125140
static ZEND_METHOD(_ZendTestTrait, testMethod);
141+
static ZEND_METHOD(ZendTestParameterAttribute, __construct);
142+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override);
143+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override);
144+
static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override);
126145
static ZEND_METHOD(ZendTestNS_Foo, method);
127146
static ZEND_METHOD(ZendTestNS2_Foo, method);
128147
static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method);
@@ -147,6 +166,7 @@ static const zend_function_entry ext_functions[] = {
147166
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
148167
ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump)
149168
ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum)
169+
ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute)
150170
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
151171
ZEND_FE_END
152172
};
@@ -183,6 +203,25 @@ static const zend_function_entry class_ZendTestAttribute_methods[] = {
183203
};
184204

185205

206+
static const zend_function_entry class_ZendTestParameterAttribute_methods[] = {
207+
ZEND_ME(ZendTestParameterAttribute, __construct, arginfo_class_ZendTestParameterAttribute___construct, ZEND_ACC_PUBLIC)
208+
ZEND_FE_END
209+
};
210+
211+
212+
static const zend_function_entry class_ZendTestClassWithMethodWithParameterAttribute_methods[] = {
213+
ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, no_override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
214+
ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC)
215+
ZEND_FE_END
216+
};
217+
218+
219+
static const zend_function_entry class_ZendTestChildClassWithMethodWithParameterAttribute_methods[] = {
220+
ZEND_ME(ZendTestChildClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC)
221+
ZEND_FE_END
222+
};
223+
224+
186225
static const zend_function_entry class_ZendTestUnitEnum_methods[] = {
187226
ZEND_FE_END
188227
};
@@ -314,6 +353,43 @@ static zend_class_entry *register_class_ZendTestAttribute(void)
314353
return class_entry;
315354
}
316355

356+
static zend_class_entry *register_class_ZendTestParameterAttribute(void)
357+
{
358+
zend_class_entry ce, *class_entry;
359+
360+
INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods);
361+
class_entry = zend_register_internal_class_ex(&ce, NULL);
362+
class_entry->ce_flags |= ZEND_ACC_FINAL;
363+
364+
zval property_parameter_default_value;
365+
ZVAL_UNDEF(&property_parameter_default_value);
366+
zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, 1);
367+
zend_declare_typed_property(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
368+
zend_string_release(property_parameter_name);
369+
370+
return class_entry;
371+
}
372+
373+
static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttribute(void)
374+
{
375+
zend_class_entry ce, *class_entry;
376+
377+
INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods);
378+
class_entry = zend_register_internal_class_ex(&ce, NULL);
379+
380+
return class_entry;
381+
}
382+
383+
static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_class_entry *class_entry_ZendTestClassWithMethodWithParameterAttribute)
384+
{
385+
zend_class_entry ce, *class_entry;
386+
387+
INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods);
388+
class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute);
389+
390+
return class_entry;
391+
}
392+
317393
static zend_class_entry *register_class_ZendTestUnitEnum(void)
318394
{
319395
zend_class_entry *class_entry = zend_register_internal_enum("ZendTestUnitEnum", IS_UNDEF, class_ZendTestUnitEnum_methods);

0 commit comments

Comments
 (0)