diff options
Diffstat (limited to 'Python/compile.c')
| -rw-r--r-- | Python/compile.c | 190 | 
1 files changed, 126 insertions, 64 deletions
| diff --git a/Python/compile.c b/Python/compile.c index 6d66255..160c6fc 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -149,8 +149,7 @@ handled by the symbol analysis pass.  */  struct compiler { -    const char *c_filename; -    PyObject *c_filename_obj; +    PyObject *c_filename;      struct symtable *c_st;      PyFutureFeatures *c_future; /* pointer to module's __future__ */      PyCompilerFlags *c_flags; @@ -288,8 +287,8 @@ compiler_init(struct compiler *c)  }  PyCodeObject * -PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, -                int optimize, PyArena *arena) +PyAST_CompileObject(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, +                   int optimize, PyArena *arena)  {      struct compiler c;      PyCodeObject *co = NULL; @@ -304,12 +303,10 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,      if (!compiler_init(&c))          return NULL; +    Py_INCREF(filename);      c.c_filename = filename; -    c.c_filename_obj = PyUnicode_DecodeFSDefault(filename); -    if (!c.c_filename_obj) -        goto finally;      c.c_arena = arena; -    c.c_future = PyFuture_FromAST(mod, filename); +    c.c_future = PyFuture_FromASTObject(mod, filename);      if (c.c_future == NULL)          goto finally;      if (!flags) { @@ -323,7 +320,7 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,      c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;      c.c_nestlevel = 0; -    c.c_st = PySymtable_Build(mod, filename, c.c_future); +    c.c_st = PySymtable_BuildObject(mod, filename, c.c_future);      if (c.c_st == NULL) {          if (!PyErr_Occurred())              PyErr_SetString(PyExc_SystemError, "no symtable"); @@ -339,6 +336,21 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,  }  PyCodeObject * +PyAST_CompileEx(mod_ty mod, const char *filename_str, PyCompilerFlags *flags, +                int optimize, PyArena *arena) +{ +    PyObject *filename; +    PyCodeObject *co; +    filename = PyUnicode_DecodeFSDefault(filename_str); +    if (filename == NULL) +        return NULL; +    co = PyAST_CompileObject(mod, filename, flags, optimize, arena); +    Py_DECREF(filename); +    return co; + +} + +PyCodeObject *  PyNode_Compile(struct _node *n, const char *filename)  {      PyCodeObject *co = NULL; @@ -360,8 +372,7 @@ compiler_free(struct compiler *c)          PySymtable_Free(c->c_st);      if (c->c_future)          PyObject_Free(c->c_future); -    if (c->c_filename_obj) -        Py_DECREF(c->c_filename_obj); +    Py_XDECREF(c->c_filename);      Py_DECREF(c->c_stack);  } @@ -535,6 +546,37 @@ compiler_enter_scope(struct compiler *c, identifier name,          compiler_unit_free(u);          return 0;      } +    if (u->u_ste->ste_needs_class_closure) { +        /* Cook up a implicit __class__ cell. */ +        _Py_IDENTIFIER(__class__); +        PyObject *tuple, *name, *zero; +        int res; +        assert(u->u_scope_type == COMPILER_SCOPE_CLASS); +        assert(PyDict_Size(u->u_cellvars) == 0); +        name = _PyUnicode_FromId(&PyId___class__); +        if (!name) { +            compiler_unit_free(u); +            return 0; +        } +        tuple = PyTuple_Pack(2, name, Py_TYPE(name)); +        if (!tuple) { +            compiler_unit_free(u); +            return 0; +        } +        zero = PyLong_FromLong(0); +        if (!zero) { +            Py_DECREF(tuple); +            compiler_unit_free(u); +            return 0; +        } +        res = PyDict_SetItem(u->u_cellvars, tuple, zero); +        Py_DECREF(tuple); +        Py_DECREF(zero); +        if (res < 0) { +            compiler_unit_free(u); +            return 0; +        } +    }      u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,                                 PyDict_Size(u->u_cellvars)); @@ -862,8 +904,6 @@ opcode_stack_effect(int opcode, int oparg)              return 7;          case WITH_CLEANUP:              return -1; /* XXX Sometimes more */ -        case STORE_LOCALS: -            return -1;          case RETURN_VALUE:              return -1;          case IMPORT_STAR: @@ -970,6 +1010,7 @@ opcode_stack_effect(int opcode, int oparg)          case LOAD_CLOSURE:              return 1;          case LOAD_DEREF: +        case LOAD_CLASSDEREF:              return 1;          case STORE_DEREF:              return -1; @@ -1330,16 +1371,19 @@ compiler_mod(struct compiler *c, mod_ty mod)  static int  get_ref_type(struct compiler *c, PyObject *name)  { -    int scope = PyST_GetScope(c->u->u_ste, name); +    int scope; +    if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && +        !PyUnicode_CompareWithASCIIString(name, "__class__")) +        return CELL; +    scope = PyST_GetScope(c->u->u_ste, name);      if (scope == 0) {          char buf[350];          PyOS_snprintf(buf, sizeof(buf), -                      "unknown scope for %.100s in %.100s(%s) in %s\n" +                      "unknown scope for %.100s in %.100s(%s)\n"                        "symbols: %s\nlocals: %s\nglobals: %s",                        PyBytes_AS_STRING(name),                        PyBytes_AS_STRING(c->u->u_name),                        PyObject_REPR(c->u->u_ste->ste_id), -                      c->c_filename,                        PyObject_REPR(c->u->u_ste->ste_symbols),                        PyObject_REPR(c->u->u_varnames),                        PyObject_REPR(c->u->u_names) @@ -1501,15 +1545,15 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,      if (compiler_visit_argannotations(c, args->args, names))          goto error; -    if (args->varargannotation && -        compiler_visit_argannotation(c, args->vararg, -                                     args->varargannotation, names)) +    if (args->vararg && args->vararg->annotation && +        compiler_visit_argannotation(c, args->vararg->arg, +                                     args->vararg->annotation, names))          goto error;      if (compiler_visit_argannotations(c, args->kwonlyargs, names))          goto error; -    if (args->kwargannotation && -        compiler_visit_argannotation(c, args->kwarg, -                                     args->kwargannotation, names)) +    if (args->kwarg && args->kwarg->annotation && +        compiler_visit_argannotation(c, args->kwarg->arg, +                                     args->kwarg->annotation, names))          goto error;      if (!return_str) { @@ -1568,6 +1612,8 @@ compiler_function(struct compiler *c, stmt_ty s)      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); @@ -1575,8 +1621,6 @@ compiler_function(struct compiler *c, stmt_ty s)              return 0;          kw_default_count = res;      } -    if (args->defaults) -        VISIT_SEQ(c, expr, args->defaults);      num_annotations = compiler_visit_annotations(c, args, returns);      if (num_annotations < 0)          return 0; @@ -1661,12 +1705,6 @@ compiler_class(struct compiler *c, stmt_ty s)          Py_INCREF(s->v.ClassDef.name);          Py_XDECREF(c->u->u_private);          c->u->u_private = s->v.ClassDef.name; -        /* force it to have one mandatory argument */ -        c->u->u_argcount = 1; -        /* load the first argument (__locals__) ... */ -        ADDOP_I(c, LOAD_FAST, 0); -        /* ... and store it into f_locals */ -        ADDOP_IN_SCOPE(c, STORE_LOCALS);          /* load (global) __name__ ... */          str = PyUnicode_InternFromString("__name__");          if (!str || !compiler_nameop(c, str, Load)) { @@ -1703,24 +1741,24 @@ compiler_class(struct compiler *c, stmt_ty s)              compiler_exit_scope(c);              return 0;          } -        /* return the (empty) __class__ cell */ -        str = PyUnicode_InternFromString("__class__"); -        if (str == NULL) { -            compiler_exit_scope(c); -            return 0; -        } -        i = compiler_lookup_arg(c->u->u_cellvars, str); -        Py_DECREF(str); -        if (i == -1) { -            /* This happens when nobody references the cell */ -            PyErr_Clear(); -            /* Return None */ -            ADDOP_O(c, LOAD_CONST, Py_None, consts); -        } -        else { +        if (c->u->u_ste->ste_needs_class_closure) { +            /* return the (empty) __class__ cell */ +            str = PyUnicode_InternFromString("__class__"); +            if (str == NULL) { +                compiler_exit_scope(c); +                return 0; +            } +            i = compiler_lookup_arg(c->u->u_cellvars, str); +            Py_DECREF(str); +            assert(i == 0);              /* Return the cell where to store __class__ */              ADDOP_I(c, LOAD_CLOSURE, i);          } +        else { +            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); @@ -1797,14 +1835,14 @@ 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;      } -    if (args->defaults) -        VISIT_SEQ(c, expr, args->defaults);      if (!compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION,                                (void *)e, e->lineno))          return 0; @@ -2288,8 +2326,11 @@ compiler_import(struct compiler *c, stmt_ty s)              identifier tmp = alias->name;              Py_ssize_t dot = PyUnicode_FindChar(                  alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); -            if (dot != -1) +            if (dot != -1) {                  tmp = PyUnicode_Substring(alias->name, 0, dot); +                if (tmp == NULL) +                    return 0; +            }              r = compiler_nameop(c, tmp, Store);              if (dot != -1) {                  Py_DECREF(tmp); @@ -2380,6 +2421,7 @@ compiler_assert(struct compiler *c, stmt_ty s)  {      static PyObject *assertion_error = NULL;      basicblock *end; +    PyObject* msg;      if (c->c_optimize)          return 1; @@ -2390,11 +2432,17 @@ compiler_assert(struct compiler *c, stmt_ty s)      }      if (s->v.Assert.test->kind == Tuple_kind &&          asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) { -        const char* msg = -            "assertion is always true, perhaps remove parentheses?"; -        if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, c->c_filename, -                               c->u->u_lineno, NULL, NULL) == -1) +        msg = PyUnicode_FromString("assertion is always true, " +                                   "perhaps remove parentheses?"); +        if (msg == NULL) +            return 0; +        if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, +                                     c->c_filename, c->u->u_lineno, +                                     NULL, NULL) == -1) { +            Py_DECREF(msg);              return 0; +        } +        Py_DECREF(msg);      }      VISIT(c, expr, s->v.Assert.test);      end = compiler_new_block(c); @@ -2638,6 +2686,10 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)      if (!mangled)          return 0; +    assert(PyUnicode_CompareWithASCIIString(name, "None") && +           PyUnicode_CompareWithASCIIString(name, "True") && +           PyUnicode_CompareWithASCIIString(name, "False")); +      op = 0;      optype = OP_NAME;      scope = PyST_GetScope(c->u->u_ste, mangled); @@ -2673,7 +2725,9 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)      switch (optype) {      case OP_DEREF:          switch (ctx) { -        case Load: op = LOAD_DEREF; break; +        case Load: +            op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; +            break;          case Store: op = STORE_DEREF; break;          case AugLoad:          case AugStore: @@ -3197,12 +3251,18 @@ expr_constant(struct compiler *c, expr_ty e)      case Name_kind:          /* optimize away names that can't be reassigned */          id = PyUnicode_AsUTF8(e->v.Name.id); -        if (strcmp(id, "True") == 0) return 1; -        if (strcmp(id, "False") == 0) return 0; -        if (strcmp(id, "None") == 0) return 0; -        if (strcmp(id, "__debug__") == 0) -            return ! c->c_optimize; -        /* fall through */ +        if (id && strcmp(id, "__debug__") == 0) +            return !c->c_optimize; +        return -1; +    case NameConstant_kind: { +        PyObject *o = e->v.NameConstant.value; +        if (o == Py_None) +            return 0; +        else if (o == Py_True) +            return 1; +        else if (o == Py_False) +            return 0; +    }      default:          return -1;      } @@ -3378,6 +3438,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e)      case Ellipsis_kind:          ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);          break; +    case NameConstant_kind: +        ADDOP_O(c, LOAD_CONST, e->v.NameConstant.value, consts); +        break;      /* The following exprs can be assignment targets. */      case Attribute_kind:          if (e->v.Attribute.ctx != AugStore) @@ -3547,12 +3610,12 @@ compiler_error(struct compiler *c, const char *errstr)      PyObject *loc;      PyObject *u = NULL, *v = NULL; -    loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno); +    loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno);      if (!loc) {          Py_INCREF(Py_None);          loc = Py_None;      } -    u = Py_BuildValue("(OiiO)", c->c_filename_obj, c->u->u_lineno, +    u = Py_BuildValue("(OiiO)", c->c_filename, c->u->u_lineno,                        c->u->u_col_offset, loc);      if (!u)          goto exit; @@ -4060,9 +4123,8 @@ compute_code_flags(struct compiler *c)  {      PySTEntryObject *ste = c->u->u_ste;      int flags = 0, n; -    if (ste->ste_type != ModuleBlock) -        flags |= CO_NEWLOCALS;      if (ste->ste_type == FunctionBlock) { +        flags |= CO_NEWLOCALS;          if (!ste->ste_unoptimized)              flags |= CO_OPTIMIZED;          if (ste->ste_nested) @@ -4143,7 +4205,7 @@ makecode(struct compiler *c, struct assembler *a)                      nlocals, stackdepth(c), flags,                      bytecode, consts, names, varnames,                      freevars, cellvars, -                    c->c_filename_obj, c->u->u_name, +                    c->c_filename, c->u->u_name,                      c->u->u_firstlineno,                      a->a_lnotab);   error: | 
