Skip to content

Stdlib: empty construct, fmod, and float min/max - #7

Merged
PurHur merged 1 commit into
masterfrom
stdlib-empty-fmod-minmax
May 17, 2026
Merged

Stdlib: empty construct, fmod, and float min/max#7
PurHur merged 1 commit into
masterfrom
stdlib-empty-fmod-minmax

Conversation

@PurHur

@PurHur PurHur commented May 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • Implement the empty() language construct in the VM and JIT (reuses boolval truthiness rules).
  • Add fmod() for integer and float operands with VM and JIT paths via libm.
  • Extend min() / max() to accept float and mixed numeric pairs.
  • Add compliance PHPT specs and an integration test.

Test plan

  • make test passes VM and JIT compliance suites in Docker
  • test/compliance/cases/stdlib/empty.phpt passes
  • test/compliance/cases/stdlib/fmod.phpt passes
  • test/compliance/cases/stdlib/min_max_float.phpt passes
  • test/real/cases/stdlib_empty_fmod.phpt passes

Made with Cursor

Implement the empty() language construct in VM and JIT, add fmod() via libm,
extend min/max for float operands, and add compliance and integration PHPT specs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@PurHur
PurHur merged commit fde1020 into master May 17, 2026
@PurHur
PurHur deleted the stdlib-empty-fmod-minmax branch May 17, 2026 10:46
PurHur added a commit that referenced this pull request Jul 28, 2026
… (Phase 2.5) (#24387)

RELEASE-PLAN Phase 2.5 wants extensions to become separate, discoverable, side-loadable modules. The
blocker measured in #24285: Module declares no dependencies and no default-enabled flag, so the set
cannot be selected per build and the load order lives only in a hand-maintained list in
Runtime::loadCoreModules().

Adds two declarations, with defaults in ModuleAbstract that preserve current behaviour exactly:

  getExtensionDependencies(): list<string>   default []      — ordering constraints, today implicit
  isDefaultEnabled(): bool                   default true    — all 76 load unconditionally now

Safe to add to the interface: all 76 ext/*/Module.php extend ModuleAbstract and it is the only
implementor, so nothing needs updating.

Declares the libxml family, where the constraint is real and currently only remembered — php-src
ext/dom, simplexml, xml, xmlreader, xmlwriter build on ext/libxml, and xsl additionally on dom:

  dom, simplexml, xml, xmlreader, xmlwriter -> libxml
  xsl -> libxml, dom

A declaration nobody verifies is worse than none — it reads as authoritative while being free to
drift — so script/check-extension-dependencies.php asserts every declared dependency exists, is
loaded, and loads BEFORE its dependent in Runtime::loadCoreModules(). It reorders nothing; its job is
to prove the declarations describe reality, which is the precondition for later deriving the order
from them instead of hand-maintaining it.

Validated in both directions:

  as declared                          ok — 6 extensions, 7 edges, all satisfied
  with dom -> xsl (xsl loads later)    FAILED: dom (load #6) declares dependency "xsl" but xsl
                                       loads later at #7                              exit 1

Nothing consumes isDefaultEnabled() yet. The declaration comes first so the set can be made
selectable without a flag day.

Gate (touches lib/Module.php and lib/ModuleAbstract.php, which every extension implements), branch
vs a clean master checkout, run sequentially, both cold, waiting for each sweep to COMPLETE before
diffing:

  cold aot-smoke : 8/8 both sides
  VM  --repeat 2 : 110/110 both sides, exit 0
  AOT --repeat 3 : master 18 failing, branch 18 failing
                   regressions (branch-only): NONE
                   fixed (master-only)      : NONE

Co-authored-by: PurHur <tedyyyyy@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant