1*898184e3Ssthen#!perl 2*898184e3Ssthen 3*898184e3Ssthen# This script tests not only the interface for XS AUTOLOAD routines to find 4*898184e3Ssthen# out the sub name, but also that that interface does not interfere with 5*898184e3Ssthen# prototypes, the way it did before 5.15.4. 6*898184e3Ssthen 7*898184e3Ssthenuse strict; 8*898184e3Ssthenuse warnings; 9*898184e3Ssthen 10*898184e3Ssthenuse Test::More tests => 26; 11*898184e3Ssthen 12*898184e3Ssthenuse XS::APItest; 13*898184e3Ssthen 14*898184e3Ssthenis XS::APItest::AutoLoader::frob(), 'frob', 'name passed to XS AUTOLOAD'; 15*898184e3Ssthenis "XS::APItest::AutoLoader::fr\0b"->(), "fr\0b", 16*898184e3Ssthen 'name with embedded null passed to XS AUTOLOAD'; 17*898184e3Ssthenis "XS::APItest::AutoLoader::fr\x{1ed9}b"->(), "fr\x{1ed9}b", 18*898184e3Ssthen 'Unicode name passed to XS AUTOLOAD'; 19*898184e3Ssthen 20*898184e3Ssthen*AUTOLOAD = *XS::APItest::AutoLoader::AUTOLOADp; 21*898184e3Ssthen 22*898184e3Ssthenis frob(), 'frob', 'name passed to XS AUTOLOAD with proto'; 23*898184e3Ssthenis prototype \&AUTOLOAD, '*$', 'prototype is unchanged'; 24*898184e3Ssthenis "fr\0b"->(), "fr\0b", 25*898184e3Ssthen 'name with embedded null passed to XS AUTOLOAD with proto'; 26*898184e3Ssthenis prototype \&AUTOLOAD, '*$', 'proto unchanged after embedded-null call'; 27*898184e3Ssthenis "fr\x{1ed9}b"->(), "fr\x{1ed9}b", 28*898184e3Ssthen 'Unicode name passed to XS AUTOLOAD with proto'; 29*898184e3Ssthenis prototype \&AUTOLOAD, '*$', 'prototype is unchanged after Unicode call'; 30*898184e3Ssthen 31*898184e3Ssthen# Test that the prototype was preserved from the parser’s point of view 32*898184e3Ssthen 33*898184e3Ssthenok !eval "sub { ::AUTOLOAD(1) }", 34*898184e3Ssthen 'parse failure due to AUTOLOAD prototype'; 35*898184e3Ssthenok eval "sub { ::AUTOLOAD(1,2) }", 'successful parse respecting prototype' 36*898184e3Ssthen or diag $@; 37*898184e3Ssthen 38*898184e3Ssthenpackage fribble { sub a { return 7 } } 39*898184e3Ssthenno warnings 'once'; 40*898184e3Ssthen*a = \&AUTOLOAD; 41*898184e3Ssthen'$'->(); 42*898184e3Ssthen# &a('fribble') will return '$' 43*898184e3Ssthen# But if intuit_method does not see the (*...) proto, this compiles as 44*898184e3Ssthen# fribble->a 45*898184e3Ssthenno strict; 46*898184e3Ssthenis eval 'a fribble, 3', '$', 'intuit_method sees * in AUTOLOAD proto' 47*898184e3Ssthen or diag $@; 48*898184e3Ssthen 49*898184e3Ssthen# precedence check 50*898184e3Ssthen# *$ should parse as a list operator, but right now the AUTOLOAD 51*898184e3Ssthen# sub name is $ 52*898184e3Ssthenis join(" ", eval 'a "b", "c"'), '$', 53*898184e3Ssthen 'precedence determination respects prototype of AUTOLOAD sub'; 54*898184e3Ssthen 55*898184e3Ssthen{ 56*898184e3Ssthen my $w; 57*898184e3Ssthen local $SIG{__WARN__} = sub { $w .= shift }; 58*898184e3Ssthen eval 'sub a($){}'; 59*898184e3Ssthen like $w, qr/^Prototype mismatch: sub main::a \(\*\$\) vs \(\$\)/m, 60*898184e3Ssthen 'proto warnings respect AUTOLOAD prototypes'; 61*898184e3Ssthen undef $w; 62*898184e3Ssthen *a = \&AUTOLOAD; 63*898184e3Ssthen like $w, qr/^Prototype mismatch: sub main::a \(\$\) vs \(\*\$\)/m, 64*898184e3Ssthen 'GV assignment proto warnings respect AUTOLOAD prototypes'; 65*898184e3Ssthen} 66*898184e3Ssthen 67*898184e3Ssthen 68*898184e3Ssthen# 69*898184e3Ssthen# This is a test for AUTOLOAD implemented as an XSUB. 70*898184e3Ssthen# It tests that $AUTOLOAD is set correctly, including the 71*898184e3Ssthen# case of inheritance. 72*898184e3Ssthen# 73*898184e3Ssthen# Rationale: Due to change ed850460, $AUTOLOAD is not currently set 74*898184e3Ssthen# for XSUB AUTOLOADs at all. Instead, as of adb5a9ae the PV of the 75*898184e3Ssthen# AUTOLOAD XSUB is set to the name of the method. We cruelly test it 76*898184e3Ssthen# regardless. 77*898184e3Ssthen# 78*898184e3Ssthen 79*898184e3Ssthen# First, make sure we have the XS AUTOLOAD available for testing 80*898184e3Ssthenok(XS::APItest::AUTOLOADtest->can('AUTOLOAD'), 'Test class ->can AUTOLOAD'); 81*898184e3Ssthen 82*898184e3Ssthen# Used to communicate from the XS AUTOLOAD to Perl land 83*898184e3Ssthenuse vars '$the_method'; 84*898184e3Ssthen 85*898184e3Ssthen# First, set up the Perl equivalent to what we're testing in 86*898184e3Ssthen# XS so we have a comparison 87*898184e3Ssthenpackage PerlBase; 88*898184e3Ssthenuse vars '$AUTOLOAD'; 89*898184e3Ssthensub AUTOLOAD { 90*898184e3Ssthen Test::More::ok(defined $AUTOLOAD); 91*898184e3Ssthen return 1 if not defined $AUTOLOAD; 92*898184e3Ssthen $main::the_method = $AUTOLOAD; 93*898184e3Ssthen return 0; 94*898184e3Ssthen} 95*898184e3Ssthen 96*898184e3Ssthenpackage PerlDerived; 97*898184e3Ssthenuse vars '@ISA'; 98*898184e3Ssthen@ISA = qw(PerlBase); 99*898184e3Ssthen 100*898184e3Ssthenpackage Derived; 101*898184e3Ssthenuse vars '@ISA'; 102*898184e3Ssthen@ISA = qw(XS::APItest::AUTOLOADtest); 103*898184e3Ssthen 104*898184e3Ssthenpackage main; 105*898184e3Ssthen 106*898184e3Ssthen# Test Perl AUTOLOAD in base class directly 107*898184e3Ssthen$the_method = undef; 108*898184e3Ssthenis(PerlBase->Blah(), 0, 109*898184e3Ssthen "Perl AUTOLOAD gets called and returns success"); 110*898184e3Ssthenis($the_method, 'PerlBase::Blah', 111*898184e3Ssthen 'Scalar set to correct class/method name'); 112*898184e3Ssthen 113*898184e3Ssthen# Test Perl AUTOLOAD in derived class 114*898184e3Ssthen$the_method = undef; 115*898184e3Ssthenis(PerlDerived->Boo(), 0, 116*898184e3Ssthen 'Perl AUTOLOAD on derived class gets called and returns success'); 117*898184e3Ssthenis($the_method, 'PerlDerived::Boo', 118*898184e3Ssthen 'Scalar set to correct class/method name'); 119*898184e3Ssthen 120*898184e3Ssthen# Test XS AUTOLOAD in base class directly 121*898184e3Ssthen$the_method = undef; 122*898184e3Ssthenis(XS::APItest::AUTOLOADtest->Blah(), 0, 123*898184e3Ssthen 'XS AUTOLOAD gets called and returns success'); 124*898184e3Ssthenis($the_method, 'XS::APItest::AUTOLOADtest::Blah', 125*898184e3Ssthen 'Scalar set to correct class/method name'); 126*898184e3Ssthen 127*898184e3Ssthen# Test XS AUTOLOAD in derived class directly 128*898184e3Ssthen$the_method = undef; 129*898184e3Ssthenis(Derived->Foo(), 0, 130*898184e3Ssthen 'XS AUTOLOAD gets called and returns success'); 131*898184e3Ssthenis($the_method, 'Derived::Foo', 132*898184e3Ssthen 'Scalar set to correct class/method name'); 133