perldoc pod update
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 9b2284d..6bfa1a1 100644 (file)
--- a/op.c
+++ b/op.c
@@ -35,6 +35,8 @@
         Nullop )                                               \
      : (CHECKCALL[type])((OP*)o))
 
+#define PAD_MAX 999999999
+
 static bool scalar_mod_type _((OP *o, I32 type));
 #ifndef PERL_OBJECT
 static I32 list_assignment _((OP *o));
@@ -46,7 +48,7 @@ static OP *too_few_arguments _((OP *o, char* name));
 static OP *too_many_arguments _((OP *o, char* name));
 static void null _((OP* o));
 static PADOFFSET pad_findlex _((char* name, PADOFFSET newoff, U32 seq,
-       CV* startcv, I32 cx_ix));
+       CV* startcv, I32 cx_ix, I32 saweval));
 static OP *newDEFSVOP _((void));
 static OP *new_logop _((I32 type, I32 flags, OP **firstp, OP **otherp));
 #endif
@@ -131,11 +133,12 @@ pad_allocmy(char *name)
        for (off = AvFILLp(PL_comppad_name); off > PL_comppad_name_floor; off--) {
            if ((sv = svp[off])
                && sv != &PL_sv_undef
+               && (SvIVX(sv) == PAD_MAX || SvIVX(sv) == 0)
                && strEQ(name, SvPVX(sv)))
            {
                warner(WARN_UNSAFE,
                        "\"my\" variable %s masks earlier declaration in same %s", 
-                       name, (SvIVX(sv) == 999999999 ? "scope" : "statement"));
+                       name, (SvIVX(sv) == PAD_MAX ? "scope" : "statement"));
                break;
            }
        }
@@ -153,7 +156,7 @@ pad_allocmy(char *name)
        PL_sv_objcount++;
     }
     av_store(PL_comppad_name, off, sv);
-    SvNVX(sv) = (double)999999999;
+    SvNVX(sv) = (double)PAD_MAX;
     SvIVX(sv) = 0;                     /* Not yet introduced--see newSTATEOP */
     if (!PL_min_intro_pending)
        PL_min_intro_pending = off;
@@ -167,7 +170,7 @@ pad_allocmy(char *name)
 }
 
 STATIC PADOFFSET
-pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
+pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix, I32 saweval)
 {
     dTHR;
     CV *cv;
@@ -175,7 +178,6 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
     SV *sv;
     register I32 i;
     register PERL_CONTEXT *cx;
-    int saweval;
 
     for (cv = startcv; cv; cv = CvOUTSIDE(cv)) {
        AV *curlist = CvPADLIST(cv);
@@ -215,8 +217,14 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
                    sv_setpv(namesv, name);
                    av_store(PL_comppad_name, newoff, namesv);
                    SvNVX(namesv) = (double)PL_curcop->cop_seq;
-                   SvIVX(namesv) = 999999999;  /* A ref, intro immediately */
+                   SvIVX(namesv) = PAD_MAX;    /* A ref, intro immediately */
                    SvFAKE_on(namesv);          /* A ref, not a real var */
+                   if (SvOBJECT(sv)) {         /* A typed var */
+                       SvOBJECT_on(namesv);
+                       (void)SvUPGRADE(namesv, SVt_PVMG);
+                       SvSTASH(namesv) = (HV*)SvREFCNT_inc((SV*)SvSTASH(sv));
+                       PL_sv_objcount++;
+                   }
                    if (CvANON(PL_compcv) || SvTYPE(PL_compcv) == SVt_PVFM) {
                        /* "It's closures all the way down." */
                        CvCLONE_on(PL_compcv);
@@ -228,14 +236,18 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
                            CV *bcv;
                            for (bcv = startcv;
                                 bcv && bcv != cv && !CvCLONE(bcv);
-                                bcv = CvOUTSIDE(bcv)) {
+                                bcv = CvOUTSIDE(bcv))
+                           {
                                if (CvANON(bcv))
                                    CvCLONE_on(bcv);
                                else {
-                                   if (ckWARN(WARN_CLOSURE) && !CvUNIQUE(cv))
+                                   if (ckWARN(WARN_CLOSURE)
+                                       && !CvUNIQUE(bcv) && !CvUNIQUE(cv))
+                                   {
                                        warner(WARN_CLOSURE,
                                          "Variable \"%s\" may be unavailable",
                                             name);
+                                   }
                                    break;
                                }
                            }
@@ -258,20 +270,20 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
      * XXX This will also probably interact badly with eval tree caching.
      */
 
-    saweval = 0;
     for (i = cx_ix; i >= 0; i--) {
        cx = &cxstack[i];
-       switch (cx->cx_type) {
+       switch (CxTYPE(cx)) {
        default:
            if (i == 0 && saweval) {
                seq = cxstack[saweval].blk_oldcop->cop_seq;
-               return pad_findlex(name, newoff, seq, PL_main_cv, 0);
+               return pad_findlex(name, newoff, seq, PL_main_cv, -1, saweval);
            }
            break;
        case CXt_EVAL:
            switch (cx->blk_eval.old_op_type) {
            case OP_ENTEREVAL:
-               saweval = i;
+               if (CxREALEVAL(cx))
+                   saweval = i;
                break;
            case OP_REQUIRE:
                /* require must have its own scope */
@@ -287,7 +299,7 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
                continue;
            }
            seq = cxstack[saweval].blk_oldcop->cop_seq;
-           return pad_findlex(name, newoff, seq, cv, i-1);
+           return pad_findlex(name, newoff, seq, cv, i-1, saweval);
        }
     }
 
@@ -303,6 +315,8 @@ pad_findmy(char *name)
     SV *sv;
     SV **svp = AvARRAY(PL_comppad_name);
     U32 seq = PL_cop_seqmax;
+    PERL_CONTEXT *cx;
+    CV *outside;
 
 #ifdef USE_THREADS
     /*
@@ -332,8 +346,20 @@ pad_findmy(char *name)
        }
     }
 
+    outside = CvOUTSIDE(PL_compcv);
+
+    /* Check if if we're compiling an eval'', and adjust seq to be the
+     * eval's seq number.  This depends on eval'' having a non-null
+     * CvOUTSIDE() while it is being compiled.  The eval'' itself is
+     * identified by CvUNIQUE being set and CvGV being null. */
+    if (outside && CvUNIQUE(PL_compcv) && !CvGV(PL_compcv) && cxstack_ix >= 0) {
+       cx = &cxstack[cxstack_ix];
+       if (CxREALEVAL(cx))
+           seq = cx->blk_oldcop->cop_seq;
+    }
+
     /* See if it's in a nested scope */
-    off = pad_findlex(name, 0, seq, CvOUTSIDE(PL_compcv), cxstack_ix);
+    off = pad_findlex(name, 0, seq, outside, cxstack_ix, 0);
     if (off) {
        /* If there is a pending local definition, this new alias must die */
        if (pendoff)
@@ -357,7 +383,7 @@ pad_leavemy(I32 fill)
     }
     /* "Deintroduce" my variables that are leaving with this scope. */
     for (off = AvFILLp(PL_comppad_name); off > fill; off--) {
-       if ((sv = svp[off]) && sv != &PL_sv_undef && SvIVX(sv) == 999999999)
+       if ((sv = svp[off]) && sv != &PL_sv_undef && SvIVX(sv) == PAD_MAX)
            SvIVX(sv) = PL_cop_seqmax;
     }
 }
@@ -1579,7 +1605,7 @@ block_start(int full)
     PL_pad_reset_pending = FALSE;
     SAVEHINTS();
     PL_hints &= ~HINT_BLOCK_SCOPE;
-    SAVEPPTR(compiling.cop_warnings); 
+    SAVEPPTR(PL_compiling.cop_warnings); 
     if (PL_compiling.cop_warnings != WARN_ALL && 
        PL_compiling.cop_warnings != WARN_NONE) {
         PL_compiling.cop_warnings = newSVsv(PL_compiling.cop_warnings) ;
@@ -1598,7 +1624,7 @@ block_end(I32 floor, OP *seq)
     OP* retval = scalarseq(seq);
     LEAVE_SCOPE(floor);
     PL_pad_reset_pending = FALSE;
-    compiling.op_private = PL_hints;
+    PL_compiling.op_private = PL_hints;
     if (needblockscope)
        PL_hints |= HINT_BLOCK_SCOPE; /* propagate out */
     pad_leavemy(PL_comppad_name_fill);
@@ -1897,7 +1923,7 @@ append_list(I32 type, LISTOP *first, LISTOP *last)
     first->op_last = last->op_last;
     first->op_children += last->op_children;
     if (first->op_children)
-       last->op_flags |= OPf_KIDS;
+       first->op_flags |= OPf_KIDS;
 
     Safefree(last);
     return (OP*)first;
@@ -2579,6 +2605,7 @@ utilize(int aver, I32 floor, OP *version, OP *id, OP *arg)
     OP *rqop;
     OP *imop;
     OP *veop;
+    GV *gv;
 
     if (id->op_type != OP_CONST)
        croak("Module name must be constant");
@@ -2630,8 +2657,21 @@ utilize(int aver, I32 floor, OP *version, OP *id, OP *arg)
                        newUNOP(OP_METHOD, 0, meth)));
     }
 
-    /* Fake up a require */
-    rqop = newUNOP(OP_REQUIRE, 0, id);
+    /* Fake up a require, handle override, if any */
+    gv = gv_fetchpv("require", FALSE, SVt_PVCV);
+    if (!(gv && GvIMPORTED_CV(gv)))
+       gv = gv_fetchpv("CORE::GLOBAL::require", FALSE, SVt_PVCV);
+
+    if (gv && GvIMPORTED_CV(gv)) {
+       rqop = ck_subr(newUNOP(OP_ENTERSUB, OPf_STACKED,
+                              append_elem(OP_LIST, id,
+                                          scalar(newUNOP(OP_RV2CV, 0,
+                                                         newGVOP(OP_GV, 0,
+                                                                 gv))))));
+    }
+    else {
+       rqop = newUNOP(OP_REQUIRE, 0, id);
+    }
 
     /* Fake up the BEGIN {}, which does its thing immediately. */
     newSUB(floor,
@@ -2648,6 +2688,29 @@ utilize(int aver, I32 floor, OP *version, OP *id, OP *arg)
 }
 
 OP *
+dofile(OP *term)
+{
+    OP *doop;
+    GV *gv;
+
+    gv = gv_fetchpv("do", FALSE, SVt_PVCV);
+    if (!(gv && GvIMPORTED_CV(gv)))
+       gv = gv_fetchpv("CORE::GLOBAL::do", FALSE, SVt_PVCV);
+
+    if (gv && GvIMPORTED_CV(gv)) {
+       doop = ck_subr(newUNOP(OP_ENTERSUB, OPf_STACKED,
+                              append_elem(OP_LIST, term,
+                                          scalar(newUNOP(OP_RV2CV, 0,
+                                                         newGVOP(OP_GV, 0,
+                                                                 gv))))));
+    }
+    else {
+       doop = newUNOP(OP_DOFILE, 0, scalar(term));
+    }
+    return doop;
+}
+
+OP *
 newSLICEOP(I32 flags, OP *subscript, OP *listval)
 {
     return newBINOP(OP_LSLICE, flags,
@@ -2847,7 +2910,7 @@ newSTATEOP(I32 flags, char *label, OP *o)
 #ifdef NATIVE_HINTS
     cop->op_private |= NATIVE_HINTS;
 #endif
-    compiling.op_private = cop->op_private;
+    PL_compiling.op_private = cop->op_private;
     cop->op_next = (OP*)cop;
 
     if (label) {
@@ -2898,7 +2961,7 @@ intro_my(void)
     svp = AvARRAY(PL_comppad_name);
     for (i = PL_min_intro_pending; i <= PL_max_intro_pending; i++) {
        if ((sv = svp[i]) && sv != &PL_sv_undef && !SvIVX(sv)) {
-           SvIVX(sv) = 999999999;      /* Don't know scope end yet. */
+           SvIVX(sv) = PAD_MAX;        /* Don't know scope end yet. */
            SvNVX(sv) = (double)PL_cop_seqmax;
        }
     }
@@ -3448,7 +3511,7 @@ CV* cv;
                  cv,
                  (CvANON(cv) ? "ANON"
                   : (cv == PL_main_cv) ? "MAIN"
-                  : CvUNIQUE(outside) ? "UNIQUE"
+                  : CvUNIQUE(cv) ? "UNIQUE"
                   : CvGV(cv) ? GvNAME(CvGV(cv)) : "UNDEFINED"),
                  outside,
                  (!outside ? "null"
@@ -3548,7 +3611,7 @@ cv_clone2(CV *proto, CV *outside)
            char *name = SvPVX(namesv);    /* XXX */
            if (SvFLAGS(namesv) & SVf_FAKE) {   /* lexical from outside? */
                I32 off = pad_findlex(name, ix, SvIVX(namesv),
-                                     CvOUTSIDE(cv), cxstack_ix);
+                                     CvOUTSIDE(cv), cxstack_ix, 0);
                if (!off)
                    PL_curpad[ix] = SvREFCNT_inc(ppad[ix]);
                else if (off != ix)
@@ -3775,9 +3838,10 @@ newSUB(I32 floor, OP *o, OP *proto, OP *block)
     CvSTASH(cv) = PL_curstash;
 #ifdef USE_THREADS
     CvOWNER(cv) = 0;
-    if (!CvMUTEXP(cv))
+    if (!CvMUTEXP(cv)) {
        New(666, CvMUTEXP(cv), 1, perl_mutex);
-    MUTEX_INIT(CvMUTEXP(cv));
+       MUTEX_INIT(CvMUTEXP(cv));
+    }
 #endif /* USE_THREADS */
 
     if (ps)