Skip to content

Commit e95993a

Browse files
committed
variadics variation and fixes
1 parent 2378036 commit e95993a

File tree

3 files changed

+105
-44
lines changed

3 files changed

+105
-44
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Partial application variation variadics user
3+
--FILE--
4+
<?php
5+
function foo($a, ...$b) {
6+
var_dump($a, ...$b);
7+
}
8+
9+
$foo = foo(10, 100, ...);
10+
11+
echo (string) new ReflectionFunction($foo);
12+
13+
$foo(1000, 10000);
14+
?>
15+
--EXPECTF--
16+
Function [ <user> partial function foo ] {
17+
@@ %s 2 - 4
18+
19+
- Parameters [1] {
20+
Parameter #0 [ <optional> ...$b ]
21+
}
22+
}
23+
int(10)
24+
int(100)
25+
int(1000)
26+
int(10000)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Partial application variation variadics internal
3+
--FILE--
4+
<?php
5+
$sprintf = sprintf("%d %d %d", 100, ...);
6+
7+
echo (string) new ReflectionFunction($sprintf);
8+
9+
echo $sprintf(1000, 10000);
10+
?>
11+
--EXPECTF--
12+
Function [ <internal:standard> partial function sprintf ] {
13+
14+
- Parameters [1] {
15+
Parameter #0 [ <optional> mixed ...$values ]
16+
}
17+
- Return [ string ]
18+
}
19+
100 1000 10000

Zend/zend_partial.c

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,17 @@ static zend_always_inline void zend_partial_prototype_u(zend_partial *partial, z
138138

139139
partial->prototype.common.fn_flags |= ZEND_ACC_PARTIAL;
140140

141-
if (partial->prototype.common.fn_flags & ZEND_ACC_VARIADIC &&
142-
partial->prototype.common.num_args > 0) {
143-
partial->prototype.common.num_args--;
141+
if (partial->prototype.common.fn_flags & ZEND_ACC_VARIADIC) {
142+
if (partial->prototype.common.num_args > 0) {
143+
partial->prototype.common.num_args--;
144+
} else {
145+
memcpy(
146+
partial->prototype.op_array.arg_info +
147+
partial->prototype.op_array.num_args,
148+
partial->func.op_array.arg_info +
149+
partial->func.op_array.num_args,
150+
sizeof(zend_arg_info));
151+
}
144152
}
145153
}
146154

@@ -204,9 +212,17 @@ static zend_always_inline void zend_partial_prototype_i(zend_partial *partial, z
204212

205213
partial->prototype.common.fn_flags |= ZEND_ACC_PARTIAL;
206214

207-
if (partial->prototype.common.fn_flags & ZEND_ACC_VARIADIC &&
208-
partial->prototype.common.num_args > 0) {
209-
partial->prototype.common.num_args--;
215+
if (partial->prototype.common.fn_flags & ZEND_ACC_VARIADIC) {
216+
if (partial->prototype.common.num_args > 0) {
217+
partial->prototype.common.num_args--;
218+
} else {
219+
memcpy(
220+
partial->prototype.internal_function.arg_info +
221+
partial->prototype.internal_function.num_args,
222+
partial->func.internal_function.arg_info +
223+
partial->func.internal_function.num_args,
224+
sizeof(zend_internal_arg_info));
225+
}
210226
}
211227
}
212228

@@ -276,27 +292,27 @@ static zend_always_inline void zend_partial_debug_i(zend_partial *partial, HashT
276292
}
277293

278294
if (partial->func.common.fn_flags & ZEND_ACC_VARIADIC) {
279-
zval variadics;
280-
281-
array_init(&variadics);
295+
zval variadics;
296+
297+
array_init(&variadics);
282298

283-
zend_hash_str_add(ht, info->name, strlen(info->name), &variadics);
299+
zend_hash_str_add(ht, info->name, strlen(info->name), &variadics);
284300

285-
while (arg < aend) {
286-
if (ZEND_PARTIAL_IS_NOT_PLACEHOLDER(arg)) {
287-
zend_hash_next_index_insert(Z_ARRVAL(variadics), arg);
288-
289-
if (Z_OPT_REFCOUNTED_P(arg)) {
290-
Z_ADDREF_P(arg);
291-
}
292-
}
301+
while (arg < aend) {
302+
if (ZEND_PARTIAL_IS_NOT_PLACEHOLDER(arg)) {
303+
zend_hash_next_index_insert(Z_ARRVAL(variadics), arg);
304+
305+
if (Z_OPT_REFCOUNTED_P(arg)) {
306+
Z_ADDREF_P(arg);
307+
}
308+
}
293309

294-
arg++;
295-
}
310+
arg++;
311+
}
296312

297-
if (partial->named) {
298-
zend_hash_merge(Z_ARRVAL(variadics), partial->named, zval_copy_ctor, true);
299-
}
313+
if (partial->named) {
314+
zend_hash_merge(Z_ARRVAL(variadics), partial->named, zval_copy_ctor, true);
315+
}
300316
}
301317
}
302318

@@ -328,27 +344,27 @@ static zend_always_inline void zend_partial_debug_u(zend_partial *partial, HashT
328344
}
329345

330346
if (partial->func.common.fn_flags & ZEND_ACC_VARIADIC) {
331-
zval variadics;
332-
333-
array_init(&variadics);
334-
335-
zend_hash_add(ht, info->name, &variadics);
336-
337-
while (arg < aend) {
338-
if (ZEND_PARTIAL_IS_NOT_PLACEHOLDER(arg)) {
339-
zend_hash_next_index_insert(Z_ARRVAL(variadics), arg);
340-
341-
if (Z_OPT_REFCOUNTED_P(arg)) {
342-
Z_ADDREF_P(arg);
343-
}
344-
}
345-
346-
arg++;
347-
}
348-
349-
if (partial->named) {
350-
zend_hash_merge(Z_ARRVAL(variadics), partial->named, zval_copy_ctor, true);
351-
}
347+
zval variadics;
348+
349+
array_init(&variadics);
350+
351+
zend_hash_add(ht, info->name, &variadics);
352+
353+
while (arg < aend) {
354+
if (ZEND_PARTIAL_IS_NOT_PLACEHOLDER(arg)) {
355+
zend_hash_next_index_insert(Z_ARRVAL(variadics), arg);
356+
357+
if (Z_OPT_REFCOUNTED_P(arg)) {
358+
Z_ADDREF_P(arg);
359+
}
360+
}
361+
362+
arg++;
363+
}
364+
365+
if (partial->named) {
366+
zend_hash_merge(Z_ARRVAL(variadics), partial->named, zval_copy_ctor, true);
367+
}
352368
}
353369
}
354370

0 commit comments

Comments
 (0)