This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: Remove memory leak
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 8813a51..a283712 100644 (file)
--- a/perl.h
+++ b/perl.h
 /* this is used for functions which take a depth trailing
  * argument under debugging */
 #ifdef DEBUGGING
-#define _pDEPTH ,U32 depth
-#define _aDEPTH ,depth
+#  define _pDEPTH ,U32 depth
+#  define _aDEPTH ,depth
 #else
-#define _pDEPTH
-#define _aDEPTH
+#  define _pDEPTH
+#  define _aDEPTH
 #endif
 
 /* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
 #  endif
 #endif
 
-#ifdef PERL_GLOBAL_STRUCT_PRIVATE
-#  ifndef PERL_GLOBAL_STRUCT
-#    define PERL_GLOBAL_STRUCT
-#  endif
-#endif
-
-#ifdef PERL_GLOBAL_STRUCT
-#  ifndef MULTIPLICITY
-#    define MULTIPLICITY
-#  endif
-#endif
-
 #ifdef MULTIPLICITY
 #  ifndef PERL_IMPLICIT_CONTEXT
 #    define PERL_IMPLICIT_CONTEXT
 #   undef _WIN32
 #endif
 
-#if defined(__SYMBIAN32__) || (defined(__VC32__) && defined(WINS))
-#   ifndef SYMBIAN
-#       define SYMBIAN
-#   endif
-#endif
-
-#ifdef __SYMBIAN32__
-#  include "symbian/symbian_proto.h"
-#endif
-
-/* Any stack-challenged places.  The limit varies (and often
- * is configurable), but using more than a kilobyte of stack
- * is usually dubious in these systems. */
-#if defined(__SYMBIAN32__)
-/* Symbian: need to work around the SDK features. *
- * On WINS: MS VC5 generates calls to _chkstk,         *
- * if a "large" stack frame is allocated.              *
- * gcc on MARM does not generate calls like these.     */
-#   define USE_HEAP_INSTEAD_OF_STACK
-#endif
-
 /* Use the reentrant APIs like localtime_r and getpwent_r */
 /* Win32 has naturally threadsafe libraries, no need to use any _r variants.
  * XXX KEEP makedef.pl copy of this code in sync */
 
 /* <--- here ends the logic shared by perl.h and makedef.pl */
 
+/*
+=for apidoc_section $directives
+=for apidoc AmnUu|void|EXTERN_C
+When not compiling using C++, expands to nothing.
+Otherwise is used in a declaration of a function to indicate the function
+should have external C linkage.  This is required for things to work for just
+about all functions with external linkage compiled into perl.
+Often, you can use C<L</START_EXTERN_C>> ... C<L</END_EXTERN_C>> blocks
+surrounding all your code that you need to have this linkage.
+
+Example usage:
+
+ EXTERN_C int flock(int fd, int op);
+
+=for apidoc Amnu||START_EXTERN_C
+When not compiling using C++, expands to nothing.
+Otherwise begins a section of code in which every function will effectively
+have C<L</EXTERN_C>> applied to it, that is to have external C linkage.  The
+section is ended by a C<L</END_EXTERN_C>>.
+
+=for apidoc Amnu||END_EXTERN_C
+When not compiling using C++, expands to nothing.
+Otherwise ends a section of code already begun by a C<L</START_EXTERN_C>>.
+
+=cut
+*/
+
 #undef START_EXTERN_C
 #undef END_EXTERN_C
 #undef EXTERN_C
 #ifdef __cplusplus
-#  define START_EXTERN_C extern "C" {
-#  define END_EXTERN_C }
 #  define EXTERN_C extern "C"
+#  define START_EXTERN_C EXTERN_C {
+#  define END_EXTERN_C }
 #else
 #  define START_EXTERN_C
 #  define END_EXTERN_C
 #  endif
 #endif
 
-#if defined(PERL_GLOBAL_STRUCT) && !defined(PERL_GET_VARS)
-#    ifdef PERL_GLOBAL_STRUCT_PRIVATE
-       EXTERN_C struct perl_vars* Perl_GetVarsPrivate();
-#      define PERL_GET_VARS() Perl_GetVarsPrivate() /* see miniperlmain.c */
-#    else
-#      define PERL_GET_VARS() PL_VarsPtr
-#    endif
-#endif
-
-/* this used to be off by default, now its on, see perlio.h */
-#define PERLIO_FUNCS_CONST
+/*
+=for apidoc_section $concurrency
+=for apidoc AmU|void|dTHXa|PerlInterpreter * a
+On threaded perls, set C<pTHX> to C<a>; on unthreaded perls, do nothing
 
-#define pVAR    struct perl_vars* my_vars PERL_UNUSED_DECL
+=for apidoc AmU|void|dTHXoa|PerlInterpreter * a
+Now a synonym for C<L</dTHXa>>.
 
-#ifdef PERL_GLOBAL_STRUCT
-#  define dVAR         pVAR    = (struct perl_vars*)PERL_GET_VARS()
-#else
-#  define dVAR         dNOOP
-#endif
+=cut
+*/
 
 #ifdef PERL_IMPLICIT_CONTEXT
 #  ifndef MULTIPLICITY
 #  define pTHX  tTHX my_perl PERL_UNUSED_DECL
 #  define aTHX my_perl
 #  define aTHXa(a) aTHX = (tTHX)a
-#  ifdef PERL_GLOBAL_STRUCT
-#    define dTHXa(a)   dVAR; pTHX = (tTHX)a
-#  else
-#    define dTHXa(a)   pTHX = (tTHX)a
-#  endif
-#  ifdef PERL_GLOBAL_STRUCT
-#    define dTHX               dVAR; pTHX = PERL_GET_THX
-#  else
-#    define dTHX               pTHX = PERL_GET_THX
-#  endif
+#  define dTHXa(a)     pTHX = (tTHX)a
+#  define dTHX         pTHX = PERL_GET_THX
 #  define pTHX_                pTHX,
 #  define aTHX_                aTHX,
 #  define pTHX_1       2
  * implementation of multiplicity using C++ objects. They have been left
  * here solely for the sake of XS code which has incorrectly
  * cargo-culted them.
+ *
+ * The only one Devel::PPPort handles is this; list it as deprecated
+
+=for apidoc_section $concurrency
+=for apidoc AmD|void|CPERLscope|void x
+Now a no-op.
+
+=cut
  */
-#define CPERLscope(x) x
-#define CPERLarg void
-#define CPERLarg_
-#define _CPERLarg
-#define PERL_OBJECT_THIS
-#define _PERL_OBJECT_THIS
-#define PERL_OBJECT_THIS_
-#define CALL_FPTR(fptr) (*fptr)
-#define MEMBER_TO_FPTR(name) name
+#  define CPERLscope(x) x
+#  define CPERLarg void
+#  define CPERLarg_
+#  define _CPERLarg
+#  define PERL_OBJECT_THIS
+#  define _PERL_OBJECT_THIS
+#  define PERL_OBJECT_THIS_
+#  define CALL_FPTR(fptr) (*fptr)
+#  define MEMBER_TO_FPTR(name) name
 #endif /* !PERL_CORE */
 
 #define CALLRUNOPS  PL_runops
     RX_ENGINE(rx)->qr_package(aTHX_ (rx))
 
 #if defined(USE_ITHREADS)
-#define CALLREGDUPE(prog,param) \
+#  define CALLREGDUPE(prog,param) \
     Perl_re_dup(aTHX_ (prog),(param))
 
-#define CALLREGDUPE_PVT(prog,param) \
+#  define CALLREGDUPE_PVT(prog,param) \
     (prog ? RX_ENGINE(prog)->dupe(aTHX_ (prog),(param)) \
           : (REGEXP *)NULL)
 #endif
 
+/* some compilers impersonate gcc */
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
+#  define PERL_IS_GCC 1
+#endif
+
 /* In case Configure was not used (we are using a "canned config"
  * such as Win32, or a cross-compilation setup, for example) try going
  * by the gcc major and minor versions.  One useful URL is
  */
 
 #ifndef PERL_MICRO
-#if defined __GNUC__ && !defined(__INTEL_COMPILER)
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3 /* 3.1 -> */
-#    define HASATTRIBUTE_DEPRECATED
-#  endif
-#  if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
-#    define HASATTRIBUTE_FORMAT
-#    if defined __MINGW32__
-#      define PRINTF_FORMAT_NULL_OK
+#  if defined __GNUC__ && !defined(__INTEL_COMPILER)
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3 /* 3.1 -> */
+#      define HASATTRIBUTE_DEPRECATED
+#    endif
+#    if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
+#      define HASATTRIBUTE_FORMAT
+#      if defined __MINGW32__
+#        define PRINTF_FORMAT_NULL_OK
+#      endif
+#    endif
+#    if __GNUC__ >= 3 /* 3.0 -> */
+#      define HASATTRIBUTE_MALLOC
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 /* 3.3 -> */
+#      define HASATTRIBUTE_NONNULL
+#    endif
+#    if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 /* 2.5 -> */
+#      define HASATTRIBUTE_NORETURN
+#    endif
+#    if __GNUC__ >= 3 /* gcc 3.0 -> */
+#      define HASATTRIBUTE_PURE
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
+#      define HASATTRIBUTE_UNUSED
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined(__cplusplus)
+#      define HASATTRIBUTE_UNUSED /* gcc-3.3, but not g++-3.3. */
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
+#      define HASATTRIBUTE_WARN_UNUSED_RESULT
+#    endif
+     /* always_inline is buggy in gcc <= 4.6 and causes compilation errors */
+#    if __GNUC__ == 4 && __GNUC_MINOR__ >= 7 || __GNUC__ > 4 /* 4.7 -> */
+#      define HASATTRIBUTE_ALWAYS_INLINE
 #    endif
 #  endif
-#  if __GNUC__ >= 3 /* 3.0 -> */
-#    define HASATTRIBUTE_MALLOC
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 /* 3.3 -> */
-#    define HASATTRIBUTE_NONNULL
-#  endif
-#  if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 /* 2.5 -> */
-#    define HASATTRIBUTE_NORETURN
-#  endif
-#  if __GNUC__ >= 3 /* gcc 3.0 -> */
-#    define HASATTRIBUTE_PURE
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
-#    define HASATTRIBUTE_UNUSED
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined(__cplusplus)
-#    define HASATTRIBUTE_UNUSED /* gcc-3.3, but not g++-3.3. */
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
-#    define HASATTRIBUTE_WARN_UNUSED_RESULT
-#  endif
-#endif
 #endif /* #ifndef PERL_MICRO */
 
 #ifdef HASATTRIBUTE_DEPRECATED
 #ifdef HASATTRIBUTE_WARN_UNUSED_RESULT
 #  define __attribute__warn_unused_result__ __attribute__((warn_unused_result))
 #endif
+#ifdef HASATTRIBUTE_ALWAYS_INLINE
+/* always_inline is buggy in gcc <= 4.6 and causes compilation errors */
+#  if !defined(PERL_IS_GCC) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7 || __GNUC__ > 4)
+#    define __attribute__always_inline__      __attribute__((always_inline))
+#  endif
+#endif
 
 /* If we haven't defined the attributes yet, define them to blank. */
 #ifndef __attribute__deprecated__
 #ifndef __attribute__warn_unused_result__
 #  define __attribute__warn_unused_result__
 #endif
