summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorAbhijit Menon-Sen <ams@wiw.org>2001-08-11 11:48:19 +0530
committerJarkko Hietaniemi <jhi@iki.fi>2001-08-12 13:56:18 +0000
commitff76feabe05d384b669cf347124af347cb9ad879 (patch)
tree226d867acb5d1d5ec504b3e64146f5d20163e2f4 /mg.c
parent4ba0502e5961da529150fbb2a715432f1866ff19 (diff)
downloadperl-ff76feabe05d384b669cf347124af347cb9ad879.tar.gz
Re: [ID 20010730.010] FETCH called twice with -T
Message-ID: <20010811061819.P526@lustre.dyn.wiw.org> p4raw-id: //depot/perl@11641
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/mg.c b/mg.c
index 2e528ba538..ea9650c9b5 100644
--- a/mg.c
+++ b/mg.c
@@ -93,34 +93,48 @@ Do magic after a value is retrieved from the SV. See C<sv_magic>.
int
Perl_mg_get(pTHX_ SV *sv)
{
- I32 mgs_ix;
- MAGIC* mg;
- MAGIC** mgp;
- int mgp_valid = 0;
+ int new = 0;
+ MAGIC *newmg, *head, *cur, *mg;
+ I32 mgs_ix = SSNEW(sizeof(MGS));
- mgs_ix = SSNEW(sizeof(MGS));
save_magic(mgs_ix, sv);
- mgp = &SvMAGIC(sv);
- while ((mg = *mgp) != 0) {
- MGVTBL* vtbl = mg->mg_virtual;
+ /* We must call svt_get(sv, mg) for each valid entry in the linked
+ list of magic. svt_get() may delete the current entry, add new
+ magic to the head of the list, or upgrade the SV. AMS 20010810 */
+
+ newmg = cur = head = mg = SvMAGIC(sv);
+ while (mg) {
+ MGVTBL *vtbl = mg->mg_virtual;
+
if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
CALL_FPTR(vtbl->svt_get)(aTHX_ sv, mg);
- /* Ignore this magic if it's been deleted */
- if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) &&
- (mg->mg_flags & MGf_GSKIP))
- (SSPTR(mgs_ix, MGS*))->mgs_flags = 0;
+ /* Don't restore the flags for this entry if it was deleted. */
+ if (mg->mg_flags & MGf_GSKIP)
+ (SSPTR(mgs_ix, MGS *))->mgs_flags = 0;
}
- /* Advance to next magic (complicated by possible deletion) */
- if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) {
- mgp = &mg->mg_moremagic;
- mgp_valid = 1;
+
+ mg = mg->mg_moremagic;
+
+ if (new) {
+ /* Have we finished with the new entries we saw? Start again
+ where we left off (unless there are more new entries). */
+ if (mg == head) {
+ new = 0;
+ mg = cur;
+ head = newmg;
+ }
+ }
+
+ /* Were any new entries added? */
+ if (!new && (newmg = SvMAGIC(sv)) != head) {
+ new = 1;
+ cur = mg;
+ mg = newmg;
}
- else
- mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */
}
- restore_magic(aTHXo_ INT2PTR(void*, (IV)mgs_ix));
+ restore_magic(aTHXo_ INT2PTR(void *, (IV)mgs_ix));
return 0;
}