This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
IV changes for long long (was Re: 5.004_68 on its way to the CPAN)
[perl5.git] / perl.c
diff --git a/perl.c b/perl.c
index a119a45..db78b4e 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -45,36 +45,13 @@ dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n";
 #endif
 #endif
 
-#define I_REINIT \
-  STMT_START {                 \
-    chopset    = " \n-";       \
-    copline    = NOLINE;       \
-    curcop     = &compiling;   \
-    curcopdb    = NULL;                \
-    cxstack_ix  = -1;          \
-    cxstack_max = 128;         \
-    dbargs     = 0;            \
-    dlmax      = 128;          \
-    laststatval        = -1;           \
-    laststype  = OP_STAT;      \
-    maxscream  = -1;           \
-    maxsysfd   = MAXSYSFD;     \
-    statname   = Nullsv;       \
-    tmps_floor = -1;           \
-    tmps_ix     = -1;          \
-    op_mask     = NULL;                \
-    dlmax       = 128;         \
-    laststatval = -1;          \
-    laststype   = OP_STAT;     \
-    mess_sv     = Nullsv;      \
-  } STMT_END
-
 #ifdef PERL_OBJECT
 static I32 read_e_script _((CPerlObj* pPerl, int idx, SV *buf_sv, int maxlen));
 #else
 static void find_beginning _((void));
 static void forbid_setid _((char *));
 static void incpush _((char *, int));
+static void init_interp _((void));
 static void init_ids _((void));
 static void init_debugger _((void));
 static void init_lexer _((void));
@@ -135,6 +112,7 @@ perl_construct(register PerlInterpreter *sv_interp)
 #endif
 
 #ifdef MULTIPLICITY
+    ++ninterps;
     Zero(sv_interp, 1, PerlInterpreter);
 #endif
 
@@ -165,7 +143,7 @@ perl_construct(register PerlInterpreter *sv_interp)
        thr = init_main_thread();
 #endif /* USE_THREADS */
 
-       linestr = NEWSV(65,80);
+       linestr = NEWSV(65,79);
        sv_upgrade(linestr,SVt_PVIV);
 
        if (!SvREADONLY(&sv_undef)) {
@@ -204,18 +182,20 @@ perl_construct(register PerlInterpreter *sv_interp)
 
     init_stacks(ARGS);
 #ifdef MULTIPLICITY
-    I_REINIT;
+    init_interp();
     perl_destruct_level = 1; 
 #else
-   if(perl_destruct_level > 0)
-       I_REINIT;
+   if (perl_destruct_level > 0)
+       init_interp();
 #endif
 
     init_ids();
     lex_state = LEX_NOTPARSING;
 
-    install_tryblock_method(0);     /* default to set/longjmp style tryblock */
-    JMPENV_TOPINIT(start_env);
+    start_env.je_prev = NULL;
+    start_env.je_ret = -1;
+    start_env.je_mustcatch = TRUE;
+    top_env     = &start_env;
     STATUS_ALL_SUCCESS;
 
     SET_NUMERIC_STANDARD();
@@ -350,6 +330,10 @@ perl_destruct(register PerlInterpreter *sv_interp)
     LEAVE;
     FREETMPS;
 
+#ifdef MULTIPLICITY
+    --ninterps;
+#endif
+
     /* We must account for everything.  */
 
     /* Destroy the main CV and syntax tree */
@@ -549,8 +533,11 @@ perl_destruct(register PerlInterpreter *sv_interp)
     /* No SVs have survived, need to clean out */
     linestr = NULL;
     pidstatus = Nullhv;
-    if (origfilename)
-       Safefree(origfilename);
+    Safefree(origfilename);
+    Safefree(archpat_auto);
+    Safefree(reg_start_tmp);
+    Safefree(HeKEY_hek(&hv_fetch_ent_mh));
+    Safefree(op_mask);
     nuke_stacks();
     hints = 0;         /* Reset hints. Should hints be per-interpreter ? */
     
@@ -608,17 +595,6 @@ perl_atexit(void (*fn) (void *), void *ptr)
     ++exitlistlen;
 }
 
-struct try_parse_locals {
-    void (*xsinit)();
-    int argc;
-    char **argv;
-    char **env;
-    I32 oldscope;
-    int ret;
-};
-typedef struct try_parse_locals TRY_PARSE_LOCALS;
-static TRYVTBL PerlParseVtbl;
-
 int
 #ifdef PERL_OBJECT
 CPerlObj::perl_parse(void (*xsinit) (CPerlObj*), int argc, char **argv, char **env)
