This is a live mirror of the Perl 5 development currently hosted at
Workaround for perl #124212: these functions are not true static inline
authorJarkko Hietaniemi <>
Sun, 1 Nov 2015 17:55:49 +0000 (12:55 -0500)
committerJarkko Hietaniemi <>
Sun, 1 Nov 2015 22:12:40 +0000 (17:12 -0500)
By "true" I mean that they have prototypes, but no bodies.

So don't declare their prototypes under PERL_NO_INLINE_FUNCTIONS.

After some studying of
it seems like Perl is trying to implement the "simple portable" model.

But the functions listed as failing during porting/extrefs.t in Tru64:
they are neither fish nor fowl.  Their prototypes are listed in
proto.h as PERL_STATIC_INLINE (which in Tru64 is "static inline"),
but since the test is built with -DPERL_NO_INLINE_FUNCTIONS,
the function bodies (which would be in inline.h) are not visible.
So they end up being body-less static inline prototypes, which is,
I believe, somewhat of an oxymoron.

The "complicated portable" model might be a more wortwhile longer
term goal: in that, there is no "static inline", and there would be
a new source file, say, inline.c.  Now with the "simple portable",
the bodies might end up being compiled multiple times, multiple copies
ending up in different object files, depending on how smart the
compiler/linker is.

Another move could be that maybe there should be no prototypes at all
for inlineables, because having those is kind beside the point.  How
well that would work across different compilers is unknown.

Yet another move, perhaps the simplest one, would be to move these
particular functions away from inline.h.  But this would be just
dodging the larger problems discussed above.


index c7dfead..d694f4e 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -231,7 +231,9 @@ Apd |void   |av_push        |NN AV *av|NN SV *val
 EXp    |void   |av_reify       |NN AV *av
 ApdR   |SV*    |av_shift       |NN AV *av
 Apd    |SV**   |av_store       |NN AV *av|SSize_t key|NULLOK SV *val
 AidR   |SSize_t|av_top_index   |NN AV *av
 AmpdR  |SSize_t|av_tindex      |NN AV *av
 Apd    |void   |av_undef       |NN AV *av
 ApdoxM |SV**   |av_create_and_unshift_one|NN AV **const avp|NN SV *const val
@@ -654,7 +656,9 @@ pR  |OP*    |invert         |NULLOK OP* cmd
 ApR    |I32    |is_lvalue_sub
 : Used in cop.h
 XopR   |I32    |was_lvalue_sub
 AiMRn  |STRLEN |_is_utf8_char_slow|NN const U8 *s|NN const U8 *e
 ADMpPR |U32    |to_uni_upper_lc|U32 c
 ADMpPR |U32    |to_uni_title_lc|U32 c
 ADMpPR |U32    |to_uni_lower_lc|U32 c
@@ -1446,7 +1450,9 @@ Apd       |void   |sv_magic       |NN SV *const sv|NULLOK SV *const obj|const int how \
 Apd    |MAGIC *|sv_magicext    |NN SV *const sv|NULLOK SV *const obj|const int how \
                                |NULLOK const MGVTBL *const vtbl|NULLOK const char *const name \
                                |const I32 namlen
 Ein    |bool   |sv_only_taint_gmagic|NN SV *sv
 : exported for
 EXp    |MAGIC *|sv_magicext_mglob|NN SV *sv
 ApdbamR        |SV*    |sv_mortalcopy  |NULLOK SV *const oldsv
@@ -1690,8 +1696,10 @@ Am       |I32    |whichsig       |NN const char* sig
 Ap     |I32    |whichsig_sv    |NN SV* sigsv
 Ap     |I32    |whichsig_pv    |NN const char* sig
 Ap     |I32    |whichsig_pvn   |NN const char* sig|STRLEN len
 : used to check for NULs in pathnames and other names
 AiR    |bool   |is_safe_syscall|NN const char *pv|STRLEN len|NN const char *what|NN const char *op_name
 #ifdef PERL_CORE
 inR    |bool   |should_warn_nl|NN const char *pv
@@ -2513,7 +2521,9 @@ sRM       |U8*    |swash_scan_list_line|NN U8* l|NN U8* const lend|NN UV* min \
                |NN const U8* const typestr
 AiMn   |void   |append_utf8_from_native_byte|const U8 byte|NN U8** dest
 Apd    |void   |sv_setsv_flags |NN SV *dstr|NULLOK SV *sstr|const I32 flags
 Apd    |void   |sv_catpvn_flags|NN SV *const dstr|NN const char *sstr|const STRLEN len \
