Skip to content

Create new OP_MULTIPARAM to implement subroutine signatures #23574

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

Draft
wants to merge 6 commits into
base: blead
Choose a base branch
from

Conversation

leonerd
Copy link
Contributor

@leonerd leonerd commented Aug 14, 2025

Creates a new UNOP_AUX op type, OP_MULTIPARAM, that handles all of the initial behaviour of assigning values to parameters of a subroutine signature out of values passed by the caller. This is created in a similar style to other multi-ops like OP_MULTIDEREF and OP_MULTICONCAT where the op's aux structure contains a sub-program of sorts, which describes all of the small details of operation.

Also adds a LOGOP, OP_PARAMTEST and UNOP OP_PARAMSTORE which are responsible for implementing the default expressions of optional parameters. These use the SvPADSTALE flag set on pad lexicals used as parameters to remember whether assignment has happened, ensuring that missing vs present-but-undef can be detected in a way that does not depend on counting arguments on the stack.

This change is carefully designed to support two future ideas:

  • Named parameters as per PPC0024

  • "no-snails"; the performance optimisation that avoids storing incoming argument values in the @_ AV and instead consumes them directly from the stack

--

This set of changes currently does not have a perldelta entry, because it doesn't directly make any changes that are end-user visible. However, since it is quite a significant internal change, I could be talked into writing an entry in the "internal changes" section anyway. Reviewers: Thoughts?

The previous names were just copied from similar fields in previous
signature handling code. These new names are a better fit for their
current and intended future purpose.
By defining a helper term for optional defaulting expression we can
remove one of the three alternate cases down to just two. This will help
when adding more code to these action blocks in future,
This two new helper functions will be useful for sharing behaviour with
upcoming code, when adding OP_MULTIPARAM.
…gument processing

The specific behaviour of this obscure modification case is not
documented or relied upon elsewhere in code. Rather than attempt to
preserve this cornercase, it's easier just to no longer test for it, as
upcoming changes will alter the values that are visible.
Creates a new UNOP_AUX op type, `OP_MULTIPARAM`, that handles all of the
initial behaviour of assigning values to parameters of a subroutine
signature out of values passed by the caller. This is created in a
similar style to other multi-ops like `OP_MULTIDEREF` and
`OP_MULTICONCAT` where the op's aux structure contains a sub-program of
sorts, which describes all of the small details of operation.

Also adds a LOGOP, `OP_PARAMTEST` and UNOP `OP_PARAMSTORE` which are
responsible for implementing the default expressions of optional
parameters. These use the `SvPADSTALE` flag set on pad lexicals used as
parameters to remember whether assignment has happened, ensuring that
missing vs present-but-undef can be detected in a way that does not
depend on counting arguments on the stack.

This change is carefully designed to support two future ideas:

  * Named parameters as per PPC0024
    https://github.com/Perl/PPCs/blob/main/ppcs/ppc0024-signature-named-parameters.md

  * "no-snails"; the performance optimisation that avoids storing
    incoming argument values in the `@_` AV and instead consumes them
    directly from the stack
@leonerd leonerd marked this pull request as draft August 14, 2025 20:21
@leonerd
Copy link
Contributor Author

leonerd commented Aug 14, 2025

Weirdly, while github CI and most commentors on IRC report test failures in t/op/signatures.t, this runs reliably on my local machine. Very strange.

In case it's somehow related to build options, the script I use to configure and build is:

test -f config.sh && rm config.sh
test -f Policy.sh && rm Policy.sh

./Configure -des \
  -Dusedevel \
  -Dprefix=$HOME/perl5/perlbrew/perls/bleadperl/ \
  -DDEBUGGING \
  -Uversiononly \
  -Dman1dir=none -Dman3dir=none \
  -Dusethreads \
  -Dinc_version_list=none \
  -Doptimize='-gdwarf-2 -g3' \
  "$@"

make -j8
make -j8 test_prep

Copy link
Contributor

@mauke mauke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commit message: "This two" should be "These two"

*/
varop->op_next = defop;
defexpr->op_next = varop;
param->padix = allocmy("", 0, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perl_allocmy currently does not support empty names because it blindly uses name[1]. It needs to be changed to check len first.

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.

3 participants