summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorPerl 5 Porters <perl5-porters@africa.nicoh.com>1997-01-01 08:59:00 +1200
committerChip Salzenberg <chip@atlantic.net>1997-01-01 08:59:00 +1200
commita60067777be62ee91d1318f9ae26d9ed713245de (patch)
tree9e312a824c6ef40aa10dd0e60451fd737098a965 /op.c
parenta034a98d8bfd0fd904012bd5227ce209aaaa0b26 (diff)
downloadperl-a60067777be62ee91d1318f9ae26d9ed713245de.tar.gz
[inseparable changes from patch from perl5.003_17 to perl5.003_18]
CORE LANGUAGE CHANGES Subject: Inherited overloading Date: Sun, 29 Dec 1996 08:12:54 -0500 (EST) From: Ilya Zakharevich <ilya@math.ohio-state.edu> Files: gv.c lib/overload.pm perl.h sv.c sv.h t/op/overload.t Chip Salzenberg writes: > > Patch now, tarchive later: Below is the fixed overloading patch. Note that in between AMG_names got const on it (a good thing!), but as a corollary I needed to cast away const-ness to actually use it (since, say, newSVpv does not have const args). Enjoy, p5p-msgid: <199612291312.IAA02134@monk.mps.ohio-state.edu> Subject: Closures at file scope must be anonymous From: Chip Salzenberg <chip@atlantic.net> Files: op.c Subject: Warn on '{if,while} ($x = X)' where X is glob, readdir, or <FH> From: Chip Salzenberg <chip@atlantic.net> Files: op.c pod/perldiag.pod DOCUMENTATION Subject: Re: perldiag.pod entry for "Scalar value @%s{%s} ..." Date: Tue, 31 Dec 1996 11:50:19 -0500 From: Roderick Schertler <roderick@gate.net> Files: pod/perldiag.pod Msg-ID: <2043.852051019@eeyore.ibcinc.com> (applied based on p5p patch as commit c885792efecf3f527b3b5099727cc16b03eee1dc) OTHER CORE CHANGES Subject: Get rid of 'Leaked scalars' From: Chip Salzenberg <chip@atlantic.net> Files: cop.h gv.c op.c TESTS Subject: Expanded locale.t and misc.t From: Jarkko Hietaniemi <jhi@cc.hut.fi> Files: t/lib/locale.t t/lib/misc.t Subject: Expanded my.t From: Chip Salzenberg <chip@atlantic.net> Files: t/lib/my.t
Diffstat (limited to 'op.c')
-rw-r--r--op.c92
1 files changed, 60 insertions, 32 deletions
diff --git a/op.c b/op.c
index eecde67660..ac7b1a619c 100644
--- a/op.c
+++ b/op.c
@@ -210,16 +210,14 @@ pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)
SvNVX(sv) = (double)curcop->cop_seq;
SvIVX(sv) = 999999999; /* A ref, intro immediately */
SvFLAGS(sv) |= SVf_FAKE;
- if (!CvUNIQUE(cv)) {
- /* "It's closures all the way down." */
- CvCLONE_on(compcv);
- if (cv != startcv) {
- CV *bcv;
- for (bcv = startcv;
- bcv && bcv != cv && !CvCLONE(bcv);
- bcv = CvOUTSIDE(bcv))
- CvCLONE_on(bcv);
- }
+ /* "It's closures all the way down." */
+ CvCLONE_on(compcv);
+ if (cv != startcv) {
+ CV *bcv;
+ for (bcv = startcv;
+ bcv && bcv != cv && !CvCLONE(bcv);
+ bcv = CvOUTSIDE(bcv))
+ CvCLONE_on(bcv);
}
}
av_store(comppad, newoff, SvREFCNT_inc(oldsv));
@@ -454,8 +452,13 @@ OP *op;
case OP_ENTEREVAL:
op->op_targ = 0; /* Was holding hints. */
break;
+ default:
+ if (!(op->op_flags & OPf_REF) || (check[op->op_type] != ck_ftst))
+ break;
+ /* FALL THROUGH */
case OP_GVSV:
case OP_GV:
+ case OP_AELEMFAST:
SvREFCNT_dec(cGVOP->op_gv);
break;
case OP_NEXTSTATE:
@@ -484,8 +487,6 @@ OP *op;
pregfree(cPMOP->op_pmregexp);
SvREFCNT_dec(cPMOP->op_pmshort);
break;
- default:
- break;
}
if (op->op_targ > 0)
@@ -2444,6 +2445,27 @@ OP* other;
else
scalar(other);
}
+ else if (dowarn && (first->op_flags & OPf_KIDS)) {
+ OP *k1 = ((UNOP*)first)->op_first;
+ OP *k2 = k1->op_sibling;
+ OPCODE warnop = 0;
+ switch (first->op_type)
+ {
+ case OP_NULL:
+ if (k2 && k2->op_type == OP_READLINE
+ && (k2->op_flags & OPf_STACKED)
+ && (k1->op_type == OP_RV2SV || k1->op_type == OP_PADSV))
+ warnop = k2->op_type;
+ break;
+
+ case OP_SASSIGN:
+ if (k1->op_type == OP_READDIR || k1->op_type == OP_GLOB)
+ warnop = k1->op_type;
+ break;
+ }
+ if (warnop)
+ warn("Value of %s may be \"0\"; use \"defined\"", op_desc[warnop]);
+ }
if (!other)
return first;
@@ -2982,8 +3004,11 @@ OP *block;
if (op)
sub_generation++;
if (cv = GvCV(gv)) {
- if (GvCVGEN(gv))
- cv = 0; /* just a cached method */
+ if (GvCVGEN(gv)) {
+ /* just a cached method */
+ SvREFCNT_dec(cv);
+ cv = 0;
+ }
else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) {
SV* const_sv = cv_const_sv(cv);
@@ -3009,6 +3034,7 @@ OP *block;
}
if (cv) { /* must reuse cv if autoloaded */
cv_undef(cv);
+ CvFLAGS(cv) = (CvFLAGS(cv)&~CVf_CLONE) | (CvFLAGS(compcv)&CVf_CLONE);
CvOUTSIDE(cv) = CvOUTSIDE(compcv);
CvOUTSIDE(compcv) = 0;
CvPADLIST(cv) = CvPADLIST(compcv);
@@ -3044,6 +3070,10 @@ OP *block;
return cv;
}
+ /* XXX: Named functions at file scope cannot be closures */
+ if (op && CvUNIQUE(CvOUTSIDE(cv)))
+ CvCLONE_off(cv);
+
av = newAV(); /* Will be @_ */
av_extend(av, 0);
av_store(comppad, 0, (SV*)av);
@@ -3061,40 +3091,37 @@ OP *block;
CvSTART(cv) = LINKLIST(CvROOT(cv));
CvROOT(cv)->op_next = 0;
peep(CvSTART(cv));
+
if (s = strrchr(name,':'))
s++;
else
s = name;
if (strEQ(s, "BEGIN") && !error_count) {
- line_t oldline = compiling.cop_line;
- SV *oldrs = rs;
-
ENTER;
SAVESPTR(compiling.cop_filegv);
+ SAVEI16(compiling.cop_line);
SAVEI32(perldb);
+ save_svref(&rs);
+ sv_setsv(rs, nrs);
+
if (!beginav)
beginav = newAV();
- av_push(beginav, (SV *)cv);
DEBUG_x( dump_sub(gv) );
- rs = SvREFCNT_inc(nrs);
- SvREFCNT_inc(cv);
+ av_push(beginav, (SV *)cv);
+ GvCV(gv) = 0;
calllist(beginav);
- if (GvCV(gv) == cv) { /* Detach it. */
- SvREFCNT_dec(cv);
- GvCV(gv) = 0; /* Was above calllist, why? IZ */
- }
- SvREFCNT_dec(rs);
- rs = oldrs;
+
curcop = &compiling;
- curcop->cop_line = oldline; /* might have recursed to yylex */
LEAVE;
}
else if (strEQ(s, "END") && !error_count) {
if (!endav)
endav = newAV();
av_unshift(endav, 1);
- av_store(endav, 0, SvREFCNT_inc(cv));
+ av_store(endav, 0, (SV *)cv);
+ GvCV(gv) = 0;
}
+
if (perldb && curstash != debstash) {
SV *sv;
SV *tmpstr = sv_newmortal();
@@ -3122,13 +3149,14 @@ OP *block;
perl_call_sv((SV*)cv, G_DISCARD);
}
}
- op_free(op);
- copline = NOLINE;
- LEAVE_SCOPE(floor);
+
if (!op) {
GvCV(gv) = 0; /* Will remember in SVOP instead. */
CvANON_on(cv);
}
+ op_free(op);
+ copline = NOLINE;
+ LEAVE_SCOPE(floor);
return cv;
}
@@ -4397,7 +4425,7 @@ register OP* o;
o->op_type = OP_AELEMFAST;
o->op_ppaddr = ppaddr[OP_AELEMFAST];
o->op_private = (U8)i;
- GvAVn((GV*)(((SVOP*)o)->op_sv));
+ GvAVn(((GVOP*)o)->op_gv);
}
}
o->op_seq = op_seqmax++;