# include "config.h"
#endif
+/* this is used for functions which take a depth trailing
+ * argument under debugging */
+#ifdef DEBUGGING
+#define _pDEPTH ,U32 depth
+#define _aDEPTH ,depth
+#else
+#define _pDEPTH
+#define _aDEPTH
+#endif
+
/* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
* because the __STDC_VERSION__ became a thing only with C90. Therefore,
* with gcc, HAS_C99 will never become true as long as we use -std=c89.
* NOTE 2: headers lie. Do not expect that if HAS_C99 gets to be true,
* all the C99 features are there and are correct. */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
- defined(_STDC_C99)
+ defined(_STDC_C99) || defined(__c99)
# define HAS_C99 1
#endif
# ifdef PERL_GLOBAL_STRUCT_PRIVATE
EXTERN_C struct perl_vars* Perl_GetVarsPrivate();
# define PERL_GET_VARS() Perl_GetVarsPrivate() /* see miniperlmain.c */
-# ifndef PERLIO_FUNCS_CONST
-# define PERLIO_FUNCS_CONST /* Can't have these lying around. */
-# endif
# else
# define PERL_GET_VARS() PL_VarsPtr
# endif
# endif
#endif
+/* this used to be off by default, now its on, see perlio.h */
+#define PERLIO_FUNCS_CONST
+
#define pVAR struct perl_vars* my_vars PERL_UNUSED_DECL
#ifdef PERL_GLOBAL_STRUCT
Perl_pregfree(aTHX_ (prog))
#define CALLREGFREE_PVT(prog) \
- if(prog) RX_ENGINE(prog)->free(aTHX_ (prog))
+ if(prog) RX_ENGINE(prog)->rxfree(aTHX_ (prog))
#define CALLREG_NUMBUF_FETCH(rx,paren,usesv) \
RX_ENGINE(rx)->numbered_buff_FETCH(aTHX_ (rx),(paren),(usesv))
#endif
#ifndef PERL_UNUSED_DECL
-# if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
+# if defined(HASATTRIBUTE_UNUSED) && (!defined(__cplusplus) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
# define PERL_UNUSED_DECL __attribute__unused__
# else
# define PERL_UNUSED_DECL
* or variables/arguments that are used only in certain configurations.
*/
#ifndef PERL_UNUSED_ARG
-# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */
-# include <note.h>
-# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x))
-# else
-# define PERL_UNUSED_ARG(x) ((void)sizeof(x))
-# endif
+# define PERL_UNUSED_ARG(x) ((void)sizeof(x))
#endif
#ifndef PERL_UNUSED_VAR
# define PERL_UNUSED_VAR(x) ((void)sizeof(x))
# define GCC_DIAG_IGNORE(w)
# define GCC_DIAG_RESTORE
#endif
+/* for clang specific pragmas */
+#if defined(__clang__) || defined(__clang)
+# define CLANG_DIAG_PRAGMA(x) _Pragma (#x)
+# define CLANG_DIAG_IGNORE(x) _Pragma("clang diagnostic push") \
+ CLANG_DIAG_PRAGMA(clang diagnostic ignored #x)
+# define CLANG_DIAG_RESTORE _Pragma("clang diagnostic pop")
+#else
+# define CLANG_DIAG_IGNORE(w)
+# define CLANG_DIAG_RESTORE
+#endif
#define NOOP /*EMPTY*/(void)0
/* cea2e8a9dd23747f accidentally lost the comment originally from the first
# endif
#endif
-/* Some platforms require marking function declarations
- * for them to be exportable. Used in perlio.h, proto.h
- * is handled either by the makedef.pl or by defining the
- * PERL_CALLCONV to be something special. See also the
- * definition of XS() in XSUB.h. */
-#ifndef PERL_EXPORT_C
-# ifdef __cplusplus
-# define PERL_EXPORT_C extern "C"
-# else
-# define PERL_EXPORT_C extern
-# endif
-#endif
-#ifndef PERL_XS_EXPORT_C
-# ifdef __cplusplus
-# define PERL_XS_EXPORT_C extern "C"
-# else
-# define PERL_XS_EXPORT_C
-# endif
-#endif
-
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus)
# ifndef PERL_USE_GCC_BRACE_GROUPS
# define PERL_USE_GCC_BRACE_GROUPS
# define TAINT_WARN_get 0
# define TAINT_WARN_set(s) NOOP
#else
-# define TAINT (PL_tainted = TRUE)
+# define TAINT (PL_tainted = PL_tainting)
# define TAINT_NOT (PL_tainted = FALSE)
-# define TAINT_IF(c) if (UNLIKELY(c)) { PL_tainted = TRUE; }
+# define TAINT_IF(c) if (UNLIKELY(c)) { PL_tainted = PL_tainting; }
# define TAINT_ENV() if (UNLIKELY(PL_tainting)) { taint_env(); }
# define TAINT_PROPER(s) if (UNLIKELY(PL_tainting)) { taint_proper(NULL, s); }
# define TAINT_set(s) (PL_tainted = (s))
# endif
#endif
+/* 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 1
+#endif
#ifdef I_STDARG
# include <stdarg.h>
#else
# include <locale.h>
#endif
+#ifdef I_XLOCALE
+# include <xlocale.h>
+#endif
+
#if !defined(NO_LOCALE) && defined(HAS_SETLOCALE)
# define USE_LOCALE
# define HAS_SKIP_LOCALE_INIT /* Solely for XS code to test for this
# if !defined(NO_LOCALE_TIME) && defined(LC_TIME)
# define USE_LOCALE_TIME
# endif
-# ifndef WIN32 /* No wrapper except on Windows */
-# define my_setlocale(a,b) setlocale(a,b)
-# endif
#endif /* !NO_LOCALE && HAS_SETLOCALE */
#include <setjmp.h>
/* If this causes problems, set i_unistd=undef in the hint file. */
#ifdef I_UNISTD
+# if defined(__amigaos4__)
+# ifdef I_NETINET_IN
+# include <netinet/in.h>
+# endif
+# endif
# include <unistd.h>
+# if defined(__amigaos4__)
+/* Under AmigaOS 4 newlib.library provides an environ. However using
+ * it doesn't give us enough control over inheritance of variables by
+ * subshells etc. so replace with custom version based on abc-shell
+ * code. */
+extern char **myenviron;
+# undef environ
+# define environ myenviron
+# endif
#endif
/* for WCOREDUMP */
# endif
#else
# ifndef memcpy
-# ifdef HAS_BCOPY
-# define memcpy(d,s,l) bcopy(s,d,l)
-# else
-# define memcpy(d,s,l) my_bcopy(s,d,l)
-# endif
+# define memcpy(d,s,l) my_bcopy(s,d,l)
# endif
#endif /* HAS_MEMCPY */
#endif /* HAS_MEMSET */
#if !defined(HAS_MEMMOVE) && !defined(memmove)
-# if defined(HAS_BCOPY) && defined(HAS_SAFE_BCOPY)
-# define memmove(d,s,l) bcopy(s,d,l)
+# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY)
+# define memmove(d,s,l) memcpy(d,s,l)
# else
-# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY)
-# define memmove(d,s,l) memcpy(d,s,l)
-# else
-# define memmove(d,s,l) my_bcopy(s,d,l)
-# endif
+# define memmove(d,s,l) my_bcopy(s,d,l)
# endif
#endif
# endif
# endif
#else
-# ifndef memcmp
-# define memcmp my_memcmp
-# endif
+# undef memcmp
+# define memcmp my_memcmp
#endif /* HAS_MEMCMP && HAS_SANE_MEMCMP */
#ifndef memzero
# define SS_IVCHAN SS$_IVCHAN
# define SS_NORMAL SS$_NORMAL
# define SS_NOPRIV SS$_NOPRIV
+# define SS_BUFFEROVF SS$_BUFFEROVF
#else
# define LIB_INVARG 0
# define RMS_DIR 0
# define SS_IVCHAN 0
# define SS_NORMAL 0
# define SS_NOPRIV 0
+# define SS_BUFFEROVF 0
#endif
#ifdef WIN32
#define ERRSV GvSVn(PL_errgv)
+/* contains inlined gv_add_by_type */
#define CLEAR_ERRSV() STMT_START { \
- if (!GvSV(PL_errgv)) { \
- sv_setpvs(GvSV(gv_add_by_type(PL_errgv, SVt_PV)), ""); \
- } else if (SvREADONLY(GvSV(PL_errgv))) { \
- SvREFCNT_dec(GvSV(PL_errgv)); \
- GvSV(PL_errgv) = newSVpvs(""); \
+ SV ** const svp = &GvSV(PL_errgv); \
+ if (!*svp) { \
+ *svp = newSVpvs(""); \
+ } else if (SvREADONLY(*svp)) { \
+ SvREFCNT_dec_NN(*svp); \
+ *svp = newSVpvs(""); \
} else { \
- SV *const errsv = GvSV(PL_errgv); \
- sv_setpvs(errsv, ""); \
+ SV *const errsv = *svp; \
+ SvPVCLEAR(errsv); \
+ SvPOK_only(errsv); \
if (SvMAGICAL(errsv)) { \
mg_free(errsv); \
} \
- SvPOK_only(errsv); \
} \
} STMT_END
* that should be true only if the snprintf()/vsnprintf() are true
* to the standard. */
-#define PERL_SNPRINTF_CHECK(len, max, api) STMT_START { if ((max) > 0 && (Size_t)len >= (max)) Perl_croak_nocontext("panic: %s buffer overflow", STRINGIFY(api)); } STMT_END
+#define PERL_SNPRINTF_CHECK(len, max, api) STMT_START { if ((max) > 0 && (Size_t)len > (max)) Perl_croak_nocontext("panic: %s buffer overflow", STRINGIFY(api)); } STMT_END
#ifdef USE_QUADMATH
# define my_snprintf Perl_my_snprintf
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
#ifdef USE_LONG_DOUBLE
-# if defined(HAS_LONG_DOUBLE) && LONG_DOUBLESIZE == DOUBLESIZE
-# define LONG_DOUBLE_EQUALS_DOUBLE
-# endif
-# if !(defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE))
-# undef USE_LONG_DOUBLE /* Ouch! */
+# if LONG_DOUBLESIZE == DOUBLESIZE
+# define LONG_DOUBLE_EQUALS_DOUBLE
+# undef USE_LONG_DOUBLE /* Ouch! */
# endif
#endif
/* Also Tru64 cc has broken NaN comparisons. */
# define NAN_COMPARE_BROKEN
#endif
+#if defined(__sgi)
+# define NAN_COMPARE_BROKEN
+#endif
#ifdef USE_LONG_DOUBLE
# ifdef I_SUNMATH
# include <sunmath.h>
# endif
-# if defined(USE_QUADMATH) && defined(I_QUADMATH)
-# include <quadmath.h>
-# endif
-# ifdef FLT128_DIG
-# define NV_DIG FLT128_DIG
-# define NV_MANT_DIG FLT128_MANT_DIG
-# define NV_MIN FLT128_MIN
-# define NV_MAX FLT128_MAX
-# define NV_MIN_EXP FLT128_MIN_EXP
-# define NV_MAX_EXP FLT128_MAX_EXP
-# define NV_EPSILON FLT128_EPSILON
-# define NV_MIN_10_EXP FLT128_MIN_10_EXP
-# define NV_MAX_10_EXP FLT128_MAX_10_EXP
-# define NV_INF HUGE_VALQ
-# define NV_NAN nanq("0")
-# elif defined(LDBL_DIG)
+# if defined(LDBL_DIG)
# define NV_DIG LDBL_DIG
# ifdef LDBL_MANT_DIG
# define NV_MANT_DIG LDBL_MANT_DIG
# endif
# endif
# endif
-# if defined(USE_QUADMATH) && defined(I_QUADMATH)
-# define Perl_acos acosq
-# define Perl_asin asinq
-# define Perl_atan atanq
-# define Perl_atan2 atan2q
-# define Perl_ceil ceilq
-# define Perl_cos cosq
-# define Perl_cosh coshq
-# define Perl_exp expq
-/* no Perl_fabs, but there's PERL_ABS */
-# define Perl_floor floorq
-# define Perl_fmod fmodq
-# define Perl_log logq
-# define Perl_log10 log10q
-# define Perl_pow powq
-# define Perl_sin sinq
-# define Perl_sinh sinhq
-# define Perl_sqrt sqrtq
-# define Perl_tan tanq
-# define Perl_tanh tanhq
-# define Perl_modf(x,y) modfq(x,y)
-# define Perl_frexp(x,y) frexpq(x,y)
-# define Perl_ldexp(x, y) ldexpq(x,y)
-# define Perl_isinf(x) isinfq(x)
-# define Perl_isnan(x) isnanq(x)
-# define Perl_isfinite(x) !(isnanq(x) || isinfq(x))
-# elif defined(HAS_SQRTL)
+# if defined(HAS_SQRTL)
# define Perl_acos acosl
# define Perl_asin asinl
# define Perl_atan atanl
# ifndef Perl_isnan
# if defined(HAS_ISNANL) && !(defined(isnan) && defined(HAS_C99))
# define Perl_isnan(x) isnanl(x)
+# elif defined(__sgi) && defined(__c99) /* XXX Configure test needed */
+# define Perl_isnan(x) isnan(x)
# endif
# endif
# ifndef Perl_isinf
# if defined(HAS_ISINFL) && !(defined(isinf) && defined(HAS_C99))
# define Perl_isinf(x) isinfl(x)
+# elif defined(__sgi) && defined(__c99) /* XXX Configure test needed */
+# define Perl_isinf(x) isinf(x)
# elif defined(LDBL_MAX) && !defined(NAN_COMPARE_BROKEN)
# define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
# endif
# ifndef Perl_isfinite
# define Perl_isfinite(x) Perl_isfinitel(x)
# endif
+#elif defined(USE_QUADMATH) && defined(I_QUADMATH)
+# include <quadmath.h>
+# define NV_DIG FLT128_DIG
+# define NV_MANT_DIG FLT128_MANT_DIG
+# define NV_MIN FLT128_MIN
+# define NV_MAX FLT128_MAX
+# define NV_MIN_EXP FLT128_MIN_EXP
+# define NV_MAX_EXP FLT128_MAX_EXP
+# define NV_EPSILON FLT128_EPSILON
+# define NV_MIN_10_EXP FLT128_MIN_10_EXP
+# define NV_MAX_10_EXP FLT128_MAX_10_EXP
+# define Perl_acos acosq
+# define Perl_asin asinq
+# define Perl_atan atanq
+# define Perl_atan2 atan2q
+# define Perl_ceil ceilq
+# define Perl_cos cosq
+# define Perl_cosh coshq
+# define Perl_exp expq
+/* no Perl_fabs, but there's PERL_ABS */
+# define Perl_floor floorq
+# define Perl_fmod fmodq
+# define Perl_log logq
+# define Perl_log10 log10q
+# define Perl_pow powq
+# define Perl_sin sinq
+# define Perl_sinh sinhq
+# define Perl_sqrt sqrtq
+# define Perl_tan tanq
+# define Perl_tanh tanhq
+# define Perl_modf(x,y) modfq(x,y)
+# define Perl_frexp(x,y) frexpq(x,y)
+# define Perl_ldexp(x, y) ldexpq(x,y)
+# define Perl_isinf(x) isinfq(x)
+# define Perl_isnan(x) isnanq(x)
+# define Perl_isfinite(x) !(isnanq(x) || isinfq(x))
+# define Perl_fp_class(x) ((x) == 0.0Q ? 0 : isinfq(x) ? 3 : isnanq(x) ? 4 : PERL_ABS(x) < FLT128_MIN ? 2 : 1)
+# define Perl_fp_class_inf(x) (Perl_fp_class(x) == 3)
+# define Perl_fp_class_nan(x) (Perl_fp_class(x) == 4)
+# define Perl_fp_class_norm(x) (Perl_fp_class(x) == 1)
+# define Perl_fp_class_denorm(x) (Perl_fp_class(x) == 2)
+# define Perl_fp_class_zero(x) (Perl_fp_class(x) == 0)
#else
# define NV_DIG DBL_DIG
# ifdef DBL_MANT_DIG
/* Solaris and IRIX have fpclass/fpclassl, but they are using
* an enum typedef, not cpp symbols, and Configure doesn't detect that.
* Define some symbols also as cpp symbols so we can detect them. */
-# if defined(__sun) || defined(__irix__) /* XXX Configure test instead */
+# if defined(__sun) || defined(__sgi) /* XXX Configure test instead */
# define FP_PINF FP_PINF
# define FP_QNAN FP_QNAN
# endif
# include <fp_class.h>
# endif
# if defined(FP_POS_INF) && defined(FP_QNAN)
-# ifdef __irix__ /* XXX Configure test instead */
+# ifdef __sgi /* XXX Configure test instead */
# ifdef USE_LONG_DOUBLE
# define Perl_fp_class(x) fp_class_l(x)
# else
typedef struct op OP;
typedef struct cop COP;
typedef struct unop UNOP;
+typedef struct unop_aux UNOP_AUX;
typedef struct binop BINOP;
typedef struct listop LISTOP;
typedef struct logop LOGOP;
typedef struct ptr_tbl PTR_TBL_t;
typedef struct clone_params CLONE_PARAMS;
-/* a pad or name pad is currently just an AV; but that might change,
+/* a pad is currently just an AV; but that might change,
* so hide the type. */
typedef struct padlist PADLIST;
typedef AV PAD;
-typedef AV PADNAMELIST;
-typedef SV PADNAME;
+typedef struct padnamelist PADNAMELIST;
+typedef struct padname PADNAME;
-/* enable PERL_NEW_COPY_ON_WRITE by default */
-#if !defined(PERL_OLD_COPY_ON_WRITE) && !defined(PERL_NEW_COPY_ON_WRITE) && !defined(PERL_NO_COW)
-# define PERL_NEW_COPY_ON_WRITE
+/* enable PERL_OP_PARENT by default */
+#if !defined(PERL_OP_PARENT) && !defined(PERL_NO_OP_PARENT)
+# define PERL_OP_PARENT
#endif
-#if defined(PERL_OLD_COPY_ON_WRITE) || defined(PERL_NEW_COPY_ON_WRITE)
-# if defined(PERL_OLD_COPY_ON_WRITE) && defined(PERL_NEW_COPY_ON_WRITE)
-# error PERL_OLD_COPY_ON_WRITE and PERL_NEW_COPY_ON_WRITE are exclusive
-# else
+/* enable PERL_COPY_ON_WRITE by default */
+#if !defined(PERL_COPY_ON_WRITE) && !defined(PERL_NO_COW)
+# define PERL_COPY_ON_WRITE
+#endif
+
+#ifdef PERL_COPY_ON_WRITE
# define PERL_ANY_COW
-# endif
#else
# define PERL_SAWAMPERSAND
#endif
#endif
#include "handy.h"
+#include "charclass_invlists.h"
#if defined(USE_LARGE_FILES) && !defined(NO_64_BIT_RAWIO)
# if LSEEKSIZE == 8 && !defined(USE_64_BIT_RAWIO)
# include "unixish.h"
#endif
+#ifdef __amigaos4__
+# include "amigaos.h"
+# undef FD_CLOEXEC /* a lie in AmigaOS */
+#endif
+
/* NSIG logic from Configure --> */
/* Strange style to avoid deeply-nested #if/#else/#endif */
#ifndef NSIG
signal(SIGFPE, SIG_IGN); \
} STMT_END
#endif
+/* In IRIX the default for Flush to Zero bit is true,
+ * which means that results going below the minimum of normal
+ * floating points go to zero, instead of going denormal/subnormal.
+ * This is unlike almost any other system running Perl, so let's clear it.
+ * [perl #123767] IRIX64 blead (ddce084a) opbasic/arith.t failure, originally
+ * [perl #120426] small numbers shouldn't round to zero if they have extra floating digits
+ *
+ * XXX The flush-to-zero behaviour should be a Configure scan.
+ * To change the behaviour usually requires some system-specific
+ * incantation, though, like the below. */
+#ifdef __sgi
+# include <sys/fpu.h>
+# define PERL_SYS_FPU_INIT \
+ STMT_START { \
+ union fpc_csr csr; \
+ csr.fc_word = get_fpc_csr(); \
+ csr.fc_struct.flush = 0; \
+ set_fpc_csr(csr.fc_word); \
+ } STMT_END
+#endif
#ifndef PERL_SYS_FPU_INIT
# define PERL_SYS_FPU_INIT NOOP
* May make sense to have threads after "*ish.h" anyway
*/
+/* clang Thread Safety Analysis/Annotations/Attributes
+ * http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
+ *
+ * Available since clang 3.6-ish (appeared in 3.4, but shaky still in 3.5).
+ * Apple XCode hijacks __clang_major__ and __clang_minor__
+ * (6.1 means really clang 3.6), so needs extra hijinks
+ * (could probably also test the contents of __apple_build_version__).
+ */
+#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) || \
+ (__clang_major__ >= 4))) || \
+ (defined(__apple_build_version__) && \
+ ((__clang_major__ == 6 && __clang_minor__ >= 1) || \
+ (__clang_major__ >= 7))))
+# define PERL_TSA__(x) __attribute__((x))
+# define PERL_TSA_ACTIVE
+#else
+# define PERL_TSA__(x) /* No TSA, make TSA attributes no-ops. */
+# undef PERL_TSA_ACTIVE
+#endif
+
+/* PERL_TSA_CAPABILITY() is used to annotate typedefs.
+ * typedef old_type PERL_TSA_CAPABILITY("mutex") new_type;
+ */
+#define PERL_TSA_CAPABILITY(x) \
+ PERL_TSA__(capability(x))
+
+/* In the below examples the mutex must be lexically visible, usually
+ * either as global variables, or as function arguments. */
+
+/* PERL_TSA_GUARDED_BY() is used to annotate global variables.
+ *
+ * Foo foo PERL_TSA_GUARDED_BY(mutex);
+ */
+#define PERL_TSA_GUARDED_BY(x) \
+ PERL_TSA__(guarded_by(x))
+
+/* PERL_TSA_PT_GUARDED_BY() is used to annotate global pointers.
+ * The data _behind_ the pointer is guarded.
+ *
+ * Foo* ptr PERL_TSA_PT_GUARDED_BY(mutex);
+ */
+#define PERL_TSA_PT_GUARDED_BY(x) \
+ PERL_TSA__(pt_guarded_by(x))
+
+/* PERL_TSA_REQUIRES() is used to annotate functions.
+ * The caller MUST hold the resource when calling the function.
+ *
+ * void Foo() PERL_TSA_REQUIRES(mutex);
+ */
+#define PERL_TSA_REQUIRES(x) \
+ PERL_TSA__(requires_capability(x))
+
+/* PERL_TSA_EXCLUDES() is used to annotate functions.
+ * The caller MUST NOT hold resource when calling the function.
+ *
+ * EXCLUDES should be used when the function first acquires
+ * the resource and then releases it. Use to avoid deadlock.
+ *
+ * void Foo() PERL_TSA_EXCLUDES(mutex);
+ */
+#define PERL_TSA_EXCLUDES(x) \
+ PERL_TSA__(locks_excluded(x))
+
+/* PERL_TSA_ACQUIRE() is used to annotate functions.
+ * The caller MUST NOT hold the resource when calling the function,
+ * and the function will acquire the resource.
+ *
+ * void Foo() PERL_TSA_ACQUIRE(mutex);
+ */
+#define PERL_TSA_ACQUIRE(x) \
+ PERL_TSA__(acquire_capability(x))
+
+/* PERL_TSA_RELEASE() is used to annotate functions.
+ * The caller MUST hold the resource when calling the function,
+ * and the function will release the resource.
+ *
+ * void Foo() PERL_TSA_RELEASE(mutex);
+ */
+#define PERL_TSA_RELEASE(x) \
+ PERL_TSA__(release_capability(x))
+
+/* PERL_TSA_NO_TSA is used to annotate functions.
+ * Used when being intentionally unsafe, or when the code is too
+ * complicated for the analysis. Use sparingly.
+ *
+ * void Foo() PERL_TSA_NO_TSA;
+ */
+#define PERL_TSA_NO_TSA \
+ PERL_TSA__(no_thread_safety_analysis)
+
+/* There are more annotations/attributes available, see the clang
+ * documentation for details. */
+
#if defined(USE_ITHREADS)
# ifdef NETWARE
# include <nw5thread.h>
# include <pthread.h>
# endif
typedef pthread_t perl_os_thread;
-typedef pthread_mutex_t perl_mutex;
+typedef pthread_mutex_t PERL_TSA_CAPABILITY("mutex") perl_mutex;
typedef pthread_cond_t perl_cond;
typedef pthread_key_t perl_key;
# endif /* I_MACH_CTHREADS */
# endif /* NETWARE */
#endif /* USE_ITHREADS */
+#ifdef PERL_TSA_ACTIVE
+/* Since most pthread mutex interfaces have not been annotated, we
+ * need to have these wrappers. The NO_TSA annotation is quite ugly
+ * but it cannot be avoided in plain C, unlike in C++, where one could
+ * e.g. use ACQUIRE() with no arg on a mutex lock method.
+ *
+ * The bodies of these wrappers are in util.c
+ *
+ * TODO: however, some platforms are starting to get these clang
+ * thread safety annotations for pthreads, for example FreeBSD.
+ * Do we need a way to a bypass these wrappers? */
+EXTERN_C int perl_tsa_mutex_lock(perl_mutex* mutex)
+ PERL_TSA_ACQUIRE(*mutex)
+ PERL_TSA_NO_TSA;
+EXTERN_C int perl_tsa_mutex_unlock(perl_mutex* mutex)
+ PERL_TSA_RELEASE(*mutex)
+ PERL_TSA_NO_TSA;
+#endif
+
#if defined(WIN32)
# include "win32.h"
#endif
vaxc$errno = PL_statusvalue_vms = MY_POSIX_EXIT ? \
(C_FAC_POSIX | (1 << 3) | STS$K_ERROR | STS$M_INHIB_MSG) : SS$_ABORT)
+#elif defined(__amigaos4__)
+ /* A somewhat experimental attempt to simulate posix return code values */
+# define STATUS_NATIVE PL_statusvalue_posix
+# define STATUS_NATIVE_CHILD_SET(n) \
+ STMT_START { \
+ PL_statusvalue_posix = (n); \
+ if (PL_statusvalue_posix < 0) { \
+ PL_statusvalue = -1; \
+ } \
+ else { \
+ PL_statusvalue = n << 8; \
+ } \
+ } STMT_END
+# define STATUS_UNIX_SET(n) \
+ STMT_START { \
+ PL_statusvalue = (n); \
+ if (PL_statusvalue != -1) \
+ PL_statusvalue &= 0xFFFF; \
+ } STMT_END
+# define STATUS_UNIX_EXIT_SET(n) STATUS_UNIX_SET(n)
+# define STATUS_EXIT_SET(n) STATUS_UNIX_SET(n)
+# define STATUS_CURRENT STATUS_UNIX
+# define STATUS_EXIT STATUS_UNIX
+# define STATUS_ALL_SUCCESS (PL_statusvalue = 0, PL_statusvalue_posix = 0)
+# define STATUS_ALL_FAILURE (PL_statusvalue = 1, PL_statusvalue_posix = 1)
+
#else
# define STATUS_NATIVE PL_statusvalue_posix
# if defined(WCOREDUMP)
#endif
#define UTF8fARG(u,l,p) (int)cBOOL(u), (UV)(l), (void*)(p)
+#define PNf UTF8f
+#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 */
# undef UVf
# define __attribute__warn_unused_result__
#endif
-#if defined(DEBUGGING) && defined(I_ASSERT)
+#ifdef I_ASSERT
+# if !defined(DEBUGGING) && !defined(NDEBUG)
+# define NDEBUG 1
+# endif
# include <assert.h>
#endif
appropriate to call return. In either case, include the lint directive.
*/
#ifdef HASATTRIBUTE_NORETURN
-# define NORETURN_FUNCTION_END NOT_REACHED; /* NOTREACHED */
+# define NORETURN_FUNCTION_END NOT_REACHED;
#else
-# define NORETURN_FUNCTION_END NOT_REACHED; /* NOTREACHED */ return 0
+# define NORETURN_FUNCTION_END NOT_REACHED; return 0
#endif
/* Some OS warn on NULL format to printf */
/* placeholder */
#endif
+/* STATIC_ASSERT_DECL/STATIC_ASSERT_STMT are like assert(), but for compile
+ time invariants. That is, their argument must be a constant expression that
+ can be verified by the compiler. This expression can contain anything that's
+ known to the compiler, e.g. #define constants, enums, or sizeof (...). If
+ the expression evaluates to 0, compilation fails.
+ Because they generate no runtime code (i.e. their use is "free"), they're
+ always active, even under non-DEBUGGING builds.
+ STATIC_ASSERT_DECL expands to a declaration and is suitable for use at
+ file scope (outside of any function).
+ STATIC_ASSERT_STMT expands to a statement and is suitable for use inside a
+ function.
+*/
+#if (defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L)) && (!defined(__IBMC__) || __IBMC__ >= 1210)
+/* static_assert is a macro defined in <assert.h> in C11 or a compiler
+ builtin in C++11. But IBM XL C V11 does not support _Static_assert, no
+ matter what <assert.h> says.
+*/
+# define STATIC_ASSERT_DECL(COND) static_assert(COND, #COND)
+#else
+/* We use a bit-field instead of an array because gcc accepts
+ 'typedef char x[n]' where n is not a compile-time constant.
+ We want to enforce constantness.
+*/
+# define STATIC_ASSERT_2(COND, SUFFIX) \
+ typedef struct { \
+ unsigned int _static_assertion_failed_##SUFFIX : (COND) ? 1 : -1; \
+ } _static_assertion_failed_##SUFFIX PERL_UNUSED_DECL
+# define STATIC_ASSERT_1(COND, SUFFIX) STATIC_ASSERT_2(COND, SUFFIX)
+# define STATIC_ASSERT_DECL(COND) STATIC_ASSERT_1(COND, __LINE__)
+#endif
+/* We need this wrapper even in C11 because 'case X: static_assert(...);' is an
+ error (static_assert is a declaration, and only statements can have labels).
+*/
+#define STATIC_ASSERT_STMT(COND) do { STATIC_ASSERT_DECL(COND); } while (0)
#ifndef __has_builtin
# define __has_builtin(x) 0 /* not a clang style compiler */
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 atleast X times. ASSUME is based off MSVC's __assume
+ that a loop will run at least X times. ASSUME is based off MSVC's __assume
intrinsic function, see its documents for more details.
*/
#ifndef DEBUGGING
# if __has_builtin(__builtin_unreachable) \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 5) /* 4.5 -> */
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 4) /* 4.5 -> */
# define ASSUME(x) ((x) ? (void) 0 : __builtin_unreachable())
# elif defined(_MSC_VER)
# define ASSUME(x) __assume(x)
# define ASSUME(x) assert(x)
#endif
-#define NOT_REACHED ASSUME(0)
+#if defined(__sun) /* ASSUME() generates warnings on Solaris */
+# define NOT_REACHED
+#else
+# define NOT_REACHED ASSUME(0)
+#endif
/* Some unistd.h's give a prototype for pause() even though
HAS_PAUSE ends up undefined. This causes the #define
# define USEMYBINMODE /**/
# include <io.h> /* for setmode() prototype */
# define my_binmode(fp, iotype, mode) \
- (PerlLIO_setmode(fileno(fp), mode) != -1 ? TRUE : FALSE)
+ cBOOL(PerlLIO_setmode(fileno(fp), mode) != -1)
#endif
#ifdef __CYGWIN__
#else
union any {
void* any_ptr;
+ SV* any_sv;
+ SV** any_svp;
+ GV* any_gv;
+ AV* any_av;
+ HV* any_hv;
+ OP* any_op;
+ char* any_pv;
+ char** any_pvp;
I32 any_i32;
U32 any_u32;
IV any_iv;
#endif /* threading */
#endif /* AIX */
+#ifndef PERL_CALLCONV
+# ifdef __cplusplus
+# define PERL_CALLCONV extern "C"
+# else
+# define PERL_CALLCONV
+# endif
+#endif
+#ifndef PERL_CALLCONV_NO_RET
+# define PERL_CALLCONV_NO_RET PERL_CALLCONV
+#endif
+
+/* PERL_STATIC_NO_RET is supposed to be equivalent to STATIC on builds that
+ dont have a noreturn as a declaration specifier
+*/
+#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
+*/
+#ifndef PERL_STATIC_INLINE_NO_RET
+# define PERL_STATIC_INLINE_NO_RET PERL_STATIC_INLINE
+#endif
+
#if !defined(OS2)
# include "iperlsys.h"
#endif
#endif
/* [perl #22371] Algorimic Complexity Attack on Perl 5.6.1, 5.8.0.
- * Note that the USE_HASH_SEED and USE_HASH_SEED_EXPLICIT are *NOT*
- * defined by Configure, despite their names being similar to the
- * other defines like USE_ITHREADS. Configure in fact knows nothing
- * about the randomised hashes. Therefore to enable/disable the hash
- * randomisation defines use the Configure -Accflags=... instead. */
-#if !defined(NO_HASH_SEED) && !defined(USE_HASH_SEED) && !defined(USE_HASH_SEED_EXPLICIT)
+ * Note that the USE_HASH_SEED and similar defines are *NOT* defined by
+ * Configure, despite their names being similar to other defines like
+ * USE_ITHREADS. Configure in fact knows nothing about the randomised
+ * hashes. Therefore to enable/disable the hash randomisation defines
+ * use the Configure -Accflags=... instead. */
+#if !defined(NO_HASH_SEED) && !defined(USE_HASH_SEED)
# define USE_HASH_SEED
#endif
-/* Win32 defines a type 'WORD' in windef.h. This conflicts with the enumerator
- * 'WORD' defined in perly.h. The yytokentype enum is only a debugging aid, so
- * it's not really needed.
- */
-#if defined(WIN32)
-# define YYTOKENTYPE
-#endif
#include "perly.h"
#undef _XPVMG_HEAD
#undef _XPVCV_COMMON
-typedef struct _sublex_info SUBLEXINFO;
-struct _sublex_info {
- U8 super_state; /* lexer state to save */
- U16 sub_inwhat; /* "lex_inwhat" to use */
- OP *sub_op; /* "lex_op" to use */
- SV *repl; /* replacement of s/// or y/// */
-};
-
#include "parser.h"
typedef struct magic_state MGS; /* struct magic_state defined in mg.c */
#define DEBUG_u_FLAG 0x00000800 /* 2048 */
/* U is reserved for Unofficial, exploratory hacking */
#define DEBUG_U_FLAG 0x00001000 /* 4096 */
-#define DEBUG_H_FLAG 0x00002000 /* 8192 */
+/* spare 8192 */
#define DEBUG_X_FLAG 0x00004000 /* 16384 */
#define DEBUG_D_FLAG 0x00008000 /* 32768 */
#define DEBUG_S_FLAG 0x00010000 /* 65536 */
#define DEBUG_M_FLAG 0x01000000 /*16777216*/
#define DEBUG_B_FLAG 0x02000000 /*33554432*/
#define DEBUG_L_FLAG 0x04000000 /*67108864*/
-#define DEBUG_MASK 0x07FFEFFF /* mask of all the standard flags */
+#define DEBUG_i_FLAG 0x08000000 /*134217728*/
+#define DEBUG_MASK 0x0FFFEFFF /* mask of all the standard flags */
#define DEBUG_DB_RECURSE_FLAG 0x40000000
-#define DEBUG_TOP_FLAG 0x80000000 /* XXX what's this for ??? Signal
- that something was done? */
-
-# define DEBUG_p_TEST_ (PL_debug & DEBUG_p_FLAG)
-# define DEBUG_s_TEST_ (PL_debug & DEBUG_s_FLAG)
-# define DEBUG_l_TEST_ (PL_debug & DEBUG_l_FLAG)
-# define DEBUG_t_TEST_ (PL_debug & DEBUG_t_FLAG)
-# define DEBUG_o_TEST_ (PL_debug & DEBUG_o_FLAG)
-# define DEBUG_c_TEST_ (PL_debug & DEBUG_c_FLAG)
-# define DEBUG_P_TEST_ (PL_debug & DEBUG_P_FLAG)
-# define DEBUG_m_TEST_ (PL_debug & DEBUG_m_FLAG)
-# define DEBUG_f_TEST_ (PL_debug & DEBUG_f_FLAG)
-# define DEBUG_r_TEST_ (PL_debug & DEBUG_r_FLAG)
-# define DEBUG_x_TEST_ (PL_debug & DEBUG_x_FLAG)
-# define DEBUG_u_TEST_ (PL_debug & DEBUG_u_FLAG)
-# define DEBUG_U_TEST_ (PL_debug & DEBUG_U_FLAG)
-# define DEBUG_H_TEST_ (PL_debug & DEBUG_H_FLAG)
-# define DEBUG_X_TEST_ (PL_debug & DEBUG_X_FLAG)
-# define DEBUG_D_TEST_ (PL_debug & DEBUG_D_FLAG)
-# define DEBUG_S_TEST_ (PL_debug & DEBUG_S_FLAG)
-# define DEBUG_T_TEST_ (PL_debug & DEBUG_T_FLAG)
-# define DEBUG_R_TEST_ (PL_debug & DEBUG_R_FLAG)
-# define DEBUG_J_TEST_ (PL_debug & DEBUG_J_FLAG)
-# define DEBUG_v_TEST_ (PL_debug & DEBUG_v_FLAG)
-# define DEBUG_C_TEST_ (PL_debug & DEBUG_C_FLAG)
-# define DEBUG_A_TEST_ (PL_debug & DEBUG_A_FLAG)
-# define DEBUG_q_TEST_ (PL_debug & DEBUG_q_FLAG)
-# define DEBUG_M_TEST_ (PL_debug & DEBUG_M_FLAG)
-# define DEBUG_B_TEST_ (PL_debug & DEBUG_B_FLAG)
-# define DEBUG_L_TEST_ (PL_debug & DEBUG_L_FLAG)
+#define DEBUG_TOP_FLAG 0x80000000 /* -D was given --> PL_debug |= FLAG */
+
+# 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)
+# define DEBUG_t_TEST_ UNLIKELY(PL_debug & DEBUG_t_FLAG)
+# define DEBUG_o_TEST_ UNLIKELY(PL_debug & DEBUG_o_FLAG)
+# define DEBUG_c_TEST_ UNLIKELY(PL_debug & DEBUG_c_FLAG)
+# define DEBUG_P_TEST_ UNLIKELY(PL_debug & DEBUG_P_FLAG)
+# define DEBUG_m_TEST_ UNLIKELY(PL_debug & DEBUG_m_FLAG)
+# define DEBUG_f_TEST_ UNLIKELY(PL_debug & DEBUG_f_FLAG)
+# define DEBUG_r_TEST_ UNLIKELY(PL_debug & DEBUG_r_FLAG)
+# define DEBUG_x_TEST_ UNLIKELY(PL_debug & DEBUG_x_FLAG)
+# define DEBUG_u_TEST_ UNLIKELY(PL_debug & DEBUG_u_FLAG)
+# define DEBUG_U_TEST_ UNLIKELY(PL_debug & DEBUG_U_FLAG)
+# define DEBUG_X_TEST_ UNLIKELY(PL_debug & DEBUG_X_FLAG)
+# define DEBUG_D_TEST_ UNLIKELY(PL_debug & DEBUG_D_FLAG)
+# define DEBUG_S_TEST_ UNLIKELY(PL_debug & DEBUG_S_FLAG)
+# define DEBUG_T_TEST_ UNLIKELY(PL_debug & DEBUG_T_FLAG)
+# define DEBUG_R_TEST_ UNLIKELY(PL_debug & DEBUG_R_FLAG)
+# define DEBUG_J_TEST_ UNLIKELY(PL_debug & DEBUG_J_FLAG)
+# define DEBUG_v_TEST_ UNLIKELY(PL_debug & DEBUG_v_FLAG)
+# define DEBUG_C_TEST_ UNLIKELY(PL_debug & DEBUG_C_FLAG)
+# define DEBUG_A_TEST_ UNLIKELY(PL_debug & DEBUG_A_FLAG)
+# define DEBUG_q_TEST_ UNLIKELY(PL_debug & DEBUG_q_FLAG)
+# define DEBUG_M_TEST_ UNLIKELY(PL_debug & DEBUG_M_FLAG)
+# define DEBUG_B_TEST_ UNLIKELY(PL_debug & DEBUG_B_FLAG)
+# define DEBUG_L_TEST_ UNLIKELY(PL_debug & DEBUG_L_FLAG)
+# define DEBUG_i_TEST_ UNLIKELY(PL_debug & DEBUG_i_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_)
#ifdef DEBUGGING
# define DEBUG_x_TEST DEBUG_x_TEST_
# define DEBUG_u_TEST DEBUG_u_TEST_
# define DEBUG_U_TEST DEBUG_U_TEST_
-# define DEBUG_H_TEST DEBUG_H_TEST_
# define DEBUG_X_TEST DEBUG_X_TEST_
# define DEBUG_D_TEST DEBUG_D_TEST_
# define DEBUG_S_TEST DEBUG_S_TEST_
# define DEBUG_M_TEST DEBUG_M_TEST_
# define DEBUG_B_TEST DEBUG_B_TEST_
# define DEBUG_L_TEST DEBUG_L_TEST_
+# define DEBUG_i_TEST DEBUG_i_TEST_
# define DEBUG_Xv_TEST DEBUG_Xv_TEST_
# define DEBUG_Uv_TEST DEBUG_Uv_TEST_
# define DEBUG_Pv_TEST DEBUG_Pv_TEST_
+# define DEBUG_Lv_TEST DEBUG_Lv_TEST_
# define PERL_DEB(a) a
+# define PERL_DEB2(a,b) a
# define PERL_DEBUG(a) if (PL_debug) a
# define DEBUG_p(a) if (DEBUG_p_TEST) a
# define DEBUG_s(a) if (DEBUG_s_TEST) a
/* Temporarily turn off memory debugging in case the a
* does memory allocation, either directly or indirectly. */
# define DEBUG_m(a) \
- STMT_START { \
- if (PERL_GET_INTERP) { dTHX; if (DEBUG_m_TEST) {PL_debug&=~DEBUG_m_FLAG; a; PL_debug|=DEBUG_m_FLAG;} } \
+ STMT_START { \
+ if (PERL_GET_INTERP) { \
+ dTHX; \
+ if (DEBUG_m_TEST) { \
+ PL_debug &= ~DEBUG_m_FLAG; \
+ a; \
+ PL_debug |= DEBUG_m_FLAG; \
+ } \
+ } \
} STMT_END
-# define DEBUG__(t, a) \
- STMT_START { \
- if (t) STMT_START {a;} STMT_END; \
- } STMT_END
+# define DEBUG__(t, a) \
+ STMT_START { \
+ if (t) STMT_START {a;} STMT_END; \
+ } STMT_END
# define DEBUG_f(a) DEBUG__(DEBUG_f_TEST, a)
+
#ifndef PERL_EXT_RE_BUILD
# define DEBUG_r(a) DEBUG__(DEBUG_r_TEST, a)
#else
# define DEBUG_r(a) STMT_START {a;} STMT_END
#endif /* PERL_EXT_RE_BUILD */
+
# define DEBUG_x(a) DEBUG__(DEBUG_x_TEST, a)
# define DEBUG_u(a) DEBUG__(DEBUG_u_TEST, a)
# define DEBUG_U(a) DEBUG__(DEBUG_U_TEST, a)
-# define DEBUG_H(a) DEBUG__(DEBUG_H_TEST, a)
# define DEBUG_X(a) DEBUG__(DEBUG_X_TEST, a)
# define DEBUG_D(a) DEBUG__(DEBUG_D_TEST, a)
# define DEBUG_Xv(a) DEBUG__(DEBUG_Xv_TEST, a)
# define DEBUG_Uv(a) DEBUG__(DEBUG_Uv_TEST, a)
# define DEBUG_Pv(a) DEBUG__(DEBUG_Pv_TEST, a)
+# define DEBUG_Lv(a) DEBUG__(DEBUG_Lv_TEST, a)
# define DEBUG_S(a) DEBUG__(DEBUG_S_TEST, a)
# define DEBUG_T(a) DEBUG__(DEBUG_T_TEST, a)
# define DEBUG_M(a) DEBUG__(DEBUG_M_TEST, a)
# define DEBUG_B(a) DEBUG__(DEBUG_B_TEST, a)
# define DEBUG_L(a) DEBUG__(DEBUG_L_TEST, a)
+# define DEBUG_i(a) DEBUG__(DEBUG_i_TEST, a)
#else /* DEBUGGING */
# define DEBUG_x_TEST (0)
# define DEBUG_u_TEST (0)
# define DEBUG_U_TEST (0)
-# define DEBUG_H_TEST (0)
# define DEBUG_X_TEST (0)
# define DEBUG_D_TEST (0)
# define DEBUG_S_TEST (0)
# define DEBUG_M_TEST (0)
# define DEBUG_B_TEST (0)
# define DEBUG_L_TEST (0)
+# define DEBUG_i_TEST (0)
# define DEBUG_Xv_TEST (0)
# define DEBUG_Uv_TEST (0)
# define DEBUG_Pv_TEST (0)
+# define DEBUG_Lv_TEST (0)
# define PERL_DEB(a)
+# define PERL_DEB2(a,b) b
# define PERL_DEBUG(a)
# define DEBUG_p(a)
# define DEBUG_s(a)
# define DEBUG_x(a)
# define DEBUG_u(a)
# define DEBUG_U(a)
-# define DEBUG_H(a)
# define DEBUG_X(a)
# define DEBUG_D(a)
# define DEBUG_S(a)
# define DEBUG_M(a)
# define DEBUG_B(a)
# define DEBUG_L(a)
+# define DEBUG_i(a)
# define DEBUG_Xv(a)
# define DEBUG_Uv(a)
# define DEBUG_Pv(a)
+# define DEBUG_Lv(a)
#endif /* DEBUGGING */
/* Keep the old croak based assert for those who want it, and as a fallback if
the platform is so heretically non-ANSI that it can't assert. */
-#define Perl_assert(what) PERL_DEB( \
+#define Perl_assert(what) PERL_DEB2( \
((what) ? ((void) 0) : \
(Perl_croak_nocontext("Assertion %s failed: file \"" __FILE__ \
"\", line %d", STRINGIFY(what), __LINE__), \
- (void) 0)))
+ (void) 0)), ((void)0))
/* assert() gets defined if DEBUGGING (and I_ASSERT).
* If no DEBUGGING, the <assert.h> has not been included. */
END_EXTERN_C
#endif
-#ifdef WIN32
-# if !defined(NV_INF) && defined(HUGE_VAL)
-# define NV_INF HUGE_VAL
-# endif
-/* For WIN32 the best NV_NAN is the __PL_nan_u trick, see below.
- * There is no supported way of getting the NAN across all the crts. */
-#endif
-
-/* If you are thinking of using HUGE_VAL for infinity, or using
- * <math.h> functions to generate NV_INF (e.g. exp(1e9), log(-1.0)),
- * stop. Neither will work portably: HUGE_VAL can be just DBL_MAX,
- * and the math functions might be just generating DBL_MAX, or even
- * zero. */
-
-#if !defined(NV_INF) && defined(USE_LONG_DOUBLE)
-# if !defined(NV_INF) && defined(LDBL_INFINITY)
-# define NV_INF LDBL_INFINITY
-# endif
-# if !defined(NV_INF) && defined(INFINITYL)
-# define NV_INF INFINITYL
-# endif
-#endif
-#if !defined(NV_INF) && defined(DBL_INFINITY)
-# define NV_INF (NV)DBL_INFINITY
-#endif
-#if !defined(NV_INF) && defined(INFINITY)
-# define NV_INF (NV)INFINITY
-#endif
-#if !defined(NV_INF) && defined(INF)
-# define NV_INF (NV)INF
-#endif
-#if !defined(NV_INF)
-# if INTSIZE == 4
-/* At this point we assume the IEEE 754 floating point (and of course,
- * we also assume a floating point format that can encode an infinity).
- * We will coerce an int32 (which will encode the infinity) into
- * a 32-bit float, which will then be cast into NV.
- *
- * Note that we intentionally use a float and 32-bit int, instead of
- * shifting a small integer into a full IV, and from that into a full
- * NV, because:
- *
- * (1) an IV might not be wide enough to cover all the bits of an NV.
- * (2) the exponent part (including the infinity and nan bits) of a NV
- * might be wider than just 16 bits.
- *
- * Below the NV_NAN logic has similar __PL_nan_u fallback, the only
- * difference being the int32 constant being coerced. */
-# define __PL_inf_float_int32 0x7F800000
-static const union { unsigned int __i; float __f; } __PL_inf_u =
- { __PL_inf_float_int32 };
-# define NV_INF ((NV)(__PL_inf_u.__f))
-# endif
-#endif
-#if !defined(NV_INF)
-# define NV_INF ((NV)1.0/0.0) /* Some compilers will warn. */
-#endif
-
-#if !defined(NV_NAN) && defined(USE_LONG_DOUBLE)
-# if !defined(NV_NAN) && defined(LDBL_NAN)
-# define NV_NAN LDBL_NAN
-# endif
-# if !defined(NV_NAN) && defined(NANL)
-# define NV_NAN NANL
-# endif
-# if !defined(NV_NAN) && defined(LDBL_QNAN)
-# define NV_NAN LDBL_QNAN
-# endif
-# if !defined(NV_NAN) && defined(LDBL_SNAN)
-# define NV_NAN LDBL_SNAN
-# endif
-#endif
-#if !defined(NV_NAN) && defined(DBL_NAN)
-# define NV_NAN (NV)DBL_NAN
-#endif
-#if !defined(NV_NAN) && defined(DBL_QNAN)
-# define NV_NAN (NV)DBL_QNAN
-#endif
-#if !defined(NV_NAN) && defined(DBL_SNAN)
-# define NV_NAN (NV)DBL_SNAN
-#endif
-#if !defined(NV_NAN) && defined(NAN)
-# define NV_NAN (NV)NAN
-#endif
-#if !defined(NV_NAN) && defined(QNAN)
-# define NV_NAN (NV)QNAN
-#endif
-#if !defined(NV_NAN) && defined(SNAN)
-# define NV_NAN (NV)SNAN
-#endif
-#if !defined(NV_NAN)
-# if INTSIZE == 4
-/* See the discussion near __PL_inf_u. */
-# define __PL_nan_float_int32 0x7FC00000
-static const union { unsigned int __i; float __f; } __PL_nan_u =
- { __PL_nan_float_int32 };
-# define NV_NAN ((NV)(__PL_nan_u.__f))
-# endif
-#endif
-#if !defined(NV_NAN)
-# define NV_NAN ((NV)0.0/0.0) /* Some compilers will warn. */
-#endif
-/* Do NOT try doing NV_NAN based on NV_INF and trying (NV_INF-NV_INF).
- * Though IEEE-754-logically correct, some compilers (like Visual C 2003)
- * falsely misoptimize that to zero (x-x is zero, right?) */
-
#ifndef __cplusplus
# if !defined(WIN32) && !defined(VMS)
#ifndef crypt
INIT("Unsuccessful %s on filename containing newline");
EXTCONST char PL_no_wrongref[]
INIT("Can't use %s ref as %s ref");
-/* The core no longer needs these here. If you require the string constant,
+/* The core no longer needs this here. If you require the string constant,
please inline a copy into your own code. */
EXTCONST char PL_no_symref[] __attribute__deprecated__
INIT("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use");
-EXTCONST char PL_no_symref_sv[] __attribute__deprecated__
- INIT("Can't use string (\"%" SVf32 "\") as %s ref while \"strict refs\" in use");
+EXTCONST char PL_no_symref_sv[]
+ INIT("Can't use string (\"%" SVf32 "\"%s) as %s ref while \"strict refs\" in use");
+
EXTCONST char PL_no_usym[]
INIT("Can't use an undefined value as %s reference");
EXTCONST char PL_no_aelem[]
INIT("1");
EXTCONST char PL_No[]
INIT("");
+EXTCONST char PL_Zero[]
+ INIT("0");
EXTCONST char PL_hexdigit[]
INIT("0123456789abcdef0123456789ABCDEF");
EXTCONST char PL_uuemap[65]
INIT("`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
+/* a special string address whose value is "isa", but which perl knows
+ * to treat as if it were really "DOES" when printing the method name in
+ * the "Can't call method '%s'" error message */
+EXTCONST char PL_isa_DOES[]
+ INIT("isa");
+
#ifdef DOINIT
EXTCONST char PL_uudmap[256] =
# ifdef PERL_MICRO
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, 255 /*sharp s*/,
+ 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)
+ 255 /*sharp s*/,
+#else /* uc() is itself in early unicode */
+ 223,
+#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,
"WHEN",
"BLOCK",
"GIVEN",
- "LOOP_FOR",
- "LOOP_PLAIN",
+ "LOOP_ARY",
"LOOP_LAZYSV",
"LOOP_LAZYIV",
+ "LOOP_LIST",
+ "LOOP_PLAIN",
"SUB",
"FORMAT",
"EVAL",
/* These are all the compile time options that affect binary compatibility.
Other compile time options that are binary compatible are in perl.c
- Both are combined for the output of perl -V
+ (in S_Internals_V()). Both are combined for the output of perl -V
However, this string will be embedded in any shared perl library, which will
allow us add a comparison check in perlmain.c in the near future. */
#ifdef DOINIT
# ifdef PERL_NEED_TIMESBASE
" PERL_NEED_TIMESBASE"
# endif
-# ifdef PERL_OLD_COPY_ON_WRITE
- " PERL_OLD_COPY_ON_WRITE"
-# endif
# ifdef PERL_POISON
" PERL_POISON"
# endif
#ifndef PERL_SET_PHASE
# define PERL_SET_PHASE(new_phase) \
- PHASE_CHANGE_PROBE(PL_phase_names[new_phase], PL_phase_names[PL_phase]); \
+ PERL_DTRACE_PROBE_PHASE(new_phase); \
PL_phase = new_phase;
#endif
/* Do not use this macro. It only exists for extensions that rely on PL_dirty
* instead of using the newer PL_phase, which provides everything PL_dirty
* provided, and more. */
-# define PL_dirty (PL_phase == PERL_PHASE_DESTRUCT)
+# define PL_dirty cBOOL(PL_phase == PERL_PHASE_DESTRUCT)
# define PL_amagic_generation PL_na
+# define PL_encoding ((SV *)NULL)
#endif /* !PERL_CORE */
#define PL_hints PL_compiling.cop_hints
+#define PL_maxo MAXO
END_EXTERN_C
/* update exp_name[] in toke.c if adding to this enum */
} expectation;
+#define KEY_sigvar 0xFFFF /* fake keyword representing a signature var */
+
/* Hints are now stored in a dedicated U32, so the bottom 8 bits are no longer
special and there is no need for HINT_PRIVATE_MASK for COPs
However, bitops store HINT_INTEGER in their op_private.
#define HINT_FEATURE_MASK 0x1c000000 /* 3 bits for feature bundles */
- /* Note: Used for NATIVE_HINTS, currently
- defined by vms/vmsish.h:
+ /* Note: Used for HINT_M_VMSISH_*,
+ currently defined by vms/vmsish.h:
0x40000000
0x80000000
*/
(SAWAMPERSAND_LEFT|SAWAMPERSAND_MIDDLE|SAWAMPERSAND_RIGHT)
#endif
+/* Used for debugvar magic */
+#define DBVARMG_SINGLE 0
+#define DBVARMG_TRACE 1
+#define DBVARMG_SIGNAL 2
+#define DBVARMG_COUNT 3
+
+#define PL_DBsingle_iv (PL_DBcontrol[DBVARMG_SINGLE])
+#define PL_DBtrace_iv (PL_DBcontrol[DBVARMG_TRACE])
+#define PL_DBsignal_iv (PL_DBcontrol[DBVARMG_SIGNAL])
+
/* Various states of the input record separator SV (rs) */
#define RsSNARF(sv) (! SvOK(sv))
#define RsSIMPLE(sv) (SvOK(sv) && (! SvPOK(sv) || SvCUR(sv)))
#include "thread.h"
#include "pp.h"
-#ifndef PERL_CALLCONV
-# ifdef __cplusplus
-# define PERL_CALLCONV extern "C"
-# else
-# define PERL_CALLCONV
-# endif
-#endif
-#ifndef PERL_CALLCONV_NO_RET
-# define PERL_CALLCONV_NO_RET PERL_CALLCONV
-#endif
-
-/* PERL_STATIC_NO_RET is supposed to be equivalent to STATIC on builds that
- dont have a noreturn as a declaration specifier
-*/
-#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
-*/
-#ifndef PERL_STATIC_INLINE_NO_RET
-# define PERL_STATIC_INLINE_NO_RET PERL_STATIC_INLINE
-#endif
-
-
#undef PERL_CKDEF
#undef PERL_PPDEF
#define PERL_CKDEF(s) PERL_CALLCONV OP *s (pTHX_ OP *o);
# include "malloc_ctl.h"
#endif
+/*
+ * This provides a layer of functions and macros to ensure extensions will
+ * get to use the same RTL functions as the core.
+ */
+#if defined(WIN32)
+# include "win32iop.h"
+#endif
+
+
#include "proto.h"
/* this has structure inits, so it cannot be included before here */
#undef PERLVARI
#undef PERLVARIC
+#if !defined(MULTIPLICITY)
+/* Set up PERLVAR macros for populating structs */
+# define PERLVAR(prefix,var,type) type prefix##var;
+/* 'var' is an array of length 'n' */
+# define PERLVARA(prefix,var,n,type) type prefix##var[n];
+/* initialize 'var' to init' */
+# define PERLVARI(prefix,var,type,init) type prefix##var;
+/* like PERLVARI, but make 'var' a const */
+# define PERLVARIC(prefix,var,type,init) type prefix##var;
+
+/* this is never instantiated, is it just used for sizeof(struct PerlHandShakeInterpreter) */
+struct PerlHandShakeInterpreter {
+# include "intrpvar.h"
+};
+# undef PERLVAR
+# undef PERLVARA
+# undef PERLVARI
+# undef PERLVARIC
+#endif
+
START_EXTERN_C
/* dummy variables that hold pointers to both runops functions, thus forcing
EXTCONST runops_proc_t PL_runops_dbg
INIT(Perl_runops_debug);
-/* PERL_GLOBAL_STRUCT_PRIVATE wants to keep global data like the
- * magic vtables const, but this is incompatible with SWIG which
- * does want to modify the vtables. */
-#ifdef PERL_GLOBAL_STRUCT_PRIVATE
-# define EXT_MGVTBL EXTCONST MGVTBL
-#else
-# define EXT_MGVTBL EXT MGVTBL
-#endif
+#define EXT_MGVTBL EXTCONST MGVTBL
#define PERL_MAGIC_READONLY_ACCEPTABLE 0x40
#define PERL_MAGIC_VALUE_MAGIC 0x80
EXTCONST bool
PL_valid_types_NVX[] = { 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 };
EXTCONST bool
-PL_valid_types_PVX[] = { 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1 };
+PL_valid_types_PVX[] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 };
EXTCONST bool
PL_valid_types_RV[] = { 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 };
EXTCONST bool
#endif
+/* In C99 we could use designated (named field) union initializers.
+ * In C89 we need to initialize the member declared first.
+ * In C++ we need extern C initializers.
+ *
+ * With the U8_NV version you will want to have inner braces,
+ * while with the NV_U8 use just the NV. */
+
+#ifdef __cplusplus
+#define INFNAN_U8_NV_DECL EXTERN_C const union { U8 u8[NVSIZE]; NV nv; }
+#define INFNAN_NV_U8_DECL EXTERN_C const union { NV nv; U8 u8[NVSIZE]; }
+#else
+#define INFNAN_U8_NV_DECL EXTCONST union { U8 u8[NVSIZE]; NV nv; }
+#define INFNAN_NV_U8_DECL EXTCONST union { NV nv; U8 u8[NVSIZE]; }
+#endif
/* if these never got defined, they need defaults */
#ifndef PERL_SET_CONTEXT
#define PERLDBf_SAVESRC_NOSUBS 0x800 /* Including evals that generate no subroutines */
#define PERLDBf_SAVESRC_INVALID 0x1000 /* Save source that did not compile */
-#define PERLDB_SUB (PL_perldb && (PL_perldb & PERLDBf_SUB))
-#define PERLDB_LINE (PL_perldb && (PL_perldb & PERLDBf_LINE))
-#define PERLDB_NOOPT (PL_perldb && (PL_perldb & PERLDBf_NOOPT))
-#define PERLDB_INTER (PL_perldb && (PL_perldb & PERLDBf_INTER))
-#define PERLDB_SUBLINE (PL_perldb && (PL_perldb & PERLDBf_SUBLINE))
-#define PERLDB_SINGLE (PL_perldb && (PL_perldb & PERLDBf_SINGLE))
-#define PERLDB_SUB_NN (PL_perldb && (PL_perldb & (PERLDBf_NONAME)))
-#define PERLDB_GOTO (PL_perldb && (PL_perldb & PERLDBf_GOTO))
-#define PERLDB_NAMEEVAL (PL_perldb && (PL_perldb & PERLDBf_NAMEEVAL))
-#define PERLDB_NAMEANON (PL_perldb && (PL_perldb & PERLDBf_NAMEANON))
-#define PERLDB_SAVESRC (PL_perldb && (PL_perldb & PERLDBf_SAVESRC))
-#define PERLDB_SAVESRC_NOSUBS (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_NOSUBS))
-#define PERLDB_SAVESRC_INVALID (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_INVALID))
+#define PERLDB_SUB (PL_perldb & PERLDBf_SUB)
+#define PERLDB_LINE (PL_perldb & PERLDBf_LINE)
+#define PERLDB_NOOPT (PL_perldb & PERLDBf_NOOPT)
+#define PERLDB_INTER (PL_perldb & PERLDBf_INTER)
+#define PERLDB_SUBLINE (PL_perldb & PERLDBf_SUBLINE)
+#define PERLDB_SINGLE (PL_perldb & PERLDBf_SINGLE)
+#define PERLDB_SUB_NN (PL_perldb & PERLDBf_NONAME)
+#define PERLDB_GOTO (PL_perldb & PERLDBf_GOTO)
+#define PERLDB_NAMEEVAL (PL_perldb & PERLDBf_NAMEEVAL)
+#define PERLDB_NAMEANON (PL_perldb & PERLDBf_NAMEANON)
+#define PERLDB_SAVESRC (PL_perldb & PERLDBf_SAVESRC)
+#define PERLDB_SAVESRC_NOSUBS (PL_perldb & PERLDBf_SAVESRC_NOSUBS)
+#define PERLDB_SAVESRC_INVALID (PL_perldb & PERLDBf_SAVESRC_INVALID)
+
+#define PERLDB_LINE_OR_SAVESRC (PL_perldb & (PERLDBf_LINE | PERLDBf_SAVESRC))
#ifdef USE_LOCALE
/* These locale things are all subject to change */
+
+# if defined(USE_ITHREADS) \
+ && defined(HAS_NEWLOCALE) \
+ && defined(LC_ALL_MASK) \
+ && defined(HAS_FREELOCALE) \
+ && defined(HAS_USELOCALE) \
+ && ! defined(NO_THREAD_SAFE_USELOCALE)
+
+ /* The code is written for simplicity to assume that any platform advanced
+ * enough to have the Posix 2008 locale functions has LC_ALL. The test
+ * above makes sure that assumption is valid */
+
+# define USE_THREAD_SAFE_LOCALE
+# endif
+
+# define LOCALE_INIT MUTEX_INIT(&PL_locale_mutex)
+
+# ifdef USE_THREAD_SAFE_LOCALE
+# define LOCALE_TERM \
+ STMT_START { \
+ MUTEX_DESTROY(&PL_locale_mutex); \
+ 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 MUTEX_DESTROY(&PL_locale_mutex)
+# endif
+
+# define LOCALE_LOCK MUTEX_LOCK(&PL_locale_mutex)
+# define LOCALE_UNLOCK MUTEX_UNLOCK(&PL_locale_mutex)
+
/* Returns TRUE if the plain locale pragma without a parameter is in effect
*/
-# define IN_LOCALE_RUNTIME cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE)
+# define IN_LOCALE_RUNTIME (PL_curcop \
+ && CopHINTS_get(PL_curcop) & HINT_LOCALE)
/* Returns TRUE if either form of the locale pragma is in effect */
# define IN_SOME_LOCALE_FORM_RUNTIME \
# define IN_LC_PARTIAL_COMPILETIME cBOOL(PL_hints & HINT_LOCALE_PARTIAL)
# define IN_LC_PARTIAL_RUNTIME \
- cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE_PARTIAL)
+ (PL_curcop && CopHINTS_get(PL_curcop) & HINT_LOCALE_PARTIAL)
# define IN_LC_COMPILETIME(category) \
(IN_LC_ALL_COMPILETIME || (IN_LC_PARTIAL_COMPILETIME \
# define IN_LC(category) \
(IN_LC_COMPILETIME(category) || IN_LC_RUNTIME(category))
+# if defined (PERL_CORE) || defined (PERL_IN_XSUB_RE)
+
+ /* This internal macro should be called from places that operate under
+ * locale rules. It there is a problem with the current locale that
+ * hasn't been raised yet, it will output a warning this time. Because
+ * this will so rarely be true, there is no point to optimize for
+ * time; instead it makes sense to minimize space used and do all the
+ * work in the rarely called function */
+# ifdef USE_LOCALE_CTYPE
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE \
+ STMT_START { \
+ if (UNLIKELY(PL_warn_locale)) { \
+ Perl__warn_problematic_locale(); \
+ } \
+ } STMT_END
+# else
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE
+# endif
+
+
+ /* These two internal macros are called when a warning should be raised,
+ * and will do so if enabled. The first takes a single code point
+ * argument; the 2nd, is a pointer to the first byte of the UTF-8 encoded
+ * string, and an end position which it won't try to read past */
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_CP_MSG(cp) \
+ STMT_START { \
+ if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) { \
+ Perl_warner(aTHX_ packWARN(WARN_LOCALE), \
+ "Wide character (U+%" UVXf ") in %s",\
+ (UV) cp, OP_DESC(PL_op)); \
+ } \
+ } STMT_END
+
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(s, send) \
+ STMT_START { /* Check if to warn before doing the conversion work */\
+ if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) { \
+ UV cp = utf8_to_uvchr_buf((U8 *) s, (U8 *) send, NULL); \
+ Perl_warner(aTHX_ packWARN(WARN_LOCALE), \
+ "Wide character (U+%" UVXf ") in %s", \
+ (cp == 0) \
+ ? UNICODE_REPLACEMENT \
+ : (UV) cp, \
+ OP_DESC(PL_op)); \
+ } \
+ } STMT_END
+
+# endif /* PERL_CORE or PERL_IN_XSUB_RE */
+
#else /* No locale usage */
+# define LOCALE_INIT
+# define LOCALE_TERM
+# define LOCALE_LOCK
+# define LOCALE_UNLOCK
# define IN_LOCALE_RUNTIME 0
# define IN_SOME_LOCALE_FORM_RUNTIME 0
# define IN_LOCALE_COMPILETIME 0
# define IN_LC_COMPILETIME(category) 0
# define IN_LC_RUNTIME(category) 0
# define IN_LC(category) 0
+
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_CP_MSG(a)
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(a,b)
#endif
#ifdef USE_LOCALE_NUMERIC
-/* These macros are for toggling between the underlying locale (LOCAL) and the
- * C locale. */
+/* These macros are for toggling between the underlying locale (UNDERLYING or
+ * LOCAL) and the C locale (STANDARD).
+
+=head1 Locale-related functions and macros
+
+=for apidoc Amn|void|DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+
+This macro should be used as a statement. It declares a private variable
+(whose name begins with an underscore) that is needed by the other macros in
+this section. Failing to include this correctly should lead to a syntax error.
+For compatibility with C89 C compilers it should be placed in a block before
+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
+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
+function L<setlocale(3)> behind its back; calling L</sync_locale> before calling
+this macro will update perl's records.)
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
+
+The private variable is used to save the current locale state, so
+that the requisite matching call to L</RESTORE_LC_NUMERIC> can restore it.
+
+=for apidoc Am|void|STORE_LC_NUMERIC_SET_TO_NEEDED
+
+This is used to help wrap XS or C code that that is C<LC_NUMERIC> locale-aware.
+This locale category is generally kept set to the C locale by Perl for
+backwards compatibility, and because most XS code that reads floating point
+values can cope only with the decimal radix character being a dot.
+
+This macro makes sure the current C<LC_NUMERIC> state is set properly, to be
+aware of locale if the call to the XS or C code from the Perl program is
+from within the scope of a S<C<use locale>>; or to ignore locale if the call is
+instead from outside such scope.
+
+This macro is the start of wrapping the C or XS code; the wrap ending is done
+by calling the L</RESTORE_LC_NUMERIC> macro after the operation. Otherwise
+the state can be changed that will adversely affect other XS code.
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
+
+=for apidoc Am|void|RESTORE_LC_NUMERIC
-/* The first set makes sure that the locale is set to C unless within a 'use
- * locale's scope; otherwise to the default locale. A function pointer is
- * used, which can be declared separately by
- * DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED, followed by the actual
- * setting (using STORE_LC_NUMERIC_SET_TO_NEEDED()), or the two can be combined
- * into one call DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED().
- * RESTORE_LC_NUMERIC() in all cases restores the locale to what it was before
- * these were called */
+This is used in conjunction with one of the macros
+L</STORE_LC_NUMERIC_SET_TO_NEEDED>
+and
+L</STORE_LC_NUMERIC_FORCE_TO_UNDERLYING>
+
+to properly restore the C<LC_NUMERIC> state.
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro and the two
+C<STORE> ones. This macro should be called as a single statement, not an
+expression, but with an empty argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
+
+=cut
+
+*/
#define _NOT_IN_NUMERIC_STANDARD (! PL_numeric_standard)
/* We can lock the category to stay in the C locale, making requests to the
- * contrary noops, in the dynamic scope by setting PL_numeric_standard to 2 */
-#define _NOT_IN_NUMERIC_LOCAL (! PL_numeric_local && PL_numeric_standard < 2)
-
-#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED \
- void (*_restore_LC_NUMERIC_function)(pTHX) = NULL;
-
-#define STORE_LC_NUMERIC_SET_TO_NEEDED() \
- if (IN_LC(LC_NUMERIC)) { \
- if (_NOT_IN_NUMERIC_LOCAL) { \
- set_numeric_local(); \
- _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
- } \
- } \
- else { \
- if (_NOT_IN_NUMERIC_STANDARD) { \
- SET_NUMERIC_STANDARD(); \
- _restore_LC_NUMERIC_function = &Perl_set_numeric_local; \
- } \
+ * contrary be noops, in the dynamic scope by setting PL_numeric_standard to 2.
+ * */
+#define _NOT_IN_NUMERIC_UNDERLYING \
+ (! PL_numeric_local && PL_numeric_standard < 2)
+
+#define DECLARATION_FOR_LC_NUMERIC_MANIPULATION \
+ void (*_restore_LC_NUMERIC_function)(pTHX) = NULL
+
+#define STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ if (IN_LC(LC_NUMERIC)) { \
+ if (_NOT_IN_NUMERIC_UNDERLYING) { \
+ Perl_set_numeric_local(aTHX); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
+ } \
+ } \
+ else { \
+ if (_NOT_IN_NUMERIC_STANDARD) { \
+ SET_NUMERIC_STANDARD(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_local; \
+ } \
}
-#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED() \
- DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED; \
- STORE_LC_NUMERIC_SET_TO_NEEDED();
-
-#define RESTORE_LC_NUMERIC() \
- if (_restore_LC_NUMERIC_function) { \
- _restore_LC_NUMERIC_function(aTHX); \
+#define RESTORE_LC_NUMERIC() \
+ if (_restore_LC_NUMERIC_function) { \
+ _restore_LC_NUMERIC_function(aTHX); \
}
/* The next two macros set unconditionally. These should be rarely used, and
* only after being sure that this is what is needed */
#define SET_NUMERIC_STANDARD() \
- STMT_START { if (_NOT_IN_NUMERIC_STANDARD) set_numeric_standard(); \
- } STMT_END
+ STMT_START { if (_NOT_IN_NUMERIC_STANDARD) \
+ Perl_set_numeric_standard(aTHX); \
+ } STMT_END
-#define SET_NUMERIC_LOCAL() \
- STMT_START { if (_NOT_IN_NUMERIC_LOCAL) \
- set_numeric_local(); } STMT_END
+#define SET_NUMERIC_UNDERLYING() \
+ STMT_START { if (_NOT_IN_NUMERIC_UNDERLYING) \
+ Perl_set_numeric_local(aTHX); } STMT_END
/* The rest of these LC_NUMERIC macros toggle to one or the other state, with
* the RESTORE_foo ones called to switch back, but only if need be */
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
- bool _was_local = _NOT_IN_NUMERIC_STANDARD; \
- if (_was_local) set_numeric_standard();
+#define STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD() \
+ bool _was_local = _NOT_IN_NUMERIC_STANDARD; \
+ if (_was_local) Perl_set_numeric_standard(aTHX);
/* Doesn't change to underlying locale unless within the scope of some form of
* 'use locale'. This is the usual desired behavior. */
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
- bool _was_standard = _NOT_IN_NUMERIC_LOCAL \
- && IN_LC(LC_NUMERIC); \
- if (_was_standard) set_numeric_local();
+#define STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING() \
+ bool _was_standard = _NOT_IN_NUMERIC_UNDERLYING \
+ && IN_LC(LC_NUMERIC); \
+ if (_was_standard) Perl_set_numeric_local(aTHX);
/* Rarely, we want to change to the underlying locale even outside of 'use
* locale'. This is principally in the POSIX:: functions */
-#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
- bool _was_standard = _NOT_IN_NUMERIC_LOCAL; \
- if (_was_standard) set_numeric_local();
-
-/* Lock to the C locale until unlock is called */
-#define LOCK_NUMERIC_STANDARD() \
- (__ASSERT_(PL_numeric_standard) \
- PL_numeric_standard = 2)
-
-#define UNLOCK_NUMERIC_STANDARD() \
- (__ASSERT_(PL_numeric_standard == 2) \
- PL_numeric_standard = 1)
+#define STORE_LC_NUMERIC_FORCE_TO_UNDERLYING() \
+ if (_NOT_IN_NUMERIC_UNDERLYING) { \
+ Perl_set_numeric_local(aTHX); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
+ }
-#define RESTORE_NUMERIC_LOCAL() \
- if (_was_local) set_numeric_local();
+/* Lock/unlock to the C locale until unlock is called. This needs to be
+ * recursively callable. [perl #128207] */
+#define LOCK_LC_NUMERIC_STANDARD() \
+ (__ASSERT_(PL_numeric_standard) \
+ PL_numeric_standard++)
+#define UNLOCK_LC_NUMERIC_STANDARD() \
+ STMT_START { \
+ if (PL_numeric_standard > 1) { \
+ PL_numeric_standard--; \
+ } \
+ else { \
+ assert(0); \
+ } \
+ } STMT_END
-#define RESTORE_NUMERIC_STANDARD() \
- if (_was_standard) SET_NUMERIC_STANDARD();
+#define RESTORE_LC_NUMERIC_UNDERLYING() \
+ if (_was_local) Perl_set_numeric_local(aTHX);
-#define Atof my_atof
+#define RESTORE_LC_NUMERIC_STANDARD() \
+ if (_restore_LC_NUMERIC_function) { \
+ _restore_LC_NUMERIC_function(aTHX); \
+ }
#else /* !USE_LOCALE_NUMERIC */
-#define SET_NUMERIC_STANDARD() /**/
-#define SET_NUMERIC_LOCAL() /**/
+#define SET_NUMERIC_STANDARD()
+#define SET_NUMERIC_UNDERLYING()
#define IS_NUMERIC_RADIX(a, b) (0)
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() /**/
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() /**/
-#define STORE_NUMERIC_STANDARD_FORCE_LOCAL()
-#define RESTORE_NUMERIC_LOCAL() /**/
-#define RESTORE_NUMERIC_STANDARD() /**/
-#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED
+#define STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD()
+#define STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING()
+#define STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
+#define RESTORE_LC_NUMERIC_UNDERLYING()
+#define RESTORE_LC_NUMERIC_STANDARD()
+#define DECLARATION_FOR_LC_NUMERIC_MANIPULATION
#define STORE_LC_NUMERIC_SET_TO_NEEDED()
-#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED()
#define RESTORE_LC_NUMERIC()
-#define LOCK_NUMERIC_STANDARD()
-#define UNLOCK_NUMERIC_STANDARD()
+#define LOCK_LC_NUMERIC_STANDARD()
+#define UNLOCK_LC_NUMERIC_STANDARD()
+
+#endif /* !USE_LOCALE_NUMERIC */
#define Atof my_atof
-#endif /* !USE_LOCALE_NUMERIC */
+/* Back-compat names */
+#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED \
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED; \
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
+#define LOCK_NUMERIC_STANDARD() LOCK_LC_NUMERIC_STANDARD()
+#define RESTORE_NUMERIC_LOCAL() RESTORE_LC_NUMERIC_UNDERLYING()
+#define RESTORE_NUMERIC_STANDARD() RESTORE_LC_NUMERIC_STANDARD()
+#define SET_NUMERIC_LOCAL() SET_NUMERIC_UNDERLYING()
+#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
+ STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD()
+#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
+ STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING()
+#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
+ STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
+#define UNLOCK_NUMERIC_STANDARD() UNLOCK_LC_NUMERIC_STANDARD()
+
+
#ifdef USE_QUADMATH
# define Perl_strtod(s, e) strtoflt128(s, e)
#define PERL_SCRIPT_MODE "r"
#endif
-/*
- * Some operating systems are stingy with stack allocation,
- * so perl may have to guard against stack overflow.
- */
-#ifndef PERL_STACK_OVERFLOW_CHECK
+/* not used. Kept as a NOOP for backcompat */
#define PERL_STACK_OVERFLOW_CHECK() NOOP
-#endif
/*
* Some nonpreemptive operating systems find it convenient to
/* Clones the per-interpreter data. */
# define MY_CXT_CLONE \
my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
- Copy(PL_my_cxt_list[MY_CXT_INDEX], my_cxtp, 1, my_cxt_t);\
- PL_my_cxt_list[MY_CXT_INDEX] = my_cxtp \
+ void * old_my_cxtp = PL_my_cxt_list[MY_CXT_INDEX]; \
+ PL_my_cxt_list[MY_CXT_INDEX] = my_cxtp; \
+ Copy(old_my_cxtp, my_cxtp, 1, my_cxt_t);
+
/* This macro must be used to access members of the my_cxt_t structure.
# include <fcntl.h>
#endif
+#ifdef __amigaos4__
+# undef FD_CLOEXEC /* a lie in AmigaOS */
+#endif
+
#ifdef I_SYS_FILE
# include <sys/file.h>
#endif
int). value returned in pointed-
to UV */
#define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 /* pointed to UV undefined */
-#define IS_NUMBER_NOT_INT 0x04 /* saw . or E notation */
+#define IS_NUMBER_NOT_INT 0x04 /* saw . or E notation or infnan */
#define IS_NUMBER_NEG 0x08 /* leading minus sign */
#define IS_NUMBER_INFINITY 0x10 /* this is big */
#define IS_NUMBER_NAN 0x20 /* this is not */
/* See http://www.unicode.org/unicode/reports/tr13/ */
#define NEXT_LINE_CHAR NEXT_LINE_NATIVE
-/* The UTF-8 bytes of the Unicode LS and PS, U+2028 and U+2029 */
-#define UNICODE_LINE_SEPA_0 0xE2
-#define UNICODE_LINE_SEPA_1 0x80
-#define UNICODE_LINE_SEPA_2 0xA8
-#define UNICODE_PARA_SEPA_0 0xE2
-#define UNICODE_PARA_SEPA_1 0x80
-#define UNICODE_PARA_SEPA_2 0xA9
-
#ifndef PIPESOCK_MODE
# define PIPESOCK_MODE
#endif
#define IS_SAFE_PATHNAME(p, len, op_name) IS_SAFE_SYSCALL((p), (len), "pathname", (op_name))
-#if defined(OEMVS)
+#if defined(OEMVS) || defined(__amigaos4__)
#define NO_ENV_ARRAY_IN_MAIN
#endif
* passed straight through to _escape.
*/
-#define PERL_PV_ESCAPE_QUOTE 0x0001
+#define PERL_PV_ESCAPE_QUOTE 0x000001
#define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE
-#define PERL_PV_PRETTY_ELLIPSES 0x0002
-#define PERL_PV_PRETTY_LTGT 0x0004
-
-#define PERL_PV_ESCAPE_FIRSTCHAR 0x0008
+#define PERL_PV_PRETTY_ELLIPSES 0x000002
+#define PERL_PV_PRETTY_LTGT 0x000004
+#define PERL_PV_PRETTY_EXACTSIZE 0x000008
-#define PERL_PV_ESCAPE_UNI 0x0100
-#define PERL_PV_ESCAPE_UNI_DETECT 0x0200
-#define PERL_PV_ESCAPE_NONASCII 0x0400
+#define PERL_PV_ESCAPE_UNI 0x000100
+#define PERL_PV_ESCAPE_UNI_DETECT 0x000200
+#define PERL_PV_ESCAPE_NONASCII 0x000400
+#define PERL_PV_ESCAPE_FIRSTCHAR 0x000800
-#define PERL_PV_ESCAPE_ALL 0x1000
-#define PERL_PV_ESCAPE_NOBACKSLASH 0x2000
-#define PERL_PV_ESCAPE_NOCLEAR 0x4000
-#define PERL_PV_ESCAPE_RE 0x8000
+#define PERL_PV_ESCAPE_ALL 0x001000
+#define PERL_PV_ESCAPE_NOBACKSLASH 0x002000
+#define PERL_PV_ESCAPE_NOCLEAR 0x004000
+#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
+#define PERL_PV_ESCAPE_RE 0x008000
-#define PERL_PV_ESCAPE_DWIM 0x10000
+#define PERL_PV_ESCAPE_DWIM 0x010000
-#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
/* used by pv_display in dump.c*/
#define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE
#define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE|PERL_PV_ESCAPE_NONASCII
+#if DOUBLEKIND == DOUBLE_IS_VAX_F_FLOAT || \
+ DOUBLEKIND == DOUBLE_IS_VAX_D_FLOAT || \
+ DOUBLEKIND == DOUBLE_IS_VAX_G_FLOAT
+# define DOUBLE_IS_VAX_FLOAT
+#else
+# define DOUBLE_IS_IEEE_FORMAT
+#endif
+
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define DOUBLE_LITTLE_ENDIAN
+#endif
+
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define DOUBLE_BIG_ENDIAN
+#endif
+
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
+# define DOUBLE_MIX_ENDIAN
+#endif
+
+/* The VAX fp formats are neither consistently little-endian nor
+ * big-endian, and neither are they really IEEE-mixed endian like
+ * the mixed-endian ARM IEEE formats (with swapped bytes).
+ * Ultimately, the VAX format came from the PDP-11.
+ *
+ * The ordering of the parts in VAX floats is quite vexing.
+ * In the below the fraction_n are the mantissa bits.
+ *
+ * The fraction_1 is the most significant (numbering as by DEC/Digital),
+ * while the rightmost bit in each fraction is the least significant:
+ * in other words, big-endian bit order within the fractions.
+ *
+ * The fraction segments themselves would be big-endianly, except that
+ * within 32 bit segments the less significant half comes first, the more
+ * significant after, except that in the format H (used for long doubles)
+ * the first fraction segment is alone, because the exponent is wider.
+ * This means for example that both the most and the least significant
+ * bits can be in the middle of the floats, not at either end.
+ *
+ * References:
+ * http://nssdc.gsfc.nasa.gov/nssdc/formats/VAXFloatingPoint.htm
+ * http://www.quadibloc.com/comp/cp0201.htm
+ * http://h71000.www7.hp.com/doc/82final/6443/6443pro_028.html
+ * (somebody at HP should be fired for the URLs)
+ *
+ * F fraction_2:16 sign:1 exp:8 fraction_1:7
+ * (exponent bias 128, hidden first one-bit)
+ *
+ * D fraction_2:16 sign:1 exp:8 fraction_1:7
+ * fraction_4:16 fraction_3:16
+ * (exponent bias 128, hidden first one-bit)
+ *
+ * G fraction_2:16 sign:1 exp:11 fraction_1:4
+ * fraction_4:16 fraction_3:16
+ * (exponent bias 1024, hidden first one-bit)
+ *
+ * H fraction_1:16 sign:1 exp:15
+ * fraction_3:16 fraction_2:16
+ * fraction_5:16 fraction_4:16
+ * fraction_7:16 fraction_6:16
+ * (exponent bias 16384, hidden first one-bit)
+ * (available only on VAX, and only on Fortran?)
+ *
+ * The formats S, T and X are available on the Alpha (and Itanium,
+ * also known as I64/IA64) and are equivalent with the IEEE-754 formats
+ * binary32, binary64, and binary128 (commonly: float, double, long double).
+ *
+ * S sign:1 exp:8 mantissa:23
+ * (exponent bias 127, hidden first one-bit)
+ *
+ * T sign:1 exp:11 mantissa:52
+ * (exponent bias 1022, hidden first one-bit)
+ *
+ * X sign:1 exp:15 mantissa:112
+ * (exponent bias 16382, hidden first one-bit)
+ *
+ */
+
+#ifdef DOUBLE_IS_VAX_FLOAT
+# define DOUBLE_VAX_ENDIAN
+#endif
+
+#ifdef DOUBLE_IS_IEEE_FORMAT
+/* All the basic IEEE formats have the implicit bit,
+ * except for the x86 80-bit extended formats, which will undef this.
+ * Also note that the IEEE 754 subnormals (formerly known as denormals)
+ * do not have the implicit bit of one. */
+# define NV_IMPLICIT_BIT
+#endif
+
+#if defined(LONG_DOUBLEKIND) && LONG_DOUBLEKIND != LONG_DOUBLE_IS_DOUBLE
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+# define LONGDOUBLE_LITTLE_ENDIAN
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+# define LONGDOUBLE_BIG_ENDIAN
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+# define LONGDOUBLE_MIX_ENDIAN
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+# define LONGDOUBLE_X86_80_BIT
+# ifdef USE_LONG_DOUBLE
+# undef NV_IMPLICIT_BIT
+# define NV_X86_80_BIT
+# endif
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+# define LONGDOUBLE_DOUBLEDOUBLE
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_VAX_H_FLOAT
+# define LONGDOUBLE_VAX_ENDIAN
+# endif
+
+#endif /* LONG_DOUBLEKIND */
+
+#ifdef USE_QUADMATH /* assume quadmath endianness == native double endianness */
+# if defined(DOUBLE_LITTLE_ENDIAN)
+# define NV_LITTLE_ENDIAN
+# elif defined(DOUBLE_BIG_ENDIAN)
+# define NV_BIG_ENDIAN
+# elif defined(DOUBLE_MIX_ENDIAN) /* stretch */
+# define NV_MIX_ENDIAN
+# endif
+#elif NVSIZE == DOUBLESIZE
+# ifdef DOUBLE_LITTLE_ENDIAN
+# define NV_LITTLE_ENDIAN
+# endif
+# ifdef DOUBLE_BIG_ENDIAN
+# define NV_BIG_ENDIAN
+# endif
+# ifdef DOUBLE_MIX_ENDIAN
+# define NV_MIX_ENDIAN
+# endif
+# ifdef DOUBLE_VAX_ENDIAN
+# define NV_VAX_ENDIAN
+# endif
+#elif NVSIZE == LONG_DOUBLESIZE
+# ifdef LONGDOUBLE_LITTLE_ENDIAN
+# define NV_LITTLE_ENDIAN
+# endif
+# ifdef LONGDOUBLE_BIG_ENDIAN
+# define NV_BIG_ENDIAN
+# endif
+# ifdef LONGDOUBLE_MIX_ENDIAN
+# define NV_MIX_ENDIAN
+# endif
+# ifdef LONGDOUBLE_VAX_ENDIAN
+# define NV_VAX_ENDIAN
+# endif
+#endif
+
+#ifdef DOUBLE_IS_IEEE_FORMAT
+# define DOUBLE_HAS_INF
+# define DOUBLE_HAS_NAN
+#endif
+
+#ifdef DOUBLE_HAS_NAN
+
+#ifdef DOINIT
+
+/* PL_inf and PL_nan initialization.
+ *
+ * For inf and nan initialization the ultimate fallback is dividing
+ * one or zero by zero: however, some compilers will warn or even fail
+ * on divide-by-zero, but hopefully something earlier will work.
+ *
+ * If you are thinking of using HUGE_VAL for infinity, or using
+ * <math.h> functions to generate NV_INF (e.g. exp(1e9), log(-1.0)),
+ * stop. Neither will work portably: HUGE_VAL can be just DBL_MAX,
+ * and the math functions might be just generating DBL_MAX, or even zero.
+ *
+ * Also, do NOT try doing NV_NAN based on NV_INF and trying (NV_INF-NV_INF).
+ * Though logically correct, some compilers (like Visual C 2003)
+ * falsely misoptimize that to zero (x-x is always zero, right?)
+ *
+ * Finally, note that not all floating point formats define Inf (or NaN).
+ * For the infinity a large number may be used instead. Operations that
+ * under the IEEE floating point would return Inf or NaN may return
+ * either large numbers (positive or negative), or they may cause
+ * a floating point exception or some other fault.
+ */
+
+/* The quadmath literals are anon structs which -Wc++-compat doesn't like. */
+GCC_DIAG_IGNORE(-Wc++-compat)
+
+# ifdef USE_QUADMATH
+/* Cannot use HUGE_VALQ for PL_inf because not a compile-time
+ * constant. */
+INFNAN_NV_U8_DECL PL_inf = { 1.0Q/0.0Q };
+# elif NVSIZE == LONG_DOUBLESIZE && defined(LONGDBLINFBYTES)
+INFNAN_U8_NV_DECL PL_inf = { { LONGDBLINFBYTES } };
+# elif NVSIZE == DOUBLESIZE && defined(DOUBLEINFBYTES)
+INFNAN_U8_NV_DECL PL_inf = { { DOUBLEINFBYTES } };
+# else
+# if NVSIZE == LONG_DOUBLESIZE && defined(USE_LONG_DOUBLE)
+# if defined(LDBL_INFINITY)
+INFNAN_NV_U8_DECL PL_inf = { LDBL_INFINITY };
+# elif defined(LDBL_INF)
+INFNAN_NV_U8_DECL PL_inf = { LDBL_INF };
+# elif defined(INFINITY)
+INFNAN_NV_U8_DECL PL_inf = { (NV)INFINITY };
+# elif defined(INF)
+INFNAN_NV_U8_DECL PL_inf = { (NV)INF };
+# else
+INFNAN_NV_U8_DECL PL_inf = { 1.0L/0.0L }; /* keep last */
+# endif
+# else
+# if defined(DBL_INFINITY)
+INFNAN_NV_U8_DECL PL_inf = { DBL_INFINITY };
+# elif defined(DBL_INF)
+INFNAN_NV_U8_DECL PL_inf = { DBL_INF };
+# elif defined(INFINITY) /* C99 */
+INFNAN_NV_U8_DECL PL_inf = { (NV)INFINITY };
+# elif defined(INF)
+INFNAN_NV_U8_DECL PL_inf = { (NV)INF };
+# else
+INFNAN_NV_U8_DECL PL_inf = { 1.0/0.0 }; /* keep last */
+# endif
+# endif
+# endif
+
+# ifdef USE_QUADMATH
+/* Cannot use nanq("0") for PL_nan because not a compile-time
+ * constant. */
+INFNAN_NV_U8_DECL PL_nan = { 0.0Q/0.0Q };
+# elif NVSIZE == LONG_DOUBLESIZE && defined(LONGDBLNANBYTES)
+INFNAN_U8_NV_DECL PL_nan = { { LONGDBLNANBYTES } };
+# elif NVSIZE == DOUBLESIZE && defined(DOUBLENANBYTES)
+INFNAN_U8_NV_DECL PL_nan = { { DOUBLENANBYTES } };
+# else
+# if NVSIZE == LONG_DOUBLESIZE && defined(USE_LONG_DOUBLE)
+# if defined(LDBL_NAN)
+INFNAN_NV_U8_DECL PL_nan = { LDBL_NAN };
+# elif defined(LDBL_QNAN)
+INFNAN_NV_U8_DECL PL_nan = { LDBL_QNAN };
+# elif defined(NAN)
+INFNAN_NV_U8_DECL PL_nan = { (NV)NAN };
+# else
+INFNAN_NV_U8_DECL PL_nan = { 0.0L/0.0L }; /* keep last */
+# endif
+# else
+# if defined(DBL_NAN)
+INFNAN_NV_U8_DECL PL_nan = { DBL_NAN };
+# elif defined(DBL_QNAN)
+INFNAN_NV_U8_DECL PL_nan = { DBL_QNAN };
+# elif defined(NAN) /* C99 */
+INFNAN_NV_U8_DECL PL_nan = { (NV)NAN };
+# else
+INFNAN_NV_U8_DECL PL_nan = { 0.0/0.0 }; /* keep last */
+# endif
+# endif
+# endif
+
+GCC_DIAG_RESTORE
+
+#else
+
+INFNAN_NV_U8_DECL PL_inf;
+INFNAN_NV_U8_DECL PL_nan;
+
+#endif
+
+/* If you have not defined NV_INF/NV_NAN (like for example win32/win32.h),
+ * we will define NV_INF/NV_NAN as the nv part of the global const
+ * PL_inf/PL_nan. Note, however, that the preexisting NV_INF/NV_NAN
+ * might not be a compile-time constant, in which case it cannot be
+ * used to initialize PL_inf/PL_nan above. */
+#ifndef NV_INF
+# define NV_INF PL_inf.nv
+#endif
+#ifndef NV_NAN
+# define NV_NAN PL_nan.nv
+#endif
+
+/* NaNs (not-a-numbers) can carry payload bits, in addition to
+ * "nan-ness". Part of the payload is the quiet/signaling bit.
+ * To back up a bit (harhar):
+ *
+ * For IEEE 754 64-bit formats [1]:
+ *
+ * s 000 (mantissa all-zero) zero
+ * s 000 (mantissa non-zero) subnormals (denormals)
+ * s 001 ... 7fe normals
+ * s 7ff q nan
+ *
+ * For IEEE 754 128-bit formats:
+ *
+ * s 0000 (mantissa all-zero) zero
+ * s 0000 (mantissa non-zero) subnormals (denormals)
+ * s 0001 ... 7ffe normals
+ * s 7fff q nan
+ *
+ * [1] this looks like big-endian, but applies equally to little-endian.
+ *
+ * s = Sign bit. Yes, zeros and nans can have negative sign,
+ * the interpretation is application-specific.
+ *
+ * q = Quietness bit, the interpretation is platform-specific.
+ * Most platforms have the most significant bit being one
+ * meaning quiet, but some (older mips, hppa) have the msb
+ * being one meaning signaling. Note that the above means
+ * that on most platforms there cannot be signaling nan with
+ * zero payload because that is identical with infinity;
+ * while conversely on older mips/hppa there cannot be a quiet nan
+ * because that is identical with infinity.
+ *
+ * Moreover, whether there is any behavioral difference
+ * between quiet and signaling NaNs, depends on the platform.
+ *
+ * x86 80-bit extended precision is different, the mantissa bits:
+ *
+ * 63 62 61 30387+ pre-387 visual c
+ * -------- ---- -------- --------
+ * 0 0 0 invalid infinity
+ * 0 0 1 invalid snan
+ * 0 1 0 invalid snan
+ * 0 1 1 invalid snan
+ * 1 0 0 infinity snan 1.#INF
+ * 1 0 1 snan 1.#SNAN
+ * 1 1 0 qnan -1.#IND (x86 chooses this to negative)
+ * 1 1 1 qnan 1.#QNAN
+ *
+ * This means that in this format there are 61 bits available
+ * for the nan payload.
+ *
+ * Note that the 32-bit x86 ABI cannot do signaling nans: the x87
+ * simply cannot preserve the bit. You can either use the 80-bit
+ * extended precision (long double, -Duselongdouble), or use x86-64.
+ *
+ * In all platforms, the payload bytes (and bits, some of them are
+ * often in a partial byte) themselves can be either all zero (x86),
+ * all one (sparc or mips), or a mixture: in IEEE 754 128-bit double
+ * or in a double-double, the first half of the payload can follow the
+ * native double, while in the second half the payload can be all
+ * zeros. (Therefore the mask for payload bits is not necessarily
+ * identical to bit complement of the NaN.) Another way of putting
+ * this: the payload for the default NaN might not be zero.
+ *
+ * For the x86 80-bit long doubles, the trailing bytes (the 80 bits
+ * being 'packaged' in either 12 or 16 bytes) can be whatever random
+ * garbage.
+ *
+ * Furthermore, the semantics of the sign bit on NaNs are platform-specific.
+ * On normal floats, the sign bit being on means negative. But this may,
+ * or may not, be reverted on NaNs: in other words, the default NaN might
+ * have the sign bit on, and therefore look like negative if you look
+ * at it at the bit level.
+ *
+ * NaN payloads are not propagated even on copies, or in arithmetics.
+ * They *might* be, according to some rules, on your particular
+ * cpu/os/compiler/libraries, but no guarantees.
+ *
+ * To summarize, on most platforms, and for 64-bit doubles
+ * (using big-endian ordering here):
+ *
+ * [7FF8000000000000..7FFFFFFFFFFFFFFF] quiet
+ * [FFF8000000000000..FFFFFFFFFFFFFFFF] quiet
+ * [7FF0000000000001..7FF7FFFFFFFFFFFF] signaling
+ * [FFF0000000000001..FFF7FFFFFFFFFFFF] signaling
+ *
+ * The C99 nan() is supposed to generate *quiet* NaNs.
+ *
+ * Note the asymmetry:
+ * The 7FF0000000000000 is positive infinity,
+ * the FFF0000000000000 is negative infinity.
+ */
+
+/* NVMANTBITS is the number of _real_ mantissa bits in an NV.
+ * For the standard IEEE 754 fp this number is usually one less that
+ * *DBL_MANT_DIG because of the implicit (aka hidden) bit, which isn't
+ * real. For the 80-bit extended precision formats (x86*), the number
+ * of mantissa bits... depends. For normal floats, it's 64. But for
+ * the inf/nan, it's different (zero for inf, 61 for nan).
+ * NVMANTBITS works for normal floats. */
+
+/* We do not want to include the quiet/signaling bit. */
+#define NV_NAN_BITS (NVMANTBITS - 1)
+
+#if defined(USE_LONG_DOUBLE) && NVSIZE > DOUBLESIZE
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 13
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 2
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 7
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 2
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+# define NV_NAN_QS_BYTE_OFFSET 13
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+# define NV_NAN_QS_BYTE_OFFSET 1
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+# define NV_NAN_QS_BYTE_OFFSET 9
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+# define NV_NAN_QS_BYTE_OFFSET 6
+# else
+# error "Unexpected long double format"
+# endif
+#else
+# ifdef USE_QUADMATH
+# ifdef NV_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 13
+# elif defined(NV_BIG_ENDIAN)
+# define NV_NAN_QS_BYTE_OFFSET 2
+# else
+# error "Unexpected quadmath format"
+# endif
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 2
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 1
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 6
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 1
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 13
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define NV_NAN_QS_BYTE_OFFSET 2
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE
+# define NV_NAN_QS_BYTE_OFFSET 2 /* bytes 4 5 6 7 0 1 2 3 (MSB 7) */
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
+# define NV_NAN_QS_BYTE_OFFSET 5 /* bytes 3 2 1 0 7 6 5 4 (MSB 7) */
+# else
+/* For example the VAX formats should never
+ * get here because they do not have NaN. */
+# error "Unexpected double format"
+# endif
+#endif
+/* NV_NAN_QS_BYTE is the byte to test for the quiet/signaling */
+#define NV_NAN_QS_BYTE(nvp) (((U8*)(nvp))[NV_NAN_QS_BYTE_OFFSET])
+/* NV_NAN_QS_BIT is the bit to test in the NV_NAN_QS_BYTE_OFFSET
+ * for the quiet/signaling */
+#if defined(USE_LONG_DOUBLE) && \
+ (LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN)
+# define NV_NAN_QS_BIT_SHIFT 6 /* 0x40 */
+#elif defined(USE_LONG_DOUBLE) && \
+ (LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE)
+# define NV_NAN_QS_BIT_SHIFT 3 /* 0x08, but not via NV_NAN_BITS */
+#else
+# define NV_NAN_QS_BIT_SHIFT ((NV_NAN_BITS) % 8) /* usually 3, or 0x08 */
+#endif
+#define NV_NAN_QS_BIT (1 << (NV_NAN_QS_BIT_SHIFT))
+/* NV_NAN_QS_BIT_OFFSET is the bit offset from the beginning of a NV
+ * (bytes ordered big-endianly) for the quiet/signaling bit
+ * for the quiet/signaling */
+#define NV_NAN_QS_BIT_OFFSET \
+ (8 * (NV_NAN_QS_BYTE_OFFSET) + (NV_NAN_QS_BIT_SHIFT))
+/* NV_NAN_QS_QUIET (always defined) is true if the NV_NAN_QS_QS_BIT being
+ * on indicates quiet NaN. NV_NAN_QS_SIGNALING (also always defined)
+ * is true if the NV_NAN_QS_BIT being on indicates signaling NaN. */
+#define NV_NAN_QS_QUIET \
+ ((NV_NAN_QS_BYTE(PL_nan.u8) & NV_NAN_QS_BIT) == NV_NAN_QS_BIT)
+#define NV_NAN_QS_SIGNALING (!(NV_NAN_QS_QUIET))
+#define NV_NAN_QS_TEST(nvp) (NV_NAN_QS_BYTE(nvp) & NV_NAN_QS_BIT)
+/* NV_NAN_IS_QUIET() returns true if the NV behind nvp is a NaN,
+ * whether it is a quiet NaN, NV_NAN_IS_SIGNALING() if a signaling NaN.
+ * Note however that these do not check whether the nvp is a NaN. */
+#define NV_NAN_IS_QUIET(nvp) \
+ (NV_NAN_QS_TEST(nvp) == (NV_NAN_QS_QUIET ? NV_NAN_QS_BIT : 0))
+#define NV_NAN_IS_SIGNALING(nvp) \
+ (NV_NAN_QS_TEST(nvp) == (NV_NAN_QS_QUIET ? 0 : NV_NAN_QS_BIT))
+#define NV_NAN_SET_QUIET(nvp) \
+ (NV_NAN_QS_QUIET ? \
+ (NV_NAN_QS_BYTE(nvp) |= NV_NAN_QS_BIT) : \
+ (NV_NAN_QS_BYTE(nvp) &= ~NV_NAN_QS_BIT))
+#define NV_NAN_SET_SIGNALING(nvp) \
+ (NV_NAN_QS_QUIET ? \
+ (NV_NAN_QS_BYTE(nvp) &= ~NV_NAN_QS_BIT) : \
+ (NV_NAN_QS_BYTE(nvp) |= NV_NAN_QS_BIT))
+#define NV_NAN_QS_XOR(nvp) (NV_NAN_QS_BYTE(nvp) ^= NV_NAN_QS_BIT)
+
+/* NV_NAN_PAYLOAD_MASK: masking the nan payload bits.
+ *
+ * NV_NAN_PAYLOAD_PERM: permuting the nan payload bytes.
+ * 0xFF means "don't go here".*/
+
+/* Shorthands to avoid typoses. */
+#define NV_NAN_PAYLOAD_MASK_SKIP_EIGHT \
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+#define NV_NAN_PAYLOAD_PERM_SKIP_EIGHT \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+#define NV_NAN_PAYLOAD_PERM_0_TO_7 \
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
+#define NV_NAN_PAYLOAD_PERM_7_TO_0 \
+ 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0
+#define NV_NAN_PAYLOAD_MASK_IEEE_754_128_LE \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00
+#define NV_NAN_PAYLOAD_PERM_IEEE_754_128_LE \
+ NV_NAN_PAYLOAD_PERM_0_TO_7, \
+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF
+#define NV_NAN_PAYLOAD_MASK_IEEE_754_128_BE \
+ 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+#define NV_NAN_PAYLOAD_PERM_IEEE_754_128_BE \
+ 0xFF, 0xFF, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, \
+ NV_NAN_PAYLOAD_PERM_7_TO_0
+#define NV_NAN_PAYLOAD_MASK_IEEE_754_64_LE \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00
+#define NV_NAN_PAYLOAD_PERM_IEEE_754_64_LE \
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xFF
+#define NV_NAN_PAYLOAD_MASK_IEEE_754_64_BE \
+ 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+#define NV_NAN_PAYLOAD_PERM_IEEE_754_64_BE \
+ 0xFF, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0
+
+#if defined(USE_LONG_DOUBLE) && NVSIZE > DOUBLESIZE
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_LE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_LE
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_BE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_BE
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
+# if LONG_DOUBLESIZE == 10
+# define NV_NAN_PAYLOAD_MASK \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, \
+ 0x00, 0x00
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_0_TO_7, 0xFF, 0xFF
+# elif LONG_DOUBLESIZE == 12
+# define NV_NAN_PAYLOAD_MASK \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, \
+ 0x00, 0x00, 0x00, 0x00
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_0_TO_7, 0xFF, 0xFF, 0xFF, 0xFF
+# elif LONG_DOUBLESIZE == 16
+# define NV_NAN_PAYLOAD_MASK \
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_0_TO_7, \
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+# else
+# error "Unexpected x86 80-bit little-endian long double format"
+# endif
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+# if LONG_DOUBLESIZE == 10
+# define NV_NAN_PAYLOAD_MASK \
+ 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_7_TO_0, 0xFF, 0xFF
+# elif LONG_DOUBLESIZE == 12
+# define NV_NAN_PAYLOAD_MASK \
+ 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0x00, 0x00
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_7_TO_0, 0xFF, 0xFF, 0xFF, 0xFF
+# elif LONG_DOUBLESIZE == 16
+# define NV_NAN_PAYLOAD_MASK \
+ 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, \
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_7_TO_0, \
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+# else
+# error "Unexpected x86 80-bit big-endian long double format"
+# endif
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
+/* For double-double we assume only the first double (in LE or BE terms)
+ * is used for NaN. */
+# define NV_NAN_PAYLOAD_MASK \
+ NV_NAN_PAYLOAD_MASK_SKIP_EIGHT, NV_NAN_PAYLOAD_MASK_IEEE_754_64_LE
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_SKIP_EIGHT, NV_NAN_PAYLOAD_PERM_IEEE_754_64_LE
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
+# define NV_NAN_PAYLOAD_MASK \
+ NV_NAN_PAYLOAD_MASK_IEEE_754_64_BE
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_IEEE_754_64_BE
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
+# define NV_NAN_PAYLOAD_MASK \
+ NV_NAN_PAYLOAD_MASK_IEEE_754_64_LE
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_IEEE_754_64_LE
+# elif LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+# define NV_NAN_PAYLOAD_MASK \
+ NV_NAN_PAYLOAD_MASK_SKIP_EIGHT, NV_NAN_PAYLOAD_MASK_IEEE_754_64_BE
+# define NV_NAN_PAYLOAD_PERM \
+ NV_NAN_PAYLOAD_PERM_SKIP_EIGHT, NV_NAN_PAYLOAD_PERM_IEEE_754_64_BE
+# else
+# error "Unexpected long double format"
+# endif
+#else
+# ifdef USE_QUADMATH /* quadmath is not long double */
+# ifdef NV_LITTLE_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_LE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_LE
+# elif defined(NV_BIG_ENDIAN)
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_BE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_BE
+# else
+# error "Unexpected quadmath format"
+# endif
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN
+# define NV_NAN_PAYLOAD_MASK 0xff, 0xff, 0x07, 0x00
+# define NV_NAN_PAYLOAD_PERM 0x0, 0x1, 0x2, 0xFF
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN
+# define NV_NAN_PAYLOAD_MASK 0x00, 0x07, 0xff, 0xff
+# define NV_NAN_PAYLOAD_PERM 0xFF, 0x2, 0x1, 0x0
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_64_LE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_64_LE
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_64_BE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_64_BE
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_LE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_LE
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define NV_NAN_PAYLOAD_MASK NV_NAN_PAYLOAD_MASK_IEEE_754_128_BE
+# define NV_NAN_PAYLOAD_PERM NV_NAN_PAYLOAD_PERM_IEEE_754_128_BE
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE
+# define NV_NAN_PAYLOAD_MASK 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff
+# define NV_NAN_PAYLOAD_PERM 0x4, 0x5, 0x6, 0xFF, 0x0, 0x1, 0x2, 0x3
+# elif DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
+# define NV_NAN_PAYLOAD_MASK 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff
+# define NV_NAN_PAYLOAD_PERM 0x3, 0x2, 0x1, 0x0, 0xFF, 0x6, 0x5, 0x4
+# else
+# error "Unexpected double format"
+# endif
+#endif
+
+#endif /* DOUBLE_HAS_NAN */
+
+
/*
(KEEP THIS LAST IN perl.h!)
#endif /* Include guard */
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/