develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About