OP_CUSTOM
=> opnumber(
'custom'
),
OP_ENTER
=> opnumber(
'enter'
),
OP_LINESEQ
=> opnumber(
'lineseq'
),
};
my
$orig_pp_leave
;
{
no
warnings
'redefine'
;
no
strict
'refs'
;
$orig_pp_leave
= *{
"B::Deparse::pp_leave"
}{CODE};
*{
"B::Deparse::pp_leave"
} = \
&pp_leave
;
}
sub
pp_leave
{
my
$self
=
shift
;
my
(
$op
) =
@_
;
my
$enter
=
$op
->first;
$enter
->type == OP_ENTER or
return
$self
->
$orig_pp_leave
(
@_
);
my
$body
=
$enter
->sibling;
my
$first
=
$body
->first;
my
$finally
=
""
;
if
(
$body
->type == OP_LINESEQ and
$first
->name eq
"pushfinally"
) {
my
$finally_cv
=
$first
->sv;
$finally
=
"\nfinally "
.
$self
->deparse_sub(
$finally_cv
) .
"\cK"
;
$first
=
$first
->sibling;
$first
=
$first
->sibling
while
$first
and
$first
->name eq
"lineseq"
;
if
(
$first
->type == 0 ) {
$body
=
$first
;
$first
=
$first
->first;
}
}
if
(
$first
->type == OP_CUSTOM and
$first
->name eq
"catch"
) {
shift
;
return
$self
->deparse(
$body
,
@_
) .
$finally
;
}
elsif
(
length
$finally
) {
my
$try
= B::Deparse::scopeop( 1,
$self
,
$body
, 0 );
return
"try {\n\t$try\n\b}"
.
$finally
;
}
return
$orig_pp_leave
->(
$self
,
@_
);
}
sub
B::Deparse::pp_catch
{
my
$self
=
shift
;
my
(
$op
) =
@_
;
my
$tryop
=
$op
->first;
my
$catchop
=
$op
->first->sibling;
my
$try
=
$self
->pp_leave(
$tryop
, 0);
my
$catch
=
$self
->deparse(
$catchop
->first, 0);
return
"try {\n\t$try\n\b}\ncatch {\n\t$catch\n\b}\cK"
;
}
0x55AA;