Integrate from ansi branch to mainline.
[p5sagit/p5-mst-13.2.git] / perl.c
diff --git a/perl.c b/perl.c
index 6606f71..381d574 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -69,6 +69,9 @@ static void init_ids _((void));
 static void init_debugger _((void));
 static void init_lexer _((void));
 static void init_main_stash _((void));
+#ifdef USE_THREADS
+static struct perl_thread * init_main_thread _((void));
+#endif /* USE_THREADS */
 static void init_perllib _((void));
 static void init_postdump_symbols _((int, char **, char **));
 static void init_predump_symbols _((void));
@@ -109,7 +112,7 @@ perl_construct(register PerlInterpreter *sv_interp)
 #ifdef USE_THREADS
     int i;
 #ifndef FAKE_THREADS
-    struct thread *thr;
+    struct perl_thread *thr;
 #endif /* FAKE_THREADS */
 #endif /* USE_THREADS */
     
@@ -125,7 +128,9 @@ perl_construct(register PerlInterpreter *sv_interp)
 #ifdef USE_THREADS
 
        INIT_THREADS;
-#ifndef WIN32
+#ifdef ALLOC_THREAD_KEY
+        ALLOC_THREAD_KEY;
+#else
        if (pthread_key_create(&thr_key, 0))
            croak("panic: pthread_key_create");
 #endif
@@ -139,9 +144,8 @@ perl_construct(register PerlInterpreter *sv_interp)
        COND_INIT(&eval_cond);
        MUTEX_INIT(&threads_mutex);
        COND_INIT(&nthreads_cond);
-       MUTEX_INIT(&keys_mutex);
        
-       thr = new_struct_thread(0);
+       thr = init_main_thread();
 #endif /* USE_THREADS */
 
        linestr = NEWSV(65,80);
@@ -211,9 +215,6 @@ perl_construct(register PerlInterpreter *sv_interp)
 
     fdpid = newAV();   /* for remembering popen pids by fd */
 
