diff options
Diffstat (limited to 'Python/peephole.c')
| -rw-r--r-- | Python/peephole.c | 44 | 
1 files changed, 33 insertions, 11 deletions
| diff --git a/Python/peephole.c b/Python/peephole.c index c27878c..359eda8 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -4,10 +4,8 @@  #include "Python-ast.h"  #include "node.h" -#include "pyarena.h"  #include "ast.h"  #include "code.h" -#include "compile.h"  #include "symtable.h"  #include "opcode.h" @@ -31,7 +29,8 @@     new constant (c1, c2, ... cn) can be appended.     Called with codestr pointing to the first LOAD_CONST.     Bails out with no change if one or more of the LOAD_CONSTs is missing. -   Also works for BUILD_LIST when followed by an "in" or "not in" test. +   Also works for BUILD_LIST and BUILT_SET when followed by an "in" or "not in" +   test; for BUILD_SET it assembles a frozenset rather than a tuple.  */  static int  tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts) @@ -41,7 +40,7 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)      /* Pre-conditions */      assert(PyList_CheckExact(consts)); -    assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST); +    assert(codestr[n*3] == BUILD_TUPLE || codestr[n*3] == BUILD_LIST || codestr[n*3] == BUILD_SET);      assert(GETARG(codestr, (n*3)) == n);      for (i=0 ; i<n ; i++)          assert(codestr[i*3] == LOAD_CONST); @@ -59,6 +58,16 @@ tuple_of_constants(unsigned char *codestr, Py_ssize_t n, PyObject *consts)          PyTuple_SET_ITEM(newconst, i, constant);      } +    /* If it's a BUILD_SET, use the PyTuple we just built to create a +      PyFrozenSet, and use that as the constant instead: */ +    if (codestr[n*3] == BUILD_SET) { +        PyObject *tuple = newconst; +        newconst = PyFrozenSet_New(tuple); +        Py_DECREF(tuple); +        if (newconst == NULL) +            return 0; +    } +      /* Append folded constant onto consts */      if (PyList_Append(consts, newconst)) {          Py_DECREF(newconst); @@ -166,13 +175,16 @@ fold_binops_on_constants(unsigned char *codestr, PyObject *consts)              return 0;      }      if (newconst == NULL) { -        PyErr_Clear(); +        if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) +            PyErr_Clear();          return 0;      }      size = PyObject_Size(newconst); -    if (size == -1) +    if (size == -1) { +        if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) +            return 0;          PyErr_Clear(); -    else if (size > 20) { +    } else if (size > 20) {          Py_DECREF(newconst);          return 0;      } @@ -215,6 +227,9 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)          case UNARY_INVERT:              newconst = PyNumber_Invert(v);              break; +        case UNARY_POSITIVE: +            newconst = PyNumber_Positive(v); +            break;          default:              /* Called with an unknown opcode */              PyErr_Format(PyExc_SystemError, @@ -223,7 +238,8 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts)              return 0;      }      if (newconst == NULL) { -        PyErr_Clear(); +        if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) +            PyErr_Clear();          return 0;      } @@ -269,6 +285,7 @@ markblocks(unsigned char *code, Py_ssize_t len)              case SETUP_LOOP:              case SETUP_EXCEPT:              case SETUP_FINALLY: +            case SETUP_WITH:                  j = GETJUMPTGT(code, i);                  blocks[j] = 1;                  break; @@ -450,20 +467,21 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,                  cumlc = 0;                  break; -                /* Try to fold tuples of constants (includes a case for lists +                /* Try to fold tuples of constants (includes a case for lists and sets                     which are only used for "in" and "not in" tests).                     Skip over BUILD_SEQN 1 UNPACK_SEQN 1.                     Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.                     Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */              case BUILD_TUPLE:              case BUILD_LIST: +            case BUILD_SET:                  j = GETARG(codestr, i);                  h = i - 3 * j;                  if (h >= 0  &&                      j <= lastlc                  &&                      ((opcode == BUILD_TUPLE &&                        ISBASICBLOCK(blocks, h, 3*(j+1))) || -                     (opcode == BUILD_LIST && +                     ((opcode == BUILD_LIST || opcode == BUILD_SET) &&                        codestr[i+3]==COMPARE_OP &&                        ISBASICBLOCK(blocks, h, 3*(j+2)) &&                        (GETARG(codestr,i+3)==6 || @@ -475,7 +493,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,                  }                  if (codestr[i+3] != UNPACK_SEQUENCE  ||                      !ISBASICBLOCK(blocks,i,6) || -                    j != GETARG(codestr, i+3)) +                    j != GETARG(codestr, i+3) || +                    opcode == BUILD_SET)                      continue;                  if (j == 1) {                      memset(codestr+i, NOP, 6); @@ -517,6 +536,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,                     LOAD_CONST c1  UNARY_OP -->                  LOAD_CONST unary_op(c) */              case UNARY_NEGATIVE:              case UNARY_INVERT: +            case UNARY_POSITIVE:                  if (lastlc >= 1                  &&                      ISBASICBLOCK(blocks, i-3, 4)  &&                      fold_unaryops_on_constants(&codestr[i-3], consts))                  { @@ -584,6 +604,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,              case SETUP_LOOP:              case SETUP_EXCEPT:              case SETUP_FINALLY: +            case SETUP_WITH:                  tgt = GETJUMPTGT(codestr, i);                  /* Replace JUMP_* to a RETURN into just a RETURN */                  if (UNCONDITIONAL_JUMP(opcode) && @@ -666,6 +687,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,              case SETUP_LOOP:              case SETUP_EXCEPT:              case SETUP_FINALLY: +            case SETUP_WITH:                  j = addrmap[GETARG(codestr, i) + i + 3] - addrmap[i] - 3;                  SETARG(codestr, i, j);                  break; | 
