Skip to content

Commit b713240

Browse files
committed
ParseXS: refactor: set XSRETURN_count_* earlier
Previously these two values were set at the end of parsing an XSUB: XSRETURN_count_basic XSRETURN_count_extra They represent whether a RETVAL SV will be returned by the XSUB, and how many extra SVs are returned due to parameters declared as OUTLIST. This commit sets them earlier, as in particular, the next commit will need to access XSRETURN_count_basic earlier. XSRETURN_count_extra is now set right after parsing the XSUB's declaration, as its value can't change after then. XSRETURN_count_basic is now set after parsing the output part of the each body of the XSUB (an XSUB can have a body per CASE). Its value *aught* to be consistent across all bodies, but it's possible for the CODE_sets_ST0 hack (which looks for code like like 'ST(0) = ...' in any CODE: block) to vary across bodies; so this commit also adds a new warning and test for that.
1 parent c4d786d commit b713240

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

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

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ BEGIN { $build_subclass->('', # parent
204204
'seen_SCOPE',
205205

206206
# These three fields indicate how many SVs are returned to the caller,
207-
# and so influence the emitting of EXTEND(n) and XSRETURN(n).
207+
# and so influence the emitting of 'EXTEND(n)', 'XSRETURN(n)', and
208+
# potentially, the value of n in 'ST(n) = ...'.
208209
#
209210
# XSRETURN_count_basic is 0 or 1 and indicates whether a basic return
210211
# value is pushed onto the stack. It is usually directly related to
@@ -365,21 +366,6 @@ sub parse {
365366
}
366367
} # end while (@{ $pxs->{line} })
367368

368-
# Work out how many SVs will be returned
369-
370-
$self->{XSRETURN_count_basic} =
371-
( $self->{CODE_sets_ST0}
372-
or ( $self->{decl}{return_type}{type} ne "void"
373-
&& !$self->{decl}{return_type}{no_output})
374-
)
375-
? 1 : 0;
376-
377-
$self->{XSRETURN_count_extra} =
378-
grep { defined $_->{in_out}
379-
&& $_->{in_out} =~ /OUTLIST$/
380-
}
381-
@{$self->{decl}{params}{kids}};
382-
383369
# If any aliases have been declared, make the main sub name ix 0
384370
# if not specified.
385371

@@ -767,6 +753,14 @@ sub parse {
767753
$params->parse($pxs, $xsub, $params_text);
768754
$self->{params} = $params;
769755

756+
# How many OUTLIST SVs get returned in addition to RETVAL
757+
$xsub->{XSRETURN_count_extra} =
758+
grep { defined $_->{in_out}
759+
&& $_->{in_out} =~ /OUTLIST$/
760+
}
761+
@{$self->{params}{kids}};
762+
763+
770764
1;
771765
}
772766

@@ -2806,6 +2800,17 @@ sub parse {
28062800
. $ExtUtils::ParseXS::Constants::generic_xsub_keywords_alt,
28072801
);
28082802

2803+
# Work out whether a RETVAL SV will be returned. Note that this should
2804+
# be consistent across CASEs; we warn elsewhere if CODE_sets_ST0 isn't
2805+
# consistent.
2806+
2807+
$xsub->{XSRETURN_count_basic} =
2808+
( $xsub->{CODE_sets_ST0}
2809+
or ( $xsub->{decl}{return_type}{type} ne "void"
2810+
&& !$xsub->{decl}{return_type}{no_output})
2811+
)
2812+
? 1 : 0;
2813+
28092814
1;
28102815
}
28112816

@@ -3697,10 +3702,15 @@ sub parse {
36973702
# will be used later when deciding how/whether to emit EXTEND(n) and
36983703
# XSRETURN(n).
36993704

3700-
$xsub->{CODE_sets_ST0} =
3705+
my $st0 =
37013706
$code =~ m{ ( \b ST \s* \( [^;]* = )
37023707
| ( \b XST_m\w+\s* \( ) }x;
37033708

3709+
$pxs->Warn("Warning: ST(0) isn't consistently set in every CASE's CODE block")
3710+
if defined $xsub->{CODE_sets_ST0}
3711+
&& $xsub->{CODE_sets_ST0} ne $st0;
3712+
$xsub->{CODE_sets_ST0} = $st0;
3713+
37043714
1;
37053715
}
37063716

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3620,6 +3620,21 @@ EOF
36203620
[ 1, 0, qr/\QError: junk at end of function: " INPUTx:" in /,
36213621
"expected err" ],
36223622
],
3623+
[
3624+
"CASE: setting ST(0)",
3625+
[ Q(<<'EOF') ],
3626+
|void
3627+
|foo(a)
3628+
|CASE: X
3629+
| CODE:
3630+
| ST(0) = 1;
3631+
|CASE: Y
3632+
| CODE:
3633+
| blah
3634+
EOF
3635+
[ 1, 0, qr/\QWarning: ST(0) isn't consistently set in every CASE's CODE block/,
3636+
"expected err" ],
3637+
],
36233638
36243639
36253640
);

0 commit comments

Comments
 (0)