#define e_tmpname (curinterp->Ie_tmpname)
#define endav (curinterp->Iendav)
#define envgv (curinterp->Ienvgv)
-#define errhv (curinterp->Ierrhv)
-#define errsv (curinterp->Ierrsv)
+#define errgv (curinterp->Ierrgv)
#define eval_root (curinterp->Ieval_root)
#define eval_start (curinterp->Ieval_start)
#define fdpid (curinterp->Ifdpid)
#define Ie_tmpname e_tmpname
#define Iendav endav
#define Ienvgv envgv
-#define Ierrhv errhv
-#define Ierrsv errsv
+#define Ierrgv errgv
#define Ieval_root eval_root
#define Ieval_start eval_start
#define Ifdpid fdpid
#define e_fp Perl_e_fp
#define e_tmpname Perl_e_tmpname
#define endav Perl_endav
-#define errhv Perl_errhv
-#define errsv Perl_errsv
+#define errgv Perl_errgv
#define eval_root Perl_eval_root
#define eval_start Perl_eval_start
#define fdpid Perl_fdpid
SvREFCNT_dec(thr->cvcache);
SvREFCNT_dec(thr->magicals);
SvREFCNT_dec(thr->specific);
+ SvREFCNT_dec(thr->errsv);
+ SvREFCNT_dec(thr->errhv);
Safefree(markstack);
Safefree(scopestack);
Safefree(savestack);
e_tmpname
endav
envgv
-errhv
-errsv
+errgv
eval_root
eval_start
fdpid
break;
#ifdef USE_THREADS
case '@':
- sv_setsv(sv, errsv);
+ sv_setsv(sv, thr->errsv);
break;
#endif /* USE_THREADS */
}
break;
#ifdef USE_THREADS
case '@':
- sv_setsv(errsv, sv);
+ sv_setsv(thr->errsv, sv);
break;
#endif /* USE_THREADS */
}
croak(not_safe);
else {
/* force display of errors found but not reported */
- sv_catpv(errsv, not_safe);
- croak("%s", SvPV(errsv, na));
+ sv_catpv(ERRSV, not_safe);
+ croak("%s", SvPVx(ERRSV, na));
}
}
}
envgv = Nullgv;
siggv = Nullgv;
incgv = Nullgv;
- errhv = Nullhv;
- errsv = Nullsv;
+ errgv = Nullgv;
argvgv = Nullgv;
argvoutgv = Nullgv;
stdingv = Nullgv;
char* name;
I32 create;
{
+#ifdef USE_THREADS
+ PADOFFSET tmp;
+ if (name[1] == '\0' && !isALPHA(name[0])
+ && (tmp = find_thread_magical(name)) != NOT_IN_PAD) {
+ return *av_fetch(thr->magicals, tmp, FALSE);
+ }
+#endif /* USE_THREADS */
GV* gv = gv_fetchpv(name, create, SVt_PV);
if (gv)
return GvSV(gv);
if (flags & G_KEEPERR)
in_eval |= 4;
else
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
}
markstack_ptr++;
runops();
retval = stack_sp - (stack_base + oldmark);
if ((flags & G_EVAL) && !(flags & G_KEEPERR))
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
cleanup:
if (flags & G_EVAL) {
runops();
retval = stack_sp - (stack_base + oldmark);
if (!(flags & G_KEEPERR))
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
cleanup:
JMPENV_POP;
sv = POPs;
PUTBACK;
- if (croak_on_error && SvTRUE(errsv))
- croak(SvPV(errsv, na));
+ if (croak_on_error && SvTRUE(ERRSV))
+ croak(SvPVx(ERRSV, na));
return sv;
}
incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
GvMULTI_on(incgv);
defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
- errsv = newSVpv("", 0);
- errhv = newHV();
+ errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
+ GvMULTI_on(errgv);
(void)form("%240s",""); /* Preallocate temp - for immediate signals. */
- sv_grow(errsv, 240); /* Preallocate - for immediate signals. */
- sv_setpvn(errsv, "", 0);
+ sv_grow(ERRSV, 240); /* Preallocate - for immediate signals. */
+ sv_setpvn(ERRSV, "", 0);
curstash = defstash;
compiling.cop_stash = defstash;
debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
thr->cvcache = newHV();
thr->magicals = newAV();
thr->specific = newAV();
+ thr->errsv = newSVpv("", 0);
+ thr->errhv = newHV();
thr->flags = THRf_R_JOINABLE;
MUTEX_INIT(&thr->mutex);
/* Handcraft thrsv similarly to mess_sv */
JMPENV_PUSH(ret);
switch (ret) {
case 0: {
+ SV* atsv = ERRSV;
PUSHMARK(stack_sp);
perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
- (void)SvPV(errsv, len);
+ (void)SvPV(atsv, len);
if (len) {
JMPENV_POP;
curcop = &compiling;
curcop->cop_line = oldline;
if (list == beginav)
- sv_catpv(errsv, "BEGIN failed--compilation aborted");
+ sv_catpv(atsv, "BEGIN failed--compilation aborted");
else
- sv_catpv(errsv, "END failed--cleanup aborted");
+ sv_catpv(atsv, "END failed--cleanup aborted");
while (scopestack_ix > oldscope)
LEAVE;
- croak("%s", SvPVX(errsv));
+ croak("%s", SvPVX(atsv));
}
}
break;
# define SETERRNO(errcode,vmserrcode) errno = (errcode)
#endif
+#ifdef USE_THREADS
+# define ERRSV (thr->errsv)
+# define ERRHV (thr->errhv)
+#else
+# define ERRSV GvSV(errgv)
+# define ERRHV GvHV(errgv)
+#endif /* USE_THREADS */
+
#ifndef errno
extern int errno; /* ANSI allows errno to be an lvalue expr */
#endif
IEXT SV * Ilastscream;
/* shortcuts to misc objects */
-IEXT HV * Ierrhv;
-IEXT SV * Ierrsv;
+IEXT GV * Ierrgv;
/* shortcuts to debugging objects */
IEXT GV * IDBgv;
SV **svp;
STRLEN klen = strlen(message);
- svp = hv_fetch(errhv, message, klen, TRUE);
+ svp = hv_fetch(ERRHV, message, klen, TRUE);
if (svp) {
if (!SvIOK(*svp)) {
static char prefix[] = "\t(in cleanup) ";
sv_upgrade(*svp, SVt_IV);
(void)SvIOK_only(*svp);
- SvGROW(errsv, SvCUR(errsv)+sizeof(prefix)+klen);
- sv_catpvn(errsv, prefix, sizeof(prefix)-1);
- sv_catpvn(errsv, message, klen);
+ SvGROW(ERRSV, SvCUR(ERRSV)+sizeof(prefix)+klen);
+ sv_catpvn(ERRSV, prefix, sizeof(prefix)-1);
+ sv_catpvn(ERRSV, message, klen);
}
sv_inc(*svp);
}
}
else
- sv_setpv(errsv, message);
+ sv_setpv(ERRSV, message);
cxix = dopoptoeval(cxstack_ix);
if (cxix >= 0) {
LEAVE;
if (optype == OP_REQUIRE) {
- char* msg = SvPV(errsv, na);
+ char* msg = SvPVx(ERRSV, na);
DIE("%s", *msg ? msg : "Compilation failed in require");
}
return pop_return();
if (saveop->op_flags & OPf_SPECIAL)
in_eval |= 4;
else
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
if (yyparse() || error_count || !eval_root) {
SV **newsp;
I32 gimme;
lex_end();
LEAVE;
if (optype == OP_REQUIRE) {
- char* msg = SvPV(errsv, na);
+ char* msg = SvPVx(ERRSV, na);
DIE("%s", *msg ? msg : "Compilation failed in require");
}
SvREFCNT_dec(rs);
LEAVE;
if (!(save_flags & OPf_SPECIAL))
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
RETURNOP(retop);
}
eval_root = op; /* Only needed so that goto works right. */
in_eval = 1;
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
PUTBACK;
return DOCATCH(op->op_next);
}
curpm = newpm; /* Don't pop $1 et al till now */
LEAVE;
- sv_setpv(errsv,"");
+ sv_setpv(ERRSV,"");
RETURN;
}
tmps = SvPV(TOPs, na);
}
if (!tmps || !*tmps) {
- (void)SvUPGRADE(errsv, SVt_PV);
- if (SvPOK(errsv) && SvCUR(errsv))
- sv_catpv(errsv, "\t...caught");
- tmps = SvPV(errsv, na);
+ (void)SvUPGRADE(ERRSV, SVt_PV);
+ if (SvPOK(ERRSV) && SvCUR(ERRSV))
+ sv_catpv(ERRSV, "\t...caught");
+ tmps = SvPV(ERRSV, na);
}
if (!tmps || !*tmps)
tmps = "Warning: something's wrong";
tmps = SvPV(TOPs, na);
}
if (!tmps || !*tmps) {
- (void)SvUPGRADE(errsv, SVt_PV);
- if (SvPOK(errsv) && SvCUR(errsv))
- sv_catpv(errsv, "\t...propagated");
- tmps = SvPV(errsv, na);
+ (void)SvUPGRADE(ERRSV, SVt_PV);
+ if (SvPOK(ERRSV) && SvCUR(ERRSV))
+ sv_catpv(ERRSV, "\t...propagated");
+ tmps = SvPV(ERRSV, na);
}
if (!tmps || !*tmps)
tmps = "Died";
CATCH_SET(oldcatch);
#else
ENTER;
- perl_call_sv((SV*)gv, G_SCALAR);
+ perl_call_sv((SV*)GvCV(gv), G_SCALAR);
SPAGAIN;
#endif
sv = TOPs;
runops();
#else
PUTBACK;
- perl_call_sv((SV*)gv, G_SCALAR);
+ perl_call_sv((SV*)GvCV(gv), G_SCALAR);
#endif
SPAGAIN;
if (op = pp_entersub(ARGS))
runops();
#else
- perl_call_sv((SV*)gv, G_SCALAR);
+ perl_call_sv((SV*)GvCV(gv), G_SCALAR);
#endif
SPAGAIN;
}
U32 flags;
AV * magicals; /* Per-thread magicals */
AV * specific; /* Thread-specific user data */
+ SV * errsv; /* Backing SV for $@ */
+ HV * errhv; /* HV for what was %@ in pp_ctl.c */
perl_mutex mutex; /* For the fields others can change */
U32 tid;
struct thread *next, *prev; /* Circular linked list of threads */
if (in_eval & 2)
warn("%_", msg);
else if (in_eval)
- sv_catsv(errsv, msg);
+ sv_catsv(ERRSV, msg);
else
PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg));
if (++error_count >= 10)
thr->cvcache = newHV();
thr->magicals = newAV();
thr->specific = newAV();
+ thr->errsv = newSVpv("", 0);
+ thr->errhv = newHV();
thr->flags = THRf_R_JOINABLE;
MUTEX_INIT(&thr->mutex);