summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embed.h1
-rw-r--r--global.sym1
-rw-r--r--objXSUB.h2
-rw-r--r--objpp.h2
-rw-r--r--pp_ctl.c6
-rw-r--r--proto.h1
-rw-r--r--scope.c22
-rw-r--r--scope.h62
8 files changed, 63 insertions, 34 deletions
diff --git a/embed.h b/embed.h
index c2254a97e3..a04f5c64ee 100644
--- a/embed.h
+++ b/embed.h
@@ -888,6 +888,7 @@
#define save_freeop Perl_save_freeop
#define save_freepv Perl_save_freepv
#define save_freesv Perl_save_freesv
+#define save_generic_svref Perl_save_generic_svref
#define save_gp Perl_save_gp
#define save_hash Perl_save_hash
#define save_helem Perl_save_helem
diff --git a/global.sym b/global.sym
index 8dff0fcc2d..8c08a1b9d1 100644
--- a/global.sym
+++ b/global.sym
@@ -937,6 +937,7 @@ save_destructor
save_freeop
save_freepv
save_freesv
+save_generic_svref
save_gp
save_hash
save_helem
diff --git a/objXSUB.h b/objXSUB.h
index 463301e42a..a88cff70e3 100644
--- a/objXSUB.h
+++ b/objXSUB.h
@@ -1638,6 +1638,8 @@
#define save_freeop pPerl->Perl_save_freeop
#undef save_freepv
#define save_freepv pPerl->Perl_save_freepv
+#undef save_generic_svref
+#define save_generic_svref pPerl->Perl_generic_save_svref
#undef save_gp
#define save_gp pPerl->Perl_save_gp
#undef save_hash
diff --git a/objpp.h b/objpp.h
index e19e3661e4..039ac4fc2a 100644
--- a/objpp.h
+++ b/objpp.h
@@ -1170,6 +1170,8 @@
#define save_freeop CPerlObj::Perl_save_freeop
#undef save_freepv
#define save_freepv CPerlObj::Perl_save_freepv
+#undef save_generic_svref
+#define save_generic_svref CPerlObj::Perl_save_generic_svref
#undef save_gp
#define save_gp CPerlObj::Perl_save_gp
#undef save_hash
diff --git a/pp_ctl.c b/pp_ctl.c
index 04efce653b..f5b45b33d1 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2697,10 +2697,8 @@ PP(pp_require)
ENTER;
SAVETMPS;
lex_start(sv_2mortal(newSVpv("",0)));
- if (PL_rsfp_filters){
- save_aptr(&PL_rsfp_filters);
- PL_rsfp_filters = NULL;
- }
+ SAVEGENERICSV(PL_rsfp_filters);
+ PL_rsfp_filters = Nullav;
PL_rsfp = tryrsfp;
name = savepv(name);
diff --git a/proto.h b/proto.h
index ba00b3ab66..c5d635aeba 100644
--- a/proto.h
+++ b/proto.h
@@ -515,6 +515,7 @@ void save_destructor _((void (*f)(void*), void* p));
VIRTUAL void save_freesv _((SV* sv));
VIRTUAL void save_freeop _((OP* o));
VIRTUAL void save_freepv _((char* pv));
+VIRTUAL void save_generic_svref _((SV** sptr));
VIRTUAL void save_gp _((GV* gv, I32 empty));
VIRTUAL HV* save_hash _((GV* gv));
VIRTUAL void save_helem _((HV* hv, SV *key, SV **sptr));
diff --git a/scope.c b/scope.c
index eb43648f1b..b7a40ca0b1 100644
--- a/scope.c
+++ b/scope.c
@@ -204,6 +204,18 @@ save_svref(SV **sptr)
return save_scalar_at(sptr);
}
+/* Like save_svref(), but doesn't deal with magic. Can be used to
+ * restore a global SV to its prior contents, freeing new value. */
+void
+save_generic_svref(SV **sptr)
+{
+ dTHR;
+ SSCHECK(3);
+ SSPUSHPTR(sptr);
+ SSPUSHPTR(SvREFCNT_inc(*sptr));
+ SSPUSHINT(SAVEt_GENERIC_SVREF);
+}
+
void
save_gp(GV *gv, I32 empty)
{
@@ -578,6 +590,16 @@ leave_scope(I32 base)
ptr = &GvSV(gv);
SvREFCNT_dec(gv);
goto restore_sv;
+ case SAVEt_GENERIC_SVREF: /* generic sv */
+ value = (SV*)SSPOPPTR;
+ ptr = SSPOPPTR;
+ if (ptr) {
+ sv = *(SV**)ptr;
+ *(SV**)ptr = value;
+ SvREFCNT_dec(sv);
+ }
+ SvREFCNT_dec(value);
+ break;
case SAVEt_SVREF: /* scalar reference */
value = (SV*)SSPOPPTR;
ptr = SSPOPPTR;
diff --git a/scope.h b/scope.h
index a9d4ba33e3..aa865bf9b4 100644
--- a/scope.h
+++ b/scope.h
@@ -1,32 +1,33 @@
-#define SAVEt_ITEM 0
-#define SAVEt_SV 1
-#define SAVEt_AV 2
-#define SAVEt_HV 3
-#define SAVEt_INT 4
-#define SAVEt_LONG 5
-#define SAVEt_I32 6
-#define SAVEt_IV 7
-#define SAVEt_SPTR 8
-#define SAVEt_APTR 9
-#define SAVEt_HPTR 10
-#define SAVEt_PPTR 11
-#define SAVEt_NSTAB 12
-#define SAVEt_SVREF 13
-#define SAVEt_GP 14
-#define SAVEt_FREESV 15
-#define SAVEt_FREEOP 16
-#define SAVEt_FREEPV 17
-#define SAVEt_CLEARSV 18
-#define SAVEt_DELETE 19
-#define SAVEt_DESTRUCTOR 20
-#define SAVEt_REGCONTEXT 21
-#define SAVEt_STACK_POS 22
-#define SAVEt_I16 23
-#define SAVEt_AELEM 24
-#define SAVEt_HELEM 25
-#define SAVEt_OP 26
-#define SAVEt_HINTS 27
-#define SAVEt_ALLOC 28
+#define SAVEt_ITEM 0
+#define SAVEt_SV 1
+#define SAVEt_AV 2
+#define SAVEt_HV 3
+#define SAVEt_INT 4
+#define SAVEt_LONG 5
+#define SAVEt_I32 6
+#define SAVEt_IV 7
+#define SAVEt_SPTR 8
+#define SAVEt_APTR 9
+#define SAVEt_HPTR 10
+#define SAVEt_PPTR 11
+#define SAVEt_NSTAB 12
+#define SAVEt_SVREF 13
+#define SAVEt_GP 14
+#define SAVEt_FREESV 15
+#define SAVEt_FREEOP 16
+#define SAVEt_FREEPV 17
+#define SAVEt_CLEARSV 18
+#define SAVEt_DELETE 19
+#define SAVEt_DESTRUCTOR 20
+#define SAVEt_REGCONTEXT 21
+#define SAVEt_STACK_POS 22
+#define SAVEt_I16 23
+#define SAVEt_AELEM 24
+#define SAVEt_HELEM 25
+#define SAVEt_OP 26
+#define SAVEt_HINTS 27
+#define SAVEt_ALLOC 28
+#define SAVEt_GENERIC_SVREF 29
#define SSCHECK(need) if (PL_savestack_ix + need > PL_savestack_max) savestack_grow()
#define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i))
@@ -63,7 +64,7 @@
#define LEAVE_SCOPE(old) if (PL_savestack_ix > old) leave_scope(old)
/*
- * Not using SOFT_CAST on SAVEFREESV and SAVEFREESV
+ * Not using SOFT_CAST on SAVESPTR, SAVEGENERICSV and SAVEFREESV
* because these are used for several kinds of pointer values
*/
#define SAVEI16(i) save_I16(SOFT_CAST(I16*)&(i))
@@ -77,6 +78,7 @@
#define SAVEFREEOP(o) save_freeop(SOFT_CAST(OP*)(o))
#define SAVEFREEPV(p) save_freepv(SOFT_CAST(char*)(p))
#define SAVECLEARSV(sv) save_clearsv(SOFT_CAST(SV**)&(sv))
+#define SAVEGENERICSV(s) save_generic_svref((SV**)&(s))
#define SAVEDELETE(h,k,l) \
save_delete(SOFT_CAST(HV*)(h), SOFT_CAST(char*)(k), (I32)(l))
#ifdef PERL_OBJECT