diff options
Diffstat (limited to 'Python/compile.c')
| -rw-r--r-- | Python/compile.c | 1321 | 
1 files changed, 972 insertions, 349 deletions
| diff --git a/Python/compile.c b/Python/compile.c index adc33ac..a8d7fcd 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -29,6 +29,7 @@  #include "code.h"  #include "symtable.h"  #include "opcode.h" +#include "wordcode_helpers.h"  #define DEFAULT_BLOCK_SIZE 16  #define DEFAULT_BLOCKS 8 @@ -43,7 +44,6 @@  struct instr {      unsigned i_jabs : 1;      unsigned i_jrel : 1; -    unsigned i_hasarg : 1;      unsigned char i_opcode;      int i_oparg;      struct basicblock_ *i_target; /* target block (if jump instruction) */ @@ -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); @@ -180,6 +179,7 @@ static int compiler_visit_stmt(struct compiler *, stmt_ty);  static int compiler_visit_keyword(struct compiler *, keyword_ty);  static int compiler_visit_expr(struct compiler *, expr_ty);  static int compiler_augassign(struct compiler *, stmt_ty); +static int compiler_annassign(struct compiler *, stmt_ty);  static int compiler_visit_slice(struct compiler *, slice_ty,                                  expr_context_ty); @@ -196,12 +196,22 @@ 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);  static int compiler_set_qualname(struct compiler *); +static int compiler_sync_comprehension_generator( +                                      struct compiler *c, +                                      asdl_seq *generators, int gen_index, +                                      expr_ty elt, expr_ty val, int type); + +static int compiler_async_comprehension_generator( +                                      struct compiler *c, +                                      asdl_seq *generators, int gen_index, +                                      expr_ty elt, expr_ty val, int type); +  static PyCodeObject *assemble(struct compiler *, int addNone);  static PyObject *__doc__; @@ -477,9 +487,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((uintptr_t)block != 0xcbcbcbcbU); +        assert((uintptr_t)block != 0xfbfbfbfbU); +        assert((uintptr_t)block != 0xdbdbdbdbU);          if (block->b_instr != NULL) {              assert(block->b_ialloc > 0);              assert(block->b_iused > 0); @@ -523,6 +533,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 +631,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 +745,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 +770,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); @@ -810,7 +815,7 @@ compiler_next_instr(struct compiler *c, basicblock *b)          oldsize = b->b_ialloc * sizeof(struct instr);          newsize = oldsize << 1; -        if (oldsize > (PY_SIZE_MAX >> 1)) { +        if (oldsize > (SIZE_MAX >> 1)) {              PyErr_NoMemory();              return -1;          } @@ -939,6 +944,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)              return -1;          case IMPORT_STAR:              return -1; +        case SETUP_ANNOTATIONS: +            return 0;          case YIELD_VALUE:              return 0;          case YIELD_FROM: @@ -976,16 +983,19 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)          case BUILD_TUPLE:          case BUILD_LIST:          case BUILD_SET: +        case BUILD_STRING:              return 1-oparg;          case BUILD_LIST_UNPACK:          case BUILD_TUPLE_UNPACK: +        case BUILD_TUPLE_UNPACK_WITH_CALL:          case BUILD_SET_UNPACK:          case BUILD_MAP_UNPACK: -            return 1 - oparg;          case BUILD_MAP_UNPACK_WITH_CALL: -            return 1 - (oparg & 0xFF); +            return 1 - oparg;          case BUILD_MAP:              return 1 - 2*oparg; +        case BUILD_CONST_KEY_MAP: +            return -oparg;          case LOAD_ATTR:              return 0;          case COMPARE_OP: @@ -1023,22 +1033,20 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)              return -1;          case DELETE_FAST:              return 0; +        case STORE_ANNOTATION: +            return -1;          case RAISE_VARARGS:              return -oparg; -#define NARGS(o) (((o) % 256) + 2*(((o) / 256) % 256))          case CALL_FUNCTION: -            return -NARGS(oparg); -        case CALL_FUNCTION_VAR: +            return -oparg;          case CALL_FUNCTION_KW: -            return -NARGS(oparg)-1; -        case CALL_FUNCTION_VAR_KW: -            return -NARGS(oparg)-2; +            return -oparg-1; +        case CALL_FUNCTION_EX: +            return - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0);          case MAKE_FUNCTION: -            return -1 -NARGS(oparg) - ((oparg >> 16) & 0xffff); -        case MAKE_CLOSURE: -            return -2 - NARGS(oparg) - ((oparg >> 16) & 0xffff); -#undef NARGS +            return -1 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - +                ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0);          case BUILD_SLICE:              if (oparg == 3)                  return -2; @@ -1066,6 +1074,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;      } @@ -1082,13 +1094,14 @@ compiler_addop(struct compiler *c, int opcode)      basicblock *b;      struct instr *i;      int off; +    assert(!HAS_ARG(opcode));      off = compiler_next_instr(c, c->u->u_curblock);      if (off < 0)          return 0;      b = c->u->u_curblock;      i = &b->b_instr[off];      i->i_opcode = opcode; -    i->i_hasarg = 0; +    i->i_oparg = 0;      if (opcode == RETURN_VALUE)          b->b_return = 1;      compiler_set_lineno(c, off); @@ -1165,10 +1178,15 @@ 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 8-bit. +       EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ +    assert(HAS_ARG(opcode)); +    assert(0 <= oparg && oparg <= 2147483647);      off = compiler_next_instr(c, c->u->u_curblock);      if (off < 0) @@ -1176,7 +1194,6 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg)      i = &c->u->u_curblock->b_instr[off];      i->i_opcode = opcode;      i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); -    i->i_hasarg = 1;      compiler_set_lineno(c, off);      return 1;  } @@ -1187,6 +1204,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)      struct instr *i;      int off; +    assert(HAS_ARG(opcode));      assert(b != NULL);      off = compiler_next_instr(c, c->u->u_curblock);      if (off < 0) @@ -1194,7 +1212,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)      i = &c->u->u_curblock->b_instr[off];      i->i_opcode = opcode;      i->i_target = b; -    i->i_hasarg = 1;      if (absolute)          i->i_jabs = 1;      else @@ -1203,22 +1220,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; \ @@ -1241,6 +1248,15 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)          return 0; \  } +/* Same as ADDOP_O, but steals a reference. */ +#define ADDOP_N(C, OP, O, TYPE) { \ +    if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ +        Py_DECREF((O)); \ +        return 0; \ +    } \ +    Py_DECREF((O)); \ +} +  #define ADDOP_NAME(C, OP, O, TYPE) { \      if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \          return 0; \ @@ -1309,10 +1325,110 @@ 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; +} + +static int +is_const(expr_ty e) +{ +    switch (e->kind) { +    case Constant_kind: +    case Num_kind: +    case Str_kind: +    case Bytes_kind: +    case Ellipsis_kind: +    case NameConstant_kind: +        return 1; +    default: +        return 0; +    } +} + +static PyObject * +get_const_value(expr_ty e) +{ +    switch (e->kind) { +    case Constant_kind: +        return e->v.Constant.value; +    case Num_kind: +        return e->v.Num.n; +    case Str_kind: +        return e->v.Str.s; +    case Bytes_kind: +        return e->v.Bytes.s; +    case Ellipsis_kind: +        return Py_Ellipsis; +    case NameConstant_kind: +        return e->v.NameConstant.value; +    default: +        assert(!is_const(e)); +        return NULL; +    } +} + +/* Search if variable annotations are present statically in a block. */ + +static int +find_ann(asdl_seq *stmts) +{ +    int i, j, res = 0; +    stmt_ty st; + +    for (i = 0; i < asdl_seq_LEN(stmts); i++) { +        st = (stmt_ty)asdl_seq_GET(stmts, i); +        switch (st->kind) { +        case AnnAssign_kind: +            return 1; +        case For_kind: +            res = find_ann(st->v.For.body) || +                  find_ann(st->v.For.orelse); +            break; +        case AsyncFor_kind: +            res = find_ann(st->v.AsyncFor.body) || +                  find_ann(st->v.AsyncFor.orelse); +            break; +        case While_kind: +            res = find_ann(st->v.While.body) || +                  find_ann(st->v.While.orelse); +            break; +        case If_kind: +            res = find_ann(st->v.If.body) || +                  find_ann(st->v.If.orelse); +            break; +        case With_kind: +            res = find_ann(st->v.With.body); +            break; +        case AsyncWith_kind: +            res = find_ann(st->v.AsyncWith.body); +            break; +        case Try_kind: +            for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) { +                excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( +                    st->v.Try.handlers, j); +                if (find_ann(handler->v.ExceptHandler.body)) { +                    return 1; +                } +            } +            res = find_ann(st->v.Try.body) || +                  find_ann(st->v.Try.finalbody) || +                  find_ann(st->v.Try.orelse); +            break; +        default: +            res = 0; +        } +        if (res) { +            break; +        } +    } +    return res;  } -/* Compile a sequence of statements, checking for a docstring. */ +/* Compile a sequence of statements, checking for a docstring +   and for annotations. */  static int  compiler_body(struct compiler *c, asdl_seq *stmts) @@ -1320,6 +1436,19 @@ compiler_body(struct compiler *c, asdl_seq *stmts)      int i = 0;      stmt_ty st; +    /* Set current line number to the line number of first statement. +       This way line number for SETUP_ANNOTATIONS will always +       coincide with the line number of first "real" statement in module. +       If body is empy, then lineno will be set later in assemble. */ +    if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && +        !c->u->u_lineno && asdl_seq_LEN(stmts)) { +        st = (stmt_ty)asdl_seq_GET(stmts, 0); +        c->u->u_lineno = st->lineno; +    } +    /* Every annotated class and module should have __annotations__. */ +    if (find_ann(stmts)) { +        ADDOP(c, SETUP_ANNOTATIONS); +    }      if (!asdl_seq_LEN(stmts))          return 1;      st = (stmt_ty)asdl_seq_GET(stmts, 0); @@ -1357,6 +1486,9 @@ compiler_mod(struct compiler *c, mod_ty mod)          }          break;      case Interactive_kind: +        if (find_ann(mod->v.Interactive.body)) { +            ADDOP(c, SETUP_ANNOTATIONS); +        }          c->c_interactive = 1;          VISIT_SEQ_IN_SCOPE(c, stmt,                                  mod->v.Interactive.body); @@ -1426,53 +1558,50 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)  }  static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyObject *qualname) +compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname)  {      Py_ssize_t i, free = PyCode_GetNumFree(co);      if (qualname == NULL)          qualname = co->co_name; -    if (free == 0) { -        ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts); -        ADDOP_O(c, LOAD_CONST, qualname, consts); -        ADDOP_I(c, MAKE_FUNCTION, args); -        return 1; -    } -    for (i = 0; i < free; ++i) { -        /* Bypass com_addop_varname because it will generate -           LOAD_DEREF but LOAD_CLOSURE is needed. -        */ -        PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); -        int arg, reftype; - -        /* Special case: If a class contains a method with a -           free variable that has the same name as a method, -           the name will be considered free *and* local in the -           class.  It should be handled by the closure, as -           well as by the normal name loookup logic. -        */ -        reftype = get_ref_type(c, name); -        if (reftype == CELL) -            arg = compiler_lookup_arg(c->u->u_cellvars, name); -        else /* (reftype == FREE) */ -            arg = compiler_lookup_arg(c->u->u_freevars, name); -        if (arg == -1) { -            fprintf(stderr, -                "lookup %s in %s %d %d\n" -                "freevars of %s: %s\n", -                PyUnicode_AsUTF8(PyObject_Repr(name)), -                PyUnicode_AsUTF8(c->u->u_name), -                reftype, arg, -                PyUnicode_AsUTF8(co->co_name), -                PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); -            Py_FatalError("compiler_make_closure()"); +    if (free) { +        for (i = 0; i < free; ++i) { +            /* Bypass com_addop_varname because it will generate +               LOAD_DEREF but LOAD_CLOSURE is needed. +            */ +            PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); +            int arg, reftype; + +            /* Special case: If a class contains a method with a +               free variable that has the same name as a method, +               the name will be considered free *and* local in the +               class.  It should be handled by the closure, as +               well as by the normal name loookup logic. +            */ +            reftype = get_ref_type(c, name); +            if (reftype == CELL) +                arg = compiler_lookup_arg(c->u->u_cellvars, name); +            else /* (reftype == FREE) */ +                arg = compiler_lookup_arg(c->u->u_freevars, name); +            if (arg == -1) { +                fprintf(stderr, +                    "lookup %s in %s %d %d\n" +                    "freevars of %s: %s\n", +                    PyUnicode_AsUTF8(PyObject_Repr(name)), +                    PyUnicode_AsUTF8(c->u->u_name), +                    reftype, arg, +                    PyUnicode_AsUTF8(co->co_name), +                    PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); +                Py_FatalError("compiler_make_closure()"); +            } +            ADDOP_I(c, LOAD_CLOSURE, arg);          } -        ADDOP_I(c, LOAD_CLOSURE, arg); +        flags |= 0x08; +        ADDOP_I(c, BUILD_TUPLE, free);      } -    ADDOP_I(c, BUILD_TUPLE, free);      ADDOP_O(c, LOAD_CONST, (PyObject*)co, consts);      ADDOP_O(c, LOAD_CONST, qualname, consts); -    ADDOP_I(c, MAKE_CLOSURE, args); +    ADDOP_I(c, MAKE_FUNCTION, flags);      return 1;  } @@ -1494,26 +1623,60 @@ static int  compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,                                asdl_seq *kw_defaults)  { -    /* Return the number of defaults + 1. -       Returns 0 on error. -     */ -    int i, default_count = 0; +    /* Push a dict of keyword-only default values. + +       Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. +       */ +    int i; +    PyObject *keys = NULL; +      for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {          arg_ty arg = asdl_seq_GET(kwonlyargs, i);          expr_ty default_ = asdl_seq_GET(kw_defaults, i);          if (default_) {              PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg); -            if (!mangled) -                return 0; -            ADDOP_O(c, LOAD_CONST, mangled, consts); -            Py_DECREF(mangled); +            if (!mangled) { +                goto error; +            } +            if (keys == NULL) { +                keys = PyList_New(1); +                if (keys == NULL) { +                    Py_DECREF(mangled); +                    return 0; +                } +                PyList_SET_ITEM(keys, 0, mangled); +            } +            else { +                int res = PyList_Append(keys, mangled); +                Py_DECREF(mangled); +                if (res == -1) { +                    goto error; +                } +            }              if (!compiler_visit_expr(c, default_)) { -                return 0; +                goto error;              } -            default_count++;          }      } -    return default_count + 1; +    if (keys != NULL) { +        Py_ssize_t default_count = PyList_GET_SIZE(keys); +        PyObject *keys_tuple = PyList_AsTuple(keys); +        Py_DECREF(keys); +        if (keys_tuple == NULL) { +            return 0; +        } +        ADDOP_N(c, LOAD_CONST, keys_tuple, consts); +        ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); +        assert(default_count > 0); +        return 1; +    } +    else { +        return -1; +    } + +error: +    Py_XDECREF(keys); +    return 0;  }  static int @@ -1556,11 +1719,10 @@ static int  compiler_visit_annotations(struct compiler *c, arguments_ty args,                             expr_ty returns)  { -    /* Push arg annotations and a list of the argument names. Return the # -       of items pushed + 1. The expressions are evaluated out-of-order wrt the -       source code. +    /* Push arg annotation dict. +       The expressions are evaluated out-of-order wrt the source code. -       More than 2^16-1 annotations is a SyntaxError. Returns 0 on error. +       Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.         */      static identifier return_str;      PyObject *names; @@ -1592,32 +1754,20 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,      }      len = PyList_GET_SIZE(names); -    if (len > 65534) { -        /* len must fit in 16 bits, and len is incremented below */ -        PyErr_SetString(PyExc_SyntaxError, -                        "too many annotations"); -        goto error; -    }      if (len) { -        /* convert names to a tuple and place on stack */ -        PyObject *elt; -        Py_ssize_t i; -        PyObject *s = PyTuple_New(len); -        if (!s) -            goto error; -        for (i = 0; i < len; i++) { -            elt = PyList_GET_ITEM(names, i); -            Py_INCREF(elt); -            PyTuple_SET_ITEM(s, i, elt); +        PyObject *keytuple = PyList_AsTuple(names); +        Py_DECREF(names); +        if (keytuple == NULL) { +            return 0;          } -        ADDOP_O(c, LOAD_CONST, s, consts); -        Py_DECREF(s); -        len++; /* include the just-pushed tuple */ +        ADDOP_N(c, LOAD_CONST, keytuple, consts); +        ADDOP_I(c, BUILD_CONST_KEY_MAP, len); +        return 1; +    } +    else { +        Py_DECREF(names); +        return -1;      } -    Py_DECREF(names); - -    /* We just checked that len <= 65535, see above */ -    return Py_SAFE_DOWNCAST(len + 1, Py_ssize_t, int);  error:      Py_DECREF(names); @@ -1625,6 +1775,36 @@ error:  }  static int +compiler_visit_defaults(struct compiler *c, arguments_ty args) +{ +    VISIT_SEQ(c, expr, args->defaults); +    ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); +    return 1; +} + +static Py_ssize_t +compiler_default_arguments(struct compiler *c, arguments_ty args) +{ +    Py_ssize_t funcflags = 0; +    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) { +        if (!compiler_visit_defaults(c, args)) +            return -1; +        funcflags |= 0x01; +    } +    if (args->kwonlyargs) { +        int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, +                                                args->kw_defaults); +        if (res == 0) { +            return -1; +        } +        else if (res > 0) { +            funcflags |= 0x02; +        } +    } +    return funcflags; +} + +static int  compiler_function(struct compiler *c, stmt_ty s, int is_async)  {      PyCodeObject *co; @@ -1635,12 +1815,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)      asdl_seq* decos;      asdl_seq *body;      stmt_ty st; -    Py_ssize_t i, n, arglength; -    int docstring, kw_default_count = 0; -    int num_annotations; +    Py_ssize_t i, n, funcflags; +    int docstring; +    int annotations;      int scope_type; -      if (is_async) {          assert(s->kind == AsyncFunctionDef_kind); @@ -1665,30 +1844,32 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)      if (!compiler_decorators(c, decos))          return 0; -    if (args->defaults) -        VISIT_SEQ(c, expr, args->defaults); -    if (args->kwonlyargs) { -        int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, -                                                args->kw_defaults); -        if (res == 0) -            return 0; -        kw_default_count = res - 1; + +    funcflags = compiler_default_arguments(c, args); +    if (funcflags == -1) { +        return 0;      } -    num_annotations = compiler_visit_annotations(c, args, returns); -    if (num_annotations == 0) + +    annotations = compiler_visit_annotations(c, args, returns); +    if (annotations == 0) {          return 0; -    num_annotations--; -    assert((num_annotations & 0xFFFF) == num_annotations); +    } +    else if (annotations > 0) { +        funcflags |= 0x04; +    } -    if (!compiler_enter_scope(c, name, -                              scope_type, (void *)s, -                              s->lineno)) +    if (!compiler_enter_scope(c, name, scope_type, (void *)s, s->lineno)) {          return 0; +    }      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; @@ -1712,12 +1893,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)          return 0;      } -    arglength = asdl_seq_LEN(args->defaults); -    arglength |= kw_default_count << 8; -    arglength |= num_annotations << 16; -    if (is_async) -        co->co_flags |= CO_COROUTINE; -    compiler_make_closure(c, co, arglength, qualname); +    compiler_make_closure(c, co, funcflags, qualname);      Py_DECREF(qualname);      Py_DECREF(co); @@ -1792,7 +1968,7 @@ compiler_class(struct compiler *c, stmt_ty s)              return 0;          }          if (c->u->u_ste->ste_needs_class_closure) { -            /* return the (empty) __class__ cell */ +            /* store __classcell__ into class namespace */              str = PyUnicode_InternFromString("__class__");              if (str == NULL) {                  compiler_exit_scope(c); @@ -1805,15 +1981,20 @@ compiler_class(struct compiler *c, stmt_ty s)                  return 0;              }              assert(i == 0); -            /* Return the cell where to store __class__ */ +              ADDOP_I(c, LOAD_CLOSURE, i); +            str = PyUnicode_InternFromString("__classcell__"); +            if (!str || !compiler_nameop(c, str, Store)) { +                Py_XDECREF(str); +                compiler_exit_scope(c); +                return 0; +            } +            Py_DECREF(str);          }          else { +            /* This happens when nobody references the cell. */              assert(PyDict_Size(c->u->u_cellvars) == 0); -            /* This happens when nobody references the cell. Return None. */ -            ADDOP_O(c, LOAD_CONST, Py_None, consts);          } -        ADDOP_IN_SCOPE(c, RETURN_VALUE);          /* create the code object */          co = assemble(c, 1);      } @@ -1877,8 +2058,7 @@ compiler_lambda(struct compiler *c, expr_ty e)      PyCodeObject *co;      PyObject *qualname;      static identifier name; -    int kw_default_count = 0; -    Py_ssize_t arglength; +    Py_ssize_t funcflags;      arguments_ty args = e->v.Lambda.args;      assert(e->kind == Lambda_kind); @@ -1888,14 +2068,11 @@ compiler_lambda(struct compiler *c, expr_ty e)              return 0;      } -    if (args->defaults) -        VISIT_SEQ(c, expr, args->defaults); -    if (args->kwonlyargs) { -        int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, -                                                args->kw_defaults); -        if (res == 0) return 0; -        kw_default_count = res - 1; +    funcflags = compiler_default_arguments(c, args); +    if (funcflags == -1) { +        return 0;      } +      if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA,                                (void *)e, e->lineno))          return 0; @@ -1921,9 +2098,7 @@ compiler_lambda(struct compiler *c, expr_ty e)      if (co == NULL)          return 0; -    arglength = asdl_seq_LEN(args->defaults); -    arglength |= kw_default_count << 8; -    compiler_make_closure(c, co, arglength, qualname); +    compiler_make_closure(c, co, funcflags, qualname);      Py_DECREF(qualname);      Py_DECREF(co); @@ -2002,14 +2177,14 @@ compiler_for(struct compiler *c, stmt_ty s)  static int  compiler_async_for(struct compiler *c, stmt_ty s)  { -    static PyObject *stopiter_error = NULL; +    _Py_IDENTIFIER(StopAsyncIteration); +      basicblock *try, *except, *end, *after_try, *try_cleanup,                 *after_loop, *after_loop_else; -    if (stopiter_error == NULL) { -        stopiter_error = PyUnicode_InternFromString("StopAsyncIteration"); -        if (stopiter_error == NULL) -            return 0; +    PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration); +    if (stop_aiter_error == NULL) { +        return 0;      }      try = compiler_new_block(c); @@ -2051,7 +2226,7 @@ compiler_async_for(struct compiler *c, stmt_ty s)      compiler_use_next_block(c, except);      ADDOP(c, DUP_TOP); -    ADDOP_O(c, LOAD_GLOBAL, stopiter_error, names); +    ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names);      ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH);      ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup); @@ -2599,6 +2774,25 @@ 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; +    } + +    if (is_const(value)) { +        /* ignore constant statement */ +        return 1; +    } + +    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; @@ -2617,6 +2811,9 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)          if (c->u->u_ste->ste_type != FunctionBlock)              return compiler_error(c, "'return' outside function");          if (s->v.Return.value) { +            if (c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) +                return compiler_error( +                    c, "'return' with value in async generator");              VISIT(c, expr, s->v.Return.value);          }          else @@ -2638,6 +2835,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)          break;      case AugAssign_kind:          return compiler_augassign(c, s); +    case AnnAssign_kind: +        return compiler_annassign(c, s);      case For_kind:          return compiler_for(c, s);      case While_kind: @@ -2668,16 +2867,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: @@ -3079,9 +3269,53 @@ compiler_set(struct compiler *c, expr_ty e)  }  static int +are_all_items_const(asdl_seq *seq, Py_ssize_t begin, Py_ssize_t end) +{ +    Py_ssize_t i; +    for (i = begin; i < end; i++) { +        expr_ty key = (expr_ty)asdl_seq_GET(seq, i); +        if (key == NULL || !is_const(key)) +            return 0; +    } +    return 1; +} + +static int +compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end) +{ +    Py_ssize_t i, n = end - begin; +    PyObject *keys, *key; +    if (n > 1 && are_all_items_const(e->v.Dict.keys, begin, end)) { +        for (i = begin; i < end; i++) { +            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); +        } +        keys = PyTuple_New(n); +        if (keys == NULL) { +            return 0; +        } +        for (i = begin; i < end; i++) { +            key = get_const_value((expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); +            Py_INCREF(key); +            PyTuple_SET_ITEM(keys, i - begin, key); +        } +        ADDOP_N(c, LOAD_CONST, keys, consts); +        ADDOP_I(c, BUILD_CONST_KEY_MAP, n); +    } +    else { +        for (i = begin; i < end; i++) { +            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); +            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); +        } +        ADDOP_I(c, BUILD_MAP, n); +    } +    return 1; +} + +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; @@ -3089,7 +3323,8 @@ compiler_dict(struct compiler *c, expr_ty e)      for (i = 0; i < n; i++) {          is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;          if (elements == 0xFFFF || (elements && is_unpacking)) { -            ADDOP_I(c, BUILD_MAP, elements); +            if (!compiler_subdict(c, e, i - elements, i)) +                return 0;              containers++;              elements = 0;          } @@ -3098,13 +3333,12 @@ compiler_dict(struct compiler *c, expr_ty e)              containers++;          }          else { -            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); -            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));              elements++;          }      }      if (elements || containers == 0) { -        ADDOP_I(c, BUILD_MAP, elements); +        if (!compiler_subdict(c, e, n - elements, n)) +            return 0;          containers++;      }      /* If there is more than one dict, they need to be merged into a new @@ -3173,28 +3407,124 @@ compiler_call(struct compiler *c, expr_ty e)                                  e->v.Call.keywords);  } +static int +compiler_joined_str(struct compiler *c, expr_ty e) +{ +    VISIT_SEQ(c, expr, e->v.JoinedStr.values); +    ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); +    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; +} + +static int +compiler_subkwargs(struct compiler *c, asdl_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +{ +    Py_ssize_t i, n = end - begin; +    keyword_ty kw; +    PyObject *keys, *key; +    assert(n > 0); +    if (n > 1) { +        for (i = begin; i < end; i++) { +            kw = asdl_seq_GET(keywords, i); +            VISIT(c, expr, kw->value); +        } +        keys = PyTuple_New(n); +        if (keys == NULL) { +            return 0; +        } +        for (i = begin; i < end; i++) { +            key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg; +            Py_INCREF(key); +            PyTuple_SET_ITEM(keys, i - begin, key); +        } +        ADDOP_N(c, LOAD_CONST, keys, consts); +        ADDOP_I(c, BUILD_CONST_KEY_MAP, n); +    } +    else { +        /* a for loop only executes once */ +        for (i = begin; i < end; i++) { +            kw = asdl_seq_GET(keywords, i); +            ADDOP_O(c, LOAD_CONST, kw->arg, consts); +            VISIT(c, expr, kw->value); +        } +        ADDOP_I(c, BUILD_MAP, n); +    } +    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 i, nseen, nelts, nkwelts; +    int mustdictunpack = 0;      /* the number of tuples and dictionaries on the stack */      Py_ssize_t nsubargs = 0, nsubkwargs = 0; -    nkw = 0; -    nseen = 0;  /* the number of positional arguments on the stack */      nelts = asdl_seq_LEN(args); +    nkwelts = asdl_seq_LEN(keywords); + +    for (i = 0; i < nkwelts; i++) { +        keyword_ty kw = asdl_seq_GET(keywords, i); +        if (kw->arg == NULL) { +            mustdictunpack = 1; +            break; +        } +    } + +    nseen = n;  /* the number of positional arguments on the stack */      for (i = 0; i < nelts; i++) {          expr_ty elt = asdl_seq_GET(args, i);          if (elt->kind == Starred_kind) {              /* A star-arg. If we've seen positional arguments, -               pack the positional arguments into a -               tuple. */ +               pack the positional arguments into a tuple. */              if (nseen) {                  ADDOP_I(c, BUILD_TUPLE, nseen);                  nseen = 0; @@ -3203,92 +3533,78 @@ compiler_call_helper(struct compiler *c,              VISIT(c, expr, elt->v.Starred.value);              nsubargs++;          } -        else if (nsubargs) { -            /* We've seen star-args already, so we -               count towards items-to-pack-into-tuple. */ -            VISIT(c, expr, elt); -            nseen++; -        }          else { -            /* Positional arguments before star-arguments -               are left on the stack. */              VISIT(c, expr, elt); -            n++; +            nseen++;          }      } -    if (nseen) { -        /* Pack up any trailing positional arguments. */ -        ADDOP_I(c, BUILD_TUPLE, nseen); -        nsubargs++; -    } -    if (nsubargs) { -        code |= 1; + +    /* Same dance again for keyword arguments */ +    if (nsubargs || mustdictunpack) { +        if (nseen) { +            /* Pack up any trailing positional arguments. */ +            ADDOP_I(c, BUILD_TUPLE, nseen); +            nsubargs++; +        }          if (nsubargs > 1) {              /* If we ended up with more than one stararg, we need                 to concatenate them into a single sequence. */ -            ADDOP_I(c, BUILD_LIST_UNPACK, nsubargs); +            ADDOP_I(c, BUILD_TUPLE_UNPACK_WITH_CALL, nsubargs);          } -    } - -    /* Same dance again for keyword arguments */ -    nseen = 0;  /* the number of keyword arguments on the stack following */ -    nelts = asdl_seq_LEN(keywords); -    for (i = 0; i < nelts; i++) { -        keyword_ty kw = asdl_seq_GET(keywords, i); -        if (kw->arg == NULL) { -            /* A keyword argument unpacking. */ -            if (nseen) { -                ADDOP_I(c, BUILD_MAP, nseen); -                nseen = 0; +        else if (nsubargs == 0) { +            ADDOP_I(c, BUILD_TUPLE, 0); +        } +        nseen = 0;  /* the number of keyword arguments on the stack following */ +        for (i = 0; i < nkwelts; i++) { +            keyword_ty kw = asdl_seq_GET(keywords, i); +            if (kw->arg == NULL) { +                /* A keyword argument unpacking. */ +                if (nseen) { +                    if (!compiler_subkwargs(c, keywords, i - nseen, i)) +                        return 0; +                    nsubkwargs++; +                    nseen = 0; +                } +                VISIT(c, expr, kw->value);                  nsubkwargs++;              } -            VISIT(c, expr, kw->value); -            nsubkwargs++; -        } -        else if (nsubkwargs) { -            /* A keyword argument and we already have a dict. */ -            ADDOP_O(c, LOAD_CONST, kw->arg, consts); -            VISIT(c, expr, kw->value); -            nseen++; +            else { +                nseen++; +            }          } -        else { -            /* keyword argument */ -            VISIT(c, keyword, kw) -            nkw++; +        if (nseen) { +            /* Pack up any trailing keyword arguments. */ +            if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) +                return 0; +            nsubkwargs++;          } -    } -    if (nseen) { -        /* Pack up any trailing keyword arguments. */ -        ADDOP_I(c, BUILD_MAP, nseen); -        nsubkwargs++; -    } -    if (nsubkwargs) { -        code |= 2;          if (nsubkwargs > 1) {              /* Pack it all up */ -            int function_pos = n + (code & 1) + 2 * nkw + 1; -            ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs | (function_pos << 8)); +            ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs);          } +        ADDOP_I(c, CALL_FUNCTION_EX, nsubkwargs > 0); +        return 1;      } -    assert(n < 1<<8); -    assert(nkw < 1<<24); -    n |= nkw << 8; - -    switch (code) { -    case 0: -        ADDOP_I(c, CALL_FUNCTION, n); -        break; -    case 1: -        ADDOP_I(c, CALL_FUNCTION_VAR, n); -        break; -    case 2: -        ADDOP_I(c, CALL_FUNCTION_KW, n); -        break; -    case 3: -        ADDOP_I(c, CALL_FUNCTION_VAR_KW, n); -        break; +    else if (nkwelts) { +        PyObject *names; +        VISIT_SEQ(c, keyword, keywords); +        names = PyTuple_New(nkwelts); +        if (names == NULL) { +            return 0; +        } +        for (i = 0; i < nkwelts; i++) { +            keyword_ty kw = asdl_seq_GET(keywords, i); +            Py_INCREF(kw->arg); +            PyTuple_SET_ITEM(names, i, kw->arg); +        } +        ADDOP_N(c, LOAD_CONST, names, consts); +        ADDOP_I(c, CALL_FUNCTION_KW, n + nelts + nkwelts); +        return 1; +    } +    else { +        ADDOP_I(c, CALL_FUNCTION, n + nelts); +        return 1;      } -    return 1;  } @@ -3307,11 +3623,28 @@ compiler_call_helper(struct compiler *c,      - iterate over the generator sequence instead of using recursion  */ +  static int  compiler_comprehension_generator(struct compiler *c,                                   asdl_seq *generators, int gen_index,                                   expr_ty elt, expr_ty val, int type)  { +    comprehension_ty gen; +    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); +    if (gen->is_async) { +        return compiler_async_comprehension_generator( +            c, generators, gen_index, elt, val, type); +    } else { +        return compiler_sync_comprehension_generator( +            c, generators, gen_index, elt, val, type); +    } +} + +static int +compiler_sync_comprehension_generator(struct compiler *c, +                                      asdl_seq *generators, int gen_index, +                                      expr_ty elt, expr_ty val, int type) +{      /* generate code for the iterator, then each of the ifs,         and then write to the element */ @@ -3398,20 +3731,167 @@ compiler_comprehension_generator(struct compiler *c,  }  static int +compiler_async_comprehension_generator(struct compiler *c, +                                      asdl_seq *generators, int gen_index, +                                      expr_ty elt, expr_ty val, int type) +{ +    _Py_IDENTIFIER(StopAsyncIteration); + +    comprehension_ty gen; +    basicblock *anchor, *skip, *if_cleanup, *try, +               *after_try, *except, *try_cleanup; +    Py_ssize_t i, n; + +    PyObject *stop_aiter_error = _PyUnicode_FromId(&PyId_StopAsyncIteration); +    if (stop_aiter_error == NULL) { +        return 0; +    } + +    try = compiler_new_block(c); +    after_try = compiler_new_block(c); +    try_cleanup = compiler_new_block(c); +    except = compiler_new_block(c); +    skip = compiler_new_block(c); +    if_cleanup = compiler_new_block(c); +    anchor = compiler_new_block(c); + +    if (skip == NULL || if_cleanup == NULL || anchor == NULL || +            try == NULL || after_try == NULL || +            except == NULL || after_try == NULL) { +        return 0; +    } + +    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + +    if (gen_index == 0) { +        /* Receive outermost iter as an implicit argument */ +        c->u->u_argcount = 1; +        ADDOP_I(c, LOAD_FAST, 0); +    } +    else { +        /* Sub-iter - calculate on the fly */ +        VISIT(c, expr, gen->iter); +        ADDOP(c, GET_AITER); +        ADDOP_O(c, LOAD_CONST, Py_None, consts); +        ADDOP(c, YIELD_FROM); +    } + +    compiler_use_next_block(c, try); + + +    ADDOP_JREL(c, SETUP_EXCEPT, except); +    if (!compiler_push_fblock(c, EXCEPT, try)) +        return 0; + +    ADDOP(c, GET_ANEXT); +    ADDOP_O(c, LOAD_CONST, Py_None, consts); +    ADDOP(c, YIELD_FROM); +    VISIT(c, expr, gen->target); +    ADDOP(c, POP_BLOCK); +    compiler_pop_fblock(c, EXCEPT, try); +    ADDOP_JREL(c, JUMP_FORWARD, after_try); + + +    compiler_use_next_block(c, except); +    ADDOP(c, DUP_TOP); +    ADDOP_O(c, LOAD_GLOBAL, stop_aiter_error, names); +    ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); +    ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup); + +    ADDOP(c, POP_TOP); +    ADDOP(c, POP_TOP); +    ADDOP(c, POP_TOP); +    ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */ +    ADDOP_JABS(c, JUMP_ABSOLUTE, anchor); + + +    compiler_use_next_block(c, try_cleanup); +    ADDOP(c, END_FINALLY); + +    compiler_use_next_block(c, after_try); + +    n = asdl_seq_LEN(gen->ifs); +    for (i = 0; i < n; i++) { +        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); +        VISIT(c, expr, e); +        ADDOP_JABS(c, POP_JUMP_IF_FALSE, if_cleanup); +        NEXT_BLOCK(c); +    } + +    if (++gen_index < asdl_seq_LEN(generators)) +        if (!compiler_comprehension_generator(c, +                                              generators, gen_index, +                                              elt, val, type)) +        return 0; + +    /* only append after the last for generator */ +    if (gen_index >= asdl_seq_LEN(generators)) { +        /* comprehension specific code */ +        switch (type) { +        case COMP_GENEXP: +            VISIT(c, expr, elt); +            ADDOP(c, YIELD_VALUE); +            ADDOP(c, POP_TOP); +            break; +        case COMP_LISTCOMP: +            VISIT(c, expr, elt); +            ADDOP_I(c, LIST_APPEND, gen_index + 1); +            break; +        case COMP_SETCOMP: +            VISIT(c, expr, elt); +            ADDOP_I(c, SET_ADD, gen_index + 1); +            break; +        case COMP_DICTCOMP: +            /* With 'd[k] = v', v is evaluated before k, so we do +               the same. */ +            VISIT(c, expr, val); +            VISIT(c, expr, elt); +            ADDOP_I(c, MAP_ADD, gen_index + 1); +            break; +        default: +            return 0; +        } + +        compiler_use_next_block(c, skip); +    } +    compiler_use_next_block(c, if_cleanup); +    ADDOP_JABS(c, JUMP_ABSOLUTE, try); +    compiler_use_next_block(c, anchor); +    ADDOP(c, POP_TOP); + +    return 1; +} + +static int  compiler_comprehension(struct compiler *c, expr_ty e, int type,                         identifier name, asdl_seq *generators, expr_ty elt,                         expr_ty val)  {      PyCodeObject *co = NULL; -    expr_ty outermost_iter; +    comprehension_ty outermost;      PyObject *qualname = NULL; +    int is_async_function = c->u->u_ste->ste_coroutine; +    int is_async_generator = 0; -    outermost_iter = ((comprehension_ty) -                      asdl_seq_GET(generators, 0))->iter; +    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);      if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION,                                (void *)e, e->lineno)) +    {          goto error; +    } + +    is_async_generator = c->u->u_ste->ste_coroutine; + +    if (is_async_generator && !is_async_function) { +        if (e->lineno > c->u->u_lineno) { +            c->u->u_lineno = e->lineno; +            c->u->u_lineno_set = 0; +        } +        compiler_error(c, "asynchronous comprehension outside of " +                          "an asynchronous function"); +        goto error_in_scope; +    }      if (type != COMP_GENEXP) {          int op; @@ -3454,9 +3934,24 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,      Py_DECREF(qualname);      Py_DECREF(co); -    VISIT(c, expr, outermost_iter); -    ADDOP(c, GET_ITER); +    VISIT(c, expr, outermost->iter); + +    if (outermost->is_async) { +        ADDOP(c, GET_AITER); +        ADDOP_O(c, LOAD_CONST, Py_None, consts); +        ADDOP(c, YIELD_FROM); +    } else { +        ADDOP(c, GET_ITER); +    } +      ADDOP_I(c, CALL_FUNCTION, 1); + +    if (is_async_generator && type != COMP_GENEXP) { +        ADDOP(c, GET_AWAITABLE); +        ADDOP_O(c, LOAD_CONST, Py_None, consts); +        ADDOP(c, YIELD_FROM); +    } +      return 1;  error_in_scope:      compiler_exit_scope(c); @@ -3531,7 +4026,6 @@ compiler_dictcomp(struct compiler *c, expr_ty e)  static int  compiler_visit_keyword(struct compiler *c, keyword_ty k)  { -    ADDOP_O(c, LOAD_CONST, k->arg, consts);      VISIT(c, expr, k->value);      return 1;  } @@ -3549,6 +4043,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: @@ -3592,9 +4088,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   */ @@ -3794,8 +4290,6 @@ compiler_visit_expr(struct compiler *c, expr_ty e)      case Yield_kind:          if (c->u->u_ste->ste_type != FunctionBlock)              return compiler_error(c, "'yield' outside function"); -        if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) -            return compiler_error(c, "'yield' inside async function");          if (e->v.Yield.value) {              VISIT(c, expr, e->v.Yield.value);          } @@ -3820,11 +4314,8 @@ compiler_visit_expr(struct compiler *c, expr_ty e)          if (c->u->u_ste->ste_type != FunctionBlock)              return compiler_error(c, "'await' outside function"); -        if (c->u->u_scope_type == COMPILER_SCOPE_COMPREHENSION) -            return compiler_error( -                c, "'await' expressions in comprehensions are not supported"); - -        if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) +        if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && +                c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION)              return compiler_error(c, "'await' outside async function");          VISIT(c, expr, e->v.Await.value); @@ -3836,12 +4327,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; @@ -3976,6 +4474,144 @@ compiler_augassign(struct compiler *c, stmt_ty s)  }  static int +check_ann_expr(struct compiler *c, expr_ty e) +{ +    VISIT(c, expr, e); +    ADDOP(c, POP_TOP); +    return 1; +} + +static int +check_annotation(struct compiler *c, stmt_ty s) +{ +    /* Annotations are only evaluated in a module or class. */ +    if (c->u->u_scope_type == COMPILER_SCOPE_MODULE || +        c->u->u_scope_type == COMPILER_SCOPE_CLASS) { +        return check_ann_expr(c, s->v.AnnAssign.annotation); +    } +    return 1; +} + +static int +check_ann_slice(struct compiler *c, slice_ty sl) +{ +    switch(sl->kind) { +    case Index_kind: +        return check_ann_expr(c, sl->v.Index.value); +    case Slice_kind: +        if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) { +            return 0; +        } +        if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) { +            return 0; +        } +        if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) { +            return 0; +        } +        break; +    default: +        PyErr_SetString(PyExc_SystemError, +                        "unexpected slice kind"); +        return 0; +    } +    return 1; +} + +static int +check_ann_subscr(struct compiler *c, slice_ty sl) +{ +    /* We check that everything in a subscript is defined at runtime. */ +    Py_ssize_t i, n; + +    switch (sl->kind) { +    case Index_kind: +    case Slice_kind: +        if (!check_ann_slice(c, sl)) { +            return 0; +        } +        break; +    case ExtSlice_kind: +        n = asdl_seq_LEN(sl->v.ExtSlice.dims); +        for (i = 0; i < n; i++) { +            slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i); +            switch (subsl->kind) { +            case Index_kind: +            case Slice_kind: +                if (!check_ann_slice(c, subsl)) { +                    return 0; +                } +                break; +            case ExtSlice_kind: +            default: +                PyErr_SetString(PyExc_SystemError, +                                "extended slice invalid in nested slice"); +                return 0; +            } +        } +        break; +    default: +        PyErr_Format(PyExc_SystemError, +                     "invalid subscript kind %d", sl->kind); +        return 0; +    } +    return 1; +} + +static int +compiler_annassign(struct compiler *c, stmt_ty s) +{ +    expr_ty targ = s->v.AnnAssign.target; +    PyObject* mangled; + +    assert(s->kind == AnnAssign_kind); + +    /* We perform the actual assignment first. */ +    if (s->v.AnnAssign.value) { +        VISIT(c, expr, s->v.AnnAssign.value); +        VISIT(c, expr, targ); +    } +    switch (targ->kind) { +    case Name_kind: +        /* If we have a simple name in a module or class, store annotation. */ +        if (s->v.AnnAssign.simple && +            (c->u->u_scope_type == COMPILER_SCOPE_MODULE || +             c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { +            mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); +            if (!mangled) { +                return 0; +            } +            VISIT(c, expr, s->v.AnnAssign.annotation); +            /* ADDOP_N decrefs its argument */ +            ADDOP_N(c, STORE_ANNOTATION, mangled, names); +        } +        break; +    case Attribute_kind: +        if (!s->v.AnnAssign.value && +            !check_ann_expr(c, targ->v.Attribute.value)) { +            return 0; +        } +        break; +    case Subscript_kind: +        if (!s->v.AnnAssign.value && +            (!check_ann_expr(c, targ->v.Subscript.value) || +             !check_ann_subscr(c, targ->v.Subscript.slice))) { +                return 0; +        } +        break; +    default: +        PyErr_Format(PyExc_SystemError, +                     "invalid node type (%d) for annotated assignment", +                     targ->kind); +            return 0; +    } +    /* Annotation is evaluated last. */ +    if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { +        return 0; +    } +    return 1; +} + +static int  compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b)  {      struct fblockinfo *f; @@ -4273,7 +4909,7 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)      a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);      if (!a->a_lnotab)          return 0; -    if ((size_t)nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { +    if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {          PyErr_NoMemory();          return 0;      } @@ -4295,18 +4931,6 @@ assemble_free(struct assembler *a)          PyObject_Free(a->a_postorder);  } -/* Return the size of a basic block in bytes. */ - -static int -instrsize(struct instr *instr) -{ -    if (!instr->i_hasarg) -        return 1;               /* 1 byte for the opcode*/ -    if (instr->i_oparg > 0xffff) -        return 6;               /* 1 (opcode) + 1 (EXTENDED_ARG opcode) + 2 (oparg) + 2(oparg extended) */ -    return 3;                   /* 1 (opcode) + 2 (oparg) */ -} -  static int  blocksize(basicblock *b)  { @@ -4314,7 +4938,7 @@ blocksize(basicblock *b)      int size = 0;      for (i = 0; i < b->b_iused; i++) -        size += instrsize(&b->b_instr[i]); +        size += instrsize(b->b_instr[i].i_oparg);      return size;  } @@ -4329,11 +4953,10 @@ assemble_lnotab(struct assembler *a, struct instr *i)      Py_ssize_t len;      unsigned char *lnotab; -    d_bytecode = a->a_offset - a->a_lineno_off; +    d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT);      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; @@ -4363,9 +4986,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) { @@ -4383,15 +5018,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) { @@ -4423,38 +5058,23 @@ assemble_lnotab(struct assembler *a, struct instr *i)  static int  assemble_emit(struct assembler *a, struct instr *i)  { -    int size, arg = 0, ext = 0; +    int size, arg = 0;      Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); -    char *code; +    _Py_CODEUNIT *code; -    size = instrsize(i); -    if (i->i_hasarg) { -        arg = i->i_oparg; -        ext = arg >> 16; -    } +    arg = i->i_oparg; +    size = instrsize(arg);      if (i->i_lineno && !assemble_lnotab(a, i))          return 0; -    if (a->a_offset + size >= len) { +    if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {          if (len > PY_SSIZE_T_MAX / 2)              return 0;          if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)              return 0;      } -    code = PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; +    code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;      a->a_offset += size; -    if (size == 6) { -        assert(i->i_hasarg); -        *code++ = (char)EXTENDED_ARG; -        *code++ = ext & 0xff; -        *code++ = ext >> 8; -        arg &= 0xffff; -    } -    *code++ = i->i_opcode; -    if (i->i_hasarg) { -        assert(size == 3 || size == 6); -        *code++ = arg & 0xff; -        *code++ = arg >> 8; -    } +    write_op_arg(code, i->i_opcode, arg, size);      return 1;  } @@ -4462,7 +5082,7 @@ static void  assemble_jump_offsets(struct assembler *a, struct compiler *c)  {      basicblock *b; -    int bsize, totsize, extended_arg_count = 0, last_extended_arg_count; +    int bsize, totsize, extended_arg_recompile;      int i;      /* Compute the size of each block and fixup jump args. @@ -4475,27 +5095,27 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)              b->b_offset = totsize;              totsize += bsize;          } -        last_extended_arg_count = extended_arg_count; -        extended_arg_count = 0; +        extended_arg_recompile = 0;          for (b = c->u->u_blocks; b != NULL; b = b->b_list) {              bsize = b->b_offset;              for (i = 0; i < b->b_iused; i++) {                  struct instr *instr = &b->b_instr[i]; +                int isize = instrsize(instr->i_oparg);                  /* Relative jumps are computed relative to                     the instruction pointer after fetching                     the jump instruction.                  */ -                bsize += instrsize(instr); -                if (instr->i_jabs) +                bsize += isize; +                if (instr->i_jabs || instr->i_jrel) {                      instr->i_oparg = instr->i_target->b_offset; -                else if (instr->i_jrel) { -                    int delta = instr->i_target->b_offset - bsize; -                    instr->i_oparg = delta; +                    if (instr->i_jrel) { +                        instr->i_oparg -= bsize; +                    } +                    instr->i_oparg *= sizeof(_Py_CODEUNIT); +                    if (instrsize(instr->i_oparg) != isize) { +                        extended_arg_recompile = 1; +                    }                  } -                else -                    continue; -                if (instr->i_oparg > 0xffff) -                    extended_arg_count++;              }          } @@ -4505,7 +5125,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)          The issue is that in the first loop blocksize() is called          which calls instrsize() which requires i_oparg be set -        appropriately.          There is a bootstrap problem because +        appropriately. There is a bootstrap problem because          i_oparg is calculated in the second loop above.          So we loop until we stop seeing new EXTENDED_ARGs. @@ -4513,7 +5133,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c)          ones in jump instructions.  So this should converge          fairly quickly.      */ -    } while (last_extended_arg_count != extended_arg_count); +    } while (extended_arg_recompile);  }  static PyObject * @@ -4549,8 +5169,12 @@ compute_code_flags(struct compiler *c)          flags |= CO_NEWLOCALS | CO_OPTIMIZED;          if (ste->ste_nested)              flags |= CO_NESTED; -        if (ste->ste_generator) +        if (ste->ste_generator && !ste->ste_coroutine)              flags |= CO_GENERATOR; +        if (!ste->ste_generator && ste->ste_coroutine) +            flags |= CO_COROUTINE; +        if (ste->ste_generator && ste->ste_coroutine) +            flags |= CO_ASYNC_GENERATOR;          if (ste->ste_varargs)              flags |= CO_VARARGS;          if (ste->ste_varkeywords) @@ -4659,9 +5283,9 @@ dump_instr(const struct instr *i)      char arg[128];      *arg = '\0'; -    if (i->i_hasarg) +    if (HAS_ARG(i->i_opcode)) {          sprintf(arg, "arg: %d ", i->i_oparg); - +    }      fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",                      i->i_lineno, i->i_opcode, arg, jabs, jrel);  } @@ -4711,7 +5335,7 @@ assemble(struct compiler *c, int addNone)      /* Set firstlineno if it wasn't explicitly set. */      if (!c->u->u_firstlineno) { -        if (entryblock && entryblock->b_instr) +        if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno)              c->u->u_firstlineno = entryblock->b_instr->i_lineno;          else              c->u->u_firstlineno = 1; @@ -4733,7 +5357,7 @@ assemble(struct compiler *c, int addNone)      if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)          goto error; -    if (_PyBytes_Resize(&a.a_bytecode, a.a_offset) < 0) +    if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0)          goto error;      co = makecode(c, &a); @@ -4749,4 +5373,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,  {      return PyAST_CompileEx(mod, filename, flags, -1, arena);  } - | 
