Skip to content

[ php-wasm ] Keep constant attributes in the PHP 8.5 OPcache file cache - #4499

Draft
mho22 wants to merge 3 commits into
trunkfrom
opcache-attributed-const-file-cache
Draft

mho22 wants to merge 3 commits into
trunkfrom
opcache-attributed-const-file-cache

Conversation

@mho22

@mho22 mho22 commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes PHP 8.5 on php-wasm when OPcache stores a script that declares an attribute on a constant, such as #[Deprecated] const FOO = 1;. symfony/polyfill-uuid 1.43.0 declares such constants in bootstrap85.php.

Why

I found this bug in Laravel Snippets. Its weekly "Refresh snippet sweep report" workflow runs Laravel snippets in Playground on PHP 8.5. The sweep now crashes with "Target crashed" when it loads symfony/polyfill-uuid 1.43.0. It passed on 2026-09-28 and failed on 2026-10-05, 2026-10-12 and 2026-10-19.

This PR patches PHP 8.5 in php8.5.patch until php-src fixes the bug. A php-src PR follows. When a PHP 8.5 release includes that fix, the hunk can go.

Cause

zend_file_cache_serialize_op_array() in ext/opcache/zend_file_cache.c serializes the attributes of each ZEND_DECLARE_ATTRIBUTED_CONST through the literal in the next ZEND_OP_DATA opline. On 32-bit builds, ZEND_USE_ABS_CONST_ADDR is set, so RT_CONSTANT() returns a pointer into script->mem, not into the serialization buffer. The serializer then rewrites the live script and writes a raw pointer to the .bin file. wasm32 is a 32-bit target. The persist and unserialize code are correct. The bug is also on php-src master, and no php-src issue exists yet.

Commits

  1. A failing test in php-opcache.spec.ts that reads the constant attribute from the compiled script and again from the file cache.
  2. The fix in php8.5.patch.
  3. The PHP 8.5 binaries rebuilt with the fix, from PHP 8.5.12. lastRelease goes from 8.5.10 to 8.5.12, and the web/README.md examples follow.

Testing

keeps constant attributes in the file cache in php-opcache.spec.ts:

Binaries Node JSPI Node Asyncify Web JSPI Web Asyncify
trunk, 8.5.10 fails fails fails fails
this PR, 8.5.12 passes passes passes passes

On Node 24, WebAssembly.Suspending exists without a flag, so test-group-N-asyncify also loads the JSPI binary. The Asyncify columns come from a temporary spec that loads the Asyncify glue directly.

Node JSPI groups 1 to 6 on this PR's binaries: all pass except 4 Imagick tests in group 2, on PHP 7.4 and 8.0. These tests download image.jpg from raw.githubusercontent.com and time out after 5 s. This PR does not touch those binaries.

Also run: npx nx test php-wasm-web (79 pass), npx nx test php-wasm-compile-extension (37 pass), npx nx lint php-wasm-node. php8.5.patch applies to php-src php-8.5.10, and the new hunk applies alone to php-src master.

PHP 8.5 adds attributes on constants. On php-wasm, OPcache corrupts these attributes when it writes the script to the file cache. The new test compiles a file that declares `#[Deprecated(message: 'bar')] const FOO`, then reads the attribute arguments again from the cached script. The test fails on the current PHP 8.5.10 binaries.
@coderabbitai

coderabbitai Bot commented Oct 22, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

On 32-bit builds, `ZEND_USE_ABS_CONST_ADDR` is set, so `RT_CONSTANT()` returns a pointer into `script->mem`, not into the serialization buffer. `zend_file_cache_serialize_op_array()` then rewrites the attributes of `ZEND_DECLARE_ATTRIBUTED_CONST` in the live script and writes a raw pointer to the file cache. The `php8.5.patch` hunk moves the literal pointer into the buffer before `SERIALIZE_ATTRIBUTES()`.
@mho22 mho22 changed the title [PHP] Keep constant attributes in the PHP 8.5 OPcache file cache [ php-wasm ] Keep constant attributes in the PHP 8.5 OPcache file cache Oct 22, 2026
Rebuild the web and Node.js binaries, JSPI and Asyncify, for PHP 8.5 with the `php8.5.patch` fix. The build uses the 8.5.12 release tag, so `8_5_10/` becomes `8_5_12/` and the README examples follow.

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant