Skip to content

Commit f7dbd62

Browse files
committed
Gain control of macro namespace visibility
This commit adds the capability to undefine macros that are visible to XS code but shouldn't be. This can be used to stop macro namespace pollution by perl. It works by changing embed.h to have two modes, controlled by a #ifdef that is set by perl.h. perl.h now #includes embed.h twice. The first time works as it always has. The second sets the #ifdef, and causes embed.h to #undef the macros that shouldn't be visible. This call is just before perl.h returns to its includer, so that these macros have come and gone before the file that #included perl.h is affected by them. It comes after the inline headers get included, so they have access to all the symbols that are defined. The list of macros is determined by the visibility given by the apidoc lines documenting them, plus several exception lists that allow a symbol to be visible even though it is not documented as such. In this commit, the main exception list contains everything that is currently visible outside the Perl core, so this should not break any code. But it means that the visibility control is established for future changes to our code base. New macros will not be visible except when documented as needing to be such. We can no longer inadvertently add new names to pollute the user's. I expect that over time, the exception list will become smaller, as we go through it and remove the items that really shouldn't be visible. We can then see via smoking if someone is actually using them, and either decide that these should be visible, or work with the module author for another way to accomplish their needs. (I would hope this would lead to proper documentation of the ones that need to be visible.) There are currently four lists of symbols. One list is for symbols that are used by libc functions, and that Perl may redefine (usually so that code doesn't have to know if it is running on a platform that is lacking the given feature.) The algorithm added here catches most of these and keeps them visible, but there are a few items that currently must be manually listed. A second list is of symbols that the re extension to Perl requires, but no one else needs to. This list is currently empty, as everything initially is in the main exception list. A third list is for items that other Perl extensions require, but no one else needs to. This list is currently empty, as everything initially is in the main exception list. The final list is for items that currently are visible to the whole world. It contains thousands of items. This list should be examined for: 1) Names that shouldn't be so visible; and 2) Names that need to remain visible but should be changed so they are less likely to clash with anything the user might come up with. I have wanted this ability to happen for a long time; and now things have come together to enable it. This allows us to have a clear-cut boundary with CPAN. It means you can add macros that have internal-only use without having to worry about making them likely not to clash with user names. It shows precisely in one place what our names are that are visible to CPAN.
1 parent e1bda61 commit f7dbd62

File tree

3 files changed

+5764
-86
lines changed

3 files changed

+5764
-86
lines changed

embed.h

Lines changed: 77 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -21,77 +21,23 @@
2121

2222
/* (Doing namespace management portably in C is really gross.) */
2323

24-
/* By defining PERL_NO_SHORT_NAMES (not done by default) the short forms
25-
* (like warn instead of Perl_warn) for the API are not defined.
26-
* Not defining the short forms is a good thing for cleaner embedding.
27-
* BEWARE that a bunch of macros don't have long names, so either must be
28-
* added or don't use them if you define this symbol */
24+
/* When this symbol is defined, we undef various symbols we have defined
25+
* earlier when this file was #included with this symbol undefined */
26+
#if defined(PERL_DO_UNDEFS)
27+
# if !defined(PERL_CORE)
28+
# undef do_aexec
29+
# undef free_c_backtrace
30+
# undef my_lstat
31+
# undef my_stat
32+
# if !defined(PERL_EXT)
33+
# undef invlist_intersection_
34+
# undef invlist_subtract_
35+
# undef invlist_union_
36+
# endif
37+
# endif /* !defined(PERL_CORE) */
38+
#else /* if !defined(PERL_DO_UNDEFS) */
2939

30-
#if !defined(MULTIPLICITY)
31-
/* undefined symbols, point them back at the usual ones */
32-
# define Perl_deb_nocontext Perl_deb
33-
# define Perl_form_nocontext Perl_form
34-
# define Perl_load_module_nocontext Perl_load_module
35-
# define Perl_mess_nocontext Perl_mess
36-
# define Perl_newSVpvf_nocontext Perl_newSVpvf
37-
# define Perl_sv_catpvf_nocontext Perl_sv_catpvf
38-
# define Perl_sv_catpvf_mg_nocontext Perl_sv_catpvf_mg
39-
# define Perl_sv_setpvf_nocontext Perl_sv_setpvf
40-
# define Perl_sv_setpvf_mg_nocontext Perl_sv_setpvf_mg
41-
# define Perl_warn_nocontext Perl_warn
42-
# define Perl_warner_nocontext Perl_warner
43-
#endif /* !defined(MULTIPLICITY) */
44-
#if !defined(PERL_CORE)
45-
/* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
46-
* disable them.
47-
*/
48-
# define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
49-
# define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
50-
# if !defined(PERL_NOCOMPAT)
51-
52-
/* Compatibility for this renamed function. */
53-
# define perl_atexit(a,b) Perl_call_atexit(aTHX_ a,b)
54-
55-
/* Compatibility for these functions that had a 'perl_' prefix before
56-
* 'Perl_' became the standard */
57-
# define perl_call_argv(a,b,c) Perl_call_argv(aTHX_ a,b,c)
58-
# define perl_call_method(a,b) Perl_call_method(aTHX_ a,b)
59-
# define perl_call_pv(a,b) Perl_call_pv(aTHX_ a,b)
60-
# define perl_call_sv(a,b) Perl_call_sv(aTHX_ a,b)
61-
# define perl_eval_pv(a,b) Perl_eval_pv(aTHX_ a,b)
62-
# define perl_eval_sv(a,b) Perl_eval_sv(aTHX_ a,b)
63-
# define perl_get_av(a,b) Perl_get_av(aTHX_ a,b)
64-
# define perl_get_cv(a,b) Perl_get_cv(aTHX_ a,b)
65-
# define perl_get_hv(a,b) Perl_get_hv(aTHX_ a,b)
66-
# define perl_get_sv(a,b) Perl_get_sv(aTHX_ a,b)
67-
# define perl_init_i18nl10n(a) Perl_init_i18nl10n(aTHX_ a)
68-
# define perl_require_pv(a) Perl_require_pv(aTHX_ a)
69-
70-
/* Before C99, macros could not wrap varargs functions. This
71-
provides a set of compatibility functions that don't take an
72-
extra argument but grab the context pointer using the macro dTHX.
73-
*/
74-
75-
# if defined(MULTIPLICITY) && !defined(PERL_NO_SHORT_NAMES) && \
76-
!defined(PERL_WANT_VARARGS)
77-
# define deb Perl_deb_nocontext
78-
# define form Perl_form_nocontext
79-
# define load_module Perl_load_module_nocontext
80-
# define mess Perl_mess_nocontext
81-
# define newSVpvf Perl_newSVpvf_nocontext
82-
# define sv_catpvf Perl_sv_catpvf_nocontext
83-
# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext
84-
# define sv_setpvf Perl_sv_setpvf_nocontext
85-
# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext
86-
# define warn Perl_warn_nocontext
87-
# define warner Perl_warner_nocontext
88-
# endif /* defined(MULTIPLICITY) && !defined(PERL_NO_SHORT_NAMES) &&
89-
!defined(PERL_WANT_VARARGS) */
90-
# endif /* !defined(PERL_NOCOMPAT) */
91-
#endif /* !defined(PERL_CORE) */
92-
#if !defined(PERL_NO_SHORT_NAMES)
93-
94-
/* Hide global symbols */
40+
/* Create short name macros that hide any need for thread context */
9541

9642
# define AvFILL_(a) Perl_AvFILL_(aTHX_ a)
9743
# define Gv_AMupdate(a,b) Perl_Gv_AMupdate(aTHX_ a,b)
@@ -908,7 +854,20 @@
908854
# define sv_setpvf_nocontext Perl_sv_setpvf_nocontext
909855
# define warn_nocontext Perl_warn_nocontext
910856
# define warner_nocontext Perl_warner_nocontext
911-
# endif /* defined(MULTIPLICITY) */
857+
# else /* if !defined(MULTIPLICITY) */
858+
/* undefined symbols, point them back at the usual ones */
859+
# define Perl_deb_nocontext Perl_deb
860+
# define Perl_form_nocontext Perl_form
861+
# define Perl_load_module_nocontext Perl_load_module
862+
# define Perl_mess_nocontext Perl_mess
863+
# define Perl_newSVpvf_nocontext Perl_newSVpvf
864+
# define Perl_sv_catpvf_nocontext Perl_sv_catpvf
865+
# define Perl_sv_catpvf_mg_nocontext Perl_sv_catpvf_mg
866+
# define Perl_sv_setpvf_nocontext Perl_sv_setpvf
867+
# define Perl_sv_setpvf_mg_nocontext Perl_sv_setpvf_mg
868+
# define Perl_warn_nocontext Perl_warn
869+
# define Perl_warner_nocontext Perl_warner
870+
# endif /* !defined(MULTIPLICITY) */
912871
# if !defined(MULTIPLICITY) || defined(PERL_CORE) || \
913872
defined(PERL_WANT_VARARGS)
914873
# define deb(...) Perl_deb(aTHX_ __VA_ARGS__)
@@ -1834,7 +1793,52 @@
18341793
# else
18351794
# define do_exec3(a,b,c) Perl_do_exec3(aTHX_ a,b,c)
18361795
# endif
1837-
# endif /* defined(PERL_CORE) */
1796+
# else /* if !defined(PERL_CORE) */
1797+
/* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
1798+
* disable them.
1799+
*/
1800+
# define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
1801+
# define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
1802+
# if !defined(PERL_NOCOMPAT)
1803+
1804+
/* Compatibility for this renamed function. */
1805+
# define perl_atexit(a,b) Perl_call_atexit(aTHX_ a,b)
1806+
1807+
/* Compatibility for these functions that had a 'perl_' prefix before
1808+
* 'Perl_' became the standard */
1809+
# define perl_call_argv(a,b,c) Perl_call_argv(aTHX_ a,b,c)
1810+
# define perl_call_method(a,b) Perl_call_method(aTHX_ a,b)
1811+
# define perl_call_pv(a,b) Perl_call_pv(aTHX_ a,b)
1812+
# define perl_call_sv(a,b) Perl_call_sv(aTHX_ a,b)
1813+
# define perl_eval_pv(a,b) Perl_eval_pv(aTHX_ a,b)
1814+
# define perl_eval_sv(a,b) Perl_eval_sv(aTHX_ a,b)
1815+
# define perl_get_av(a,b) Perl_get_av(aTHX_ a,b)
1816+
# define perl_get_cv(a,b) Perl_get_cv(aTHX_ a,b)
1817+
# define perl_get_hv(a,b) Perl_get_hv(aTHX_ a,b)
1818+
# define perl_get_sv(a,b) Perl_get_sv(aTHX_ a,b)
1819+
# define perl_init_i18nl10n(a) Perl_init_i18nl10n(aTHX_ a)
1820+
# define perl_require_pv(a) Perl_require_pv(aTHX_ a)
1821+
1822+
/* Before C99, macros could not wrap varargs functions. This
1823+
provides a set of compatibility functions that don't take an
1824+
extra argument but grab the context pointer using the macro dTHX.
1825+
*/
1826+
1827+
# if defined(MULTIPLICITY) && !defined(PERL_WANT_VARARGS)
1828+
# define deb Perl_deb_nocontext
1829+
# define form Perl_form_nocontext
1830+
# define load_module Perl_load_module_nocontext
1831+
# define mess Perl_mess_nocontext
1832+
# define newSVpvf Perl_newSVpvf_nocontext
1833+
# define sv_catpvf Perl_sv_catpvf_nocontext
1834+
# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext
1835+
# define sv_setpvf Perl_sv_setpvf_nocontext
1836+
# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext
1837+
# define warn Perl_warn_nocontext
1838+
# define warner Perl_warner_nocontext
1839+
# endif /* defined(MULTIPLICITY) && !defined(PERL_WANT_VARARGS) */
1840+
# endif /* !defined(PERL_NOCOMPAT) */
1841+
# endif /* !defined(PERL_CORE) */
18381842
# if defined(PERL_CORE) || defined(PERL_EXT)
18391843
# define append_utf8_from_native_byte Perl_append_utf8_from_native_byte
18401844
# define av_reify(a) Perl_av_reify(aTHX_ a)
@@ -2474,6 +2478,6 @@
24742478
# else
24752479
# define get_context Perl_get_context
24762480
# endif
2477-
#endif /* !defined(PERL_NO_SHORT_NAMES) */
2481+
#endif /* !defined(PERL_DO_UNDEFS) */
24782482

24792483
/* ex: set ro ft=c: */

perl.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9354,6 +9354,16 @@ END_EXTERN_C
93549354
93559355
*/
93569356

9357+
START_EXTERN_C
9358+
9359+
/* #including a second time causes it to #undef any unwanted symbols to avoid
9360+
* polluting the user name space */
9361+
# define PERL_DO_UNDEFS
9362+
# include "embed.h"
9363+
# undef PERL_DO_UNDEFS
9364+
9365+
END_EXTERN_C
9366+
93579367
#endif /* Include guard */
93589368

93599369
/*

0 commit comments

Comments
 (0)