diff options
Diffstat (limited to 'Python/symtable.c')
| -rw-r--r-- | Python/symtable.c | 185 | 
1 files changed, 72 insertions, 113 deletions
| diff --git a/Python/symtable.c b/Python/symtable.c index 1ec51f7..b622835 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -19,10 +19,6 @@  #define IMPORT_STAR_WARNING "import * only allowed at module level" -#define RETURN_VAL_IN_GENERATOR \ -    "'return' with argument inside generator" - -  static PySTEntryObject *  ste_new(struct symtable *st, identifier name, _Py_block_ty block,          void *key, int lineno, int col_offset) @@ -185,6 +181,7 @@ static int symtable_visit_params(struct symtable *st, asdl_seq *args);  static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args);  static int symtable_implicit_arg(struct symtable *st, int pos);  static int symtable_visit_annotations(struct symtable *st, stmt_ty s); +static int symtable_visit_withitem(struct symtable *st, withitem_ty item);  static identifier top = NULL, lambda = NULL, genexpr = NULL, @@ -224,10 +221,17 @@ symtable_new(void)  struct symtable *  PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)  { -    struct symtable *st = symtable_new(); +    struct symtable *st;      asdl_seq *seq;      int i; +    if (__class__ == NULL) { +        __class__ = PyUnicode_InternFromString("@__class__"); +        if (__class__ == NULL) +            return NULL; +    } + +    st = symtable_new();      if (st == NULL)          return st;      st->st_filename = filename; @@ -743,14 +747,12 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,      }      else {          /* Special-case __class__ */ -        if (!GET_IDENTIFIER(__class__)) -            goto error;          assert(PySet_Contains(local, __class__) == 1);          if (PySet_Add(newbound, __class__) < 0)              goto error;      } -    /* Recursively call analyze_block() on each child block. +    /* Recursively call analyze_child_block() on each child block.         newbound, newglobal now contain the names visible in         nested blocks.  The free variables in the children will @@ -782,7 +784,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,                                                           NULL))          goto error;      else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree, -                                                           "__class__")) +                                                           "@__class__"))          goto error;      /* Records the results of the analysis in the symbol table entry */      if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, @@ -893,18 +895,15 @@ symtable_warn(struct symtable *st, char *msg, int lineno)  static int  symtable_exit_block(struct symtable *st, void *ast)  { -    Py_ssize_t end; - -    Py_CLEAR(st->st_cur); -    end = PyList_GET_SIZE(st->st_stack) - 1; -    if (end >= 0) { -        st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, -                                                        end); -        if (st->st_cur == NULL) -            return 0; -        Py_INCREF(st->st_cur); -        if (PySequence_DelItem(st->st_stack, end) < 0) +    Py_ssize_t size; + +    st->st_cur = NULL; +    size = PyList_GET_SIZE(st->st_stack); +    if (size) { +        if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0)              return 0; +        if (--size) +            st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, size - 1);      }      return 1;  } @@ -913,23 +912,23 @@ static int  symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block,                       void *ast, int lineno, int col_offset)  { -    PySTEntryObject *prev = NULL; +    PySTEntryObject *prev = NULL, *ste; -    if (st->st_cur) { -        prev = st->st_cur; -        if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) { -            return 0; -        } -        Py_DECREF(st->st_cur); -    } -    st->st_cur = ste_new(st, name, block, ast, lineno, col_offset); -    if (st->st_cur == NULL) +    ste = ste_new(st, name, block, ast, lineno, col_offset); +    if (ste == NULL)          return 0; +    if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) { +        Py_DECREF(ste); +        return 0; +    } +    prev = st->st_cur; +    /* The entry is owned by the stack. Borrow it for st_cur. */ +    Py_DECREF(ste); +    st->st_cur = ste;      if (block == ModuleBlock)          st->st_global = st->st_cur->ste_symbols;      if (prev) { -        if (PyList_Append(prev->ste_children, -                          (PyObject *)st->st_cur) < 0) { +        if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) {              return 0;          }      } @@ -1023,12 +1022,6 @@ error:      if (!symtable_visit_ ## TYPE((ST), (V))) \          return 0; -#define VISIT_IN_BLOCK(ST, TYPE, V, S) \ -    if (!symtable_visit_ ## TYPE((ST), (V))) { \ -        symtable_exit_block((ST), (S)); \ -        return 0; \ -    } -  #define VISIT_SEQ(ST, TYPE, SEQ) { \      int i; \      asdl_seq *seq = (SEQ); /* avoid variable capture */ \ @@ -1039,18 +1032,6 @@ error:      } \  } -#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \ -    int i; \ -    asdl_seq *seq = (SEQ); /* avoid variable capture */ \ -    for (i = 0; i < asdl_seq_LEN(seq); i++) { \ -        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ -        if (!symtable_visit_ ## TYPE((ST), elt)) { \ -            symtable_exit_block((ST), (S)); \ -            return 0; \ -        } \ -    } \ -} -  #define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \      int i; \      asdl_seq *seq = (SEQ); /* avoid variable capture */ \ @@ -1061,18 +1042,6 @@ error:      } \  } -#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \ -    int i; \ -    asdl_seq *seq = (SEQ); /* avoid variable capture */ \ -    for (i = (START); i < asdl_seq_LEN(seq); i++) { \ -        TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ -        if (!symtable_visit_ ## TYPE((ST), elt)) { \ -            symtable_exit_block((ST), (S)); \ -            return 0; \ -        } \ -    } \ -} -  #define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \      int i = 0; \      asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \ @@ -1122,8 +1091,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)                                    FunctionBlock, (void *)s, s->lineno,                                    s->col_offset))              return 0; -        VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s); -        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s); +        VISIT(st, arguments, s->v.FunctionDef.args); +        VISIT_SEQ(st, stmt, s->v.FunctionDef.body);          if (!symtable_exit_block(st, s))              return 0;          break; @@ -1142,8 +1111,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)          if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,                                    (void *)s, s->lineno, s->col_offset))              return 0; -        if (!GET_IDENTIFIER(__class__) || -            !symtable_add_def(st, __class__, DEF_LOCAL) || +        if (!symtable_add_def(st, __class__, DEF_LOCAL) ||              !GET_IDENTIFIER(__locals__) ||              !symtable_add_def(st, __locals__, DEF_PARAM)) {              symtable_exit_block(st, s); @@ -1151,7 +1119,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)          }          tmp = st->st_private;          st->st_private = s->v.ClassDef.name; -        VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s); +        VISIT_SEQ(st, stmt, s->v.ClassDef.body);          st->st_private = tmp;          if (!symtable_exit_block(st, s))              return 0; @@ -1161,14 +1129,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)          if (s->v.Return.value) {              VISIT(st, expr, s->v.Return.value);              st->st_cur->ste_returns_value = 1; -            if (st->st_cur->ste_generator) { -                PyErr_SetString(PyExc_SyntaxError, -                    RETURN_VAL_IN_GENERATOR); -                PyErr_SyntaxLocationEx(st->st_filename, -                                       s->lineno, -                                       s->col_offset); -                return 0; -            }          }          break;      case Delete_kind: @@ -1205,19 +1165,16 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)      case Raise_kind:          if (s->v.Raise.exc) {              VISIT(st, expr, s->v.Raise.exc); -        if (s->v.Raise.cause) { -        VISIT(st, expr, s->v.Raise.cause); -        } +            if (s->v.Raise.cause) { +                VISIT(st, expr, s->v.Raise.cause); +            }          }          break; -    case TryExcept_kind: -        VISIT_SEQ(st, stmt, s->v.TryExcept.body); -        VISIT_SEQ(st, stmt, s->v.TryExcept.orelse); -        VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers); -        break; -    case TryFinally_kind: -        VISIT_SEQ(st, stmt, s->v.TryFinally.body); -        VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody); +    case Try_kind: +        VISIT_SEQ(st, stmt, s->v.Try.body); +        VISIT_SEQ(st, stmt, s->v.Try.orelse); +        VISIT_SEQ(st, excepthandler, s->v.Try.handlers); +        VISIT_SEQ(st, stmt, s->v.Try.finalbody);          break;      case Assert_kind:          VISIT(st, expr, s->v.Assert.test); @@ -1305,10 +1262,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)          /* nothing to do here */          break;      case With_kind: -        VISIT(st, expr, s->v.With.context_expr); -        if (s->v.With.optional_vars) { -            VISIT(st, expr, s->v.With.optional_vars); -        } +        VISIT_SEQ(st, withitem, s->v.With.items);          VISIT_SEQ(st, stmt, s->v.With.body);          break;      } @@ -1341,8 +1295,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)                                    FunctionBlock, (void *)e, e->lineno,                                    e->col_offset))              return 0; -        VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); -        VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); +        VISIT(st, arguments, e->v.Lambda.args); +        VISIT(st, expr, e->v.Lambda.body);          if (!symtable_exit_block(st, (void *)e))              return 0;          break; @@ -1376,17 +1330,14 @@ symtable_visit_expr(struct symtable *st, expr_ty e)              return 0;          break;      case Yield_kind: -        if (e->v.Yield.value) -            VISIT(st, expr, e->v.Yield.value); +    case YieldFrom_kind: { +        expr_ty value; +        value = (e->kind == YieldFrom_kind) ? e->v.YieldFrom.value : e->v.Yield.value; +        if (value) +            VISIT(st, expr, value);          st->st_cur->ste_generator = 1; -        if (st->st_cur->ste_returns_value) { -            PyErr_SetString(PyExc_SyntaxError, -                RETURN_VAL_IN_GENERATOR); -            PyErr_SyntaxLocationEx(st->st_filename, -                                   e->lineno, e->col_offset); -            return 0; -        }          break; +    }      case Compare_kind:          VISIT(st, expr, e->v.Compare.left);          VISIT_SEQ(st, expr, e->v.Compare.comparators); @@ -1425,8 +1376,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)          if (e->v.Name.ctx == Load &&              st->st_cur->ste_type == FunctionBlock &&              !PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) { -            if (!GET_IDENTIFIER(__class__) || -                !symtable_add_def(st, __class__, USE)) +            if (!symtable_add_def(st, __class__, USE))                  return 0;          }          break; @@ -1543,6 +1493,16 @@ symtable_visit_excepthandler(struct symtable *st, excepthandler_ty eh)      return 1;  } +static int +symtable_visit_withitem(struct symtable *st, withitem_ty item) +{ +    VISIT(st, expr, item->context_expr); +    if (item->optional_vars) { +        VISIT(st, expr, item->optional_vars); +    } +    return 1; +} +  static int  symtable_visit_alias(struct symtable *st, alias_ty a) @@ -1553,10 +1513,10 @@ symtable_visit_alias(struct symtable *st, alias_ty a)      */      PyObject *store_name;      PyObject *name = (a->asname == NULL) ? a->name : a->asname; -    const Py_UNICODE *base = PyUnicode_AS_UNICODE(name); -    Py_UNICODE *dot = Py_UNICODE_strchr(base, '.'); -    if (dot) { -        store_name = PyUnicode_FromUnicode(base, dot - base); +    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, +                                        PyUnicode_GET_LENGTH(name), 1); +    if (dot != -1) { +        store_name = PyUnicode_Substring(name, 0, dot);          if (!store_name)              return 0;      } @@ -1653,13 +1613,12 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e,          symtable_exit_block(st, (void *)e);          return 0;      } -    VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e); -    VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e); -    VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, -                            generators, 1, (void*)e); +    VISIT(st, expr, outermost->target); +    VISIT_SEQ(st, expr, outermost->ifs); +    VISIT_SEQ_TAIL(st, comprehension, generators, 1);      if (value) -        VISIT_IN_BLOCK(st, expr, value, (void*)e); -    VISIT_IN_BLOCK(st, expr, elt, (void*)e); +        VISIT(st, expr, value); +    VISIT(st, expr, elt);      return symtable_exit_block(st, (void *)e);  } | 
