#define same_dirent Perl_same_dirent
#define save_I16 Perl_save_I16
#define save_I32 Perl_save_I32
+#define save_aelem Perl_save_aelem
#define save_aptr Perl_save_aptr
#define save_ary Perl_save_ary
#define save_clearsv Perl_save_clearsv
#define save_freesv Perl_save_freesv
#define save_gp Perl_save_gp
#define save_hash Perl_save_hash
+#define save_helem Perl_save_helem
#define save_hptr Perl_save_hptr
#define save_int Perl_save_int
#define save_item Perl_save_item
same_dirent
save_I16
save_I32
+save_aelem
save_aptr
save_ary
save_clearsv
save_freesv
save_gp
save_hash
+save_helem
save_hptr
save_int
save_item
if (!svp || *svp == &sv_undef)
DIE(no_aelem, elem);
if (op->op_private & OPpLVAL_INTRO)
- save_svref(svp);
+ save_aelem(av, elem, svp);
}
*MARK = svp ? *svp : &sv_undef;
}
if (!he || HeVAL(he) == &sv_undef)
DIE(no_helem, SvPV(keysv, na));
if (op->op_private & OPpLVAL_INTRO)
- save_svref(&HeVAL(he));
+ save_helem(hv, keysv, &HeVAL(he));
}
*MARK = he ? HeVAL(he) : &sv_undef;
}
if (HvNAME(hv) && isGV(*svp))
save_gp((GV*)*svp, !(op->op_flags & OPf_SPECIAL));
else
- save_svref(svp);
+ save_helem(hv, keysv, svp);
}
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
RETURN;
}
if (op->op_private & OPpLVAL_INTRO)
- save_svref(svp);
+ save_aelem(av, elem, svp);
else if (op->op_private & OPpDEREF)
vivify_ref(*svp, op->op_private & OPpDEREF);
}
void
save_list(register SV **sarg, I32 maxsarg)
+save_aelem(av,idx,sptr)
+AV *av;
+I32 idx;
+SV **sptr;
+{
+ SSCHECK(4);
+ SSPUSHPTR(av);
+ SSPUSHINT(idx);
+ SSPUSHPTR(*sptr);
+ SSPUSHINT(SAVEt_AELEM);
+ save_scalar_at(sptr);
+}
+
+void
+save_helem(hv,key,sptr)
+HV *hv;
+SV *key;
+SV **sptr;
+{
+ SSCHECK(4);
+ SSPUSHPTR(hv);
+ SSPUSHPTR(key);
+ SSPUSHPTR(*sptr);
+ SSPUSHINT(SAVEt_HELEM);
+ save_scalar_at(sptr);
+}
+
+void
{
dTHR;
register SV *sv;
register AV *av;
register HV *hv;
register void* ptr;
+ I32 i;
if (base < -1)
croak("panic: corrupt saved stack index");
(*SSPOPDPTR)(ptr);
break;
case SAVEt_REGCONTEXT:
- {
- I32 delta = SSPOPINT;
- savestack_ix -= delta; /* regexp must have croaked */
- }
+ i = SSPOPINT;
+ savestack_ix -= i; /* regexp must have croaked */
break;
case SAVEt_STACK_POS: /* Position on Perl stack */
- {
- I32 delta = SSPOPINT;
- stack_sp = stack_base + delta;
- }
+ i = SSPOPINT;
+ stack_sp = stack_base + i;
break;
+ case SAVEt_AELEM: /* array element */
+ value = (SV*)SSPOPPTR;
+ i = SSPOPINT;
+ av = (AV*)SSPOPPTR;
+ ptr = av_fetch(av,i,1);
+ goto restore_sv;
+ case SAVEt_HELEM: /* hash element */
+ value = (SV*)SSPOPPTR;
+ sv = (SV*)SSPOPINT;
+ hv = (HV*)SSPOPPTR;
+ ptr = hv_fetch_ent(hv, sv, 1, 0);
+ ptr = &HeVAL((HE*)ptr);
+ goto restore_sv;
case SAVEt_OP:
op = (OP*)SSPOPPTR;
break;
#define SAVEt_REGCONTEXT 21
#define SAVEt_STACK_POS 22
#define SAVEt_I16 23
+#define SAVEt_AELEM 24
+#define SAVEt_HELEM 25
#define SAVEt_OP 24
#define SSCHECK(need) if (savestack_ix + need > savestack_max) savestack_grow()
# $RCSfile: local.t,v $$Revision: 4.1 $$Date: 92/08/07 18:28:04 $
-print "1..25\n";
+print "1..36\n";
sub foo {
local($a, $b) = @_;
print +($@ =~ /Can't localize through a reference/) ? "" : "not ", "ok 23\n";
# check for scope leakage
+
$a = 'outer';
if (1) { local $a = 'inner' }
print +($a eq 'outer') ? "" : "not ", "ok 24\n";
}
};
print $m == 5 ? "" : "not ", "ok 25\n";
+
+# Array and hash elements
+
+@a = ('a', 'b', 'c');
+{
+ local($a[1]) = 'foo';
+ local($a[2]) = $a[2];
+ print +($a[1] eq 'foo') ? "" : "not ", "ok 26\n";
+ print +($a[2] eq 'c') ? "" : "not ", "ok 27\n";
+ undef @a;
+}
+print +($a[1] eq 'b') ? "" : "not ", "ok 28\n";
+print +($a[2] eq 'c') ? "" : "not ", "ok 29\n";
+print +(!defined $a[0]) ? "" : "not ", "ok 30\n";
+
+@a = ('a', 'b', 'c');
+{
+ local($a[1]) = "X";
+ shift @a;
+}
+print +($a[0].$a[1] eq "Xb") ? "" : "not ", "ok 31\n";
+
+%h = ('a' => 1, 'b' => 2, 'c' => 3);
+{
+ local($h{'a'}) = 'foo';
+ local($h{'b'}) = $h{'b'};
+ print +($h{'a'} eq 'foo') ? "" : "not ", "ok 32\n";
+ print +($h{'b'} == 2) ? "" : "not ", "ok 33\n";
+ local($h{'c'});
+ delete $h{'c'};
+}
+print +($h{'a'} == 1) ? "" : "not ", "ok 34\n";
+print +($h{'b'} == 2) ? "" : "not ", "ok 35\n";
+print +($h{'c'} == 3) ? "" : "not ", "ok 36\n";