This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fcntl receiving -1 from fileno, fcntl failing.
[perl5.git] / perl.c
diff --git a/perl.c b/perl.c
index a4a05f5..8480a5d 100644 (file)
--- a/perl.c
+++ b/perl.c
 #include "perl.h"
 #include "patchlevel.h"                        /* for local_patches */
 #include "XSUB.h"
+#include "charclass_invlists.h"
 
 #ifdef NETWARE
 #include "nwutil.h"    
 #endif
 
-#ifdef USE_KERN_PROC_PATHNAME
-#  include <sys/sysctl.h>
-#endif
-
-#ifdef USE_NSGETEXECUTABLEPATH
-#  include <mach-o/dyld.h>
-#endif
-
 #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
 #  ifdef I_SYSUIO
 #    include <sys/uio.h>
@@ -58,10 +51,6 @@ union control_un {
 
 #endif
 
-#ifdef __BEOS__
-#  define HZ 1000000
-#endif
-
 #ifndef HZ
 #  ifdef CLK_TCK
 #    define HZ CLK_TCK
@@ -148,7 +137,7 @@ Perl_sys_init3(int* argc, char*** argv, char*** env)
 }
 
 void
-Perl_sys_term()
+Perl_sys_term(void)
 {
     dVAR;
     if (!PL_veto_cleanup) {
@@ -242,32 +231,14 @@ perl_construct(pTHXx)
 #endif
     PL_curcop = &PL_compiling; /* needed by ckWARN, right away */
 
-    /* set read-only and try to insure than we wont see REFCNT==0
-       very often */
-
-    SvREADONLY_on(&PL_sv_undef);
-    SvREFCNT(&PL_sv_undef) = (~(U32)0)/2;
-
-    sv_setpv(&PL_sv_no,PL_No);
-    /* value lookup in void context - happens to have the side effect
-       of caching the numeric forms. However, as &PL_sv_no doesn't contain
-       a string that is a valid numer, we have to turn the public flags by
-       hand:  */
-    SvNV(&PL_sv_no);
-    SvIV(&PL_sv_no);
-    SvIOK_on(&PL_sv_no);
-    SvNOK_on(&PL_sv_no);
-    SvREADONLY_on(&PL_sv_no);
-    SvREFCNT(&PL_sv_no) = (~(U32)0)/2;
-
-    sv_setpv(&PL_sv_yes,PL_Yes);
-    SvNV(&PL_sv_yes);
-    SvIV(&PL_sv_yes);
-    SvREADONLY_on(&PL_sv_yes);
-    SvREFCNT(&PL_sv_yes) = (~(U32)0)/2;
+#ifdef PERL_TRACE_OPS
+    Zero(PL_op_exec_cnt, OP_max+2, UV);
+#endif
+
+    init_constants();
 
     SvREADONLY_on(&PL_sv_placeholder);
-    SvREFCNT(&PL_sv_placeholder) = (~(U32)0)/2;
+    SvREFCNT(&PL_sv_placeholder) = SvREFCNT_IMMORTAL;
 
     PL_sighandlerp = (Sighandler_t) Perl_sighandler;
 #ifdef PERL_USES_PL_PIDSTATUS
@@ -284,6 +255,12 @@ perl_construct(pTHXx)
     STATUS_ALL_SUCCESS;
 
     init_i18nl10n(1);
+
+    /* Keep LC_NUMERIC in the C locale for backwards compatibility for XS
+     * modules.  (Core operations that need the underlying locale change to it
+     * temporarily).  An explicit call to POSIX::setlocale() still will cause
+     * XS module failures, but this is how it has been for a long time [perl
+     * #121317] */
     SET_NUMERIC_STANDARD();
 
 #if defined(LOCAL_PATCH_COUNT)
@@ -312,6 +289,19 @@ perl_construct(pTHXx)
 #ifdef USE_REENTRANT_API
     Perl_reentrant_init(aTHX);
 #endif
+#if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
+        /* [perl #22371] Algorimic Complexity Attack on Perl 5.6.1, 5.8.0
+         * This MUST be done before any hash stores or fetches take place.
+         * If you set PL_hash_seed (and presumably also PL_hash_seed_set)
+         * yourself, it is your responsibility to provide a good random seed!
+         * You can also define PERL_HASH_SEED in compile time, see hv.h.
+         *
+         * XXX: fix this comment */
+    if (PL_hash_seed_set == FALSE) {
+        Perl_get_hash_seed(aTHX_ PL_hash_seed);
+        PL_hash_seed_set= TRUE;
+    }
+#endif /* #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) */
 
     /* Note that strtab is a rather special HV.  Assumptions are made
        about not iterating on it, and not adding tie magic to it.
@@ -321,6 +311,8 @@ perl_construct(pTHXx)
     HvSHAREKEYS_off(PL_strtab);                        /* mandatory */
     hv_ksplit(PL_strtab, 512);
 
+    Zero(PL_sv_consts, SV_CONSTS_COUNT, SV*);
+
 #if defined(__DYNAMIC__) && (defined(NeXT) || defined(__NeXT__))
     _dyld_lookup_and_bind
        ("__environ", (unsigned long *) &environ_pointer, NULL);
@@ -334,10 +326,9 @@ perl_construct(pTHXx)
 
     /* Use sysconf(_SC_CLK_TCK) if available, if not
      * available or if the sysconf() fails, use the HZ.
-     * BeOS has those, but returns the wrong value.
      * The HZ if not originally defined has been by now
      * been defined as CLK_TCK, if available. */
-#if defined(HAS_SYSCONF) && defined(_SC_CLK_TCK) && !defined(__BEOS__)
+#if defined(HAS_SYSCONF) && defined(_SC_CLK_TCK)
     PL_clocktick = sysconf(_SC_CLK_TCK);
     if (PL_clocktick <= 0)
 #endif
@@ -396,6 +387,24 @@ perl_construct(pTHXx)
     /* Start with 1 bucket, for DFS.  It's unlikely we'll need more.  */
     HvMAX(PL_registered_mros) = 0;
 
+    PL_XPosix_ptrs[_CC_ASCII] = _new_invlist_C_array(ASCII_invlist);
+    PL_XPosix_ptrs[_CC_ALPHANUMERIC] = _new_invlist_C_array(XPosixAlnum_invlist);
+    PL_XPosix_ptrs[_CC_ALPHA] = _new_invlist_C_array(XPosixAlpha_invlist);
+    PL_XPosix_ptrs[_CC_BLANK] = _new_invlist_C_array(XPosixBlank_invlist);
+    PL_XPosix_ptrs[_CC_CASED] =  _new_invlist_C_array(Cased_invlist);
+    PL_XPosix_ptrs[_CC_CNTRL] = _new_invlist_C_array(XPosixCntrl_invlist);
+    PL_XPosix_ptrs[_CC_DIGIT] = _new_invlist_C_array(XPosixDigit_invlist);
+    PL_XPosix_ptrs[_CC_GRAPH] = _new_invlist_C_array(XPosixGraph_invlist);
+    PL_XPosix_ptrs[_CC_LOWER] = _new_invlist_C_array(XPosixLower_invlist);
+    PL_XPosix_ptrs[_CC_PRINT] = _new_invlist_C_array(XPosixPrint_invlist);
+    PL_XPosix_ptrs[_CC_PUNCT] = _new_invlist_C_array(XPosixPunct_invlist);
+    PL_XPosix_ptrs[_CC_SPACE] = _new_invlist_C_array(XPerlSpace_invlist);
+    PL_XPosix_ptrs[_CC_PSXSPC] = _new_invlist_C_array(XPosixSpace_invlist);
+    PL_XPosix_ptrs[_CC_UPPER] = _new_invlist_C_array(XPosixUpper_invlist);
+    PL_XPosix_ptrs[_CC_VERTSPACE] = _new_invlist_C_array(VertSpace_invlist);
+    PL_XPosix_ptrs[_CC_WORDCHAR] = _new_invlist_C_array(XPosixWord_invlist);
+    PL_XPosix_ptrs[_CC_XDIGIT] = _new_invlist_C_array(XPosixXDigit_invlist);
+
     ENTER;
 }
 
@@ -510,7 +519,7 @@ Perl_dump_sv_child(pTHX_ SV *sv)
     if (returned_errno || *buffer) {
        Perl_warn(aTHX_ "Debug leaking scalars child failed%s%.*s with errno"
                  " %d: %s", (*buffer ? " at " : ""), (int) *buffer, buffer + 1,
-                 returned_errno, strerror(returned_errno));
+                 returned_errno, Strerror(returned_errno));
     }
 }
 #endif
@@ -532,6 +541,7 @@ perl_destruct(pTHXx)
 #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP
     pid_t child;
 #endif
+    int i;
 
     PERL_ARGS_ASSERT_PERL_DESTRUCT;
 #ifndef MULTIPLICITY
@@ -544,13 +554,18 @@ perl_destruct(pTHXx)
     PERL_WAIT_FOR_CHILDREN;
 
     destruct_level = PL_perl_destruct_level;
-#ifdef DEBUGGING
+#if defined(DEBUGGING) || defined(PERL_TRACK_MEMPOOL)
     {
        const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
        if (s) {
             const int i = atoi(s);
-           if (destruct_level < i)
-               destruct_level = i;
+#ifdef DEBUGGING
+           if (destruct_level < i) destruct_level = i;
+#endif
+#ifdef PERL_TRACK_MEMPOOL
+            /* RT #114496, for perl_free */
+            PL_perl_destruct_level = i;
+#endif
        }
     }
 #endif
