regen/embed.pl: Handle m with p flags

Prior to this commit these were illegal.

This causes embed.fnc to generate macro 'Perl_foo' #defined to be  macro
'foo'.  If the macro name is all upper case, we instead get macro
'PERL_FOO' for 'FOO'.  This could be used to easily convert existing
macros into having long names should some become a name space pollution
problem.

This also documents in embed.fnc, under the 'm' flag discussion, how to
use this instead of placing things in mathoms.c, or creating stub
functions.
This commit is contained in:
Karl Williamson 2024-10-21 12:51:40 -06:00 committed by Karl Williamson
parent f8a5e26267
commit 90f4e9b863
4 changed files with 80 additions and 42 deletions

View File

@ -1878,7 +1878,11 @@ sub docout ($fh, $section_name, $element_name, $docref) {
|| $needs_Perl_entry
|| $cant_use_short_name)
{
$name = "Perl_$name";
# An all uppercase macro name gets an uppercase prefix.
my $perl = ($flags =~ /m/ && $name !~ /[[:lower:]]/)
? "PERL_"
: "Perl_";
$name = "$perl$name";
# We can't hide the existence of any thread context
# parameter when using the "Perl_" long form. So it must

View File

@ -14,7 +14,8 @@
: real (full) name, with any appropriate thread context paramaters, thus hiding
: that detail from the typical code.
:
: Most macros (as opposed to functions) listed here are the complete full name.
: Many macros (as opposed to functions) listed here are the complete full name,
: though we may want to start converting those to have full names.
:
: All non-static functions defined by perl need to be listed in this file.
: embed.pl uses the entries here to construct:
@ -157,8 +158,9 @@
: and you know at a glance that the macro actually has documentation. It
: doesn't by itself create any documentation; instead the other apidoc lines
: pull in information specified by these lines. Many of the lines in this
: file for macros could be pulled out of here and replaced by these lines
: throughout the source. It is a goal to do that as convenience dictates.
: file for macros that don't also have the 'p' flag (described below) could be
: pulled out of here and replaced by these lines throughout the source. It is
: a goal to do that as convenience dictates.
:
: The other apidoc lines either have the usage data as part of the line, or
: pull in the data from this file or apidoc_defn lines.
@ -210,10 +212,10 @@
: line that begins with an '='. In particular, an '=cut' line ends that
: documentation without introducing something new.
:
: Various macros and other elements aren't listed here in embed.fnc. They are
: documented in the same manner, but since they don't have this file to get
: information from, the defining lines have the syntax and meaning they do in
: this file, so it can be specified:
: Various macros and other elements aren't listed here in embed.fnc (though
: they could be). They are documented in the same manner, but since they don't
: have this file to get information from, the defining lines have the syntax
: and meaning they do in this file, so it can be specified:
:
: =for apidoc flags|return_type|name|arg1|arg2|...|argN
: =for apidoc_item flags|return_type|name|arg1|arg2|...|argN
@ -301,14 +303,13 @@
: functions flagged with this, the installation can run Configure with
: the -Accflags='-DNO_MATHOMS' parameter to not even compile them.
:
: Sometimes the function has been subsumed by a more general one (say,
: by adding a flags parameter), and a macro exists with the original
: short name API, and it calls the new function, bypassing this one, and
: the original 'Perl_' form is being deprecated. In this case also
: specify the 'M' flag.
: If the function can be implemented as a macro (that evaluates its
: arguments exactly once), use the 'm' and 'p' flags together to implement
: this. (See the discussion under 'm'.) Another option for this is to
: use the 'M' flag.
:
: Without the M flag, these functions should be deprecated, and it is an
: error to not also specify the 'D' flag.
: Without the m or M flags, these functions should be deprecated, and it
: is an error to not also specify the 'D' flag.
:
: The 'b' functions are normally moved to mathoms.c, but if
: circumstances dictate otherwise, they can be anywhere, provided the
@ -439,24 +440,50 @@
: __attribute__always_inline__ is added
:
: 'm' Implemented as a macro; there is no function associated with this
: name, and hence no long Perl_ or S_ name. However, if the macro name
: itself begins with 'Perl_', autodoc.pl will show a thread context
: parameter unless the 'T' flag is specified.
: name. There is no long S_ name.
:
: However, you may #define the macro with a long name like 'Perl_foo',
: and specify the 'p' flag. This will cause an embed.h entry to be
: created that #defines 'foo' as 'Perl_foo'. This can be used to make
: any macro have a long name, perhaps to avoid name collisions. If
: instead you define the macro as 'PERL_FOO' (all uppercase), the
: embed.h entry will use all uppercase.
:
: It is particularly useful tp preserve backward compatibility when a
: function is converted to be a macro (remembering to not create a macro
: which evaluates its parameters more than once). Most of mathoms.c
: could be converted to use this facility. When there is no thread
: context involved, you just do something like
:
: #define Perl_foo(a, b, c) Perl_bar(a, b, 0, c)
:
: Otherwise consider this general case where there is a series of macros
: that build on the previous ones by calling something with a different
: name or with an extra parameter beyond what the previous one did:
:
: #define Perl_foo(mTHX, a) Perl_bar1(aTHX, a)
: #define Perl_bar1(mTHX, a) Perl_bar2(aTHX, a, 0)
: #define Perl_bar2(mTHX, a, b) Perl_bar3(aTHX, a, b, 0)
: #define Perl_bar3(mTHX, a, b, c) Perl_func(aTHX_ a, b, c, 0)
:
: Use the formal parameter name 'mTHX,' (which stands for "macro thread
: context") as the first in each macro definition, and call the next
: macro in the sequence with 'aTHX,' (Note the commas). Eventually, the
: sequence will end with a function call (or else there would be no need
: for thread context). For that instead call it with 'aTHX_' (with an
: underscore instead of a comma).
:
: suppress proto.h entry (actually, not suppressed, but commented out)
: suppress entry in the list of exported symbols available on all
: platforms
: suppress embed.h entry, as the implementation should furnish the macro
: suppress embed.h entry (when no 'p' flag), as the implementation
: should furnish the macro
:
: 'M' The implementation is furnishing its own macro instead of relying on
: the automatically generated short name macro (which simply expands to
: call the real name function). One reason to do this is if the
: parameters need to be cast from what the caller has, or if there is a
: macro that bypasses this function (whose long name is being retained
: for backward compatibility for those who call it with that name). An
: example is when a new function is created with an extra parameter and
: a wrapper macro is added that has the old API, but calls the new one
: with the exta parameter set to a default.
: parameters need to be cast from what the caller has. There is less
: need to do this now that 'm' and 'p' together is supported.
:
: This flag requires the 'p' flag to be specified, as there would be no
: need to do this if the function weren't publicly accessible before.
@ -492,8 +519,8 @@
:
: This is used for whatever reason to force the function to be called
: with the long name. Perhaps there is a varargs issue. Use the 'M'
: flag instead for wrapper macros, and legacy-only functions should
: also use 'b'.
: or 'm' flags instead for wrapper macros, and legacy-only functions
: should also use 'b'.
:
: embed.h: suppress "#define foo Perl_foo"
:
@ -518,9 +545,10 @@
:
: proto.h: add __attribute__pure__
:
: 'p' Function in source code has a Perl_ prefix:
: 'p' Function or macro in source code has a Perl_ prefix:
:
: proto.h: function is declared as Perl_foo rather than foo
: proto.h: function or macro is declared as Perl_foo rather than foo
: (though the entries for macros will be commented out)
: embed.h: "#define foo Perl_foo" entries added
:
: 'R' Return value must not be ignored (also implied by 'a' and 'P' flags):

View File

@ -22,15 +22,15 @@
/*
* This file contains mathoms, various binary artifacts from previous
* versions of Perl which we cannot completely remove from the core
* code. There are two reasons functions should be here:
* code. There is only one reason these days for functions should be here:
*
* 1) A function has been replaced by a macro within a minor release,
* so XS modules compiled against an older release will expect to
* still be able to link against the function
* 2) A function Perl_foo(...) with #define foo Perl_foo(aTHX_ ...)
* has been replaced by a macro, e.g. #define foo(...) foo_flags(...,0)
* but XS code may still explicitly use the long form, i.e.
* Perl_foo(aTHX_ ...)
*
* It used to be that this was the way to handle the case were a function
* Perl_foo(...) had been replaced by a macro. But see the 'm' flag discussion
* in embed.fnc for a better way to handle this.
*
* This file can't just be cleaned out periodically, because that would break
* builds with -DPERL_NO_SHORT_NAMES

View File

@ -49,7 +49,14 @@ sub full_name ($$) { # Returns the function name with potentially the
# prefixes 'S_' or 'Perl_'
my ($func, $flags) = @_;
return "Perl_$func" if $flags =~ /[ps]/;
if ($flags =~ /[ps]/) {
# An all uppercase macro name gets an uppercase prefix.
return ($flags =~ /m/ && $flags =~ /p/ && $func !~ /[[:lower:]]/)
? "PERL_$func"
: "Perl_$func";
}
return "S_$func" if $flags =~ /[SIi]/;
return $func;
}
@ -141,10 +148,6 @@ sub generate_proto_h {
if ($flags =~ /S/) {
die_at_end "$plain_func: m and S flags are mutually exclusive";
}
elsif ($flags =~ /p/ && $has_context) {
die_at_end "$plain_func: m flag with p flag currently requires"
. " T flag";
}
}
else {
die_at_end "$plain_func: u flag only usable with m" if $flags =~ /u/;
@ -509,7 +512,7 @@ sub embed_h {
my $inner_ind= $ind ? " " : " ";
if ($flags !~ /[omM]/ or ($flags =~ /m/ && $flags =~ /p/)) {
my $argc = scalar @$args;
if ($flags =~ /[Tm]/) {
if ($flags =~ /[T]/) {
my $full_name = full_name($func, $flags);
next if $full_name eq $func; # Don't output a no-op.
$ret = indent_define($func, $full_name, $ind);
@ -532,8 +535,11 @@ sub embed_h {
$use_va_list ? ("__VA_ARGS__") : ());
$ret = "#${ind}define $func($paramlist) ";
add_indent($ret,full_name($func, $flags) . "(aTHX");
$ret .= "_ " if $replacelist;
$ret .= $replacelist;
if ($replacelist) {
$ret .= ($flags =~ /m/) ? "," : "_ ";
$ret .= $replacelist;
}
if ($flags =~ /W/) {
if ($replacelist) {
$ret .= " comma_aDEPTH";