Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParseXS: codify typeless param and SV* as placeholders #22761

Merged
merged 2 commits into from
Nov 19, 2024
Merged

Conversation

iabyn
Copy link
Contributor

@iabyn iabyn commented Nov 18, 2024

These two commits: add tests for the existing behaviour of allowing an XSUB parameter which doesn't have a type to act as a placeholder; and as a special case, restores the recently changed behaviour of also allowing 'SV*' to denote a placeholder.

  • This set of changes does not require a perldelta entry.

@tonycoz
Copy link
Contributor

tonycoz commented Nov 18, 2024

The semantics of such XSUBs with no body (i.e. autocall) are a bit odd.
The parameter is passed as an arg to the wrapped C function even though
the C var hasn't been declared or initialised. I decided to keep that
as-is, because it's possible that the var has instead been declared in a
PREINIT section. (I have no idea why you would want to do that, which
makes it almost certain that some XS module on CPAN is in fact doing
it.)

I've dealt with this before with C_ARGS.

In XS, you can declare a parameter without a type being specified
(neither in the signature, nor in an INPUT line) and it informally
becomes a placeholder: no C variable of that name is declared, but it
causes the next arg to be skipped. For example,

    int
    foo(int A, B, int C)
        ...

emits C code which: checks for 3 args, declares A and C as vars, and
assigns them the values of ST(0) and ST(2).

This commit adds some tests which confirm this behaviour.

The semantics of such XSUBs with no body (i.e. autocall) are a bit odd.
The parameter is passed as an arg to the wrapped C function even though
the C var hasn't been declared or initialised. I decided to keep that
as-is, because it's possible that the var has instead been declared in a
PREINIT section. (I have no idea why you would want to do that, which
makes it almost certain that some XS module on CPAN is in fact doing
it.)

Note that placeholders with default values are supported: both the var
and the default value are ignored, and the arg is skipped. This is a bit
ugly, but it allows an XSUB to accept a variable number of parameters,
even if one of those parameters is no longer used.

(And like most such things, I first discovered that it was a "thing" by
seeing DB_File.xs break when I tried to disallow it. If there is a weird
or impossible thing to do in XS, you can be certain that DB_File is
doing it.)
ExtUtils::ParseXS, up until and including perl 5.40.0, accepted
unparseable XSUB parameter declarations: if the parameter couldn't be
parsed, it was just silently skipped. This had the side effect that
any old line noise could be used as a placeholder: no parameter would
be declared, but during arg processing, the arg would be skipped.

During my recent refactoring work, I instead made it an error if the
parameter couldn't be parsed, but this broke some modules which were
using 'SV*' as a placeholder, e.g.

    int
    foo(int a, SV*, int b)
        ...

To partially restore backwards compatibility, this commit recognises
the special case of 'SV*' being used as a placeholder. All other
unparseable parameter declarations will continue to be an error.

It will however now still emit an error if 'SV*' is used on a bodiless sub.
It used to cause the call to the C function to be emitted as (from the
example above),

    RETVAL = foo(a, SV*, b);

which isn't legal C code. So making it an error isn't breaking backwards
compatibility.

The coder can still use C_ARGS, e.g.

    int
    foo(int a, SV*, int b)
        C_ARGS: a, b
@iabyn iabyn force-pushed the davem/xs_refactor7 branch from 1491ccd to 1b37187 Compare November 19, 2024 09:09
@iabyn
Copy link
Contributor Author

iabyn commented Nov 19, 2024

Just pushed an update with prototypes for 'SV*' placeholder fixed - the SV* wasn't getting a '$'.

@iabyn iabyn merged commit 2ac0488 into blead Nov 19, 2024
67 checks passed
@iabyn iabyn deleted the davem/xs_refactor7 branch November 19, 2024 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants