This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Enhance PERL_TRACK_MEMPOOL so that it also emulates the PerlHost
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 63eba70..8a91175 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1,7 +1,7 @@
 /*    perl.h
  *
  *    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #  endif
 #endif
 
-#if defined(MULTIPLICITY)
-#  ifndef PERL_IMPLICIT_CONTEXT
-#    define PERL_IMPLICIT_CONTEXT
-#  endif
-#endif
-
 #ifdef PERL_GLOBAL_STRUCT_PRIVATE
 #  ifndef PERL_GLOBAL_STRUCT
 #    define PERL_GLOBAL_STRUCT
 #  endif
 #endif
+
 #ifdef PERL_GLOBAL_STRUCT
 #  ifndef MULTIPLICITY
 #    define MULTIPLICITY
 #  endif
 #endif
 
+#ifdef MULTIPLICITY
+#  ifndef PERL_IMPLICIT_CONTEXT
+#    define PERL_IMPLICIT_CONTEXT
+#  endif
+#endif
+
 /* undef WIN32 when building on Cygwin (for libwin32) - gph */
 #ifdef __CYGWIN__
 #   undef WIN32
 #   endif
 #endif
 
-#ifdef SYMBIAN
+#ifdef __SYMBIAN32__
 #  include "symbian/symbian_proto.h"
 #endif
 
 /* Any stack-challenged places.  The limit varies (and often
  * is configurable), but using more than a kilobyte of stack
  * is usually dubious in these systems. */
-#if defined(EPOC) || defined(SYMBIAN)
+#if defined(EPOC) || defined(__SYMBIAN32__)
 /* EPOC/Symbian: need to work around the SDK features. *
  * On WINS: MS VC5 generates calls to _chkstk,         *
  * if a "large" stack frame is allocated.              *
 #  ifndef MULTIPLICITY
 #    define MULTIPLICITY
 #  endif
-#  define pTHX register PerlInterpreter *my_perl PERL_UNUSED_DECL
+#  define tTHX PerlInterpreter*
+#  define pTHX register tTHX my_perl PERL_UNUSED_DECL
 #  define aTHX my_perl
 #  ifdef PERL_GLOBAL_STRUCT
-#    define dTHXa(a)   dVAR; pTHX = (PerlInterpreter*)a
+#    define dTHXa(a)   dVAR; pTHX = (tTHX)a
 #  else
-#    define dTHXa(a)   pTHX = (PerlInterpreter*)a
+#    define dTHXa(a)   pTHX = (tTHX)a
 #  endif
 #  ifdef PERL_GLOBAL_STRUCT
 #    define dTHX               dVAR; pTHX = PERL_GET_THX
 #  define pTHX_7       8
 #  define pTHX_8       9
 #  define pTHX_9       10
+#  if defined(DEBUGGING) && !defined(PERL_TRACK_MEMPOOL)
+#    define PERL_TRACK_MEMPOOL
+#  endif
+#else
+#  undef PERL_TRACK_MEMPOOL
 #endif
 
 #define STATIC static
 #define CALLREG_INTUIT_STRING CALL_FPTR(PL_regint_string)
 #define CALLREGFREE CALL_FPTR(PL_regfree)
 
-#if defined(SYMBIAN) && defined(__GNUC__)
+/* XXX The PERL_UNUSED_DECL suffix is unfortunately rather inflexible:
+ * it assumes that in all compilers the way to suppress an "unused"
+ * warning is to have a suffix.  In some compilers that might be a
+ * a compiler pragma, e.g. #pragma unused(varname). */
+
+#if defined(__SYMBIAN32__) && defined(__GNUC__)
 #  ifdef __cplusplus
 #    define PERL_UNUSED_DECL
 #  else
 #define dNOOP extern int Perl___notused PERL_UNUSED_DECL
 
 #ifndef pTHX
+/* Don't bother defining tTHX and sTHX; using them outside
+ * code guarded by PERL_IMPLICIT_CONTEXT is an error.
+ */
 #  define pTHX         void
 #  define pTHX_
 #  define aTHX
@@ -385,11 +400,11 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #define DOSISH 1
 #endif
 
-#if defined(__STDC__) || defined(vax11c) || defined(_AIX) || defined(__stdc__) || defined(__cplusplus) || defined( EPOC) || defined(NETWARE) || defined(SYMBIAN)
+#if defined(__STDC__) || defined(_AIX) || defined(__stdc__) || defined(__cplusplus) || defined(EPOC) || defined(NETWARE) || defined(__SYMBIAN32__)
 # define STANDARD_C 1
 #endif
 
-#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(__EMX__) || defined(__DGUX) || defined( EPOC) || defined(__QNX__) || defined(NETWARE) || defined(PERL_MICRO)
+#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(__EMX__) || defined(__DGUX) || defined(EPOC) || defined(__QNX__) || defined(NETWARE) || defined(PERL_MICRO)
 # define DONT_DECLARE_STD 1
 #endif
 
@@ -407,7 +422,7 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #define TAINT_NOT      (PL_tainted = FALSE)
 #define TAINT_IF(c)    if (c) { PL_tainted = TRUE; }
 #define TAINT_ENV()    if (PL_tainting) { taint_env(); }
-#define TAINT_PROPER(s)        if (PL_tainting) { taint_proper(Nullch, s); }
+#define TAINT_PROPER(s)        if (PL_tainting) { taint_proper(NULL, s); }
 
 /* XXX All process group stuff is handled in pp_sys.c.  Should these
    defines move there?  If so, I could simplify this a lot. --AD  9/96.
@@ -547,7 +562,7 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #   include <unistd.h>
 #endif
 
-#ifdef SYMBIAN
+#ifdef __SYMBIAN32__
 #   undef _SC_ARG_MAX /* Symbian has _SC_ARG_MAX but no sysconf() */
 #endif
 
@@ -810,6 +825,14 @@ int usleep(unsigned int);
 #define PERL_DONT_CREATE_GVSV
 #endif
 
+#if !defined(HAS_WAITPID) && !defined(HAS_WAIT4) || defined(HAS_WAITPID_RUNTIME)
+#define PERL_USES_PL_PIDSTATUS
+#endif
+
+#if !defined(OS2) && !defined(WIN32) && !defined(DJGPP) && !defined(EPOC) && !defined(__SYMBIAN32__) && !defined(MACOS_TRADITIONAL)
+#define PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
+#endif
+
 /* Cannot include embed.h here on Win32 as win32.h has not 
    yet been included and defines some config variables e.g. HAVE_INTERP_INTERN
  */
@@ -833,7 +856,7 @@ int usleep(unsigned int);
 #   define STRUCT_OFFSET(s,m)  (Size_t)(&(((s *)0)->m))
 #endif
 
-#ifndef SYMBIAN
+#ifndef __SYMBIAN32__
 #  if defined(I_STRING) || defined(__cplusplus)
 #     include <string.h>
 #  else
@@ -1397,6 +1420,16 @@ int sockatmark(int);
 #  define sprintf UTS_sprintf_wrap
 #endif
 
+/* For the times when you want the return value of sprintf, and you want it
+   to be the length. Can't have a thread variable passed in, because C89 has
+   no varargs macros.
+*/
+#ifdef SPRINTF_RETURNS_STRLEN
+#  define my_sprintf sprintf
+#else
+#  define my_sprintf Perl_my_sprintf
+#endif
+
 /* Configure gets this right but the UTS compiler gets it wrong.
    -- Hal Morris <hom00@utsglobal.com> */
 #ifdef UTS
@@ -1497,20 +1530,25 @@ typedef UVTYPE UV;
 #else
 #  if PTRSIZE == LONGSIZE
 #    define PTRV               unsigned long
+#    define PTR2ul(p)          (unsigned long)(p)
 #  else
 #    define PTRV               unsigned
 #  endif
+#endif
+
+#ifndef INT2PTR
 #  define INT2PTR(any,d)       (any)(PTRV)(d)
 #endif
+
+#ifndef PTR2ul
+#  define PTR2ul(p)    INT2PTR(unsigned long,p)        
+#endif
+
 #define NUM2PTR(any,d) (any)(PTRV)(d)
 #define PTR2IV(p)      INT2PTR(IV,p)
 #define PTR2UV(p)      INT2PTR(UV,p)
 #define PTR2NV(p)      NUM2PTR(NV,p)
-#if PTRSIZE == LONGSIZE
-#  define PTR2ul(p)    (unsigned long)(p)
-#else
-#  define PTR2ul(p)    INT2PTR(unsigned long,p)        
-#endif
+#define PTR2nat(p)     (PTRV)(p)       /* pointer to integer of PTRSIZE */
 
 /* According to strict ANSI C89 one cannot freely cast between
  * data pointers and function (code) pointers.  There are at least
@@ -1522,8 +1560,8 @@ typedef UVTYPE UV;
  * The only feasible use is probably temporarily storing
  * function pointers in a data pointer (such as a void pointer). */
 
-#define DPTR2FPTR(t,p) ((t)(PTRV)(p)) /* data pointer to function pointer */
-#define FPTR2DPTR(t,p) ((t)(PTRV)(p)) /* function pointer to data pointer */
+#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
+#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
 
 #ifdef USE_LONG_DOUBLE
 #  if defined(HAS_LONG_DOUBLE) && LONG_DOUBLESIZE == DOUBLESIZE
@@ -2307,7 +2345,7 @@ typedef struct clone_params CLONE_PARAMS;
 #   define ISHISH "epoc"
 #endif
 
-#ifdef SYMBIAN
+#ifdef __SYMBIAN32__
 #   include "symbian/symbianish.h"
 #   include "embed.h"
 #   define ISHISH "symbian"
@@ -2462,7 +2500,7 @@ typedef struct clone_params CLONE_PARAMS;
  * have HASATTRIBUTE_FORMAT).
  */
 
-#if defined __GNUC__
+#if defined __GNUC__ && !defined(__INTEL_COMPILER)
 #  if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
 #    define HASATTRIBUTE_FORMAT
 #  endif
@@ -2540,41 +2578,188 @@ typedef pthread_key_t  perl_key;
 #define STATUS_UNIX    PL_statusvalue
 #ifdef VMS
 #   define STATUS_NATIVE       PL_statusvalue_vms
-#   define STATUS_NATIVE_EXPORT \
-       (((I32)PL_statusvalue_vms == -1 ? 44 : PL_statusvalue_vms) | (VMSISH_HUSHED ? 0x10000000 : 0))
-#   define STATUS_NATIVE_SET(n)                                                \
+/*
+ * vaxc$errno is only guaranteed to be valid if errno == EVMSERR, otherwise
+ * its contents can not be trusted.  Unfortunately, Perl seems to check
+ * it on exit, so it when PL_statusvalue_vms is updated, vaxc$errno should
+ * be updated also.
+ */
+#  include <stsdef.h>
+#  include <ssdef.h>
+/* Presume this because if VMS changes it, it will require a new
+ * set of APIs for waiting on children for binary compatibility.
+ */
+#  define child_offset_bits (8)
+#  ifndef C_FAC_POSIX
+#  define C_FAC_POSIX 0x35A000
+#  endif
+
+/*  STATUS_EXIT - validates and returns a NATIVE exit status code for the
+ * platform from the existing UNIX or Native status values.
+ */
+
+#   define STATUS_EXIT \
+       (((I32)PL_statusvalue_vms == -1 ? SS$_ABORT : PL_statusvalue_vms) | \
+          (VMSISH_HUSHED ? STS$M_INHIB_MSG : 0))
+
+
+/* STATUS_NATIVE_CHILD_SET - Calculate UNIX status that matches the child
+ * exit code and shifts the UNIX value over the correct number of bits to
+ * be a child status.  Usually the number of bits is 8, but that could be
+ * platform dependent.  The NATIVE status code is presumed to have either
+ * from a child process.
+ */
+
+/* This is complicated.  The child processes return a true native VMS
+   status which must be saved.  But there is an assumption in Perl that
+   the UNIX child status has some relationship to errno values, so
+   Perl tries to translate it to text in some of the tests.  
+   In order to get the string translation correct, for the error, errno
+   must be EVMSERR, but that generates a different text message
+   than what the test programs are expecting.  So an errno value must
+   be derived from the native status value when an error occurs.
+   That will hide the true native status message.  With this version of
+   perl, the true native child status can always be retrieved so that
+   is not a problem.  But in this case, Pl_statusvalue and errno may
+   have different values in them.
+ */
+
+#   define STATUS_NATIVE_CHILD_SET(n) \
        STMT_START {                                                    \
-           PL_statusvalue_vms = (n);                                   \
-           if ((I32)PL_statusvalue_vms == -1)                          \
+           I32 evalue = (I32)n;                                        \
+           if (evalue == EVMSERR) {                                    \
+             PL_statusvalue_vms = vaxc$errno;                          \
+             PL_statusvalue = evalue;                                  \
+           } else {                                                    \
+             PL_statusvalue_vms = evalue;                              \
+             if (evalue == -1) {                                       \
                PL_statusvalue = -1;                                    \
-           else if (PL_statusvalue_vms & STS$M_SUCCESS)                \
-               PL_statusvalue = 0;                                     \
-           else if ((PL_statusvalue_vms & STS$M_SEVERITY) == 0)        \
-               PL_statusvalue = 1 << 8;                                \
-           else                                                        \
-               PL_statusvalue = (PL_statusvalue_vms & STS$M_SEVERITY) << 8;    \
+               PL_statusvalue_vms = SS$_ABORT; /* Should not happen */ \
+             } else                                                    \
+               PL_statusvalue = Perl_vms_status_to_unix(evalue, 1);    \
+             set_vaxc_errno(evalue);                                   \
+             if ((PL_statusvalue_vms & C_FAC_POSIX) == C_FAC_POSIX)    \
+                 set_errno(EVMSERR);                                   \
+             else set_errno(Perl_vms_status_to_unix(evalue, 0));       \
+             PL_statusvalue = PL_statusvalue << child_offset_bits;     \
+           }                                                           \
        } STMT_END