+#ifndef __attribute__always_inline__
+#  define __attribute__always_inline__
+#endif
 
 /* Some OS warn on NULL format to printf */
 #ifdef PRINTF_FORMAT_NULL_OK
  * marking unused variables (they need e.g. a #pragma) and therefore
  * cpp macros like PERL_UNUSED_DECL cannot work for this purpose, even
  * if it were PERL_UNUSED_DECL(x), which it cannot be (see above).
- *
+
+=for apidoc_section $directives
+=for apidoc AmnU||PERL_UNUSED_DECL
+Tells the compiler that the parameter in the function prototype just before it
+is not necessarily expected to be used in the function.  Not that many
+compilers understand this, so this should only be used in cases where
+C<L</PERL_UNUSED_ARG>> can't conveniently be used.
+
+Example usage:
+
+=over
+
+ Signal_t
+ Perl_perly_sighandler(int sig, Siginfo_t *sip PERL_UNUSED_DECL,
+                       void *uap PERL_UNUSED_DECL, bool safe)
+
+=back
+
+=cut
  */
 
 #ifndef PERL_UNUSED_DECL
  * for silencing unused variables that are actually used most of the time,
  * but we cannot quite get rid of, such as "ax" in PPCODE+noargs xsubs,
  * or variables/arguments that are used only in certain configurations.
+
+=for apidoc Ams||PERL_UNUSED_ARG|void x
+This is used to suppress compiler warnings that a parameter to a function is
+not used.  This situation can arise, for example, when a parameter is needed
+under some configuration conditions, but not others, so that C preprocessor
+conditional compilation causes it be used just some times.
+
+=for apidoc Amns||PERL_UNUSED_CONTEXT
+This is used to suppress compiler warnings that the thread context parameter to
+a function is not used.  This situation can arise, for example, when a
+C preprocessor conditional compilation causes it be used just some times.
+
+=for apidoc Ams||PERL_UNUSED_VAR|void x
+This is used to suppress compiler warnings that the variable I<x> is not used.
+This situation can arise, for example, when a C preprocessor conditional
+compilation causes it be used just some times.
+
+=cut
  */
 #ifndef PERL_UNUSED_ARG
 #  define PERL_UNUSED_ARG(x) ((void)sizeof(x))
 #  define PERL_UNUSED_VAR(x) ((void)sizeof(x))
 #endif
 
-#if defined(USE_ITHREADS) || defined(PERL_GLOBAL_STRUCT)
+#if defined(USE_ITHREADS)
 #  define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl)
 #else
 #  define PERL_UNUSED_CONTEXT
 #  endif
 #endif
 
-/* Use PERL_UNUSED_RESULT() to suppress the warnings about unused results
- * of function calls, e.g. PERL_UNUSED_RESULT(foo(a, b)).
- *
- * The main reason for this is that the combination of gcc -Wunused-result
- * (part of -Wall) and the __attribute__((warn_unused_result)) cannot
- * be silenced with casting to void.  This causes trouble when the system
- * header files use the attribute.
- *
- * Use PERL_UNUSED_RESULT sparingly, though, since usually the warning
- * is there for a good reason: you might lose success/failure information,
- * or leak resources, or changes in resources.
- *
- * But sometimes you just want to ignore the return value, e.g. on
- * codepaths soon ending up in abort, or in "best effort" attempts,
- * or in situations where there is no good way to handle failures.
- *
- * Sometimes PERL_UNUSED_RESULT might not be the most natural way:
- * another possibility is that you can capture the return value
- * and use PERL_UNUSED_VAR on that.
- *
- * The __typeof__() is used instead of typeof() since typeof() is not
- * available under strict C89, and because of compilers masquerading
- * as gcc (clang and icc), we want exactly the gcc extension
- * __typeof__ and nothing else.
- */
+/*
+
+=for apidoc Am||PERL_UNUSED_RESULT|void x
+
+This macro indicates to discard the return value of the function call inside
+it, I<e.g.>,
+
+ PERL_UNUSED_RESULT(foo(a, b))
+
+The main reason for this is that the combination of C<gcc -Wunused-result>
+(part of C<-Wall>) and the C<__attribute__((warn_unused_result))> cannot
+be silenced with casting to C<void>.  This causes trouble when the system
+header files use the attribute.
+
+Use C<PERL_UNUSED_RESULT> sparingly, though, since usually the warning
+is there for a good reason: you might lose success/failure information,
+or leak resources, or changes in resources.
+
+But sometimes you just want to ignore the return value, I<e.g.>, on
+codepaths soon ending up in abort, or in "best effort" attempts,
+or in situations where there is no good way to handle failures.
+
+Sometimes C<PERL_UNUSED_RESULT> might not be the most natural way:
+another possibility is that you can capture the return value
+and use C<L</PERL_UNUSED_VAR>> on that.
+
+=cut
+
+The __typeof__() is used instead of typeof() since typeof() is not
+available under strict C89, and because of compilers masquerading
+as gcc (clang and icc), we want exactly the gcc extension
+__typeof__ and nothing else.
+
+*/
 #ifndef PERL_UNUSED_RESULT
 #  if defined(__GNUC__) && defined(HASATTRIBUTE_WARN_UNUSED_RESULT)
 #    define PERL_UNUSED_RESULT(v) STMT_START { __typeof__(v) z = (v); (void)sizeof(z); } STMT_END
 #  endif
 #endif
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && _MSC_VER < 1400
 /* XXX older MSVC versions have a smallish macro buffer */
-#define PERL_SMALL_MACRO_BUFFER
+#  define PERL_SMALL_MACRO_BUFFER
 #endif
 
 /* on gcc (and clang), specify that a warning should be temporarily
 #define MSVC_DIAG_IGNORE_STMT(x) MSVC_DIAG_IGNORE(x) NOOP
 #define MSVC_DIAG_RESTORE_STMT MSVC_DIAG_RESTORE NOOP
 
+/*
+=for apidoc Amns||NOOP
+Do nothing; typically used as a placeholder to replace something that used to
+do something.
+
+=for apidoc Amns||dNOOP
+Declare nothing; typically used as a placeholder to replace something that used
+to declare something.  Works on compilers that require declarations before any
+code.
+
+=cut
+*/
 #define NOOP /*EMPTY*/(void)0
 #define dNOOP struct Perl___notused_struct
 
 #  define pTHX_12      12
 #endif
 
-#ifndef dVAR
+/*
+=for apidoc_section $concurrency
+=for apidoc AmnU||dVAR
+This is now a synonym for dNOOP: declare nothing
+
+=for apidoc_section $XS
+=for apidoc Amns||dMY_CXT_SV
+Now a placeholder that declares nothing
+
+=cut
+*/
+
+#ifndef PERL_CORE
+    /* Backwards compatibility macro for XS code. It used to be part of the
+     * PERL_GLOBAL_STRUCT(_PRIVATE) feature, which no longer exists */
 #  define dVAR         dNOOP
-#endif
 
-/* these are only defined for compatibility; should not be used internally */
-#if !defined(pTHXo) && !defined(PERL_CORE)
-#  define pTHXo                pTHX
-#  define pTHXo_       pTHX_
-#  define aTHXo                aTHX
-#  define aTHXo_       aTHX_
-#  define dTHXo                dTHX
-#  define dTHXoa(x)    dTHXa(x)
+    /* these are only defined for compatibility; should not be used internally.
+     * */
+#  define dMY_CXT_SV    dNOOP
+#  ifndef pTHXo
+#    define pTHXo              pTHX
+#    define pTHXo_     pTHX_
+#    define aTHXo              aTHX
+#    define aTHXo_     aTHX_
+#    define dTHXo              dTHX
+#    define dTHXoa(x)  dTHXa(x)
+#  endif
 #endif
 
 #ifndef pTHXx
  * PerlIO_foo() expands to PL_StdIO->pFOO(PL_StdIO, ...).
  * dTHXs is therefore needed for all functions using PerlIO_foo(). */
 #ifdef PERL_IMPLICIT_SYS
-#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-#    define dTHXs              dVAR; dTHX
-#  else
 #    define dTHXs              dTHX
-#  endif
 #else
-#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-#    define dTHXs              dVAR
-#  else
 #    define dTHXs              dNOOP
-#  endif
 #endif
 
 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus)
 #endif
 
 /*
-=head1 Miscellaneous Functions
-
+=for apidoc_section $directives
 =for apidoc AmnUu|void|STMT_START
+=for apidoc_item ||STMT_END
+
+This allows a series of statements in a macro to be used as a single statement,
+as in
+
+ if (x) STMT_START { ... } STMT_END else ...
+
+Note that you can't return a value out of them, which limits their utility.
+But see C<L</PERL_USE_GCC_BRACE_GROUPS>>.
+
+=for apidoc AmnuU|bool|PERL_USE_GCC_BRACE_GROUPS
+
+This C pre-processor value, if defined, indicates that it is permissible to use
+the GCC brace groups extension.  This extension, of the form
 
- STMT_START { statements; } STMT_END;
+ ({ statement ... })
 
-can be used as a single statement, as in
+turns the block consisting of I<statements ...> into an expression with a
+value, unlike plain C language blocks.  This can present optimization
+possibilities, B<BUT> you generally need to specify an alternative in case this
+ability doesn't exist or has otherwise been forbidden.
 
- if (x) STMT_START { ... } STMT_END; else ...
+Example usage:
 
-These are often used in macro definitions.  Note that you can't return a value
-out of them.
+=over
 
-=for apidoc AmnUhu|void|STMT_END
+ #ifdef PERL_USE_GCC_BRACE_GROUPS
+   ...
+ #else
+   ...
+ #endif
+
+=back
 
 =cut
 
@@ -803,16 +892,6 @@ out of them.
 
 #include <sys/types.h>
 
-/* EVC 4 SDK headers includes a bad definition of MB_CUR_MAX in stdlib.h
-  which is included from stdarg.h. Bad definition not present in SD 2008
-  SDK headers. wince.h is not yet included, so we cant fix this from there
-  since by then MB_CUR_MAX will be defined from stdlib.h.
-  cewchar.h includes a correct definition of MB_CUR_MAX and it is copied here
-  since cewchar.h can't be included this early */
-#if defined(UNDER_CE) && (_MSC_VER < 1300)
-#  define MB_CUR_MAX 1uL
-#endif
-
 #  ifdef I_WCHAR
 #    include <wchar.h>
 #  endif
@@ -904,6 +983,12 @@ out of them.
 #   if !defined(NO_LOCALE_TELEPHONE) && defined(LC_TELEPHONE)
 #      define USE_LOCALE_TELEPHONE
 #   endif
+#   if !defined(NO_LOCALE_SYNTAX) && defined(LC_SYNTAX)
+#      define USE_LOCALE_SYNTAX
+#   endif
+#   if !defined(NO_LOCALE_TOD) && defined(LC_TOD)
+#      define USE_LOCALE_TOD
+#   endif
 
 /* XXX The next few defines are unfortunately duplicated in makedef.pl, and
  * changes here MUST also be made there */
@@ -985,10 +1070,6 @@ extern char **myenviron;
 #   include <sys/wait.h>
 #endif
 
-#ifdef __SYMBIAN32__
-#   undef _SC_ARG_MAX /* Symbian has _SC_ARG_MAX but no sysconf() */
-#endif
-
 #if defined(HAS_SYSCALL) && !defined(HAS_SYSCALL_PROTO)
 EXTERN_C int syscall(int, ...);
 #endif
@@ -997,9 +1078,33 @@ EXTERN_C int syscall(int, ...);
 EXTERN_C int usleep(unsigned int);
 #endif
 
-/* macros for correct constant construction.  These are in C99 <stdint.h>
+/* Macros for correct constant construction.  These are in C99 <stdint.h>
  * (so they will not be available in strict C89 mode), but they are nice, so
- * let's define them if necessary. */
+ * let's define them if necessary.
+=for apidoc_section $integer
+=for apidoc    Am|I16|INT16_C|number
+=for apidoc_item |I32|INT32_C|number
+=for apidoc_item |I64|INT64_C|number
+
+Returns a token the C compiler recognizes for the constant C<number> of the
+corresponding integer type on the machine.
+
+If the machine does not have a 64-bit type, C<INT64_C> is undefined.
+Use C<L</INTMAX_C>> to get the largest type available on the platform.
+
+=for apidoc    Am|U16|UINT16_C|number
+=for apidoc_item |U32|UINT32_C|number
+=for apidoc_item |U64|UINT64_C|number
+
+Returns a token the C compiler recognizes for the constant C<number> of the
+corresponding unsigned integer type on the machine.
+
+If the machine does not have a 64-bit type, C<UINT64_C> is undefined.
+Use C<L</UINTMAX_C>> to get the largest type available on the platform.
+
+
+=cut
+*/
 #ifndef UINT16_C
 #  if INTSIZE >= 2
 #    define UINT16_C(x) ((U16_TYPE)x##U)
@@ -1065,6 +1170,33 @@ EXTERN_C int usleep(unsigned int);
 #    define UINT64_C(c) PeRl_UINT64_C(c)
 #  endif
 
+/*
+=for apidoc_section $integer
+=for apidoc Am||INTMAX_C|number
+Returns a token the C compiler recognizes for the constant C<number> of the
+widest integer type on the machine.  For example, if the machine has C<long
+long>s, C<INTMAX_C(-1)> would yield
+
+ -1LL
+
+See also, for example, C<L</INT32_C>>.
+
+Use L</IV> to declare variables of the maximum usable size on this platform.
+
+=for apidoc Am||UINTMAX_C|number
+Returns a token the C compiler recognizes for the constant C<number> of the
+widest unsigned integer type on the machine.  For example, if the machine has
+C<long>s, C<UINTMAX_C(1)> would yield
+
+ 1UL
+
+See also, for example, C<L</UINT32_C>>.
+
+Use L</UV> to declare variables of the maximum usable size on this platform.
+
+=cut
+*/
+
 #  ifndef I_STDINT
     typedef I64TYPE PERL_INTMAX_T;
     typedef U64TYPE PERL_UINTMAX_T;
@@ -1162,7 +1294,7 @@ EXTERN_C int usleep(unsigned int);
 #define PERL_USES_PL_PIDSTATUS
 #endif
 
-#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(__SYMBIAN32__)
+#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP)
 #define PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
 #endif
 
@@ -1207,9 +1339,7 @@ EXTERN_C int usleep(unsigned int);
 #  define Ptrdiff_t SSize_t
 #endif
 
-#ifndef __SYMBIAN32__
 #  include <string.h>
-#endif
 
 /* This comes after <stdlib.h> so we don't try to change the standard
  * library prototypes; we'll use our own in proto.h instead. */
@@ -1262,6 +1392,12 @@ EXTERN_C int usleep(unsigned int);
 #define MALLOC_TOO_LATE_FOR(ch)        TOO_LATE_FOR_(ch, " with $ENV{PERL_MALLOC_OPT}")
 #define MALLOC_CHECK_TAINT2(argc,argv) MALLOC_CHECK_TAINT(argc,argv,NULL)
 
