Repository navigation
Closed
Labels
area:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsPhase 4 – stdlib for web apps
Description
Category
stdlib | language
Problem
PHP 8.4 array_first() / array_last() must return the first/last array element as stored, including backed enum case objects. VM today materializes int-backed cases to their backing scalar (int(1) / int(2) instead of E::A / E::B).
Verified on master:
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/vm.php -r "enum E: int { case A=1; case B=2; } \$a=[E::A,E::B]; var_dump(array_first(\$a), array_last(\$a));"'
# int(1) int(2) — wrongZend PHP 8.4+ returns enum objects (same identity as input elements). Distinct from #8899 (pointer walkers) and #6949 ($strict third parameter).
php-src reference
- php/php-src
ext/standard/array.c—PHP_FUNCTION(array_first),PHP_FUNCTION(array_last) - php/php-src
Zend/zend_hash.c—zend_hash_get_current_data_ex/ end pointer walk without scalarizing enums
Repro
test/repro-maintainer/parity_array_first_last_enum.php:
<?php
enum E: int { case A = 1; case B = 2; }
$a = [E::A, E::B];
$first = array_first($a);
$last = array_last($a);
var_export($first === E::A);
echo "\n";
var_export($last === E::B);
echo "\n";
var_export($first instanceof E);
echo "\n";./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro-maintainer/parity_array_first_last_enum.php
php bin/vm.php test/repro-maintainer/parity_array_first_last_enum.php'| Check | Zend 8.4+ | VM today |
|---|---|---|
array_first([E::A, E::B]) === E::A |
true |
false (int 1) |
array_last(...) === E::B |
true |
false (int 2) |
Scope (PHP-in-PHP, php-src-strict)
| Path | Work |
|---|---|
ext/standard/VmArray.php |
valueFirst() / valueLast() — preserve enum objects from HashTable iteration |
lib/VM/HashTable.php |
If iterCurrentValue() / copyFrom scalarizes enums, fix shared path (reuse EnumCaseSupport guards) |
ext/standard/array_first.php, array_last.php |
VM entry unchanged if helper fixed |
lib/JIT/Builtin/ |
JIT lowering for array_first/array_last if enum boxes are coerced in IR |
| Tests | test/compliance/cases/stdlib/array_first_enum.phpt |
Done when
- Repro prints
truefor all threevar_exportlines onbin/vm.php(php-src-strict) - Empty-array
array_first([])still returnsnullon VM -
./script/ci-fast.sh --filter array_firstgreen (or targeted PHPUnit) - No new C in
runtime/— enum preservation belongs in PHP VM/JIT paths
Related
- Stdlib: current()/prev()/next()/end()/reset() materialize enum cases to backing scalars (ext/standard/array.c) #8899, Stdlib: array_values()/array_merge() on enum case arrays coerces to backed scalars (ext/standard/array.c) #5547, Epic: Self-host critical path — compiler compiles itself (M3→M5) #1492
Metadata
Metadata
Assignees
Labels
area:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-4:stdlibPhase 4 – stdlib for web appsPhase 4 – stdlib for web apps
Activity
PurHur commentedon Jun 27, 2026
claim: cursor-agent-lane-c — batch (issues #8987)
PurHur commentedon Jun 27, 2026
claim released: cursor-agent-lane-c — repro green on master (enum cases preserved); pivoting to #4403.
PurHur commentedon Jul 2, 2026
claim: worker-lane-c — batch (issues #9263, #9212, #8987)
PurHur commentedon Jul 2, 2026
claim released: worker-lane-c — already green on master (enum identity repro prints true/true/true).
PurHur commentedon Jul 5, 2026
claim: cursor-agent-lane-c — starting this run
PurHur commentedon Jul 7, 2026
claim: worker-lane-C — starting this run
PurHur commentedon Jul 7, 2026
claim released: repro green on master with PHP_COMPILER_PROFILE=8.4 — array_first/last return enum(E::A)/enum(E::B); array_first_last_enum_jit.phpt passes VM+JIT.
PurHur commentedon Jul 13, 2026
Stale on master (lane C hygiene, 2026-07-13): repro green on Zend + VM. Verified via
./script/docker-exec.sh— no code change needed.