+
 #   ifdef VMSISH_STATUS
 #      define STATUS_CURRENT   (VMSISH_STATUS ? STATUS_NATIVE : STATUS_UNIX)
 #   else
 #      define STATUS_CURRENT   STATUS_UNIX
 #   endif
+
+  /* STATUS_UNIX_SET - takes a UNIX/POSIX errno value and attempts to update
+   * the NATIVE status to an equivalent value.  Can not be used to translate
+   * exit code values as exit code values are not guaranteed to have any
+   * relationship at all to errno values.
+   * This is used when Perl is forcing errno to have a specific value.
+   */
 #   define STATUS_UNIX_SET(n)                          \
        STMT_START {                                    \
-           PL_statusvalue = (n);                               \
+           I32 evalue = (I32)n;                        \
+           PL_statusvalue = evalue;                    \
            if (PL_statusvalue != -1) {                 \
-               PL_statusvalue &= 0xFFFF;                       \
-               PL_statusvalue_vms = PL_statusvalue ? 44 : 1;   \
+               if (PL_statusvalue != EVMSERR) {        \
+                 PL_statusvalue &= 0xFFFF;             \
+                 if (MY_POSIX_EXIT)                    \
+                   PL_statusvalue_vms=PL_statusvalue ? SS$_ABORT : SS$_NORMAL;\
+                 else PL_statusvalue_vms = Perl_unix_status_to_vms(evalue); \
+               }                                       \
+               else {                                  \
+                 PL_statusvalue_vms = vaxc$errno;      \
+               }                                       \
            }                                           \
-           else PL_statusvalue_vms = -1;                       \
+           else PL_statusvalue_vms = SS$_ABORT;        \
+           set_vaxc_errno(PL_statusvalue_vms);         \
        } STMT_END
