Commit b483338
* Perl::Critic support: add English.pm and fix foreach my @array scoping
Phase 1 of Perl::Critic support plan (see dev/modules/perl_critic.md):
1. Add English.pm core module - provides human-readable aliases for
Perl punctuation special variables. Required by Perl::Critic's
Build.PL via inc/Perl/Critic/BuildUtilities.pm.
2. Fix foreach statement modifier scoping bug - in
'EXPR foreach my @v = LIST', the my @v declaration was trapped
inside inner scopes (BlockNode for local and For1Node loop scope)
instead of being visible in the enclosing scope.
Fix applied at two levels:
- StatementResolver: hoist my declarations from the foreach list
expression before the BlockNode wrapper
- EmitForeach: pre-evaluate list expression before enterScope()
This fixes List::SomeUtils::PP::apply() which uses this pattern.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Update Perl::Critic plan with Phase 2 blockers; use perl5/ English.pm via sync.pl
- Switch English.pm source from system Perl (v1.11) to perl5/ tree (v1.12)
- Register English.pm in dev/import-perl5/config.yaml for sync.pl
- Document Phase 2 blockers found during jcpan test:
Readonly (Module::Build::Tiny/DynaLoader), Params::Util XS,
Pod-Parser script generation, Pod::Spell Encode
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* docs: add detailed Phase 2 blocker plan to perl_critic.md
Root-cause analysis and recommended fixes for:
- 2a: DynaLoader.pm stub (unblocks Readonly via Module::Build::Tiny)
- 2b: XSLoader PP-companion detection (unblocks PPI via Params::Util)
- 2c: MakeMaker PL_FILES non-fatal (unblocks Pod-Parser)
- 2d: Pod::Spell/Encode (deferred, optional)
Includes dependency chain install order and verification steps.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: unblock Perl::Critic Phase 2 dependencies
- Add DynaLoader.pm stub so `require DynaLoader` succeeds and CPAN
can resolve version dependencies (unblocks Module::Build::Tiny → Readonly)
- Set $DynaLoader::VERSION in DynaLoader.java initialize()
- Detect ::PP companion modules in XSLoader.java before dying, so
modules like Params::Util that pre-load a PP fallback before calling
XSLoader::load can proceed (unblocks PPI)
- Prefix PL_FILES commands with `-` in MakeMaker.pm so script generation
failures are non-fatal (unblocks Pod-Parser)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: @{[expr]} whitespace parsing, tied array iteration, autodie/Fatal import
- Fix @{ [expr] } parsing in string/regex interpolation when whitespace
appears between { and [. The tokenIndex backup used decrement-by-1 which
landed on a WHITESPACE token instead of the opening brace. Now uses
savedIndex to restore to the correct position. Unblocks Perl::Critic::Document.
- Fix tied array iteration in RuntimeArray: getList(), addToArray(), and
toString() now check for TIED_ARRAY and use size()/get(i) instead of
ArrayList iterator (which uses private size field, always 0 for TieArray).
Fixes Readonly::Array behavior.
- Import Fatal.pm, autodie, Tie::RefHash from perl5/ tree via sync.pl
- Add Config.pm startperl (was undefined, caused Module::Build::Tiny
make_executable() to die under FATAL => all)
- Update TAP::Parser::Multiplexer and _charnames.pm from perl5/ sync
With all fixes, use Perl::Critic loads and runs successfully.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: (??{}) in groups, interpreter local list assignment, Encode improvements
- Fix (??{...}) recursive regex failing when nested inside groups
(e.g., (?:abc|(??{42}))). The handler was consuming the closing ')'
and returning past it, but handleParentheses convention is to return
offset AT ')' and let the caller's offset++ move past it. Removed
the early return and let the code fall through to common '' handling.
- Fix interpreter ClassCastException for local(,)=(val1,val2).
ARRAY_GET expects a register containing the index, but code was
passing a raw integer. Fixed by allocating a register and loading
the index with LOAD_INT first.
- Encode.java: resolve_alias() now returns canonical charset name
instead of undef. define_encoding() registers encoding objects in
%Encode::Encoding hash, fixing Encode::Guess add_suspects.
- Add Encode::Encoding and Encode::Unicode stub modules.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
EOF
)
* fix: fork-open emulation returns lines in list context
The fork-open emulation (open FH, "-|" + exec) returned the captured
command output as a single string, even in list context. This broke
Module::Build's _default_INC which expects individual lines from
_backticks. The fix splits output into lines (preserving newlines,
like Perl's <FH> in list context when callContext is LIST.
This fixes PERL5LIB construction in Module::Build which was including
jar:PERL5LIB (a virtual @inc entry with a colon) that got corrupted
when split by the path separator. Now _default_INC properly identifies
default @inc entries, so only real added paths go into PERL5LIB.
Unblocks Perl::Critic test suite (2708/2708 tests pass in t/00_modules.t).
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
EOF
)
* fix: 5 bugs blocking Perl::Critic test suite (99.5% pass rate)
- List::Util::reduce: use coderef's packageName for $a/$b instead
of hardcoded "main::" (fixes reduce/pairmap/pairgrep/pairfirst)
- caller(): default null package names to "main" in stack traces,
preventing Devel::StackTrace crashes when filtering frames
- local *glob: create new empty replacement objects instead of
calling dynamicSaveState on existing ones, fixing corruption of
blessed objects when localizing typeglobs (Pod::Parser pattern)
- \N{CARRIAGE RETURN}: add all C0/C1 control character name aliases
to UnicodeResolver (NUL, SOH, CR, LF, TAB, etc.) since ICU4J
doesn't support Unicode Name Aliases
- state variable hoisting: suppress false "redeclared" warnings
when EmitBlock hoists state declarations to enclosing scope
Perl::Critic test results: 34/40 files pass, 5389/5416 subtests
(99.5%). Remaining 27 failures are from a deep eval-string closure
capture bug (Bug 6) and unrelated Perl::Tidy/charnames issues.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: reduce aliasing bug, caller null package, Exception::Class aliases
- List::Util::reduce: clone accumulator before finally block restores
$a/$b, preventing the result from being corrupted when the code block
returns $a or $b directly (same RuntimeScalar object as varA/varB)
- caller(): ensure package name is never null (defaults to "main")
in both scalar and list context return paths
- ExceptionFormatter: null-check package name in runSpecialBlock handler
Perl-side workarounds (in ~/.perlonjava/lib/):
- Exception::Class: replace alias closure with eval-string to avoid
eval-string closure capture bug corrupting $subclass
- Devel::StackTrace: guard against undef package in frame filter
Perl::Critic: 37/40 files pass, 5406/5416 subtests (99.8%)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: charnames::viacode, ref(*{$fh}{IO}), Perl::Critic 99.9% pass rate
- Wire _charnames::viacode() to Java-backed ICU4J lookup via
_java_viacode, bypassing missing unicore/Name.pl. Add C0/C1
control character name table to Charnames.java.
- Fix populate_txt() in _charnames.pm to not crash when
unicore/Name.pl is unavailable.
- Fix ref(*{$fh}{IO}) to return "IO::Handle" instead of "GLOB"
by checking for RuntimeIO in ReferenceOperators.java.
- Perl::Critic test suite: 39/40 files, 5411/5416 subtests (99.9%)
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add ClassFormatError to interpreter fallback
Perl::Tidy's Formatter module has subroutines with 113+ hash key
accesses that exceed JVM's 255-argument method signature limit,
causing ClassFormatError. This catch enables graceful fallback to
the interpreter backend for such cases.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* perf: selective closure variable capture, fix BIPUSH overflow
Closures now only capture variables actually referenced in their body,
instead of all visible lexical variables. This prevents JVM 255
constructor argument limit from being hit in modules like Perl::Tidy
where subroutines have 200+ lexicals in scope.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: selective closure capture for named subs, fix Perl::Tidy re-entry hang
SubroutineParser: Apply VariableCollectorVisitor-based selective capture
filtering to named subs (matching anonymous subs in EmitSubroutine).
Prevents hitting JVM 255 constructor argument limit for large modules.
Perl::Tidy workaround: Fix infinite loop in _decrement_count() while
_increment_count() > 1 pattern in Formatter.pm and Tokenizer.pm.
Replaced with correct peek-reset-set pattern for missing DESTROY.
Unblocks t/20_policy_require_tidy_code.t (6/6 tests now pass).
Generated with Devin (https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: VariableCollectorVisitor missing TryNode.finallyBlock and ListNode.handle
The selective closure capture visitor was not traversing:
- TryNode.finallyBlock: variables used only in finally blocks were
not collected, causing 'Global symbol requires explicit package name'
errors under use strict (broke op/try.t)
- ListNode.handle: variables used in indirect object syntax like
'exec $prog "hello"' were not collected (broke op/taint.t)
Generated with Devin (https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: local *glob now properly saves/restores pinned code refs
When `local *glob` was used, dynamicSaveState() replaced the
globalCodeRefs entry with a new empty object, but pinnedCodeRefs
still pointed to the saved (original) object. Since getGlobalCodeRef()
checks pinnedCodeRefs first, assignments during the local scope
(e.g. `*foo = sub { ... }`) would mutate the saved snapshot object
instead of the new empty one, making dynamicRestoreState() a no-op.
Fix: Added GlobalVariable.replacePinnedCodeRef() to redirect the
pinned ref during local scope and restore it on scope exit. This
fixes method_caching.t tests 7, 9, 10, 11 and method_caching_utf8.t
tests 7, 9.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: constant-fold (??{...}) with simple constants in regex patterns
For simple constant expressions like (??{1}) or (??{"[x]"}), inline
the evaluated value directly as a regex pattern: (?:1) or (?:[x]).
This avoids the empty-group issue where (??{}) produced an empty match.
Non-constant or complex expressions still fall through to the existing
runtime eval path.
Fixes 8 test failures in re/regexp.t and related re_tests variants.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: kv-slice closure capture and tied array CLEAR-during-assign
Two fixes for branch regressions:
1. VariableCollectorVisitor: %a[@i] and @A[@i] now correctly capture
@A (the array), not just %a. The selective closure capture was only
handling $a[idx] -> @A, missing the % and @ sigil variants used in
kv-slices and array slices. Fixes kvaslice.t test 23.
2. RuntimeArray.setFromList (TIED_ARRAY): return materializedList
instead of `this` after assignment. When CLEAR replaces the glob
(e.g. *a = []), the old tied array becomes invalid. Returning it
caused getList() to call FETCHSIZE on the dead tied object.
Fixes tie.t test 55.
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: preprocess (??{const}) output through handleRegex
The constant-folded value from (??{"[x]"}) may contain regex
constructs like (?[...]) from regex_sets_compat.t transformation.
Run the value through handleRegex() so these get converted to
Java-compatible patterns.
Fixes regex_sets_compat.t test 1709; net +1 over master (2089 vs 2088).
Generated with [Devin](https://cli.devin.ai/docs)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 8bd6e15 commit b483338
42 files changed
Lines changed: 6021 additions & 171 deletions
File tree
- dev
- import-perl5
- modules
- src/main
- java/org/perlonjava
- backend
- bytecode
- jvm
- core
- frontend/parser
- runtime
- operators
- perlmodule
- regex
- runtimetypes
- perl/lib
- Encode
- ExtUtils
- TAP/Parser
- Tie
- autodie
- Scope
- exception
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
341 | 341 | | |
342 | 342 | | |
343 | 343 | | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
344 | 381 | | |
345 | 382 | | |
346 | 383 | | |
| |||
0 commit comments