+/*
+=for apidoc Am|void|memzero|void * d|Size_t l
+Set the C<l> bytes starting at C<*d> to all zeroes.
+
+=cut
+*/
 #ifndef memzero
 #   define memzero(d,l) memset(d,0,l)
 #endif
@@ -1378,7 +1514,7 @@ EXTERN_C char *crypt(const char *, const char *);
 #endif
 
 /*
-=head1 Errno
+=for apidoc_section $errno
 
 =for apidoc m|void|SETERRNO|int errcode|int vmserrcode
 
@@ -1481,7 +1617,7 @@ was saved by C<dSAVE_ERRNO> or C<RESTORE_ERRNO>.
 #endif
 
 /*
-=head1 Warning and Dieing
+=for apidoc_section $warning
 
 =for apidoc Amn|SV *|ERRSV
 
@@ -1558,6 +1694,20 @@ any magic.
 # define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv))
 #endif
 
+/*
+=for apidoc_section $SV
+=for apidoc Amn|SV *|DEFSV
+Returns the SV associated with C<$_>
+
+=for apidoc Am|void|DEFSV_set|SV * sv
+Associate C<sv> with C<$_>
+
+=for apidoc Amn|void|SAVE_DEFSV
+Localize C<$_>.  See L<perlguts/Localizing changes>.
+
+=cut
+*/
+
 #ifndef errno
        extern int errno;     /* ANSI allows errno to be an lvalue expr.
                               * For example in multithreaded environments
@@ -1767,8 +1917,7 @@ any magic.
  * longer need that. XS modules can (and do) use this name, so it must remain
  * a part of the API that's visible to modules.
 
-=head1 Miscellaneous Functions
-
+=for apidoc_section $string
 =for apidoc ATmD|int|my_sprintf|NN char *buffer|NN const char *pat|...
 
 Do NOT use this due to the possibility of overflowing C<buffer>.  Instead use
@@ -1887,13 +2036,13 @@ typedef UVTYPE UV;
 
 #if defined(USE_64_BIT_INT) && defined(HAS_QUAD)
 #  if QUADKIND == QUAD_IS_INT64_T && defined(INT64_MAX)
-#    define IV_MAX INT64_MAX
-#    define IV_MIN INT64_MIN
-#    define UV_MAX UINT64_MAX
+#    define IV_MAX ((IV)INT64_MAX)
+#    define IV_MIN ((IV)INT64_MIN)
+#    define UV_MAX ((UV)UINT64_MAX)
 #    ifndef UINT64_MIN
 #      define UINT64_MIN 0
 #    endif
-#    define UV_MIN UINT64_MIN
+#    define UV_MIN ((UV)UINT64_MIN)
 #  else
 #    define IV_MAX PERL_QUAD_MAX
 #    define IV_MIN PERL_QUAD_MIN
@@ -1904,17 +2053,17 @@ typedef UVTYPE UV;
 #  define UV_IS_QUAD
 #else
 #  if defined(INT32_MAX) && IVSIZE == 4
-#    define IV_MAX INT32_MAX
-#    define IV_MIN INT32_MIN
+#    define IV_MAX ((IV)INT32_MAX)
+#    define IV_MIN ((IV)INT32_MIN)
 #    ifndef UINT32_MAX_BROKEN /* e.g. HP-UX with gcc messes this up */
-#        define UV_MAX UINT32_MAX
+#        define UV_MAX ((UV)UINT32_MAX)
 #    else
-#        define UV_MAX 4294967295U
+#        define UV_MAX ((UV)4294967295U)
 #    endif
 #    ifndef UINT32_MIN
 #      define UINT32_MIN 0
 #    endif
-#    define UV_MIN UINT32_MIN
+#    define UV_MIN ((UV)UINT32_MIN)
 #  else
 #    define IV_MAX PERL_LONG_MAX
 #    define IV_MIN PERL_LONG_MIN
@@ -1958,6 +2107,8 @@ typedef UVTYPE UV;
  *  For int conversions we do not need two casts if pointers are
  *  the same size as IV and UV.   Otherwise we need an explicit
  *  cast (PTRV) to avoid compiler warnings.
+ *
+ *  These are mentioned in perlguts
  */
 #if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
 #  define PTRV                 UV
@@ -1977,6 +2128,14 @@ typedef UVTYPE UV;
 #  define PTR2ul(p)    INT2PTR(unsigned long,p)        
 #endif
 
+/*
+=for apidoc_section Casting
+=for apidoc Cyh|type|NUM2PTR|type|int value
+You probably want to be using L<C</INT2PTR>> instead.
+
+=cut
+*/
+
 #define NUM2PTR(any,d) (any)(PTRV)(d)
 #define PTR2IV(p)      INT2PTR(IV,p)
 #define PTR2UV(p)      INT2PTR(UV,p)
@@ -2019,7 +2178,22 @@ typedef UVTYPE UV;
 #  endif
 #endif
 
-typedef NVTYPE NV;
+/* On MS Windows,with 64-bit mingw-w64 compilers, we
+   need to attend to a __float128 alignment issue if
+   USE_QUADMATH is defined. Otherwise we simply:
+   typedef NVTYPE NV
+   32-bit mingw.org compilers might also require
+   aligned(32) - at least that's what I found with my
+   Math::Foat128 module. But this is as yet untested
+   here, so no allowance is being made for mingw.org
+   compilers at this stage. -- sisyphus January 2021
+*/
+#if defined(USE_QUADMATH) && defined(__MINGW64__)
+   /* 64-bit build, mingw-w64 compiler only */
+   typedef NVTYPE NV __attribute__ ((aligned(8)));
+#else
+   typedef NVTYPE NV;
+#endif
 
 #ifdef I_IEEEFP
 #   include <ieeefp.h>
@@ -2309,7 +2483,7 @@ extern long double Perl_my_frexpl(long double x, int *e);
 #     define FP_QNAN FP_QNAN
 #    endif
 #    include <math.h>
-#    ifdef I_IEEFP
+#    ifdef I_IEEEFP
 #        include <ieeefp.h>
 #    endif
 #    ifdef I_FP
@@ -2424,8 +2598,8 @@ extern long double Perl_my_frexpl(long double x, int *e);
 #    define Perl_fp_class_snan(x) (_fpclass(x) & _FPCLASS_SNAN)
 #    define Perl_fp_class_qnan(x) (_fpclass(x) & _FPCLASS_QNAN)
 #    define Perl_fp_class_nan(x) (_fpclass(x) & (_FPCLASS_SNAN|_FPCLASS_QNAN))
-#    define Perl_fp_class_ninf(x) (_fpclass(x) & _FPCLASS_NINF))
-#    define Perl_fp_class_pinf(x) (_fpclass(x) & _FPCLASS_PINF))
+#    define Perl_fp_class_ninf(x) (_fpclass(x) & _FPCLASS_NINF)
+#    define Perl_fp_class_pinf(x) (_fpclass(x) & _FPCLASS_PINF)
 #    define Perl_fp_class_inf(x) (_fpclass(x) & (_FPCLASS_NINF|_FPCLASS_PINF))
 #    define Perl_fp_class_nnorm(x) (_fpclass(x) & _FPCLASS_NN)
 #    define Perl_fp_class_pnorm(x) (_fpclass(x) & _FPCLASS_PN)
@@ -2518,7 +2692,7 @@ extern long double Perl_my_frexpl(long double x, int *e);
 #        define Perl_isfinitel(x) isfinitel(x)
 #    elif defined(HAS_FINITEL)
 #        define Perl_isfinitel(x) finitel(x)
-#    elif defined(HAS_INFL) && defined(HAS_NANL)
+#    elif defined(HAS_ISINFL) && defined(HAS_ISNANL)
 #        define Perl_isfinitel(x) !(isinfl(x)||isnanl(x))
 #    else
 #        define Perl_isfinitel(x) ((x) * 0 == 0)  /* See Perl_isfinite. */
@@ -2553,6 +2727,41 @@ extern long double Perl_my_frexpl(long double x, int *e);
 #define my_atof2(a,b) my_atof3(a,b,0)
 
 /*
+=for apidoc_section $numeric
+=for apidoc   AmT|NV|Perl_acos|NV x
+=for apidoc_item |NV|Perl_asin|NV x
+=for apidoc_item |NV|Perl_atan|NV x
+=for apidoc_item |NV|Perl_atan2|NV x|NV y
+=for apidoc_item |NV|Perl_ceil|NV x
+=for apidoc_item |NV|Perl_cos|NV x
+=for apidoc_item |NV|Perl_cosh|NV x
+=for apidoc_item |NV|Perl_exp|NV x
+=for apidoc_item |NV|Perl_floor|NV x
+=for apidoc_item |NV|Perl_fmod|NV x|NV y
+=for apidoc_item |NV|Perl_frexp|NV x|int *exp
+=for apidoc_item |IV|Perl_isfinite|NV x
+=for apidoc_item |IV|Perl_isinf|NV x
+=for apidoc_item |IV|Perl_isnan|NV x
+=for apidoc_item |NV|Perl_ldexp|NV x|int exp
+=for apidoc_item |NV|Perl_log|NV x
+=for apidoc_item |NV|Perl_log10|NV x
+=for apidoc_item |NV|Perl_modf|NV x|NV *iptr
+=for apidoc_item |NV|Perl_pow|NV x|NV y
+=for apidoc_item |NV|Perl_sin|NV x
+=for apidoc_item |NV|Perl_sinh|NV x
+=for apidoc_item |NV|Perl_sqrt|NV x
+=for apidoc_item |NV|Perl_tan|NV x
+=for apidoc_item |NV|Perl_tanh|NV x
+
+These perform the corresponding mathematical operation on the operand(s), using
+the libc function designed for the task that has just enough precision for an
+NV on this platform.  If no such function with sufficient precision exists,
+the highest precision one available is used.
+
+=cut
+*/
+
+/*
  * CHAR_MIN and CHAR_MAX are not included here, as the (char) type may be
  * ambiguous. It may be equivalent to (signed char) or (unsigned char)
  * depending on local options. Until Configure detects this (or at least
@@ -2590,43 +2799,28 @@ extern long double Perl_my_frexpl(long double x, int *e);
 #endif
 
 /*
-=head1 Numeric functions
-
-=for apidoc AmnUh||PERL_INT_MIN
-=for apidoc AmnUh||PERL_LONG_MAX
-=for apidoc AmnUh||PERL_LONG_MIN
-=for apidoc AmnUh||PERL_QUAD_MAX
-=for apidoc AmnUh||PERL_SHORT_MAX
-=for apidoc AmnUh||PERL_SHORT_MIN
-=for apidoc AmnUh||PERL_UCHAR_MAX
-=for apidoc AmnUh||PERL_UCHAR_MIN
-=for apidoc AmnUh||PERL_UINT_MAX
-=for apidoc AmnUh||PERL_ULONG_MAX
-=for apidoc AmnUh||PERL_ULONG_MIN
-=for apidoc AmnUh||PERL_UQUAD_MAX
-=for apidoc AmnUh||PERL_UQUAD_MIN
-=for apidoc AmnUh||PERL_USHORT_MAX
-=for apidoc AmnUh||PERL_USHORT_MIN
-=for apidoc AmnUh||PERL_QUAD_MIN
+=for apidoc_section $integer
+
 =for apidoc AmnU||PERL_INT_MAX
-This and
-C<PERL_INT_MIN>,
-C<PERL_LONG_MAX>,
-C<PERL_LONG_MIN>,
-C<PERL_QUAD_MAX>,
-C<PERL_SHORT_MAX>,
-C<PERL_SHORT_MIN>,
-C<PERL_UCHAR_MAX>,
-C<PERL_UCHAR_MIN>,
-C<PERL_UINT_MAX>,
-C<PERL_ULONG_MAX>,
-C<PERL_ULONG_MIN>,
-C<PERL_UQUAD_MAX>,
-C<PERL_UQUAD_MIN>,
-C<PERL_USHORT_MAX>,
-C<PERL_USHORT_MIN>,
-C<PERL_QUAD_MIN>
-give the largest and smallest number representable in the current
+=for apidoc_item ||PERL_INT_MIN
+=for apidoc_item ||PERL_LONG_MAX
+=for apidoc_item ||PERL_LONG_MIN
+=for apidoc_item ||PERL_SHORT_MAX
+=for apidoc_item ||PERL_SHORT_MIN
+=for apidoc_item ||PERL_UCHAR_MAX
+=for apidoc_item ||PERL_UCHAR_MIN
+=for apidoc_item ||PERL_UINT_MAX
+=for apidoc_item ||PERL_UINT_MIN
+=for apidoc_item ||PERL_ULONG_MAX
+=for apidoc_item ||PERL_ULONG_MIN
+=for apidoc_item ||PERL_USHORT_MAX
+=for apidoc_item ||PERL_USHORT_MIN
+=for apidoc_item ||PERL_QUAD_MAX
+=for apidoc_item ||PERL_QUAD_MIN
+=for apidoc_item ||PERL_UQUAD_MAX
+=for apidoc_item ||PERL_UQUAD_MIN
+
+These give the largest and smallest number representable in the current
 platform in variables of the corresponding types.
 
 For signed types, the smallest representable number is the most negative
@@ -2683,6 +2877,7 @@ typedef struct gv GV;
 typedef struct io IO;
 typedef struct context PERL_CONTEXT;
 typedef struct block BLOCK;
+typedef struct invlist INVLIST;
 
 typedef struct magic MAGIC;
 typedef struct xpv XPV;
@@ -2855,8 +3050,6 @@ typedef struct padname PADNAME;
 #   else
 #     include "vos/vosish.h"
 #   endif
-#elif defined(__SYMBIAN32__)
-#   include "symbian/symbianish.h"
 #elif defined(__HAIKU__)
 #   include "haiku/haikuish.h"
 #else
@@ -2898,7 +3091,6 @@ typedef struct padname PADNAME;
 #  define USE_ENVIRON_ARRAY
 #endif
 
-
 #if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
     /* having sigaction(2) means that the OS supports both 1-arg and 3-arg
      * signal handlers. But the perl core itself only fully supports 1-arg
@@ -2920,6 +3112,9 @@ typedef struct padname PADNAME;
 #if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
     typedef siginfo_t Siginfo_t;
 #else
+#ifdef si_signo /* minix */
+#undef si_signo
+#endif
     typedef struct {
         int si_signo;
     } Siginfo_t;