-#   define STATUS_ALL_SUCCESS  (PL_statusvalue = 0, PL_statusvalue_vms = 1)
-#   define STATUS_ALL_FAILURE  (PL_statusvalue = 1, PL_statusvalue_vms = 44)
+
+  /* STATUS_UNIX_EXIT_SET - Takes a UNIX/POSIX exit code and sets
+   * the NATIVE error status based on it.  It does not assume that
+   * the UNIX/POSIX exit codes have any relationship to errno, except
+   * that 0 indicates a success.  When in the default mode to comply
+   * with the Perl VMS documentation, any other code sets the NATIVE
+   * status to a failure code of SS$_ABORT.
+   *
+   * In the new POSIX EXIT mode, native status will be set so that the
+   * actual exit code will can be retrieved by the calling program or
+   * shell.
+   *
+   * If the exit code is not clearly a UNIX parent or child exit status,
+   * it will be passed through as a VMS status.
+   */
+
+#   define STATUS_UNIX_EXIT_SET(n)                     \
+       STMT_START {                                    \
+           I32 evalue = (I32)n;                        \
+           PL_statusvalue = evalue;                    \
+           if (evalue != -1) {                         \
+             if (evalue <= 0xFF00) {                   \
+               if (evalue > 0xFF)                      \
+                 evalue = (evalue >> child_offset_bits) & 0xFF; \
+               if (evalue == 0)                        \
+                 PL_statusvalue_vms == SS$_NORMAL;     \
+               else                                    \
+                 if (MY_POSIX_EXIT)                    \
+                   PL_statusvalue_vms =        \
+                      (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \
+                       (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \
+                 else                                  \
+                   PL_statusvalue_vms = SS$_ABORT; \
+             } else { /* forgive them Perl, for they have sinned */ \
+               if (evalue != EVMSERR) PL_statusvalue_vms = evalue; \
+               else PL_statusvalue_vms = vaxc$errno;           \
+               /* And obviously used a VMS status value instead of UNIX */ \
+               PL_statusvalue = EVMSERR;                               \
+             }                                                 \
+           }                                                   \
+           else PL_statusvalue_vms = SS$_ABORT;                \
+           set_vaxc_errno(PL_statusvalue_vms);                 \
+       } STMT_END
+
+  /* STATUS_EXIT_SET - Takes a NATIVE/UNIX/POSIX exit code
+   * and sets the NATIVE error status based on it.  This special case
+   * is needed to maintain compatibility with past VMS behavior.
+   *
+   * In the default mode on VMS, this number is passed through as
+   * both the NATIVE and UNIX status.  Which makes it different
+   * that the STATUS_UNIX_EXIT_SET.
+   *
+   * In the new POSIX EXIT mode, native status will be set so that the
+   * actual exit code will can be retrieved by the calling program or
+   * shell.
+   *
+   */
+
+#   define STATUS_EXIT_SET(n)                          \
+       STMT_START {                                    \
+           I32 evalue = (I32)n;                        \
+           PL_statusvalue = evalue;                    \
+           if (MY_POSIX_EXIT)                          \
+               PL_statusvalue_vms =                    \
+                 (C_FAC_POSIX | (evalue << 3 ) | (evalue == 1)? \
+                  (STS$K_ERROR | STS$M_INHIB_MSG) : 1); \
+           else                                        \
+               PL_statusvalue_vms = evalue ? evalue : SS$_NORMAL; \
+           set_vaxc_errno(PL_statusvalue_vms);         \
+       } STMT_END
+
+
+ /* This macro forces a success status */
+#   define STATUS_ALL_SUCCESS  \
+       (PL_statusvalue = 0, PL_statusvalue_vms = SS$_NORMAL)
+
+ /* This macro forces a failure status */
+#   define STATUS_ALL_FAILURE  (PL_statusvalue = 1, \
+     vaxc$errno = PL_statusvalue_vms = MY_POSIX_EXIT ? \
+       (C_FAC_POSIX | (1 << 3) | STS$K_ERROR | STS$M_INHIB_MSG) : SS$_ABORT)
+
 #else
 #   define STATUS_NATIVE       PL_statusvalue_posix
-#   define STATUS_NATIVE_EXPORT        STATUS_NATIVE
 #   if defined(WCOREDUMP)
-#       define STATUS_NATIVE_SET(n)                        \
+#       define STATUS_NATIVE_CHILD_SET(n)                  \
             STMT_START {                                   \
                 PL_statusvalue_posix = (n);                \
                 if (PL_statusvalue_posix == -1)            \
@@ -2587,7 +2772,7 @@ typedef pthread_key_t     perl_key;
                 }                                          \
             } STMT_END
 #   elif defined(WIFEXITED)
