Skip to content

Commit 2922d67

Browse files
committed
Merge branch 'fix-variadics-macro' into PHP-8.1
2 parents 12290b7 + aead0c8 commit 2922d67

File tree

6 files changed

+82
-5
lines changed

6 files changed

+82
-5
lines changed

Zend/zend_API.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ typedef struct _zend_fcall_info_cache {
131131
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
132132
#define ZEND_ARG_OBJ_TYPE_MASK(pass_by_ref, name, class_name, type_mask, default_value) \
133133
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
134-
#define ZEND_ARG_VARIADIC_OBJ_TYPE_MASK(pass_by_ref, name, class_name, type_mask, default_value) \
135-
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), default_value },
134+
#define ZEND_ARG_VARIADIC_OBJ_TYPE_MASK(pass_by_ref, name, class_name, type_mask) \
135+
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
136136

137137
/* Arginfo structures with object type information */
138138
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, class_name, allow_null) \

build/gen_stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,10 +2735,10 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
27352735
$arginfoType = $argType->toArginfoType();
27362736
if ($arginfoType->hasClassType()) {
27372737
$code .= sprintf(
2738-
"\tZEND_%s_OBJ_TYPE_MASK(%s, %s, %s, %s, %s)\n",
2738+
"\tZEND_%s_OBJ_TYPE_MASK(%s, %s, %s, %s%s)\n",
27392739
$argKind, $argInfo->getSendByString(), $argInfo->name,
27402740
$arginfoType->toClassTypeString(), $arginfoType->toTypeMask(),
2741-
$argInfo->getDefaultValueAsArginfoString()
2741+
!$argInfo->isVariadic ? ", " . $argInfo->getDefaultValueAsArginfoString() : ""
27422742
);
27432743
} else {
27442744
$code .= sprintf(

ext/zend_test/test.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,31 @@ static ZEND_METHOD(_ZendTestClass, returnsThrowable)
412412
zend_throw_error(NULL, "Dummy");
413413
}
414414

415+
static ZEND_METHOD(_ZendTestClass, variadicTest) {
416+
int argc, i;
417+
zval *args = NULL;
418+
419+
ZEND_PARSE_PARAMETERS_START(0, -1)
420+
Z_PARAM_VARIADIC('*', args, argc)
421+
ZEND_PARSE_PARAMETERS_END();
422+
423+
for (i = 0; i < argc; i++) {
424+
zval *arg = args + i;
425+
426+
if (Z_TYPE_P(arg) == IS_STRING) {
427+
continue;
428+
}
429+
if (Z_TYPE_P(arg) == IS_OBJECT && instanceof_function(Z_OBJ_P(arg)->ce, zend_ce_iterator)) {
430+
continue;
431+
}
432+
433+
zend_argument_type_error(i + 1, "must be of class Iterator or a string, %s given", zend_zval_type_name(arg));
434+
RETURN_THROWS();
435+
}
436+
437+
object_init_ex(return_value, zend_get_called_scope(execute_data));
438+
}
439+
415440
static ZEND_METHOD(_ZendTestChildClass, returnsThrowable)
416441
{
417442
ZEND_PARSE_PARAMETERS_NONE();

ext/zend_test/test.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public function __toString() {}
3030
public function returnsStatic(): static {}
3131

3232
public function returnsThrowable(): Throwable {}
33+
34+
static public function variadicTest(string|Iterator ...$elements) : static {}
3335
}
3436

3537
class _ZendTestChildClass extends _ZendTestClass

ext/zend_test/test_arginfo.h

Lines changed: 7 additions & 1 deletion
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: 1eca5b01969498e67501a59dc69ba4c01263c4d9 */
2+
* Stub hash: 614310958c6e2acde46c9b7932ba894caf72d6df */
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()
@@ -96,6 +96,10 @@ ZEND_END_ARG_INFO()
9696
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class__ZendTestClass_returnsThrowable, 0, 0, Throwable, 0)
9797
ZEND_END_ARG_INFO()
9898

99+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class__ZendTestClass_variadicTest, 0, 0, IS_STATIC, 0)
100+
ZEND_ARG_VARIADIC_OBJ_TYPE_MASK(0, elements, Iterator, MAY_BE_STRING)
101+
ZEND_END_ARG_INFO()
102+
99103
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class__ZendTestChildClass_returnsThrowable, 0, 0, Exception, 0)
100104
ZEND_END_ARG_INFO()
101105

@@ -144,6 +148,7 @@ static ZEND_METHOD(_ZendTestClass, is_object);
144148
static ZEND_METHOD(_ZendTestClass, __toString);
145149
static ZEND_METHOD(_ZendTestClass, returnsStatic);
146150
static ZEND_METHOD(_ZendTestClass, returnsThrowable);
151+
static ZEND_METHOD(_ZendTestClass, variadicTest);
147152
static ZEND_METHOD(_ZendTestChildClass, returnsThrowable);
148153
static ZEND_METHOD(_ZendTestTrait, testMethod);
149154
static ZEND_METHOD(ZendTestParameterAttribute, __construct);
@@ -192,6 +197,7 @@ static const zend_function_entry class__ZendTestClass_methods[] = {
192197
ZEND_ME(_ZendTestClass, __toString, arginfo_class__ZendTestClass___toString, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
193198
ZEND_ME(_ZendTestClass, returnsStatic, arginfo_class__ZendTestClass_returnsStatic, ZEND_ACC_PUBLIC)
194199
ZEND_ME(_ZendTestClass, returnsThrowable, arginfo_class__ZendTestClass_returnsThrowable, ZEND_ACC_PUBLIC)
200+
ZEND_ME(_ZendTestClass, variadicTest, arginfo_class__ZendTestClass_variadicTest, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
195201
ZEND_FE_END
196202
};
197203

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Verify that variadic arguments create proper stub
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$reflection = new ReflectionMethod("_ZendTestClass", "variadicTest");
9+
$arguments = $reflection->getParameters();
10+
11+
echo (string) $arguments[0], "\n";
12+
var_dump($arguments[0]->isVariadic());
13+
14+
$type = $arguments[0]->getType();
15+
16+
var_dump($type instanceof ReflectionUnionType);
17+
18+
echo "\n";
19+
20+
$types = $type->getTypes();
21+
22+
var_dump($types[0]->getName());
23+
var_dump($types[0] instanceof ReflectionNamedType);
24+
var_dump($types[0]->allowsNull());
25+
26+
echo "\n";
27+
28+
var_dump($types[1]->getName());
29+
var_dump($types[1] instanceof ReflectionNamedType);
30+
var_dump($types[1]->allowsNull());
31+
32+
?>
33+
--EXPECTF--
34+
Parameter #0 [ <optional> Iterator|string ...$elements ]
35+
bool(true)
36+
bool(true)
37+
38+
string(8) "Iterator"
39+
bool(true)
40+
bool(false)
41+
42+
string(6) "string"
43+
bool(true)
44+
bool(false)

0 commit comments

Comments
 (0)