X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/148f39b7de6eae9ddd59e0b0aff691d6abea7aca..a5fd18fc405e67ffaf10d634ba8dcb2128cad88a:/perl.c diff --git a/perl.c b/perl.c index 012d94f..aa7d8b6 100644 --- a/perl.c +++ b/perl.c @@ -3,7 +3,7 @@ * * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 * 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - * by Larry Wall and others + * 2013, 2014, 2015, 2016 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. @@ -22,6 +22,10 @@ * and destroy a perl interpreter, plus the functions used by XS code to * call back into perl. Note that it does not contain the actual main() * function of the interpreter; that can be found in perlmain.c + * + * Note that at build time this file is also linked to as perlmini.c, + * and perlmini.o is then built with PERL_IS_MINIPERL defined, which is + * then used to create the miniperl executable, rather than perl.o. */ #if defined(PERL_IS_MINIPERL) && !defined(USE_SITECUSTOMIZE) @@ -33,7 +37,6 @@ #include "perl.h" #include "patchlevel.h" /* for local_patches */ #include "XSUB.h" -#include "charclass_invlists.h" #ifdef NETWARE #include "nwutil.h" @@ -94,6 +97,7 @@ S_init_tls_and_interp(PerlInterpreter *my_perl) OP_REFCNT_INIT; OP_CHECK_MUTEX_INIT; HINTS_REFCNT_INIT; + LOCALE_INIT; MUTEX_INIT(&PL_dollarzero_mutex); MUTEX_INIT(&PL_my_ctx_mutex); # endif @@ -214,6 +218,26 @@ Initializes a new Perl interpreter. See L. =cut */ +static void +S_fixup_platform_bugs(void) +{ +#if defined(__GLIBC__) && IVSIZE == 8 \ + && ( __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8)) + { + IV l = 3; + IV r = -10; + /* Cannot do this check with inlined IV constants since + * that seems to work correctly even with the buggy glibc. */ + if (l % r == -3) { + dTHX; + /* Yikes, we have the bug. + * Patch in the workaround version. */ + PL_ppaddr[OP_I_MODULO] = &Perl_pp_i_modulo_glibc_bugfix; + } + } +#endif +} + void perl_construct(pTHXx) { @@ -251,6 +275,8 @@ perl_construct(pTHXx) init_ids(); + S_fixup_platform_bugs(); + JMPENV_BOOTSTRAP; STATUS_ALL_SUCCESS; @@ -269,9 +295,9 @@ perl_construct(pTHXx) PL_fdpid = newAV(); /* for remembering popen pids by fd */ PL_modglobal = newHV(); /* pointers to per-interpreter module globals */ PL_errors = newSVpvs(""); - sv_setpvs(PERL_DEBUG_PAD(0), ""); /* For regex debugging. */ - sv_setpvs(PERL_DEBUG_PAD(1), ""); /* ext/re needs these */ - sv_setpvs(PERL_DEBUG_PAD(2), ""); /* even without DEBUGGING. */ + SvPVCLEAR(PERL_DEBUG_PAD(0)); /* For regex debugging. */ + SvPVCLEAR(PERL_DEBUG_PAD(1)); /* ext/re needs these */ + SvPVCLEAR(PERL_DEBUG_PAD(2)); /* even without DEBUGGING. */ #ifdef USE_ITHREADS /* First entry is a list of empty elements. It needs to be initialised else all hell breaks loose in S_find_uninit_var(). */ @@ -325,7 +351,6 @@ perl_construct(pTHXx) PL_stashcache = newHV(); PL_patchlevel = newSVpvs("v" PERL_VERSION_STRING); - PL_apiversion = newSVpvs("v" PERL_API_VERSION_STRING); #ifdef HAS_MMAP if (!PL_mmap_page_size) { @@ -387,11 +412,17 @@ perl_construct(pTHXx) 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); + PL_GCB_invlist = _new_invlist_C_array(_Perl_GCB_invlist); + PL_SB_invlist = _new_invlist_C_array(_Perl_SB_invlist); + PL_WB_invlist = _new_invlist_C_array(_Perl_WB_invlist); + PL_LB_invlist = _new_invlist_C_array(_Perl_LB_invlist); +#ifdef USE_THREAD_SAFE_LOCALE + PL_C_locale_obj = newlocale(LC_ALL_MASK, "C", NULL); +#endif ENTER; } @@ -546,7 +577,16 @@ perl_destruct(pTHXx) { const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL"); if (s) { - const int i = atoi(s); + int i; + if (strEQ(s, "-1")) { /* Special case: modperl folklore. */ + i = -1; + } else { + UV uv; + if (grok_atoUV(s, &uv, NULL) && uv <= INT_MAX) + i = (int)uv; + else + i = 0; + } #ifdef DEBUGGING if (destruct_level < i) destruct_level = i; #endif @@ -575,19 +615,42 @@ perl_destruct(pTHXx) assert(PL_scopestack_ix == 0); /* Need to flush since END blocks can produce output */ + /* flush stdout separately, since we can identify it */ +#ifdef USE_PERLIO + { + PerlIO *stdo = PerlIO_stdout(); + if (*stdo && PerlIO_flush(stdo)) { + PerlIO_restore_errno(stdo); + if (errno) + PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s", + Strerror(errno)); + if (!STATUS_UNIX) + STATUS_ALL_FAILURE; + } + } +#endif my_fflush_all(); #ifdef PERL_TRACE_OPS - /* If we traced all Perl OP usage, report and clean up */ + /* dump OP-counts if $ENV{PERL_TRACE_OPS} > 0 */ + { + const char * const ptoenv = PerlEnv_getenv("PERL_TRACE_OPS"); + UV uv; + + if (!ptoenv || !Perl_grok_atoUV(ptoenv, &uv, NULL) + || !(uv > 0)) + goto no_trace_out; + } 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; + if (PL_op_exec_cnt[i]) + PerlIO_printf(Perl_debug_log, " %s: %"UVuf"\n", PL_op_name[i], PL_op_exec_cnt[i]); } /* 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"); + no_trace_out: #endif @@ -901,7 +964,6 @@ perl_destruct(pTHXx) Safefree(PL_inplace); PL_inplace = NULL; SvREFCNT_dec(PL_patchlevel); - SvREFCNT_dec(PL_apiversion); if (PL_e_script) { SvREFCNT_dec(PL_e_script); @@ -963,6 +1025,9 @@ perl_destruct(pTHXx) PL_DBsingle = NULL; PL_DBtrace = NULL; PL_DBsignal = NULL; + PL_DBsingle_iv = 0; + PL_DBtrace_iv = 0; + PL_DBsignal_iv = 0; PL_DBcv = NULL; PL_dbargs = NULL; PL_debstash = NULL; @@ -1029,10 +1094,14 @@ perl_destruct(pTHXx) SvREFCNT_dec(PL_utf8_foldable); SvREFCNT_dec(PL_utf8_foldclosures); SvREFCNT_dec(PL_AboveLatin1); + SvREFCNT_dec(PL_InBitmap); SvREFCNT_dec(PL_UpperLatin1); SvREFCNT_dec(PL_Latin1); SvREFCNT_dec(PL_NonL1NonFinalFold); SvREFCNT_dec(PL_HasMultiCharFold); +#ifdef USE_LOCALE_CTYPE + SvREFCNT_dec(PL_warn_locale); +#endif PL_utf8_mark = NULL; PL_utf8_toupper = NULL; PL_utf8_totitle = NULL; @@ -1042,7 +1111,11 @@ perl_destruct(pTHXx) PL_utf8_idcont = NULL; PL_utf8_foldclosures = NULL; PL_AboveLatin1 = NULL; + PL_InBitmap = NULL; PL_HasMultiCharFold = NULL; +#ifdef USE_LOCALE_CTYPE + PL_warn_locale = NULL; +#endif PL_Latin1 = NULL; PL_NonL1NonFinalFold = NULL; PL_UpperLatin1 = NULL; @@ -1050,6 +1123,10 @@ perl_destruct(pTHXx) SvREFCNT_dec(PL_XPosix_ptrs[i]); PL_XPosix_ptrs[i] = NULL; } + PL_GCB_invlist = NULL; + PL_LB_invlist = NULL; + PL_SB_invlist = NULL; + PL_WB_invlist = NULL; if (!specialWARN(PL_compiling.cop_warnings)) PerlMemShared_free(PL_compiling.cop_warnings); @@ -1062,7 +1139,7 @@ perl_destruct(pTHXx) hv = PL_defstash; /* break ref loop *:: <=> %:: */ - (void)hv_delete(hv, "main::", 6, G_DISCARD); + (void)hv_deletes(hv, "main::", G_DISCARD); PL_defstash = 0; SvREFCNT_dec(hv); SvREFCNT_dec(PL_curstname); @@ -1282,14 +1359,22 @@ perl_destruct(pTHXx) TAINTING_set(FALSE); TAINT_WARN_set(FALSE); PL_hints = 0; /* Reset hints. Should hints be per-interpreter ? */ - PL_debug = 0; DEBUG_P(debprofdump()); + PL_debug = 0; + #ifdef USE_REENTRANT_API Perl_reentrant_free(aTHX); #endif + /* These all point to HVs that are about to be blown away. + Code in core and on CPAN assumes that if the interpreter is re-started + that they will be cleanly NULL or pointing to a valid HV. */ + PL_custom_op_names = NULL; + PL_custom_op_descs = NULL; + PL_custom_ops = NULL; + sv_free_arenas(); while (PL_regmatch_slab) { @@ -1356,8 +1441,11 @@ perl_free(pTHXx) "free this thread's memory\n"); PL_debug &= ~ DEBUG_m_FLAG; } - while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header)) - safesysfree(PERL_MEMORY_DEBUG_HEADER_SIZE + (char *)(aTHXx->Imemory_debug_header.next)); + while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header)){ + char * next = (char *)(aTHXx->Imemory_debug_header.next); + Malloc_t ptr = PERL_MEMORY_DEBUG_HEADER_SIZE + next; + safesysfree(ptr); + } PL_debug = old_debug; } } @@ -1415,7 +1503,6 @@ perl_fini(void) void Perl_call_atexit(pTHX_ ATEXIT_t fn, void *ptr) { - dVAR; Renew(PL_exitlist, PL_exitlistlen+1, PerlExitListEntry); PL_exitlist[PL_exitlistlen].fn = fn; PL_exitlist[PL_exitlistlen].ptr = ptr; @@ -1452,9 +1539,9 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env) { 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; + if (s && strEQ(s, "1")) { + const unsigned char *seed= PERL_HASH_SEED; + const 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++); @@ -1468,6 +1555,14 @@ perl_parse(pTHXx_ XSINIT_t xsinit, int argc, char **argv, char **env) } } #endif /* #if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT) */ + +#ifdef __amigaos4__ + { + struct NameTranslationInfo nti; + __translate_amiga_to_unix_path_name(&argv[0],&nti); + } +#endif + PL_origargc = argc; PL_origargv = argv; @@ -1660,6 +1755,9 @@ S_Internals_V(pTHX_ CV *cv) # ifdef PERL_BOOL_AS_CHAR " PERL_BOOL_AS_CHAR" # endif +# ifdef PERL_COPY_ON_WRITE + " PERL_COPY_ON_WRITE" +# endif # ifdef PERL_DISABLE_PMC " PERL_DISABLE_PMC" # endif @@ -1705,8 +1803,8 @@ 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" +# ifdef PERL_OP_PARENT + " PERL_OP_PARENT" # endif # ifdef PERL_PERTURB_KEYS_DETERMINISTIC " PERL_PERTURB_KEYS_DETERMINISTIC" @@ -1729,6 +1827,9 @@ S_Internals_V(pTHX_ CV *cv) # ifdef PERL_USE_SAFE_PUTENV " PERL_USE_SAFE_PUTENV" # endif +# ifdef SILENT_NO_TAINT_SUPPORT + " SILENT_NO_TAINT_SUPPORT" +# endif # ifdef UNLINK_ALL_VERSIONS " UNLINK_ALL_VERSIONS" # endif @@ -1747,6 +1848,9 @@ S_Internals_V(pTHX_ CV *cv) # ifdef USE_LOCALE_CTYPE " USE_LOCALE_CTYPE" # endif +# ifdef WIN32_NO_REGISTRY + " USE_NO_REGISTRY" +# endif # ifdef USE_PERL_ATOF " USE_PERL_ATOF" # endif @@ -1755,7 +1859,7 @@ S_Internals_V(pTHX_ CV *cv) # endif ; PERL_UNUSED_ARG(cv); - PERL_UNUSED_ARG(items); + PERL_UNUSED_VAR(items); EXTEND(SP, entries); @@ -1763,15 +1867,20 @@ S_Internals_V(pTHX_ CV *cv) PUSHs(Perl_newSVpvn_flags(aTHX_ non_bincompat_options, sizeof(non_bincompat_options) - 1, SVs_TEMP)); -#ifdef __DATE__ -# ifdef __TIME__ +#ifndef PERL_BUILD_DATE +# ifdef __DATE__ +# ifdef __TIME__ +# define PERL_BUILD_DATE __DATE__ " " __TIME__ +# else +# define PERL_BUILD_DATE __DATE__ +# endif +# endif +#endif + +#ifdef PERL_BUILD_DATE PUSHs(Perl_newSVpvn_flags(aTHX_ - STR_WITH_LEN("Compiled at " __DATE__ " " __TIME__), - SVs_TEMP)); -# else - PUSHs(Perl_newSVpvn_flags(aTHX_ STR_WITH_LEN("Compiled on " __DATE__), + STR_WITH_LEN("Compiled at " PERL_BUILD_DATE), SVs_TEMP)); -# endif #else PUSHs(&PL_sv_undef); #endif @@ -1801,7 +1910,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) int argc = PL_origargc; char **argv = PL_origargv; const char *scriptname = NULL; - VOL bool dosearch = FALSE; + bool dosearch = FALSE; char c; bool doextract = FALSE; const char *cddir = NULL; @@ -1983,6 +2092,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) #endif (s = PerlEnv_getenv("PERL5OPT"))) { + /* s points to static memory in getenv(), which may be overwritten at + * any time; use a mortal copy instead */ + s = SvPVX(sv_2mortal(newSVpv(s, 0))); + while (isSPACE(*s)) s++; if (*s == '-' && *(s+1) == 'T') { @@ -2066,9 +2179,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) 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} and do q%c%"SVf"/buildcustomize.pl%c || die $@ }", - 0, SVfARG(*inc0), 0, - 0, SVfARG(*inc0), 0)); + "BEGIN { my $f = q%c%s%"SVf"/buildcustomize.pl%c; " + "do {local $!; -f $f }" + " and do $f || die $@ || qq '$f: $!' }", + 0, (TAINTING_get ? "./" : ""), SVfARG(*inc0), 0)); } # else /* SITELIB_EXP is a function call on Win32. */ @@ -2152,7 +2266,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) PL_main_cv = PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV)); CvUNIQUE_on(PL_compcv); - CvPADLIST(PL_compcv) = pad_new(0); + CvPADLIST_set(PL_compcv, pad_new(0)); PL_isarev = newHV(); @@ -2186,6 +2300,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) /* PL_unicode is turned on by -C, or by $ENV{PERL_UNICODE}, * or explicitly in some platforms. + * PL_utf8locale is conditionally turned on by * locale.c:Perl_init_i18nl10n() if the environment * look like the user wants to use UTF-8. */ #if defined(__SYMBIAN32__) @@ -2286,8 +2401,10 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) #ifdef MYMALLOC { const char *s; - if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2) - dump_mstats("after compilation:"); + UV uv; + s = PerlEnv_getenv("PERL_DEBUG_MSTATS"); + if (s && grok_atoUV(s, &uv, NULL) && uv >= 2) + dump_mstats("after compilation:"); } #endif @@ -2308,7 +2425,6 @@ Tells a Perl interpreter to run. See L. int perl_run(pTHXx) { - dVAR; I32 oldscope; int ret = 0; dJMPENV; @@ -2366,7 +2482,6 @@ perl_run(pTHXx) STATIC void S_run_body(pTHX_ I32 oldscope) { - dVAR; DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support (0x%x).\n", PL_sawampersand ? "Enabling" : "Omitting", (unsigned int)(PL_sawampersand))); @@ -2384,7 +2499,7 @@ S_run_body(pTHX_ I32 oldscope) my_exit(0); } if (PERLDB_SINGLE && PL_DBsingle) - sv_setiv(PL_DBsingle, 1); + PL_DBsingle_iv = 1; if (PL_initav) { PERL_SET_PHASE(PERL_PHASE_INIT); call_list(oldscope, PL_initav); @@ -2411,8 +2526,7 @@ S_run_body(pTHX_ I32 oldscope) CALLRUNOPS(aTHX); } my_exit(0); - /* NOTREACHED */ - assert(0); + NOT_REACHED; /* NOTREACHED */ } /* @@ -2479,7 +2593,7 @@ Perl_get_av(pTHX_ const char *name, I32 flags) Returns the HV of the specified Perl hash. C are passed to C. If C is set and the Perl variable does not exist then it will be created. If C is zero -and the variable does not exist then NULL is returned. +and the variable does not exist then C is returned. =cut */ @@ -2553,7 +2667,7 @@ 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 (a NULL-terminated array of strings) as arguments. See +with C (a C-terminated array of strings) as arguments. See L. Approximate Perl equivalent: C<&{"$sub_name"}(@$argv)>. @@ -2567,19 +2681,16 @@ Perl_call_argv(pTHX_ const char *sub_name, I32 flags, char **argv) /* See G_* flags in cop.h */ /* null terminated arg list */ { - dVAR; dSP; PERL_ARGS_ASSERT_CALL_ARGV; PUSHMARK(SP); - if (argv) { - while (*argv) { - mXPUSHs(newSVpv(*argv,0)); - argv++; - } - PUTBACK; + while (*argv) { + mXPUSHs(newSVpv(*argv,0)); + argv++; } + PUTBACK; return call_pv(sub_name, flags); } @@ -2631,8 +2742,22 @@ Perl_call_method(pTHX_ const char *methname, I32 flags) /* =for apidoc p||call_sv -Performs a callback to the Perl sub whose name is in the SV. See -L. +Performs a callback to the Perl sub specified by the SV. + +If neither the C nor C flag is supplied, the +SV may be any of a CV, a GV, a reference to a CV, a reference to a GV +or C will be used as the name of the sub to call. + +If the C flag is supplied, the SV may be a reference to a CV or +C will be used as the name of the method to call. + +If the C flag is supplied, C will be used as +the name of the method to call. + +Some other values are treated specially for internal use and should +not be depended on. + +See L. =cut */ @@ -2641,13 +2766,11 @@ I32 Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) /* See G_* flags in cop.h */ { - dVAR; dSP; + dVAR; LOGOP myop; /* fake syntax tree node */ - UNOP method_unop; - SVOP method_svop; + METHOP method_op; I32 oldmark; VOL I32 retval = 0; - I32 oldscope; bool oldcatch = CATCH_GET; int ret; OP* const oldop = PL_op; @@ -2672,11 +2795,13 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) SAVEOP(); PL_op = (OP*)&myop; - EXTEND(PL_stack_sp, 1); - if (!(flags & G_METHOD_NAMED)) - *++PL_stack_sp = sv; + if (!(flags & G_METHOD_NAMED)) { + dSP; + EXTEND(SP, 1); + PUSHs(sv); + PUTBACK; + } oldmark = TOPMARK; - oldscope = PL_scopestack_ix; if (PERLDB_SUB && PL_curstash != PL_debstash /* Handle first BEGIN of -d. */ @@ -2688,23 +2813,19 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) myop.op_private |= OPpENTERSUB_DB; if (flags & (G_METHOD|G_METHOD_NAMED)) { + Zero(&method_op, 1, METHOP); + method_op.op_next = (OP*)&myop; + PL_op = (OP*)&method_op; 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; + method_op.op_ppaddr = PL_ppaddr[OP_METHOD_NAMED]; + method_op.op_type = OP_METHOD_NAMED; + method_op.op_u.op_meth_sv = sv; } 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; + 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; - } if (!(flags & G_EVAL)) { @@ -2714,10 +2835,12 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) CATCH_SET(oldcatch); } else { + I32 old_cxix; myop.op_other = (OP*)&myop; - PL_markstack_ptr--; - create_eval_scope(flags|G_FAKINGEVAL); - PL_markstack_ptr++; + (void)POPMARK; + old_cxix = cxstack_ix; + create_eval_scope(NULL, flags|G_FAKINGEVAL); + INCMARK; JMPENV_PUSH(ret); @@ -2739,8 +2862,7 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) FREETMPS; JMPENV_POP; my_exit_jump(); - /* NOTREACHED */ - assert(0); + NOT_REACHED; /* NOTREACHED */ case 3: if (PL_restartop) { PL_restartjmpenv = NULL; @@ -2758,8 +2880,13 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) break; } - if (PL_scopestack_ix > oldscope) + /* if we croaked, depending on how we croaked the eval scope + * may or may not have already been popped */ + if (cxstack_ix > old_cxix) { + assert(cxstack_ix == old_cxix + 1); + assert(CxTYPE(CX_CUR()) == CXt_EVAL); delete_eval_scope(); + } JMPENV_POP; } @@ -2779,7 +2906,7 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) =for apidoc p||eval_sv Tells Perl to C the string in the SV. It supports the same flags -as C, with the obvious exception of G_EVAL. See L. +as C, with the obvious exception of C. See L. =cut */ @@ -2790,9 +2917,8 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) /* See G_* flags in cop.h */ { dVAR; - dSP; UNOP myop; /* fake syntax tree node */ - VOL I32 oldmark = SP - PL_stack_base; + VOL I32 oldmark; VOL I32 retval = 0; int ret; OP* const oldop = PL_op; @@ -2808,8 +2934,13 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) SAVEOP(); PL_op = (OP*)&myop; Zero(&myop, 1, UNOP); - EXTEND(PL_stack_sp, 1); - *++PL_stack_sp = sv; + { + dSP; + oldmark = SP - PL_stack_base; + EXTEND(SP, 1); + PUSHs(sv); + PUTBACK; + } if (!(flags & G_NOARGS)) myop.op_flags = OPf_STACKED; @@ -2822,7 +2953,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) 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 */ + * before a cx_pusheval(), which corrupts the stack after a croak */ TAINT_PROPER("eval_sv()"); JMPENV_PUSH(ret); @@ -2849,8 +2980,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) FREETMPS; JMPENV_POP; my_exit_jump(); - /* NOTREACHED */ - assert(0); + NOT_REACHED; /* NOTREACHED */ case 3: if (PL_restartop) { PL_restartjmpenv = NULL; @@ -2883,7 +3013,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) /* =for apidoc p||eval_pv -Tells Perl to C the given string and return an SV* result. +Tells Perl to C the given string in scalar context and return an SV* result. =cut */ @@ -2891,7 +3021,6 @@ Tells Perl to C the given string and return an SV* result. SV* Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error) { - dVAR; SV* sv = newSVpv(p, 0); PERL_ARGS_ASSERT_EVAL_PV; @@ -2932,7 +3061,6 @@ implemented that way; consider using load_module instead. void Perl_require_pv(pTHX_ const char *pv) { - dVAR; dSP; SV* sv; @@ -3031,39 +3159,37 @@ Perl_get_debug_opts(pTHX_ const char **s, bool givehelp) " 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", + " i trace PerlIO layer processing\n", NULL }; - int i = 0; + UV uv = 0; PERL_ARGS_ASSERT_GET_DEBUG_OPTS; if (isALPHA(**s)) { /* if adding extra options, remember to update DEBUG_MASK */ - static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAqMBL"; + static const char debopts[] = "psltocPmfrxuUHXDSTRJvCAqMBLi"; for (; isWORDCHAR(**s); (*s)++) { const char * const d = strchr(debopts,**s); if (d) - i |= 1 << (d - debopts); + uv |= 1 << (d - debopts); else if (ckWARN_d(WARN_DEBUGGING)) Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "invalid option -D%c, use -D'' to see choices\n", **s); } } else if (isDIGIT(**s)) { - i = atoi(*s); + const char* e; + if (grok_atoUV(*s, &uv, &e)) + *s = e; for (; isWORDCHAR(**s); (*s)++) ; } else if (givehelp) { const char *const *p = usage_msgd; while (*p) PerlIO_puts(PerlIO_stdout(), *p++); } -# ifdef EBCDIC - if ((i & DEBUG_p_FLAG) && ckWARN_d(WARN_DEBUGGING)) - Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), - "-Dp not implemented on this platform\n"); -# endif - return i; + return (int)uv; /* ignore any UV->int conversion loss */ } #endif @@ -3100,10 +3226,9 @@ Perl_moreswitches(pTHX_ const char *s) s--; } PL_rs = newSVpvs(""); - SvGROW(PL_rs, (STRLEN)(UNISKIP(rschar) + 1)); - tmps = (U8*)SvPVX(PL_rs); + tmps = (U8*) SvGROW(PL_rs, (STRLEN)(UVCHR_SKIP(rschar) + 1)); uvchr_to_utf8(tmps, rschar); - SvCUR_set(PL_rs, UNISKIP(rschar)); + SvCUR_set(PL_rs, UVCHR_SKIP(rschar)); SvUTF8_on(PL_rs); } else { @@ -3203,9 +3328,12 @@ Perl_moreswitches(pTHX_ const char *s) for (s++; isWORDCHAR(*s); s++) ; #endif return s; + NOT_REACHED; /* NOTREACHED */ } case 'h': usage(); + NOT_REACHED; /* NOTREACHED */ + case 'i': Safefree(PL_inplace); #if defined(__CYGWIN__) /* do backup extension automagically */ @@ -3221,11 +3349,6 @@ Perl_moreswitches(pTHX_ const char *s) PL_inplace = savepvn(start, s - start); } - if (*s) { - ++s; - if (*s == '-') /* Additional switches on #! line. */ - s++; - } return s; case 'I': /* -I handled both here and in parse_body() */ forbid_setid('I', FALSE); @@ -3472,7 +3595,7 @@ S_minus_v(pTHX) #endif PerlIO_printf(PIO_stdout, - "\n\nCopyright 1987-2014, Larry Wall\n"); + "\n\nCopyright 1987-2016, Larry Wall\n"); #ifdef MSDOS PerlIO_printf(PIO_stdout, "\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n"); @@ -3534,7 +3657,6 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n"); void Perl_my_unexec(pTHX) { - PERL_UNUSED_CONTEXT; #ifdef UNEXEC SV * prog = newSVpv(BIN_EXP, 0); SV * file = newSVpv(PL_origfilename, 0); @@ -3548,10 +3670,11 @@ Perl_my_unexec(pTHX) /* unexec prints msg to stderr in case of failure */ PerlProc_exit(status); #else + PERL_UNUSED_CONTEXT; # ifdef VMS lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */ # elif defined(WIN32) || defined(__CYGWIN__) - Perl_croak(aTHX_ "dump is not supported"); + Perl_croak_nocontext("dump is not supported"); # else ABORT(); /* for use with undump */ # endif @@ -3562,7 +3685,6 @@ Perl_my_unexec(pTHX) STATIC void S_init_interp(pTHX) { - dVAR; #ifdef MULTIPLICITY # define PERLVAR(prefix,var,type) # define PERLVARA(prefix,var,n,type) @@ -3595,7 +3717,6 @@ S_init_interp(pTHX) STATIC void S_init_main_stash(pTHX) { - dVAR; GV *gv; PL_curstash = PL_defstash = (HV *)SvREFCNT_inc_simple_NN(newHV()); @@ -3609,7 +3730,7 @@ S_init_main_stash(pTHX) because otherwise all we do is delete "main" from it as a consequence of the SvREFCNT_dec, only to add it again with hv_name_set */ SvREFCNT_dec(GvHV(gv)); - hv_name_set(PL_defstash, "main", 4, 0); + hv_name_sets(PL_defstash, "main", 0); GvHV(gv) = MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash)); SvREADONLY_on(gv); PL_incgv = gv_HVadd(gv_AVadd(gv_fetchpvs("INC", GV_ADD|GV_NOTQUAL, @@ -3629,7 +3750,7 @@ S_init_main_stash(pTHX) GvMULTI_on(PL_replgv); (void)Perl_form(aTHX_ "%240s",""); /* Preallocate temp - for immediate signals. */ #ifdef PERL_DONT_CREATE_GVSV - gv_SVadd(PL_errgv); + (void)gv_SVadd(PL_errgv); #endif sv_grow(ERRSV, 240); /* Preallocate - for immediate signals. */ CLEAR_ERRSV(); @@ -3647,7 +3768,6 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript) { int fdscript = -1; PerlIO *rsfp = NULL; - dVAR; Stat_t tmpstatbuf; int fd; @@ -3657,14 +3777,17 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript) PL_origfilename = savepvs("-e"); } else { + const char *s; + UV uv; /* if find_script() returns, it returns a malloc()-ed value */ scriptname = PL_origfilename = find_script(scriptname, dosearch, NULL, 1); - if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) { - const char *s = scriptname + 8; - fdscript = atoi(s); - while (isDIGIT(*s)) - s++; + if (strEQs(scriptname, "/dev/fd/") + && isDIGIT(scriptname[8]) + && grok_atoUV(scriptname + 8, &uv, &s) + && uv <= PERL_INT_MAX + ) { + fdscript = (int)uv; if (*s) { /* PSz 18 Feb 04 * Tell apart "normal" usage of fdscript, e.g. @@ -3722,7 +3845,7 @@ 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 old_umask = umask(0177); int tmpfd = mkstemp(tmpname); umask(old_umask); if (tmpfd > -1) { @@ -3758,10 +3881,10 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript) CopFILE(PL_curcop), Strerror(errno)); } fd = PerlIO_fileno(rsfp); -#if defined(HAS_FCNTL) && defined(F_SETFD) +#if defined(HAS_FCNTL) && defined(F_SETFD) && defined(FD_CLOEXEC) if (fd >= 0) { /* ensure close-on-exec */ - if (fcntl(fd, F_SETFD, 1) < 0) { + if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { Perl_croak(aTHX_ "Can't open perl script \"%s\": %s\n", CopFILE(PL_curcop), Strerror(errno)); } @@ -3802,16 +3925,13 @@ S_validate_suid(pTHX_ PerlIO *rsfp) if (my_euid != my_uid || my_egid != my_gid) { /* (suidperl doesn't exist, in fact) */ dVAR; 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"); - } + Stat_t statbuf; + if (fd < 0 || PerlLIO_fstat(fd, &statbuf) < 0) { /* may be either wrapped or real suid */ + Perl_croak_nocontext( "Illegal suidscript"); } - if ((my_euid != my_uid && my_euid == PL_statbuf.st_uid && PL_statbuf.st_mode & S_ISUID) + if ((my_euid != my_uid && my_euid == statbuf.st_uid && statbuf.st_mode & S_ISUID) || - (my_egid != my_gid && my_egid == PL_statbuf.st_gid && PL_statbuf.st_mode & S_ISGID) + (my_egid != my_gid && my_egid == statbuf.st_gid && statbuf.st_mode & S_ISGID) ) if (!PL_do_undump) Perl_croak(aTHX_ "YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\ @@ -3824,7 +3944,6 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); STATIC void S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp) { - dVAR; const char *s; const char *s2; @@ -3844,7 +3963,7 @@ S_find_beginning(pTHX_ SV* linestr_sv, PerlIO *rsfp) if (*s++ == '-') { while (isDIGIT(s2[-1]) || s2[-1] == '-' || s2[-1] == '.' || s2[-1] == '_') s2--; - if (strnEQ(s2-4,"perl",4)) + if (strEQs(s2-4,"perl")) while ((s = moreswitches(s))) ; } @@ -3857,12 +3976,13 @@ S_init_ids(pTHX) /* no need to do anything here any more if we don't * do tainting. */ #ifndef NO_TAINT_SUPPORT - dVAR; 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_UNUSED_CONTEXT; + /* Should not happen: */ CHECK_MALLOC_TAINT(my_uid && (my_euid != my_uid || my_egid != my_gid)); TAINTING_set( TAINTING_get | (my_uid && (my_euid != my_uid || my_egid != my_gid)) ); @@ -3910,7 +4030,7 @@ Perl_doing_taint(int argc, char *argv[], char *envp[]) * if -T are the first chars together; otherwise one gets * "Too late" message. */ if ( argc > 1 && argv[1][0] == '-' - && (argv[1][1] == 't' || argv[1][1] == 'T') ) + && isALPHA_FOLD_EQ(argv[1][1], 't')) return 1; return 0; } @@ -3922,10 +4042,10 @@ Perl_doing_taint(int argc, char *argv[], char *envp[]) STATIC void S_forbid_setid(pTHX_ const char flag, const bool suidscript) /* g */ { - dVAR; char string[3] = "-x"; const char *message = "program input from stdin"; + PERL_UNUSED_CONTEXT; if (flag) { string[1] = flag; message = string; @@ -3962,8 +4082,8 @@ Perl_init_dbargs(pTHX) void Perl_init_debugger(pTHX) { - dVAR; HV * const ostash = PL_curstash; + MAGIC *mg; PL_curstash = (HV *)SvREFCNT_inc_simple(PL_debstash); @@ -3980,12 +4100,24 @@ Perl_init_debugger(pTHX) PL_DBsingle = GvSV((gv_fetchpvs("DB::single", GV_ADDMULTI, SVt_PV))); if (!SvIOK(PL_DBsingle)) sv_setiv(PL_DBsingle, 0); + mg = sv_magicext(PL_DBsingle, NULL, PERL_MAGIC_debugvar, &PL_vtbl_debugvar, 0, 0); + mg->mg_private = DBVARMG_SINGLE; + SvSETMAGIC(PL_DBsingle); + PL_DBtrace = GvSV((gv_fetchpvs("DB::trace", GV_ADDMULTI, SVt_PV))); if (!SvIOK(PL_DBtrace)) sv_setiv(PL_DBtrace, 0); + mg = sv_magicext(PL_DBtrace, NULL, PERL_MAGIC_debugvar, &PL_vtbl_debugvar, 0, 0); + mg->mg_private = DBVARMG_TRACE; + SvSETMAGIC(PL_DBtrace); + PL_DBsignal = GvSV((gv_fetchpvs("DB::signal", GV_ADDMULTI, SVt_PV))); if (!SvIOK(PL_DBsignal)) sv_setiv(PL_DBsignal, 0); + mg = sv_magicext(PL_DBsignal, NULL, PERL_MAGIC_debugvar, &PL_vtbl_debugvar, 0, 0); + mg->mg_private = DBVARMG_SIGNAL; + SvSETMAGIC(PL_DBsignal); + SvREFCNT_dec(PL_curstash); PL_curstash = ostash; } @@ -4001,7 +4133,8 @@ Perl_init_debugger(pTHX) void Perl_init_stacks(pTHX) { - dVAR; + SSize_t size; + /* start with 128-item stack and 8K cxstack */ PL_curstackinfo = new_stackinfo(REASONABLE(128), REASONABLE(8192/sizeof(PERL_CONTEXT) - 1)); @@ -4031,9 +4164,11 @@ Perl_init_stacks(pTHX) PL_scopestack_ix = 0; PL_scopestack_max = REASONABLE(32); - Newx(PL_savestack,REASONABLE_but_at_least(128,SS_MAXPUSH),ANY); + size = REASONABLE_but_at_least(128,SS_MAXPUSH); + Newx(PL_savestack, size, ANY); PL_savestack_ix = 0; - PL_savestack_max = REASONABLE_but_at_least(128,SS_MAXPUSH); + /*PL_savestack_max lies: it always has SS_MAXPUSH more than it claims */ + PL_savestack_max = size - SS_MAXPUSH; } #undef REASONABLE @@ -4041,7 +4176,6 @@ Perl_init_stacks(pTHX) STATIC void S_nuke_stacks(pTHX) { - dVAR; while (PL_curstackinfo->si_next) PL_curstackinfo = PL_curstackinfo->si_next; while (PL_curstackinfo) { @@ -4097,7 +4231,6 @@ Perl_populate_isa(pTHX_ const char *name, STRLEN len, ...) STATIC void S_init_predump_symbols(pTHX) { - dVAR; GV *tmpgv; IO *io; @@ -4158,8 +4291,6 @@ S_init_predump_symbols(pTHX) void Perl_init_argv_symbols(pTHX_ int argc, char **argv) { - dVAR; - PERL_ARGS_ASSERT_INIT_ARGV_SYMBOLS; argc--,argv++; /* skip name of script */ @@ -4206,15 +4337,17 @@ Perl_init_argv_symbols(pTHX_ int argc, char **argv) STATIC void S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env) { +#ifdef USE_ITHREADS dVAR; +#endif GV* tmpgv; PERL_ARGS_ASSERT_INIT_POSTDUMP_SYMBOLS; PL_toptarget = newSV_type(SVt_PVIV); - sv_setpvs(PL_toptarget, ""); + SvPVCLEAR(PL_toptarget); PL_bodytarget = newSV_type(SVt_PVIV); - sv_setpvs(PL_bodytarget, ""); + SvPVCLEAR(PL_bodytarget); PL_formtarget = PL_bodytarget; TAINT; @@ -4251,23 +4384,70 @@ S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env) } if (env) { char *s, *old_var; + STRLEN nlen; SV *sv; + HV *dups = newHV(); + for (; *env; env++) { old_var = *env; if (!(s = strchr(old_var,'=')) || s == old_var) continue; + nlen = s - old_var; #if defined(MSDOS) && !defined(DJGPP) *s = '\0'; (void)strupr(old_var); *s = '='; #endif - sv = newSVpv(s+1, 0); - (void)hv_store(hv, old_var, s - old_var, sv, 0); + if (hv_exists(hv, old_var, nlen)) { + const char *name = savepvn(old_var, nlen); + + /* make sure we use the same value as getenv(), otherwise code that + uses getenv() (like setlocale()) might see a different value to %ENV + */ + sv = newSVpv(PerlEnv_getenv(name), 0); + + /* keep a count of the dups of this name so we can de-dup environ later */ + if (hv_exists(dups, name, nlen)) + ++SvIVX(*hv_fetch(dups, name, nlen, 0)); + else + (void)hv_store(dups, name, nlen, newSViv(1), 0); + + Safefree(name); + } + else { + sv = newSVpv(s+1, 0); + } + (void)hv_store(hv, old_var, nlen, sv, 0); if (env_is_not_environ) mg_set(sv); } + if (HvKEYS(dups)) { + /* environ has some duplicate definitions, remove them */ + HE *entry; + hv_iterinit(dups); + while ((entry = hv_iternext_flags(dups, 0))) { + STRLEN nlen; + const char *name = HePV(entry, nlen); + IV count = SvIV(HeVAL(entry)); + IV i; + SV **valp = hv_fetch(hv, name, nlen, 0); + + assert(valp); + + /* try to remove any duplicate names, depending on the + * implementation used in my_setenv() the iteration might + * not be necessary, but let's be safe. + */ + for (i = 0; i < count; ++i) + my_setenv(name, 0); + + /* and set it back to the value we set $ENV{name} to */ + my_setenv(name, SvPV_nolen(*valp)); + } + } + SvREFCNT_dec_NN(dups); } #endif /* USE_ENVIRON_ARRAY */ #endif /* !PERL_MICRO */ @@ -4283,7 +4463,6 @@ S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env) STATIC void S_init_perllib(pTHX) { - dVAR; #ifndef VMS const char *perl5lib = NULL; #endif @@ -4318,12 +4497,12 @@ S_init_perllib(pTHX) */ char buf[256]; int idx = 0; - if (my_trnlnm("PERL5LIB",buf,0)) + if (vmstrnenv("PERL5LIB",buf,0,NULL,0)) do { incpush_use_sep(buf, 0, INCPUSH_ADD_SUB_DIRS); - } while (my_trnlnm("PERL5LIB",buf,++idx)); + } while (vmstrnenv("PERL5LIB",buf,++idx,NULL,0)); else { - while (my_trnlnm("PERLLIB",buf,idx++)) + while (vmstrnenv("PERLLIB",buf,idx++,NULL,0)) incpush_use_sep(buf, 0, 0); } #endif /* VMS */ @@ -4353,7 +4532,7 @@ S_init_perllib(pTHX) #ifdef SITELIB_EXP # if defined(WIN32) /* this picks up sitearch as well */ - s = win32_get_sitelib(PERL_FS_VERSION, &len); + s = PerlEnv_sitelib_path(PERL_FS_VERSION, &len); if (s) incpush_use_sep(s, len, INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE); # else @@ -4373,7 +4552,7 @@ S_init_perllib(pTHX) #ifdef PERL_VENDORLIB_EXP # if defined(WIN32) /* this picks up vendorarch as well */ - s = win32_get_vendorlib(PERL_FS_VERSION, &len); + s = PerlEnv_vendorlib_path(PERL_FS_VERSION, &len); if (s) incpush_use_sep(s, len, INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE); # else @@ -4391,7 +4570,7 @@ S_init_perllib(pTHX) #endif #if defined(WIN32) - s = win32_get_privlib(PERL_FS_VERSION, &len); + s = PerlEnv_lib_path(PERL_FS_VERSION, &len); if (s) incpush_use_sep(s, len, INCPUSH_ADD_SUB_DIRS|INCPUSH_CAN_RELOCATE); #else @@ -4429,11 +4608,11 @@ S_init_perllib(pTHX) */ char buf[256]; int idx = 0; - if (my_trnlnm("PERL5LIB",buf,0)) + if (vmstrnenv("PERL5LIB",buf,0,NULL,0)) do { incpush_use_sep(buf, 0, INCPUSH_ADD_OLD_VERS|INCPUSH_NOT_BASEDIR); - } while (my_trnlnm("PERL5LIB",buf,++idx)); + } while (vmstrnenv("PERL5LIB",buf,++idx,NULL,0)); #endif /* VMS */ } @@ -4472,8 +4651,8 @@ S_init_perllib(pTHX) #if defined(DOSISH) || defined(__SYMBIAN32__) # define PERLLIB_SEP ';' #else -# if defined(VMS) -# define PERLLIB_SEP '|' +# if defined(__VMS) +# define PERLLIB_SEP PL_perllib_sep # else # define PERLLIB_SEP ':' # endif @@ -4489,7 +4668,6 @@ S_init_perllib(pTHX) STATIC SV * S_incpush_if_exists(pTHX_ AV *const av, SV *dir, SV *const stem) { - dVAR; Stat_t tmpstatbuf; PERL_ARGS_ASSERT_INCPUSH_IF_EXISTS; @@ -4599,7 +4777,7 @@ S_mayberelocate(pTHX_ const char *const dir, STRLEN len, U32 flags) if (lastslash) { SV *tempsv; while ((*lastslash = '\0'), /* Do that, come what may. */ - (libpath_len >= 3 && memEQ(libpath, "../", 3) + (libpath_len >= 3 && _memEQs(libpath, "../") && (lastslash = strrchr(prefix, '/')))) { if (lastslash[1] == '\0' || (lastslash[1] == '.' @@ -4644,7 +4822,6 @@ S_mayberelocate(pTHX_ const char *const dir, STRLEN len, U32 flags) STATIC void S_incpush(pTHX_ const char *const dir, STRLEN len, U32 flags) { - dVAR; #ifndef PERL_IS_MINIPERL const U8 using_sub_dirs = (U8)flags & (INCPUSH_ADD_VERSIONED_SUB_DIRS @@ -4803,9 +4980,8 @@ S_incpush_use_sep(pTHX_ const char *p, STRLEN len, U32 flags) void Perl_call_list(pTHX_ I32 oldscope, AV *paramList) { - dVAR; SV *atsv; - volatile const line_t oldline = PL_curcop ? CopLINE(PL_curcop) : 0; + VOL const line_t oldline = PL_curcop ? CopLINE(PL_curcop) : 0; CV *cv; STRLEN len; int ret; @@ -4868,8 +5044,7 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) CopLINE_set(PL_curcop, oldline); JMPENV_POP; my_exit_jump(); - /* NOTREACHED */ - assert(0); + NOT_REACHED; /* NOTREACHED */ case 3: if (PL_restartop) { PL_curcop = &PL_compiling; @@ -4887,7 +5062,6 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) void Perl_my_exit(pTHX_ U32 status) { - dVAR; if (PL_exit_flags & PERL_EXIT_ABORT) { abort(); } @@ -4913,7 +5087,6 @@ Perl_my_exit(pTHX_ U32 status) void Perl_my_failure_exit(pTHX) { - dVAR; #ifdef VMS /* We have been called to fall on our sword. The desired exit code * should be already set in STATUS_UNIX, but could be shifted over @@ -5007,15 +5180,16 @@ Perl_my_failure_exit(pTHX) STATIC void S_my_exit_jump(pTHX) { - dVAR; - if (PL_e_script) { SvREFCNT_dec(PL_e_script); PL_e_script = NULL; } POPSTACK_TO(PL_mainstack); - dounwind(-1); + if (cxstack_ix >= 0) { + dounwind(-1); + cx_popblock(cxstack); + } LEAVE_SCOPE(0); JMPENV_JUMP(2); @@ -5024,7 +5198,6 @@ S_my_exit_jump(pTHX) static I32 read_e_script(pTHX_ int idx, SV *buf_sv, int maxlen) { - dVAR; const char * const p = SvPVX_const(PL_e_script); const char *nl = strchr(p, '\n'); @@ -5041,12 +5214,15 @@ read_e_script(pTHX_ int idx, SV *buf_sv, int maxlen) return 1; } +/* removes boilerplate code at the end of each boot_Module xsub */ +void +Perl_xs_boot_epilog(pTHX_ const I32 ax) +{ + if (PL_unitcheckav) + call_list(PL_scopestack_ix, PL_unitcheckav); + XSRETURN_YES; +} + /* - * Local variables: - * c-indentation-style: bsd - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - * * ex: set ts=8 sts=4 sw=4 et: */