develooper Front page | perl.perl5.porters | Postings from October 2005

[PATCH] Re: [perl #37350] $#{@$aref} in debugger gives: Bizarre copy of ARRAY in leave

Thread Previous | Thread Next
From:
Robin Houston
Date:
October 12, 2005 00:39
Subject:
[PATCH] Re: [perl #37350] $#{@$aref} in debugger gives: Bizarre copy of ARRAY in leave
Message ID:
20051011221549.GA8356@rpc142.cs.man.ac.uk
David Landgren wrote:
> That's because perl is trying to do the right thing with bad syntax.

Well yes, but that's still a bug because perl ought to reject bad
syntax! The reason it isn't rejected is that pp_rv2av will happily
accept an AV on the stack, in lieu of an actual reference. That
can't be changed in general, since it's relied on.

One way to fix it is shown in the patch below. I added a new
private flag to OP_RV2AV, which indicates that it shouldn't
accept a real AV.

(HEALTH WARNING: I'm not sure that I picked a safe value for
the flag. Other values that I thought would be okay turned out
to cause problems, for some reason that I don't properly understand,
presumably connected to the hint bits. Maybe this just causes a
more subtle problem that evades the test suite. Can someone confirm
or deny that this is okay?)

The other issue with this approach is that it presumably slows
rv2av down very very slightly.

Robin


--- op.c.orig	2005-10-11 22:03:08.000000000 +0100
+++ op.c	2005-10-11 22:56:42.000000000 +0100
@@ -1455,6 +1455,8 @@
 	break;
 
     case OP_RV2AV:
+	if (type == OP_AV2ARYLEN)
+	    o->op_private |= OPpRV2AV_REFONLY;
     case OP_RV2HV:
 	o->op_flags |= OPf_REF;
 	/* FALL THROUGH */
--- op.h.orig	2005-10-11 22:03:20.000000000 +0100
+++ op.h	2005-10-11 22:51:59.000000000 +0100
@@ -177,6 +177,9 @@
 #define OPpMAYBE_LVSUB		8	/* We might be an lvalue to return */
   /* for OP_RV2?V, lower bits carry hints (currently only HINT_STRICT_REFS) */
 
+/* Private for OP_RV2AV */
+#define OPpRV2AV_REFONLY	64	/* Only accept an RV or GV, not an AV. */
+
 /* Private for OPs with TARGLEX */
   /* (lower bits may carry MAXARG) */
 #define OPpTARGET_MY		16	/* Target is PADMY. */
--- pp_hot.c.orig	2005-10-11 22:01:22.000000000 +0100
+++ pp_hot.c	2005-10-11 22:56:03.000000000 +0100
@@ -696,7 +696,11 @@
     else {
 	if (SvTYPE(sv) == SVt_PVAV) {
 	    av = (AV*)sv;
-	    if (PL_op->op_flags & OPf_REF) {
+
+	    if (PL_op->op_private & OPpRV2AV_REFONLY)
+		DIE(aTHX_ "Not an ARRAY reference");
+
+	    else if (PL_op->op_flags & OPf_REF) {
 		SETs((SV*)av);
 		RETURN;
 	    }

Thread Previous | Thread Next


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