{
dTHR;
register GP *gp;
+ bool doproto = SvTYPE(gv) > SVt_NULL;
+ char *proto = (doproto && SvPOK(gv)) ? SvPVX(gv) : NULL;
sv_upgrade((SV*)gv, SVt_PVGV);
- if (SvLEN(gv))
- Safefree(SvPVX(gv));
+ if (SvLEN(gv)) {
+ if (proto) {
+ SvPVX(gv) = NULL;
+ SvLEN(gv) = 0;
+ SvPOK_off(gv);
+ } else
+ Safefree(SvPVX(gv));
+ }
Newz(602, gp, 1, GP);
GvGP(gv) = gp_ref(gp);
GvSV(gv) = NEWSV(72,0);
GvNAMELEN(gv) = len;
if (multi)
GvMULTI_on(gv);
+ if (doproto) { /* Replicate part of newSUB here. */
+ ENTER;
+ start_subparse(0,0); /* Create CV in compcv. */
+ GvCV(gv) = compcv;
+ LEAVE;
+
+ GvCVGEN(gv) = 0;
+ sub_generation++;
+ CvGV(GvCV(gv)) = (GV*)SvREFCNT_inc(gv);
+ CvFILEGV(GvCV(gv)) = curcop->cop_filegv;
+ CvSTASH(GvCV(gv)) = curstash;
+#ifdef USE_THREADS
+ CvOWNER(GvCV(gv)) = 0;
+ New(666, CvMUTEXP(GvCV(gv)), 1, perl_mutex);
+ MUTEX_INIT(CvMUTEXP(GvCV(gv)));
+#endif /* USE_THREADS */
+ if (proto) {
+ sv_setpv((SV*)GvCV(gv), proto);
+ Safefree(proto);
+ }
+ }
}
static void
register char *namend;
HV *stash = 0;
U32 add_gvflags = 0;
- char *tmpbuf;
if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
name++;
len = namend - name;
if (len > 0) {
- New(601, tmpbuf, len+3, char);
+ char *tmpbuf;
+ char autobuf[64];
+
+ if (len < sizeof(autobuf) - 2)
+ tmpbuf = autobuf;
+ else
+ New(601, tmpbuf, len+3, char);
Copy(name, tmpbuf, len, char);
tmpbuf[len++] = ':';
tmpbuf[len++] = ':';
else
GvMULTI_on(gv);
}
- Safefree(tmpbuf);
+ if (tmpbuf != autobuf)
+ Safefree(tmpbuf);
if (!gv || gv == (GV*)&sv_undef)
return Nullgv;
- else
- gv_init(gv, stash, nambeg, namend - nambeg, (add & 2));
if (!(stash = GvHV(gv)))
stash = GvHV(gv) = newHV();
/* By this point we should have a stash and a name */
if (!stash) {
- if (add) {
- warn("Global symbol \"%s\" requires explicit package name", name);
- ++error_count;
- stash = curstash ? curstash : defstash; /* avoid core dumps */
- add_gvflags = ((sv_type == SVt_PV) ? GVf_IMPORTED_SV
- : (sv_type == SVt_PVAV) ? GVf_IMPORTED_AV
- : (sv_type == SVt_PVHV) ? GVf_IMPORTED_HV
- : 0);
- }
- else
+ if (!add)
return Nullgv;
+ if (add & ~2) {
+ char sv_type_char = ((sv_type == SVt_PV) ? '$'
+ : (sv_type == SVt_PVAV) ? '@'
+ : (sv_type == SVt_PVHV) ? '%'
+ : 0);
+ if (sv_type_char)
+ warn("Global symbol \"%c%s\" requires explicit package name",
+ sv_type_char, name);
+ else
+ warn("Global symbol \"%s\" requires explicit package name",
+ name);
+ }
+ ++error_count;
+ stash = curstash ? curstash : defstash; /* avoid core dumps */
+ add_gvflags = ((sv_type == SVt_PV) ? GVf_IMPORTED_SV
+ : (sv_type == SVt_PVAV) ? GVf_IMPORTED_AV
+ : (sv_type == SVt_PVHV) ? GVf_IMPORTED_HV
+ : 0);
}
if (!SvREFCNT(stash)) /* symbol table under destruction */
gv_init_sv(gv, sv_type);
}
return gv;
+ } else if (add & GV_NOINIT) {
+ return gv;
}
/* Adding a new symbol */
- if (add & 4)
+ if (add & GV_ADDWARN)
warn("Had to create %s unexpectedly", nambeg);
- gv_init(gv, stash, name, len, add & 2);
+ gv_init(gv, stash, name, len, add & GV_ADDMULTI);
gv_init_sv(gv, sv_type);
GvFLAGS(gv) |= add_gvflags;
GvMULTI_on(gv);
sv_magic((SV*)av, (SV*)gv, 'I', Nullch, 0);
/* NOTE: No support for tied ISA */
- if (add & 2 && strEQ(nambeg,"AnyDBM_File::ISA") && AvFILLp(av) == -1)
+ if ((add & GV_ADDMULTI) && strEQ(nambeg,"AnyDBM_File::ISA")
+ && AvFILLp(av) == -1)
{
char *pname;
av_push(av, newSVpv(pname = "NDBM_File",0));
psig_ptr[i] = 0;
psig_name[i] = 0;
}
- /* initialize signal stack */
- signalstack = newAV();
- AvREAL_off(signalstack);
- av_extend(signalstack, 30);
- av_fill(signalstack, 0);
}
break;
#endif
goto magicalize;
+ case '!':
+ if(len > 1)
+ break;
+ if(sv_type > SVt_PV) {
+ HV* stash = gv_stashpvn("Errno",5,FALSE);
+ if(!stash || !(gv_fetchmethod(stash, "TIEHASH"))) {
+ dSP;
+ PUTBACK;
+ perl_require_pv("Errno.pm");
+ SPAGAIN;
+ stash = gv_stashpvn("Errno",5,FALSE);
+ if (!stash || !(gv_fetchmethod(stash, "TIEHASH")))
+ croak("Can't use %%! because Errno.pm is not avaliable");
+ }
+ }
+ goto magicalize;
case '#':
case '*':
if (dowarn && len == 1 && sv_type == SVt_PV)
warn("Use of $%s is deprecated", name);
/* FALL THROUGH */
case '[':
- case '!':
case '^':
case '~':
case '=':
}
else if (isALPHA(*HeKEY(entry))) {
gv = (GV*)HeVAL(entry);
- if (GvMULTI(gv))
+ if (SvTYPE(gv) != SVt_PVGV || GvMULTI(gv))
continue;
curcop->cop_line = GvLINE(gv);
filegv = GvFILEGV(gv);
return FALSE;
}
-/* During call to this subroutine stack can be reallocated. It is
- * advised to call SPAGAIN macro in your code after call */
-
SV*
amagic_call(SV *left, SV *right, int method, int flags)
{
myop.op_next = Nullop;
myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
+ PUSHSTACK(SI_OVERLOAD);
ENTER;
SAVEOP();
op = (OP *) &myop;
PUTBACK;
pp_pushmark(ARGS);
- EXTEND(sp, notfound + 5);
+ EXTEND(SP, notfound + 5);
PUSHs(lr>0? right: left);
PUSHs(lr>0? left: right);
PUSHs( lr > 0 ? &sv_yes : ( assign ? &sv_undef : &sv_no ));
SPAGAIN;
res=POPs;
- PUTBACK;
+ POPSTACK();
CATCH_SET(oldcatch);
if (postpr) {