diff options
Diffstat (limited to 'Python/compile.c')
| -rw-r--r-- | Python/compile.c | 236 | 
1 files changed, 176 insertions, 60 deletions
| diff --git a/Python/compile.c b/Python/compile.c index 1e720ea..29a2ade 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -171,7 +171,6 @@ static int compiler_addop(struct compiler *, int);  static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *);  static int compiler_addop_i(struct compiler *, int, Py_ssize_t);  static int compiler_addop_j(struct compiler *, int, basicblock *, int); -static basicblock *compiler_use_new_block(struct compiler *);  static int compiler_error(struct compiler *, const char *);  static int compiler_nameop(struct compiler *, identifier, expr_context_ty); @@ -196,7 +195,7 @@ static int expr_constant(struct compiler *, expr_ty);  static int compiler_with(struct compiler *, stmt_ty, int);  static int compiler_async_with(struct compiler *, stmt_ty, int);  static int compiler_async_for(struct compiler *, stmt_ty); -static int compiler_call_helper(struct compiler *c, Py_ssize_t n, +static int compiler_call_helper(struct compiler *c, int n,                                  asdl_seq *args,                                  asdl_seq *keywords);  static int compiler_try_except(struct compiler *, stmt_ty); @@ -477,9 +476,9 @@ compiler_unit_check(struct compiler_unit *u)  {      basicblock *block;      for (block = u->u_blocks; block != NULL; block = block->b_list) { -        assert((void *)block != (void *)0xcbcbcbcb); -        assert((void *)block != (void *)0xfbfbfbfb); -        assert((void *)block != (void *)0xdbdbdbdb); +        assert((Py_uintptr_t)block != 0xcbcbcbcbU); +        assert((Py_uintptr_t)block != 0xfbfbfbfbU); +        assert((Py_uintptr_t)block != 0xdbdbdbdbU);          if (block->b_instr != NULL) {              assert(block->b_ialloc > 0);              assert(block->b_iused > 0); @@ -523,6 +522,7 @@ compiler_enter_scope(struct compiler *c, identifier name,                       int scope_type, void *key, int lineno)  {      struct compiler_unit *u; +    basicblock *block;      u = (struct compiler_unit *)PyObject_Malloc(sizeof(                                              struct compiler_unit)); @@ -620,8 +620,11 @@ compiler_enter_scope(struct compiler *c, identifier name,      c->u = u;      c->c_nestlevel++; -    if (compiler_use_new_block(c) == NULL) + +    block = compiler_new_block(c); +    if (block == NULL)          return 0; +    c->u->u_curblock = block;      if (u->u_scope_type != COMPILER_SCOPE_MODULE) {          if (!compiler_set_qualname(c)) @@ -731,6 +734,7 @@ compiler_set_qualname(struct compiler *c)      return 1;  } +  /* Allocate a new block and return a pointer to it.     Returns NULL on error.  */ @@ -755,16 +759,6 @@ compiler_new_block(struct compiler *c)  }  static basicblock * -compiler_use_new_block(struct compiler *c) -{ -    basicblock *block = compiler_new_block(c); -    if (block == NULL) -        return NULL; -    c->u->u_curblock = block; -    return block; -} - -static basicblock *  compiler_next_block(struct compiler *c)  {      basicblock *block = compiler_new_block(c); @@ -1066,6 +1060,10 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)              return 1;          case GET_YIELD_FROM_ITER:              return 0; +        case FORMAT_VALUE: +            /* If there's a fmt_spec on the stack, we go from 2->1, +               else 1->1. */ +            return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0;          default:              return PY_INVALID_STACK_EFFECT;      } @@ -1165,10 +1163,14 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg)      struct instr *i;      int off; -    /* Integer arguments are limit to 16-bit. There is an extension for 32-bit -       integer arguments. */ -    assert((-2147483647-1) <= oparg); -    assert(oparg <= 2147483647); +    /* oparg value is unsigned, but a signed C int is usually used to store +       it in the C code (like Python/ceval.c). + +       Limit to 32-bit signed C int (rather than INT_MAX) for portability. + +       The argument of a concrete bytecode instruction is limited to 16-bit. +       EXTENDED_ARG is used for 32-bit arguments. */ +    assert(0 <= oparg && oparg <= 2147483647);      off = compiler_next_instr(c, c->u->u_curblock);      if (off < 0) @@ -1203,22 +1205,12 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)      return 1;  } -/* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle.  (I'd -   like to find better names.)  NEW_BLOCK() creates a new block and sets -   it as the current block.  NEXT_BLOCK() also creates an implicit jump -   from the current block to the new block. -*/ +/* NEXT_BLOCK() creates an implicit jump from the current block +   to the new block. -/* The returns inside these macros make it impossible to decref objects -   created in the local function.  Local objects should use the arena. +   The returns inside this macro make it impossible to decref objects +   created in the local function. Local objects should use the arena.  */ - - -#define NEW_BLOCK(C) { \ -    if (compiler_use_new_block((C)) == NULL) \ -        return 0; \ -} -  #define NEXT_BLOCK(C) { \      if (compiler_next_block((C)) == NULL) \          return 0; \ @@ -1309,7 +1301,11 @@ compiler_isdocstring(stmt_ty s)  {      if (s->kind != Expr_kind)          return 0; -    return s->v.Expr.value->kind == Str_kind; +    if (s->v.Expr.value->kind == Str_kind) +        return 1; +    if (s->v.Expr.value->kind == Constant_kind) +        return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value); +    return 0;  }  /* Compile a sequence of statements, checking for a docstring. */ @@ -1683,8 +1679,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)      st = (stmt_ty)asdl_seq_GET(body, 0);      docstring = compiler_isdocstring(st); -    if (docstring && c->c_optimize < 2) -        first_const = st->v.Expr.value->v.Str.s; +    if (docstring && c->c_optimize < 2) { +        if (st->v.Expr.value->kind == Constant_kind) +            first_const = st->v.Expr.value->v.Constant.value; +        else +            first_const = st->v.Expr.value->v.Str.s; +    }      if (compiler_add_o(c, c->u->u_consts, first_const) < 0)      {          compiler_exit_scope(c);          return 0; @@ -2595,6 +2595,35 @@ compiler_assert(struct compiler *c, stmt_ty s)  }  static int +compiler_visit_stmt_expr(struct compiler *c, expr_ty value) +{ +    if (c->c_interactive && c->c_nestlevel <= 1) { +        VISIT(c, expr, value); +        ADDOP(c, PRINT_EXPR); +        return 1; +    } + +    switch (value->kind) +    { +    case Str_kind: +    case Num_kind: +    case Ellipsis_kind: +    case Bytes_kind: +    case NameConstant_kind: +    case Constant_kind: +        /* ignore constant statement */ +        return 1; + +    default: +        break; +    } + +    VISIT(c, expr, value); +    ADDOP(c, POP_TOP); +    return 1; +} + +static int  compiler_visit_stmt(struct compiler *c, stmt_ty s)  {      Py_ssize_t i, n; @@ -2664,16 +2693,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)      case Nonlocal_kind:          break;      case Expr_kind: -        if (c->c_interactive && c->c_nestlevel <= 1) { -            VISIT(c, expr, s->v.Expr.value); -            ADDOP(c, PRINT_EXPR); -        } -        else if (s->v.Expr.value->kind != Str_kind && -                 s->v.Expr.value->kind != Num_kind) { -            VISIT(c, expr, s->v.Expr.value); -            ADDOP(c, POP_TOP); -        } -        break; +        return compiler_visit_stmt_expr(c, s->v.Expr.value);      case Pass_kind:          break;      case Break_kind: @@ -3077,7 +3097,8 @@ compiler_set(struct compiler *c, expr_ty e)  static int  compiler_dict(struct compiler *c, expr_ty e)  { -    Py_ssize_t i, n, containers, elements; +    Py_ssize_t i, n, elements; +    int containers;      int is_unpacking = 0;      n = asdl_seq_LEN(e->v.Dict.values);      containers = 0; @@ -3169,15 +3190,91 @@ compiler_call(struct compiler *c, expr_ty e)                                  e->v.Call.keywords);  } +static int +compiler_joined_str(struct compiler *c, expr_ty e) +{ +    /* Concatenate parts of a string using ''.join(parts). There are +       probably better ways of doing this. + +       This is used for constructs like "'x=' f'{42}'", which have to +       be evaluated at compile time. */ + +    static PyObject *empty_string; +    static PyObject *join_string; + +    if (!empty_string) { +        empty_string = PyUnicode_FromString(""); +        if (!empty_string) +            return 0; +    } +    if (!join_string) { +        join_string = PyUnicode_FromString("join"); +        if (!join_string) +            return 0; +    } + +    ADDOP_O(c, LOAD_CONST, empty_string, consts); +    ADDOP_NAME(c, LOAD_ATTR, join_string, names); +    VISIT_SEQ(c, expr, e->v.JoinedStr.values); +    ADDOP_I(c, BUILD_LIST, asdl_seq_LEN(e->v.JoinedStr.values)); +    ADDOP_I(c, CALL_FUNCTION, 1); +    return 1; +} + +/* Used to implement f-strings. Format a single value. */ +static int +compiler_formatted_value(struct compiler *c, expr_ty e) +{ +    /* Our oparg encodes 2 pieces of information: the conversion +       character, and whether or not a format_spec was provided. + +       Convert the conversion char to 2 bits: +       None: 000  0x0  FVC_NONE +       !s  : 001  0x1  FVC_STR +       !r  : 010  0x2  FVC_REPR +       !a  : 011  0x3  FVC_ASCII + +       next bit is whether or not we have a format spec: +       yes : 100  0x4 +       no  : 000  0x0 +    */ + +    int oparg; + +    /* Evaluate the expression to be formatted. */ +    VISIT(c, expr, e->v.FormattedValue.value); + +    switch (e->v.FormattedValue.conversion) { +    case 's': oparg = FVC_STR;   break; +    case 'r': oparg = FVC_REPR;  break; +    case 'a': oparg = FVC_ASCII; break; +    case -1:  oparg = FVC_NONE;  break; +    default: +        PyErr_SetString(PyExc_SystemError, +                        "Unrecognized conversion character"); +        return 0; +    } +    if (e->v.FormattedValue.format_spec) { +        /* Evaluate the format spec, and update our opcode arg. */ +        VISIT(c, expr, e->v.FormattedValue.format_spec); +        oparg |= FVS_HAVE_SPEC; +    } + +    /* And push our opcode and oparg */ +    ADDOP_I(c, FORMAT_VALUE, oparg); +    return 1; +} +  /* shared code between compiler_call and compiler_class */  static int  compiler_call_helper(struct compiler *c, -                     Py_ssize_t n, /* Args already pushed */ +                     int n, /* Args already pushed */                       asdl_seq *args,                       asdl_seq *keywords)  {      int code = 0; -    Py_ssize_t nelts, i, nseen, nkw; +    Py_ssize_t nelts, i, nseen; +    int nkw;      /* the number of tuples and dictionaries on the stack */      Py_ssize_t nsubargs = 0, nsubkwargs = 0; @@ -3545,6 +3642,8 @@ expr_constant(struct compiler *c, expr_ty e)      switch (e->kind) {      case Ellipsis_kind:          return 1; +    case Constant_kind: +        return PyObject_IsTrue(e->v.Constant.value);      case Num_kind:          return PyObject_IsTrue(e->v.Num.n);      case Str_kind: @@ -3588,9 +3687,9 @@ expr_constant(struct compiler *c, expr_ty e)         BLOCK     finally:         if an exception was raised: -       exc = copy of (exception, instance, traceback) +           exc = copy of (exception, instance, traceback)         else: -       exc = (None, None, None) +           exc = (None, None, None)         if not (await exit(*exc)):             raise   */ @@ -3832,12 +3931,19 @@ compiler_visit_expr(struct compiler *c, expr_ty e)          return compiler_compare(c, e);      case Call_kind:          return compiler_call(c, e); +    case Constant_kind: +        ADDOP_O(c, LOAD_CONST, e->v.Constant.value, consts); +        break;      case Num_kind:          ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);          break;      case Str_kind:          ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts);          break; +    case JoinedStr_kind: +        return compiler_joined_str(c, e); +    case FormattedValue_kind: +        return compiler_formatted_value(c, e);      case Bytes_kind:          ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts);          break; @@ -4329,7 +4435,6 @@ assemble_lnotab(struct assembler *a, struct instr *i)      d_lineno = i->i_lineno - a->a_lineno;      assert(d_bytecode >= 0); -    assert(d_lineno >= 0);      if(d_bytecode == 0 && d_lineno == 0)          return 1; @@ -4359,9 +4464,21 @@ assemble_lnotab(struct assembler *a, struct instr *i)          d_bytecode -= ncodes * 255;          a->a_lnotab_off += ncodes * 2;      } -    assert(d_bytecode <= 255); -    if (d_lineno > 255) { -        int j, nbytes, ncodes = d_lineno / 255; +    assert(0 <= d_bytecode && d_bytecode <= 255); + +    if (d_lineno < -128 || 127 < d_lineno) { +        int j, nbytes, ncodes, k; +        if (d_lineno < 0) { +            k = -128; +            /* use division on positive numbers */ +            ncodes = (-d_lineno) / 128; +        } +        else { +            k = 127; +            ncodes = d_lineno / 127; +        } +        d_lineno -= ncodes * k; +        assert(ncodes >= 1);          nbytes = a->a_lnotab_off + 2 * ncodes;          len = PyBytes_GET_SIZE(a->a_lnotab);          if (nbytes >= len) { @@ -4379,15 +4496,15 @@ assemble_lnotab(struct assembler *a, struct instr *i)          lnotab = (unsigned char *)                     PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;          *lnotab++ = d_bytecode; -        *lnotab++ = 255; +        *lnotab++ = k;          d_bytecode = 0;          for (j = 1; j < ncodes; j++) {              *lnotab++ = 0; -            *lnotab++ = 255; +            *lnotab++ = k;          } -        d_lineno -= ncodes * 255;          a->a_lnotab_off += ncodes * 2;      } +    assert(-128 <= d_lineno && d_lineno <= 127);      len = PyBytes_GET_SIZE(a->a_lnotab);      if (a->a_lnotab_off + 2 >= len) { @@ -4745,4 +4862,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,  {      return PyAST_CompileEx(mod, filename, flags, -1, arena);  } - | 