@@ -574,6 +589,20 @@ perl_destruct(pTHXx)
     /* Need to flush since END blocks can produce output */
     my_fflush_all();
 
+#ifdef PERL_TRACE_OPS
+    /* If we traced all Perl OP usage, report and clean up */
+    PerlIO_printf(Perl_debug_log, "Trace of all OPs executed:\n");
+    for (i = 0; i <= OP_max; ++i) {
+        PerlIO_printf(Perl_debug_log, "  %s: %"UVuf"\n", PL_op_name[i], PL_op_exec_cnt[i]);
+        PL_op_exec_cnt[i] = 0;
+    }
+    /* Utility slot for easily doing little tracing experiments in the runloop: */
+    if (PL_op_exec_cnt[OP_max+1] != 0)
+        PerlIO_printf(Perl_debug_log, "  SPECIAL: %"UVuf"\n", PL_op_exec_cnt[OP_max+1]);
+    PerlIO_printf(Perl_debug_log, "\n");
+#endif
+
+
     if (PL_threadhook(aTHX)) {
         /* Threads hook has vetoed further cleanup */
        PL_veto_cleanup = TRUE;
@@ -648,7 +677,7 @@ perl_destruct(pTHXx)
                msg.msg_name = NULL;
                msg.msg_namelen = 0;
                msg.msg_iov = vec;
-               msg.msg_iovlen = sizeof(vec)/sizeof(vec[0]);
+               msg.msg_iovlen = C_ARRAY_LENGTH(vec);
 
                vec[0].iov_base = (void*)&target;
                vec[0].iov_len = sizeof(target);
@@ -746,6 +775,7 @@ perl_destruct(pTHXx)
        /* ensure comppad/curpad to refer to main's pad */
        if (CvPADLIST(PL_main_cv)) {
            PAD_SET_CUR_NOSAVE(CvPADLIST(PL_main_cv), 1);
+           PL_comppad_name = PadlistNAMES(CvPADLIST(PL_main_cv));
        }
        op_free(PL_main_root);
        PL_main_root = NULL;
@@ -766,15 +796,12 @@ perl_destruct(pTHXx)
 
     PerlIO_destruct(aTHX);
 
-    if (PL_sv_objcount) {
-       /*
-        * Try to destruct global references.  We do this first so that the
-        * destructors and destructees still exist.  Some sv's might remain.
-        * Non-referenced objects are on their own.
-        */
-       sv_clean_objs();
-       PL_sv_objcount = 0;
-    }
+    /*
+     * Try to destruct global references.  We do this first so that the
+     * destructors and destructees still exist.  Some sv's might remain.
+     * Non-referenced objects are on their own.
+     */
+    sv_clean_objs();
 
     /* unhook hooks which will soon be, or use, destroyed data */
     SvREFCNT_dec(PL_warnhook);
@@ -834,6 +861,8 @@ perl_destruct(pTHXx)
         return STATUS_EXIT;
     }
 
+    /* Below, do clean up for when PERL_DESTRUCT_LEVEL is not 0 */
+
 #ifdef USE_ITHREADS
     /* the syntax tree is shared between clones
      * so op_free(PL_main_root) only ReREFCNT_dec's
@@ -849,7 +878,6 @@ perl_destruct(pTHXx)
            ary[i] = &PL_sv_undef;
        }
     }
-    Safefree(PL_stashpad);
 #endif
 
 
@@ -877,7 +905,9 @@ perl_destruct(pTHXx)
     PL_minus_F      = FALSE;
     PL_doswitches   = FALSE;
     PL_dowarn       = G_WARN_OFF;
-    PL_sawampersand = FALSE;   /* must save all match strings */
+#ifdef PERL_SAWAMPERSAND
+    PL_sawampersand = 0;       /* must save all match strings */
+#endif
     PL_unsafe       = FALSE;
 
     Safefree(PL_inplace);
@@ -936,19 +966,12 @@ perl_destruct(pTHXx)
     PL_initav = NULL;
 
     /* shortcuts just get cleared */
-    PL_envgv = NULL;
-    PL_incgv = NULL;
     PL_hintgv = NULL;
     PL_errgv = NULL;
-    PL_argvgv = NULL;
     PL_argvoutgv = NULL;
     PL_stdingv = NULL;
     PL_stderrgv = NULL;
     PL_last_in_gv = NULL;
-    PL_replgv = NULL;
-    PL_DBgv = NULL;
-    PL_DBline = NULL;
-    PL_DBsub = NULL;
     PL_DBsingle = NULL;
     PL_DBtrace = NULL;
     PL_DBsignal = NULL;
@@ -956,6 +979,21 @@ perl_destruct(pTHXx)
     PL_dbargs = NULL;
     PL_debstash = NULL;
 
+    SvREFCNT_dec(PL_envgv);
+    SvREFCNT_dec(PL_incgv);
+    SvREFCNT_dec(PL_argvgv);
+    SvREFCNT_dec(PL_replgv);
+    SvREFCNT_dec(PL_DBgv);
+    SvREFCNT_dec(PL_DBline);
+    SvREFCNT_dec(PL_DBsub);
+    PL_envgv = NULL;
+    PL_incgv = NULL;
+    PL_argvgv = NULL;
+    PL_replgv = NULL;
+    PL_DBgv = NULL;
+    PL_DBline = NULL;
+    PL_DBsub = NULL;
+
     SvREFCNT_dec(PL_argvout_stack);
     PL_argvout_stack = NULL;
 
@@ -988,18 +1026,11 @@ perl_destruct(pTHXx)
     PL_numeric_radix_sv = NULL;
 #endif
 
-    /* clear utf8 character classes */
-    SvREFCNT_dec(PL_utf8_alnum);
-    SvREFCNT_dec(PL_utf8_alpha);
-    SvREFCNT_dec(PL_utf8_blank);
-    SvREFCNT_dec(PL_utf8_space);
-    SvREFCNT_dec(PL_utf8_graph);
-    SvREFCNT_dec(PL_utf8_digit);
-    SvREFCNT_dec(PL_utf8_upper);
-    SvREFCNT_dec(PL_utf8_lower);
-    SvREFCNT_dec(PL_utf8_print);
-    SvREFCNT_dec(PL_utf8_punct);
-    SvREFCNT_dec(PL_utf8_xdigit);
+    /* clear character classes  */
+    for (i = 0; i < POSIX_SWASH_COUNT; i++) {
+        SvREFCNT_dec(PL_utf8_swash_ptrs[i]);
+        PL_utf8_swash_ptrs[i] = NULL;
+    }
     SvREFCNT_dec(PL_utf8_mark);
     SvREFCNT_dec(PL_utf8_toupper);
     SvREFCNT_dec(PL_utf8_totitle);
@@ -1007,18 +1038,13 @@ perl_destruct(pTHXx)
     SvREFCNT_dec(PL_utf8_tofold);
     SvREFCNT_dec(PL_utf8_idstart);
     SvREFCNT_dec(PL_utf8_idcont);
+    SvREFCNT_dec(PL_utf8_foldable);
     SvREFCNT_dec(PL_utf8_foldclosures);
-    PL_utf8_alnum      = NULL;
-    PL_utf8_alpha      = NULL;
-    PL_utf8_blank      = NULL;
-    PL_utf8_space      = NULL;
-    PL_utf8_graph      = NULL;
-    PL_utf8_digit      = NULL;
-    PL_utf8_upper      = NULL;
-    PL_utf8_lower      = NULL;
-    PL_utf8_print      = NULL;
-    PL_utf8_punct      = NULL;
-    PL_utf8_xdigit     = NULL;
+    SvREFCNT_dec(PL_AboveLatin1);
+    SvREFCNT_dec(PL_UpperLatin1);
+    SvREFCNT_dec(PL_Latin1);
+    SvREFCNT_dec(PL_NonL1NonFinalFold);
+    SvREFCNT_dec(PL_HasMultiCharFold);
     PL_utf8_mark       = NULL;
     PL_utf8_toupper    = NULL;
     PL_utf8_totitle    = NULL;
@@ -1027,6 +1053,15 @@ perl_destruct(pTHXx)
     PL_utf8_idstart    = NULL;
     PL_utf8_idcont     = NULL;
     PL_utf8_foldclosures = NULL;
+    PL_AboveLatin1       = NULL;
+    PL_HasMultiCharFold  = NULL;
+    PL_Latin1            = NULL;
+    PL_NonL1NonFinalFold = NULL;
+    PL_UpperLatin1       = NULL;
+    for (i = 0; i < POSIX_CC_COUNT; i++) {
+        SvREFCNT_dec(PL_XPosix_ptrs[i]);
+        PL_XPosix_ptrs[i] = NULL;
+    }
 
     if (!specialWARN(PL_compiling.cop_warnings))
        PerlMemShared_free(PL_compiling.cop_warnings);
@@ -1087,6 +1122,10 @@ perl_destruct(pTHXx)
     while (sv_clean_all() > 2)
        ;
 
+#ifdef USE_ITHREADS
+    Safefree(PL_stashpad); /* must come after sv_clean_all */
+#endif
+
     AvREAL_off(PL_fdpid);              /* no surviving entries */
     SvREFCNT_dec(PL_fdpid);            /* needed in io_close() */
     PL_fdpid = NULL;
@@ -1095,6 +1134,12 @@ perl_destruct(pTHXx)
     sys_intern_clear();
 #endif
 
