Skip to content

feat(Class::C3::XS): pure-Perl shim so jcpan -t Class::C3::XS passes#620

Merged
fglock merged 1 commit intomasterfrom
feature/class-c3-xs-pure-perl-shim
Apr 29, 2026
Merged

feat(Class::C3::XS): pure-Perl shim so jcpan -t Class::C3::XS passes#620
fglock merged 1 commit intomasterfrom
feature/class-c3-xs-pure-perl-shim

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 29, 2026

Summary

jcpan -t Class::C3::XS was failing 12/13 test files with:

Can't load loadable object for module Class::C3::XS: no Java XS implementation available

Class::C3::XS is XS-only — the dist's lib/Class/C3/XS.pm is just an XSLoader::load(...) plus a few next::* dispatch subs. The four functions it exports map cleanly onto core mro (5.9.5+), so this PR adds a pure-Perl shim and a generalised XSLoader hook to load it.

Changes

New src/main/perl/lib/Class/C3/XS.pm — pure-Perl shim:

  • calculateMROmro::get_linear_isa($class, 'c3')
  • _plsubgen → monotonic counter (only consulted for cache invalidation)
  • _calculate_method_dispatch_table → no-op (core mro handles C3 dispatch)
  • _nextcan → walks caller() past next:: / maybe::next:: frames, then searches the C3 MRO from the calling package onward
  • Also defines next::can, next::method, maybe::next::method (PerlOnJava's MakeMaker skips installing the dist's pm because it's superseded by the bundled jar shim, so these have to live here for goto &next::can in t/36_next_goto.t)

XSLoader.java — when the existing @ISA / ::PP fallback paths don't apply, try loading a bundled jar:PERL5LIB shim of the same name. loadJarShimOverrides now returns boolean to signal whether a shim was actually found. This generalises the existing hook so any future XS-only module can be supported by dropping a .pm into src/main/perl/lib/.

Test plan

  • make (full unit suite) — green
  • ./jcpan -t Class::C3::XSFiles=13, Tests=46, Result: PASS
  • All 13 individual test files in the dist pass: t/01_MRO.tt/05_MRO.t, t/30_next_method.tt/36_next_goto.t

Generated with Devin

Class::C3::XS is XS-only (the dist's lib/Class/C3/XS.pm is just an
XSLoader::load + a few next:: dispatch subs). Without XS, the test
suite fails 12/13 with "Can't load loadable object". Provide a
pure-Perl shim:

  src/main/perl/lib/Class/C3/XS.pm

implementing the four exported subs on top of core mro:
  - calculateMRO        -> mro::get_linear_isa($class, 'c3')
  - _plsubgen           -> monotonically increasing counter
  - _calculate_method_dispatch_table -> no-op (core mro handles c3)
  - _nextcan            -> walks caller() up past next::/maybe::next::
                          frames, then searches the C3 MRO from the
                          calling package onward.

Also re-define next::can / next::method / maybe::next::method to
delegate to _nextcan, mirroring what the dist's pm does. PerlOnJava's
MakeMaker shim skips installing the dist's pm (it's superseded by the
bundled jar shim), so these definitions have to live here for tests
like t/36_next_goto.t (`goto &next::can`) to work.

In XSLoader.java, when the existing @isa / ::PP fallback paths don't
apply, try loading a bundled jar:PERL5LIB shim of the same name. This
generalises the existing loadJarShimOverrides hook so any future XS
module can be backed by dropping a .pm into src/main/perl/lib/.
loadJarShimOverrides now returns boolean to signal whether a shim was
found.

Result: jcpan -t Class::C3::XS passes 46/46 tests across 13 files.

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock merged commit 36aee1c into master Apr 29, 2026
2 checks passed
@fglock fglock deleted the feature/class-c3-xs-pure-perl-shim branch April 29, 2026 12:34
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