{
PERL_ARGS_ASSERT_COP_FREE;
+ /* If called during global destruction PL_defstash might be NULL and there
+ shouldn't be any code running that will trip over the bad cop address.
+ This also avoids uselessly creating the AV after it's been destroyed.
+ */
+ if (cop->op_type == OP_DBSTATE && PL_phase != PERL_PHASE_DESTRUCT) {
+ /* Remove the now invalid op from the line number information.
+ This could cause a freed memory overwrite if the debugger tried to
+ set a breakpoint on this line.
+ */
+ AV *av = CopFILEAVn(cop);
+ if (av) {
+ SV * const * const svp = av_fetch(av, CopLINE(cop), FALSE);
+ if (svp && *svp != &PL_sv_undef && SvIVX(*svp) == PTR2IV(cop) ) {
+ (void)SvIOK_off(*svp);
+ SvIV_set(*svp, 0);
+ }
+ }
+ }
CopFILE_free(cop);
if (! specialWARN(cop->cop_warnings))
PerlMemShared_free(cop->cop_warnings);
C<defer> semantics. The C<block> optree is consumed by this function and
becomes part of the returned optree.
-The C<flags> argument is currently ignored.
+The C<flags> argument carries additional flags to set on the returned op,
+including the C<op_private> field.
=cut
*/
OP *o, *start, *blockfirst;
PERL_ARGS_ASSERT_NEWDEFEROP;
- PERL_UNUSED_ARG(flags);
start = LINKLIST(block);
block->op_next = block;
o = (OP *)alloc_LOGOP(OP_PUSHDEFER, block, start);
- o->op_flags |= OPf_WANT_VOID;
+ o->op_flags |= OPf_WANT_VOID | (U8)(flags);
+ o->op_private = (U8)(flags >> 8);
/* Terminate the block */
blockfirst = cUNOPx(block)->op_first;
return o;
}
+/*
+=for apidoc op_wrap_finally
+
+Wraps the given C<block> optree fragment in its own scoped block, arranging
+for the C<finally> optree fragment to be invoked when leaving that block for
+any reason. Both optree fragments are consumed and the combined result is
+returned.
+
+=cut
+*/
+
+OP *
+Perl_op_wrap_finally(pTHX_ OP *block, OP *finally)
+{
+ PERL_ARGS_ASSERT_OP_WRAP_FINALLY;
+
+ /* TODO: If block is already an ENTER/LEAVE-wrapped line sequence we can
+ * just splice the DEFEROP in at the top, for efficiency.
+ */
+
+ OP *o = newLISTOP(OP_LINESEQ, 0, newDEFEROP((OPpDEFER_FINALLY << 8), finally), block);
+ o = op_prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), o);
+ OpTYPE_set(o, OP_LEAVE);
+
+ return o;
+}
+
/* must not conflict with SVf_UTF8 */
#define CV_CKPROTO_CURSTASH 0x1
const line_t oldline = CopLINE(PL_curcop);
SV *namesv = o
? cSVOPo->op_sv
- : sv_2mortal(newSVpvn_utf8(
- PadnamePV(name)+1,PadnameLEN(name)-1, PadnameUTF8(name)
- ));
+ : newSVpvn_flags( PadnamePV(name)+1,PadnameLEN(name)-1,
+ (PadnameUTF8(name)) ? SVf_UTF8|SVs_TEMP : SVs_TEMP
+ );
if (PL_parser && PL_parser->copline != NOLINE)
/* This ensures that warnings are reported at the first
line of a redefinition, not the last. */
simplify_sort(o);
firstkid = OpSIBLING(cLISTOPo->op_first); /* get past pushmark */
+ if (!firstkid)
+ return too_few_arguments_pv(o,OP_DESC(o), 0);
+
if ((stacked = o->op_flags & OPf_STACKED)) { /* may have been cleared */
OP *kid = cUNOPx(firstkid)->op_first; /* get past null */
DEFER(cLOGOPo->op_other);
break;
+ case OP_ENTERTRYCATCH:
+ assert(cLOGOPo->op_other->op_type == OP_CATCH);
+ /* catch body is the ->op_other of the OP_CATCH */
+ DEFER(cLOGOPx(cLOGOPo->op_other)->op_other);
+ break;
+
case OP_SUBST:
if ((o->op_flags & OPf_WANT) == OPf_WANT_SCALAR)
S_check_for_bool_cxt(o, 1, OPpTRUEBOOL, 0);
}
case OP_REF:
- /* see if ref() is used in boolean context */
+ case OP_BLESSED:
+ /* if the op is used in boolean context, set the TRUEBOOL flag
+ * which enables an optimisation at runtime which avoids creating
+ * a stack temporary for known-true package names */
if ((o->op_flags & OPf_WANT) == OPf_WANT_SCALAR)
S_check_for_bool_cxt(o, 1, OPpTRUEBOOL, OPpMAYBE_TRUEBOOL);
break;