-#       define STATUS_NATIVE_SET(n)                        \
+#       define STATUS_NATIVE_CHILD_SET(n)                  \
             STMT_START {                                   \
                 PL_statusvalue_posix = (n);                \
                 if (PL_statusvalue_posix == -1)            \
@@ -2599,7 +2784,7 @@ typedef pthread_key_t     perl_key;
                 }                                          \
             } STMT_END
 #   else
-#       define STATUS_NATIVE_SET(n)                        \
+#       define STATUS_NATIVE_CHILD_SET(n)                  \
             STMT_START {                                   \
                 PL_statusvalue_posix = (n);                \
                 if (PL_statusvalue_posix == -1)            \
@@ -2613,11 +2798,13 @@ typedef pthread_key_t   perl_key;
 #   define STATUS_UNIX_SET(n)          \
        STMT_START {                    \
            PL_statusvalue = (n);               \
-            PL_statusvalue_posix = PL_statusvalue;       \
            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)
 #endif
@@ -2689,7 +2876,7 @@ typedef pthread_key_t     perl_key;
 */
 
 #ifndef SVf_
-#  define SVf_(n) "-" #n "p"
+#  define SVf_(n) "-" STRINGIFY(n) "p"
 #endif
 
 #ifndef SVf
@@ -2710,9 +2897,7 @@ typedef pthread_key_t     perl_key;
  
 #ifndef VDf
 #  if vdNUMBER 
-#    define vdFORMAT(n) #n "p"
-#    define VDf_(n) vdFORMAT(n)
-#    define VDf VDf_(vdNUMBER)
+#    define VDf STRINGIFY(vdNUMBER) "p"
 #  else
 #    define VDf "vd"
 #  endif
@@ -2722,10 +2907,6 @@ typedef pthread_key_t    perl_key;
 #  define UVf UVuf
 #endif
 
-#ifndef DieNull
-#  define DieNull Perl_vdie(aTHX_ Nullch, Null(va_list *))
-#endif
-
 #ifdef HASATTRIBUTE_FORMAT
 #  define __attribute__format__(x,y,z)      __attribute__((format(x,y,z)))
 #endif
@@ -2792,11 +2973,16 @@ typedef pthread_key_t   perl_key;
 
 #ifndef IOCPARM_LEN
 #   ifdef IOCPARM_MASK
-       /* on BSDish systes we're safe */
+       /* on BSDish systems we're safe */
 #      define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
 #   else
+#      if defined(_IOC_SIZE) && defined(__GLIBC__)
+       /* on Linux systems we're safe; except when we're not [perl #38223] */
+#          define IOCPARM_LEN(x) (_IOC_SIZE(x) < 256 ? 256 : _IOC_SIZE(x))
+#      else
        /* otherwise guess at what's safe */
-#      define IOCPARM_LEN(x)   256
+#          define IOCPARM_LEN(x)       256
+#      endif
 #   endif
 #endif
 
@@ -3255,7 +3441,7 @@ Gid_t getegid (void);
 
 #define DEBUG_SCOPE(where) \
     DEBUG_l(WITH_THR(Perl_deb(aTHX_ "%s scope %ld at %s:%d\n", \
-                   where, PL_scopestack_ix, __FILE__, __LINE__)));
+                   where, (long)PL_scopestack_ix, __FILE__, __LINE__)));
 
 
 
