Skip to content

Commit 8a6fade

Browse files
committed
ParseXS: refactor: avoid cur_xsub/xbody in as_code
During the course of the refactoring in this branch, perl code has gradually been split between doing parsing in Node::FOO::parse() methods and code emitting in Node::FOO::as_code() methods (before, both were completely interleaved). How the current xsub and xbody nodes are tracked varies between those two types of methods: the as_code() methods pass them as explicit parameters, while the parse() methods rely on two 'global' fields within the ExtUtils::ParseXS object, cur_xsub and cur_xbody. However, some some as_code() methods were still relying on cur_xsub/xbody rather than the passed $xsub and $xbody params. This commit fixes that. At the moment it is mostly harmless, as each XSUB's top_level as_code() is called immediately after it's top-level parse(), so cur_xsub still points to the right XSUB. But that will change in future, so get it right now. The next commit will in fact explicitly undef cur_xsub/xbody immediately after parsing is finished. This commit includes a test for one edge case where the cur_xbody being wrong did make a difference.
1 parent 5a137aa commit 8a6fade

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -557,34 +557,34 @@ sub boot_code {
557557
# Now use those values to append suitable newXS() and other code
558558
# into @code, for later insertion into the boot sub.
559559

560-
my $pname = $pxs->{cur_xsub}{decl}{full_perl_name};
561-
my $cname = $pxs->{cur_xsub}{decl}{full_C_name};
560+
my $pname = $self->{decl}{full_perl_name};
561+
my $cname = $self->{decl}{full_C_name};
562562

563-
if ( $pxs->{cur_xsub}{map_alias_name_to_value}
564-
and keys %{ $pxs->{cur_xsub}{map_alias_name_to_value} })
563+
if ( $self->{map_alias_name_to_value}
564+
and keys %{ $self->{map_alias_name_to_value} })
565565
{
566566
# For the main XSUB and for each alias name, generate a newXS() call
567567
# and 'XSANY.any_i32 = ix' line.
568568

569569
# Make the main name one of the aliases if it isn't already
570-
$pxs->{cur_xsub}{map_alias_name_to_value}->{$pname} = 0
571-
unless defined $pxs->{cur_xsub}{map_alias_name_to_value}{$pname};
570+
$self->{map_alias_name_to_value}->{$pname} = 0
571+
unless defined $self->{map_alias_name_to_value}{$pname};
572572

573573
foreach my $xname (sort keys
574-
%{ $pxs->{cur_xsub}{map_alias_name_to_value} })
574+
%{ $self->{map_alias_name_to_value} })
575575
{
576-
my $value = $pxs->{cur_xsub}{map_alias_name_to_value}{$xname};
576+
my $value = $self->{map_alias_name_to_value}{$xname};
577577
push(@code, ExtUtils::ParseXS::Q(<<"EOF"));
578578
| cv = $newXS(\"$xname\", XS_$cname$file_arg$proto_arg);
579579
| XSANY.any_i32 = $value;
580580
EOF
581581
$pxs->{need_boot_cv} = 1;
582582
}
583583
}
584-
elsif ($pxs->{cur_xsub}{attributes}) {
584+
elsif ($self->{attributes}) {
585585
# Generate a standard newXS() call, plus a single call to
586586
# apply_attrs_string() call with the string of attributes.
587-
my $attrs = "@{$pxs->{cur_xsub}{attributes}}";
587+
my $attrs = "@{$self->{attributes}}";
588588
push(@code, ExtUtils::ParseXS::Q(<<"EOF"));
589589
| cv = $newXS(\"$pname\", XS_$cname$file_arg$proto_arg);
590590
| apply_attrs_string("$pxs->{PACKAGE_name}", cv, "$attrs", 0);
@@ -597,12 +597,12 @@ EOF
597597
# For each interface name, generate both a newXS() and
598598
# XSINTERFACE_FUNC_SET() call.
599599
foreach my $yname (sort keys
600-
%{ $pxs->{cur_xsub}{map_interface_name_short_to_original} })
600+
%{ $self->{map_interface_name_short_to_original} })
601601
{
602-
my $value = $pxs->{cur_xsub}{map_interface_name_short_to_original}{$yname};
602+
my $value = $self->{map_interface_name_short_to_original}{$yname};
603603
$yname = "$pxs->{PACKAGE_name}\::$yname" unless $yname =~ /::/;
604604

605-
my $macro = $pxs->{cur_xsub}{interface_macro_set};
605+
my $macro = $self->{interface_macro_set};
606606
$macro = 'XSINTERFACE_FUNC_SET' unless defined $macro;
607607
push(@code, ExtUtils::ParseXS::Q(<<"EOF"));
608608
| cv = $newXS(\"$yname\", XS_$cname$file_arg$proto_arg);
@@ -635,7 +635,7 @@ EOF
635635
# For every overload operator, generate an additional newXS()
636636
# call to add an alias such as "Foo::(<=>" for this XSUB.
637637

638-
for my $operator (sort keys %{ $pxs->{cur_xsub}{overload_name_seen} })
638+
for my $operator (sort keys %{ $self->{overload_name_seen} })
639639
{
640640
$pxs->{map_overloaded_package_to_C_package}->{$pxs->{PACKAGE_name}}
641641
= $pxs->{PACKAGE_C_name};
@@ -950,7 +950,7 @@ sub as_code {
950950

951951
print "\tSTRLEN\tSTRLEN_length_of_$name;\n";
952952
# defer this line until after all the other declarations
953-
$pxs->{cur_xbody}{input_part}{deferred_code_lines} .=
953+
$xbody->{input_part}{deferred_code_lines} .=
954954
"\n\tXSauto_length_of_$name = STRLEN_length_of_$name;\n";
955955

956956
# this var will be declared using the normal typemap mechanism below
@@ -1057,7 +1057,7 @@ sub as_code {
10571057
# on an object of the right class. Basically, for T_foo_OBJ, use
10581058
# T_foo_REF instead. T_REF_IV_PTR was added in v5.22.0.
10591059
$xstype =~ s/OBJ$/REF/ || $xstype =~ s/^T_REF_IV_PTR$/T_PTRREF/
1060-
if $pxs->{cur_xsub}{decl}{name} =~ /DESTROY$/;
1060+
if $xsub->{decl}{name} =~ /DESTROY$/;
10611061

10621062
# For a string-ish parameter foo, if length(foo) was also declared
10631063
# as a pseudo-parameter, then override the normal typedef - which
@@ -1162,7 +1162,7 @@ sub as_code {
11621162
if ($default eq 'NO_INIT') {
11631163
# for foo(a, b = NO_INIT), add code to initialise later only if
11641164
# an arg was supplied.
1165-
$pxs->{cur_xbody}{input_part}{deferred_code_lines}
1165+
$xbody->{input_part}{deferred_code_lines}
11661166
.= sprintf "\n\tif (items >= %d) {\n%s;\n\t}\n",
11671167
$arg_num, $init_code;
11681168
}
@@ -1172,7 +1172,7 @@ sub as_code {
11721172
my $else = ($init_code =~ /\S/) ? "\telse {\n$init_code;\n\t}\n" : "";
11731173

11741174
$default =~ s/"/\\"/g; # escape double quotes
1175-
$pxs->{cur_xbody}{input_part}{deferred_code_lines}
1175+
$xbody->{input_part}{deferred_code_lines}
11761176
.= sprintf "\n\tif (items < %d)\n\t %s = %s;\n%s",
11771177
$arg_num,
11781178
$var,
@@ -1190,7 +1190,7 @@ sub as_code {
11901190

11911191
print ";\n";
11921192

1193-
$pxs->{cur_xbody}{input_part}{deferred_code_lines}
1193+
$xbody->{input_part}{deferred_code_lines}
11941194
.= sprintf "\n%s;\n", $init_code
11951195
if $init_code =~ /\S/;
11961196
}
@@ -1205,7 +1205,7 @@ sub as_code {
12051205
}
12061206

12071207
if (defined $defer) {
1208-
$pxs->{cur_xbody}{input_part}{deferred_code_lines}
1208+
$xbody->{input_part}{deferred_code_lines}
12091209
.= $pxs->eval_input_typemap_code("qq\a$defer\a", $eval_vars) . "\n";
12101210
}
12111211
}
@@ -3581,7 +3581,7 @@ sub as_code {
35813581

35823582
$self->SUPER::as_code($pxs, $xsub, $xbody); # emit code block
35833583

3584-
print "\tLEAVE;\n" if $pxs->{cur_xsub}{SCOPE_enabled};
3584+
print "\tLEAVE;\n" if $xsub->{SCOPE_enabled};
35853585

35863586
# Suppress "statement is unreachable" warning on HPUX
35873587
print "#if defined(__HP_cc) || defined(__HP_aCC)\n",

dist/ExtUtils-ParseXS/t/001-basic.t

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,6 +3537,28 @@ EOF
35373537
\QPUSHi((IV)RETVAL);\E
35383538
}sx, "branch Y doesn't return RETVAL" ],
35393539
],
3540+
[
3541+
"CASE with variant deferred var inits",
3542+
[ Q(<<'EOF') ],
3543+
|int
3544+
|foo(abc)
3545+
| CASE: X
3546+
| AV *abc
3547+
|
3548+
| CASE: Y
3549+
| HV *abc
3550+
EOF
3551+
[ 0, 0, qr{\Qif (X)\E
3552+
.*
3553+
croak.*\Qnot an ARRAY reference\E
3554+
.*
3555+
\Qelse if (Y)\E
3556+
.*
3557+
croak.*\Qnot a HASH reference\E
3558+
}sx, "differing croaks" ],
3559+
3560+
],
3561+
35403562
[
35413563
"CASE: case follows unconditional CASE",
35423564
[ Q(<<'EOF') ],

0 commit comments

Comments
 (0)