+    /* constant strings */
+    for (i = 0; i < SV_CONSTS_COUNT; i++) {
+        SvREFCNT_dec(PL_sv_consts[i]);
+        PL_sv_consts[i] = NULL;
+    }
+
     /* Destruct the global string table. */
     {
        /* Yell and reset the HeVAL() slots that are still holding refcounts,
@@ -1165,7 +1210,7 @@ perl_destruct(pTHXx)
     if (PL_sv_count != 0) {
        SV* sva;
        SV* sv;
-       register SV* svend;
+       SV* svend;
 
        for (sva = PL_sv_arenaroot; sva; sva = MUTABLE_SV(SvANY(sva))) {
            svend = &sva[SvREFCNT(sva)];
@@ -1233,7 +1278,6 @@ perl_destruct(pTHXx)
     Safefree(PL_origfilename);
     PL_origfilename = NULL;
     Safefree(PL_reg_curpm);
-    Safefree(PL_reg_poscache);
     free_tied_hv_pool();
     Safefree(PL_op_mask);
     Safefree(PL_psig_name);
@@ -1246,10 +1290,9 @@ perl_destruct(pTHXx)
        PL_psig_pend = (int*)NULL;
        Safefree(psig_save);
     }
-    PL_formfeed = NULL;
     nuke_stacks();
-    PL_tainting = FALSE;
-    PL_taint_warn = FALSE;
+    TAINTING_set(FALSE);
+    TAINT_WARN_set(FALSE);
     PL_hints = 0;              /* Reset hints. Should hints be per-interpreter ? */
     PL_debug = 0;
 
@@ -1316,8 +1359,7 @@ perl_free(pTHXx)
         * Don't free thread memory if PERL_DESTRUCT_LEVEL is set to a non-zero
         * value as we're probably hunting memory leaks then
         */
-       const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
-       if (!s || atoi(s) == 0) {
+       if (PL_perl_destruct_level == 0) {
            const U32 old_debug = PL_debug;
            /* Emulate the PerlHost behaviour of free()ing all memory allocated in this
               thread at thread exit.  */
@@ -1327,7 +1369,7 @@ perl_free(pTHXx)
                PL_debug &= ~ DEBUG_m_FLAG;
            }
            while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header))
-               safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next));
+               safesysfree(PERL_MEMORY_DEBUG_HEADER_SIZE + (char *)(aTHXx->Imemory_debug_header.next));
            PL_debug = old_debug;
        }
     }
@@ -1338,13 +1380,11 @@ perl_free(pTHXx)
     {
 #    ifdef NETWARE
        void *host = nw_internal_host;
-#    else
-       void *host = w32_internal_host;
-#    endif
        PerlMem_free(aTHXx);
-#    ifdef NETWARE
        nw_delete_internal_host(host);
 #    else
+       void *host = w32_internal_host;
+       PerlMem_free(aTHXx);
        win32_delete_internal_host(host);
 #    endif
     }
@@ -1373,7 +1413,11 @@ __attribute__((destructor))
 perl_fini(void)
 {
     dVAR;
-    if (PL_curinterp  && !PL_veto_cleanup)
+    if (
+#ifdef PERL_GLOBAL_STRUCT_PRIVATE
+        my_vars &&
+#endif
+        PL_curinterp && !PL_veto_cleanup)
        FREE_THREAD_KEY;
 }
 
@@ -1390,85 +1434,6 @@ Perl_call_atexit(pTHX_ ATEXIT_t fn, void *ptr)
     ++PL_exitlistlen;
 }
 
-STATIC void
-S_set_caret_X(pTHX) {
-    dVAR;
-    GV* tmpgv = gv_fetchpvs("\030", GV_ADD|GV_NOTQUAL, SVt_PV); /* $^X */
-    if (tmpgv) {
-       SV *const caret_x = GvSV(tmpgv);
-#if defined(OS2)
-       sv_setpv(caret_x, os2_execname(aTHX));
-#else
-#  ifdef USE_KERN_PROC_PATHNAME
-       size_t size = 0;
-       int mib[4];
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_PROC;
-       mib[2] = KERN_PROC_PATHNAME;
-       mib[3] = -1;
-
-       if (sysctl(mib, 4, NULL, &size, NULL, 0) == 0
-           && size > 0 && size < MAXPATHLEN * MAXPATHLEN) {
-           sv_grow(caret_x, size);
-
-           if (sysctl(mib, 4, SvPVX(caret_x), &size, NULL, 0) == 0
-               && size > 2) {
-               SvPOK_only(caret_x);
-               SvCUR_set(caret_x, size - 1);
-               SvTAINT(caret_x);
-               return;
-           }
-       }
-#  elif defined(USE_NSGETEXECUTABLEPATH)
-       char buf[1];
-       uint32_t size = sizeof(buf);
-
-       _NSGetExecutablePath(buf, &size);
-       if (size < MAXPATHLEN * MAXPATHLEN) {
-           sv_grow(caret_x, size);
-           if (_NSGetExecutablePath(SvPVX(caret_x), &size) == 0) {
-               char *const tidied = realpath(SvPVX(caret_x), NULL);
-               if (tidied) {
-                   sv_setpv(caret_x, tidied);
-                   free(tidied);
-               } else {
-                   SvPOK_only(caret_x);
-                   SvCUR_set(caret_x, size);
-               }
-               return;
-           }
-       }
-#  elif defined(HAS_PROCSELFEXE)
-       char buf[MAXPATHLEN];
-       int len = readlink(PROCSELFEXE_PATH, buf, sizeof(buf) - 1);
-
-       /* On Playstation2 Linux V1.0 (kernel 2.2.1) readlink(/proc/self/exe)
-          includes a spurious NUL which will cause $^X to fail in system
-          or backticks (this will prevent extensions from being built and
-          many tests from working). readlink is not meant to add a NUL.
-          Normal readlink works fine.
-       */
-       if (len > 0 && buf[len-1] == '\0') {
-           len--;
-       }
-
-       /* FreeBSD's implementation is acknowledged to be imperfect, sometimes
-          returning the text "unknown" from the readlink rather than the path
-          to the executable (or returning an error from the readlink). Any
-          valid path has a '/' in it somewhere, so use that to validate the
-          result. See http://www.freebsd.org/cgi/query-pr.cgi?pr=35703
-       */
-       if (len > 0 && memchr(buf, '/', len)) {
-           sv_setpvn(caret_x, buf, len);
-           return;
-       }
-#  endif
-       /* Fallback to this:  */
-       sv_setpv(caret_x, PL_origargv[0]);
-#endif
-    }
-}
-
 /*
 =for apidoc perl_parse
 
@@ -1495,23 +1460,26 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
 #ifndef MULTIPLICITY
     PERL_UNUSED_ARG(my_perl);
 #endif
-
-#if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)
-    /* [perl #22371] Algorimic Complexity Attack on Perl 5.6.1, 5.8.0
-     * This MUST be done before any hash stores or fetches take place.
-     * If you set PL_rehash_seed (and presumably also PL_rehash_seed_set)
-     * yourself, it is your responsibility to provide a good random seed!
-     * You can also define PERL_HASH_SEED in compile time, see hv.h. */
-    if (!PL_rehash_seed_set)
-        PL_rehash_seed = get_hash_seed();
+#if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) || defined(USE_HASH_SEED_DEBUG)
     {
-       const char * const s = PerlEnv_getenv("PERL_HASH_SEED_DEBUG");
-
-       if (s && (atoi(s) == 1))
-           PerlIO_printf(Perl_debug_log, "HASH_SEED = %"UVuf"\n", PL_rehash_seed);
+        const char * const s = PerlEnv_getenv("PERL_HASH_SEED_DEBUG");
+
+        if (s && (atoi(s) == 1)) {
+            unsigned char *seed= PERL_HASH_SEED;
+            unsigned char *seed_end= PERL_HASH_SEED + PERL_HASH_SEED_BYTES;
+            PerlIO_printf(Perl_debug_log, "HASH_FUNCTION = %s HASH_SEED = 0x", PERL_HASH_FUNC);
+            while (seed < seed_end) {
+                PerlIO_printf(Perl_debug_log, "%02x", *seed++);
+            }
+#ifdef PERL_HASH_RANDOMIZE_KEYS
+            PerlIO_printf(Perl_debug_log, " PERTURB_KEYS = %d (%s)",
+                    PL_HASH_RAND_BITS_ENABLED,
+                    PL_HASH_RAND_BITS_ENABLED == 0 ? "NO" : PL_HASH_RAND_BITS_ENABLED == 1 ? "RANDOM" : "DETERMINISTIC");
+#endif
+            PerlIO_printf(Perl_debug_log, "\n");
+        }
     }
 #endif /* #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) */
-
     PL_origargc = argc;
     PL_origargv = argv;
 
@@ -1528,8 +1496,7 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
         * --jhi */
         const char *s = NULL;
         int i;
-        const UV mask =
-          ~(UV)(PTRSIZE == 4 ? 3 : PTRSIZE == 8 ? 7 : PTRSIZE == 16 ? 15 : 0);
+        const UV mask = ~(UV)(PTRSIZE-1);
          /* Do the mask check only if the args seem like aligned. */
         const UV aligned =
           (mask < ~(UV)0) && ((PTR2UV(argv[0]) & mask) == PTR2UV(argv[0]));
@@ -1613,9 +1580,9 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env)
        PL_do_undump = FALSE;
        cxstack_ix = -1;                /* start label stack again */
        init_ids();
-       assert (!PL_tainted);
+       assert (!TAINT_get);
        TAINT;
-       S_set_caret_X(aTHX);
+       set_caret_X();
        TAINT_NOT;
        init_postdump_symbols(argc,argv,env);
        return 0;
