Skip to content

Commit

Permalink
regen/embed.pl: Handle m with p flags
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
khwilliamson committed Oct 28, 2024
1 parent f8a5e26 commit 90f4e9b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 42 deletions.
6 changes: 5 additions & 1 deletion autodoc.pl
Original file line number Diff line number Diff line change
Expand Up @@ -1878,7 +1878,11 @@ ($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
Expand Down
84 changes: 56 additions & 28 deletions embed.fnc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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"
:
Expand All @@ -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):
Expand Down
10 changes: 5 additions & 5 deletions mathoms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 14 additions & 8 deletions regen/embed.pl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@ ($$)
# 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;
}
Expand Down Expand Up @@ -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/;
Expand Down Expand Up @@ -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);
Expand All @@ -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";
Expand Down

0 comments on commit 90f4e9b

Please sign in to comment.