@@ -2994,7 +3189,7 @@ typedef struct padname PADNAME;
 #endif
 
 /*
-=head1 Miscellaneous Functions
+=for apidoc_section $embedding
 
 =for apidoc Am|void|PERL_SYS_INIT|int *argc|char*** argv
 Provides system-specific tune up of the C runtime environment necessary to
@@ -3043,12 +3238,6 @@ freeing any remaining Perl interpreters.
 #  endif
 #endif
 
-/* USE_5005THREADS needs to be after unixish.h as <pthread.h> includes
- * <sys/signal.h> which defines NSIG - which will stop inclusion of <signal.h>
- * this results in many functions being undeclared which bothers C++
- * May make sense to have threads after "*ish.h" anyway
- */
-
 /* clang Thread Safety Analysis/Annotations/Attributes
  * http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
  *
@@ -3059,8 +3248,6 @@ freeing any remaining Perl interpreters.
  */
 #if defined(USE_ITHREADS) && defined(I_PTHREAD) && \
     defined(__clang__) && \
-    !defined(PERL_GLOBAL_STRUCT) && \
-    !defined(PERL_GLOBAL_STRUCT_PRIVATE) && \
     !defined(SWIG) && \
   ((!defined(__apple_build_version__) &&               \
     ((__clang_major__ == 3 && __clang_minor__ >= 6) || \
@@ -3168,6 +3355,15 @@ typedef pthread_mutex_t PERL_TSA_CAPABILITY("mutex") perl_mutex;
 typedef pthread_cond_t perl_cond;
 typedef pthread_key_t  perl_key;
 #  endif
+
+/* Many readers; single writer */
+typedef struct {
+    perl_mutex lock;
+    perl_cond  wakeup;
+    SSize_t    readers_count;
+} perl_RnW1_mutex_t;
+
+
 #endif /* USE_ITHREADS */
 
 #ifdef PERL_TSA_ACTIVE
@@ -3559,11 +3755,8 @@ EXTERN_C int perl_tsa_mutex_unlock(perl_mutex* mutex)
 
 #define HEKfARG(p) ((void*)(p))
 
-/*
-=for apidoc Amnh||UTF8f
-=for apidoc Amh||UTF8fARG|bool is_utf8|Size_t byte_len|char *str
-
-=cut
+/* Documented in perlguts
+ *
  * %4p is a custom format
  */
 #ifndef UTF8f
@@ -3575,7 +3768,13 @@ EXTERN_C int perl_tsa_mutex_unlock(perl_mutex* mutex)
 #define PNfARG(pn) (int)1, (UV)PadnameLEN(pn), (void *)PadnamePV(pn)
 
 #ifdef PERL_CORE
-/* not used; but needed for backward compatibility with XS code? - RMB */
+/* not used; but needed for backward compatibility with XS code? - RMB
+=for apidoc AmnD|const char *|UVf
+
+Obsolete form of C<UVuf>, which you should convert to instead use
+
+=cut
+*/
 #  undef UVf
 #elif !defined(UVf)
 #  define UVf UVuf
@@ -3602,14 +3801,14 @@ EXTERN_C int perl_tsa_mutex_unlock(perl_mutex* mutex)
 #endif
 
 /*
-=head1 Miscellaneous Functions
+=for apidoc_section $directives
 
-=for apidoc AmU|bool|LIKELY|const bool expr
+=for apidoc Am||LIKELY|bool expr
 
 Returns the input unchanged, but at the same time it gives a branch prediction
 hint to the compiler that this condition is likely to be true.
 
-=for apidoc AmU|bool|UNLIKELY|const bool expr
+=for apidoc Am||UNLIKELY|bool expr
 
 Returns the input unchanged, but at the same time it gives a branch prediction
 hint to the compiler that this condition is likely to be false.
@@ -3665,40 +3864,55 @@ hint to the compiler that this condition is likely to be false.
 #  define __has_builtin(x) 0 /* not a clang style compiler */
 #endif
 
-/* ASSUME is like assert(), but it has a benefit in a release build. It is a
-   hint to a compiler about a statement of fact in a function call free
-   expression, which allows the compiler to generate better machine code.
-   In a debug build, ASSUME(x) is a synonym for assert(x). ASSUME(0) means
-   the control path is unreachable. In a for loop, ASSUME can be used to hint
-   that a loop will run at least X times. ASSUME is based off MSVC's __assume
-   intrinsic function, see its documents for more details.
+/*
+=for apidoc Am||ASSUME|bool expr
+C<ASSUME> is like C<assert()>, but it has a benefit in a release build. It is a
+hint to a compiler about a statement of fact in a function call free
+expression, which allows the compiler to generate better machine code.  In a
+debug build, C<ASSUME(x)> is a synonym for C<assert(x)>. C<ASSUME(0)> means the
+control path is unreachable. In a for loop, C<ASSUME> can be used to hint that
+a loop will run at least X times. C<ASSUME> is based off MSVC's C<__assume>
+intrinsic function, see its documents for more details.
+
+=cut
 */
 
-#ifndef DEBUGGING
-#  if __has_builtin(__builtin_unreachable) \
-     || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 4) /* 4.5 -> */
+#ifdef DEBUGGING
+#  define ASSUME(x) assert(x)
+#  if __has_builtin(__builtin_unreachable)
+#    define HAS_BUILTIN_UNREACHABLE
+#  elif (defined(__GNUC__) && (   __GNUC__ > 4                              \
+                               || __GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+#    define HAS_BUILTIN_UNREACHABLE
+#  endif
+#endif
+
+#if defined(__sun) || (defined(__hpux) && !defined(__GNUC__))
+#  ifndef ASSUME
+#    define ASSUME(x)      /* ASSUME() generates warnings on Solaris */
+#  endif
+#  define NOT_REACHED
+#elif defined(HAS_BUILTIN_UNREACHABLE)
+#  ifndef ASSUME
 #    define ASSUME(x) ((x) ? (void) 0 : __builtin_unreachable())
-#  elif defined(_MSC_VER)
+#  endif
+#  define NOT_REACHED                                                       \
+        STMT_START {                                                        \
+            ASSUME(!"UNREACHABLE"); __builtin_unreachable();                \
+        } STMT_END
+#else
+#  if defined(_MSC_VER)
 #    define ASSUME(x) __assume(x)
 #  elif defined(__ARMCC_VERSION) /* untested */
 #    define ASSUME(x) __promise(x)
 #  else
-/* a random compiler might define assert to its own special optimization token
-   so pass it through to C lib as a last resort */
+    /* a random compiler might define assert to its own special optimization
+     * token so pass it through to C lib as a last resort */
 #    define ASSUME(x) assert(x)
 #  endif
-#else
-#  define ASSUME(x) assert(x)
-#endif
-
-#if defined(__sun)      /* ASSUME() generates warnings on Solaris */
-#  define NOT_REACHED
-#elif defined(DEBUGGING) && (__has_builtin(__builtin_unreachable) \
-     || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 4)) /* 4.5 -> */
-#  define NOT_REACHED STMT_START { ASSUME(!"UNREACHABLE"); __builtin_unreachable(); } STMT_END
-#else
 #  define NOT_REACHED ASSUME(!"UNREACHABLE")
 #endif
+#undef HAS_BUILTIN_UNREACHABLE
 
 /* Some unistd.h's give a prototype for pause() even though
    HAS_PAUSE ends up undefined.  This causes the #define
@@ -3774,7 +3988,7 @@ typedef I32 (*filter_t) (pTHX_ int, SV *, int);
                && idx >= AvFILLp(PL_parser->rsfp_filters))
 #define PERL_FILTER_EXISTS(i) \
            (PL_parser && PL_parser->rsfp_filters \
-               && (i) <= av_tindex(PL_parser->rsfp_filters))
+               && (Size_t) (i) < av_count(PL_parser->rsfp_filters))
 
 #if defined(_AIX) && !defined(_AIX43)
 #if defined(USE_REENTRANT) || defined(_REENTRANT) || defined(_THREAD_SAFE)
@@ -3794,7 +4008,7 @@ typedef        struct crypt_data {     /* straight from /usr/include/crypt.h */
 
 #ifndef PERL_CALLCONV
 #  ifdef __cplusplus
-#    define PERL_CALLCONV extern "C"
+#    define PERL_CALLCONV  EXTERN_C
 #  else
 #    define PERL_CALLCONV
 #  endif
