Skip to content

Commit 4d52853

Browse files
authored
ext/spl: extract AppendIterator constructor (#21367)
The implementation of it is simple whereas spl_dual_it_construct() is extremely convoluted
1 parent f102735 commit 4d52853

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

ext/spl/spl_iterators.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,15 +1341,6 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
13411341
}
13421342
break;
13431343
}
1344-
case DIT_AppendIterator:
1345-
if (zend_parse_parameters_none() == FAILURE) {
1346-
return NULL;
1347-
}
1348-
intern->dit_type = DIT_AppendIterator;
1349-
object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator);
1350-
zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL);
1351-
intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0);
1352-
return intern;
13531344
case DIT_RegexIterator:
13541345
case DIT_RecursiveRegexIterator: {
13551346
zend_string *regex;
@@ -2814,7 +2805,21 @@ static void spl_append_it_next(spl_dual_it_object *intern) /* {{{ */
28142805
/* {{{ Create an AppendIterator */
28152806
PHP_METHOD(AppendIterator, __construct)
28162807
{
2817-
spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_AppendIterator, zend_ce_iterator, DIT_AppendIterator);
2808+
ZEND_PARSE_PARAMETERS_NONE();
2809+
2810+
spl_dual_it_object *intern = Z_SPLDUAL_IT_P(ZEND_THIS);
2811+
2812+
/* TODO: This should be converted to a normal Error as this is triggered when calling the constructor twice */
2813+
if (intern->dit_type != DIT_Unknown) {
2814+
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s::getIterator() must be called exactly once per instance", ZSTR_VAL(spl_ce_AppendIterator->name));
2815+
RETURN_THROWS();
2816+
}
2817+
2818+
intern->dit_type = DIT_AppendIterator;
2819+
object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator);
2820+
zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL);
2821+
intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0);
2822+
28182823
} /* }}} */
28192824

28202825
/* {{{ Append an iterator */

ext/spl/tests/iterator_031.phpt

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ SPL: AppendIterator::append() rewinds when necessary
33
--FILE--
44
<?php
55

6+
$ap = new AppendIterator();
7+
try {
8+
$ap->__construct();
9+
} catch (\Throwable $e) {
10+
echo $e::class, ': ', $e->getMessage(), "\n";
11+
}
12+
613
class MyArrayIterator extends ArrayIterator
714
{
815
function rewind(): void
@@ -14,8 +21,7 @@ class MyArrayIterator extends ArrayIterator
1421

1522
$it = new MyArrayIterator(array(1,2));
1623

17-
foreach($it as $k=>$v)
18-
{
24+
foreach($it as $k=>$v) {
1925
echo "$k=>$v\n";
2026
}
2127

@@ -44,45 +50,38 @@ class MyAppendIterator extends AppendIterator
4450
parent::append($what);
4551
}
4652

47-
function parent__construct()
48-
{
53+
function parent__construct() {
4954
parent::__construct();
5055
}
5156
}
5257

5358
$ap = new MyAppendIterator;
5459

55-
try
56-
{
60+
try {
5761
$ap->append($it);
58-
}
59-
catch(\Error $e)
60-
{
62+
} catch(\Error $e) {
6163
echo $e->getMessage() . "\n";
6264
}
6365

6466
$ap->parent__construct();
6567

66-
try
67-
{
68+
try {
6869
$ap->parent__construct($it);
69-
}
70-
catch(BadMethodCallException $e)
71-
{
70+
} catch(BadMethodCallException $e) {
7271
echo $e->getMessage() . "\n";
7372
}
7473

7574
$ap->append($it);
7675
$ap->append($it);
7776
$ap->append($it);
7877

79-
foreach($ap as $k=>$v)
80-
{
78+
foreach($ap as $k=>$v) {
8179
echo "$k=>$v\n";
8280
}
8381

8482
?>
8583
--EXPECT--
84+
BadMethodCallException: AppendIterator::getIterator() must be called exactly once per instance
8685
MyArrayIterator::rewind
8786
0=>1
8887
1=>2

0 commit comments

Comments
 (0)