This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make utf8::encode respect magic
[perl5.git] / t / op / goto_xs.t
CommitLineData
1fa4e549
AD
1#!./perl
2# tests for "goto &sub"-ing into XSUBs
3
1fa4e549
AD
4# Note: This only tests things that should *work*. At some point, it may
5# be worth while to write some failure tests for things that should
6# *break* (such as calls with wrong number of args). For now, I'm
7# guessing that if all of these work correctly, the bad ones will
8# break correctly as well.
9
4210e2f6
NC
10BEGIN {
11 chdir 't' if -d 't';
0758e0bf 12 require './test.pl';
1fa4e549 13# turn warnings into fatal errors
4210e2f6 14 $SIG{__WARN__} = sub { die "WARNING: @_" } ;
1fa4e549 15
0758e0bf
NC
16 skip_all_if_miniperl("no dynamic loading on miniperl, no Fcntl");
17 require Fcntl;
4210e2f6 18}
0758e0bf
NC
19use strict;
20use warnings;
21use vars '$VALID';
22
23plan(tests => 11);
1fa4e549
AD
24
25# We don't know what symbols are defined in platform X's system headers.
26# We don't even want to guess, because some platform out there will
582b1831
NC
27# likely do the unthinkable. However, Fcntl::S_IMODE(0)
28# should always return a value.
1fa4e549 29# If this ceases to be the case, we're in trouble. =)
582b1831 30$VALID = 0;
1fa4e549 31
582b1831
NC
32### First, we check whether Fcntl::S_IMODE returns sane answers.
33# Fcntl::S_IMODE(0) should always succeed.
1fa4e549 34
0758e0bf
NC
35my $value = Fcntl::S_IMODE($VALID);
36isnt($value, undef, 'Sanity check broke, remaining tests will fail');
1fa4e549
AD
37
38### OK, we're ready to do real tests.
39
582b1831 40sub goto_const { goto &Fcntl::S_IMODE; }
1fa4e549 41
0758e0bf
NC
42my $ret = goto_const($VALID);
43is($ret, $value, 'goto &function_constant');
1fa4e549 44
0758e0bf 45my $FNAME1 = 'Fcntl::S_IMODE';
1fa4e549
AD
46sub goto_name1 { goto &$FNAME1; }
47
59d526a3 48$ret = goto_name1($VALID);
0758e0bf 49is($ret, $value, 'goto &$function_package_and_name');
1fa4e549 50
59d526a3 51$ret = goto_name1($VALID);
0758e0bf 52is($ret, $value, 'goto &$function_package_and_name; again, with dirtier stack');
59d526a3 53$ret = goto_name1($VALID);
0758e0bf 54is($ret, $value, 'goto &$function_package_and_name; again, with dirtier stack');
1fa4e549 55
0758e0bf 56# test
1fa4e549 57package Fcntl;
0758e0bf 58my $FNAME2 = 'S_IMODE';
1fa4e549
AD
59sub goto_name2 { goto &$FNAME2; }
60package main;
61
59d526a3 62$ret = Fcntl::goto_name2($VALID);
0758e0bf 63is($ret, $value, 'goto &$function_name; from local package');
1fa4e549 64
0758e0bf 65my $FREF = \&Fcntl::S_IMODE;
1fa4e549
AD
66sub goto_ref { goto &$FREF; }
67
59d526a3 68$ret = goto_ref($VALID);
0758e0bf 69is($ret, $value, 'goto &$function_ref');
1fa4e549
AD
70
71### tests where the args are not on stack but in GvAV(defgv) (ie, @_)
72
1fa4e549
AD
73sub call_goto_const { &goto_const; }
74
59d526a3 75$ret = call_goto_const($VALID);
0758e0bf 76is($ret, $value, 'goto &function_constant; from a sub called without arglist');
1fa4e549
AD
77
78# test "goto &$function_package_and_name" from a sub called without arglist
79sub call_goto_name1 { &goto_name1; }
80
59d526a3 81$ret = call_goto_name1($VALID);
0758e0bf
NC
82is($ret, $value,
83 'goto &$function_package_and_name; from a sub called without arglist');
1fa4e549 84
1fa4e549
AD
85sub call_goto_ref { &goto_ref; }
86
59d526a3 87$ret = call_goto_ref($VALID);
0758e0bf 88is($ret, $value, 'goto &$function_ref; from a sub called without arglist');
5eff7df7 89
5eff7df7 90
976bd1ee
DM
91BEGIN {
92 use Config;
93 if ($Config{extensions} =~ m{XS/APItest}) {
94 eval q[use XS::APItest qw(mycroak); 1]
95 or die "use XS::APItest: $@\n";
96 }
97 else {
98 *mycroak = sub { die @_ };
99 }
100}
5eff7df7
DM
101
102sub goto_croak { goto &mycroak }
103
104{
105 my $e;
106 for (1..4) {
107 eval { goto_croak("boo$_\n") };
108 $e .= $@;
109 }
0758e0bf
NC
110 is($e, "boo1\nboo2\nboo3\nboo4\n",
111 '[perl #35878] croak in XS after goto segfaulted')
5eff7df7
DM
112}
113