Front page | perl.perl5.porters |
Postings from October 2005
Re: [PATCH] Re: [perl #37350] $#{@$aref} in debugger gives: Bizarre copy of ARRAY in leave
Thread Previous
From:
Robin Houston
Date:
October 13, 2005 07:02
Subject:
Re: [PATCH] Re: [perl #37350] $#{@$aref} in debugger gives: Bizarre copy of ARRAY in leave
Message ID:
20051013101629.GA3228@rpc142.cs.man.ac.uk
On Wed, Oct 12, 2005 at 03:33:45PM -0700, Yitzchak Scott-Thoennes wrote:
> The solution I'm thinking of would require another parameter to Perl_ref
> to say whether it should set OPf_REF for PADAV, PADHV, RV2AV, and RV2HV.
> All external calls would set it to true, and recursive calls would
> propagate it, except for OP_SCOPE and OP_LEAVE, which would set it false.
>
> Does that sound like the right effect? Can you think of anything that
> would break? Can you think of a way to do it without adding a parameter?
That works great, and nothing seems to break.
One implementation is below (run embed.pl after applying), though maybe for
performance reasons doref should be external and ref() should be a macro?
Robin
--- embed.fnc.orig 2005-10-03 16:46:16.000000000 +0100
+++ embed.fnc 2005-10-13 11:03:02.000000000 +0100
@@ -1083,6 +1083,7 @@
s |const char* |gv_ename |NN GV *gv
s |bool |scalar_mod_type|NN const OP *o|I32 type
s |OP * |my_kid |NULLOK OP *o|NULLOK OP *attrs|NN OP **imopsp
+s |OP * |doref |NN OP *o|I32 type|bool set_op_ref
s |OP * |dup_attrlist |NN OP *o
s |void |apply_attrs |NN HV *stash|NN SV *target|NULLOK OP *attrs|bool for_my
s |void |apply_attrs_my |NN HV *stash|NN OP *target|NULLOK OP *attrs|NN OP **imopsp
--- op.c.orig 2005-09-27 11:38:14.000000000 +0100
+++ op.c 2005-10-13 11:09:55.000000000 +0100
@@ -1411,8 +1411,8 @@
return o;
}
-OP *
-Perl_ref(pTHX_ OP *o, I32 type)
+STATIC OP *
+S_doref(pTHX_ OP *o, I32 type, bool set_op_ref)
{
dVAR;
OP *kid;
@@ -1434,12 +1434,12 @@
case OP_COND_EXPR:
for (kid = cUNOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
- ref(kid, type);
+ doref(kid, type, set_op_ref);
break;
case OP_RV2SV:
if (type == OP_DEFINED)
o->op_flags |= OPf_SPECIAL; /* don't create GV */
- ref(cUNOPo->op_first, o->op_type);
+ doref(cUNOPo->op_first, o->op_type, set_op_ref);
/* FALL THROUGH */
case OP_PADSV:
if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
@@ -1456,28 +1456,30 @@
case OP_RV2AV:
case OP_RV2HV:
- o->op_flags |= OPf_REF;
+ if (set_op_ref)
+ o->op_flags |= OPf_REF;
/* FALL THROUGH */
case OP_RV2GV:
if (type == OP_DEFINED)
o->op_flags |= OPf_SPECIAL; /* don't create GV */
- ref(cUNOPo->op_first, o->op_type);
+ doref(cUNOPo->op_first, o->op_type, set_op_ref);
break;
case OP_PADAV:
case OP_PADHV:
- o->op_flags |= OPf_REF;
+ if (set_op_ref)
+ o->op_flags |= OPf_REF;
break;
case OP_SCALAR:
case OP_NULL:
if (!(o->op_flags & OPf_KIDS))
break;
- ref(cBINOPo->op_first, type);
+ doref(cBINOPo->op_first, type, set_op_ref);
break;
case OP_AELEM:
case OP_HELEM:
- ref(cBINOPo->op_first, o->op_type);
+ doref(cBINOPo->op_first, o->op_type, set_op_ref);
if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) {
o->op_private |= (type == OP_RV2AV ? OPpDEREF_AV
: type == OP_RV2HV ? OPpDEREF_HV
@@ -1488,11 +1490,13 @@
case OP_SCOPE:
case OP_LEAVE:
+ set_op_ref = FALSE;
+ /* FALL THROUGH */
case OP_ENTER:
case OP_LIST:
if (!(o->op_flags & OPf_KIDS))
break;
- ref(cLISTOPo->op_last, type);
+ doref(cLISTOPo->op_last, type, set_op_ref);
break;
default:
break;
@@ -1501,6 +1505,12 @@
}
+OP *
+Perl_ref(pTHX_ OP *o, I32 type)
+{
+ return doref(o, type, TRUE);
+}
+
STATIC OP *
S_dup_attrlist(pTHX_ OP *o)
{
Thread Previous