Skip to content

Commit

Permalink
remove some stringy eval
Browse files Browse the repository at this point in the history
  • Loading branch information
plicease committed Dec 19, 2021
1 parent 57551ad commit af60c0a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 60 deletions.
2 changes: 2 additions & 0 deletions Changes
@@ -1,6 +1,8 @@
Revision history for {{$dist->name}}

{{$NEXT}}
- Remove the most uses of stringy eval (gh#6) One still remains
- Remove dependency on Data::Munge (gh#6)

0.06 2021-10-11 16:57:42 -0600
- Fixed test bug (rt#133221)
Expand Down
109 changes: 50 additions & 59 deletions lib/Return/MultiLevel.pm
Expand Up @@ -4,7 +4,6 @@ use strict;
use warnings;
use 5.008001;
use Carp qw(confess);
use Data::Munge qw(eval_string);
use parent 'Exporter';

# ABSTRACT: Return across multiple call levels
Expand All @@ -14,90 +13,82 @@ our @EXPORT_OK = qw(with_return);

our $_backend;

sub with_return (&);

if (!$ENV{RETURN_MULTILEVEL_PP} && eval { require Scope::Upper }) {
eval_string <<'EOT';
sub with_return (&) {

*with_return = sub (&) {
my ($f) = @_;
my $ctx = Scope::Upper::HERE();
my @canary =
!$ENV{RETURN_MULTILEVEL_DEBUG}
? '-'
: Carp::longmess "Original call to with_return"
;
my @canary = !$ENV{RETURN_MULTILEVEL_DEBUG}
? '-'
: Carp::longmess "Original call to with_return";

local $canary[0];
$f->(sub {
$canary[0]
and confess
$canary[0] eq '-'
? ""
: "Captured stack:\n$canary[0]\n",
"Attempt to re-enter dead call frame"
;
Scope::Upper::unwind(@_, $ctx);
$canary[0] and confess $canary[0] eq '-'
? ""
: "Captured stack:\n$canary[0]\n",
"Attempt to re-enter dead call frame";
Scope::Upper::unwind(@_, $ctx);
})
}
EOT
};

$_backend = 'XS';
$_backend = 'XS';

} else {

eval_string <<'EOT';
{
*_label_at = do {
my $_label_prefix = '_' . __PACKAGE__ . '_';
$_label_prefix =~ tr/A-Za-z0-9_/_/cs;

sub _label_at { $_label_prefix . $_[0] }
}
sub { $_label_prefix . $_[0] };
};

our @_trampoline_cache;
our @_trampoline_cache;

sub _get_trampoline {
*_get_trampoline = sub {
my ($i) = @_;
my $label = _label_at $i;
my $label = _label_at($i);
(
$label,
$_trampoline_cache[$i] ||= eval_string qq{
sub {
my \$rr = shift;
my \$fn = shift;
return &\$fn;
$label: splice \@\$rr
}
},
$label,
$_trampoline_cache[$i] ||= eval ## no critic (BuiltinFunctions::ProhibitStringyEval)
qq{
sub {
my \$rr = shift;
my \$fn = shift;
return &\$fn;
$label: splice \@\$rr
}
},
)
}
};

our $_depth = 0;
our $_depth = 0;

sub with_return (&) {
*with_return = sub (&) {
my ($f) = @_;
my ($label, $trampoline) = _get_trampoline $_depth;
my ($label, $trampoline) = _get_trampoline($_depth);
local $_depth = $_depth + 1;
my @canary =
!$ENV{RETURN_MULTILEVEL_DEBUG}
? '-'
: Carp::longmess "Original call to with_return"
;
my @canary = !$ENV{RETURN_MULTILEVEL_DEBUG}
? '-'
: Carp::longmess "Original call to with_return";

local $canary[0];
my @ret;
$trampoline->(
\@ret,
$f,
sub {
$canary[0]
and confess
$canary[0] eq '-'
? ""
: "Captured stack:\n$canary[0]\n",
"Attempt to re-enter dead call frame"
;
@ret = @_;
goto $label;
},
\@ret,
$f,
sub {
$canary[0] and confess $canary[0] eq '-'
? ""
: "Captured stack:\n$canary[0]\n",
"Attempt to re-enter dead call frame";
@ret = @_;
goto $label;
},
)
}
EOT
};

$_backend = 'PP';
}
Expand Down
1 change: 0 additions & 1 deletion t/00_diag.t
Expand Up @@ -11,7 +11,6 @@ my $post_diag;

$modules{$_} = $_ for qw(
Carp
Data::Munge
Exporter
ExtUtils::MakeMaker
Scope::Upper
Expand Down
9 changes: 9 additions & 0 deletions t/basic.t
Expand Up @@ -3,6 +3,15 @@ use warnings;
use Test::More tests => 5;
use Return::MultiLevel qw(with_return);

diag '';
diag '';
diag '';

diag "backend = @{[ $Return::MultiLevel::_backend ]}";

diag '';
diag '';

is with_return {
my ($ret) = @_;
42
Expand Down

0 comments on commit af60c0a

Please sign in to comment.