Skip to content

merge: cascade 8.4 into master - #181

Closed
github-actions[bot] wants to merge 12 commits into
masterfrom
8.4
Closed

merge: cascade 8.4 into master#181
github-actions[bot] wants to merge 12 commits into
masterfrom
8.4

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Automated cascade merge of 8.4 into master (branch flow defined in .github/branch-flow.json).

Resolve conflicts in favour of the newer engine structures where they touch include/ - regenerate headers on the target branch instead of merging them textually. See AGENTS.md.

claude and others added 12 commits August 8, 2026 18:19
Mirrors the darwin bootstrap: a "Generate windows headers" workflow builds
the windows-x64-{nts,zts} FFI definitions on real Windows runners (clang via
the MSVC INCLUDE environment) and commits them back to the branch, while CI
gains tests-windows and header-drift-windows legs that warn and skip until
the artifacts are committed. The FFI preflights bind the engine DLL
explicitly and prove __vectorcall (@@N-mangled) symbols resolve - the two
things Windows does differently from every POSIX platform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
README gains windows-x64 (nts, zts) in the 8.4 support row; AGENTS.md gets a
Windows artifacts section covering the four load-bearing platform
differences (FFI_LIB/DLL binding, __vectorcall export mangling, devel-pack
headers instead of php-config, ucrtbase free) and the #119 exclusions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
Windows has no process-image symbol resolution, so Core::init() now passes
the engine DLL (php8.dll / php8ts.dll, already loaded by php.exe) to
FFI::cdef, which ignores the header's FFI_LIB define. platformKey()
lowercases php_uname('m') - Windows reports AMD64 and previously fell
through to a windows-AMD64-* key - and becomes public so the artifact tests
stop carrying their own copy of the mapping. persistentFree() binds
ucrtbase.dll on Windows: the PHP DLL does not export libc free, while
pemalloc draws from that same process-wide UCRT heap. PayloadRelocator
gains an isSupported() predicate so its tests can skip instead of erroring
on unsupported platforms (#118 ZTS, #119 Windows).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
ResidentMemory reports 0 (not measurable) on Windows instead of shelling
out to a ps that does not exist; the rm -rf teardown in BinaryCacheFileTest
becomes a portable recursive delete; the relocator suites skip via
PayloadRelocator::isSupported() rather than erroring on the constructor
guard; and the opcache.preload-dependent tests (ClassSpecializerShmTest,
the preload leg of OpcacheSupportMatrixTest) plus the POSIX-path file-cache
fixture skip on Windows, where preload does not exist and the cache layout
differs (#119).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
Ports the native pipeline to Windows. generate.php resolves the matching
php-devel-pack from windows.php.net (releases.json, sha256-verified, cached
in temp, --php-dev override, archives fallback) since Windows has no
php-config; emit.php gains --include-dir to derive the -I set from the pack
and passes -DZEND_WIN32/-DPHP_WIN32/-DWIN32/-D_MBCS (+-DZTS) explicitly -
on Windows those come from build CFLAGS, not any header. All subprocess
spawns move to proc_open argv arrays (no cmd.exe quoting, no POSIX-only
shell builtins); the probe compiles with clang -o probe.exe and runs via
cwd. The emitter converts clang's __attribute__((vectorcall)) qualType
annotation into the __vectorcall keyword FFI mangles to the DLL's decorated
name@@n exports (the attribute spelling is silently ignored by FFI), hard
guards against zero-argument __vectorcall declarations (upstream FFI
NULL-deref), and strips the MSVC-only tokens system headers leak while
preserving __declspec(align). Windows headers carry FFI_LIB naming the
engine DLL, 'free' leaves the Windows manifest (the DLL does not export the
CRT), _iobuf joins the opaque libc types, and validate.php accepts the DLL
so cdef eagerly resolves every declared function at generation time.

Linux artifact generation stays byte-identical (verified against the
committed linux-x64-nts artifacts after every refactor).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
proc_open resolves a relative program path against the parent's cwd on
macOS, so './probe' with a cwd argument failed there with posix_spawn
ENOENT - the absolute path works everywhere while cwd still controls where
the probe writes its outputs. The Windows generation and drift jobs add
ext-zip to setup-php: generate.php extracts the devel pack with ZipArchive,
which Windows builds do not enable by default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
Like the other Windows configuration macros it comes from the build's
CFLAGS, not from any installed header. Preprocessing survived without it
(#if reads an undefined macro as 0) but the probe uses ZEND_DEBUG as a C
expression for the layouts meta, which needs a real definition.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
… DLL in the raw-cdef scenario

Three findings from the first real Windows test run (425 tests, 2
failures). clang's -E output goes through the CRT in text mode on Windows,
so the sliced declarations carried CRLF into engine.h and tripped the
drift check - pre.c is normalized before the AST pass so offsets and
artifacts stay LF everywhere. EG(timed_out) reads back as a one-byte
string on MSVC builds (the non-C11 atomic fallback stores a char), so
isTimedOut() accepts that shape; the int-write in requestInterrupt()
already works as proven by the passing interrupt tests. The throw-hook
scenario's deliberate raw FFI::cdef now names the engine DLL on Windows,
where process-image resolution does not exist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj
The generation workflow's commit lands with GITHUB_TOKEN and cannot
retrigger CI itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0188iU6pEvBQgtjPTXEdzHwj

Copy link
Copy Markdown
Owner

Superseded by #182, which carries this cascade with the conflicts resolved (README support matrix, docblock version strings) and the master-line adaptations (generate-windows-headers.yml pinned to PHP 8.5, AGENTS.md wording). The 8.5 windows artifacts bootstrap on that PR via the generation workflow.


Generated by Claude Code

@lisachenko lisachenko closed this Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants