Skip to content

Commit 4a93e0f

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 6a09231 commit 4a93e0f

File tree

3 files changed

+5754
-86
lines changed

3 files changed

+5754
-86
lines changed

embed.h

Lines changed: 65 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -21,77 +21,11 @@
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)
2927

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 */
28+
/* Create short name macros that hide any need for thread context */
9529

9630
# define AvFILL_(a) Perl_AvFILL_(aTHX_ a)
9731
# define Gv_AMupdate(a,b) Perl_Gv_AMupdate(aTHX_ a,b)
@@ -908,7 +842,20 @@
908842
# define sv_setpvf_nocontext Perl_sv_setpvf_nocontext
909843
# define warn_nocontext Perl_warn_nocontext
910844
# define warner_nocontext Perl_warner_nocontext
911-
# endif /* defined(MULTIPLICITY) */
845+
# else /* if !defined(MULTIPLICITY) */
846+
/* undefined symbols, point them back at the usual ones */
847+
# define Perl_deb_nocontext Perl_deb
848+
# define Perl_form_nocontext Perl_form
849+
# define Perl_load_module_nocontext Perl_load_module
850+
# define Perl_mess_nocontext Perl_mess
851+
# define Perl_newSVpvf_nocontext Perl_newSVpvf
852+
# define Perl_sv_catpvf_nocontext Perl_sv_catpvf
853+
# define Perl_sv_catpvf_mg_nocontext Perl_sv_catpvf_mg
854+
# define Perl_sv_setpvf_nocontext Perl_sv_setpvf
855+
# define Perl_sv_setpvf_mg_nocontext Perl_sv_setpvf_mg
856+
# define Perl_warn_nocontext Perl_warn
857+
# define Perl_warner_nocontext Perl_warner
858+
# endif /* !defined(MULTIPLICITY) */
912859
# if !defined(MULTIPLICITY) || defined(PERL_CORE) || \
913860
defined(PERL_WANT_VARARGS)
914861
# define deb(...) Perl_deb(aTHX_ __VA_ARGS__)
@@ -1834,7 +1781,52 @@
18341781
# else
18351782
# define do_exec3(a,b,c) Perl_do_exec3(aTHX_ a,b,c)
18361783
# endif
1837-
# endif /* defined(PERL_CORE) */
1784+
# else /* if !defined(PERL_CORE) */
1785+
/* Compatibility stubs. Compile extensions with -DPERL_NOCOMPAT to
1786+
* disable them.
1787+
*/
1788+
# define sv_setptrobj(rv,ptr,name) sv_setref_iv(rv,name,PTR2IV(ptr))
1789+
# define sv_setptrref(rv,ptr) sv_setref_iv(rv,NULL,PTR2IV(ptr))
1790+
# if !defined(PERL_NOCOMPAT)
1791+
1792+
/* Compatibility for this renamed function. */
1793+
# define perl_atexit(a,b) Perl_call_atexit(aTHX_ a,b)
1794+
1795+
/* Compatibility for these functions that had a 'perl_' prefix before
1796+
* 'Perl_' became the standard */
1797+
# define perl_call_argv(a,b,c) Perl_call_argv(aTHX_ a,b,c)
1798+
# define perl_call_method(a,b) Perl_call_method(aTHX_ a,b)
1799+
# define perl_call_pv(a,b) Perl_call_pv(aTHX_ a,b)
1800+
# define perl_call_sv(a,b) Perl_call_sv(aTHX_ a,b)
1801+
# define perl_eval_pv(a,b) Perl_eval_pv(aTHX_ a,b)
1802+
# define perl_eval_sv(a,b) Perl_eval_sv(aTHX_ a,b)
1803+
# define perl_get_av(a,b) Perl_get_av(aTHX_ a,b)
1804+
# define perl_get_cv(a,b) Perl_get_cv(aTHX_ a,b)
1805+
# define perl_get_hv(a,b) Perl_get_hv(aTHX_ a,b)
1806+
# define perl_get_sv(a,b) Perl_get_sv(aTHX_ a,b)
1807+
# define perl_init_i18nl10n(a) Perl_init_i18nl10n(aTHX_ a)
1808+
# define perl_require_pv(a) Perl_require_pv(aTHX_ a)
1809+
1810+
/* Before C99, macros could not wrap varargs functions. This
1811+
provides a set of compatibility functions that don't take an
1812+
extra argument but grab the context pointer using the macro dTHX.
1813+
*/
1814+
1815+
# if defined(MULTIPLICITY) && !defined(PERL_WANT_VARARGS)
1816+
# define deb Perl_deb_nocontext
1817+
# define form Perl_form_nocontext
1818+
# define load_module Perl_load_module_nocontext
1819+
# define mess Perl_mess_nocontext
1820+
# define newSVpvf Perl_newSVpvf_nocontext
1821+
# define sv_catpvf Perl_sv_catpvf_nocontext
1822+
# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext
1823+
# define sv_setpvf Perl_sv_setpvf_nocontext
1824+
# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext
1825+
# define warn Perl_warn_nocontext
1826+
# define warner Perl_warner_nocontext
1827+
# endif /* defined(MULTIPLICITY) && !defined(PERL_WANT_VARARGS) */
1828+
# endif /* !defined(PERL_NOCOMPAT) */
1829+
# endif /* !defined(PERL_CORE) */
18381830
# if defined(PERL_CORE) || defined(PERL_EXT)
18391831
# define append_utf8_from_native_byte Perl_append_utf8_from_native_byte
18401832
# define av_reify(a) Perl_av_reify(aTHX_ a)
@@ -2474,6 +2466,6 @@
24742466
# else
24752467
# define get_context Perl_get_context
24762468
# endif
2477-
#endif /* !defined(PERL_NO_SHORT_NAMES) */
2469+
#endif /* !defined(PERL_DO_UNDEFS) */
24782470

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

perl.h

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

9357+
/* #including a second time causes it to #undef any unwanted symbols to avoid
9358+
* polluting the user name space */
9359+
# define PERL_DO_UNDEFS
9360+
# include "embed.h"
9361+
# undef PERL_DO_UNDEFS
9362+
93579363
#endif /* Include guard */
93589364

93599365
/*

0 commit comments

Comments
 (0)