diff --git a/embed.h b/embed.h
index 5472b07..272ecf5 100644 (file)
--- a/embed.h
+++ b/embed.h
@@ -32,7 +32,6 @@
 #define _is_uni_perl_idcont(a) Perl__is_uni_perl_idcont(aTHX_ a)
 #define _is_uni_perl_idstart(a)        Perl__is_uni_perl_idstart(aTHX_ a)
 #define _is_utf8_FOO(a,b)      Perl__is_utf8_FOO(aTHX_ a,b)
-#define _is_utf8_char_slow     S__is_utf8_char_slow
 #define _is_utf8_idcont(a)     Perl__is_utf8_idcont(aTHX_ a)
 #define _is_utf8_idstart(a)    Perl__is_utf8_idstart(aTHX_ a)
 #define _is_utf8_mark(a)       Perl__is_utf8_mark(aTHX_ a)
@@ -47,7 +46,6 @@
 #define _to_utf8_upper_flags(a,b,c,d)  Perl__to_utf8_upper_flags(aTHX_ a,b,c,d)
 #define amagic_call(a,b,c,d)   Perl_amagic_call(aTHX_ a,b,c,d)
 #define amagic_deref_call(a,b) Perl_amagic_deref_call(aTHX_ a,b)
-#define append_utf8_from_native_byte   S_append_utf8_from_native_byte
 #define apply_attrs_string(a,b,c,d)    Perl_apply_attrs_string(aTHX_ a,b,c,d)
 #define atfork_lock            Perl_atfork_lock
 #define atfork_unlock          Perl_atfork_unlock
@@ -63,7 +61,6 @@
 #define av_push(a,b)           Perl_av_push(aTHX_ a,b)
 #define av_shift(a)            Perl_av_shift(aTHX_ a)
 #define av_store(a,b,c)                Perl_av_store(aTHX_ a,b,c)
-#define av_top_index(a)                S_av_top_index(aTHX_ a)
 #define av_undef(a)            Perl_av_undef(aTHX_ a)
 #define av_unshift(a,b)                Perl_av_unshift(aTHX_ a,b)
 #define block_end(a,b)         Perl_block_end(aTHX_ a,b)
 #define isIDFIRST_lazy(a)      Perl_isIDFIRST_lazy(aTHX_ a)
 #define is_invariant_string    Perl_is_invariant_string
 #define is_lvalue_sub()                Perl_is_lvalue_sub(aTHX)
-#define is_safe_syscall(a,b,c,d)       S_is_safe_syscall(aTHX_ a,b,c,d)
 #define is_uni_alnum(a)                Perl_is_uni_alnum(aTHX_ a)
 #define is_uni_alnum_lc(a)     Perl_is_uni_alnum_lc(aTHX_ a)
 #define is_uni_alnumc(a)       Perl_is_uni_alnumc(aTHX_ a)
 #define my_pclose(a)           Perl_my_pclose(aTHX_ a)
 #define my_popen(a,b)          Perl_my_popen(aTHX_ a,b)
+#define _is_utf8_char_slow     S__is_utf8_char_slow
+#define append_utf8_from_native_byte   S_append_utf8_from_native_byte
+#define av_top_index(a)                S_av_top_index(aTHX_ a)
+#define is_safe_syscall(a,b,c,d)       S_is_safe_syscall(aTHX_ a,b,c,d)
 #if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
 #define my_bcopy               Perl_my_bcopy
 #define reg_temp_copy(a,b)     Perl_reg_temp_copy(aTHX_ a,b)
 #define report_uninit(a)       Perl_report_uninit(aTHX_ a)
 #define sv_magicext_mglob(a)   Perl_sv_magicext_mglob(aTHX_ a)
-#define sv_only_taint_gmagic   S_sv_only_taint_gmagic
 #define validate_proto(a,b,c)  Perl_validate_proto(aTHX_ a,b,c)
 #define vivify_defelem(a)      Perl_vivify_defelem(aTHX_ a)
 #define yylex()                        Perl_yylex(aTHX)
 #define invlist_trim           S_invlist_trim
 #    endif
 #  endif
