Skip to content

fix: require/do trailing value & CPANPLUS jcpan bootstrap#750

Open
fglock wants to merge 6 commits into
masterfrom
fix/cpanplus-require-jcpan-parity
Open

fix: require/do trailing value & CPANPLUS jcpan bootstrap#750
fglock wants to merge 6 commits into
masterfrom
fix/cpanplus-require-jcpan-parity

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented May 16, 2026

Summary

  • Preserve the trailing compilation-unit value for require/do: stop compilationUnitFromRequireOrDo from leaking into nested JVM/lazy-sub compilations, reset it on nested eval compilations, and teach the bytecode interpreter outer block to scalarize the last statement when JVM passes RUNTIME as the call context. Skip refactoring the outermost require/do block in LargeBlockRefactorer when it would drop the tail return path.
  • ModuleOperators.doFile: defensive truth when a require load returns an empty RuntimeList but $@ is still empty inside the $@ probe window (fixes ConfigureCPANPLUS::ConfigBackend circular BEGIN behavior).
  • Interpreter eval string parity for direct &sub(...) call sites: SubroutineParser attaches parseTimeCodeRef when parse already saw a real callable (not a bare sub name; forward stub), so BytecodeCompiler constant-pools the CV after neighbouring use/no has deleted the stash entry—matches Perl’s pinned-CV behaviour (see src/test/resources/unit/pr694_core_regressions.t) without breaking post-delete eval (see eval_after_stash_delete.t).
  • dev/modules/cpanplus.md — full rationale plus a roadmap with detailed next steps toward ./jcpan -t CPANPLUS parity (t/031 DBIx::Simple, t/20 can_load / local *, harness re-run, routine verification).

Test plan

  • make
  • timeout 120 ./jperl src/test/resources/unit/pr694_core_regressions.t
  • timeout 120 ./jperl src/test/resources/unit/eval_after_stash_delete.t
  • ./jperl smoke: PERL5LIB=…/blib/lib:…/blib/arch:… ./jperl -e 'require CPANPLUS::Config'
  • From CPANPLUS build t/: ./jperl -e 'require "./inc/conf.pl"' with matching PERL5LIB
  • timeout 3600 ./jcpan -t CPANPLUS — refresh snapshot after this PR; remaining gaps tracked in dev/modules/cpanplus.md (t/031 SQLite, t/20 Dist::MM, etc.)

Where to continue

See dev/modules/cpanplus.md“Roadmap: ./jcpan -t CPANPLUS — detailed next steps” (sections 0–6) and the progress table.

fglock and others added 5 commits May 16, 2026 20:29
…preter)

Perl require expects a defined scalar from the compilation unit trailing statement.

- Clone CompilerOptions for nested JVM subs (EmitSubroutine) and lazy named subs (SubroutineParser); clear require/do flags on eval-string compilations (EmitEval, RuntimeCode eval clones).
- Track require/do outer apply-body with JavaClassInfo; EmitBlock evaluates the unit final statement in the caller-effective context; LargeBlockRefactorer refuses whole-block refactoring of that outer require/do root.
- BytecodeCompiler: when compiling a require unit, if JVM left currentCallContext as RUNTIME, still emit the outer block last statement in scalar/caller context (mirrors EmitBlock).
- ModuleOperators.doFile: if require of a compilation unit returns an empty RuntimeList but $@ is still empty before success cleanup, treat as success (Configure → Config ⇄ Backend circular BEGIN chain).
- PerlLanguageProvider: set compilationUnitCallerContext for scalar require loads; ancillary CompilerOptions / ConstantFoldingVisitor updates from the investigation.

Documentation: add dev/modules/cpanplus.md (full jcpan parity plan including remaining BUILD_PL/SQLite/formatting gaps) and refresh dev/modules/README.md.

Generated with Composer (https://cursor.com/)

Co-Authored-By: Composer <noreply@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Repair CPANPLUS-style patterns: BUILD_PL-/stat-era ALLCAPS must not route
through filehandle-slot parsing when followed by -> or backed by package
subs. Narrow multi-dot lexer splits to bare use/no VERSION via
parseOptionalPerlBareUseVersion so module imports keep parseOptionalPackageVersion.
Delegate version.pm tuple/decimal normalization to normalizeVersionForPerlModule;
align numify fractional-slot padding.

Add regression tests; refresh dev/modules/cpanplus.md (full jcpan PASS, t/031 done).

Co-authored-by: Cursor <cursoragent@cursor.com>
PerlOnJava left $!/$^E undef on some failure paths; $! + 0 warned under
warnings. jcpan CPANPLUS is clean TAP after rebuilding shadowJar.

Update dev/modules/cpanplus.md: File::Copy resolved, roadmap item 5 done.

Co-authored-by: Cursor <cursoragent@cursor.com>
The $^A–$^Z bootstrap left $^E as a plain undef global; stock File::Copy
uses $^E + 0 and warned under use warnings.

- Non-Windows: reuse the same ErrnoVariable as $! (perlvar).
- Windows: separate ErrnoVariable so ($!,$^E)= restores both independently.

Revert File::Copy.pm to upstream ($! + 0, $^E + 0); add errno_caret_e_defined.t;
refresh dev/modules/cpanplus.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
@fglock fglock force-pushed the fix/cpanplus-require-jcpan-parity branch from 02923fb to 31a63b0 Compare May 16, 2026 18:49
- Embed parse-time CODeref snapshots via registerCompiledCodeRef only outside
  local *Glob::name CODE shadow scopes (tracked from RuntimeGlob::dynamicSaveState),
  cloning the wrapper so pooled sites keep the displaced RuntimeCode when the
  canonical glob container is mutated (op/symbolcache.t).
- Anonymize declared package CVs orphaned by *Glob = anon-sub or stash delete so
  B::GV->NAME matches Perl (op/stash.t / uni/stash.t).

Co-authored-by: Cursor <cursoragent@cursor.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