@@ -3317,7 +3503,7 @@ Gid_t getegid (void);
 #ifndef assert  /* <assert.h> might have been included somehow */
 #define assert(what)   PERL_DEB(                                       \
        ((what) ? ((void) 0) :                                          \
-           (Perl_croak(aTHX_ "Assertion %s failed: file \"" __FILE__   \
+           (Perl_croak_nocontext("Assertion %s failed: file \"" __FILE__ \
                        "\", line %d", STRINGIFY(what), __LINE__),      \
            PerlProc_exit(1),                                           \
            (void) 0)))
@@ -3467,9 +3653,11 @@ char *getlogin (void);
 #endif
 #endif /* !__cplusplus */
 
+/* Fixme on VMS.  This needs to be a run-time, not build time options */
+/* Also rename() is affected by this */
 #ifdef UNLINK_ALL_VERSIONS /* Currently only makes sense for VMS */
 #define UNLINK unlnk
-I32 unlnk (char*);
+I32 unlnk (pTHX_ const char*);
 #else
 #define UNLINK PerlLIO_unlink
 #endif
@@ -3539,6 +3727,34 @@ typedef Sighandler_t Sigsave_t;
 #  define MALLOC_TERM
 #endif
 
+#if defined(PERL_IMPLICIT_CONTEXT)
+
+struct perl_memory_debug_header;
+struct perl_memory_debug_header {
+  tTHX interpreter;
+#  ifdef PERL_POISON
+  MEM_SIZE size;
+#  endif
+  struct perl_memory_debug_header *prev;
+  struct perl_memory_debug_header *next;
+};
+
+#  define sTHX (sizeof(struct perl_memory_debug_header) + \
+       (MEM_ALIGNBYTES - sizeof(struct perl_memory_debug_header) \
+        %MEM_ALIGNBYTES) % MEM_ALIGNBYTES)
+
+#endif
+
+#ifdef PERL_TRACK_MEMPOOL
+#  define INIT_TRACK_MEMPOOL(header, interp)                   \
+       STMT_START {                                            \
+               (header).interpreter = (interp);                \
+               (header).prev = (header).next = &(header);      \
+       } STMT_END
+#  else
+#  define INIT_TRACK_MEMPOOL(header, interp)
+#endif
+
 
 typedef int (CPERLscope(*runops_proc_t)) (pTHX);
 typedef void (CPERLscope(*share_proc_t)) (pTHX_ SV *sv);
@@ -3612,10 +3828,8 @@ EXTCONST char PL_no_myglob[]
   INIT("\"my\" variable %s can't be in a package");
 EXTCONST char PL_no_localize_ref[]
   INIT("Can't localize through a reference");
-#ifdef PERL_MALLOC_WRAP
 EXTCONST char PL_memory_wrap[]
   INIT("panic: memory wrap");
-#endif
 
 EXTCONST char PL_uuemap[65]
   INIT("`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
@@ -3833,6 +4047,9 @@ EXTCONST char* const PL_block_type[] = {
        "LOOP",
        "SUBST",
        "BLOCK",
+       "FORMAT",
+       "GIVEN",
+       "WHEN"
 };
 #else
 EXTCONST char* PL_block_type[];
@@ -4137,11 +4354,11 @@ END_EXTERN_C
 START_EXTERN_C
 
 #ifdef DOINIT
-#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var = {a,b,c,d,e,f,g}
-#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var = {(int (*)(pTHX_ SV *, MAGIC *))a,b,c,d,e,f,g} /* Like MGVTBL_SET but with the get magic having a const MG* */
+#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXT MGVTBL var = {a,b,c,d,e,f,g}
+#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXT MGVTBL var = {(int (*)(pTHX_ SV *, MAGIC *))a,b,c,d,e,f,g} /* Like MGVTBL_SET but with the get magic having a const MG* */
 #else
-#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var
-#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var
+#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXT MGVTBL var
+#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXT MGVTBL var
 #endif
 
 MGVTBL_SET(
@@ -4539,7 +4756,10 @@ enum {
   to_sv_amg,   to_av_amg,
   to_hv_amg,   to_gv_amg,
   to_cv_amg,   iter_amg,
-  int_amg,     DESTROY_amg,
+  int_amg,     smart_amg,
+
+  /* Note: Perl_Gv_AMupdate() assumes that DESTROY is the last entry */
+  DESTROY_amg,
   max_amg_code
   /* Do not leave a trailing comma here.  C9X allows it, C89 doesn't. */
 };
@@ -4586,7 +4806,8 @@ EXTCONST char * const PL_AMG_names[NofAMmeth] = {
   "(${}",      "(@{}",
   "(%{}",      "(*{}",
   "(&{}",      "(<>",
-  "(int",      "DESTROY",
+  "(int",      "(~~",
+  "DESTROY"
 };
 #else
 EXTCONST char * PL_AMG_names[NofAMmeth];
@@ -4884,6 +5105,7 @@ typedef struct am_table_short AMTS;
  * Code that uses these macros is responsible for the following:
  * 1. #define MY_CXT_KEY to a unique string, e.g.
  *    "DynaLoader::_guts" XS_VERSION
+ *    XXX in the current implementation, this string is ignored.
  * 2. Declare a typedef named my_cxt_t that is a structure that contains
  *    all the data that needs to be interpreter-local.
  * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
@@ -4900,35 +5122,30 @@ typedef struct am_table_short AMTS;
 /* This must appear in all extensions that define a my_cxt_t structure,
  * right after the definition (i.e. at file scope).  The non-threads
  * case below uses it to declare the data as static. */
-#define START_MY_CXT
-
-/* Fetches the SV that keeps the per-interpreter data. */
-#define dMY_CXT_SV \
-       SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY,             \
-                                 sizeof(MY_CXT_KEY)-1, TRUE)
+#define START_MY_CXT static int my_cxt_index = -1;
 
 /* This declaration should be used within all functions that use the
  * interpreter-local data. */
 #define dMY_CXT        \
-       dMY_CXT_SV;                                                     \
-       my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*, SvUV(my_cxt_sv))
+       my_cxt_t *my_cxtp = (my_cxt_t *)PL_my_cxt_list[my_cxt_index]
+#define dMY_CXT_INTERP(my_perl)        \
+       my_cxt_t *my_cxtp = (my_cxt_t *)(my_perl)->Imy_cxt_list[my_cxt_index]
 
 /* Creates and zeroes the per-interpreter data.
  * (We allocate my_cxtp in a Perl SV so that it will be released when
  * the interpreter goes away.) */
 #define MY_CXT_INIT \