+#define sv_only_taint_gmagic   S_sv_only_taint_gmagic
+#  endif
 #  if defined(DEBUGGING)
 #    if defined(PERL_IN_REGCOMP_C)
 #define dump_trie(a,b,c,d)     S_dump_trie(aTHX_ a,b,c,d)
diff --git a/proto.h b/proto.h
index 210d013..b017eb0 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -56,11 +56,6 @@ PERL_CALLCONV bool   Perl__is_utf8_FOO(pTHX_ const U8 classnum, const U8 *p)
-PERL_STATIC_INLINE STRLEN      S__is_utf8_char_slow(const U8 *s, const U8 *e)
-                       __attribute__warn_unused_result__;
-       assert(s); assert(e)
 PERL_CALLCONV bool     Perl__is_utf8_idcont(pTHX_ const U8 *p)
@@ -122,9 +117,6 @@ PERL_CALLCONV SV *  Perl_amagic_deref_call(pTHX_ SV *ref, int method);
 PERL_CALLCONV bool     Perl_amagic_is_enabled(pTHX_ int method);
-PERL_STATIC_INLINE void        S_append_utf8_from_native_byte(const U8 byte, U8** dest);
-       assert(dest)
 PERL_CALLCONV I32      Perl_apply(pTHX_ I32 type, SV** mark, SV** sp);
        assert(mark); assert(sp)
@@ -200,11 +192,6 @@ PERL_CALLCONV SV** Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val);
 /* PERL_CALLCONV SSize_t       Perl_av_tindex(pTHX_ AV *av)
                        __attribute__warn_unused_result__; */
-PERL_STATIC_INLINE SSize_t     S_av_top_index(pTHX_ AV *av)
-                       __attribute__warn_unused_result__;
-       assert(av)
 PERL_CALLCONV void     Perl_av_undef(pTHX_ AV *av);
@@ -1306,11 +1293,6 @@ PERL_CALLCONV bool       Perl_is_invariant_string(const U8 *s, STRLEN len)
 PERL_CALLCONV I32      Perl_is_lvalue_sub(pTHX)
-PERL_STATIC_INLINE bool        S_is_safe_syscall(pTHX_ const char *pv, STRLEN len, const char *what, const char *op_name)
-                       __attribute__warn_unused_result__;
-       assert(pv); assert(what); assert(op_name)
 PERL_CALLCONV bool     Perl_is_uni_alnum(pTHX_ UV c)
@@ -3081,9 +3063,6 @@ PERL_CALLCONV void        Perl_sv_nosharing(pTHX_ SV *sv);
 PERL_CALLCONV NV       Perl_sv_nv(pTHX_ SV* sv);
-PERL_STATIC_INLINE bool        S_sv_only_taint_gmagic(SV *sv);
-       assert(sv)
 PERL_CALLCONV char*    Perl_sv_peek(pTHX_ SV* sv);
 PERL_CALLCONV void     Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp);
@@ -3716,6 +3695,29 @@ STATIC SV *      S_incpush_if_exists(pTHX_ AV *const av, SV *dir, SV *const stem);
        assert(av); assert(dir); assert(stem)
 #  endif
+PERL_STATIC_INLINE STRLEN      S__is_utf8_char_slow(const U8 *s, const U8 *e)
+                       __attribute__warn_unused_result__;
+       assert(s); assert(e)
+PERL_STATIC_INLINE void        S_append_utf8_from_native_byte(const U8 byte, U8** dest);
+       assert(dest)
+PERL_STATIC_INLINE SSize_t     S_av_top_index(pTHX_ AV *av)
+                       __attribute__warn_unused_result__;
+       assert(av)
+PERL_STATIC_INLINE bool        S_is_safe_syscall(pTHX_ const char *pv, STRLEN len, const char *what, const char *op_name)
+                       __attribute__warn_unused_result__;
+       assert(pv); assert(what); assert(op_name)
+PERL_STATIC_INLINE bool        S_sv_only_taint_gmagic(SV *sv);
+       assert(sv)
 #if !defined(PERL_NO_UTF16_FILTER)
 #  if defined(PERL_IN_TOKE_C)
 STATIC U8*     S_add_utf16_textfilter(pTHX_ U8 *const s, bool reversed);