php: design record for the PHP back end (step 1 of #64) #702

Closed
opened 2026-10-30 19:43:36 +00:00 by orion · 3 comments
Collaborator

Context

Step 1 of epic #64 (PHP back end), the same first step #63 took for JavaScript (design record, then slices). #62 is decided and landed (PR #686: PHP floor 5.6 with a 7.4 fallback), so the design can be written. The JavaScript record (docs/design/JAVASCRIPT-BACKEND.md) and its slices (#678, #684, #701) are the model.

Source

  • docs/design/JAVASCRIPT-AND-PHP.md sections 2b (capability table), 2d (floor 5.6, fallback 7.4, what 5.6 cannot assume) and 3.
  • docs/design/JAVASCRIPT-BACKEND.md (the template: layout, construct table, kernel K1 to K8, memory, tasks, slice table).
  • docs/design/NATIVES.md (kernel), docs/design/DESTRUCTORS.md section 2a, docs/design/CONCURRENCY.md.
  • Landed JS precedent: compiler/src/backend/javascript/, runtime/javascript/, tools/conformance.sh --js, .forgejo/workflows/gates.yml job conformance-js, .forgejo/actions/node.

Goal

Add docs/design/PHP.md, a design record from which the back end can be built in slices. It covers the module layout (compiler/src/backend/php/{emit,body,type,natives,writer}.trb, runtime/php/{core,int64,libm,tasks}.php), the target and driver, the shape of the output, the IR construct by construct, the kernel K1 to K8, memory, tasks, errors and exit codes, the CI action and conformance leg, the slice table with an acceptance test per slice, and a first slice precise enough to file. Docs only: no compiler, std or runtime change.

Decided by the loop

The record carries these; none needs the owner.

  • Target linux-php: system Linux, new architecture Php (TargetArchitecture.Php, Architecture.Php); no C compiler involved; refuses to start on a 32-bit build, a big-endian host or a non-/ directory separator.
  • Control flow by goto per block, no dispatch loop and no structuring slice (PHP has goto since 5.3); no PHP references (&) in generated code, cells are objects.
  • Integers: PHP int with an is_int overflow test (an overflowing + - * always yields a float); the smallest value is emitted as (-9223372036854775807 - 1); division and remainder guarded and truncating; UInt64 as a signed bit reinterpretation with runtime helpers on 32-bit halves.
  • Text: PHP byte strings, compared only with === and strcmp (never ==, <, loose in_array); floats shown by the manifest's own routine, never by a cast (locale); names mangled to lower case with the function index.
  • Floats: pack/unpack with d, f and V only (no q, e), round and trunc in the runtime, libm answered as in the JavaScript record.
  • Representations: classes with f0... properties for records and variants, closures as {f (function name), e}, witnesses as arrays of function names, buffer objects; rc only where MakeUnique/Write or Closing.holding apply; no __destruct.
  • Tasks are the IR's state machines on a run queue, waiting in one stream_select call; no Fibers, ext-uv, ext-ev or generators. This amends the "Tasks in PHP" bullet and the "No Fibers" accelerator sentence of JAVASCRIPT-AND-PHP.md.
  • Errors: panic is exit(101) after flushing, no exceptions and no try; 102 for out of memory via a shutdown function with a reserved string; notices and warnings are internal errors (exit 70); recursion-depth counter in recursive cycles.
  • CI: action .forgejo/actions/php (pinned by version and SHA-256) with 5.6.40, 7.4.33 and 8.4.x; job conformance-php; leg tools/conformance.sh --php with CONFORMANCE_PHP; php.allow first, .nophp markers in the last slice.
  • Unmeasured: the machine that writes the record has no PHP, so the record says which statements come from the PHP manual and pins each by a named test in the slice that relies on it.

Files

  • docs/design/PHP.md (new).
  • docs/design/index.md: the documents: entry and the link.
  • docs/ROADMAP.md: milestone 9 list and the one sentence on tasks in PHP.
  • docs/design/JAVASCRIPT-AND-PHP.md: header and section 1 links, the "Tasks in PHP" bullet and the "No Fibers" sentence of section 2d.

Tests

None beyond the docs gates: torb format --check and torb docs check (the record's links resolve and the index lists the file).

Acceptance criteria

  • docs/design/PHP.md exists with the sections of the JavaScript record (layout and driver, IR construct by construct, kernel, memory, tasks), an 8-row slice table with an acceptance test each, and a first slice precise enough to file
  • A section lists every PHP-behaviour statement the design leans on, with source (manual or estimate) and the slice that pins it, and says that nothing was measured
  • The links in index.md, ROADMAP.md and JAVASCRIPT-AND-PHP.md are in place and the tasks-in-PHP text matches the record
  • One commit docs(design): add the PHP back end design record; tools/check-commits.sh clean; docs gates green in forge CI (CI only, no local bootstrap or gates)

Seed

None: docs only. seed/ is untouched.

Out of scope

Any code (compiler, runtime, std, CI). The capability table (#65) and the Composer package (#66). The entry point of a web request (an open item in the record).

Dependencies

#62 (landed, PR #686).

Part of #64 (epic; do not close it).

## Context Step 1 of epic #64 (PHP back end), the same first step #63 took for JavaScript (design record, then slices). #62 is decided and landed (PR #686: PHP floor 5.6 with a 7.4 fallback), so the design can be written. The JavaScript record (`docs/design/JAVASCRIPT-BACKEND.md`) and its slices (#678, #684, #701) are the model. ## Source - `docs/design/JAVASCRIPT-AND-PHP.md` sections 2b (capability table), 2d (floor 5.6, fallback 7.4, what 5.6 cannot assume) and 3. - `docs/design/JAVASCRIPT-BACKEND.md` (the template: layout, construct table, kernel K1 to K8, memory, tasks, slice table). - `docs/design/NATIVES.md` (kernel), `docs/design/DESTRUCTORS.md` section 2a, `docs/design/CONCURRENCY.md`. - Landed JS precedent: `compiler/src/backend/javascript/`, `runtime/javascript/`, `tools/conformance.sh --js`, `.forgejo/workflows/gates.yml` job `conformance-js`, `.forgejo/actions/node`. ## Goal Add `docs/design/PHP.md`, a design record from which the back end can be built in slices. It covers the module layout (`compiler/src/backend/php/{emit,body,type,natives,writer}.trb`, `runtime/php/{core,int64,libm,tasks}.php`), the target and driver, the shape of the output, the IR construct by construct, the kernel K1 to K8, memory, tasks, errors and exit codes, the CI action and conformance leg, the slice table with an acceptance test per slice, and a first slice precise enough to file. Docs only: no compiler, std or runtime change. ## Decided by the loop The record carries these; none needs the owner. - **Target `linux-php`**: system `Linux`, new architecture `Php` (`TargetArchitecture.Php`, `Architecture.Php`); no C compiler involved; refuses to start on a 32-bit build, a big-endian host or a non-`/` directory separator. - **Control flow by `goto` per block**, no dispatch loop and no structuring slice (PHP has `goto` since 5.3); no PHP references (`&`) in generated code, cells are objects. - **Integers**: PHP `int` with an `is_int` overflow test (an overflowing `+ - *` always yields a `float`); the smallest value is emitted as `(-9223372036854775807 - 1)`; division and remainder guarded and truncating; `UInt64` as a signed bit reinterpretation with runtime helpers on 32-bit halves. - **Text**: PHP byte strings, compared only with `===` and `strcmp` (never `==`, `<`, loose `in_array`); floats shown by the manifest's own routine, never by a cast (locale); names mangled to lower case with the function index. - **Floats**: `pack`/`unpack` with `d`, `f` and `V` only (no `q`, `e`), `round` and `trunc` in the runtime, libm answered as in the JavaScript record. - **Representations**: classes with `f0...` properties for records and variants, closures as `{f (function name), e}`, witnesses as arrays of function names, buffer objects; `rc` only where `MakeUnique`/`Write` or `Closing.holding` apply; no `__destruct`. - **Tasks are the IR's state machines on a run queue**, waiting in one `stream_select` call; no Fibers, `ext-uv`, `ext-ev` or generators. This amends the "Tasks in PHP" bullet and the "No Fibers" accelerator sentence of `JAVASCRIPT-AND-PHP.md`. - **Errors**: panic is `exit(101)` after flushing, no exceptions and no `try`; 102 for out of memory via a shutdown function with a reserved string; notices and warnings are internal errors (exit 70); recursion-depth counter in recursive cycles. - **CI**: action `.forgejo/actions/php` (pinned by version and SHA-256) with 5.6.40, 7.4.33 and 8.4.x; job `conformance-php`; leg `tools/conformance.sh --php` with `CONFORMANCE_PHP`; `php.allow` first, `.nophp` markers in the last slice. - **Unmeasured**: the machine that writes the record has no PHP, so the record says which statements come from the PHP manual and pins each by a named test in the slice that relies on it. ## Files - `docs/design/PHP.md` (new). - `docs/design/index.md`: the `documents:` entry and the link. - `docs/ROADMAP.md`: milestone 9 list and the one sentence on tasks in PHP. - `docs/design/JAVASCRIPT-AND-PHP.md`: header and section 1 links, the "Tasks in PHP" bullet and the "No Fibers" sentence of section 2d. ## Tests None beyond the docs gates: `torb format --check` and `torb docs check` (the record's links resolve and the index lists the file). ## Acceptance criteria - [ ] `docs/design/PHP.md` exists with the sections of the JavaScript record (layout and driver, IR construct by construct, kernel, memory, tasks), an 8-row slice table with an acceptance test each, and a first slice precise enough to file - [ ] A section lists every PHP-behaviour statement the design leans on, with source (manual or estimate) and the slice that pins it, and says that nothing was measured - [ ] The links in `index.md`, `ROADMAP.md` and `JAVASCRIPT-AND-PHP.md` are in place and the tasks-in-PHP text matches the record - [ ] One commit `docs(design): add the PHP back end design record`; `tools/check-commits.sh` clean; docs gates green in forge CI (CI only, no local bootstrap or gates) ## Seed None: docs only. `seed/` is untouched. ## Out of scope Any code (compiler, runtime, std, CI). The capability table (#65) and the Composer package (#66). The entry point of a web request (an open item in the record). ## Dependencies #62 (landed, PR #686). Part of #64 (epic; do not close it).
Author
Collaborator

[loop:torbscript] refine: ready. The record is already drafted on branch loop/702-php-design-record (commit docs(design): add the PHP back end design record, 4 docs files); the implementer should review it against the Goal and Acceptance criteria, fix what the docs gates (CI) report and open the PR Closes #702. Nothing was run locally (no PHP, no gates).

[loop:torbscript] refine: ready. The record is already drafted on branch `loop/702-php-design-record` (commit `docs(design): add the PHP back end design record`, 4 docs files); the implementer should review it against the Goal and Acceptance criteria, fix what the docs gates (CI) report and open the PR `Closes #702`. Nothing was run locally (no PHP, no gates).
Author
Collaborator

[loop:torbscript] claim implementation by session:loop-torbscript-20261030 @anthropic:tkoehn until 2026-10-31T04:04Z

[loop:torbscript] claim implementation by session:loop-torbscript-20261030 @anthropic:tkoehn until 2026-10-31T04:04Z
Author
Collaborator

[loop:torbscript] release implementation by session:loop-torbscript-20261030 @anthropic:tkoehn: the worker run was cancelled after opening PR #707 (head 302c20c9, mergeable, argus requested); CI on that head is pending. Release of the claim.
next: waiting (CI and review of PR #707)

[loop:torbscript] release implementation by session:loop-torbscript-20261030 @anthropic:tkoehn: the worker run was cancelled after opening PR #707 (head 302c20c9, mergeable, argus requested); CI on that head is pending. Release of the claim. next: waiting (CI and review of PR #707)
argus closed this issue 2026-10-30 22:49:59 +00:00
Sign in to join this conversation.
No labels
loop
ready
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#702
No description provided.