@@ -3809,13 +4023,22 @@ typedef        struct crypt_data {     /* straight from /usr/include/crypt.h */
 #ifndef PERL_STATIC_NO_RET
 #  define PERL_STATIC_NO_RET STATIC
 #endif
-/* PERL_STATIC_NO_RET is supposed to be equivalent to PERL_STATIC_INLINE on
-   builds that dont have a noreturn as a declaration specifier
+
+/* PERL_STATIC_INLINE_NO_RET is supposed to be equivalent to PERL_STATIC_INLINE
+ * on builds that dont have a noreturn as a declaration specifier
 */
 #ifndef PERL_STATIC_INLINE_NO_RET
 #  define PERL_STATIC_INLINE_NO_RET PERL_STATIC_INLINE
 #endif
 
+#ifndef PERL_STATIC_FORCE_INLINE
+#  define PERL_STATIC_FORCE_INLINE PERL_STATIC_INLINE
+#endif
+
+#ifndef PERL_STATIC_FORCE_INLINE_NO_RET
+#  define PERL_STATIC_FORCE_INLINE_NO_RET PERL_STATIC_INLINE
+#endif
+
 #if !defined(OS2)
 #  include "iperlsys.h"
 #endif
@@ -3880,7 +4103,8 @@ typedef        struct crypt_data {     /* straight from /usr/include/crypt.h */
 
 typedef struct magic_state MGS;        /* struct magic_state defined in mg.c */
 
-#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
+#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C) \
+ || defined(PERL_EXT_RE_BUILD)
 
 /* These have to be predeclared, as they are used in proto.h which is #included
  * before their definitions in regcomp.h. */
@@ -4027,6 +4251,21 @@ my_swap16(const U16 x) {
 /* This may look like unnecessary jumping through hoops, but converting
    out of range floating point values to integers *is* undefined behaviour,
    and it is starting to bite.
+
+=for apidoc_section $casting
+=for apidoc Am|I32|I_32|NV what
+Cast an NV to I32 while avoiding undefined C behavior
+
+=for apidoc Am|U32|U_32|NV what
+Cast an NV to U32 while avoiding undefined C behavior
+
+=for apidoc Am|IV|I_V|NV what
+Cast an NV to IV while avoiding undefined C behavior
+
+=for apidoc Am|UV|U_V|NV what
+Cast an NV to UV while avoiding undefined C behavior
+
+=cut
 */
 #ifndef CAST_INLINE
 #define I_32(what) (cast_i32((NV)(what)))
@@ -4052,6 +4291,25 @@ my_swap16(const U16 x) {
 #define U_I(what) ((unsigned int)U_32(what))
 #define U_L(what) U_32(what)
 
+/*
+=for apidoc_section $integer
+=for apidoc Amn|IV|IV_MAX
+The largest signed integer that fits in an IV on this platform.
+
+=for apidoc Amn|IV|IV_MIN
+The negative signed integer furthest away from 0 that fits in an IV on this
+platform.
+
+=for apidoc Amn|UV|UV_MAX
+The largest unsigned integer that fits in a UV on this platform.
+
+=for apidoc Amn|UV|UV_MIN
+The smallest unsigned integer that fits in a UV on this platform.  It should
+equal zero.
+
+=cut
+*/
+
 #ifdef HAS_SIGNBIT
 #  ifndef Perl_signbit
 #    define Perl_signbit signbit
@@ -4072,7 +4330,7 @@ my_swap16(const U16 x) {
 #endif
 
 #ifndef __cplusplus
-#if !(defined(WIN32) || defined(SYMBIAN))
+#if !defined(WIN32)
 Uid_t getuid (void);
 Uid_t geteuid (void);
 Gid_t getgid (void);
@@ -4129,6 +4387,11 @@ Gid_t getegid (void);
 #define DEBUG_DB_RECURSE_FLAG  0x40000000
 #define DEBUG_TOP_FLAG         0x80000000 /* -D was given --> PL_debug |= FLAG */
 
+/* Both flags have to be set */
+#  define DEBUG_BOTH_FLAGS_TEST_(flag1, flag2)              \
+            UNLIKELY((PL_debug & ((flag1)|(flag2)))         \
+                              == ((flag1)|(flag2)))
+
 #  define DEBUG_p_TEST_ UNLIKELY(PL_debug & DEBUG_p_FLAG)
 #  define DEBUG_s_TEST_ UNLIKELY(PL_debug & DEBUG_s_FLAG)
 #  define DEBUG_l_TEST_ UNLIKELY(PL_debug & DEBUG_l_FLAG)
@@ -4157,11 +4420,11 @@ Gid_t getegid (void);
 #  define DEBUG_L_TEST_ UNLIKELY(PL_debug & DEBUG_L_FLAG)
 #  define DEBUG_i_TEST_ UNLIKELY(PL_debug & DEBUG_i_FLAG)
 #  define DEBUG_y_TEST_ UNLIKELY(PL_debug & DEBUG_y_FLAG)
-#  define DEBUG_Xv_TEST_ (DEBUG_X_TEST_ && DEBUG_v_TEST_)
-#  define DEBUG_Uv_TEST_ (DEBUG_U_TEST_ && DEBUG_v_TEST_)
-#  define DEBUG_Pv_TEST_ (DEBUG_P_TEST_ && DEBUG_v_TEST_)
-#  define DEBUG_Lv_TEST_ (DEBUG_L_TEST_ && DEBUG_v_TEST_)
-#  define DEBUG_yv_TEST_ (DEBUG_y_TEST_ && DEBUG_v_TEST_)
+#  define DEBUG_Xv_TEST_ DEBUG_BOTH_FLAGS_TEST_(DEBUG_X_FLAG, DEBUG_v_FLAG)
+#  define DEBUG_Uv_TEST_ DEBUG_BOTH_FLAGS_TEST_(DEBUG_U_FLAG, DEBUG_v_FLAG)
+#  define DEBUG_Pv_TEST_ DEBUG_BOTH_FLAGS_TEST_(DEBUG_P_FLAG, DEBUG_v_FLAG)
+#  define DEBUG_Lv_TEST_ DEBUG_BOTH_FLAGS_TEST_(DEBUG_L_FLAG, DEBUG_v_FLAG)
+#  define DEBUG_yv_TEST_ DEBUG_BOTH_FLAGS_TEST_(DEBUG_y_FLAG, DEBUG_v_FLAG)
 
 #ifdef DEBUGGING
 
@@ -4231,10 +4494,11 @@ Gid_t getegid (void);
 
 #  define DEBUG_f(a) DEBUG__(DEBUG_f_TEST, a)
 
-#  ifndef PERL_EXT_RE_BUILD
-#    define DEBUG_r(a) DEBUG__(DEBUG_r_TEST, a)
-#  else
+/* For re_comp.c, re_exec.c, assume -Dr has been specified */
+#  ifdef PERL_EXT_RE_BUILD
 #    define DEBUG_r(a) STMT_START {a;} STMT_END
+#  else
+#    define DEBUG_r(a) DEBUG__(DEBUG_r_TEST, a)
 #  endif /* PERL_EXT_RE_BUILD */
 
 #  define DEBUG_x(a) DEBUG__(DEBUG_x_TEST, a)
@@ -4665,6 +4929,22 @@ EXTCONST char PL_No[]
   INIT("");
 EXTCONST char PL_Zero[]
   INIT("0");
+
+/*
+=for apidoc_section $numeric
+=for apidoc AmTuU|const char *|PL_hexdigit|U8 value
+
+This array, indexed by an integer, converts that value into the character that
+represents it.  For example, if the input is 8, the return will be a string
+whose first character is '8'.  What is actually returned is a pointer into a
+string.  All you are interested in is the first character of that string.  To
+get uppercase letters (for the values 10..15), add 16 to the index.  Hence,
+C<PL_hexdigit[11]> is C<'b'>, and C<PL_hexdigit[11+16]> is C<'B'>.  Adding 16
+to an index whose representation is '0'..'9' yields the same as not adding 16.
+Indices outside the range 0..31 result in (bad) undedefined behavior.
+
+=cut
+*/
 EXTCONST char PL_hexdigit[]
   INIT("0123456789abcdef0123456789ABCDEF");
 
@@ -4734,10 +5014,10 @@ EXTCONST int         PL_sig_num[];
  * folds such as outside the range or to multiple characters. */
 
 #ifdef DOINIT
-#ifndef EBCDIC
+#  ifndef EBCDIC
 
 /* The EBCDIC fold table depends on the code page, and hence is found in
- * utfebcdic.h */
+ * ebcdic_tables.h */
 
 EXTCONST  unsigned char PL_fold[] = {
        0,      1,      2,      3,      4,      5,      6,      7,
@@ -4773,6 +5053,42 @@ EXTCONST  unsigned char PL_fold[] = {
        240,    241,    242,    243,    244,    245,    246,    247,
        248,    249,    250,    251,    252,    253,    254,    255
 };
+
+EXT unsigned char PL_fold_locale[] = { /* Unfortunately not EXTCONST. */
+       0,      1,      2,      3,      4,      5,      6,      7,
+       8,      9,      10,     11,     12,     13,     14,     15,
+       16,     17,     18,     19,     20,     21,     22,     23,
+       24,     25,     26,     27,     28,     29,     30,     31,
+       32,     33,     34,     35,     36,     37,     38,     39,
+       40,     41,     42,     43,     44,     45,     46,     47,
+       48,     49,     50,     51,     52,     53,     54,     55,
+       56,     57,     58,     59,     60,     61,     62,     63,
+       64,     'a',    'b',    'c',    'd',    'e',    'f',    'g',
+       'h',    'i',    'j',    'k',    'l',    'm',    'n',    'o',
+       'p',    'q',    'r',    's',    't',    'u',    'v',    'w',
+       'x',    'y',    'z',    91,     92,     93,     94,     95,
+       96,     'A',    'B',    'C',    'D',    'E',    'F',    'G',
+       'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
+       'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
+       'X',    'Y',    'Z',    123,    124,    125,    126,    127,
+       128,    129,    130,    131,    132,    133,    134,    135,
+       136,    137,    138,    139,    140,    141,    142,    143,
+       144,    145,    146,    147,    148,    149,    150,    151,
+       152,    153,    154,    155,    156,    157,    158,    159,
+       160,    161,    162,    163,    164,    165,    166,    167,
+       168,    169,    170,    171,    172,    173,    174,    175,
+       176,    177,    178,    179,    180,    181,    182,    183,
+       184,    185,    186,    187,    188,    189,    190,    191,
+       192,    193,    194,    195,    196,    197,    198,    199,
+       200,    201,    202,    203,    204,    205,    206,    207,
+       208,    209,    210,    211,    212,    213,    214,    215,
+       216,    217,    218,    219,    220,    221,    222,    223,
+       224,    225,    226,    227,    228,    229,    230,    231,
+       232,    233,    234,    235,    236,    237,    238,    239,
+       240,    241,    242,    243,    244,    245,    246,    247,
+       248,    249,    250,    251,    252,    253,    254,    255
+};
+
 EXTCONST  unsigned char PL_fold_latin1[] = {
     /* Full latin1 complement folding, except for three problematic code points:
      * Micro sign (181 = 0xB5) and y with diearesis (255 = 0xFF) have their
@@ -4885,145 +5201,29 @@ EXTCONST  unsigned char PL_mod_latin1_uc[] = {
        200,    201,    202,    203,    204,    205,    206,    207,
        208,    209,    210,    211,    212,    213,    214,    215,
        216,    217,    218,    219,    220,    221,    222,
-#if    UNICODE_MAJOR_VERSION > 2                                        \
-   || (UNICODE_MAJOR_VERSION == 2 && UNICODE_DOT_VERSION >= 1          \
-                                  && UNICODE_DOT_DOT_VERSION >= 8)
+#    if    UNICODE_MAJOR_VERSION > 2                                        \
+       || (UNICODE_MAJOR_VERSION == 2 && UNICODE_DOT_VERSION >= 1           \
+                                      && UNICODE_DOT_DOT_VERSION >= 8)
                                                                255 /*sharp s*/,
-#else   /* uc(sharp s) is 'sharp s' itself in early unicode */
+#    else   /* uc(sharp s) is 'sharp s' itself in early unicode */
                                                                223,
-#endif
+#    endif
        224-32, 225-32, 226-32, 227-32, 228-32, 229-32, 230-32, 231-32,
        232-32, 233-32, 234-32, 235-32, 236-32, 237-32, 238-32, 239-32,
        240-32, 241-32, 242-32, 243-32, 244-32, 245-32, 246-32, 247,
        248-32, 249-32, 250-32, 251-32, 252-32, 253-32, 254-32, 255
 };
-#endif  /* !EBCDIC, but still in DOINIT */
+#  endif  /* !EBCDIC, but still in DOINIT */
 #else  /* ! DOINIT */
-#   ifndef EBCDIC
+#  ifndef EBCDIC
 EXTCONST unsigned char PL_fold[];
 EXTCONST unsigned char PL_fold_latin1[];
 EXTCONST unsigned char PL_mod_latin1_uc[];
 EXTCONST unsigned char PL_latin1_lc[];
+EXT      unsigned char PL_fold_locale[]; /* Unfortunately not EXTCONST. */
 #   endif
 #endif
 
-#ifndef PERL_GLOBAL_STRUCT /* or perlvars.h */
-#ifdef DOINIT
-EXT unsigned char PL_fold_locale[256] = { /* Unfortunately not EXTCONST. */
-       0,      1,      2,      3,      4,      5,      6,      7,
-       8,      9,      10,     11,     12,     13,     14,     15,
-       16,     17,     18,     19,     20,     21,     22,     23,
-       24,     25,     26,     27,     28,     29,     30,     31,
-       32,     33,     34,     35,     36,     37,     38,     39,
-       40,     41,     42,     43,     44,     45,     46,     47,
-       48,     49,     50,     51,     52,     53,     54,     55,
-       56,     57,     58,     59,     60,     61,     62,     63,
-       64,     'a',    'b',    'c',    'd',    'e',    'f',    'g',
-       'h',    'i',    'j',    'k',    'l',    'm',    'n',    'o',
-       'p',    'q',    'r',    's',    't',    'u',    'v',    'w',
-       'x',    'y',    'z',    91,     92,     93,     94,     95,
-       96,     'A',    'B',    'C',    'D',    'E',    'F',    'G',
-       'H',    'I',    'J',    'K',    'L',    'M',    'N',    'O',
-       'P',    'Q',    'R',    'S',    'T',    'U',    'V',    'W',
-       'X',    'Y',    'Z',    123,    124,    125,    126,    127,
-       128,    129,    130,    131,    132,    133,    134,    135,
-       136,    137,    138,    139,    140,    141,    142,    143,
-       144,    145,    146,    147,    148,    149,    150,    151,
-       152,    153,    154,    155,    156,    157,    158,    159,
-       160,    161,    162,    163,    164,    165,    166,    167,
-       168,    169,    170,    171,    172,    173,    174,    175,
-       176,    177,    178,    179,    180,    181,    182,    183,
-       184,    185,    186,    187,    188,    189,    190,    191,
-       192,    193,    194,    195,    196,    197,    198,    199,
-       200,    201,    202,    203,    204,    205,    206,    207,
-       208,    209,    210,    211,    212,    213,    214,    215,
-       216,    217,    218,    219,    220,    221,    222,    223,    
-       224,    225,    226,    227,    228,    229,    230,    231,
-       232,    233,    234,    235,    236,    237,    238,    239,
-       240,    241,    242,    243,    244,    245,    246,    247,
-       248,    249,    250,    251,    252,    253,    254,    255
-};
-#else
-EXT unsigned char PL_fold_locale[256]; /* Unfortunately not EXTCONST. */
-#endif
-#endif /* !PERL_GLOBAL_STRUCT */
-
-#ifdef DOINIT
-#ifdef EBCDIC
-EXTCONST unsigned char PL_freq[] = {/* EBCDIC frequencies for mixed English/C */
-    1,      2,      84,     151,    154,    155,    156,    157,
-    165,    246,    250,    3,      158,    7,      18,     29,
-    40,     51,     62,     73,     85,     96,     107,    118,
-    129,    140,    147,    148,    149,    150,    152,    153,
-    255,      6,      8,      9,     10,     11,     12,     13,
-     14,     15,     24,     25,     26,     27,     28,    226,
-     29,     30,     31,     32,     33,     43,     44,     45,
-     46,     47,     48,     49,     50,     76,     77,     78,
-     79,     80,     81,     82,     83,     84,     85,     86,
-     87,     94,     95,    234,    181,    233,    187,    190,
-    180,     96,     97,     98,     99,    100,    101,    102,
-    104,    112,    182,    174,    236,    232,    229,    103,
-    228,    226,    114,    115,    116,    117,    118,    119,
-    120,    121,    122,    235,    176,    230,    194,    162,
-    130,    131,    132,    133,    134,    135,    136,    137,
-    138,    139,    201,    205,    163,    217,    220,    224,
-    5,      248,    227,    244,    242,    255,    241,    231,
-    240,    253,    16,     197,    19,     20,     21,     187,
-    23,     169,    210,    245,    237,    249,    247,    239,
-    168,    252,    34,     196,    36,     37,     38,     39,
-    41,     42,     251,    254,    238,    223,    221,    213,
-    225,    177,    52,     53,     54,     55,     56,     57,
-    58,     59,     60,     61,     63,     64,     65,     66,
-    67,     68,     69,     70,     71,     72,     74,     75,
-    205,    208,    186,    202,    200,    218,    198,    179,
-    178,    214,    88,     89,     90,     91,     92,     93,
-    217,    166,    170,    207,    199,    209,    206,    204,
-    160,    212,    105,    106,    108,    109,    110,    111,
-    203,    113,    216,    215,    192,    175,    193,    243,
-    172,    161,    123,    124,    125,    126,    127,    128,
-    222,    219,    211,    195,    188,    193,    185,    184,
-    191,    183,    141,    142,    143,    144,    145,    146
-};
-#else  /* ascii rather than ebcdic */
-EXTCONST unsigned char PL_freq[] = {   /* letter frequencies for mixed English/C */
-       1,      2,      84,     151,    154,    155,    156,    157,
-       165,    246,    250,    3,      158,    7,      18,     29,
-       40,     51,     62,     73,     85,     96,     107,    118,
-       129,    140,    147,    148,    149,    150,    152,    153,
-       255,    182,    224,    205,    174,    176,    180,    217,
-       233,    232,    236,    187,    235,    228,    234,    226,
-       222,    219,    211,    195,    188,    193,    185,    184,
-       191,    183,    201,    229,    181,    220,    194,    162,
-       163,    208,    186,    202,    200,    218,    198,    179,
-       178,    214,    166,    170,    207,    199,    209,    206,
-       204,    160,    212,    216,    215,    192,    175,    173,
-       243,    172,    161,    190,    203,    189,    164,    230,
-       167,    248,    227,    244,    242,    255,    241,    231,
-       240,    253,    169,    210,    245,    237,    249,    247,
-       239,    168,    252,    251,    254,    238,    223,    221,
-       213,    225,    177,    197,    171,    196,    159,    4,
-       5,      6,      8,      9,      10,     11,     12,     13,
-       14,     15,     16,     17,     19,     20,     21,     22,
-       23,     24,     25,     26,     27,     28,     30,     31,
-       32,     33,     34,     35,     36,     37,     38,     39,
-       41,     42,     43,     44,     45,     46,     47,     48,
-       49,     50,     52,     53,     54,     55,     56,     57,
-       58,     59,     60,     61,     63,     64,     65,     66,
-       67,     68,     69,     70,     71,     72,     74,     75,
-       76,     77,     78,     79,     80,     81,     82,     83,
-       86,     87,     88,     89,     90,     91,     92,     93,
-       94,     95,     97,     98,     99,     100,    101,    102,
-       103,    104,    105,    106,    108,    109,    110,    111,
-       112,    113,    114,    115,    116,    117,    119,    120,
-       121,    122,    123,    124,    125,    126,    127,    128,
-       130,    131,    132,    133,    134,    135,    136,    137,
-       138,    139,    141,    142,    143,    144,    145,    146
-};
-#endif
-#else
-EXTCONST unsigned char PL_freq[];
-#endif
-
 /* Although only used for debugging, these constants must be available in
  * non-debugging builds too, since they're used in ext/re/re_exec.c,
  * which has DEBUGGING enabled always */
@@ -5060,9 +5260,6 @@ EXTCONST char PL_bincompat_options[] =
 #  ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
                             " DEBUG_LEAKING_SCALARS_FORK_DUMP"
 #  endif
-#  ifdef FCRYPT
-                            " FCRYPT"
-#  endif
 #  ifdef HAS_TIMES
                             " HAS_TIMES"
 #  endif
@@ -5084,12 +5281,6 @@ EXTCONST char PL_bincompat_options[] =
 #  ifdef PERL_DEBUG_READONLY_OPS
                             " PERL_DEBUG_READONLY_OPS"
 #  endif
-#  ifdef PERL_GLOBAL_STRUCT
-                            " PERL_GLOBAL_STRUCT"
-#  endif
-#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-                            " PERL_GLOBAL_STRUCT_PRIVATE"
-#  endif
 #  ifdef PERL_IMPLICIT_CONTEXT
                             " PERL_IMPLICIT_CONTEXT"
 #  endif
@@ -5099,12 +5290,6 @@ EXTCONST char PL_bincompat_options[] =
 #  ifdef PERL_MICRO
                             " PERL_MICRO"
 #  endif
-#  ifdef PERL_NEED_APPCTX
-                            " PERL_NEED_APPCTX"
-#  endif
-#  ifdef PERL_NEED_TIMESBASE
-                            " PERL_NEED_TIMESBASE"
-#  endif
 #  ifdef PERL_POISON
                             " PERL_POISON"
 #  endif
@@ -5298,7 +5483,7 @@ typedef enum {
 
 #define HINT_RE_FLAGS          0x02000000 /* re '/xism' pragma */
 
-#define HINT_FEATURE_MASK      0x1c000000 /* 3 bits for feature bundles */
+#define HINT_FEATURE_MASK      0x3c000000 /* 4 bits for feature bundles */
 
                                /* Note: Used for HINT_M_VMSISH_*,
                                   currently defined by vms/vmsish.h:
@@ -5310,6 +5495,16 @@ typedef enum {
 #define HINT_SORT_STABLE       0x00000100 /* sort styles */
 #define HINT_SORT_UNSTABLE     0x00000200
 
+#define HINT_ALL_STRICT       HINT_STRICT_REFS \
+                            | HINT_STRICT_SUBS \
+                            | HINT_STRICT_VARS
+
+#ifdef USE_STRICT_BY_DEFAULT
+#define HINTS_DEFAULT            HINT_ALL_STRICT
+#else
+#define HINTS_DEFAULT            0
+#endif
+
 /* flags for PL_sawampersand */
 
 #define SAWAMPERSAND_LEFT       1   /* saw $` */
@@ -5445,34 +5640,6 @@ EXTCONST U16 PL_interp_size_5_18_0
   INIT(PERL_INTERPRETER_SIZE_UPTO_MEMBER(PERL_LAST_5_18_0_INTERP_MEMBER));
 
 
-#  ifdef PERL_GLOBAL_STRUCT
-/* MULTIPLICITY is automatically defined when PERL_GLOBAL_STRUCT is defined,
-   hence it's safe and sane to nest this within #ifdef MULTIPLICITY  */
-
-struct perl_vars {
-#    include "perlvars.h"
-};
-
-EXTCONST U16 PL_global_struct_size
-  INIT(sizeof(struct perl_vars));
-
-#    ifdef PERL_CORE
-#      ifndef PERL_GLOBAL_STRUCT_PRIVATE
-EXT struct perl_vars PL_Vars;
-EXT struct perl_vars *PL_VarsPtr INIT(&PL_Vars);
-#        undef PERL_GET_VARS
-#        define PERL_GET_VARS() PL_VarsPtr
-#      endif /* !PERL_GLOBAL_STRUCT_PRIVATE */
-#    else /* PERL_CORE */
-#      if !defined(__GNUC__) || !defined(WIN32)
-EXT
-#      endif /* WIN32 */
-struct perl_vars *PL_VarsPtr;
-#      define PL_Vars (*((PL_VarsPtr) \
-                      ? PL_VarsPtr : (PL_VarsPtr = Perl_GetVars(aTHX))))
-#    endif /* PERL_CORE */
-#  endif /* PERL_GLOBAL_STRUCT */
-
 /* Done with PERLVAR macros for now ... */
 #  undef PERLVAR
 #  undef PERLVARA
@@ -5545,13 +5712,11 @@ END_EXTERN_C
    define HAVE_INTERP_INTERN  */
 #include "embed.h"
 
-#ifndef PERL_GLOBAL_STRUCT
 START_EXTERN_C
 
 #  include "perlvars.h"
 
 END_EXTERN_C
-#endif
 
 #undef PERLVAR
 #undef PERLVARA
@@ -5593,8 +5758,14 @@ EXTCONST runops_proc_t PL_runops_dbg
 #define PERL_MAGIC_READONLY_ACCEPTABLE 0x40
 #define PERL_MAGIC_VALUE_MAGIC 0x80
 #define PERL_MAGIC_VTABLE_MASK 0x3F
+
+/* can this type of magic be attached to a readonly SV? */
 #define PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(t) \
     (PL_magic_data[(U8)(t)] & PERL_MAGIC_READONLY_ACCEPTABLE)
+
+/* Is this type of magic container magic (%ENV, $1 etc),
+ * or value magic (pos, taint etc)?
+ */
 #define PERL_MAGIC_TYPE_IS_VALUE_MAGIC(t) \
     (PL_magic_data[(U8)(t)] & PERL_MAGIC_VALUE_MAGIC)
 
@@ -5803,18 +5974,19 @@ EXTCONST U8 PL_extended_utf8_dfa_tab[] = {
  *        byte ones (as they are always legal) are to this state.
  */
 
-#    define NUM_CLASSES 18
-#    define N0 0
-#    define N1 ((N0)   + NUM_CLASSES)
-#    define N2 ((N1)   + NUM_CLASSES)
-#    define N3 ((N2)   + NUM_CLASSES)
-#    define N4 ((N3)   + NUM_CLASSES)
-#    define N5 ((N4)   + NUM_CLASSES)
-#    define N6 ((N5)   + NUM_CLASSES)
-#    define N7 ((N6)   + NUM_CLASSES)
-#    define N8 ((N7)   + NUM_CLASSES)
-#    define N9 ((N8)   + NUM_CLASSES)
-#    define N10 ((N9)  + NUM_CLASSES)
+#    if defined(PERL_CORE)
+#      define NUM_CLASSES 18
+#      define N0 0
+#      define N1 ((N0)   + NUM_CLASSES)
+#      define N2 ((N1)   + NUM_CLASSES)
+#      define N3 ((N2)   + NUM_CLASSES)
+#      define N4 ((N3)   + NUM_CLASSES)
+#      define N5 ((N4)   + NUM_CLASSES)
+#      define N6 ((N5)   + NUM_CLASSES)
+#      define N7 ((N6)   + NUM_CLASSES)
+#      define N8 ((N7)   + NUM_CLASSES)
+#      define N9 ((N8)   + NUM_CLASSES)
+#      define N10 ((N9)  + NUM_CLASSES)
 
 /*Class: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17  */
 /*N0*/   0, 1,N1,N2,N3,N4,N5, 1, 1, 1, 1, 1, 1,N6,N7,N8,N9,N10,
@@ -5856,7 +6028,7 @@ EXTCONST U8 PL_extended_utf8_dfa_tab[] = {
  * drops out immediately for that.  In the dfa, classes 3 and 4 are used to
  * distinguish EF vs the rest.  Then special code is used to deal with ED,
  * that's executed only when the dfa drops out.  The code points started by ED
- * are half surrogates, and half hangul syllables.  This means that 2048 of the
+ * are half surrogates, and half hangul syllables.  This means that 2048 of
  * the hangul syllables (about 18%) take longer than all other non-problematic
  * code points to handle.
  *
@@ -5942,30 +6114,30 @@ EXTCONST U8 PL_strict_utf8_dfa_tab[] = {
  *        byte ones (as they are always legal) are to this state.
  */
 
-#    undef N0
-#    undef N1
-#    undef N2
-#    undef N3
-#    undef N4
-#    undef N5
-#    undef N6
-#    undef N7
-#    undef N8
-#    undef N9
-#    undef NUM_CLASSES
-#    define NUM_CLASSES 19
-#    define N0 0
-#    define N1  ((N0)  + NUM_CLASSES)
-#    define N2  ((N1)  + NUM_CLASSES)
-#    define N3  ((N2)  + NUM_CLASSES)
-#    define N4  ((N3)  + NUM_CLASSES)
-#    define N5  ((N4)  + NUM_CLASSES)
-#    define N6  ((N5)  + NUM_CLASSES)
-#    define N7  ((N6)  + NUM_CLASSES)
-#    define N8  ((N7)  + NUM_CLASSES)
-#    define N9  ((N8)  + NUM_CLASSES)
-#    define N10 ((N9)  + NUM_CLASSES)
-#    define N11 ((N10) + NUM_CLASSES)
+#      undef N0
+#      undef N1
+#      undef N2
+#      undef N3
+#      undef N4
+#      undef N5
+#      undef N6
+#      undef N7
+#      undef N8
+#      undef N9
+#      undef NUM_CLASSES
+#      define NUM_CLASSES 19
+#      define N0 0
+#      define N1  ((N0)  + NUM_CLASSES)
+#      define N2  ((N1)  + NUM_CLASSES)
+#      define N3  ((N2)  + NUM_CLASSES)
+#      define N4  ((N3)  + NUM_CLASSES)
+#      define N5  ((N4)  + NUM_CLASSES)
+#      define N6  ((N5)  + NUM_CLASSES)
+#      define N7  ((N6)  + NUM_CLASSES)
+#      define N8  ((N7)  + NUM_CLASSES)
+#      define N9  ((N8)  + NUM_CLASSES)
+#      define N10 ((N9)  + NUM_CLASSES)
+#      define N11 ((N10) + NUM_CLASSES)
 
 /*Class: 0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18 */
 /*N0*/   0,  1, N1, N2, N4, N7, N6, N3, N5,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
@@ -6045,24 +6217,24 @@ EXTCONST U8 PL_c9_utf8_dfa_tab[] = {
  *        byte ones (as they are always legal) are to this state.
  */
 
-#    undef N0
-#    undef N1
-#    undef N2
-#    undef N3
-#    undef N4
-#    undef N5
-#    undef N6
-#    undef N7
-#    undef NUM_CLASSES
-#    define NUM_CLASSES 12
-#    define N0 0
-#    define N1  ((N0)  + NUM_CLASSES)
-#    define N2  ((N1)  + NUM_CLASSES)
-#    define N3  ((N2)  + NUM_CLASSES)
-#    define N4  ((N3)  + NUM_CLASSES)
-#    define N5  ((N4)  + NUM_CLASSES)
-#    define N6  ((N5)  + NUM_CLASSES)
-#    define N7  ((N6)  + NUM_CLASSES)
+#      undef N0
+#      undef N1
+#      undef N2
+#      undef N3
+#      undef N4
+#      undef N5
+#      undef N6
+#      undef N7
+#      undef NUM_CLASSES
+#      define NUM_CLASSES 12
+#      define N0 0
+#      define N1  ((N0)  + NUM_CLASSES)
+#      define N2  ((N1)  + NUM_CLASSES)
+#      define N3  ((N2)  + NUM_CLASSES)
+#      define N4  ((N3)  + NUM_CLASSES)
+#      define N5  ((N4)  + NUM_CLASSES)
+#      define N6  ((N5)  + NUM_CLASSES)
+#      define N7  ((N6)  + NUM_CLASSES)
 
 /*Class: 0   1   2   3   4   5   6   7   8   9  10  11 */
 /*N0*/   0,  1, N1, N2, N5, N7, N3, N4, N6,  1,  1,  1,
@@ -6076,6 +6248,7 @@ EXTCONST U8 PL_c9_utf8_dfa_tab[] = {
 /*N7*/   1,  1,  1,  1,  1,  1,  1,  1,  1, N2,  1,  1,
 };
 
+#    endif /* defined(PERL_CORE) */
 #  else     /* End of is DOINIT */
 
 EXTCONST U8 PL_extended_utf8_dfa_tab[];
@@ -6085,22 +6258,6 @@ EXTCONST U8 PL_c9_utf8_dfa_tab[];
 #  endif
 #endif    /* end of isn't EBCDIC */
 
-#ifndef PERL_NO_INLINE_FUNCTIONS
-/* Static inline funcs that depend on includes and declarations above.
-   Some of these reference functions in the perl object files, and some
-   compilers aren't smart enough to eliminate unused static inline
-   functions, so including this file in source code can cause link errors
-   even if the source code uses none of the functions. Hence including these
-   can be be suppressed by setting PERL_NO_INLINE_FUNCTIONS. Doing this will
-   (obviously) result in unworkable XS code, but allows simple probing code
-   to continue to work, because it permits tests to include the perl headers
-   for definitions without creating a link dependency on the perl library
-   (which may not exist yet).
-*/
-
-#  include "inline.h"
-#endif
-
 #include "overload.h"
 
 END_EXTERN_C
@@ -6236,7 +6393,7 @@ typedef struct am_table_short AMTS;
                         cBOOL(PL_hints & (HINT_LOCALE|HINT_LOCALE_PARTIAL))
 
 /*
-=head1 Locale-related functions and macros
+=for apidoc_section $locale
 
 =for apidoc Amn|bool|IN_LOCALE
 
@@ -6346,89 +6503,135 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
 #endif
 
 
-/* Locale/thread synchronization macros.  These aren't needed if using
- * thread-safe locale operations, except if something is broken */
-#if    defined(USE_LOCALE)                                                  \
- &&    defined(USE_ITHREADS)                                                \
- && (! defined(USE_THREAD_SAFE_LOCALE) || defined(TS_W32_BROKEN_LOCALECONV))
+/* Locale/thread synchronization macros. */
+#if ! (   defined(USE_LOCALE)                                               \
+       &&    defined(USE_ITHREADS)                                          \
+       && (  ! defined(USE_THREAD_SAFE_LOCALE)                              \
+           || (   defined(HAS_LOCALECONV)                                   \
+               && (  ! defined(HAS_LOCALECONV_L)                            \
+                   ||  defined(TS_W32_BROKEN_LOCALECONV)))                  \
+           || (   defined(HAS_NL_LANGINFO)                                  \
+               && ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L))                 \
+           || (defined(HAS_MBLEN)  && ! defined(HAS_MBRLEN))                \
+           || (defined(HAS_MBTOWC) && ! defined(HAS_MBRTOWC))               \
+           || (defined(HAS_WCTOMB) && ! defined(HAS_WCRTOMB))))
 
-/* We have a locale object holding the 'C' locale for Posix 2008 */
-#  ifndef USE_POSIX_2008_LOCALE
-#    define _LOCALE_TERM_POSIX_2008  NOOP
-#  else
-#    define _LOCALE_TERM_POSIX_2008                                         \
-                    STMT_START {                                            \
-                        if (PL_C_locale_obj) {                              \
-                            /* Make sure we aren't using the locale         \
-                             * space we are about to free */                \
-                            uselocale(LC_GLOBAL_LOCALE);                    \
-                            freelocale(PL_C_locale_obj);                    \
-                            PL_C_locale_obj = (locale_t) NULL;              \
-                        }                                                   \
-                    } STMT_END
-#  endif
+/* The whole expression just above was complemented, so here we have no need
+ * for thread synchronization, most likely it would be that this isn't a
+ * threaded build. */
+#  define LOCALE_INIT
+#  define LOCALE_TERM
+#  define LC_NUMERIC_LOCK(cond)     NOOP
+#  define LC_NUMERIC_UNLOCK         NOOP
+#  define LOCALECONV_LOCK           NOOP
+#  define LOCALECONV_UNLOCK         NOOP
+#  define LOCALE_READ_LOCK          NOOP
+#  define LOCALE_READ_UNLOCK        NOOP
+#  define MBLEN_LOCK                NOOP
+#  define MBLEN_UNLOCK              NOOP
+#  define MBTOWC_LOCK               NOOP
+#  define MBTOWC_UNLOCK             NOOP
+#  define NL_LANGINFO_LOCK          NOOP
+#  define NL_LANGINFO_UNLOCK        NOOP
+#  define SETLOCALE_LOCK            NOOP
+#  define SETLOCALE_UNLOCK          NOOP
+#  define WCTOMB_LOCK               NOOP
+#  define WCTOMB_UNLOCK             NOOP
+#else
 
-/* This is used as a generic lock for locale operations.  For example this is
- * used when calling nl_langinfo() so that another thread won't zap the
- * contents of its buffer before it gets saved; and it's called when changing
- * the locale of LC_MESSAGES.  On some systems the latter can cause the
- * nl_langinfo buffer to be zapped under a race condition.
- *
- * If combined with LC_NUMERIC_LOCK, calls to this and its corresponding unlock
- * should be contained entirely within the locked portion of LC_NUMERIC.  This
- * mutex should be used only in very short sections of code, while
- * LC_NUMERIC_LOCK may span more operations.  By always following this
- * convention, deadlock should be impossible.  But if necessary, the two
- * mutexes could be combined.
- *
- * Actually, the two macros just below with the '_V' suffixes are used in just
- * a few places where there is a broken localeconv(), but otherwise things are
- * thread safe, and hence don't need locking.  Just below LOCALE_LOCK and
- * LOCALE_UNLOCK are defined in terms of these for use everywhere else */
-#  define LOCALE_LOCK_V                                                     \
+   /* Here, we will need critical sections in locale handling, because one or
+    * more of the above conditions are true.  This could be because the
+    * platform doesn't have thread-safe locales, or that at least one of the
+    * locale-dependent functions in the core isn't thread-safe.  The latter
+    * case is generally because they return a pointer to a static buffer, which
+    * may be per-process instead of per-thread.  There are supposedly
+    * re-entrant, safe versions for all of them Perl currently uses (which the
+    * #if above checks for), but most platforms don't have all the needed ones
+    * available, and the Posix standard doesn't require nl_langinfo_l() to be
+    * fully thread-safe, so a Configure probe was written.  localeconv_l() is
+    * uncommon, and judging by bug reports on the web, some earlier library
+    * localeconv_l versions were broken, so perhaps a probe is in order for
+    * that, but it would be a pain to write.
+    *
+    * On non-thread-safe systems, some of the above functions are vulnerable to
+    * races should another thread get control and change the locale in the
+    * middle of their execution.
+    *
+    * We currently use a single mutex for all these cases.  This solves both
+    * the problem of another thread changing the locale, and the buffer being
+    * overwritten (the code copies the results to a safe place before releasing
+    * the mutex).  Ideally, for locale thread-safe platforms where the only
+    * issue is another thread clobbering the function's static buffer, there
+    * would be a separate mutex for each such buffer.  Otherwise, things get
+    * locked that don't need to.  But, it is not expected that any of these
+    * will be called frequently, and the locked interval should be short, and
+    * modern platforms will have reentrant versions (which don't lock) for
+    * almost all of them, so khw thinks a single mutex should suffice. */
+#  define LOCALE_LOCK_                                                      \
         STMT_START {                                                        \
             DEBUG_Lv(PerlIO_printf(Perl_debug_log,                          \
                     "%s: %d: locking locale\n", __FILE__, __LINE__));       \
             MUTEX_LOCK(&PL_locale_mutex);                                   \
         } STMT_END
-#  define LOCALE_UNLOCK_V                                                   \
+#  define LOCALE_UNLOCK_                                                    \
         STMT_START {                                                        \
             DEBUG_Lv(PerlIO_printf(Perl_debug_log,                          \
                    "%s: %d: unlocking locale\n", __FILE__, __LINE__));      \
             MUTEX_UNLOCK(&PL_locale_mutex);                                 \
         } STMT_END
 
-/* On windows, we just need the mutex for LOCALE_LOCK */
-#  ifdef TS_W32_BROKEN_LOCALECONV
-#    define LOCALE_LOCK     NOOP
-#    define LOCALE_UNLOCK   NOOP
-#    define LOCALE_INIT     MUTEX_INIT(&PL_locale_mutex);
-#    define LOCALE_TERM     MUTEX_DESTROY(&PL_locale_mutex)
-#    define LC_NUMERIC_LOCK(cond)
-#    define LC_NUMERIC_UNLOCK
+   /* We do define a different macro for each case; then if we want to have
+    * separate mutexes for some of them, the only changes needed are here.
+    * Define just the necessary macros.  The compiler should then croak if the
+    * #ifdef's in the code are incorrect */
+#  if defined(HAS_LOCALECONV) && (  ! defined(HAS_POSIX_2008_LOCALE)        \
+                                 || ! defined(HAS_LOCALECONV_L)             \
+                                 ||   defined(TS_W32_BROKEN_LOCALECONV))
+#    define LOCALECONV_LOCK   LOCALE_LOCK_
+#    define LOCALECONV_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_NL_LANGINFO) && (   ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L) \
+                                   || ! defined(HAS_POSIX_2008_LOCALE))
+#    define NL_LANGINFO_LOCK   LOCALE_LOCK_
+#    define NL_LANGINFO_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_MBLEN) && ! defined(HAS_MBRLEN)
+#    define MBLEN_LOCK   LOCALE_LOCK_
+#    define MBLEN_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_MBTOWC) && ! defined(HAS_MBRTOWC)
+#    define MBTOWC_LOCK   LOCALE_LOCK_
+#    define MBTOWC_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_WCTOMB) && ! defined(HAS_WCRTOMB)
+#    define WCTOMB_LOCK   LOCALE_LOCK_
+#    define WCTOMB_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(USE_THREAD_SAFE_LOCALE)
+     /* On locale thread-safe systems, we don't need these workarounds */
+#    define LOCALE_TERM_LC_NUMERIC_   NOOP
+#    define LOCALE_INIT_LC_NUMERIC_   NOOP
+#    define LC_NUMERIC_LOCK(cond)   NOOP
+#    define LC_NUMERIC_UNLOCK       NOOP
+#    define LOCALE_INIT_LC_NUMERIC_ NOOP
+#    define LOCALE_TERM_LC_NUMERIC_ NOOP
+
+     /* There may be instance core where we this is invoked yet should do
+      * nothing.  Rather than have #ifdef's around them, define it here */
+#    define SETLOCALE_LOCK    NOOP
+#    define SETLOCALE_UNLOCK  NOOP
 #  else
-#    define LOCALE_LOCK     LOCALE_LOCK_V
-#    define LOCALE_UNLOCK   LOCALE_UNLOCK_V
-
-     /* We also need to lock LC_NUMERIC for non-windows (hence Posix 2008)
-      * systems */
-#    define LOCALE_INIT          STMT_START {                               \
-                                    MUTEX_INIT(&PL_locale_mutex);           \
-                                    MUTEX_INIT(&PL_lc_numeric_mutex);       \
-                                } STMT_END
-
-#    define LOCALE_TERM         STMT_START {                                \
-                                    MUTEX_DESTROY(&PL_locale_mutex);        \
-                                    MUTEX_DESTROY(&PL_lc_numeric_mutex);    \
-                                    _LOCALE_TERM_POSIX_2008;                \
-                                } STMT_END
-
-    /* This mutex is used to create critical sections where we want the
-     * LC_NUMERIC locale to be locked into either the C (standard) locale, or
-     * the underlying locale, so that other threads interrupting this one don't
-     * change it to the wrong state before we've had a chance to complete our
-     * operation.  It can stay locked over an entire printf operation, for
-     * example.  And so is made distinct from the LOCALE_LOCK mutex.
+#    define SETLOCALE_LOCK   LOCALE_LOCK_
+#    define SETLOCALE_UNLOCK LOCALE_UNLOCK_
+
+    /* On platforms without per-thread locales, when another thread can switch
+     * our locale, we need another mutex to create critical sections where we
+     * want the LC_NUMERIC locale to be locked into either the C (standard)
+     * locale, or the underlying locale, so that other threads interrupting
+     * this one don't change it to the wrong state before we've had a chance to
+     * complete our operation.  It can stay locked over an entire printf
+     * operation, for example.  And so is made distinct from the LOCALE_LOCK
+     * mutex.
      *
      * This simulates kind of a general semaphore.  The current thread will
      * lock the mutex if the per-thread variable is zero, and then increments
@@ -6442,7 +6645,13 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
      *
      * Clang improperly gives warnings for this, if not silenced:
      * https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#conditional-locks
-     * */
+     *
+     * If LC_NUMERIC_LOCK is combined with one of the LOCKs above, calls to
+     * that and its corresponding unlock should be contained entirely within
+     * the locked portion of LC_NUMERIC.  Those mutexes should be used only in
+     * very short sections of code, while LC_NUMERIC_LOCK may span more
+     * operations.  By always following this convention, deadlock should be
+     * impossible.  But if necessary, the two mutexes could be combined. */
 #    define LC_NUMERIC_LOCK(cond_to_panic_if_already_locked)                \
         CLANG_DIAG_IGNORE(-Wthread-safety)                                 \
         STMT_START {                                                        \
@@ -6484,16 +6693,36 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
         } STMT_END                                                          \
         CLANG_DIAG_RESTORE
 
-#  endif    /* End of needs locking LC_NUMERIC */
-#else   /* Below is no locale sync needed */
-#  define LOCALE_INIT
-#  define LOCALE_LOCK
-#  define LOCALE_LOCK_V
-#  define LOCALE_UNLOCK
-#  define LOCALE_UNLOCK_V
-#  define LC_NUMERIC_LOCK(cond)
-#  define LC_NUMERIC_UNLOCK
-#  define LOCALE_TERM
+#    define LOCALE_INIT_LC_NUMERIC_   MUTEX_INIT(&PL_lc_numeric_mutex)
+#    define LOCALE_TERM_LC_NUMERIC_   MUTEX_DESTROY(&PL_lc_numeric_mutex)
+#  endif
+
+#  ifdef USE_POSIX_2008_LOCALE
+     /* We have a locale object holding the 'C' locale for Posix 2008 */
+#    define LOCALE_TERM_POSIX_2008_                                         \
+                    STMT_START {                                            \
+                        if (PL_C_locale_obj) {                              \
+                            /* Make sure we aren't using the locale         \
+                             * space we are about to free */                \
+                            uselocale(LC_GLOBAL_LOCALE);                    \
+                            freelocale(PL_C_locale_obj);                    \
+                            PL_C_locale_obj = (locale_t) NULL;              \
+                        }                                                   \
+                    } STMT_END
+#  else
+#    define LOCALE_TERM_POSIX_2008_  NOOP
+#  endif
+
+#  define LOCALE_INIT           STMT_START {                                \
+                                    MUTEX_INIT(&PL_locale_mutex);           \
+                                    LOCALE_INIT_LC_NUMERIC_;                \
+                                } STMT_END
+
+#  define LOCALE_TERM           STMT_START {                                \
+                                    MUTEX_DESTROY(&PL_locale_mutex);        \
+                                    LOCALE_TERM_LC_NUMERIC_;                \
+                                    LOCALE_TERM_POSIX_2008_;                \
+                                } STMT_END
 #endif
 
 #ifdef USE_LOCALE_NUMERIC
@@ -6504,7 +6733,7 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
  * operations used by Perl, namely the decimal point, and even the thousands
  * separator.)
 
