#!perl
BEGIN {
chdir
't'
if
-d
't'
;
@INC
=
"../lib"
;
require
'./test.pl'
;
}
$ENV
{PERL_TEST_MEMORY} >= 60
or skip_all(
"Need ~60GB for this test"
);
$Config
{ptrsize} >= 8
or skip_all(
"Need 64-bit pointers for this test"
);
XS::APItest::wide_marks()
or skip_all(
"Not configured for SSize_t marks"
);
my
@x
;
$x
[0x8000_0000] =
"Hello"
;
my
$arg_count
;
my
@tests
=
(
[
mark
=>
sub
{
my
$count
= () = (x(), z());
is(
$count
, 0x8000_0002,
"got expected (large) list size"
);
},
],
[
xssize
=>
sub
{
my
$count
= XS::APItest::xs_items(x(), z());
is(
$count
, 0x8000_0002,
"got expected XS list size"
);
}
],
[
listsub
=>
sub
{
my
$last
= ( x() )[-1];
is(
$last
,
"Hello"
,
"list subscripting"
);
my
(
$first
,
$last2
,
$last1
) = (
"first"
, x(),
"Goodbye"
)[0, -2, -1];
is(
$first
,
"first"
,
"list subscripting in list context (0)"
);
is(
$last2
,
"Hello"
,
"list subscripting in list context (-2)"
);
is(
$last1
,
"Goodbye"
,
"list subscripting in list context (-1)"
);
}
],
[
iterctx
=>
sub
{
my
$last
= ( x(), iter() )[-1];
is(
$last
,
"abc"
,
"check iteration not confused"
);
}
],
[
split
=>
sub
{
my
$count
= () = ( x(), do_split(
"ABC"
) );
is(
$count
, 0x8000_0004,
"split base index"
);
}
],
[
xsload
=>
sub
{
my
$count
= () = (x(), loader());
is(
$count
, 0x8000_0001,
"check loading XS with large stack"
);
}
],
[
pp_list
=>
sub
{
my
$l
= ( x(), list2() )[-1];
is(
$l
, 2,
"pp_list mark handling"
);
}
],
[
chomp_av
=>
sub
{
local
$x
[-1] =
"Hello\n"
;
chomp
(
@x
);
is(
$x
[-1],
"Hello"
,
"chomp on a large array"
);
}
],
[
grepwhile
=>
sub
{
SKIP: {
skip
"This test is even slower - define PERL_RUN_SLOW_TESTS to run me"
, 1
unless
$ENV
{PERL_RUN_SLOW_TESTS};
my
$count
=
grep
1, ( (
undef
) x 0x7FFF_FFFF, 1, 1 );
is(
$count
, 0x8000_0001,
"grepwhile item count"
);
}
}
],
[
repeat
=>
sub
{
SKIP:
{
$ENV
{PERL_TEST_MEMORY} >= 70
or skip
"repeat test needs 70GB"
, 2;
my
(
$lastm1
,
$middle
) = ( ( x() ) x 2 )[-1,
@x
-1];
is(
$lastm1
,
"Hello"
,
"repeat lastm1"
);
is(
$middle
,
"Hello"
,
"repeat middle"
);
}
},
],
[
tiescalar
=>
sub
{
SKIP:
{
$ENV
{PERL_TEST_MEMORY} >= 80
or skip
"tiescalar second test needs 80GB"
, 2;
my
$x
;
ok(
ref
( ( x(),
tie
(
$x
,
"ScalarTie"
, 1..5))[-1]),
"tied with deep stack"
);
is(
$x
, 6,
"check arguments received"
);
untie
$x
;
ok(
tie
(
$x
,
"ScalarTie"
, x()),
"tie scalar with long argument list"
);
is(
$x
, 1+
scalar
(
@x
),
"check arguments received"
);
untie
$x
;
SKIP:
{
skip
"This test is even slower - define PERL_RUN_SLOW_TESTS to run me"
, 1
unless
$ENV
{PERL_RUN_SLOW_TESTS};
my
$o
=
bless
{},
"ScalarTie"
;
ok(
tie
(
$x
,
$o
, x(), 1),
"tie scalar via object with long argument list"
);
is(
$x
, 2+
scalar
(
@x
),
"check arguments received"
);
untie
$x
;
}
}
}
],
[
apply
=>
sub
{
SKIP:
{
skip
"2**31 system calls take a very long time - define PERL_RUN_SLOW_TESTS to run me"
, 1
unless
$ENV
{PERL_RUN_SLOW_TESTS};
my
$mode
= (
stat
$0)[2];
my
$tries
= 0x8000_0001;
my
$count
=
chmod
$mode
, ( $0 ) x
$tries
;
is(
$count
,
$tries
,
"chmod with 2G files"
);
}
}
],
[
join
=>
sub
{
no
warnings
'uninitialized'
;
my
$joined
=
join
""
,
@x
,
"!"
;
is(
$joined
,
"Hello!"
,
"join"
);
},
],
[
class_construct
=>
sub
{
class Foo {
field
$x
:param;
};
my
$y
= Foo->new((
x
=> 1) x 0x4000_0001);
ok(
$y
,
"construct class based object with 2G parameters"
);
},
],
[
eval_sv_count
=>
sub
{
SKIP:
{
$ENV
{PERL_TEST_MEMORY} >= 70
or skip
"eval_sv_count test needs 70GB"
, 2;
my
$count
= (
@x
, XS::APItest::eval_sv(
'@x'
, G_LIST) )[-1];
is(
$count
,
scalar
@x
,
"check eval_sv result/mark handling"
);
}
}
],
[
call_sv_args
=>
sub
{
undef
$arg_count
;
my
$ret_count
= XS::APItest::call_sv(\
&arg_count
, G_LIST, x());
is(
$ret_count
, 0,
"call_sv with 2G args - arg_count() returns nothing"
);
is(
$arg_count
,
scalar
@x
,
"check call_sv argument handling - argument count"
);
},
],
[
call_sv_mark
=>
sub
{
my
$ret_count
= ( x(), XS::APItest::call_sv(\
&list
, G_LIST) )[-1];
is(
$ret_count
, 2,
"call_sv with deep stack - returned value count"
);
},
],
);
my
%enabled
=
map
{
$_
=> 1 }
@ARGV
;
for
my
$test
(
@tests
) {
my
(
$id
,
$code
) =
@$test
;
if
(!
@ARGV
||
$enabled
{
$id
}) {
note(
$id
);
$code
->();
}
}
done_testing();
sub
x {
@x
}
sub
z { 1 }
sub
iter {
my
$result
=
''
;
my
$count
= 0;
for
my
$item
(
qw(a b c)
) {
$result
.=
$item
;
die
"iteration bug"
if
++
$count
> 5;
}
$result
;
}
sub
do_split {
return
split
//,
$_
[0];
}
sub
loader {
();
}
sub
list2 {
scalar
list(1);
}
sub
list {
return
shift
() ? (1, 2) : (2, 1);
}
sub
arg_count {
$arg_count
=
@_
;
();
}
sub
TIESCALAR {
::note(
"TIESCALAR $_[0]"
);
bless
{
count
=>
scalar
@_
}, __PACKAGE__;
}
sub
FETCH {
$_
[0]{count};
}