diff options
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 133 |
1 files changed, 89 insertions, 44 deletions
diff --git a/Python/compile.c b/Python/compile.c index dd4262c..d11e3ab 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -535,6 +535,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 +893,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 +999,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,7 +1360,11 @@ 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), @@ -1501,15 +1535,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 +1602,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 +1611,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 +1695,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 +1731,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 +1825,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 +2316,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); @@ -2638,6 +2669,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 +2708,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 +3234,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 +3421,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) @@ -4060,9 +4106,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) |