Skip to content

Language: foreach by-reference on property hooks must invoke set hook (zend_property_hooks.c) #6435

Description

@PurHur

Category

language

Problem

foreach ($iterable as &$hookedProp) (and foreach ($iterable as $k => &$hookedProp)) must route writes through the property set hook and reads through the get hook, matching Zend zend_property_hooks.c. This compiler’s foreach-by-ref path (lib/VM.php / lib/JIT.php) updates backing slots directly for hooked instance properties.

Distinct from #4599 (Generator foreach by-ref) and #4431 (array foreach parity).

php-src reference

Repro

Save as test/repro-maintainer/parity_property_hook_foreach_byref.php:

<?php
class Acc {
    private int $_n = 0;
    public int $total {
        get => $this->_n;
        set => $this->_n = $value * 10;
    }
}
$c = new Acc();
foreach ([1, 2, 3] as &$c->total) {
    $c->total++;
}
echo $c->total, "\n";
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php test/repro-maintainer/parity_property_hook_foreach_byref.php
php bin/vm.php test/repro-maintainer/parity_property_hook_foreach_byref.php
'
Runtime Output
Zend PHP 8.4+ 40 (hooked scaling; exact value follows Zend stepping)
VM today backing increment without hook scaling (wrong)

Compliance: test/compliance/cases/language/property_hook_foreach_byref.phpt

Scope (this repo)

Path Work
lib/VM.php FE_FETCH by-ref on hooked property lvalues
lib/JIT.php / lib/JIT/PropertyHookDispatch.php JIT lowering or VM deferral
Tests VM baseline; JIT when lowering exists

Done when

  • Repro output matches Zend on VM
  • unset($ref) after foreach restores hook semantics (Zend ZEND_FE_FREE)
  • ./script/ci-fast.sh --filter property_hook_foreach_byref green

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:compilerCompiler / CFG / JITarea:vmVirtual machineenhancementNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language features

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions