Skip to content

WIP: POE support (#433)#436

Open
fglock wants to merge 13 commits intomasterfrom
feature/poe-support
Open

WIP: POE support (#433)#436
fglock wants to merge 13 commits intomasterfrom
feature/poe-support

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 4, 2026

Summary

  • Initial analysis of POE 1.370 compatibility
  • ~15/97 test files currently pass
  • Plan document at dev/modules/poe.md with 7 identified root causes

Root causes (priority order)

  1. P0: exists(&sub) fails in require context — blocks IO::Socket::INET loading
  2. P0: use vars globals not visible across files under use strict
  3. P1: Symbol.pm $VERSION not set in Java module
  4. P1: POSIX missing errno/signal constants and uname()
  5. P1: Indirect method call syntax (import $pkg ())
  6. P2: POE constants as barewords (cascade from P0)
  7. P3: IO::Tty/IO::Pty need native PTY (JVM limitation)

Test plan

  • Fix exists(&sub) in require context
  • Fix cross-file use vars under strict
  • Set Symbol.pm $VERSION
  • Add POSIX errno/signal constants
  • Re-run ./jcpan -t POE and update plan

Generated with Devin

@fglock fglock force-pushed the feature/poe-support branch from 6b9fa2c to 97023ad Compare April 4, 2026 15:26
fglock and others added 10 commits April 4, 2026 20:12
Analyzed POE 1.370 test results (~15/97 pass). Identified 7 root causes:
- P0: exists(&sub) fails in require context (blocks IO::Socket::INET)
- P0: use vars globals not visible across files under strict
- P1: Symbol.pm $VERSION not set in Java module
- P1: POSIX missing errno/signal constants and uname()
- P1: indirect method call syntax (import $pkg ())
- P2: POE constants as barewords cascade from P0
- P3: IO::Tty/IO::Pty need native PTY (JVM limitation)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Fix ConstantFoldingVisitor corrupting AST for exists(&Errno::EINVAL)
  by skipping folding of & (code sigil) operands
- Add PF_UNSPEC and SOMAXCONN to Socket module (needed by IO::Pipely)
- Add POSIX signal constants (SIGHUP..SIGTSTP) with macOS/Linux values
- Add POSIX errno constants (EPERM..ERANGE)
- Add POSIX::uname(), sigprocmask() stub, SigSet/SigAction stubs
- Add SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK/SIG_DFL/SIG_IGN/SIG_ERR
- Set Symbol::$VERSION to 1.09

Result: use POE now loads successfully.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Add parsingIndirectObject flag to Parser to allow $var( pattern
  in indirect object context (e.g., import $package (), new $class (args))
- Fix ConcurrentModificationException in hash each() by snapshotting
  entries at iterator creation time, matching Perl tolerance for
  hash modification during each() iteration
- These fixes unblock POE::Filter::Reference (import $package () syntax)
  and POE::Resource::Aliases (each + delete pattern)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Perl's %SIG hash is pre-populated with all available OS signal names
as keys (with undef values). Modules like POE rely on `keys %SIG` to
discover which signals are available. Without this, POE's signal
handling was completely broken because _data_sig_initialize() found
no signals to register.

The fix adds a constructor to RuntimeSigHash that populates the hash
with POSIX signals and platform-specific signals (macOS: EMT, INFO,
IOT; Linux: CLD, STKFLT, PWR, IOT).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…aner

Uses Cleaner to detect when blessed objects become unreachable and
schedules DESTROY calls on the main thread at safe points. Per-blessId
cache makes the check O(1) for repeated bless calls. Exceptions in
DESTROY are caught and printed as "(in cleanup)" warnings matching Perl
behavior.

- DestroyManager: new class managing Cleaner registration, pending queue,
  and proxy object creation for DESTROY calls
- ReferenceOperators: call registerForDestroy at bless time
- PerlSignalQueue: check pending DESTROYs at safe points
- PerlLanguageProvider: run global destruction after END blocks

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Perl foreach iterates over elements pushed to the array during the
loop. The iterator was caching the array size at creation time, missing
new elements. Now checks elements.size() dynamically on each hasNext().

This fixes POE::Kernel->stop() which uses the foreach-push pattern to
walk the session tree.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…OY findings

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Fix parser to handle require File::Spec->catfile(...) as an expression
  rather than treating File::Spec as a module name. This allows POE to
  dynamically load Time::HiRes via require.

- Add non-blocking I/O support for internal pipe handles: InternalPipeHandle
  now supports setBlocking/isBlocking, and sysread returns undef with
  EAGAIN (errno 11) when non-blocking and no data available.

- Fix IO::Handle::blocking() to properly delegate to the underlying handle
  blocking state, and fix argument passing (shift on glob copy issue).

- Add FileDescriptorTable for managing file descriptors and implement
  4-argument select() (pselect-style) for POE I/O multiplexing.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the feature/poe-support branch from 97023ad to 88b698a Compare April 4, 2026 18:13
fglock and others added 3 commits April 4, 2026 20:20
DestroyManager.registerForDestroy used Math.abs(blessId) as the cache
key, but overloaded classes have negative blessIds (-1, -2, ...).
Math.abs(-1) = 1 collided with normal class IDs, causing getBlessStr
to return null and triggering a NullPointerException in
normalizeVariableName.

Fix: use the original blessId directly as the cache key in all three
places (registerForDestroy, invalidateDestroyCache, processPendingDestroys).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…is fragile

The Cleaner-based DESTROY implementation used proxy objects to reconstruct
blessed references after GC. This caused:
- close() inside DESTROY corrupting proxy hash access (File::Temp bug)
- Overloaded class blessId collisions (Math.abs on negative IDs)
- Incomplete reconstruction for tied/magic/overloaded objects

Tied variable DESTROY (TieScalar.tiedDestroy) is unaffected — it uses
scope-based cleanup. Updated dev/design/object_lifecycle.md with findings
and future directions (scope-based ref counting recommended over GC proxy).

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Bug 9: Updated to ATTEMPTED AND REVERTED with explanation of proxy
  reconstruction failures (close() corruption, blessId collision)
- Bug 11: require File::Spec->catfile() parser fix
- Bug 12: Non-blocking I/O for pipe handles
- Bug 13: DestroyManager Math.abs(blessId) collision
- Added Phase 3.2 to progress tracking
- Updated Key Findings with DESTROY proxy failure analysis

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.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