This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add more tests for the builtin source filter implementation, and fix
[perl5.git] / pp_ctl.c
index 4b099d4..364a1d5 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1695,11 +1695,10 @@ PP(pp_caller)
     /* XXX only hints propagated via op_private are currently
      * visible (others are not easily accessible, since they
      * use the global PL_hints) */
-    PUSHs(sv_2mortal(newSViv((I32)cx->blk_oldcop->op_private &
-                            HINT_PRIVATE_MASK)));
+    PUSHs(sv_2mortal(newSViv(CopHINTS_get(cx->blk_oldcop))));
     {
        SV * mask ;
-       SV * const old_warnings = cx->blk_oldcop->cop_warnings ;
+       STRLEN * const old_warnings = cx->blk_oldcop->cop_warnings ;
 
        if  (old_warnings == pWARN_NONE ||
                (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
@@ -1718,7 +1717,7 @@ PP(pp_caller)
            }
        }
         else
-            mask = newSVsv(old_warnings);
+            mask = newSVpvn((char *) (old_warnings + 1), old_warnings[0]);
         PUSHs(sv_2mortal(mask));
     }
 
@@ -2815,7 +2814,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
     *padp = (AV*)SvREFCNT_inc_simple(PL_comppad);
     LEAVE;
     if (IN_PERL_COMPILETIME)
-       PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);
+       CopHINTS_set(&PL_compiling, PL_hints);
 #ifdef OP_IN_REGISTER
     op = PL_opsave;
 #endif
@@ -3221,7 +3220,8 @@ PP(pp_require)
                            }
 
                            if (!tryrsfp) {
-                               tryrsfp = PerlIO_open("/dev/null", PERL_SCRIPT_MODE);
+                               tryrsfp = PerlIO_open(BIT_BUCKET,
+                                                     PERL_SCRIPT_MODE);
                            }
                        }
                        SP--;
@@ -3364,13 +3364,15 @@ PP(pp_require)
     PL_rsfp = tryrsfp;
     SAVEHINTS();
     PL_hints = 0;
-    SAVESPTR(PL_compiling.cop_warnings);
+    SAVECOMPILEWARNINGS();
     if (PL_dowarn & G_WARN_ALL_ON)
         PL_compiling.cop_warnings = pWARN_ALL ;
     else if (PL_dowarn & G_WARN_ALL_OFF)
         PL_compiling.cop_warnings = pWARN_NONE ;
-    else if (PL_taint_warn)
-        PL_compiling.cop_warnings = newSVpvn(WARN_TAINTstring, WARNsize);
+    else if (PL_taint_warn) {
+        PL_compiling.cop_warnings
+           = Perl_new_warnings_bitfield(aTHX_ NULL, WARN_TAINTstring, WARNsize);
+    }
     else
         PL_compiling.cop_warnings = pWARN_STD ;
     SAVESPTR(PL_compiling.cop_io);
@@ -3462,13 +3464,8 @@ PP(pp_entereval)
     PL_hints = PL_op->op_targ;
     if (saved_hh)
        GvHV(PL_hintgv) = saved_hh;
-    SAVESPTR(PL_compiling.cop_warnings);
-    if (specialWARN(PL_curcop->cop_warnings))
-        PL_compiling.cop_warnings = PL_curcop->cop_warnings;
-    else {
-        PL_compiling.cop_warnings = newSVsv(PL_curcop->cop_warnings);
-        SAVEFREESV(PL_compiling.cop_warnings);
-    }
+    SAVECOMPILEWARNINGS();
+    PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
     SAVESPTR(PL_compiling.cop_io);
     if (specialCopIO(PL_curcop->cop_io))
         PL_compiling.cop_io = PL_curcop->cop_io;
@@ -3477,27 +3474,13 @@ PP(pp_entereval)
         SAVEFREESV(PL_compiling.cop_io);
     }
     if (PL_compiling.cop_hints) {
-       PL_compiling.cop_hints->refcounted_he_refcnt--;
+       Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints);
     }
     PL_compiling.cop_hints = PL_curcop->cop_hints;
     if (PL_compiling.cop_hints) {
-#ifdef USE_ITHREADS
-       /* PL_curcop could be pointing to an optree owned by another /.*parent/
-          thread. We can't manipulate the reference count of the refcounted he
-          there (race condition) so we have to do something less than
-          pleasant to keep it read only. The simplest solution seems to be to
-          copy their chain. We might want to cache this.
-          Alternatively we could add a flag to the refcounted he *we* point to
-          here saying "I don't own a reference count on the thing I point to",
-          and arrange for Perl_refcounted_he_free() to spot that. If so, we'd
-          still need to copy the topmost refcounted he so that we could change
-          its flag. So still not trivial. (Flag bits could be hung from the
-          shared HEK) */
-       PL_compiling.cop_hints
-           = Perl_refcounted_he_copy(aTHX_ PL_compiling.cop_hints);
-#else
+       HINTS_REFCNT_LOCK;
        PL_compiling.cop_hints->refcounted_he_refcnt++;
-#endif
+       HINTS_REFCNT_UNLOCK;
     }
     /* special case: an eval '' executed within the DB package gets lexically
      * placed in the first non-DB CV rather than the current CV - this
@@ -4091,7 +4074,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
                PUSHs(other);
                PUSHs(*svp);
                PUTBACK;
-               if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+               if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
                    (void) pp_i_eq();
                else
                    (void) pp_eq();
@@ -4185,7 +4168,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
        /* Otherwise, numeric comparison */
        PUSHs(d); PUSHs(e);
        PUTBACK;
-       if ((PL_curcop->op_private & HINT_INTEGER) == HINT_INTEGER)
+       if (CopHINTS_get(PL_curcop) & HINT_INTEGER)
            (void) pp_i_eq();
        else
            (void) pp_eq();
@@ -4555,14 +4538,23 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
     SV * const filter_state = (SV *)IoTOP_GV(datasv);
     SV * const filter_sub = (SV *)IoBOTTOM_GV(datasv);
     int len = 0;
-
+    /* Filter API says that the filter appends to the contents of the buffer.
+       Usually the buffer is "", so the details don't matter. But if it's not,
+       then clearly what it contains is already filtered by this filter, so we
+       don't want to pass it in a second time.
+       I'm going to use a mortal in case the upstream filter croaks.  */
+    SV *const upstream
+       = ((SvOK(buf_sv) && sv_len(buf_sv)) || SvGMAGICAL(buf_sv))
+       ? sv_newmortal() : buf_sv;
+
+    SvUPGRADE(upstream, SVt_PV);
     /* I was having segfault trouble under Linux 2.2.5 after a
        parse error occured.  (Had to hack around it with a test
        for PL_error_count == 0.)  Solaris doesn't segfault --
        not sure where the trouble is yet.  XXX */
 
     if (filter_has_file) {
-       len = FILTER_READ(idx+1, buf_sv, maxlen);
+       len = FILTER_READ(idx+1, upstream, maxlen);
     }
 
     if (filter_sub && len >= 0) {
@@ -4574,7 +4566,7 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        SAVETMPS;
        EXTEND(SP, 2);
 
-       DEFSV = buf_sv;
+       DEFSV = upstream;
        PUSHMARK(SP);
        PUSHs(sv_2mortal(newSViv(maxlen)));
        if (filter_state) {
@@ -4613,6 +4605,9 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        filter_del(S_run_user_filter);
     }
 
+    if (upstream != buf_sv) {
+       sv_catsv(buf_sv, upstream);
+    }
     return len;
 }