-       dMY_CXT_SV;                                                     \
-       /* newSV() allocates one more than needed */                    \
-       my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
-       Zero(my_cxtp, 1, my_cxt_t);                                     \
-       sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+       my_cxt_t *my_cxtp = \
+           (my_cxt_t*)Perl_my_cxt_init(aTHX_ &my_cxt_index, sizeof(my_cxt_t))
+#define MY_CXT_INIT_INTERP(my_perl) \
+       my_cxt_t *my_cxtp = \
+           (my_cxt_t*)Perl_my_cxt_init(my_perl, &my_cxt_index, sizeof(my_cxt_t))
 
 /* Clones the per-interpreter data. */
 #define MY_CXT_CLONE \
-       dMY_CXT_SV;                                                     \
        my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
-       Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\
-       sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+       Copy(PL_my_cxt_list[my_cxt_index], my_cxtp, 1, my_cxt_t);\
+       PL_my_cxt_list[my_cxt_index] = my_cxtp                          \
 
 /* This macro must be used to access members of the my_cxt_t structure.
  * e.g. MYCXT.some_data */
@@ -4943,7 +5160,7 @@ typedef struct am_table_short AMTS;
 #define aMY_CXT_       aMY_CXT,
 #define _aMY_CXT       ,aMY_CXT
 
-#else /* USE_ITHREADS */
+#else /* PERL_IMPLICIT_CONTEXT */
 
 #define START_MY_CXT   static my_cxt_t my_cxt;
 #define dMY_CXT_SV     dNOOP
@@ -4959,7 +5176,7 @@ typedef struct am_table_short AMTS;
 #define aMY_CXT_
 #define _aMY_CXT
 
-#endif /* !defined(USE_ITHREADS) */
+#endif /* !defined(PERL_IMPLICIT_CONTEXT) */
 
 #ifdef I_FCNTL
 #  include <fcntl.h>
@@ -5216,6 +5433,17 @@ extern void moncontrol(int);
 #pragma message disable (mainparm) /* Perl uses the envp in main(). */
 #endif
 
+#define do_open(g, n, l, a, rm, rp, sf) \
+       do_openn(g, n, l, a, rm, rp, sf, (SV **) NULL, 0)
+#ifdef PERL_DEFAULT_DO_EXEC3_IMPLEMENTATION
+#  define do_exec(cmd)                 do_exec3(cmd,0,0)
+#endif
+#ifdef OS2
+#  define do_aexec                     Perl_do_aexec
+#else
+#  define do_aexec(really, mark,sp)    do_aexec5(really, mark, sp, 0, 0)
+#endif
+
 /* and finally... */
 #define PERL_PATCHLEVEL_H_IMPLICIT
 #include "patchlevel.h"