-=head1 Locale-related functions and macros
+=for apidoc_section $locale
 
 =for apidoc Amn|void|DECLARATION_FOR_LC_NUMERIC_MANIPULATION
 
@@ -6516,7 +6745,7 @@ any executable statements.
 
 =for apidoc Am|void|STORE_LC_NUMERIC_FORCE_TO_UNDERLYING
 
-This is used by XS code that that is C<LC_NUMERIC> locale-aware to force the
+This is used by XS code that is C<LC_NUMERIC> locale-aware to force the
 locale for category C<LC_NUMERIC> to be what perl thinks is the current
 underlying locale.  (The perl interpreter could be wrong about what the
 underlying locale actually is if some C or XS code has called the C library
@@ -6778,7 +7007,7 @@ cannot have changed since the precalculation.
 #  define SET_NUMERIC_STANDARD()
 #  define SET_NUMERIC_UNDERLYING()
 #  define IS_NUMERIC_RADIX(a, b)               (0)
-#  define DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+#  define DECLARATION_FOR_LC_NUMERIC_MANIPULATION  dNOOP
 #  define STORE_LC_NUMERIC_SET_STANDARD()
 #  define STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
 #  define STORE_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric)
@@ -6793,11 +7022,80 @@ cannot have changed since the precalculation.
 
 #endif /* !USE_LOCALE_NUMERIC */
 
+#ifdef USE_ITHREADS
+#  define ENV_LOCK            PERL_WRITE_LOCK(&PL_env_mutex)
+#  define ENV_UNLOCK          PERL_WRITE_UNLOCK(&PL_env_mutex)
+#  define ENV_READ_LOCK       PERL_READ_LOCK(&PL_env_mutex)
+#  define ENV_READ_UNLOCK     PERL_READ_UNLOCK(&PL_env_mutex)
+#  define ENV_INIT            PERL_RW_MUTEX_INIT(&PL_env_mutex)
+#  define ENV_TERM            PERL_RW_MUTEX_DESTROY(&PL_env_mutex)
+
+   /* On platforms where the static buffer contained in getenv() is per-thread
+    * rather than process-wide, another thread executing a getenv() at the same
+    * time won't destroy ours before we have copied the result safely away and
+    * unlocked the mutex.  On such platforms (which is most), we can have many
+    * readers of the environment at the same time. */
+#  ifdef GETENV_PRESERVES_OTHER_THREAD
+#    define GETENV_LOCK    ENV_READ_LOCK
+#    define GETENV_UNLOCK  ENV_READ_UNLOCK
+#  else
+     /* If, on the other hand, another thread could zap our getenv() return, we
+      * need to keep them from executing until we are done */
+#    define GETENV_LOCK    ENV_LOCK
+#    define GETENV_UNLOCK  ENV_UNLOCK
+#  endif
+#else
+#  define ENV_LOCK        NOOP
+#  define ENV_UNLOCK      NOOP
+#  define ENV_READ_LOCK   NOOP
+#  define ENV_READ_UNLOCK NOOP
+#  define ENV_INIT        NOOP
+#  define ENV_TERM        NOOP
+#  define GETENV_LOCK     NOOP
+#  define GETENV_UNLOCK   NOOP
+#endif
+
+#ifndef PERL_NO_INLINE_FUNCTIONS
+/* Static inline funcs that depend on includes and declarations above.
+   Some of these reference functions in the perl object files, and some
+   compilers aren't smart enough to eliminate unused static inline
+   functions, so including this file in source code can cause link errors
+   even if the source code uses none of the functions. Hence including these
+   can be suppressed by setting PERL_NO_INLINE_FUNCTIONS. Doing this will
+   (obviously) result in unworkable XS code, but allows simple probing code
+   to continue to work, because it permits tests to include the perl headers
+   for definitions without creating a link dependency on the perl library
+   (which may not exist yet).
+*/
+
+START_EXTERN_C
+
+#  include "inline.h"
+
+END_EXTERN_C
+
+#endif
+
+/* Some critical sections need to lock both the locale and the environment.
+ * XXX khw intends to change this to lock both mutexes, but that brings up
+ * issues of potential deadlock, so should be done at the beginning of a
+ * development cycle.  So for now, it just locks the environment.  Note that
+ * many modern platforms are locale-thread-safe anyway, so locking the locale
+ * mutex is a no-op anyway */
+#define ENV_LOCALE_LOCK     ENV_LOCK
+#define ENV_LOCALE_UNLOCK   ENV_UNLOCK
+
+/* And some critical sections care only that no one else is writing either the
+ * locale nor the environment.  XXX Again this is for the future.  This can be
+ * simulated with using COND_WAIT in thread.h */
+#define ENV_LOCALE_READ_LOCK     ENV_LOCALE_LOCK
+#define ENV_LOCALE_READ_UNLOCK   ENV_LOCALE_UNLOCK
+
 #define Atof                           my_atof
 
 /*
 
-=head1 Numeric functions
+=for apidoc_section $numeric
 
 =for apidoc AmTR|NV|Strtod|NN const char * const s|NULLOK char ** e
 
@@ -6989,15 +7287,9 @@ C<strtoul>.
 /* START_MY_CXT must appear in all extensions that define a my_cxt_t structure,
  * right after the definition (i.e. at file scope).  The non-threads
  * case below uses it to declare the data as static. */
-#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-#    define START_MY_CXT
-#    define MY_CXT_INDEX Perl_my_cxt_index(aTHX_ MY_CXT_KEY)
-#    define MY_CXT_INIT_ARG MY_CXT_KEY
-#  else
 #    define START_MY_CXT static int my_cxt_index = -1;
 #    define MY_CXT_INDEX my_cxt_index
 #    define MY_CXT_INIT_ARG &my_cxt_index
-#  endif /* #ifdef PERL_GLOBAL_STRUCT_PRIVATE */
 
 /* Creates and zeroes the per-interpreter data.
  * (We allocate my_cxtp in a Perl SV so that it will be released when
@@ -7041,9 +7333,7 @@ C<strtoul>.
 #  define _aMY_CXT     ,aMY_CXT
 
 #else /* PERL_IMPLICIT_CONTEXT */
-
 #  define START_MY_CXT         static my_cxt_t my_cxt;
-#  define dMY_CXT_SV           dNOOP
 #  define dMY_CXT              dNOOP
 #  define dMY_CXT_INTERP(my_perl) dNOOP
 #  define MY_CXT_INIT          NOOP
@@ -7131,7 +7421,7 @@ EXTERN_C int flock(int fd, int op);
 #define IS_NUMBER_TRAILING            0x40 /* number has trailing trash */
 
 /*
-=head1 Numeric functions
+=for apidoc_section $numeric
 
 =for apidoc AmdR|bool|GROK_NUMERIC_RADIX|NN const char **sp|NN const char *send
 
@@ -7201,6 +7491,8 @@ extern void moncontrol(int);
 
 #define PERL_MAGIC_UTF8_CACHESIZE      2
 
+#ifdef PERL_CORE
+
 #define PERL_UNICODE_STDIN_FLAG                        0x0001
 #define PERL_UNICODE_STDOUT_FLAG               0x0002
 #define PERL_UNICODE_STDERR_FLAG               0x0004
@@ -7239,12 +7531,23 @@ extern void moncontrol(int);
 #define PERL_UNICODE_WIDESYSCALLS              'W'
 #define PERL_UNICODE_UTF8CACHEASSERT           'a'
 
+#endif
+
+/*
+=for apidoc_section $signals
+=for apidoc Amn|U32|PERL_SIGNALS_UNSAFE_FLAG
+If this bit in C<PL_signals> is set, the system is uing the pre-Perl 5.8
+unsafe signals.  See L<perlrun/PERL_SIGNALS> and L<perlipc/Deferred Signals
+(Safe Signals)>.
+
+=cut
+*/
 #define PERL_SIGNALS_UNSAFE_FLAG       0x0001
 
 /*
-=head1 Numeric functions
+=for apidoc_section $numeric
 
-=for apidoc Am|int|PERL_ABS|int
+=for apidoc Am|int|PERL_ABS|int x
 
 Typeless C<abs> or C<fabs>, I<etc>.  (The usage below indicates it is for
 integers, but it works for any type.)  Use instead of these, since the C
@@ -7274,7 +7577,7 @@ so no C<x++>.
 
 
 /*
-=head1 Miscellaneous Functions
+=for apidoc_section $utility
 
 =for apidoc Am|bool|IS_SAFE_SYSCALL|NN const char *pv|STRLEN len|NN const char *what|NN const char *op_name