@@ -1321,7 +1321,13 @@ PHP_FUNCTION(max)
1321
1321
}
1322
1322
/* }}} */
1323
1323
1324
- static int php_array_walk (zval * array , zval * userdata , int recursive ) /* {{{ */
1324
+ typedef struct {
1325
+ zend_fcall_info fci ;
1326
+ zend_fcall_info_cache fci_cache ;
1327
+ } php_array_walk_context ;
1328
+
1329
+ static int php_array_walk (
1330
+ php_array_walk_context * context , zval * array , zval * userdata , int recursive )
1325
1331
{
1326
1332
zval args [3 ], /* Arguments to userland function */
1327
1333
retval , /* Return value - unused */
@@ -1331,15 +1337,19 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
1331
1337
uint32_t ht_iter ;
1332
1338
int result = SUCCESS ;
1333
1339
1340
+ /* Create a local copy of fci, as we want to use different arguments at different
1341
+ * levels of recursion. */
1342
+ zend_fcall_info fci = context -> fci ;
1343
+
1334
1344
/* Set up known arguments */
1335
1345
ZVAL_UNDEF (& args [1 ]);
1336
1346
if (userdata ) {
1337
1347
ZVAL_COPY (& args [2 ], userdata );
1338
1348
}
1339
1349
1340
- BG ( array_walk_fci ) .retval = & retval ;
1341
- BG ( array_walk_fci ) .param_count = userdata ? 3 : 2 ;
1342
- BG ( array_walk_fci ) .params = args ;
1350
+ fci .retval = & retval ;
1351
+ fci .param_count = userdata ? 3 : 2 ;
1352
+ fci .params = args ;
1343
1353
1344
1354
zend_hash_internal_pointer_reset_ex (target_hash , & pos );
1345
1355
ht_iter = zend_hash_iterator_add (target_hash , pos );
@@ -1386,8 +1396,6 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
1386
1396
1387
1397
if (recursive && Z_TYPE_P (Z_REFVAL_P (zv )) == IS_ARRAY ) {
1388
1398
HashTable * thash ;
1389
- zend_fcall_info orig_array_walk_fci ;
1390
- zend_fcall_info_cache orig_array_walk_fci_cache ;
1391
1399
zval ref ;
1392
1400
ZVAL_COPY_VALUE (& ref , zv );
1393
1401
@@ -1400,28 +1408,20 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
1400
1408
break ;
1401
1409
}
1402
1410
1403
- /* backup the fcall info and cache */
1404
- orig_array_walk_fci = BG (array_walk_fci );
1405
- orig_array_walk_fci_cache = BG (array_walk_fci_cache );
1406
-
1407
1411
Z_ADDREF (ref );
1408
1412
GC_PROTECT_RECURSION (thash );
1409
- result = php_array_walk (zv , userdata , recursive );
1413
+ result = php_array_walk (context , zv , userdata , recursive );
1410
1414
if (Z_TYPE_P (Z_REFVAL (ref )) == IS_ARRAY && thash == Z_ARRVAL_P (Z_REFVAL (ref ))) {
1411
1415
/* If the hashtable changed in the meantime, we'll "leak" this apply count
1412
1416
* increment -- our reference to thash is no longer valid. */
1413
1417
GC_UNPROTECT_RECURSION (thash );
1414
1418
}
1415
1419
zval_ptr_dtor (& ref );
1416
-
1417
- /* restore the fcall info and cache */
1418
- BG (array_walk_fci ) = orig_array_walk_fci ;
1419
- BG (array_walk_fci_cache ) = orig_array_walk_fci_cache ;
1420
1420
} else {
1421
1421
ZVAL_COPY (& args [0 ], zv );
1422
1422
1423
1423
/* Call the userland function */
1424
- result = zend_call_function (& BG ( array_walk_fci ) , & BG ( array_walk_fci_cache ) );
1424
+ result = zend_call_function (& fci , & context -> fci_cache );
1425
1425
if (result == SUCCESS ) {
1426
1426
zval_ptr_dtor (& retval );
1427
1427
}
@@ -1458,33 +1458,22 @@ static int php_array_walk(zval *array, zval *userdata, int recursive) /* {{{ */
1458
1458
zend_hash_iterator_del (ht_iter );
1459
1459
return result ;
1460
1460
}
1461
- /* }}} */
1462
1461
1463
1462
/* {{{ Apply a user function to every member of an array */
1464
1463
PHP_FUNCTION (array_walk )
1465
1464
{
1466
1465
zval * array ;
1467
1466
zval * userdata = NULL ;
1468
- zend_fcall_info orig_array_walk_fci ;
1469
- zend_fcall_info_cache orig_array_walk_fci_cache ;
1470
-
1471
- orig_array_walk_fci = BG (array_walk_fci );
1472
- orig_array_walk_fci_cache = BG (array_walk_fci_cache );
1467
+ php_array_walk_context context ;
1473
1468
1474
1469
ZEND_PARSE_PARAMETERS_START (2 , 3 )
1475
1470
Z_PARAM_ARRAY_OR_OBJECT_EX (array , 0 , 1 )
1476
- Z_PARAM_FUNC (BG ( array_walk_fci ), BG ( array_walk_fci_cache ) )
1471
+ Z_PARAM_FUNC (context . fci , context . fci_cache )
1477
1472
Z_PARAM_OPTIONAL
1478
1473
Z_PARAM_ZVAL (userdata )
1479
- ZEND_PARSE_PARAMETERS_END_EX (
1480
- BG (array_walk_fci ) = orig_array_walk_fci ;
1481
- BG (array_walk_fci_cache ) = orig_array_walk_fci_cache ;
1482
- return
1483
- );
1484
-
1485
- php_array_walk (array , userdata , 0 );
1486
- BG (array_walk_fci ) = orig_array_walk_fci ;
1487
- BG (array_walk_fci_cache ) = orig_array_walk_fci_cache ;
1474
+ ZEND_PARSE_PARAMETERS_END ();
1475
+
1476
+ php_array_walk (& context , array , userdata , 0 );
1488
1477
RETURN_TRUE ;
1489
1478
}
1490
1479
/* }}} */
@@ -1494,26 +1483,16 @@ PHP_FUNCTION(array_walk_recursive)
1494
1483
{
1495
1484
zval * array ;
1496
1485
zval * userdata = NULL ;
1497
- zend_fcall_info orig_array_walk_fci ;
1498
- zend_fcall_info_cache orig_array_walk_fci_cache ;
1499
-
1500
- orig_array_walk_fci = BG (array_walk_fci );
1501
- orig_array_walk_fci_cache = BG (array_walk_fci_cache );
1486
+ php_array_walk_context context ;
1502
1487
1503
1488
ZEND_PARSE_PARAMETERS_START (2 , 3 )
1504
1489
Z_PARAM_ARRAY_OR_OBJECT_EX (array , 0 , 1 )
1505
- Z_PARAM_FUNC (BG ( array_walk_fci ), BG ( array_walk_fci_cache ) )
1490
+ Z_PARAM_FUNC (context . fci , context . fci_cache )
1506
1491
Z_PARAM_OPTIONAL
1507
1492
Z_PARAM_ZVAL (userdata )
1508
- ZEND_PARSE_PARAMETERS_END_EX (
1509
- BG (array_walk_fci ) = orig_array_walk_fci ;
1510
- BG (array_walk_fci_cache ) = orig_array_walk_fci_cache ;
1511
- return
1512
- );
1513
-
1514
- php_array_walk (array , userdata , 1 );
1515
- BG (array_walk_fci ) = orig_array_walk_fci ;
1516
- BG (array_walk_fci_cache ) = orig_array_walk_fci_cache ;
1493
+ ZEND_PARSE_PARAMETERS_END ();
1494
+
1495
+ php_array_walk (& context , array , userdata , 1 );
1517
1496
RETURN_TRUE ;
1518
1497
}
1519
1498
/* }}} */
0 commit comments