Make eval {} compile directly to OP_ENTERTRY
Rafael Garcia-Suarez [Sun, 20 Dec 2009 10:01:34 +0000 (11:01 +0100)]
This way, it's correctly caught and blocked by Safe, separately
from eval "".

op.c
opcode.h
opcode.pl
toke.c

diff --git a/op.c b/op.c
index 19d7d5e..88a31d3 100644 (file)
--- a/op.c
+++ b/op.c
@@ -3092,6 +3092,7 @@ Perl_newUNOP(pTHX_ I32 type, I32 flags, OP *first)
        || (PL_opargs[type] & OA_CLASS_MASK) == OA_FILESTATOP
        || (PL_opargs[type] & OA_CLASS_MASK) == OA_LOOPEXOP
        || type == OP_SASSIGN
+       || type == OP_ENTERTRY
        || type == OP_NULL );
 
     if (!first)
@@ -6600,8 +6601,6 @@ Perl_ck_eval(pTHX_ OP *o)
            /* establish postfix order */
            enter->op_next = (OP*)enter;
 
-           CHECKOP(OP_ENTERTRY, enter);
-
            o = prepend_elem(OP_LINESEQ, (OP*)enter, (OP*)kid);
            o->op_type = OP_LEAVETRY;
            o->op_ppaddr = PL_ppaddr[OP_LEAVETRY];
index 741d641..0849839 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -1506,7 +1506,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
        MEMBER_TO_FPTR(Perl_ck_svconst),        /* hintseval */
        MEMBER_TO_FPTR(Perl_ck_eval),   /* entereval */
        MEMBER_TO_FPTR(Perl_ck_null),   /* leaveeval */
-       MEMBER_TO_FPTR(Perl_ck_null),   /* entertry */
+       MEMBER_TO_FPTR(Perl_ck_eval),   /* entertry */
        MEMBER_TO_FPTR(Perl_ck_null),   /* leavetry */
        MEMBER_TO_FPTR(Perl_ck_fun),    /* ghbyname */
        MEMBER_TO_FPTR(Perl_ck_fun),    /* ghbyaddr */
@@ -1884,7 +1884,7 @@ EXTCONST U32 PL_opargs[] = {
        0x00000c04,     /* hintseval */
        0x00003640,     /* entereval */
        0x00002200,     /* leaveeval */
-       0x00000600,     /* entertry */
+       0x00001640,     /* entertry */
        0x00000800,     /* leavetry */
        0x00003600,     /* ghbyname */
        0x00022800,     /* ghbyaddr */
index 1b9add7..01db025 100755 (executable)
--- a/opcode.pl
+++ b/opcode.pl
@@ -1068,7 +1068,7 @@ hintseval eval hints              ck_svconst      s$
 entereval      eval "string"           ck_eval         d%      S
 leaveeval      eval "string" exit      ck_null         1       S
 #evalonce      eval constant string    ck_null         d1      S
-entertry       eval {block}            ck_null         |       
+entertry       eval {block}            ck_eval         d%      
 leavetry       eval {block} exit       ck_null         @       
 
 # Get system info.
diff --git a/toke.c b/toke.c
index 2ec5f2d..db9eca3 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -6589,8 +6589,14 @@ Perl_yylex(pTHX)
 
        case KEY_eval:
            s = SKIPSPACE1(s);
-           PL_expect = (*s == '{') ? XTERMBLOCK : XTERM;
-           UNIBRACK(OP_ENTEREVAL);
+           if (*s == '{') { /* block eval */
+               PL_expect = XTERMBLOCK;
+               UNIBRACK(OP_ENTERTRY);
+           }
+           else { /* string eval */
+               PL_expect = XTERM;
+               UNIBRACK(OP_ENTEREVAL);
+           }
 
        case KEY_eof:
            UNI(OP_EOF);