@@ -1689,13 +1656,22 @@ S_Internals_V(pTHX_ CV *cv)
 #endif
     const int entries = 3 + local_patch_count;
     int i;
-    static char non_bincompat_options[] = 
+    static const char non_bincompat_options[] = 
 #  ifdef DEBUGGING
                             " DEBUGGING"
 #  endif
 #  ifdef NO_MATHOMS
                             " NO_MATHOMS"
 #  endif
+#  ifdef NO_HASH_SEED
+                            " NO_HASH_SEED"
+#  endif
+#  ifdef NO_TAINT_SUPPORT
+                            " NO_TAINT_SUPPORT"
+#  endif
+#  ifdef PERL_BOOL_AS_CHAR
+                            " PERL_BOOL_AS_CHAR"
+#  endif
 #  ifdef PERL_DISABLE_PMC
                             " PERL_DISABLE_PMC"
 #  endif
@@ -1705,6 +1681,30 @@ S_Internals_V(pTHX_ CV *cv)
 #  ifdef PERL_EXTERNAL_GLOB
                             " PERL_EXTERNAL_GLOB"
 #  endif
+#  ifdef PERL_HASH_FUNC_SIPHASH
+                            " PERL_HASH_FUNC_SIPHASH"
+#  endif
+#  ifdef PERL_HASH_FUNC_SDBM
+                            " PERL_HASH_FUNC_SDBM"
+#  endif
+#  ifdef PERL_HASH_FUNC_DJB2
+                            " PERL_HASH_FUNC_DJB2"
+#  endif
+#  ifdef PERL_HASH_FUNC_SUPERFAST
+                            " PERL_HASH_FUNC_SUPERFAST"
+#  endif
+#  ifdef PERL_HASH_FUNC_MURMUR3
+                            " PERL_HASH_FUNC_MURMUR3"
+#  endif
+#  ifdef PERL_HASH_FUNC_ONE_AT_A_TIME
+                            " PERL_HASH_FUNC_ONE_AT_A_TIME"
+#  endif
+#  ifdef PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
+                            " PERL_HASH_FUNC_ONE_AT_A_TIME_HARD"
+#  endif
+#  ifdef PERL_HASH_FUNC_ONE_AT_A_TIME_OLD
+                            " PERL_HASH_FUNC_ONE_AT_A_TIME_OLD"
+#  endif
 #  ifdef PERL_IS_MINIPERL
                             " PERL_IS_MINIPERL"
 #  endif
@@ -1717,6 +1717,18 @@ S_Internals_V(pTHX_ CV *cv)
 #  ifdef PERL_MEM_LOG_NOIMPL
                             " PERL_MEM_LOG_NOIMPL"
 #  endif
+#  ifdef PERL_NEW_COPY_ON_WRITE
+                            " PERL_NEW_COPY_ON_WRITE"
+#  endif
+#  ifdef PERL_PERTURB_KEYS_DETERMINISTIC
+                            " PERL_PERTURB_KEYS_DETERMINISTIC"
+#  endif
+#  ifdef PERL_PERTURB_KEYS_DISABLED
+                            " PERL_PERTURB_KEYS_DISABLED"
+#  endif
+#  ifdef PERL_PERTURB_KEYS_RANDOM
+                            " PERL_PERTURB_KEYS_RANDOM"
+#  endif
 #  ifdef PERL_PRESERVE_IVUV
                             " PERL_PRESERVE_IVUV"
 #  endif
@@ -1738,6 +1750,9 @@ S_Internals_V(pTHX_ CV *cv)
 #  ifdef USE_FAST_STDIO
                             " USE_FAST_STDIO"
 #  endif              
+#  ifdef USE_HASH_SEED_EXPLICIT
+                            " USE_HASH_SEED_EXPLICIT"
+#  endif
 #  ifdef USE_LOCALE
                             " USE_LOCALE"
 #  endif
@@ -1799,7 +1814,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     char **argv = PL_origargv;
     const char *scriptname = NULL;
     VOL bool dosearch = FALSE;
-    register char c;
+    char c;
     bool doextract = FALSE;
     const char *cddir = NULL;
 #ifdef USE_SITECUSTOMIZE
@@ -1851,17 +1866,31 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
            break;
 
        case 't':
+#if defined(SILENT_NO_TAINT_SUPPORT)
+            /* silently ignore */
+#elif defined(NO_TAINT_SUPPORT)
+            Perl_croak_nocontext("This perl was compiled without taint support. "
+                       "Cowardly refusing to run with -t or -T flags");
+#else
            CHECK_MALLOC_TOO_LATE_FOR('t');
