if (AvREAL(av))
return;
#ifdef DEBUGGING
- if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
+ if (SvTIED_mg((SV*)av, 'P'))
warn("av_reify called on tied array");
#endif
key = AvMAX(av) + 1;
{
dTHR; /* only necessary if we have to extend stack */
MAGIC *mg;
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
ENTER;
SAVETMPS;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
EXTEND(SP,2);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj((SV*)av, mg));
PUSHs(sv_2mortal(newSViv(key+1)));
PUTBACK;
perl_call_method("EXTEND", G_SCALAR|G_DISCARD);
/*SUPPRESS 560*/
/* Give any tie a chance to cleanup first */
- if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
+ if (SvTIED_mg((SV*)av, 'P'))
av_fill(av, -1); /* mg_clear() ? */
if (AvREAL(av)) {
if (SvREADONLY(av))
croak(no_modify);
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
EXTEND(SP,2);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj((SV*)av, mg));
PUSHs(val);
PUTBACK;
ENTER;
return &PL_sv_undef;
if (SvREADONLY(av))
croak(no_modify);
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)av, mg));
PUTBACK;
ENTER;
if (perl_call_method("POP", G_SCALAR)) {
if (SvREADONLY(av))
croak(no_modify);
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
EXTEND(SP,1+num);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj((SV*)av, mg));
while (num-- > 0) {
PUSHs(&PL_sv_undef);
}
return &PL_sv_undef;
if (SvREADONLY(av))
croak(no_modify);
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)av, mg));
PUTBACK;
ENTER;
if (perl_call_method("SHIFT", G_SCALAR)) {
croak("panic: null array");
if (fill < 0)
fill = -1;
- if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
+ if (mg = SvTIED_mg((SV*)av, 'P')) {
dSP;
ENTER;
SAVETMPS;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
EXTEND(SP,2);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj((SV*)av, mg));
PUSHs(sv_2mortal(newSViv(fill+1)));
PUTBACK;
perl_call_method("STORESIZE", G_SCALAR|G_DISCARD);
RETURN;
}
- if (!SvRMAGICAL(keys) || !mg_find((SV*)keys,'P'))
+ if (! SvTIED_mg((SV*)keys, 'P'))
i = HvKEYS(keys);
else {
i = 0;
sigprocmask(how, sigset, oldsigset = 0)
int how
POSIX::SigSet sigset
- POSIX::SigSet oldsigset
+ POSIX::SigSet oldsigset = NO_INIT
+INIT:
+ if ( items < 3 ) {
+ oldsigset = 0;
+ }
+ else if (sv_derived_from(ST(2), "POSIX::SigSet")) {
+ IV tmp = SvIV((SV*)SvRV(ST(2)));
+ oldsigset = (POSIX__SigSet) tmp;
+ }
+ else {
+ oldsigset = (sigset_t*)safemalloc(sizeof(sigset_t));
+ sigemptyset(oldsigset);
+ sv_setref_pv(ST(2), "POSIX::SigSet", (void*)oldsigset);
+ }
SysRet
sigsuspend(signal_mask)
return hv;
#if 0
- if (!SvRMAGICAL(ohv) || !mg_find((SV*)ohv,'P')) {
+ if (! SvTIED_mg((SV*)ohv, 'P')) {
/* Quick way ???*/
}
else
xhv = (XPVHV*)SvANY(hv);
oldentry = entry = xhv->xhv_eiter;
- if (SvRMAGICAL(hv) && (mg = mg_find((SV*)hv,'P'))) {
+ if (mg = SvTIED_mg((SV*)hv, 'P')) {
SV *key = sv_newmortal();
if (entry) {
sv_setsv(key, HeSVKEY_force(entry));
MAGIC* mg;
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
if (isUPPER(mg->mg_type)) {
- sv_magic(nsv, mg->mg_obj, toLOWER(mg->mg_type), key, klen);
+ sv_magic(nsv,
+ mg->mg_type == 'P' ? SvTIED_obj(sv, mg) : mg->mg_obj,
+ toLOWER(mg->mg_type), key, klen);
count++;
}
}
if (hv) {
(void) hv_iterinit(hv);
- if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P'))
+ if (! SvTIED_mg((SV*)hv, 'P'))
i = HvKEYS(hv);
else {
/*SUPPRESS 560*/
/* caller is responsible for stack switching/cleanup */
STATIC int
-magic_methcall(MAGIC *mg, char *meth, I32 flags, int n, SV *val)
+magic_methcall(SV *sv, MAGIC *mg, char *meth, I32 flags, int n, SV *val)
{
dSP;
PUSHMARK(SP);
EXTEND(SP, n);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj(sv, mg));
if (n > 1) {
if (mg->mg_ptr) {
if (mg->mg_len >= 0)
SAVETMPS;
PUSHSTACKi(PERLSI_MAGIC);
- if (magic_methcall(mg, meth, G_SCALAR, 2, NULL)) {
+ if (magic_methcall(sv, mg, meth, G_SCALAR, 2, NULL)) {
sv_setsv(sv, *PL_stack_sp--);
}
dSP;
ENTER;
PUSHSTACKi(PERLSI_MAGIC);
- magic_methcall(mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
+ magic_methcall(sv, mg, "STORE", G_SCALAR|G_DISCARD, 3, sv);
POPSTACK;
LEAVE;
return 0;
ENTER;
SAVETMPS;
PUSHSTACKi(PERLSI_MAGIC);
- if (magic_methcall(mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
+ if (magic_methcall(sv, mg, "FETCHSIZE", G_SCALAR, 2, NULL)) {
sv = *PL_stack_sp--;
retval = (U32) SvIV(sv)-1;
}
ENTER;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj(sv, mg));
PUTBACK;
perl_call_method("CLEAR", G_SCALAR|G_DISCARD);
POPSTACK;
PUSHSTACKi(PERLSI_MAGIC);
PUSHMARK(SP);
EXTEND(SP, 2);
- PUSHs(mg->mg_obj);
+ PUSHs(SvTIED_obj(sv, mg));
if (SvOK(key))
PUSHs(key);
PUTBACK;
#define MgPV(mg,lp) (((lp = (mg)->mg_len) == HEf_SVKEY) ? \
SvPV((SV*)((mg)->mg_ptr),lp) : \
(mg)->mg_ptr)
+
+#define SvTIED_mg(sv,how) \
+ (SvRMAGICAL(sv) ? mg_find((sv),(how)) : Null(MAGIC*))
+#define SvTIED_obj(sv,mg) \
+ ((mg)->mg_obj ? (mg)->mg_obj : sv_2mortal(newRV(sv)))
SV **tmparyval = 0;
MAGIC *mg;
- if (SvRMAGICAL(ary) && (mg = mg_find((SV*)ary,'P'))) {
- *MARK-- = mg->mg_obj;
+ if (mg = SvTIED_mg((SV*)ary, 'P')) {
+ *MARK-- = SvTIED_obj((SV*)ary, mg);
PUSHMARK(MARK);
PUTBACK;
ENTER;
register SV *sv = &PL_sv_undef;
MAGIC *mg;
- if (SvRMAGICAL(ary) && (mg = mg_find((SV*)ary,'P'))) {
- *MARK-- = mg->mg_obj;
+ if (mg = SvTIED_mg((SV*)ary, 'P')) {
+ *MARK-- = SvTIED_obj((SV*)ary, mg);
PUSHMARK(MARK);
PUTBACK;
ENTER;
register I32 i = 0;
MAGIC *mg;
- if (SvRMAGICAL(ary) && (mg = mg_find((SV*)ary,'P'))) {
- *MARK-- = mg->mg_obj;
+ if (mg = SvTIED_mg((SV*)ary, 'P')) {
+ *MARK-- = SvTIED_obj((SV*)ary, mg);
PUSHMARK(MARK);
PUTBACK;
ENTER;
av_extend(ary,0);
av_clear(ary);
SPAGAIN;
- if (SvRMAGICAL(ary) && (mg = mg_find((SV *) ary, 'P'))) {
+ if (mg = SvTIED_mg((SV*)ary, 'P')) {
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)ary, mg));
}
else {
if (!AvREAL(ary)) {
gv = (GV*)*++MARK;
else
gv = PL_defoutgv;
- if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+ if (mg = SvTIED_mg((SV*)gv, 'q')) {
if (MARK == ORIGMARK) {
/* If using default handle then we need to make space to
* pass object as 1st arg, so move other args up ...
++SP;
}
PUSHMARK(MARK - 1);
- *MARK = mg->mg_obj;
+ *MARK = SvTIED_obj((SV*)gv, mg);
PUTBACK;
ENTER;
perl_call_method("PRINT", G_SCALAR);
I32 gimme = GIMME_V;
MAGIC *mg;
- if (SvRMAGICAL(PL_last_in_gv) && (mg = mg_find((SV*)PL_last_in_gv, 'q'))) {
+ if (mg = SvTIED_mg((SV*)PL_last_in_gv, 'q')) {
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)PL_last_in_gv, mg));
PUTBACK;
ENTER;
perl_call_method("READLINE", gimme);
else
gv = (GV*)POPs;
- if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+ if (mg = SvTIED_mg((SV*)gv, 'q')) {
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)gv, mg));
PUTBACK;
ENTER;
perl_call_method("CLOSE", G_SCALAR);
sv = TOPs;
POPSTACK;
if (sv_isobject(sv)) {
- sv_unmagic(varsv, how);
- sv_magic(varsv, sv, how, Nullch, 0);
+ sv_unmagic(varsv, how);
+ sv_magic(varsv, (SvRV(sv) == varsv ? Nullsv : sv), how, Nullch, 0);
}
LEAVE;
SP = PL_stack_base + markoff;
PP(pp_untie)
{
djSP;
- SV * sv ;
-
- sv = POPs;
+ SV *sv = POPs;
+ char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) ? 'P' : 'q';
if (ckWARN(WARN_UNTIE)) {
MAGIC * mg ;
- if (SvMAGICAL(sv)) {
- if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
- mg = mg_find(sv, 'P') ;
- else
- mg = mg_find(sv, 'q') ;
-
+ if (mg = SvTIED_mg(sv, how)) {
if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1)
warner(WARN_UNTIE,
"untie attempted while %lu inner references still exist",
}
}
- if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
- sv_unmagic(sv, 'P');
- else
- sv_unmagic(sv, 'q');
+ sv_unmagic(sv, how);
RETPUSHYES;
}
PP(pp_tied)
{
djSP;
- SV * sv ;
- MAGIC * mg ;
+ SV *sv = POPs;
+ char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) ? 'P' : 'q';
+ MAGIC *mg;
- sv = POPs;
- if (SvMAGICAL(sv)) {
- if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
- mg = mg_find(sv, 'P') ;
- else
- mg = mg_find(sv, 'q') ;
-
- if (mg) {
- PUSHs(sv_2mortal(newSVsv(mg->mg_obj))) ;
- RETURN ;
- }
+ if (mg = SvTIED_mg(sv, how)) {
+ SV *osv = SvTIED_obj(sv, mg);
+ if (osv == mg->mg_obj)
+ osv = sv_mortalcopy(osv);
+ PUSHs(osv);
+ RETURN;
}
RETPUSHUNDEF;
}
if (!gv)
gv = PL_argvgv;
- if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+ if (mg = SvTIED_mg((SV*)gv, 'q')) {
I32 gimme = GIMME_V;
PUSHMARK(SP);
- XPUSHs(mg->mg_obj);
+ XPUSHs(SvTIED_obj((SV*)gv, mg));
PUTBACK;
ENTER;
perl_call_method("GETC", gimme);
else
gv = PL_defoutgv;
- if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+ if (mg = SvTIED_mg((SV*)gv, 'q')) {
if (MARK == ORIGMARK) {
MEXTEND(SP, 1);
++MARK;
++SP;
}
PUSHMARK(MARK - 1);
- *MARK = mg->mg_obj;
+ *MARK = SvTIED_obj((SV*)gv, mg);
PUTBACK;
ENTER;
perl_call_method("PRINTF", G_SCALAR);
gv = (GV*)*++MARK;
if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD) &&
- SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q')))
+ (mg = SvTIED_mg((SV*)gv, 'q')))
{
SV *sv;
PUSHMARK(MARK-1);
- *MARK = mg->mg_obj;
+ *MARK = SvTIED_obj((SV*)gv, mg);
ENTER;
perl_call_method("READ", G_SCALAR);
LEAVE;
MAGIC *mg;
gv = (GV*)*++MARK;
- if (PL_op->op_type == OP_SYSWRITE &&
- SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q')))
- {
+ if (PL_op->op_type == OP_SYSWRITE && (mg = SvTIED_mg((SV*)gv, 'q'))) {
SV *sv;
PUSHMARK(MARK-1);
- *MARK = mg->mg_obj;
+ *MARK = SvTIED_obj((SV*)gv, mg);
ENTER;
perl_call_method("WRITE", G_SCALAR);
LEAVE;
if (ptr) {
sv = *(SV**)ptr;
if (sv && sv != &PL_sv_undef) {
- if (SvRMAGICAL(av) && mg_find((SV*)av, 'P'))
+ if (SvTIED_mg((SV*)av, 'P'))
(void)SvREFCNT_inc(sv);
SvREFCNT_dec(av);
goto restore_sv;
SV *oval = HeVAL((HE*)ptr);
if (oval && oval != &PL_sv_undef) {
ptr = &HeVAL((HE*)ptr);
- if (SvRMAGICAL(hv) && mg_find((SV*)hv, 'P'))
+ if (SvTIED_mg((SV*)hv, 'P'))
(void)SvREFCNT_inc(*(SV**)ptr);
SvREFCNT_dec(hv);
SvREFCNT_dec(sv);
}
untie %H;
EXPECT
+########
+
+# verify no leak when underlying object is selfsame tied variable
+my ($a, $b);
+sub Self::TIEHASH { bless $_[1], $_[0] }
+sub Self::DESTROY { $b = $_[0] + 0; }
+{
+ my %b5;
+ $a = \%b5 + 0;
+ tie %b5, 'Self', \%b5;
+}
+die unless $a == $b;
+EXPECT