@@ -627,11 +603,16 @@ perl_parse(PerlInterpreter *sv_interp, void (*xsinit) (void), int argc, char **a
 #endif
 {
     dTHR;
-    TRY_PARSE_LOCALS locals;
-    locals.xsinit = xsinit;
-    locals.argc = argc;
-    locals.argv = argv;
-    locals.env = env;
+    register SV *sv;
+    register char *s;
+    char *scriptname = NULL;
+    VOL bool dosearch = FALSE;
+    char *validarg = "";
+    I32 oldscope;
+    AV* comppadlist;
+    dJMPENV;
+    int ret;
+    int fdscript = -1;
 
 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
 #ifdef IAMSUID
@@ -679,61 +660,444 @@ setuid perl scripts securely.\n");
     main_cv = Nullcv;
 
     time(&basetime);
-    locals.oldscope = scopestack_ix;
+    oldscope = scopestack_ix;
 
-    TRYBLOCK(PerlParseVtbl, locals);
-    return locals.ret;
-}
+    JMPENV_PUSH(ret);
+    switch (ret) {
+    case 1:
+       STATUS_ALL_FAILURE;
+       /* FALL THROUGH */
+    case 2:
+       /* my_exit() was called */
+       while (scopestack_ix > oldscope)
+           LEAVE;
+       FREETMPS;
+       curstash = defstash;
+       if (endav)
+           call_list(oldscope, endav);
+       JMPENV_POP;
+       return STATUS_NATIVE_EXPORT;
+    case 3:
+       JMPENV_POP;
+       PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
+       return 1;
+    }
 
-struct try_run_locals {
-    I32 oldscope;
-    int ret;
-};
-typedef struct try_run_locals TRY_RUN_LOCALS;
-static TRYVTBL PerlRunVtbl;
+    sv_setpvn(linestr,"",0);
+    sv = newSVpv("",0);                /* first used for -I flags */
+    SAVEFREESV(sv);
+    init_main_stash();
 
-int
-#ifdef PERL_OBJECT
-CPerlObj::perl_run(void)
-#else
-perl_run(PerlInterpreter *sv_interp)
+    for (argc--,argv++; argc > 0; argc--,argv++) {
+       if (argv[0][0] != '-' || !argv[0][1])
+           break;
+#ifdef DOSUID
+    if (*validarg)
+       validarg = " PHOOEY ";
+    else
+       validarg = argv[0];
 #endif
-{
-    dTHR;
-    TRY_RUN_LOCALS locals;
+       s = argv[0]+1;
+      reswitch:
+       switch (*s) {
+       case ' ':
+       case '0':
+       case 'F':
+       case 'a':
+       case 'c':
+       case 'd':
+       case 'D':
+       case 'h':
+       case 'i':
+       case 'l':
+       case 'M':
+       case 'm':
+       case 'n':
+       case 'p':
+       case 's':
+       case 'u':
+       case 'U':
+       case 'v':
+       case 'w':
+           if (s = moreswitches(s))
+               goto reswitch;
+           break;
 
-#ifndef PERL_OBJECT
-    if (!(curinterp = sv_interp))
-       return 255;
-#endif
+       case 'T':
+           tainting = TRUE;
+           s++;
+           goto reswitch;
 
-    locals.oldscope = scopestack_ix;
-    TRYBLOCK(PerlRunVtbl, locals);
-    return locals.ret;
-}
+       case 'e':
+           if (euid != uid || egid != gid)
+               croak("No -e allowed in setuid scripts");
+           if (!e_script) {
+               e_script = newSVpv("",0);
+               filter_add(read_e_script, NULL);
+           }
+           if (*++s)
+               sv_catpv(e_script, s);
+           else if (argv[1]) {
+               sv_catpv(e_script, argv[1]);
+               argc--,argv++;
+           }
+           else
+               croak("No code specified for -e");
+           sv_catpv(e_script, "\n");
+           break;
 
-SV*
-perl_get_sv(char *name, I32 create)
-{
-    GV *gv;
-#ifdef USE_THREADS
-    if (name[1] == '\0' && !isALPHA(name[0])) {
-       PADOFFSET tmp = find_threadsv(name);
-       if (tmp != NOT_IN_PAD) {
-           dTHR;
-           return THREADSV(tmp);
+       case 'I':       /* -I handled both here and in moreswitches() */
+           forbid_setid("-I");
+           if (!*++s && (s=argv[1]) != Nullch) {
+               argc--,argv++;
+           }
+           while (s && isSPACE(*s))
+               ++s;
+           if (s && *s) {
+               char *e, *p;
+               for (e = s; *e && !isSPACE(*e); e++) ;
+               p = savepvn(s, e-s);
+               incpush(p, TRUE);
+               sv_catpv(sv,"-I");
+               sv_catpv(sv,p);
+               sv_catpv(sv," ");
+               Safefree(p);
+           }   /* XXX else croak? */
+           break;
+       case 'P':
+           forbid_setid("-P");
+           preprocess = TRUE;
+           s++;
+           goto reswitch;
+       case 'S':
+           forbid_setid("-S");
+           dosearch = TRUE;
+           s++;
+           goto reswitch;
+       case 'V':
+           if (!preambleav)
+               preambleav = newAV();
+           av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
+           if (*++s != ':')  {
+               Sv = newSVpv("print myconfig();",0);
+#ifdef VMS
+               sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
+#else
+               sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
+#endif
+#if defined(DEBUGGING) || defined(NO_EMBED) || defined(MULTIPLICITY)
+               sv_catpv(Sv,"\"  Compile-time options:");
+#  ifdef DEBUGGING
+               sv_catpv(Sv," DEBUGGING");
+#  endif
+#  ifdef NO_EMBED
+               sv_catpv(Sv," NO_EMBED");
+#  endif
+#  ifdef MULTIPLICITY
+               sv_catpv(Sv," MULTIPLICITY");
+#  endif
+               sv_catpv(Sv,"\\n\",");
+#endif
+#if defined(LOCAL_PATCH_COUNT)
+               if (LOCAL_PATCH_COUNT > 0) {
+                   int i;
+                   sv_catpv(Sv,"\"  Locally applied patches:\\n\",");
+                   for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
+                       if (localpatches[i])
+                           sv_catpvf(Sv,"\"  \\t%s\\n\",",localpatches[i]);
+                   }
+               }
+#endif
+               sv_catpvf(Sv,"\"  Built under %s\\n\"",OSNAME);
+#ifdef __DATE__
+#  ifdef __TIME__
+               sv_catpvf(Sv,",\"  Compiled at %s %s\\n\"",__DATE__,__TIME__);
+#  else
+               sv_catpvf(Sv,",\"  Compiled on %s\\n\"",__DATE__);
+#  endif
+#endif
+               sv_catpv(Sv, "; \
+$\"=\"\\n    \"; \
+@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \
+print \"  \\%ENV:\\n    @env\\n\" if @env; \
+print \"  \\@INC:\\n    @INC\\n\";");
+           }
+           else {
+               Sv = newSVpv("config_vars(qw(",0);
+               sv_catpv(Sv, ++s);
+               sv_catpv(Sv, "))");
+               s += strlen(s);
+           }
+           av_push(preambleav, Sv);
+           scriptname = BIT_BUCKET;    /* don't look for script or read stdin */
+           goto reswitch;
+       case 'x':
+           doextract = TRUE;
+           s++;
+           if (*s)
+               cddir = savepv(s);
+           break;
+       case 0:
+           break;
+       case '-':
+           if (!*++s || isSPACE(*s)) {
+               argc--,argv++;
+               goto switch_end;
+           }
+           /* catch use of gnu style long options */
+           if (strEQ(s, "version")) {
+               s = "v";
+               goto reswitch;
+           }
+           if (strEQ(s, "help")) {
+               s = "h";
+               goto reswitch;
+           }
+           s--;
+           /* FALL THROUGH */
+       default:
+           croak("Unrecognized switch: -%s  (-h will show valid options)",s);
        }
     }
-#endif /* USE_THREADS */
-    gv = gv_fetchpv(name, create, SVt_PV);
-    if (gv)
-       return GvSV(gv);
-    return Nullsv;
-}
+  switch_end:
 
-AV*
-perl_get_av(char *name, I32 create)
-{
+    if (!tainting && (s = PerlEnv_getenv("PERL5OPT"))) {
+       while (s && *s) {
+           while (isSPACE(*s))
+               s++;
+           if (*s == '-') {
+               s++;
+               if (isSPACE(*s))
+                   continue;
+           }
+           if (!*s)
+               break;
+           if (!strchr("DIMUdmw", *s))
+               croak("Illegal switch in PERL5OPT: -%c", *s);
+           s = moreswitches(s);
+       }
+    }
+
+    if (!scriptname)
+       scriptname = argv[0];
+    if (e_script) {
+       argc++,argv--;
+       scriptname = BIT_BUCKET;        /* don't look for script or read stdin */
+    }
+    else if (scriptname == Nullch) {
+#ifdef MSDOS
+       if ( PerlLIO_isatty(PerlIO_fileno(PerlIO_stdin())) )
+           moreswitches("h");
+#endif
+       scriptname = "-";
+    }
+
+    init_perllib();
+
+    open_script(scriptname,dosearch,sv,&fdscript);
+
+    validate_suid(validarg, scriptname,fdscript);
+
+    if (doextract)
+       find_beginning();
+
+    main_cv = compcv = (CV*)NEWSV(1104,0);
+    sv_upgrade((SV *)compcv, SVt_PVCV);
+    CvUNIQUE_on(compcv);
+
+    comppad = newAV();
+    av_push(comppad, Nullsv);
+    curpad = AvARRAY(comppad);
+    comppad_name = newAV();
+    comppad_name_fill = 0;
+    min_intro_pending = 0;
+    padix = 0;
+#ifdef USE_THREADS
+    av_store(comppad_name, 0, newSVpv("@_", 2));
+    curpad[0] = (SV*)newAV();
+    SvPADMY_on(curpad[0]);     /* XXX Needed? */
+    CvOWNER(compcv) = 0;
+    New(666, CvMUTEXP(compcv), 1, perl_mutex);
+    MUTEX_INIT(CvMUTEXP(compcv));
+#endif /* USE_THREADS */
+
+    comppadlist = newAV();
+    AvREAL_off(comppadlist);
+    av_store(comppadlist, 0, (SV*)comppad_name);
+    av_store(comppadlist, 1, (SV*)comppad);
+    CvPADLIST(compcv) = comppadlist;
+
+    boot_core_UNIVERSAL();
+
+    if (xsinit)
+       (*xsinit)(PERL_OBJECT_THIS);    /* in case linked C routines want magical variables */
+#if defined(VMS) || defined(WIN32) || defined(DJGPP)
+    init_os_extras();
+#endif
+
+    init_predump_symbols();
+    /* init_postdump_symbols not currently designed to be called */
+    /* more than once (ENV isn't cleared first, for example)    */
+    /* But running with -u leaves %ENV & @ARGV undefined!    XXX */
+    if (!do_undump)
+       init_postdump_symbols(argc,argv,env);
+
+    init_lexer();
+
+    /* now parse the script */
+
+    SETERRNO(0,SS$_NORMAL);
+    error_count = 0;
+    if (yyparse() || error_count) {
+       if (minus_c)
+           croak("%s had compilation errors.\n", origfilename);
+       else {
+           croak("Execution of %s aborted due to compilation errors.\n",
+               origfilename);
+       }
+    }
+    curcop->cop_line = 0;
+    curstash = defstash;
+    preprocess = FALSE;
+    if (e_script) {
+       SvREFCNT_dec(e_script);
+       e_script = Nullsv;
+    }
+
+    /* now that script is parsed, we can modify record separator */
+    SvREFCNT_dec(rs);
+    rs = SvREFCNT_inc(nrs);
+    sv_setsv(perl_get_sv("/", TRUE), rs);
+    if (do_undump)
+       my_unexec();
+
+    if (dowarn)
+       gv_check(defstash);
+
+    LEAVE;
+    FREETMPS;
+
+#ifdef MYMALLOC
+    if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
+       dump_mstats("after compilation:");
+#endif
+
+    ENTER;
+    restartop = 0;
+    JMPENV_POP;
+    return 0;
+}
+
+int
+#ifdef PERL_OBJECT
+CPerlObj::perl_run(void)
+#else
+perl_run(PerlInterpreter *sv_interp)
+#endif
+{
+    dSP;
+    I32 oldscope;
+    dJMPENV;
+    int ret;
+
+#ifndef PERL_OBJECT
+    if (!(curinterp = sv_interp))
+       return 255;
+#endif
+
+    oldscope = scopestack_ix;
+
+    JMPENV_PUSH(ret);
+    switch (ret) {
+    case 1:
+       cxstack_ix = -1;                /* start context stack again */
+       break;
+    case 2:
+       /* my_exit() was called */
+       while (scopestack_ix > oldscope)
+           LEAVE;
+       FREETMPS;
+       curstash = defstash;
+       if (endav)
+           call_list(oldscope, endav);
+#ifdef MYMALLOC
+       if (PerlEnv_getenv("PERL_DEBUG_MSTATS"))
+           dump_mstats("after execution:  ");
+#endif
+       JMPENV_POP;
+       return STATUS_NATIVE_EXPORT;
+    case 3:
+       if (!restartop) {
+           PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
+           FREETMPS;
+           JMPENV_POP;
+           return 1;
+       }
+       POPSTACK_TO(mainstack);
+       break;
+    }
+
+    DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n",
+                    sawampersand ? "Enabling" : "Omitting"));
+
+    if (!restartop) {
+       DEBUG_x(dump_all());
+       DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
+#ifdef USE_THREADS
+       DEBUG_L(PerlIO_printf(Perl_debug_log, "main thread is 0x%lx\n",
+                             (unsigned long) thr));
+#endif /* USE_THREADS */       
+
+       if (minus_c) {
+           PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename);
+           my_exit(0);
+       }
+       if (PERLDB_SINGLE && DBsingle)
+          sv_setiv(DBsingle, 1); 
+       if (initav)
+           call_list(oldscope, initav);
+    }
+
+    /* do it */
+
+    if (restartop) {
+       op = restartop;
+       restartop = 0;
+       CALLRUNOPS();
+    }
+    else if (main_start) {
+       CvDEPTH(main_cv) = 1;
+       op = main_start;
+       CALLRUNOPS();
+    }
+
+    my_exit(0);
+    /* NOTREACHED */
+    return 0;
+}
+
+SV*
+perl_get_sv(char *name, I32 create)
+{
+    GV *gv;
+#ifdef USE_THREADS
+    if (name[1] == '\0' && !isALPHA(name[0])) {
+       PADOFFSET tmp = find_threadsv(name);
+       if (tmp != NOT_IN_PAD) {
+           dTHR;
+           return THREADSV(tmp);
+       }
+    }
+#endif /* USE_THREADS */
+    gv = gv_fetchpv(name, create, SVt_PV);
+    if (gv)
+       return GvSV(gv);
+    return Nullsv;
+}
+
+AV*
+perl_get_av(char *name, I32 create)
+{
     GV* gv = gv_fetchpv(name, create, SVt_PVAV);
     if (create)
        return GvAVn(gv);
@@ -826,7 +1190,7 @@ perl_call_sv(SV *sv, I32 flags)
     I32 oldscope;
     bool oldcatch = CATCH_GET;
     dJMPENV;
-    int jmpstat;
+    int ret;
     OP* oldop = op;
 
     if (flags & G_DISCARD) {
@@ -882,14 +1246,14 @@ perl_call_sv(SV *sv, I32 flags)
        }
        markstack_ptr++;
 
-       JMPENV_PUSH(jmpstat);
-       switch (jmpstat) {
-       case JMP_NORMAL:
+       JMPENV_PUSH(ret);
+       switch (ret) {
+       case 0:
            break;
-       case JMP_ABNORMAL:
+       case 1:
            STATUS_ALL_FAILURE;
            /* FALL THROUGH */
-       case JMP_MYEXIT:
+       case 2:
            /* my_exit() was called */
            curstash = defstash;
            FREETMPS;
@@ -898,7 +1262,7 @@ perl_call_sv(SV *sv, I32 flags)
                croak("Callback called exit");
            my_exit_jump();
            /* NOTREACHED */
-       case JMP_EXCEPTION:
+       case 3:
            if (restartop) {
                op = restartop;
                restartop = 0;
@@ -968,7 +1332,7 @@ perl_eval_sv(SV *sv, I32 flags)
     I32 retval;
     I32 oldscope;
     dJMPENV;
-    int jmpstat;
+    int ret;
     OP* oldop = op;
 
     if (flags & G_DISCARD) {
@@ -993,14 +1357,14 @@ perl_eval_sv(SV *sv, I32 flags)
     if (flags & G_KEEPERR)
        myop.op_flags |= OPf_SPECIAL;
 
-    JMPENV_PUSH(jmpstat);
-    switch (jmpstat) {
-    case JMP_NORMAL:
+    JMPENV_PUSH(ret);
+    switch (ret) {
+    case 0:
        break;
-    case JMP_ABNORMAL:
+    case 1:
        STATUS_ALL_FAILURE;
        /* FALL THROUGH */
-    case JMP_MYEXIT:
+    case 2:
        /* my_exit() was called */
        curstash = defstash;
        FREETMPS;
@@ -1009,7 +1373,7 @@ perl_eval_sv(SV *sv, I32 flags)
            croak("Callback called exit");
        my_exit_jump();
        /* NOTREACHED */
-    case JMP_EXCEPTION:
+    case 3:
        if (restartop) {
            op = restartop;
            restartop = 0;
@@ -1411,41 +1775,107 @@ my_unexec(void)
 #endif
 }
 
+/* initialize curinterp */
 STATIC void
-init_main_stash(void)
+init_interp(void)
 {
-    dTHR;
-    GV *gv;
 
-    /* Note that strtab is a rather special HV.  Assumptions are made
-       about not iterating on it, and not adding tie magic to it.
-       It is properly deallocated in perl_destruct() */
-    strtab = newHV();
-    HvSHAREKEYS_off(strtab);                   /* mandatory */
-    Newz(506,((XPVHV*)SvANY(strtab))->xhv_array,
-        sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char);
-    
-    curstash = defstash = newHV();
-    curstname = newSVpv("main",4);
-    gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
-    SvREFCNT_dec(GvHV(gv));
-    GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
-    SvREADONLY_on(gv);
-    HvNAME(defstash) = savepv("main");
-    incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
-    GvMULTI_on(incgv);
-    defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
-    errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
-    GvMULTI_on(errgv);
-    replgv = gv_HVadd(gv_fetchpv("\022", TRUE, SVt_PV)); /* ^R */
-    GvMULTI_on(replgv);
-    (void)form("%240s","");    /* Preallocate temp - for immediate signals. */
-    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));
+#ifdef PERL_OBJECT             /* XXX kludge */
+#define I_REINIT \
+  STMT_START {                 \
+    chopset    = " \n-";       \
+    copline    = NOLINE;       \
+    curcop     = &compiling;   \
+    curcopdb    = NULL;                \
+    dbargs     = 0;            \
+    dlmax      = 128;          \
+    laststatval        = -1;           \
+    laststype  = OP_STAT;      \
+    maxscream  = -1;           \
+    maxsysfd   = MAXSYSFD;     \
+    statname   = Nullsv;       \
+    tmps_floor = -1;           \
+    tmps_ix     = -1;          \
+    op_mask     = NULL;                \
+    dlmax       = 128;         \
+    laststatval = -1;          \
+    laststype   = OP_STAT;     \
+    mess_sv     = Nullsv;      \
+    splitstr    = " ";         \
+    generation  = 100;         \
+    exitlist    = NULL;                \
+    exitlistlen = 0;           \
+    regindent   = 0;           \
+    in_clean_objs = FALSE;     \
+    in_clean_all= FALSE;       \
+    profiledata = NULL;                \
+    rsfp       = Nullfp;       \
+    rsfp_filters= Nullav;      \
+  } STMT_END
+    I_REINIT;
+#else
+#  ifdef MULTIPLICITY
+#    define PERLVAR(var,type)
+#    define PERLVARI(var,type,init)    curinterp->var = init;
+#    define PERLVARIC(var,type,init)   curinterp->var = init;
+#    include "intrpvar.h"
+#    ifndef USE_THREADS
+#      include "thrdvar.h"
+#    endif
+#    undef PERLVAR
+#    undef PERLVARI
+#    undef PERLVARIC
+#    else
+#    define PERLVAR(var,type)
+#    define PERLVARI(var,type,init)    var = init;
+#    define PERLVARIC(var,type,init)   var = init;
+#    include "intrpvar.h"
+#    ifndef USE_THREADS
+#      include "thrdvar.h"
+#    endif
+#    undef PERLVAR
+#    undef PERLVARI
+#    undef PERLVARIC
+#  endif
+#endif
+
+}
+
+STATIC void
+init_main_stash(void)
+{
+    dTHR;
+    GV *gv;
+
+    /* Note that strtab is a rather special HV.  Assumptions are made
+       about not iterating on it, and not adding tie magic to it.
+       It is properly deallocated in perl_destruct() */
+    strtab = newHV();
+    HvSHAREKEYS_off(strtab);                   /* mandatory */
+    Newz(506,((XPVHV*)SvANY(strtab))->xhv_array,
+        sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char);
+    
+    curstash = defstash = newHV();
+    curstname = newSVpv("main",4);
+    gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
+    SvREFCNT_dec(GvHV(gv));
+    GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
+    SvREADONLY_on(gv);
+    HvNAME(defstash) = savepv("main");
+    incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
+    GvMULTI_on(incgv);
+    defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
+    errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
+    GvMULTI_on(errgv);
+    replgv = gv_fetchpv("\022", TRUE, SVt_PV); /* ^R */
+    GvMULTI_on(replgv);
+    (void)form("%240s","");    /* Preallocate temp - for immediate signals. */
+    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);
 }
@@ -1456,7 +1886,8 @@ open_script(char *scriptname, bool dosearch, SV *sv, int *fdscript)
     dTHR;
     register char *s;
 
-    scriptname = find_script(scriptname, dosearch, NULL, 0);
+    /* scriptname will be non-NULL if find_script() returns */
+    scriptname = find_script(scriptname, dosearch, NULL, 1);
 
     if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
        char *s = scriptname + 8;
@@ -1468,7 +1899,7 @@ open_script(char *scriptname, bool dosearch, SV *sv, int *fdscript)
     }
     else
        *fdscript = -1;
-    origfilename = savepv(e_script ? "-e" : scriptname);
+    origfilename = (e_script ? savepv("-e") : scriptname);
     curcop->cop_filegv = gv_fetchfile(origfilename);
     if (strEQ(origfilename,"-"))
        scriptname = "";
@@ -1481,7 +1912,7 @@ open_script(char *scriptname, bool dosearch, SV *sv, int *fdscript)
     }
     else if (preprocess) {
        char *cpp_cfg = CPPSTDIN;
-       SV *cpp = NEWSV(0,0);
+       SV *cpp = newSVpv("",0);
        SV *cmd = NEWSV(0,0);
 
        if (strEQ(cpp_cfg, "cppstdin"))
@@ -1916,44 +2347,23 @@ init_stacks(ARGSproto)
     tmps_ix = -1;
     tmps_max = REASONABLE(128);
 
-    /*
-     * The following stacks almost certainly should be per-interpreter,
-     * but for now they're not.  XXX
-     */
-
-    if (markstack) {
-       markstack_ptr = markstack;
-    } else {
-       New(54,markstack,REASONABLE(32),I32);
-       markstack_ptr = markstack;
-       markstack_max = markstack + REASONABLE(32);
-    }
+    New(54,markstack,REASONABLE(32),I32);
+    markstack_ptr = markstack;
+    markstack_max = markstack + REASONABLE(32);
 
     SET_MARKBASE;
 
-    if (scopestack) {
-       scopestack_ix = 0;
-    } else {
-       New(54,scopestack,REASONABLE(32),I32);
-       scopestack_ix = 0;
-       scopestack_max = REASONABLE(32);
-    }
+    New(54,scopestack,REASONABLE(32),I32);
+    scopestack_ix = 0;
+    scopestack_max = REASONABLE(32);
 
-    if (savestack) {
-       savestack_ix = 0;
-    } else {
-       New(54,savestack,REASONABLE(128),ANY);
-       savestack_ix = 0;
-       savestack_max = REASONABLE(128);
-    }
+    New(54,savestack,REASONABLE(128),ANY);
+    savestack_ix = 0;
+    savestack_max = REASONABLE(128);
 
-    if (retstack) {
-       retstack_ix = 0;
-    } else {
-       New(54,retstack,REASONABLE(16),OP*);
-       retstack_ix = 0;
-       retstack_max = REASONABLE(16);
-    }
+    New(54,retstack,REASONABLE(16),OP*);
+    retstack_ix = 0;
+    retstack_max = REASONABLE(16);
 }
 
 #undef REASONABLE
@@ -1972,6 +2382,10 @@ nuke_stacks(void)
        curstackinfo = p;
     }
     Safefree(tmps_stack);
+    Safefree(markstack);
+    Safefree(scopestack);
+    Safefree(savestack);
+    Safefree(retstack);
     DEBUG( {
        Safefree(debname);
        Safefree(debdelim);
@@ -2199,7 +2613,7 @@ incpush(char *p, int addsubdirs)
        return;
 
     if (addsubdirs) {
-       subdir = NEWSV(55,0);
+       subdir = sv_newmortal();
        if (!archpat_auto) {
            STRLEN len = (sizeof(ARCHNAME) + strlen(patchlevel)
                          + sizeof("//auto"));
@@ -2275,8 +2689,6 @@ incpush(char *p, int addsubdirs)
        /* finally push this lib directory on the end of @INC */
        av_push(GvAVn(incgv), libdir);
     }
-
-    SvREFCNT_dec(subdir);
 }
 
 #ifdef USE_THREADS
@@ -2350,16 +2762,16 @@ call_list(I32 oldscope, AV *paramList)
     line_t oldline = curcop->cop_line;
     STRLEN len;
     dJMPENV;
-    int jmpstat;
+    int ret;
 
     while (AvFILL(paramList) >= 0) {
        CV *cv = (CV*)av_shift(paramList);
 
        SAVEFREESV(cv);
 
-       JMPENV_PUSH(jmpstat);
-       switch (jmpstat) {
-       case JMP_NORMAL: {
+       JMPENV_PUSH(ret);
+       switch (ret) {
+       case 0: {
                SV* atsv = ERRSV;
                PUSHMARK(stack_sp);
                perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
@@ -2378,10 +2790,10 @@ call_list(I32 oldscope, AV *paramList)
                }
            }
            break;
-       case JMP_ABNORMAL:
+       case 1:
            STATUS_ALL_FAILURE;
            /* FALL THROUGH */
-       case JMP_MYEXIT:
+       case 2:
            /* my_exit() was called */
            while (scopestack_ix > oldscope)
                LEAVE;
@@ -2400,7 +2812,7 @@ call_list(I32 oldscope, AV *paramList)
            }
            my_exit_jump();
            /* NOTREACHED */
-       case JMP_EXCEPTION:
+       case 3:
            if (!restartop) {
                PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
                FREETMPS;
@@ -2409,7 +2821,7 @@ call_list(I32 oldscope, AV *paramList)
            JMPENV_POP;
            curcop = &compiling;
            curcop->cop_line = oldline;
-           JMPENV_JUMP(JMP_EXCEPTION);
+           JMPENV_JUMP(3);
        }
        JMPENV_POP;
     }
@@ -2488,14 +2900,18 @@ my_exit_jump(void)
        LEAVE;
     }
 
-    JMPENV_JUMP(JMP_MYEXIT);
+    JMPENV_JUMP(2);
 }
 
 
 #include "XSUB.h"
 
 static I32
-read_e_script(CPERLarg_ int idx, SV *buf_sv, int maxlen)
+#ifdef PERL_OBJECT
+read_e_script(CPerlObj *pPerl, int idx, SV *buf_sv, int maxlen)
+#else
+read_e_script(int idx, SV *buf_sv, int maxlen)
+#endif
 {
     char *p, *nl;
     p  = SvPVX(e_script);
@@ -2508,461 +2924,4 @@ read_e_script(CPERLarg_ int idx, SV *buf_sv, int maxlen)
     return 1;
 }
 
-/******************************************* perl_parse TRYBLOCK branches */
-
-#define TRY_LOCAL(name) ((TRY_PARSE_LOCALS*)locals)->name
-
-static void
-try_parse_normal0(CPERLarg_ void *locals)
-{
-    dTHR;
-    register SV *sv;
-    register char *s;
-    char *scriptname = NULL;
-    VOL bool dosearch = FALSE;
-    char *validarg = "";
-    AV* comppadlist;
-    int fdscript = -1;
-
-    void (*xsinit)() = TRY_LOCAL(xsinit);
-    int argc = TRY_LOCAL(argc);
-    char **argv = TRY_LOCAL(argv);
-    char **env = TRY_LOCAL(env);
-
-    sv_setpvn(linestr,"",0);
-    sv = newSVpv("",0);                /* first used for -I flags */
-    SAVEFREESV(sv);
-    init_main_stash();
-
-    for (argc--,argv++; argc > 0; argc--,argv++) {
-       if (argv[0][0] != '-' || !argv[0][1])
-           break;
-#ifdef DOSUID
-    if (*validarg)
-       validarg = " PHOOEY ";
-    else
-       validarg = argv[0];
-#endif
-       s = argv[0]+1;
-      reswitch:
-       switch (*s) {
-       case ' ':
-       case '0':
-       case 'F':
-       case 'a':
-       case 'c':
-       case 'd':
-       case 'D':
-       case 'h':
-       case 'i':
-       case 'l':
-       case 'M':
-       case 'm':
-       case 'n':
-       case 'p':
-       case 's':
-       case 'u':
-       case 'U':
-       case 'v':
-       case 'w':
-           if (s = moreswitches(s))
-               goto reswitch;
-           break;
-
-       case 'T':
-           tainting = TRUE;
-           s++;
-           goto reswitch;
-
-       case 'e':
-           if (euid != uid || egid != gid)
-               croak("No -e allowed in setuid scripts");
-           if (!e_script) {
-               e_script = newSVpv("",0);
-               filter_add(read_e_script, NULL);
-           }
-           if (*++s)
-               sv_catpv(e_script, s);
-           else if (argv[1]) {
-               sv_catpv(e_script, argv[1]);
-               argc--,argv++;
-           }
-           else
-               croak("No code specified for -e");
-           sv_catpv(e_script, "\n");
-           break;
-
-       case 'I':       /* -I handled both here and in moreswitches() */
-           forbid_setid("-I");
-           if (!*++s && (s=argv[1]) != Nullch) {
-               argc--,argv++;
-           }
-           while (s && isSPACE(*s))
-               ++s;
-           if (s && *s) {
-               char *e, *p;
-               for (e = s; *e && !isSPACE(*e); e++) ;
-               p = savepvn(s, e-s);
-               incpush(p, TRUE);
-               sv_catpv(sv,"-I");
-               sv_catpv(sv,p);
-               sv_catpv(sv," ");
-               Safefree(p);
-           }   /* XXX else croak? */
-           break;
-       case 'P':
-           forbid_setid("-P");
-           preprocess = TRUE;
-           s++;
-           goto reswitch;
-       case 'S':
-           forbid_setid("-S");
-           dosearch = TRUE;
-           s++;
-           goto reswitch;
-       case 'V':
-           if (!preambleav)
-               preambleav = newAV();
-           av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
-           if (*++s != ':')  {
-               Sv = newSVpv("print myconfig();",0);
-#ifdef VMS
-               sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
-#else
-               sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
-#endif
-#if defined(DEBUGGING) || defined(NO_EMBED) || defined(MULTIPLICITY)
-               sv_catpv(Sv,"\"  Compile-time options:");
-#  ifdef DEBUGGING
-               sv_catpv(Sv," DEBUGGING");
-#  endif
-#  ifdef NO_EMBED
-               sv_catpv(Sv," NO_EMBED");
-#  endif
-#  ifdef MULTIPLICITY
-               sv_catpv(Sv," MULTIPLICITY");
-#  endif
-               sv_catpv(Sv,"\\n\",");
-#endif
-#if defined(LOCAL_PATCH_COUNT)
-               if (LOCAL_PATCH_COUNT > 0) {
-                   int i;
-                   sv_catpv(Sv,"\"  Locally applied patches:\\n\",");
-                   for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
-                       if (localpatches[i])
-                           sv_catpvf(Sv,"\"  \\t%s\\n\",",localpatches[i]);
-                   }
-               }
-#endif
-               sv_catpvf(Sv,"\"  Built under %s\\n\"",OSNAME);
-#ifdef __DATE__
-#  ifdef __TIME__
-               sv_catpvf(Sv,",\"  Compiled at %s %s\\n\"",__DATE__,__TIME__);
-#  else
-               sv_catpvf(Sv,",\"  Compiled on %s\\n\"",__DATE__);
-#  endif
-#endif
-               sv_catpv(Sv, "; \
-$\"=\"\\n    \"; \
-@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \
-print \"  \\%ENV:\\n    @env\\n\" if @env; \
-print \"  \\@INC:\\n    @INC\\n\";");
-           }
-           else {
-               Sv = newSVpv("config_vars(qw(",0);
-               sv_catpv(Sv, ++s);
-               sv_catpv(Sv, "))");
-               s += strlen(s);
-           }
-           av_push(preambleav, Sv);
-           scriptname = BIT_BUCKET;    /* don't look for script or read stdin */
-           goto reswitch;
-       case 'x':
-           doextract = TRUE;
-           s++;
-           if (*s)
-               cddir = savepv(s);
-           break;
-       case 0:
-           break;
-       case '-':
-           if (!*++s || isSPACE(*s)) {
-               argc--,argv++;
-               goto switch_end;
-           }
-           /* catch use of gnu style long options */
-           if (strEQ(s, "version")) {
-               s = "v";
-               goto reswitch;
-           }
-           if (strEQ(s, "help")) {
-               s = "h";
-               goto reswitch;
-           }
-           s--;
-           /* FALL THROUGH */
-       default:
-           croak("Unrecognized switch: -%s  (-h will show valid options)",s);
-       }
-    }
-  switch_end:
-
-    if (!tainting && (s = PerlEnv_getenv("PERL5OPT"))) {
-       while (s && *s) {
-           while (isSPACE(*s))
-               s++;
-           if (*s == '-') {
-               s++;
-               if (isSPACE(*s))
-                   continue;
-           }
-           if (!*s)
-               break;
-           if (!strchr("DIMUdmw", *s))
-               croak("Illegal switch in PERL5OPT: -%c", *s);
-           s = moreswitches(s);
-       }
-    }
-
-    if (!scriptname)
-       scriptname = argv[0];
-    if (e_script) {
-       argc++,argv--;
-       scriptname = BIT_BUCKET;        /* don't look for script or read stdin */
-    }
-    else if (scriptname == Nullch) {
-#ifdef MSDOS
-       if ( PerlLIO_isatty(PerlIO_fileno(PerlIO_stdin())) )
-           moreswitches("h");
-#endif
-       scriptname = "-";
-    }
-
-    init_perllib();
-
-    open_script(scriptname,dosearch,sv,&fdscript);
-
-    validate_suid(validarg, scriptname,fdscript);
-
-    if (doextract)
-       find_beginning();
-
-    main_cv = compcv = (CV*)NEWSV(1104,0);
-    sv_upgrade((SV *)compcv, SVt_PVCV);
-    CvUNIQUE_on(compcv);
-
-    comppad = newAV();
-    av_push(comppad, Nullsv);
-    curpad = AvARRAY(comppad);
-    comppad_name = newAV();
-    comppad_name_fill = 0;
-    min_intro_pending = 0;
-    padix = 0;
-#ifdef USE_THREADS
-    av_store(comppad_name, 0, newSVpv("@_", 2));
-    curpad[0] = (SV*)newAV();
-    SvPADMY_on(curpad[0]);     /* XXX Needed? */
-    CvOWNER(compcv) = 0;
-    New(666, CvMUTEXP(compcv), 1, perl_mutex);
-    MUTEX_INIT(CvMUTEXP(compcv));
-#endif /* USE_THREADS */
-
-    comppadlist = newAV();
-    AvREAL_off(comppadlist);
-    av_store(comppadlist, 0, (SV*)comppad_name);
-    av_store(comppadlist, 1, (SV*)comppad);
-    CvPADLIST(compcv) = comppadlist;
-
-    boot_core_UNIVERSAL();
-
-    if (xsinit)
-       (*xsinit)(PERL_OBJECT_THIS);    /* in case linked C routines want magical variables */
-#if defined(VMS) || defined(WIN32) || defined(DJGPP)
-    init_os_extras();
-#endif
-
-    init_predump_symbols();
-    /* init_postdump_symbols not currently designed to be called */
-    /* more than once (ENV isn't cleared first, for example)    */
-    /* But running with -u leaves %ENV & @ARGV undefined!    XXX */
-    if (!do_undump)
-       init_postdump_symbols(argc,argv,env);
-
-    init_lexer();
-
-    /* now parse the script */
-
-    SETERRNO(0,SS$_NORMAL);
-    error_count = 0;
-    if (yyparse() || error_count) {
-       if (minus_c)
-           croak("%s had compilation errors.\n", origfilename);
-       else {
-           croak("Execution of %s aborted due to compilation errors.\n",
-               origfilename);
-       }
-    }
-    curcop->cop_line = 0;
-    curstash = defstash;
-    preprocess = FALSE;
-    if (e_script) {
-       SvREFCNT_dec(e_script);
-       e_script = Nullsv;
-    }
-
-    /* now that script is parsed, we can modify record separator */
-    SvREFCNT_dec(rs);
-    rs = SvREFCNT_inc(nrs);
-    sv_setsv(perl_get_sv("/", TRUE), rs);
-    if (do_undump)
-       my_unexec();
-
-    if (dowarn)
-       gv_check(defstash);
-
-    LEAVE;
-    FREETMPS;
-
-#ifdef MYMALLOC
-    if ((s=PerlEnv_getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
-       dump_mstats("after compilation:");
-#endif
-
-    ENTER;
-    restartop = 0;
-    TRY_LOCAL(ret) = 0;
-}
-
-static void
-try_parse_exception1(CPERLarg_ void *locals)
-{
-    PerlIO_printf(PerlIO_stderr(), no_top_env);
-    TRY_LOCAL(ret) = 1;
-}
 
-static void
-try_parse_myexit0(CPERLarg_ void *locals)
-{
-    dTHR;
-    I32 oldscope = TRY_LOCAL(oldscope);
-    while (scopestack_ix > oldscope)
-       LEAVE;
-    FREETMPS;
-    curstash = defstash;
-    if (endav)
-       call_list(oldscope, endav);
-    TRY_LOCAL(ret) = STATUS_NATIVE_EXPORT;
-}
-
-static void
-try_parse_abnormal0(CPERLarg_ void *locals)
-{
-    STATUS_ALL_FAILURE;
-    try_parse_myexit0(locals);
-}
-
-#undef TRY_LOCAL
-static TRYVTBL PerlParseVtbl = {
-    "perl_parse",
-    try_parse_normal0,         0,
-    try_parse_abnormal0,       0,
-    0,                         try_parse_exception1,
-    try_parse_myexit0,         0,
-};
-
-/******************************************* perl_run TRYBLOCK branches */
-
-#define TRY_LOCAL(name) ((TRY_RUN_LOCALS*)locals)->name
-
-static void
-try_run_normal0(CPERLarg_ void *locals)
-{
-    dTHR;
-    I32 oldscope = TRY_LOCAL(oldscope);
-
-    DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n",
-                    sawampersand ? "Enabling" : "Omitting"));
-
-    if (!restartop) {
-       DEBUG_x(dump_all());
-       DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
-#ifdef USE_THREADS
-       DEBUG_L(PerlIO_printf(Perl_debug_log, "main thread is 0x%lx\n",
-                             (unsigned long) thr));
-#endif /* USE_THREADS */       
-
-       if (minus_c) {
-           PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename);
-           my_exit(0);
-       }
-       if (PERLDB_SINGLE && DBsingle)
-          sv_setiv(DBsingle, 1); 
-       if (initav)
-           call_list(oldscope, initav);
-    }
-
-    /* do it */
-
-    if (restartop) {
-       op = restartop;
-       restartop = 0;
-       CALLRUNOPS();
-    }
-    else if (main_start) {
-       CvDEPTH(main_cv) = 1;
-       op = main_start;
-       CALLRUNOPS();
-    }
-
-    my_exit(0);
-}
-
-static void
-try_run_abnormal0(CPERLarg_ void *locals)
-{
-    dTHR;
-    cxstack_ix = -1;           /* start context stack again */
-    try_run_normal0(locals);
-}
-
-static void
-try_run_exception0(CPERLarg_ void *locals)
-{
-    dSP;
-    if (!restartop) {
-       PerlIO_printf(PerlIO_stderr(), no_restartop);
-       FREETMPS;
-       TRY_LOCAL(ret) = 1;
-    } else {
-       POPSTACK_TO(mainstack);
-       try_run_normal0(locals);
-    }
-}
-
-static void
-try_run_myexit0(CPERLarg_ void *locals)
-{
-    dTHR;
-    I32 oldscope = TRY_LOCAL(oldscope);
-
-    while (scopestack_ix > oldscope)
-       LEAVE;
-    FREETMPS;
-    curstash = defstash;
-    if (endav)
-       call_list(oldscope, endav);
-#ifdef MYMALLOC
-    if (PerlEnv_getenv("PERL_DEBUG_MSTATS"))
-       dump_mstats("after execution:  ");
-#endif
-    TRY_LOCAL(ret) = STATUS_NATIVE_EXPORT;
-}
-
-#undef TRY_LOCAL
-static TRYVTBL PerlRunVtbl = {
-    "perl_run",
-    try_run_normal0,   0,
-    try_run_abnormal0, 0,
-    try_run_exception0,        0,
-    try_run_myexit0,   0
-};