X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl.c;h=3ddbbfb55c51ec31a5ea65c765b8b2bb21ff970c;hb=b23a565decf7acb33d46fc5bb7bed5ad79774efe;hp=554e3127273666ad7ca617d5fd43d1cc9c52afba;hpb=f97a0ef27cbaddb0a75b0772eacfc746e93f62f4;p=p5sagit%2Fp5-mst-13.2.git diff --git a/perl.c b/perl.c index 554e312..3ddbbfb 100644 --- a/perl.c +++ b/perl.c @@ -137,6 +137,22 @@ static I32 read_e_script(pTHX_ int idx, SV *buf_sv, int maxlen); #endif #endif +#define CALL_BODY_EVAL(myop) \ + if (PL_op == (myop)) \ + PL_op = Perl_pp_entereval(aTHX); \ + if (PL_op) \ + CALLRUNOPS(aTHX); + +#define CALL_BODY_SUB(myop) \ + if (PL_op == (myop)) \ + PL_op = Perl_pp_entersub(aTHX); \ + if (PL_op) \ + CALLRUNOPS(aTHX); + +#define CALL_LIST_BODY(cv) \ + PUSHMARK(PL_stack_sp); \ + call_sv((SV*)(cv), G_EVAL|G_DISCARD); + static void S_init_tls_and_interp(PerlInterpreter *my_perl) { @@ -148,6 +164,7 @@ S_init_tls_and_interp(PerlInterpreter *my_perl) ALLOC_THREAD_KEY; PERL_SET_THX(my_perl); OP_REFCNT_INIT; + HINTS_REFCNT_INIT; MUTEX_INIT(&PL_dollarzero_mutex); # endif #ifdef PERL_IMPLICIT_CONTEXT @@ -228,7 +245,7 @@ void perl_construct(pTHXx) { dVAR; - PERL_UNUSED_ARG(my_perl); + PERL_UNUSED_CONTEXT; #ifdef MULTIPLICITY init_interp(); PL_perl_destruct_level = 1; @@ -360,7 +377,7 @@ perl_construct(pTHXx) if ((long) PL_mmap_page_size < 0) { if (errno) { SV * const error = ERRSV; - (void) SvUPGRADE(error, SVt_PV); + SvUPGRADE(error, SVt_PV); Perl_croak(aTHX_ "panic: sysconf: %s", SvPV_nolen_const(error)); } else @@ -389,6 +406,10 @@ perl_construct(pTHXx) PL_timesbase.tms_cstime = 0; #endif +#ifdef PERL_MAD + PL_curforce = -1; +#endif + ENTER; } @@ -404,6 +425,7 @@ no threads. int Perl_nothreadhook(pTHX) { + PERL_UNUSED_CONTEXT; return 0; } @@ -523,7 +545,7 @@ perl_destruct(pTHXx) pid_t child; #endif - PERL_UNUSED_ARG(my_perl); + PERL_UNUSED_CONTEXT; /* wait for all pseudo-forked children to finish */ PERL_WAIT_FOR_CHILDREN; @@ -852,7 +874,7 @@ perl_destruct(pTHXx) if(PL_rsfp) { (void)PerlIO_close(PL_rsfp); - PL_rsfp = Nullfp; + PL_rsfp = NULL; } /* Filters for program text */ @@ -894,7 +916,6 @@ perl_destruct(pTHXx) SvREFCNT_dec(PL_rs); /* $/ */ PL_rs = NULL; - PL_multiline = 0; /* $* */ Safefree(PL_osname); /* $^O */ PL_osname = NULL; @@ -1030,11 +1051,10 @@ perl_destruct(pTHXx) PL_utf8_idcont = NULL; if (!specialWARN(PL_compiling.cop_warnings)) - SvREFCNT_dec(PL_compiling.cop_warnings); + PerlMemShared_free(PL_compiling.cop_warnings); PL_compiling.cop_warnings = NULL; - if (!specialCopIO(PL_compiling.cop_io)) - SvREFCNT_dec(PL_compiling.cop_io); - PL_compiling.cop_io = NULL; + Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash); + PL_compiling.cop_hints_hash = NULL; CopFILE_free(&PL_compiling); CopSTASH_free(&PL_compiling); @@ -1251,6 +1271,12 @@ perl_destruct(pTHXx) sv_free_arenas(); + while (PL_regmatch_slab) { + regmatch_slab *s = PL_regmatch_slab; + PL_regmatch_slab = PL_regmatch_slab->next; + Safefree(s); + } + /* As the absolutely last thing, free the non-arena SV for mess() */ if (PL_mess_sv) { @@ -1288,10 +1314,19 @@ void perl_free(pTHXx) { #ifdef PERL_TRACK_MEMPOOL - /* Emulate the PerlHost behaviour of free()ing all memory allocated in this - thread at thread exit. */ - while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header)) - safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next)); + { + /* + * 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) { + /* Emulate the PerlHost behaviour of free()ing all memory allocated in this + thread at thread exit. */ + while(aTHXx->Imemory_debug_header.next != &(aTHXx->Imemory_debug_header)) + safesysfree(sTHX + (char *)(aTHXx->Imemory_debug_header.next)); + } + } #endif #if defined(WIN32) || defined(NETWARE) @@ -1323,6 +1358,8 @@ perl_free(pTHXx) #if defined(__hpux) && !(defined(__ux_version) && __ux_version <= 1020) && !defined(__GNUC__) #pragma fini "perl_fini" +#elif defined(__sun) && !defined(__GNUC__) +#pragma fini (perl_fini) #endif static void @@ -1790,6 +1827,9 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) # ifdef PERL_IMPLICIT_SYS " PERL_IMPLICIT_SYS" # endif +# ifdef PERL_MAD + " PERL_MAD" +# endif # ifdef PERL_MALLOC_WRAP " PERL_MALLOC_WRAP" # endif @@ -2010,7 +2050,8 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) #endif if (PL_taint_warn && PL_dowarn != G_WARN_ALL_OFF) { - PL_compiling.cop_warnings = newSVpvn(WARN_TAINTstring, WARNsize); + PL_compiling.cop_warnings + = Perl_new_warnings_bitfield(aTHX_ NULL, WARN_TAINTstring, WARNsize); } if (!scriptname) @@ -2163,6 +2204,25 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit) Perl_croak(aTHX_ "PERL_SIGNALS illegal: \"%s\"", s); } +#ifdef PERL_MAD + if ((s = PerlEnv_getenv("PERL_XMLDUMP"))) { + PL_madskills = 1; + PL_minus_c = 1; + if (!s || !s[0]) + PL_xmlfp = PerlIO_stdout(); + else { + PL_xmlfp = PerlIO_open(s, "w"); + if (!PL_xmlfp) + Perl_croak(aTHX_ "Can't open %s", s); + } + my_setenv("PERL_XMLDUMP", Nullch); /* hide from subprocs */ + } + if ((s = PerlEnv_getenv("PERL_MADSKILLS"))) { + PL_madskills = atoi(s); + my_setenv("PERL_MADSKILLS", Nullch); /* hide from subprocs */ + } +#endif + init_lexer(); /* now parse the script */ @@ -2234,7 +2294,7 @@ perl_run(pTHXx) int ret = 0; dJMPENV; - PERL_UNUSED_ARG(my_perl); + PERL_UNUSED_CONTEXT; oldscope = PL_scopestack_ix; #ifdef VMS @@ -2288,6 +2348,12 @@ S_run_body(pTHX_ I32 oldscope) PL_sawampersand ? "Enabling" : "Omitting")); if (!PL_restartop) { +#ifdef PERL_MAD + if (PL_xmlfp) { + xmldump_all(); + exit(0); /* less likely to core dump than my_exit(0) */ + } +#endif DEBUG_x(dump_all()); #ifdef DEBUGGING if (!DEBUG_q_TEST) @@ -2556,38 +2622,22 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) if (!(flags & G_EVAL)) { CATCH_SET(TRUE); - call_body((OP*)&myop, FALSE); + CALL_BODY_SUB((OP*)&myop); retval = PL_stack_sp - (PL_stack_base + oldmark); CATCH_SET(oldcatch); } else { myop.op_other = (OP*)&myop; PL_markstack_ptr--; - /* we're trying to emulate pp_entertry() here */ - { - register PERL_CONTEXT *cx; - const I32 gimme = GIMME_V; - - ENTER; - SAVETMPS; - - PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp); - PUSHEVAL(cx, 0, 0); - PL_eval_root = PL_op; /* Only needed so that goto works right. */ - - PL_in_eval = EVAL_INEVAL; - if (flags & G_KEEPERR) - PL_in_eval |= EVAL_KEEPERR; - else - sv_setpvn(ERRSV,"",0); - } + create_eval_scope(flags|G_FAKINGEVAL); PL_markstack_ptr++; JMPENV_PUSH(ret); + switch (ret) { case 0: redo_body: - call_body((OP*)&myop, FALSE); + CALL_BODY_SUB((OP*)&myop); retval = PL_stack_sp - (PL_stack_base + oldmark); if (!(flags & G_KEEPERR)) sv_setpvn(ERRSV,"",0); @@ -2620,21 +2670,8 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) break; } - if (PL_scopestack_ix > oldscope) { - SV **newsp; - PMOP *newpm; - I32 gimme; - register PERL_CONTEXT *cx; - I32 optype; - - POPBLOCK(cx,newpm); - POPEVAL(cx); - PL_curpm = newpm; - LEAVE; - PERL_UNUSED_VAR(newsp); - PERL_UNUSED_VAR(gimme); - PERL_UNUSED_VAR(optype); - } + if (PL_scopestack_ix > oldscope) + delete_eval_scope(); JMPENV_POP; } @@ -2648,20 +2685,6 @@ Perl_call_sv(pTHX_ SV *sv, I32 flags) return retval; } -STATIC void -S_call_body(pTHX_ const OP *myop, bool is_eval) -{ - dVAR; - if (PL_op == myop) { - if (is_eval) - PL_op = Perl_pp_entereval(aTHX); /* this doesn't do a POPMARK */ - else - PL_op = Perl_pp_entersub(aTHX); /* this does */ - } - if (PL_op) - CALLRUNOPS(aTHX); -} - /* Eval a string. The G_EVAL flag is always assumed. */ /* @@ -2715,7 +2738,7 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags) switch (ret) { case 0: redo_body: - call_body((OP*)&myop,TRUE); + CALL_BODY_EVAL((OP*)&myop); retval = PL_stack_sp - (PL_stack_base + oldmark); if (!(flags & G_KEEPERR)) sv_setpvn(ERRSV,"",0); @@ -2992,13 +3015,14 @@ Perl_moreswitches(pTHX_ char *s) case 'C': s++; PL_unicode = parse_unicode_opts( (const char **)&s ); + if (PL_unicode & PERL_UNICODE_UTF8CACHEASSERT_FLAG) + PL_utf8cache = -1; return s; case 'F': PL_minus_F = TRUE; PL_splitstr = ++s; while (*s && !isSPACE(*s)) ++s; - *s = '\0'; - PL_splitstr = savepv(PL_splitstr); + PL_splitstr = savepvn(PL_splitstr, s - PL_splitstr); return s; case 'a': PL_minus_a = TRUE; @@ -3030,7 +3054,9 @@ Perl_moreswitches(pTHX_ char *s) sv_catpv(sv, start); else { sv_catpvn(sv, start, s-start); - Perl_sv_catpvf(aTHX_ sv, " split(/,/,q%c%s%c)", 0, ++s, 0); + /* Don't use NUL as q// delimiter here, this string goes in the + * environment. */ + Perl_sv_catpvf(aTHX_ sv, " split(/,/,q{%s});", ++s); } s += strlen(s); my_setenv("PERL5DB", SvPV_nolen_const(sv)); @@ -3065,13 +3091,17 @@ Perl_moreswitches(pTHX_ char *s) return s+1; } #endif /* __CYGWIN__ */ - PL_inplace = savepv(s+1); - for (s = PL_inplace; *s && !isSPACE(*s); s++) - ; + { + const char * const start = ++s; + while (*s && !isSPACE(*s)) + ++s; + + PL_inplace = savepvn(start, s - start); + } if (*s) { - *s++ = '\0'; + ++s; if (*s == '-') /* Additional switches on #! line. */ - s++; + s++; } return s; case 'I': /* -I handled both here and in parse_body() */ @@ -3232,8 +3262,8 @@ Perl_moreswitches(pTHX_ char *s) " DEVEL" STRINGIFY(PERL_PATCHNUM) #endif " built for %s", - vstringify(PL_patchlevel), - ARCHNAME)); + (void*)vstringify(PL_patchlevel), + ARCHNAME)); #else /* DGUX */ /* Adjust verbose output as in the perl that ships with the DG/UX OS from EMC */ PerlIO_printf(PerlIO_stdout(), @@ -3252,7 +3282,7 @@ Perl_moreswitches(pTHX_ char *s) PerlIO_printf(PerlIO_stdout(), "\n(with %d registered patch%s, " "see perl -V for more detail)", - (int)LOCAL_PATCH_COUNT, + LOCAL_PATCH_COUNT, (LOCAL_PATCH_COUNT!=1) ? "es" : ""); #endif @@ -3341,14 +3371,14 @@ Internet, point your browser at http://www.perl.org/, the Perl Home Page.\n\n"); case 'W': PL_dowarn = G_WARN_ALL_ON|G_WARN_ON; if (!specialWARN(PL_compiling.cop_warnings)) - SvREFCNT_dec(PL_compiling.cop_warnings); + PerlMemShared_free(PL_compiling.cop_warnings); PL_compiling.cop_warnings = pWARN_ALL ; s++; return s; case 'X': PL_dowarn = G_WARN_ALL_OFF; if (!specialWARN(PL_compiling.cop_warnings)) - SvREFCNT_dec(PL_compiling.cop_warnings); + PerlMemShared_free(PL_compiling.cop_warnings); PL_compiling.cop_warnings = pWARN_NONE ; s++; return s; @@ -3387,15 +3417,14 @@ 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; - SV* file; + SV * prog = newSVpv(BIN_EXP, 0); + SV * file = newSVpv(PL_origfilename, 0); int status = 1; extern int etext; - prog = newSVpv(BIN_EXP, 0); sv_catpvs(prog, "/perl"); - file = newSVpv(PL_origfilename, 0); sv_catpvs(file, ".perldump"); unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0); @@ -3447,6 +3476,11 @@ S_init_interp(pTHX) # undef PERLVARIC #endif + /* As these are inside a structure, PERLVARI isn't capable of initialising + them */ + PL_regindent = 0; + PL_reg_oldcurpm = PL_reg_curpm = NULL; + PL_reg_poscache = PL_reg_starttry = NULL; } STATIC void @@ -3467,18 +3501,18 @@ S_init_main_stash(pTHX) 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); - GvHV(gv) = (HV*)SvREFCNT_inc(PL_defstash); + GvHV(gv) = (HV*)SvREFCNT_inc_simple(PL_defstash); SvREADONLY_on(gv); PL_incgv = gv_HVadd(gv_AVadd(gv_fetchpvs("INC", GV_ADD|GV_NOTQUAL, SVt_PVAV))); - SvREFCNT_inc(PL_incgv); /* Don't allow it to be freed */ + SvREFCNT_inc_simple(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 */ GvMULTI_on(PL_hintgv); PL_defgv = gv_fetchpvs("_", GV_ADD|GV_NOTQUAL, SVt_PVAV); - SvREFCNT_inc(PL_defgv); + SvREFCNT_inc_simple(PL_defgv); PL_errgv = gv_HVadd(gv_fetchpvs("@", GV_ADD|GV_NOTQUAL, SVt_PV)); - SvREFCNT_inc(PL_errgv); + SvREFCNT_inc_simple(PL_errgv); GvMULTI_on(PL_errgv); PL_replgv = gv_fetchpvs("\022", GV_ADD|GV_NOTQUAL, SVt_PV); /* ^R */ GvMULTI_on(PL_replgv); @@ -3634,8 +3668,8 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, SV *sv, Perl_sv_setpvf(aTHX_ cmd, "\ %s -ne%s%s%s %s | %"SVf" %s %"SVf" %s", - perl, quote, code, quote, scriptname, cpp, - cpp_discard_flag, sv, CPPMINUS); + perl, quote, code, quote, scriptname, (void*)cpp, + cpp_discard_flag, (void*)sv, CPPMINUS); PL_doextract = FALSE; @@ -4491,7 +4525,7 @@ S_init_lexer(pTHX) dVAR; PerlIO *tmpfp; tmpfp = PL_rsfp; - PL_rsfp = Nullfp; + PL_rsfp = NULL; lex_start(PL_linestr); PL_rsfp = tmpfp; PL_subname = newSVpvs("main"); @@ -4512,7 +4546,7 @@ S_init_predump_symbols(pTHX) IoIFP(io) = PerlIO_stdin(); tmpgv = gv_fetchpvs("stdin", GV_ADD|GV_NOTQUAL, SVt_PV); GvMULTI_on(tmpgv); - GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io); + GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io); tmpgv = gv_fetchpvs("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO); GvMULTI_on(tmpgv); @@ -4522,7 +4556,7 @@ S_init_predump_symbols(pTHX) setdefout(tmpgv); tmpgv = gv_fetchpvs("stdout", GV_ADD|GV_NOTQUAL, SVt_PV); GvMULTI_on(tmpgv); - GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io); + GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io); PL_stderrgv = gv_fetchpvs("STDERR", GV_ADD|GV_NOTQUAL, SVt_PVIO); GvMULTI_on(PL_stderrgv); @@ -4531,7 +4565,7 @@ S_init_predump_symbols(pTHX) IoOFP(io) = IoIFP(io) = PerlIO_stderr(); tmpgv = gv_fetchpvs("stderr", GV_ADD|GV_NOTQUAL, SVt_PV); GvMULTI_on(tmpgv); - GvIOp(tmpgv) = (IO*)SvREFCNT_inc(io); + GvIOp(tmpgv) = (IO*)SvREFCNT_inc_simple(io); PL_statname = newSV(0); /* last filename we did stat on */ @@ -4765,7 +4799,8 @@ S_init_perllib(pTHX) # endif #endif -#ifdef SITELIB_STEM /* Search for version-specific dirs below here */ +#if defined(SITELIB_STEM) && defined(PERL_INC_VERSION_LIST) + /* Search for version-specific dirs below here */ incpush(SITELIB_STEM, FALSE, TRUE, TRUE, TRUE); #endif @@ -5013,19 +5048,21 @@ S_incpush(pTHX_ const char *dir, bool addsubdirs, bool addoldvers, bool usesep, #endif /* .../version/archname if -d .../version/archname */ Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PATH PERL_ARCH_FMT, - libdir, + (void*)libdir, (int)PERL_REVISION, (int)PERL_VERSION, (int)PERL_SUBVERSION, ARCHNAME); subdir = S_incpush_if_exists(aTHX_ subdir); /* .../version if -d .../version */ - Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PATH, libdir, + Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT_PATH, + (void*)libdir, (int)PERL_REVISION, (int)PERL_VERSION, (int)PERL_SUBVERSION); subdir = S_incpush_if_exists(aTHX_ subdir); /* .../archname if -d .../archname */ - Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT, libdir, ARCHNAME); + Perl_sv_setpvf(aTHX_ subdir, "%"SVf PERL_ARCH_FMT, + (void*)libdir, ARCHNAME); subdir = S_incpush_if_exists(aTHX_ subdir); } @@ -5078,14 +5115,25 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) av_push(PL_checkav_save, (SV*)cv); } } else { - SAVEFREESV(cv); + if (!PL_madskills) + SAVEFREESV(cv); } JMPENV_PUSH(ret); switch (ret) { case 0: - call_list_body(cv); +#ifdef PERL_MAD + if (PL_madskills) + PL_madskills |= 16384; +#endif + CALL_LIST_BODY(cv); +#ifdef PERL_MAD + if (PL_madskills) + PL_madskills &= ~16384; +#endif atsv = ERRSV; (void)SvPV_const(atsv, len); + if (PL_madskills && PL_minus_c && paramList == PL_beginav) + break; /* not really trying to run, so just wing it */ if (len) { PL_curcop = &PL_compiling; CopLINE_set(PL_curcop, oldline); @@ -5100,7 +5148,7 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) while (PL_scopestack_ix > oldscope) LEAVE; JMPENV_POP; - Perl_croak(aTHX_ "%"SVf"", atsv); + Perl_croak(aTHX_ "%"SVf"", (void*)atsv); } break; case 1: @@ -5115,6 +5163,8 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) PL_curcop = &PL_compiling; CopLINE_set(PL_curcop, oldline); JMPENV_POP; + if (PL_madskills && PL_minus_c && paramList == PL_beginav) + return; /* not really trying to run, so just wing it */ if (PL_statusvalue && !(PL_exit_flags & PERL_EXIT_EXPECTED)) { if (paramList == PL_beginav) Perl_croak(aTHX_ "BEGIN failed--compilation aborted"); @@ -5140,15 +5190,6 @@ Perl_call_list(pTHX_ I32 oldscope, AV *paramList) } } -STATIC void * -S_call_list_body(pTHX_ CV *cv) -{ - dVAR; - PUSHMARK(PL_stack_sp); - call_sv((SV*)cv, G_EVAL|G_DISCARD); - return NULL; -} - void Perl_my_exit(pTHX_ U32 status) {