t/40-localize_delete-target.t
t/41-localize_delete-level.t
t/44-localize_delete-magic.t
+t/50-unwind-target.t
t/53-unwind-context.t
t/55-unwind-multi.t
t/81-stress-level.t
dounwind(cxix);
/* Hide the level */
- PL_stack_sp--;
+ if (items >= 0)
+ PL_stack_sp--;
mark = PL_markstack[cxstack[cxix].blk_oldmarksp];
#else
dXSARGS;
#endif
- I32 cxix;
+ I32 from = 0, cxix = cxstack_ix;
su_ud_unwind *ud;
SV *level;
- if (!items)
- Perl_croak(aTHX_ "Usage: Scope::Upper::unwind(..., level)");
PERL_UNUSED_VAR(cv); /* -W */
PERL_UNUSED_VAR(ax); /* -Wall */
- level = ST(items - 1);
- cxix = SvOK(level) ? SvIV(level) : 0;
- if (cxix < 0)
- cxix = 0;
- else if (cxix > cxstack_ix)
- cxix = cxstack_ix;
- cxix = cxstack_ix - cxix;
+ if (items) {
+ from = SvIV(ST(items - 1));
+ if (from < 0)
+ from = 0;
+ else if (from > cxix)
+ from = cxix;
+ }
+ cxix -= from;
do {
PERL_CONTEXT *cx = cxstack + cxix;
switch (CxTYPE(cx)) {
--- /dev/null
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More tests => 4;
+
+use Scope::Upper qw/unwind/;
+
+my @res;
+
+@res = (7, eval {
+ unwind;
+ 8;
+});
+is_deeply \@res, [ 7 ], 'unwind()';
+
+@res = (7, eval {
+ unwind -1;
+ 8;
+});
+is_deeply \@res, [ 7 ], 'unwind(-1)';
+
+@res = (7, eval {
+ unwind 100;
+ 8;
+});
+like $@, qr/^Can't\s+return\s+outside\s+a\s+subroutine/, 'unwind(100)';
+is_deeply \@res, [ 7 ], 'unwind(100)';