-           if( !PL_tainting ) {
-                PL_taint_warn = TRUE;
-                PL_tainting = TRUE;
+           if( !TAINTING_get ) {
+                TAINT_WARN_set(TRUE);
+                TAINTING_set(TRUE);
            }
+#endif
            s++;
            goto reswitch;
        case 'T':
+#if defined(SILENT_NO_TAINT_SUPPORT)
+            /* silently ignore */
+#elif defined(NO_TAINT_SUPPORT)
+            Perl_croak_nocontext("This perl was compiled without taint support. "
+                       "Cowardly refusing to run with -t or -T flags");
+#else
            CHECK_MALLOC_TOO_LATE_FOR('T');
-           PL_tainting = TRUE;
-           PL_taint_warn = FALSE;
+           TAINTING_set(TRUE);
+           TAINT_WARN_set(FALSE);
+#endif
            s++;
            goto reswitch;
 
@@ -1962,16 +1991,23 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 
     if (
 #ifndef SECURE_INTERNAL_GETENV
-        !PL_tainting &&
+        !TAINTING_get &&
 #endif
        (s = PerlEnv_getenv("PERL5OPT")))
     {
        while (isSPACE(*s))
            s++;
        if (*s == '-' && *(s+1) == 'T') {
+#if defined(SILENT_NO_TAINT_SUPPORT)
+            /* silently ignore */
+#elif defined(NO_TAINT_SUPPORT)
+            Perl_croak_nocontext("This perl was compiled without taint support. "
+                       "Cowardly refusing to run with -t or -T flags");
+#else
            CHECK_MALLOC_TOO_LATE_FOR('T');
-           PL_tainting = TRUE;
-            PL_taint_warn = FALSE;
+           TAINTING_set(TRUE);
+            TAINT_WARN_set(FALSE);
+#endif
        }
        else {
            char *popt_copy = NULL;
@@ -2001,10 +2037,17 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
                    }
                }
                if (*d == 't') {
-                   if( !PL_tainting ) {
-                       PL_taint_warn = TRUE;
-                       PL_tainting = TRUE;
+#if defined(SILENT_NO_TAINT_SUPPORT)
+            /* silently ignore */
+#elif defined(NO_TAINT_SUPPORT)
+                    Perl_croak_nocontext("This perl was compiled without taint support. "
+                               "Cowardly refusing to run with -t or -T flags");
+#else
+                   if( !TAINTING_get) {
+                       TAINT_WARN_set(TRUE);
+                       TAINTING_set(TRUE);
                    }
+#endif
                } else {
                    moreswitches(d);
                }
@@ -2015,9 +2058,9 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 
     /* Set $^X early so that it can be used for relocatable paths in @INC  */
     /* and for SITELIB_EXP in USE_SITECUSTOMIZE                            */
-    assert (!PL_tainted);
+    assert (!TAINT_get);
     TAINT;
-    S_set_caret_X(aTHX);
+    set_caret_X();
     TAINT_NOT;
 
 #if defined(USE_SITECUSTOMIZE)
@@ -2031,9 +2074,11 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
        SV **const inc0 = inc ? av_fetch(inc, 0, FALSE) : NULL;
 
        if (inc0) {
+            /* if lib/buildcustomize.pl exists, it should not fail. If it does,
+               it should be reported immediately as a build failure.  */
            (void)Perl_av_create_and_unshift_one(aTHX_ &PL_preambleav,
                                                 Perl_newSVpvf(aTHX_
-                                                              "BEGIN { do {local $!; -f q%c%"SVf"/buildcustomize.pl%c} && do q%c%"SVf"/buildcustomize.pl%c }",
+        "BEGIN { do {local $!; -f q%c%"SVf"/buildcustomize.pl%c} and do q%c%"SVf"/buildcustomize.pl%c || die $@ }",
                                                               0, *inc0, 0,
                                                               0, *inc0, 0));
        }
@@ -2071,7 +2116,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
        scriptname = "-";
     }
 
-    assert (!PL_tainted);
+    assert (!TAINT_get);
     init_perllib();
 
     {
@@ -2131,7 +2176,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
     if (xsinit)
        (*xsinit)(aTHX);        /* in case linked C routines want magical variables */
 #ifndef PERL_MICRO
-#if defined(VMS) || defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(EPOC) || defined(SYMBIAN)
+#if defined(VMS) || defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(SYMBIAN)
     init_os_extras();
 #endif
 #endif
@@ -2214,7 +2259,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #ifdef PERL_MAD
     {
        const char *s;
-    if ((s = PerlEnv_getenv("PERL_XMLDUMP"))) {
+    if (!TAINTING_get &&
+        (s = PerlEnv_getenv("PERL_XMLDUMP"))) {
        PL_madskills = 1;
        PL_minus_c = 1;
        if (!s || !s[0])
@@ -2238,8 +2284,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
 #endif
 
     lex_start(linestr_sv, rsfp, lex_start_flags);
-    if(linestr_sv)
-       SvREFCNT_dec(linestr_sv);
+    SvREFCNT_dec(linestr_sv);
 
     PL_subname = newSVpvs("main");
 
@@ -2360,8 +2405,9 @@ STATIC void
 S_run_body(pTHX_ I32 oldscope)
 {
     dVAR;
-    DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n",
-                    PL_sawampersand ? "Enabling" : "Omitting"));
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support (0x%x).\n",
+                    PL_sawampersand ? "Enabling" : "Omitting",
+                    (unsigned int)(PL_sawampersand)));
 
     if (!PL_restartop) {
 #ifdef PERL_MAD
@@ -2418,7 +2464,7 @@ S_run_body(pTHX_ I32 oldscope)
 =for apidoc p||get_sv
 
 Returns the SV of the specified Perl scalar.  C<flags> are passed to
-C<gv_fetchpv>. If C<GV_ADD> is set and the
+C<gv_fetchpv>.  If C<GV_ADD> is set and the
 Perl variable does not exist then it will be created.  If C<flags> is zero
 and the variable does not exist then NULL is returned.
 
@@ -2445,7 +2491,7 @@ Perl_get_sv(pTHX_ const char *name, I32 flags)
 
 Returns the AV of the specified Perl global or package array with the given
 name (so it won't work on lexical variables).  C<flags> are passed 
-to C<gv_fetchpv>. If C<GV_ADD> is set and the
+to C<gv_fetchpv>.  If C<GV_ADD> is set and the
 Perl variable does not exist then it will be created.  If C<flags> is zero
 and the variable does not exist then NULL is returned.
 
@@ -2474,7 +2520,7 @@ Perl_get_av(pTHX_ const char *name, I32 flags)
 =for apidoc p||get_hv
 
 Returns the HV of the specified Perl hash.  C<flags> are passed to
-C<gv_fetchpv>. If C<GV_ADD> is set and the
+C<gv_fetchpv>.  If C<GV_ADD> is set and the
 Perl variable does not exist then it will be created.  If C<flags> is zero
 and the variable does not exist then NULL is returned.
 
@@ -2501,7 +2547,7 @@ Perl_get_hv(pTHX_ const char *name, I32 flags)
 =for apidoc p||get_cvn_flags
 
 Returns the CV of the specified Perl subroutine.  C<flags> are passed to
-C<gv_fetchpvn_flags>. If C<GV_ADD> is set and the Perl subroutine does not
+C<gv_fetchpvn_flags>.  If C<GV_ADD> is set and the Perl subroutine does not
 exist then it will be declared (which has the same effect as saying
 C<sub name;>).  If C<GV_ADD> is not set and the subroutine does not exist
 then NULL is returned.
@@ -2550,7 +2596,8 @@ Perl_get_cv(pTHX_ const char *name, I32 flags)
 =for apidoc p||call_argv
 
 Performs a callback to the specified named and package-scoped Perl subroutine 
-with C<argv> (a NULL-terminated array of strings) as arguments. See L<perlcall>.
+with C<argv> (a NULL-terminated array of strings) as arguments.  See
+L<perlcall>.
 
 Approximate Perl equivalent: C<&{"$sub_name"}(@$argv)>.
 
@@ -2558,7 +2605,7 @@ Approximate Perl equivalent: C<&{"$sub_name"}(@$argv)>.
 */
 
 I32
-Perl_call_argv(pTHX_ const char *sub_name, I32 flags, register char **argv)
+Perl_call_argv(pTHX_ const char *sub_name, I32 flags, char **argv)
 
                        /* See G_* flags in cop.h */
                        /* null terminated arg list */
@@ -2612,12 +2659,15 @@ Perl_call_method(pTHX_ const char *methname, I32 flags)
                        /* See G_* flags in cop.h */
 {
     STRLEN len;
+    SV* sv;
     PERL_ARGS_ASSERT_CALL_METHOD;
 
     len = strlen(methname);
+    sv = flags & G_METHOD_NAMED
+        ? sv_2mortal(newSVpvn_share(methname, len,0))
+        : newSVpvn_flags(methname, len, SVs_TEMP);
 
-    /* XXX: sv_2mortal(newSVpvn_share(methname, len)) can be faster */
-    return call_sv(newSVpvn_flags(methname, len, SVs_TEMP), flags | G_METHOD);
+    return call_sv(sv, flags | G_METHOD);
 }
 
 /* May be called with any of a CV, a GV, or an SV containing the name. */
@@ -2636,7 +2686,8 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
 {
     dVAR; dSP;
     LOGOP myop;                /* fake syntax tree node */
-    UNOP method_op;
+    UNOP method_unop;
+    SVOP method_svop;
     I32 oldmark;
     VOL I32 retval = 0;
     I32 oldscope;
@@ -2658,7 +2709,6 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
     }
 
     Zero(&myop, 1, LOGOP);
-    myop.op_next = NULL;
     if (!(flags & G_NOARGS))
        myop.op_flags |= OPf_STACKED;
     myop.op_flags |= OP_GIMME_REVERSE(flags);
@@ -2666,7 +2716,8 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
     PL_op = (OP*)&myop;
 
     EXTEND(PL_stack_sp, 1);
-    *++PL_stack_sp = sv;
+    if (!(flags & G_METHOD_NAMED))
+        *++PL_stack_sp = sv;
     oldmark = TOPMARK;
     oldscope = PL_scopestack_ix;
 
@@ -2677,16 +2728,26 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
            * curstash may be meaningless. */
          && (SvTYPE(sv) != SVt_PVCV || CvSTASH((const CV *)sv) != PL_debstash)
          && !(flags & G_NODEBUG))
-       PL_op->op_private |= OPpENTERSUB_DB;
-
-    if (flags & G_METHOD) {
-       Zero(&method_op, 1, UNOP);
-       method_op.op_next = PL_op;
-       method_op.op_ppaddr = PL_ppaddr[OP_METHOD];
-       method_op.op_type = OP_METHOD;
-       myop.op_ppaddr = PL_ppaddr[OP_ENTERSUB];
-       myop.op_type = OP_ENTERSUB;
-       PL_op = (OP*)&method_op;
+       myop.op_private |= OPpENTERSUB_DB;
+
+    if (flags & (G_METHOD|G_METHOD_NAMED)) {
+        if ( flags & G_METHOD_NAMED ) {
+            Zero(&method_svop, 1, SVOP);
+            method_svop.op_next = (OP*)&myop;
+            method_svop.op_ppaddr = PL_ppaddr[OP_METHOD_NAMED];
+            method_svop.op_type = OP_METHOD_NAMED;
+            method_svop.op_sv = sv;
+            PL_op = (OP*)&method_svop;
+        } else {
+            Zero(&method_unop, 1, UNOP);
+            method_unop.op_next = (OP*)&myop;
+            method_unop.op_ppaddr = PL_ppaddr[OP_METHOD];
+            method_unop.op_type = OP_METHOD;
+            PL_op = (OP*)&method_unop;
+        }
+        myop.op_ppaddr = PL_ppaddr[OP_ENTERSUB];
+        myop.op_type = OP_ENTERSUB;
+
     }
 
     if (!(flags & G_EVAL)) {
@@ -2759,8 +2820,8 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags)
 /*
 =for apidoc p||eval_sv
 
-Tells Perl to C<eval> the string in the SV. It supports the same flags
-as C<call_sv>, with the obvious exception of G_EVAL. See L<perlcall>.
+Tells Perl to C<eval> the string in the SV.  It supports the same flags
+as C<call_sv>, with the obvious exception of G_EVAL.  See L<perlcall>.
 
 =cut
 */
@@ -2788,19 +2849,19 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
 
     SAVEOP();
     PL_op = (OP*)&myop;
-    Zero(PL_op, 1, UNOP);
+    Zero(&myop, 1, UNOP);
     EXTEND(PL_stack_sp, 1);
     *++PL_stack_sp = sv;
 
     if (!(flags & G_NOARGS))
        myop.op_flags = OPf_STACKED;
-    myop.op_next = NULL;
     myop.op_type = OP_ENTEREVAL;
     myop.op_flags |= OP_GIMME_REVERSE(flags);
     if (flags & G_KEEPERR)
        myop.op_flags |= OPf_SPECIAL;
-    if (PL_reg_state.re_reparsing)
-       myop.op_private = OPpEVAL_COPHH;
+
+    if (flags & G_RE_REPARSING)
+       myop.op_private = (OPpEVAL_COPHH | OPpEVAL_RE_REPARSING);
 
     /* fail now; otherwise we could fail after the JMPENV_PUSH but
      * before a PUSHEVAL, which corrupts the stack after a croak */
@@ -2872,7 +2933,6 @@ SV*
 Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
 {
     dVAR;
-    dSP;
     SV* sv = newSVpv(p, 0);
 
     PERL_ARGS_ASSERT_EVAL_PV;
@@ -2880,12 +2940,18 @@ Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
     eval_sv(sv, G_SCALAR);
     SvREFCNT_dec(sv);
 
-    SPAGAIN;
-    sv = POPs;
-    PUTBACK;
+    {
+        dSP;
+        sv = POPs;
+        PUTBACK;
+    }
 
-    if (croak_on_error && SvTRUE(ERRSV)) {
-       Perl_croak(aTHX_ "%s", SvPVx_nolen_const(ERRSV));
+    /* just check empty string or undef? */
+    if (croak_on_error) {
+       SV * const errsv = ERRSV;
+       if(SvTRUE_NN(errsv))
+           /* replace with croak_sv? */
+           Perl_croak_nocontext("%s", SvPV_nolen_const(errsv));
     }
 
     return sv;
@@ -2914,10 +2980,8 @@ Perl_require_pv(pTHX_ const char *pv)
     PERL_ARGS_ASSERT_REQUIRE_PV;
 
     PUSHSTACKi(PERLSI_REQUIRE);
-    PUTBACK;
     sv = Perl_newSVpvf(aTHX_ "require q%c%s%c", 0, pv, 0);
     eval_sv(sv_2mortal(sv), G_DISCARD);
-    SPAGAIN;
     POPSTACK;
 }
 
@@ -3007,6 +3071,7 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
       "  q  quiet - currently only suppresses the 'EXECUTING' message\n"
       "  M  trace smart match resolution\n"
       "  B  dump suBroutine definitions, including special Blocks like BEGIN\n",
+      "  L  trace some locale setting information--for Perl core development\n",
       NULL
     };
     int i = 0;
@@ -3015,9 +3080,9 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
 
     if (isALPHA(**s)) {
        /* if adding extra options, remember to update DEBUG_MASK */
-       static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAqMB";
+       static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAqMBL";
 
-       for (; isALNUM(**s); (*s)++) {
+       for (; isWORDCHAR(**s); (*s)++) {
            const char * const d = strchr(debopts,**s);
            if (d)
                i |= 1 << (d - debopts);
@@ -3028,7 +3093,7 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
     }
     else if (isDIGIT(**s)) {
        i = atoi(*s);
-       for (; isALNUM(**s); (*s)++) ;
+       for (; isWORDCHAR(**s); (*s)++) ;
     }
     else if (givehelp) {
       const char *const *p = usage_msgd;
@@ -3104,13 +3169,16 @@ Perl_moreswitches(pTHX_ const char *s)
            PL_utf8cache = -1;
        return s;
     case 'F':
+       PL_minus_a = TRUE;
        PL_minus_F = TRUE;
+        PL_minus_n = TRUE;
        PL_splitstr = ++s;
        while (*s && !isSPACE(*s)) ++s;
        PL_splitstr = savepvn(PL_splitstr, s - PL_splitstr);
        return s;
     case 'a':
        PL_minus_a = TRUE;
+        PL_minus_n = TRUE;
        s++;
        return s;
     case 'c':
@@ -3122,7 +3190,7 @@ Perl_moreswitches(pTHX_ const char *s)
        s++;
 
         /* -dt indicates to the debugger that threads will be used */
-       if (*s == 't' && !isALNUM(s[1])) {
+       if (*s == 't' && !isWORDCHAR(s[1])) {
            ++s;
            my_setenv("PERL5DB_THREADED", "1");
        }
@@ -3145,7 +3213,7 @@ Perl_moreswitches(pTHX_ const char *s)
            end = s + strlen(s);
 
            /* We now allow -d:Module=Foo,Bar and -d:-Module */
-           while(isALNUM(*s) || *s==':') ++s;
+           while(isWORDCHAR(*s) || *s==':') ++s;
            if (*s != '=')
                sv_catpvn(sv, start, end - start);
            else {
@@ -3173,7 +3241,7 @@ Perl_moreswitches(pTHX_ const char *s)
        if (ckWARN_d(WARN_DEBUGGING))
            Perl_warner(aTHX_ packWARN(WARN_DEBUGGING),
                   "Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)\n");
-       for (s++; isALNUM(*s); s++) ;
+       for (s++; isWORDCHAR(*s); s++) ;
 #endif
        return s;
     }  
@@ -3266,7 +3334,7 @@ Perl_moreswitches(pTHX_ const char *s)
            sv = newSVpvn(use,4);
            start = s;
            /* We allow -M'Module qw(Foo Bar)'  */
-           while(isALNUM(*s) || *s==':') {
+           while(isWORDCHAR(*s) || *s==':') {
                if( *s++ == ':' ) {
                    if( *s == ':' ) 
                        s++;
@@ -3318,8 +3386,15 @@ Perl_moreswitches(pTHX_ const char *s)
        return s;
     case 't':
     case 'T':
-        if (!PL_tainting)
+#if defined(SILENT_NO_TAINT_SUPPORT)
+            /* silently ignore */
+#elif defined(NO_TAINT_SUPPORT)
+        Perl_croak_nocontext("This perl was compiled without taint support. "
+                   "Cowardly refusing to run with -t or -T flags");
+#else
+        if (!TAINTING_get)
            TOO_LATE_FOR(*s);
+#endif
         s++;
        return s;
     case 'u':
@@ -3389,116 +3464,96 @@ Perl_moreswitches(pTHX_ const char *s)
 STATIC void
 S_minus_v(pTHX)
 {
-       if (!sv_derived_from(PL_patchlevel, "version"))
-           upg_version(PL_patchlevel, TRUE);
-#if !defined(DGUX)
+       PerlIO * PIO_stdout;
        {
-           SV* level= vstringify(PL_patchlevel);
+           const char * const level_str = "v" PERL_VERSION_STRING;
+           const STRLEN level_len = sizeof("v" PERL_VERSION_STRING)-1;
 #ifdef PERL_PATCHNUM
+           SV* level;
 #  ifdef PERL_GIT_UNCOMMITTED_CHANGES
-           SV *num = newSVpvs(PERL_PATCHNUM "*");
+           static const char num [] = PERL_PATCHNUM "*";
 #  else
-           SV *num = newSVpvs(PERL_PATCHNUM);
+           static const char num [] = PERL_PATCHNUM;
 #  endif
-
-           if (sv_len(num)>=sv_len(level) && strnEQ(SvPV_nolen(num),SvPV_nolen(level),sv_len(level))) {
-               SvREFCNT_dec(level);
-               level= num;
-           } else {
-               Perl_sv_catpvf(aTHX_ level, " (%"SVf")", num);
-               SvREFCNT_dec(num);
+           {
+               const STRLEN num_len = sizeof(num)-1;
+               /* A very advanced compiler would fold away the strnEQ
+                  and this whole conditional, but most (all?) won't do it.
+                  SV level could also be replaced by with preprocessor
+                  catenation.
+               */
+               if (num_len >= level_len && strnEQ(num,level_str,level_len)) {
+                   /* per 46807d8e80, PERL_PATCHNUM is outside of the control
+                      of the interp so it might contain format characters
+                   */
+                   level = newSVpvn(num, num_len);
+               } else {
+                   level = Perl_newSVpvf_nocontext("%s (%s)", level_str, num);
+               }
            }
- #endif
-           PerlIO_printf(PerlIO_stdout(),
+#else
+       SV* level = newSVpvn(level_str, level_len);
+#endif /* #ifdef PERL_PATCHNUM */
+       PIO_stdout =  PerlIO_stdout();
+           PerlIO_printf(PIO_stdout,
                "\nThis is perl "       STRINGIFY(PERL_REVISION)
                ", version "            STRINGIFY(PERL_VERSION)
                ", subversion "         STRINGIFY(PERL_SUBVERSION)
                " (%"SVf") built for "  ARCHNAME, level
                );
-           SvREFCNT_dec(level);
+           SvREFCNT_dec_NN(level);
        }
-#else /* DGUX */
-/* Adjust verbose output as in the perl that ships with the DG/UX OS from EMC */
-       PerlIO_printf(PerlIO_stdout(),
-               Perl_form(aTHX_ "\nThis is perl, %"SVf"\n",
-                   SVfARG(vstringify(PL_patchlevel))));
-       PerlIO_printf(PerlIO_stdout(),
-                       Perl_form(aTHX_ "        built under %s at %s %s\n",
-                                       OSNAME, __DATE__, __TIME__));
-       PerlIO_printf(PerlIO_stdout(),
-                       Perl_form(aTHX_ "        OS Specific Release: %s\n",
-                                       OSVERS));
-#endif /* !DGUX */
 #if defined(LOCAL_PATCH_COUNT)
        if (LOCAL_PATCH_COUNT > 0)
-           PerlIO_printf(PerlIO_stdout(),
+           PerlIO_printf(PIO_stdout,
                          "\n(with %d registered patch%s, "
                          "see perl -V for more detail)",
                          LOCAL_PATCH_COUNT,
                          (LOCAL_PATCH_COUNT!=1) ? "es" : "");
 #endif
 
-       PerlIO_printf(PerlIO_stdout(),
-                     "\n\nCopyright 1987-2012, Larry Wall\n");
+       PerlIO_printf(PIO_stdout,
+                     "\n\nCopyright 1987-2014, Larry Wall\n");
 #ifdef MSDOS
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
 #endif
 #ifdef DJGPP
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n"
                      "djgpp v2 port (perl5004+) by Laszlo Molnar, 1997-1999\n");
 #endif
 #ifdef OS2
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
                      "Version 5 port Copyright (c) 1994-2002, Andreas Kaiser, Ilya Zakharevich\n");
 #endif
-#ifdef atarist
-       PerlIO_printf(PerlIO_stdout(),
-                     "atariST series port, ++jrb  bammi@cadence.com\n");
-#endif
-#ifdef __BEOS__
-       PerlIO_printf(PerlIO_stdout(),
-                     "BeOS port Copyright Tom Spindler, 1997-1999\n");
-#endif
-#ifdef MPE
-       PerlIO_printf(PerlIO_stdout(),
-                     "MPE/iX port Copyright by Mark Klein and Mark Bixby, 1996-2003\n");
-#endif
 #ifdef OEMVS
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "MVS (OS390) port by Mortice Kern Systems, 1997-1999\n");
 #endif
 #ifdef __VOS__
-       PerlIO_printf(PerlIO_stdout(),
-                     "Stratus VOS port by Paul.Green@stratus.com, 1997-2002\n");
-#endif
-#ifdef __OPEN_VM
-       PerlIO_printf(PerlIO_stdout(),
-                     "VM/ESA port by Neale Ferguson, 1998-1999\n");
+       PerlIO_printf(PIO_stdout,
+                     "Stratus OpenVOS port by Paul.Green@stratus.com, 1997-2013\n");
 #endif
 #ifdef POSIX_BC
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "BS2000 (POSIX) port by Start Amadeus GmbH, 1998-1999\n");
 #endif
-#ifdef EPOC
-       PerlIO_printf(PerlIO_stdout(),
-                     "EPOC port by Olaf Flebbe, 1999-2002\n");
-#endif
 #ifdef UNDER_CE
-       PerlIO_printf(PerlIO_stdout(),"WINCE port by Rainer Keuchel, 2001-2002\n");
-       PerlIO_printf(PerlIO_stdout(),"Built on " __DATE__ " " __TIME__ "\n\n");
+       PerlIO_printf(PIO_stdout,
+                       "WINCE port by Rainer Keuchel, 2001-2002\n"
+                       "Built on " __DATE__ " " __TIME__ "\n\n");
        wce_hitreturn();
 #endif
 #ifdef __SYMBIAN32__
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "Symbian port by Nokia, 2004-2005\n");
 #endif
 #ifdef BINARY_BUILD_NOTICE
        BINARY_BUILD_NOTICE;
 #endif
-       PerlIO_printf(PerlIO_stdout(),
+       PerlIO_printf(PIO_stdout,
                      "\n\
 Perl may be copied only under the terms of either the Artistic License or the\n\
 GNU General Public License, which may be found in the Perl 5 source kit.\n\n\
@@ -3576,10 +3631,6 @@ S_init_interp(pTHX)
 #  undef PERLVARIC
 #endif
 
-    /* As these are inside a structure, PERLVARI isn't capable of initialising
-       them  */
-    PL_reg_oldcurpm = PL_reg_curpm = NULL;
-    PL_reg_poscache = PL_reg_starttry = NULL;
 }
 
 STATIC void
@@ -3607,13 +3658,15 @@ S_init_main_stash(pTHX)
     SvREFCNT_inc_simple_void(PL_incgv); /* Don't allow it to be freed */
     GvMULTI_on(PL_incgv);
     PL_hintgv = gv_fetchpvs("\010", GV_ADD|GV_NOTQUAL, SVt_PV); /* ^H */
+    SvREFCNT_inc_simple_void(PL_hintgv);
     GvMULTI_on(PL_hintgv);
     PL_defgv = gv_fetchpvs("_", GV_ADD|GV_NOTQUAL, SVt_PVAV);
     SvREFCNT_inc_simple_void(PL_defgv);
-    PL_errgv = gv_HVadd(gv_fetchpvs("@", GV_ADD|GV_NOTQUAL, SVt_PV));
+    PL_errgv = gv_fetchpvs("@", GV_ADD|GV_NOTQUAL, SVt_PV);
     SvREFCNT_inc_simple_void(PL_errgv);
     GvMULTI_on(PL_errgv);
     PL_replgv = gv_fetchpvs("\022", GV_ADD|GV_NOTQUAL, SVt_PV); /* ^R */
+    SvREFCNT_inc_simple_void(PL_replgv);
     GvMULTI_on(PL_replgv);
     (void)Perl_form(aTHX_ "%240s",""); /* Preallocate temp - for immediate signals. */
 #ifdef PERL_DONT_CREATE_GVSV
@@ -3636,6 +3689,8 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript)
     int fdscript = -1;
     PerlIO *rsfp = NULL;
     dVAR;
+    Stat_t tmpstatbuf;
+    int fd;
 
     PERL_ARGS_ASSERT_OPEN_SCRIPT;
 
@@ -3708,7 +3763,9 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript)
        const char * const err = "Failed to create a fake bit bucket";
        if (strEQ(scriptname, BIT_BUCKET)) {
 #ifdef HAS_MKSTEMP /* Hopefully mkstemp() is safe here. */
+            int old_umask = umask(0600);
            int tmpfd = mkstemp(tmpname);
+            umask(old_umask);
            if (tmpfd > -1) {
                scriptname = tmpname;
                close(tmpfd);
@@ -3741,10 +3798,24 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript)
            Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
                    CopFILE(PL_curcop), Strerror(errno));
     }
+    fd = PerlIO_fileno(rsfp);
 #if defined(HAS_FCNTL) && defined(F_SETFD)
-    /* ensure close-on-exec */
-    fcntl(PerlIO_fileno(rsfp), F_SETFD, 1);
+    if (fd >= 0) {
+        /* ensure close-on-exec */
+        if (fcntl(fd, F_SETFD, 1) < 0) {
+            Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
+                       CopFILE(PL_curcop), Strerror(errno));
+        }
+    }
 #endif
+
+    if (fd < 0 ||
+        (PerlLIO_fstat(fd, &tmpstatbuf) >= 0
+         && S_ISDIR(tmpstatbuf.st_mode)))
+        Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n",
+            CopFILE(PL_curcop),
+            Strerror(EISDIR));
+
     return rsfp;
 }
 
@@ -3762,21 +3833,27 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript)
 STATIC void
 S_validate_suid(pTHX_ PerlIO *rsfp)
 {
-    const UV  my_uid = PerlProc_getuid();
-    const UV my_euid = PerlProc_geteuid();
-    const UV  my_gid = PerlProc_getgid();
-    const UV my_egid = PerlProc_getegid();
+    const Uid_t  my_uid = PerlProc_getuid();
+    const Uid_t my_euid = PerlProc_geteuid();
+    const Gid_t  my_gid = PerlProc_getgid();
+    const Gid_t my_egid = PerlProc_getegid();
 
     PERL_ARGS_ASSERT_VALIDATE_SUID;
 
     if (my_euid != my_uid || my_egid != my_gid) {      /* (suidperl doesn't exist, in fact) */
        dVAR;
-
-       PerlLIO_fstat(PerlIO_fileno(rsfp),&PL_statbuf); /* may be either wrapped or real suid */
-       if ((my_euid != my_uid && my_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID)
-           ||
-           (my_egid != my_gid && my_egid == PL_statbuf.st_gid && PL_statbuf.st_mode & S_ISGID)
-          )
+        int fd = PerlIO_fileno(rsfp);
+        if (fd < 0) {
+            Perl_croak(aTHX_ "Illegal suidscript");
+        } else {
+            if (PerlLIO_fstat(fd, &PL_statbuf) < 0) {  /* may be either wrapped or real suid */
+                Perl_croak(aTHX_ "Illegal suidscript");
+            }
+        }
+        if ((my_euid != my_uid && my_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID)
+            ||
+            (my_egid != my_gid && my_egid == PL_statbuf.st_gid && PL_statbuf.st_mode & S_ISGID)
+            )
            if (!PL_do_undump)
                Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
@@ -3790,7 +3867,7 @@ S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp)
 {
     dVAR;
     const char *s;
-    register const char *s2;
+    const char *s2;
 
     PERL_ARGS_ASSERT_FIND_BEGINNING;
 
@@ -3818,15 +3895,19 @@ S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp)
 STATIC void
 S_init_ids(pTHX)
 {
+    /* no need to do anything here any more if we don't
+     * do tainting. */
+#ifndef NO_TAINT_SUPPORT
     dVAR;
-    const UV my_uid = PerlProc_getuid();
-    const UV my_euid = PerlProc_geteuid();
-    const UV my_gid = PerlProc_getgid();
-    const UV my_egid = PerlProc_getegid();
+    const Uid_t my_uid = PerlProc_getuid();
+    const Uid_t my_euid = PerlProc_geteuid();
+    const Gid_t my_gid = PerlProc_getgid();
+    const Gid_t my_egid = PerlProc_getegid();
 
     /* Should not happen: */
     CHECK_MALLOC_TAINT(my_uid && (my_euid != my_uid || my_egid != my_gid));
-    PL_tainting |= (my_uid && (my_euid != my_uid || my_egid != my_gid));
+    TAINTING_set( TAINTING_get | (my_uid && (my_euid != my_uid || my_egid != my_gid)) );
+#endif
     /* BUG */
     /* PSz 27 Feb 04
      * Should go by suidscript, not uid!=euid: why disallow
@@ -3853,10 +3934,10 @@ Perl_doing_taint(int argc, char *argv[], char *envp[])
      * have to add your own checks somewhere in here.  The two most
      * known samples of 'implicitness' are Win32 and NetWare, neither
      * of which has much of concept of 'uids'. */
-    int uid  = PerlProc_getuid();
-    int euid = PerlProc_geteuid();
-    int gid  = PerlProc_getgid();
-    int egid = PerlProc_getegid();
+    Uid_t uid  = PerlProc_getuid();
+    Uid_t euid = PerlProc_geteuid();
+    Gid_t gid  = PerlProc_getgid();
+    Gid_t egid = PerlProc_getegid();
     (void)envp;
 
 #ifdef VMS
@@ -3928,9 +4009,15 @@ Perl_init_debugger(pTHX)
     PL_curstash = (HV *)SvREFCNT_inc_simple(PL_debstash);
 
     Perl_init_dbargs(aTHX);
-    PL_DBgv = gv_fetchpvs("DB::DB", GV_ADDMULTI, SVt_PVGV);
-    PL_DBline = gv_fetchpvs("DB::dbline", GV_ADDMULTI, SVt_PVAV);
-    PL_DBsub = gv_HVadd(gv_fetchpvs("DB::sub", GV_ADDMULTI, SVt_PVHV));
+    PL_DBgv = MUTABLE_GV(
+       SvREFCNT_inc(gv_fetchpvs("DB::DB", GV_ADDMULTI, SVt_PVGV))
+    );
+    PL_DBline = MUTABLE_GV(
+       SvREFCNT_inc(gv_fetchpvs("DB::dbline", GV_ADDMULTI, SVt_PVAV))
+    );
+    PL_DBsub = MUTABLE_GV(SvREFCNT_inc(
+       gv_HVadd(gv_fetchpvs("DB::sub", GV_ADDMULTI, SVt_PVHV))
+    ));
     PL_DBsingle = GvSV((gv_fetchpvs("DB::single", GV_ADDMULTI, SVt_PV)));
     if (!SvIOK(PL_DBsingle))
        sv_setiv(PL_DBsingle, 0);
@@ -3946,8 +4033,10 @@ Perl_init_debugger(pTHX)
 
 #ifndef STRESS_REALLOC
 #define REASONABLE(size) (size)
+#define REASONABLE_but_at_least(size,min) (size)
 #else
 #define REASONABLE(size) (1) /* unreasonable */
+#define REASONABLE_but_at_least(size,min) (min)
 #endif
 
 void
@@ -3983,9 +4072,9 @@ Perl_init_stacks(pTHX)
     PL_scopestack_ix = 0;
     PL_scopestack_max = REASONABLE(32);
 
-    Newx(PL_savestack,REASONABLE(128),ANY);
+    Newx(PL_savestack,REASONABLE_but_at_least(128,SS_MAXPUSH),ANY);
     PL_savestack_ix = 0;
-    PL_savestack_max = REASONABLE(128);
+    PL_savestack_max = REASONABLE_but_at_least(128,SS_MAXPUSH);
 }
 
 #undef REASONABLE
@@ -4108,7 +4197,7 @@ S_init_predump_symbols(pTHX)
 }
 
 void
-Perl_init_argv_symbols(pTHX_ register int argc, register char **argv)
+Perl_init_argv_symbols(pTHX_ int argc, char **argv)
 {
     dVAR;
 
@@ -4134,12 +4223,12 @@ Perl_init_argv_symbols(pTHX_ register int argc, register char **argv)
        }
     }
     if ((PL_argvgv = gv_fetchpvs("ARGV", GV_ADD|GV_NOTQUAL, SVt_PVAV))) {
+       SvREFCNT_inc_simple_void_NN(PL_argvgv);
        GvMULTI_on(PL_argvgv);
-       (void)gv_AVadd(PL_argvgv);
        av_clear(GvAVn(PL_argvgv));
        for (; argc > 0; argc--,argv++) {
            SV * const sv = newSVpv(argv[0],0);
-           av_push(GvAVn(PL_argvgv),sv);
+           av_push(GvAV(PL_argvgv),sv);
            if (!(PL_unicode & PERL_UNICODE_LOCALE_FLAG) || PL_utf8locale) {
                 if (PL_unicode & PERL_UNICODE_ARGV_FLAG)
                      SvUTF8_on(sv);
@@ -4156,16 +4245,16 @@ Perl_init_argv_symbols(pTHX_ register int argc, register char **argv)
 }
 
 STATIC void
-S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register char **env)
+S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env)
 {
     dVAR;
     GV* tmpgv;
 
     PERL_ARGS_ASSERT_INIT_POSTDUMP_SYMBOLS;
 
-    PL_toptarget = newSV_type(SVt_PVFM);
+    PL_toptarget = newSV_type(SVt_PVIV);
     sv_setpvs(PL_toptarget, "");
-    PL_bodytarget = newSV_type(SVt_PVFM);
+    PL_bodytarget = newSV_type(SVt_PVIV);
     sv_setpvs(PL_bodytarget, "");
     PL_formtarget = PL_bodytarget;
 
@@ -4179,6 +4268,7 @@ S_init_postdump_symbols(pTHX_ register int argc, register char **argv, register
     if ((PL_envgv = gv_fetchpvs("ENV", GV_ADD|GV_NOTQUAL, SVt_PVHV))) {
        HV *hv;
        bool env_is_not_environ;
+       SvREFCNT_inc_simple_void_NN(PL_envgv);
        GvMULTI_on(PL_envgv);
        hv = GvHVn(PL_envgv);
        hv_magic(hv, NULL, PERL_MAGIC_env);
@@ -4243,7 +4333,7 @@ S_init_perllib(pTHX)
     STRLEN len;
 #endif
 
-    if (!PL_tainting) {
+    if (!TAINTING_get) {
 #ifndef VMS
        perl5lib = PerlEnv_getenv("PERL5LIB");
 /*
@@ -4359,7 +4449,7 @@ S_init_perllib(pTHX)
                      |INCPUSH_CAN_RELOCATE);
 #endif
 
-    if (!PL_tainting) {
+    if (!TAINTING_get) {
 #ifndef VMS
 /*
  * It isn't possible to delete an environment variable with
@@ -4416,11 +4506,11 @@ S_init_perllib(pTHX)
 #endif
 #endif /* !PERL_IS_MINIPERL */
 
-    if (!PL_tainting)
+    if (!TAINTING_get)
        S_incpush(aTHX_ STR_WITH_LEN("."), 0);
 }
 
-#if defined(DOSISH) || defined(EPOC) || defined(__SYMBIAN32__)
+#if defined(DOSISH) || defined(__SYMBIAN32__)
 #    define PERLLIB_SEP ';'
 #else
 #  if defined(VMS)
@@ -4466,16 +4556,12 @@ S_mayberelocate(pTHX_ const char *const dir, STRLEN len, U32 flags)
     PERL_ARGS_ASSERT_MAYBERELOCATE;
     assert(len > 0);
 
-       if (len) {
-           /* I am not convinced that this is valid when PERLLIB_MANGLE is
-              defined to so something (in os2/os2.c), but the code has been
-              this way, ignoring any possible changed of length, since
-              760ac839baf413929cd31cc32ffd6dba6b781a81 (5.003_02) so I'll leave
-              it be.  */
-           libdir = newSVpvn(PERLLIB_MANGLE(dir, len), len);
-       } else {
-           libdir = newSVpv(PERLLIB_MANGLE(dir, 0), 0);
-       }
+    /* I am not convinced that this is valid when PERLLIB_MANGLE is
+       defined to so something (in os2/os2.c), but the code has been
+       this way, ignoring any possible changed of length, since
+       760ac839baf413929cd31cc32ffd6dba6b781a81 (5.003_02) so I'll leave
+       it be.  */
+    libdir = newSVpvn(PERLLIB_MANGLE(dir, len), len);
 
 #ifdef VMS
     {
@@ -4483,7 +4569,7 @@ S_mayberelocate(pTHX_ const char *const dir, STRLEN len, U32 flags)
 
        if ((unix = tounixspec_ts(SvPV(libdir,len),NULL)) != NULL) {
            len = strlen(unix);
-           while (unix[len-1] == '/') len--;  /* Cosmetic */
+           while (len > 1 && unix[len-1] == '/') len--;  /* Cosmetic */
            sv_usepvn(libdir,unix,len);
        }
        else
@@ -4582,7 +4668,7 @@ S_mayberelocate(pTHX_ const char *const dir, STRLEN len, U32 flags)
                    SvREFCNT_dec(libdir);
                    /* And this is the new libdir.  */
                    libdir = tempsv;
-                   if (PL_tainting &&
+                   if (TAINTING_get &&
                        (PerlProc_getuid() != PerlProc_geteuid() ||
                         PerlProc_getgid() != PerlProc_getegid())) {
                        /* Need to taint relocated paths if running set ID  */
@@ -4679,9 +4765,9 @@ S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags)
        /* finally add this lib directory at the end of @INC */
        if (unshift) {
 #ifdef PERL_IS_MINIPERL
-           const U32 extra = 0;
+           const Size_t extra = 0;
 #else
-           U32 extra = av_len(av) + 1;
+           Size_t extra = av_tindex(av) + 1;
 #endif
            av_unshift(inc, extra + push_basedir);
            if (push_basedir)
@@ -4768,7 +4854,7 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList)
 
     PERL_ARGS_ASSERT_CALL_LIST;
 
-    while (av_len(paramList) >= 0) {
+    while (av_tindex(paramList) >= 0) {
        cv = MUTABLE_CV(av_shift(paramList));
        if (PL_savebegin) {
            if (paramList == PL_beginav) {
@@ -4851,6 +4937,14 @@ void
 Perl_my_exit(pTHX_ U32 status)
 {
     dVAR;
+    if (PL_exit_flags & PERL_EXIT_ABORT) {
+       abort();
+    }
+    if (PL_exit_flags & PERL_EXIT_WARN) {
+       PL_exit_flags |= PERL_EXIT_ABORT; /* Protect against reentrant calls */
+       Perl_warn(aTHX_ "Unexpected exit %lu", (unsigned long)status);
+       PL_exit_flags &= ~PERL_EXIT_ABORT;
+    }
     switch (status) {
     case 0:
        STATUS_ALL_SUCCESS;
@@ -4948,6 +5042,14 @@ Perl_my_failure_exit(pTHX)
            STATUS_UNIX_SET(255);
     }
 #endif
+    if (PL_exit_flags & PERL_EXIT_ABORT) {
+       abort();
+    }
+    if (PL_exit_flags & PERL_EXIT_WARN) {
+       PL_exit_flags |= PERL_EXIT_ABORT; /* Protect against reentrant calls */
+       Perl_warn(aTHX_ "Unexpected exit failure %ld", (long)PL_statusvalue);
+       PL_exit_flags &= ~PERL_EXIT_ABORT;
+    }
     my_exit_jump();
 }