-    for (i = 0; i < N_PER_THREAD_MAGICALS; i++)
-       magical_keys[i] = NOT_IN_PAD;
-    keys = newSVpv("", 0);
     init_stacks(ARGS);
     DEBUG( {
        New(51,debname,128,char);
@@ -417,36 +418,6 @@ perl_destruct(register PerlInterpreter *sv_interp)
 
     /* defgv, aka *_ should be taken care of elsewhere */
 
-#if 0  /* just about all regexp stuff, seems to be ok */
-
-    /* shortcuts to regexp stuff */
-    leftgv = Nullgv;
-    ampergv = Nullgv;
-
-    SAVEFREEOP(curpm);
-    SAVEFREEOP(oldlastpm); /* for saving regexp context during debugger */
-
-    regprecomp = NULL; /* uncompiled string. */
-    regparse = NULL;   /* Input-scan pointer. */
-    regxend = NULL;    /* End of input for compile */
-    regnpar = 0;       /* () count. */
-    regcode = NULL;    /* Code-emit pointer; &regdummy = don't. */
-    regsize = 0;       /* Code size. */
-    regnaughty = 0;    /* How bad is this pattern? */
-    regsawback = 0;    /* Did we see \1, ...? */
-
-    reginput = NULL;           /* String-input pointer. */
-    regbol = NULL;             /* Beginning of input, for ^ check. */
-    regeol = NULL;             /* End of input, for $ check. */
-    regstartp = (char **)NULL; /* Pointer to startp array. */
-    regendp = (char **)NULL;   /* Ditto for endp. */
-    reglastparen = 0;          /* Similarly for lastparen. */
-    regtill = NULL;            /* How far we are required to go. */
-    regflags = 0;              /* are we folding, multilining? */
-    regprev = (char)NULL;      /* char before regbol, \n if none */
-
-#endif /* if 0 */
-
     /* clean up after study() */
     SvREFCNT_dec(lastscream);
     lastscream = Nullsv;
@@ -471,8 +442,7 @@ perl_destruct(register PerlInterpreter *sv_interp)
     envgv = Nullgv;
     siggv = Nullgv;
     incgv = Nullgv;
-    errhv = Nullhv;
-    errsv = Nullsv;
+    errgv = Nullgv;
     argvgv = Nullgv;
     argvoutgv = Nullgv;
     stdingv = Nullgv;
@@ -967,7 +937,7 @@ print \"  \\@INC:\\n    @INC\\n\";");
     SvREFCNT_dec(rs);
     rs = SvREFCNT_inc(nrs);
 #ifdef USE_THREADS
-    sv_setsv(*av_fetch(thr->specific, find_thread_magical("/"), TRUE), rs); 
+    sv_setsv(*av_fetch(thr->threadsv, find_threadsv("/"), FALSE), rs); 
 #else
     sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
 #endif /* USE_THREADS */
@@ -1079,7 +1049,17 @@ perl_run(PerlInterpreter *sv_interp)
 SV*
 perl_get_sv(char *name, I32 create)
 {
-    GV* gv = gv_fetchpv(name, create, SVt_PV);
+    GV *gv;
+#ifdef USE_THREADS
+    if (name[1] == '\0' && !isALPHA(name[0])) {
+       PADOFFSET tmp = find_threadsv(name);
+       if (tmp != NOT_IN_PAD) {
+           dTHR;
+           return *av_fetch(thr->threadsv, tmp, FALSE);
+       }
+    }
+#endif /* USE_THREADS */
+    gv = gv_fetchpv(name, create, SVt_PV);
     if (gv)
        return GvSV(gv);
     return Nullsv;
@@ -1129,7 +1109,6 @@ perl_call_argv(char *subname, I32 flags, register char **argv)
                        /* See G_* flags in cop.h */
                        /* null terminated arg list */
 {
-    dTHR;
     dSP;
 
     PUSHMARK(sp);
@@ -1156,7 +1135,6 @@ perl_call_method(char *methname, I32 flags)
                                /* name of the subroutine */
                        /* See G_* flags in cop.h */
 {
-    dTHR;
     dSP;
     OP myop;
     if (!op)
@@ -1218,7 +1196,7 @@ perl_call_sv(SV *sv, I32 flags)
        markstack_ptr--;
        /* we're trying to emulate pp_entertry() here */
        {
-           register CONTEXT *cx;
+           register PERL_CONTEXT *cx;
            I32 gimme = GIMME_V;
            
            ENTER;
@@ -1233,7 +1211,7 @@ perl_call_sv(SV *sv, I32 flags)
            if (flags & G_KEEPERR)
                in_eval |= 4;
            else
-               sv_setpv(errsv,"");
+               sv_setpv(ERRSV,"");
        }
        markstack_ptr++;
 
@@ -1278,7 +1256,7 @@ perl_call_sv(SV *sv, I32 flags)
        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) {
@@ -1286,7 +1264,7 @@ perl_call_sv(SV *sv, I32 flags)
            SV **newsp;
            PMOP *newpm;
            I32 gimme;
-           register CONTEXT *cx;
+           register PERL_CONTEXT *cx;
            I32 optype;
 
            POPBLOCK(cx,newpm);
@@ -1387,7 +1365,7 @@ perl_eval_sv(SV *sv, I32 flags)
        runops();
     retval = stack_sp - (stack_base + oldmark);
     if (!(flags & G_KEEPERR))
-       sv_setpv(errsv,"");
+       sv_setpv(ERRSV,"");
 
   cleanup:
     JMPENV_POP;
@@ -1404,7 +1382,6 @@ perl_eval_sv(SV *sv, I32 flags)
 SV*
 perl_eval_pv(char *p, I32 croak_on_error)
 {
-    dTHR;
     dSP;
     SV* sv = newSVpv(p, 0);
 
@@ -1416,8 +1393,8 @@ perl_eval_pv(char *p, I32 croak_on_error)
     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;
 }
@@ -1709,6 +1686,9 @@ GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n")
        break;
     case '-':
     case 0:
+#ifdef WIN32
+    case '\r':
+#endif
     case '\n':
     case '\t':
        break;
@@ -1783,14 +1763,15 @@ init_main_stash(void)
     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));
+    globalstash = GvHV(gv_fetchpv("CORE::GLOBAL::", GV_ADDMULTI, SVt_PVHV));
     /* We must init $/ before switches are processed. */
     sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
 }
@@ -2009,7 +1990,7 @@ SV *sv;
     if (strEQ(origfilename,"-"))
        scriptname = "";
     if (fdscript >= 0) {
-       rsfp = PerlIO_fdopen(fdscript,"r");
+       rsfp = PerlIO_fdopen(fdscript,PERL_SCRIPT_MODE);
 #if defined(HAS_FCNTL) && defined(F_SETFD)
        if (rsfp)
            fcntl(PerlIO_fileno(rsfp),F_SETFD,1);  /* ensure close-on-exec */
@@ -2093,7 +2074,7 @@ sed %s -e \"/^[^#]/b\" \
        rsfp = PerlIO_stdin();
     }
     else {
-       rsfp = PerlIO_open(scriptname,"r");
+       rsfp = PerlIO_open(scriptname,PERL_SCRIPT_MODE);
 #if defined(HAS_FCNTL) && defined(F_SETFD)
        if (rsfp)
            fcntl(PerlIO_fileno(rsfp),F_SETFD,1);  /* ensure close-on-exec */
@@ -2441,8 +2422,8 @@ init_stacks(ARGSproto)
     stack_sp = stack_base;
     stack_max = stack_base + 127;
 
-    cxstack_max = 8192 / sizeof(CONTEXT) - 2;  /* Use most of 8K. */
-    New(50,cxstack,cxstack_max + 1,CONTEXT);
+    cxstack_max = 8192 / sizeof(PERL_CONTEXT) - 2;     /* Use most of 8K. */
+    New(50,cxstack,cxstack_max + 1,PERL_CONTEXT);
     cxstack_ix = -1;
 
     New(50,tmps_stack,128,SV*);
@@ -2520,7 +2501,7 @@ init_predump_symbols(void)
     GV *othergv;
 
 #ifdef USE_THREADS
-    sv_setpvn(*av_fetch(thr->specific,find_thread_magical("\""),TRUE), " ", 1);
+    sv_setpvn(*av_fetch(thr->threadsv,find_threadsv("\""),FALSE)," ", 1);
 #else
     sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
 #endif /* USE_THREADS */
@@ -2798,6 +2779,69 @@ incpush(char *p, int addsubdirs)
     SvREFCNT_dec(subdir);
 }
 
+#ifdef USE_THREADS
+static struct perl_thread *
+init_main_thread()
+{
+    struct perl_thread *thr;
+    XPV *xpv;
+
+    Newz(53, thr, 1, struct perl_thread);
+    curcop = &compiling;
+    thr->cvcache = newHV();
+    thr->threadsv = newAV();
+    thr->specific = newAV();
+    thr->errhv = newHV();
+    thr->flags = THRf_R_JOINABLE;
+    MUTEX_INIT(&thr->mutex);
+    /* Handcraft thrsv similarly to mess_sv */
+    New(53, thrsv, 1, SV);
+    Newz(53, xpv, 1, XPV);
+    SvFLAGS(thrsv) = SVt_PV;
+    SvANY(thrsv) = (void*)xpv;
+    SvREFCNT(thrsv) = 1 << 30; /* practically infinite */
+    SvPVX(thrsv) = (char*)thr;
+    SvCUR_set(thrsv, sizeof(thr));
+    SvLEN_set(thrsv, sizeof(thr));
+    *SvEND(thrsv) = '\0';      /* in the trailing_nul field */
+    thr->oursv = thrsv;
+    curcop = &compiling;
+    chopset = " \n-";
+
+    MUTEX_LOCK(&threads_mutex);
+    nthreads++;
+    thr->tid = 0;
+    thr->next = thr;
+    thr->prev = thr;
+    MUTEX_UNLOCK(&threads_mutex);
+
+#ifdef HAVE_THREAD_INTERN
+    init_thread_intern(thr);
+#endif
+
+#ifdef SET_THREAD_SELF
+    SET_THREAD_SELF(thr);
+#else
+    thr->self = pthread_self();
+#endif /* SET_THREAD_SELF */
+    SET_THR(thr);
+
+    /*
+     * These must come after the SET_THR because sv_setpvn does
+     * SvTAINT and the taint fields require dTHR.
+     */
+    toptarget = NEWSV(0,0);
+    sv_upgrade(toptarget, SVt_PVFM);
+    sv_setpvn(toptarget, "", 0);
+    bodytarget = NEWSV(0,0);
+    sv_upgrade(bodytarget, SVt_PVFM);
+    sv_setpvn(bodytarget, "", 0);
+    formtarget = bodytarget;
+    thr->errsv = newSVpv("", 0);
+    return thr;
+}
+#endif /* USE_THREADS */
+
 void
 call_list(I32 oldscope, AV *list)
 {
@@ -2815,7 +2859,7 @@ call_list(I32 oldscope, AV *list)
        JMPENV_PUSH(ret);
        switch (ret) {
        case 0: {
-               SV* atsv = sv_mortalcopy(errsv);
+               SV* atsv = ERRSV;
                PUSHMARK(stack_sp);
                perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
                (void)SvPV(atsv, len);
@@ -2920,7 +2964,7 @@ static void
 my_exit_jump(void)
 {
     dTHR;
-    register CONTEXT *cx;
+    register PERL_CONTEXT *cx;
     I32 gimme;
     SV **newsp;
 
@@ -2943,3 +2987,5 @@ my_exit_jump(void)
 
     JMPENV_JUMP(2);
 }
+
+