X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_ctl.c;h=621024a97db35f82efc692cbfc5a0e5b58427044;hb=45c0de28763808112fd2f46ea311b6bb0c6050b3;hp=0beaea93a0e1dda997b80fb3a23c273ed9ef40e9;hpb=06bf62c76633176572262d33d1b4072ea6d227a8;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_ctl.c b/pp_ctl.c index 0beaea9..621024a 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -29,6 +29,7 @@ #define CALLOP this->*PL_op #else #define CALLOP *PL_op +static void *docatch_body _((void *o)); static OP *docatch _((OP *o)); static OP *dofindlabel _((OP *o, char *label, OP **opstack, OP **oplimit)); static void doparseform _((SV *sv)); @@ -41,6 +42,7 @@ static void save_lines _((AV *array, SV *sv)); static I32 sortcv _((SV *a, SV *b)); static void qsortsv _((SV **array, size_t num_elts, I32 (*fun)(SV *a, SV *b))); static OP *doeval _((int gimme, OP** startop)); +static PerlIO *doopen_pmc _((const char *name, const char *mode)); static I32 sv_ncmp _((SV *a, SV *b)); static I32 sv_i_ncmp _((SV *a, SV *b)); static I32 amagic_ncmp _((SV *a, SV *b)); @@ -2490,38 +2492,41 @@ save_lines(AV *array, SV *sv) } } +STATIC void * +docatch_body(va_list args) +{ + CALLRUNOPS(); + return NULL; +} + STATIC OP * docatch(OP *o) { dTHR; int ret; OP *oldop = PL_op; - dJMPENV; - PL_op = o; #ifdef DEBUGGING assert(CATCH_GET == TRUE); - DEBUG_l(deb("Setting up local jumplevel %p, was %p\n", &cur_env, PL_top_env)); #endif - JMPENV_PUSH(ret); + PL_op = o; + redo_body: + CALLPROTECT(&ret, FUNC_NAME_TO_PTR(docatch_body)); switch (ret) { - default: /* topmost level handles it */ -pass_the_buck: - JMPENV_POP; + case 0: + break; + case 3: + if (PL_restartop) { + PL_op = PL_restartop; + PL_restartop = 0; + goto redo_body; + } + /* FALL THROUGH */ + default: PL_op = oldop; JMPENV_JUMP(ret); /* NOTREACHED */ - case 3: - if (!PL_restartop) - goto pass_the_buck; - PL_op = PL_restartop; - PL_restartop = 0; - /* FALL THROUGH */ - case 0: - CALLRUNOPS(); - break; } - JMPENV_POP; PL_op = oldop; return Nullop; } @@ -2771,6 +2776,38 @@ doeval(int gimme, OP** startop) RETURNOP(PL_eval_start); } +STATIC PerlIO * +doopen_pmc(const char *name, const char *mode) +{ + STRLEN namelen = strlen(name); + PerlIO *fp; + + if (namelen > 3 && strcmp(name + namelen - 3, ".pm") == 0) { + SV *pmcsv = newSVpvf("%s%c", name, 'c'); + char *pmc = SvPV_nolen(pmcsv); + Stat_t pmstat; + Stat_t pmcstat; + if (PerlLIO_stat(pmc, &pmcstat) < 0) { + fp = PerlIO_open(name, mode); + } + else { + if (PerlLIO_stat(name, &pmstat) < 0 || + pmstat.st_mtime < pmcstat.st_mtime) + { + fp = PerlIO_open(pmc, mode); + } + else { + fp = PerlIO_open(name, mode); + } + } + SvREFCNT_dec(pmcsv); + } + else { + fp = PerlIO_open(name, mode); + } + return fp; +} + PP(pp_require) { djSP; @@ -2821,7 +2858,7 @@ PP(pp_require) ) { tryname = name; - tryrsfp = PerlIO_open(name,PERL_SCRIPT_MODE); + tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE); } else { AV *ar = GvAVn(PL_incgv); @@ -2845,7 +2882,7 @@ PP(pp_require) #endif TAINT_PROPER("require"); tryname = SvPVX(namesv); - tryrsfp = PerlIO_open(tryname, PERL_SCRIPT_MODE); + tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE); if (tryrsfp) { if (tryname[0] == '.' && tryname[1] == '/') tryname += 2;