From 8fbf4fa9edcb9efd1ca5d650ed235eb4770dea3a Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 6 Dec 2012 17:41:04 -0500 Subject: create NameConstant AST class for None, True, and False literals (closes #16619) --- Python/compile.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 3cf71ef09e..3e960ccbfe 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3194,12 +3194,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; } @@ -3375,6 +3381,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) -- cgit v1.2.1 From 114832065bf0892650154c391093095d8d950c25 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 6 Dec 2012 17:49:58 -0500 Subject: assert than we never try to deal with True, False, or None as a name --- Python/compile.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 3e960ccbfe..8f876a6d0d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2635,6 +2635,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); -- cgit v1.2.1 From 3519d4fdaa0875b231d459d2bbe948aeb6761af3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 10 Feb 2013 09:29:59 -0500 Subject: evaluate positional defaults before keyword-only defaults (closes #16967) --- Python/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 8f876a6d0d..a0df40c323 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1565,6 +1565,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); @@ -1572,8 +1574,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; -- cgit v1.2.1 From 7ca707eaa6c4fb73690a0ef904261a63fd0c6385 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 10 Feb 2013 09:48:22 -0500 Subject: evaluate lambda keyword-only defaults after positional defaults (#16967 again) --- Python/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index a0df40c323..61f35f82cd 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1794,14 +1794,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; -- cgit v1.2.1 From 7eadff200c3acb1286b95d417edfcc56cee617ee Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 18 Mar 2013 10:48:58 -0700 Subject: unify some ast.argument's attrs; change Attribute column offset (closes #16795) Patch from Sven Brauch. --- Python/compile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 61f35f82cd..0aca8bd2e9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1498,15 +1498,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) { -- cgit v1.2.1 From a2fc2ebe3d645e60d26996b51d8b33a1fe177d5c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 30 Apr 2013 09:41:40 -0400 Subject: check local class namespace before reaching for cells (closes #17853) --- Python/compile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 52e8188d41..1ecbae8181 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -970,6 +970,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; @@ -2677,7 +2678,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: -- cgit v1.2.1 From f773ed5048253f3e3d86b28e47f8245c2542027c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 15 May 2013 15:26:42 -0500 Subject: hide the __class__ closure from the class body (#12370) --- Python/compile.c | 64 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 1ecbae8181..24ff61f8a9 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)); @@ -1331,6 +1362,9 @@ compiler_mod(struct compiler *c, mod_ty mod) static int get_ref_type(struct compiler *c, PyObject *name) { + if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && + !PyUnicode_CompareWithASCIIString(name, "__class__")) + return CELL; int scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; @@ -1704,24 +1738,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); -- cgit v1.2.1 From df197a8dcb7f4aba4ba0e6b28f910cb28088549e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 16 May 2013 14:37:25 -0500 Subject: rather than passing locals to the class body, just execute the class body in the proper environment --- Python/compile.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 24ff61f8a9..65043e4396 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -893,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: @@ -1696,12 +1694,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)) { @@ -4110,9 +4102,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) -- cgit v1.2.1 From 3be142c560917a899230a0695dccb1052bda0f3a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 16 May 2013 22:17:17 +0200 Subject: fix compilation on Windows --- Python/compile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 65043e4396..4fc7575926 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1360,10 +1360,11 @@ compiler_mod(struct compiler *c, mod_ty mod) static int get_ref_type(struct compiler *c, PyObject *name) { + int scope; if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && !PyUnicode_CompareWithASCIIString(name, "__class__")) return CELL; - int scope = PyST_GetScope(c->u->u_ste, name); + scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; PyOS_snprintf(buf, sizeof(buf), -- cgit v1.2.1 From 3d0056f5b1d38eeecacd4e905a25d9ff0130e322 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 11 Jul 2013 22:50:45 +0200 Subject: Issue #18408: Fix compiler_import() to handle PyUnicode_Substring() failure properly --- Python/compile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 4fc7575926..d11e3abeaa 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2316,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); -- cgit v1.2.1 From c36bfc1c99c6dffff8cb89c723001902d721ff97 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 26 Aug 2013 22:28:21 +0200 Subject: Close #11619: The parser and the import machinery do not encode Unicode filenames anymore on Windows. --- Python/compile.c | 57 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 20 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index d11e3abeaa..71a0930a8e 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"); @@ -338,6 +335,21 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags, return co; } +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) { @@ -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); } @@ -1368,12 +1379,11 @@ get_ref_type(struct compiler *c, PyObject *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) @@ -2411,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; @@ -2421,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); @@ -3593,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; @@ -4188,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: -- cgit v1.2.1 From 70fffb2ae7989ad7e784b6a029cfa27b3f8fc3f0 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 19 Oct 2013 16:01:13 -0400 Subject: give explicitly global functions and classes a global __qualname__ (closes #19301) --- Python/compile.c | 54 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 160c6fce01..85ea1d098d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -650,9 +650,10 @@ compiler_exit_scope(struct compiler *c) } static PyObject * -compiler_scope_qualname(struct compiler *c) +compiler_scope_qualname(struct compiler *c, identifier scope_name) { - Py_ssize_t stack_size, i; + Py_ssize_t stack_size; + int global_scope; _Py_static_string(dot, "."); _Py_static_string(locals, ""); struct compiler_unit *u; @@ -669,22 +670,41 @@ compiler_scope_qualname(struct compiler *c) return NULL; stack_size = PyList_GET_SIZE(c->c_stack); - for (i = 0; i < stack_size; i++) { - capsule = PyList_GET_ITEM(c->c_stack, i); + global_scope = stack_size <= 1; + if (scope_name != NULL && !global_scope) { + int scope; + PyObject *mangled; + capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); assert(u); - if (u->u_scope_type == COMPILER_SCOPE_MODULE) - continue; - if (PyList_Append(seq, u->u_name)) - goto _error; - if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) { - locals_str = _PyUnicode_FromId(&locals); - if (locals_str == NULL) - goto _error; - if (PyList_Append(seq, locals_str)) + mangled = _Py_Mangle(u->u_private, scope_name); + if (!mangled) + return NULL; + scope = PyST_GetScope(u->u_ste, mangled); + Py_DECREF(mangled); + assert(scope != GLOBAL_IMPLICIT); + if (scope == GLOBAL_EXPLICIT) + global_scope = 1; + } + if (!global_scope) { + Py_ssize_t i; + for (i = 1; i < stack_size; i++) { + capsule = PyList_GET_ITEM(c->c_stack, i); + u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); + assert(u); + assert(u->u_scope_type != COMPILER_SCOPE_MODULE); + if (PyList_Append(seq, u->u_name)) goto _error; + if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) { + locals_str = _PyUnicode_FromId(&locals); + if (locals_str == NULL) + goto _error; + if (PyList_Append(seq, locals_str)) + goto _error; + } } } + u = c->u; if (PyList_Append(seq, u->u_name)) goto _error; @@ -1649,7 +1669,7 @@ compiler_function(struct compiler *c, stmt_ty s) VISIT_IN_SCOPE(c, stmt, st); } co = assemble(c, 1); - qualname = compiler_scope_qualname(c); + qualname = compiler_scope_qualname(c, s->v.FunctionDef.name); compiler_exit_scope(c); if (qualname == NULL || co == NULL) { Py_XDECREF(qualname); @@ -1722,7 +1742,7 @@ compiler_class(struct compiler *c, stmt_ty s) } Py_DECREF(str); /* store the __qualname__ */ - str = compiler_scope_qualname(c); + str = compiler_scope_qualname(c, s->v.ClassDef.name); if (!str) { compiler_exit_scope(c); return 0; @@ -1862,7 +1882,7 @@ compiler_lambda(struct compiler *c, expr_ty e) ADDOP_IN_SCOPE(c, RETURN_VALUE); } co = assemble(c, 1); - qualname = compiler_scope_qualname(c); + qualname = compiler_scope_qualname(c, NULL); compiler_exit_scope(c); if (qualname == NULL || co == NULL) return 0; @@ -3139,7 +3159,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, } co = assemble(c, 1); - qualname = compiler_scope_qualname(c); + qualname = compiler_scope_qualname(c, NULL); compiler_exit_scope(c); if (qualname == NULL || co == NULL) goto error; -- cgit v1.2.1 From 3ab3848f8e40baaa5563d0cbc8b7d63f62075792 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 19 Oct 2013 16:14:39 -0400 Subject: strengthen condition and add assertion --- Python/compile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 85ea1d098d..9176e3131d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -670,7 +670,8 @@ compiler_scope_qualname(struct compiler *c, identifier scope_name) return NULL; stack_size = PyList_GET_SIZE(c->c_stack); - global_scope = stack_size <= 1; + assert(stack_size >= 1); + global_scope = stack_size == 1; if (scope_name != NULL && !global_scope) { int scope; PyObject *mangled; -- cgit v1.2.1 From 6f072dd7f738eee5badf213ee3f2e5b4ac1c3e13 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 19 Oct 2013 16:15:58 -0400 Subject: removal u_qualname, since compiler_scope_qualname is only ever called once --- Python/compile.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 9176e3131d..eeccd11170 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -104,7 +104,6 @@ struct compiler_unit { PySTEntryObject *u_ste; PyObject *u_name; - PyObject *u_qualname; /* dot-separated qualified name (lazy) */ int u_scope_type; /* The following fields are dicts that map objects to @@ -507,7 +506,6 @@ compiler_unit_free(struct compiler_unit *u) } Py_CLEAR(u->u_ste); Py_CLEAR(u->u_name); - Py_CLEAR(u->u_qualname); Py_CLEAR(u->u_consts); Py_CLEAR(u->u_names); Py_CLEAR(u->u_varnames); @@ -660,11 +658,6 @@ compiler_scope_qualname(struct compiler *c, identifier scope_name) PyObject *capsule, *name, *seq, *dot_str, *locals_str; u = c->u; - if (u->u_qualname != NULL) { - Py_INCREF(u->u_qualname); - return u->u_qualname; - } - seq = PyList_New(0); if (seq == NULL) return NULL; @@ -714,7 +707,6 @@ compiler_scope_qualname(struct compiler *c, identifier scope_name) goto _error; name = PyUnicode_Join(dot_str, seq); Py_DECREF(seq); - u->u_qualname = name; Py_XINCREF(name); return name; -- cgit v1.2.1 From 89896b3fde2b402fccffaa370a3fe59430044bad Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 20 Oct 2013 22:43:53 +1000 Subject: Close #19313: remove no longer needed Py_XINCREF Eliminates a refleak introduced in commit b4a325275fb0 --- Python/compile.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index eeccd11170..5b23e61ff6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -707,7 +707,6 @@ compiler_scope_qualname(struct compiler *c, identifier scope_name) goto _error; name = PyUnicode_Join(dot_str, seq); Py_DECREF(seq); - Py_XINCREF(name); return name; _error: -- cgit v1.2.1 From 623960c18d6baf99eb15f1af4dcfd379361a0ce2 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 20 Oct 2013 17:50:28 -0400 Subject: cleanup the construction of __qualname__ (closes #19301 again) --- Python/compile.c | 152 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 70 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 5b23e61ff6..32465f7169 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -94,6 +94,7 @@ enum { COMPILER_SCOPE_MODULE, COMPILER_SCOPE_CLASS, COMPILER_SCOPE_FUNCTION, + COMPILER_SCOPE_LAMBDA, COMPILER_SCOPE_COMPREHENSION, }; @@ -104,6 +105,7 @@ struct compiler_unit { PySTEntryObject *u_ste; PyObject *u_name; + PyObject *u_qualname; /* dot-separated qualified name (lazy) */ int u_scope_type; /* The following fields are dicts that map objects to @@ -199,6 +201,7 @@ static int compiler_call_helper(struct compiler *c, int n, expr_ty starargs, expr_ty kwargs); static int compiler_try_except(struct compiler *, stmt_ty); +static int compiler_set_qualname(struct compiler *); static PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__; @@ -506,6 +509,7 @@ compiler_unit_free(struct compiler_unit *u) } Py_CLEAR(u->u_ste); Py_CLEAR(u->u_name); + Py_CLEAR(u->u_qualname); Py_CLEAR(u->u_consts); Py_CLEAR(u->u_names); Py_CLEAR(u->u_varnames); @@ -620,6 +624,11 @@ compiler_enter_scope(struct compiler *c, identifier name, if (compiler_use_new_block(c) == NULL) return 0; + if (u->u_scope_type != COMPILER_SCOPE_MODULE) { + if (!compiler_set_qualname(c)) + return 0; + } + return 1; } @@ -647,71 +656,77 @@ compiler_exit_scope(struct compiler *c) } -static PyObject * -compiler_scope_qualname(struct compiler *c, identifier scope_name) +static int +compiler_set_qualname(struct compiler *c) { - Py_ssize_t stack_size; - int global_scope; _Py_static_string(dot, "."); - _Py_static_string(locals, ""); - struct compiler_unit *u; - PyObject *capsule, *name, *seq, *dot_str, *locals_str; - - u = c->u; - seq = PyList_New(0); - if (seq == NULL) - return NULL; + _Py_static_string(dot_locals, "."); + Py_ssize_t stack_size; + struct compiler_unit *u = c->u; + PyObject *name, *base, *dot_str, *dot_locals_str; + base = NULL; stack_size = PyList_GET_SIZE(c->c_stack); assert(stack_size >= 1); - global_scope = stack_size == 1; - if (scope_name != NULL && !global_scope) { - int scope; - PyObject *mangled; + if (stack_size > 1) { + int scope, force_global = 0; + struct compiler_unit *parent; + PyObject *mangled, *capsule; + capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); - u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); - assert(u); - mangled = _Py_Mangle(u->u_private, scope_name); - if (!mangled) - return NULL; - scope = PyST_GetScope(u->u_ste, mangled); - Py_DECREF(mangled); - assert(scope != GLOBAL_IMPLICIT); - if (scope == GLOBAL_EXPLICIT) - global_scope = 1; - } - if (!global_scope) { - Py_ssize_t i; - for (i = 1; i < stack_size; i++) { - capsule = PyList_GET_ITEM(c->c_stack, i); - u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); - assert(u); - assert(u->u_scope_type != COMPILER_SCOPE_MODULE); - if (PyList_Append(seq, u->u_name)) - goto _error; - if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) { - locals_str = _PyUnicode_FromId(&locals); - if (locals_str == NULL) - goto _error; - if (PyList_Append(seq, locals_str)) - goto _error; + parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); + assert(parent); + + if (u->u_scope_type == COMPILER_SCOPE_FUNCTION || u->u_scope_type == COMPILER_SCOPE_CLASS) { + assert(u->u_name); + mangled = _Py_Mangle(parent->u_private, u->u_name); + if (!mangled) + return 0; + scope = PyST_GetScope(parent->u_ste, mangled); + Py_DECREF(mangled); + assert(scope != GLOBAL_IMPLICIT); + if (scope == GLOBAL_EXPLICIT) + force_global = 1; + } + + if (!force_global) { + if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION + || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) { + dot_locals_str = _PyUnicode_FromId(&dot_locals); + if (dot_locals_str == NULL) + return 0; + base = PyUnicode_Concat(parent->u_qualname, dot_locals_str); + if (base == NULL) + return 0; + } + else { + Py_INCREF(parent->u_qualname); + base = parent->u_qualname; } } } - u = c->u; - if (PyList_Append(seq, u->u_name)) - goto _error; - dot_str = _PyUnicode_FromId(&dot); - if (dot_str == NULL) - goto _error; - name = PyUnicode_Join(dot_str, seq); - Py_DECREF(seq); - return name; - -_error: - Py_XDECREF(seq); - return NULL; + if (base != NULL) { + dot_str = _PyUnicode_FromId(&dot); + if (dot_str == NULL) { + Py_DECREF(base); + return 0; + } + name = PyUnicode_Concat(base, dot_str); + Py_DECREF(base); + if (name == NULL) + return 0; + PyUnicode_Append(&name, u->u_name); + if (name == NULL) + return 0; + } + else { + Py_INCREF(u->u_name); + name = u->u_name; + } + u->u_qualname = name; + + return 1; } /* Allocate a new block and return a pointer to it. @@ -1661,9 +1676,10 @@ compiler_function(struct compiler *c, stmt_ty s) VISIT_IN_SCOPE(c, stmt, st); } co = assemble(c, 1); - qualname = compiler_scope_qualname(c, s->v.FunctionDef.name); + qualname = c->u->u_qualname; + Py_INCREF(qualname); compiler_exit_scope(c); - if (qualname == NULL || co == NULL) { + if (co == NULL) { Py_XDECREF(qualname); Py_XDECREF(co); return 0; @@ -1733,14 +1749,8 @@ compiler_class(struct compiler *c, stmt_ty s) return 0; } Py_DECREF(str); - /* store the __qualname__ */ - str = compiler_scope_qualname(c, s->v.ClassDef.name); - if (!str) { - compiler_exit_scope(c); - return 0; - } - ADDOP_O(c, LOAD_CONST, str, consts); - Py_DECREF(str); + assert(c->u->u_qualname); + ADDOP_O(c, LOAD_CONST, c->u->u_qualname, consts); str = PyUnicode_InternFromString("__qualname__"); if (!str || !compiler_nameop(c, str, Store)) { Py_XDECREF(str); @@ -1855,7 +1865,7 @@ compiler_lambda(struct compiler *c, expr_ty e) if (res < 0) return 0; kw_default_count = res; } - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION, + if (!compiler_enter_scope(c, name, COMPILER_SCOPE_LAMBDA, (void *)e, e->lineno)) return 0; @@ -1874,9 +1884,10 @@ compiler_lambda(struct compiler *c, expr_ty e) ADDOP_IN_SCOPE(c, RETURN_VALUE); } co = assemble(c, 1); - qualname = compiler_scope_qualname(c, NULL); + qualname = c->u->u_qualname; + Py_INCREF(qualname); compiler_exit_scope(c); - if (qualname == NULL || co == NULL) + if (co == NULL) return 0; arglength = asdl_seq_LEN(args->defaults); @@ -3151,9 +3162,10 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, } co = assemble(c, 1); - qualname = compiler_scope_qualname(c, NULL); + qualname = c->u->u_qualname; + Py_INCREF(qualname); compiler_exit_scope(c); - if (qualname == NULL || co == NULL) + if (co == NULL) goto error; if (!compiler_make_closure(c, co, 0, qualname)) -- cgit v1.2.1 From 76ff36c05f434947e1b90490d682b3282646cbfd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 5 Nov 2013 18:07:34 +0100 Subject: Issue #19437: Fix compiler_class(), handle compiler_lookup_arg() failure --- Python/compile.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 32465f7169..8b00211c9f 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1772,6 +1772,10 @@ compiler_class(struct compiler *c, stmt_ty s) } i = compiler_lookup_arg(c->u->u_cellvars, str); Py_DECREF(str); + if (i < 0) { + compiler_exit_scope(c); + return 0; + } assert(i == 0); /* Return the cell where to store __class__ */ ADDOP_I(c, LOAD_CLOSURE, i); -- cgit v1.2.1 From 4bcc16eb5291c2e256c86e9316cae5a4001cbe70 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Nov 2013 22:23:20 +0100 Subject: Issue #9566: compile.c uses Py_ssize_t instead of int to store sizes to fix compiler warnings on Windows 64-bit. Use Py_SAFE_DOWNCAST() where the final downcast is needed. The bytecode doesn't support integer parameters larger than 32-bit yet. --- Python/compile.c | 116 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 48 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 8b00211c9f..dde6dcff4b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -170,7 +170,7 @@ static basicblock *compiler_new_block(struct compiler *); static int compiler_next_instr(struct compiler *, basicblock *); 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, int); +static int compiler_addop_i(struct compiler *, Py_ssize_t, 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 *); @@ -195,7 +195,7 @@ static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(struct compiler *, expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); -static int compiler_call_helper(struct compiler *c, int n, +static int compiler_call_helper(struct compiler *c, Py_ssize_t n, asdl_seq *args, asdl_seq *keywords, expr_ty starargs, @@ -388,7 +388,7 @@ list2dict(PyObject *list) n = PyList_Size(list); for (i = 0; i < n; i++) { - v = PyLong_FromLong(i); + v = PyLong_FromSsize_t(i); if (!v) { Py_DECREF(dict); return NULL; @@ -416,7 +416,7 @@ each key. */ static PyObject * -dictbytype(PyObject *src, int scope_type, int flag, int offset) +dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) { Py_ssize_t i = offset, scope, num_keys, key_i; PyObject *k, *v, *dest = PyDict_New(); @@ -450,7 +450,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset) scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; if (scope == scope_type || vi & flag) { - PyObject *tuple, *item = PyLong_FromLong(i); + PyObject *tuple, *item = PyLong_FromSsize_t(i); if (item == NULL) { Py_DECREF(sorted_keys); Py_DECREF(dest); @@ -635,7 +635,7 @@ compiler_enter_scope(struct compiler *c, identifier name, static void compiler_exit_scope(struct compiler *c) { - int n; + Py_ssize_t n; PyObject *capsule; c->c_nestlevel--; @@ -1128,7 +1128,7 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) if (PyErr_Occurred()) return -1; arg = PyDict_Size(dict); - v = PyLong_FromLong(arg); + v = PyLong_FromSsize_t(arg); if (!v) { Py_DECREF(t); return -1; @@ -1150,7 +1150,7 @@ static int compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { - int arg = compiler_add_o(c, dict, o); + Py_ssize_t arg = compiler_add_o(c, dict, o); if (arg < 0) return 0; return compiler_addop_i(c, opcode, arg); @@ -1160,7 +1160,7 @@ static int compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, PyObject *o) { - int arg; + Py_ssize_t arg; PyObject *mangled = _Py_Mangle(c->u->u_private, o); if (!mangled) return 0; @@ -1176,15 +1176,21 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, */ static int -compiler_addop_i(struct compiler *c, int opcode, int oparg) +compiler_addop_i(struct compiler *c, Py_ssize_t 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(INT32_MIN <= opcode); + assert(opcode <= INT32_MAX); + off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; - i->i_opcode = opcode; + i->i_opcode = Py_SAFE_DOWNCAST(opcode, Py_ssize_t, int); i->i_oparg = oparg; i->i_hasarg = 1; compiler_set_lineno(c, off); @@ -1436,9 +1442,9 @@ compiler_lookup_arg(PyObject *dict, PyObject *name) } static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, int args, PyObject *qualname) +compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyObject *qualname) { - int i, free = PyCode_GetNumFree(co); + Py_ssize_t i, free = PyCode_GetNumFree(co); if (qualname == NULL) qualname = co->co_name; @@ -1565,7 +1571,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, */ static identifier return_str; PyObject *names; - int len; + Py_ssize_t len; names = PyList_New(0); if (!names) return -1; @@ -1602,7 +1608,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (len) { /* convert names to a tuple and place on stack */ PyObject *elt; - int i; + Py_ssize_t i; PyObject *s = PyTuple_New(len); if (!s) goto error; @@ -1616,7 +1622,9 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, len++; /* include the just-pushed tuple */ } Py_DECREF(names); - return len; + + /* We just checked that len <= 65535, see above */ + return Py_SAFE_DOWNCAST(len, Py_ssize_t, int); error: Py_DECREF(names); @@ -1632,7 +1640,8 @@ compiler_function(struct compiler *c, stmt_ty s) expr_ty returns = s->v.FunctionDef.returns; asdl_seq* decos = s->v.FunctionDef.decorator_list; stmt_ty st; - int i, n, docstring, kw_default_count = 0, arglength; + Py_ssize_t i, n, arglength; + int docstring, kw_default_count = 0; int num_annotations; assert(s->kind == FunctionDef_kind); @@ -1851,7 +1860,8 @@ compiler_lambda(struct compiler *c, expr_ty e) PyCodeObject *co; PyObject *qualname; static identifier name; - int kw_default_count = 0, arglength; + int kw_default_count = 0; + Py_ssize_t arglength; arguments_ty args = e->v.Lambda.args; assert(e->kind == Lambda_kind); @@ -2162,7 +2172,7 @@ static int compiler_try_except(struct compiler *c, stmt_ty s) { basicblock *body, *orelse, *except, *end; - int i, n; + Py_ssize_t i, n; body = compiler_new_block(c); except = compiler_new_block(c); @@ -2328,7 +2338,7 @@ compiler_import(struct compiler *c, stmt_ty s) module names. XXX Perhaps change the representation to make this case simpler? */ - int i, n = asdl_seq_LEN(s->v.Import.names); + Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names); for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); @@ -2372,7 +2382,7 @@ compiler_import(struct compiler *c, stmt_ty s) static int compiler_from_import(struct compiler *c, stmt_ty s) { - int i, n = asdl_seq_LEN(s->v.ImportFrom.names); + Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); PyObject *names = PyTuple_New(n); PyObject *level; @@ -2489,7 +2499,7 @@ compiler_assert(struct compiler *c, stmt_ty s) static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { - int i, n; + Py_ssize_t i, n; /* Always assign a lineno to the next instruction for a stmt. */ c->u->u_lineno = s->lineno; @@ -2537,12 +2547,12 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) if (s->v.Raise.exc) { VISIT(c, expr, s->v.Raise.exc); n++; - if (s->v.Raise.cause) { - VISIT(c, expr, s->v.Raise.cause); - n++; - } + if (s->v.Raise.cause) { + VISIT(c, expr, s->v.Raise.cause); + n++; + } } - ADDOP_I(c, RAISE_VARARGS, n); + ADDOP_I(c, RAISE_VARARGS, (int)n); break; case Try_kind: return compiler_try(c, s); @@ -2702,7 +2712,8 @@ inplace_binop(struct compiler *c, operator_ty op) static int compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) { - int op, scope, arg; + int op, scope; + Py_ssize_t arg; enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; PyObject *dict = c->u->u_names; @@ -2828,7 +2839,8 @@ static int compiler_boolop(struct compiler *c, expr_ty e) { basicblock *end; - int jumpi, i, n; + int jumpi; + Py_ssize_t i, n; asdl_seq *s; assert(e->kind == BoolOp_kind); @@ -2854,7 +2866,7 @@ compiler_boolop(struct compiler *c, expr_ty e) static int compiler_list(struct compiler *c, expr_ty e) { - int n = asdl_seq_LEN(e->v.List.elts); + Py_ssize_t n = asdl_seq_LEN(e->v.List.elts); if (e->v.List.ctx == Store) { int i, seen_star = 0; for (i = 0; i < n; i++) { @@ -2887,7 +2899,7 @@ compiler_list(struct compiler *c, expr_ty e) static int compiler_tuple(struct compiler *c, expr_ty e) { - int n = asdl_seq_LEN(e->v.Tuple.elts); + Py_ssize_t n = asdl_seq_LEN(e->v.Tuple.elts); if (e->v.Tuple.ctx == Store) { int i, seen_star = 0; for (i = 0; i < n; i++) { @@ -2920,7 +2932,7 @@ compiler_tuple(struct compiler *c, expr_ty e) static int compiler_compare(struct compiler *c, expr_ty e) { - int i, n; + Py_ssize_t i, n; basicblock *cleanup = NULL; /* XXX the logic can be cleaned up for 1 or multiple comparisons */ @@ -2976,11 +2988,11 @@ compiler_call(struct compiler *c, expr_ty e) /* shared code between compiler_call and compiler_class */ static int compiler_call_helper(struct compiler *c, - int n, /* Args already pushed */ - asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs) + Py_ssize_t n, /* Args already pushed */ + asdl_seq *args, + asdl_seq *keywords, + expr_ty starargs, + expr_ty kwargs) { int code = 0; @@ -3041,7 +3053,7 @@ compiler_comprehension_generator(struct compiler *c, comprehension_ty gen; basicblock *start, *anchor, *skip, *if_cleanup; - int i, n; + Py_ssize_t i, n; start = compiler_new_block(c); skip = compiler_new_block(c); @@ -3380,7 +3392,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) static int compiler_visit_expr(struct compiler *c, expr_ty e) { - int i, n; + Py_ssize_t i, n; /* If expr e has a different line number than the last expr/stmt, set a new line number for the next instruction. @@ -3409,6 +3421,8 @@ compiler_visit_expr(struct compiler *c, expr_ty e) return compiler_ifexp(c, e); case Dict_kind: n = asdl_seq_LEN(e->v.Dict.values); + /* BUILD_MAP parameter is only used to preallocate the dictionary, + it doesn't need to be exact */ ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n)); for (i = 0; i < n; i++) { VISIT(c, expr, @@ -3756,7 +3770,7 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) case ExtSlice_kind: kindname = "extended slice"; if (ctx != AugStore) { - int i, n = asdl_seq_LEN(s->v.ExtSlice.dims); + Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims); for (i = 0; i < n; i++) { slice_ty sub = (slice_ty)asdl_seq_GET( s->v.ExtSlice.dims, i); @@ -3934,7 +3948,7 @@ static int assemble_lnotab(struct assembler *a, struct instr *i) { int d_bytecode, d_lineno; - int len; + Py_ssize_t len; unsigned char *lnotab; d_bytecode = a->a_offset - a->a_lineno_off; @@ -4125,7 +4139,7 @@ assemble_jump_offsets(struct assembler *a, struct compiler *c) } static PyObject * -dict_keys_inorder(PyObject *dict, int offset) +dict_keys_inorder(PyObject *dict, Py_ssize_t offset) { PyObject *tuple, *k, *v; Py_ssize_t i, pos = 0, size = PyDict_Size(dict); @@ -4150,7 +4164,8 @@ static int compute_code_flags(struct compiler *c) { PySTEntryObject *ste = c->u->u_ste; - int flags = 0, n; + int flags = 0; + Py_ssize_t n; if (ste->ste_type == FunctionBlock) { flags |= CO_NEWLOCALS; if (!ste->ste_unoptimized) @@ -4174,9 +4189,9 @@ compute_code_flags(struct compiler *c) if (n == 0) { n = PyDict_Size(c->u->u_cellvars); if (n < 0) - return -1; + return -1; if (n == 0) { - flags |= CO_NOFREE; + flags |= CO_NOFREE; } } @@ -4195,7 +4210,9 @@ makecode(struct compiler *c, struct assembler *a) PyObject *freevars = NULL; PyObject *cellvars = NULL; PyObject *bytecode = NULL; - int nlocals, flags; + Py_ssize_t nlocals; + int nlocals_int; + int flags; tmp = dict_keys_inorder(c->u->u_consts, 0); if (!tmp) @@ -4214,7 +4231,11 @@ makecode(struct compiler *c, struct assembler *a) freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); if (!freevars) goto error; + nlocals = PyDict_Size(c->u->u_varnames); + assert(nlocals < INT_MAX); + nlocals_int = Py_SAFE_DOWNCAST(nlocals, Py_ssize_t, int); + flags = compute_code_flags(c); if (flags < 0) goto error; @@ -4230,7 +4251,7 @@ makecode(struct compiler *c, struct assembler *a) consts = tmp; co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount, - nlocals, stackdepth(c), flags, + nlocals_int, stackdepth(c), flags, bytecode, consts, names, varnames, freevars, cellvars, c->c_filename, c->u->u_name, @@ -4349,4 +4370,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, return PyAST_CompileEx(mod, filename, flags, -1, arena); } - -- cgit v1.2.1 From 1080ebd8c165c4e1d6793745774fa99d7a42f78d Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Nov 2013 22:28:01 +0100 Subject: Issue #9566, #19617: Fix compilation on Windows INT32_MIN and INT32_MAX constants are unknown on Windows. --- Python/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index dde6dcff4b..2c8db48651 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1183,8 +1183,8 @@ compiler_addop_i(struct compiler *c, Py_ssize_t opcode, Py_ssize_t oparg) /* Integer arguments are limit to 16-bit. There is an extension for 32-bit integer arguments. */ - assert(INT32_MIN <= opcode); - assert(opcode <= INT32_MAX); + assert(-2147483648 <= opcode); + assert(opcode <= 2147483647); off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) -- cgit v1.2.1 From 814032716938b817faa2ece644ac6dc86cff8052 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Nov 2013 23:03:25 +0100 Subject: Issue #9566, #19617: New try to fix compilation on Windows Some compilers (ex: Visual Studio) decode -2147483648 as a unsigned integer instead of an signed integer. --- Python/compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 2c8db48651..78841d37da 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1183,7 +1183,7 @@ compiler_addop_i(struct compiler *c, Py_ssize_t opcode, Py_ssize_t oparg) /* Integer arguments are limit to 16-bit. There is an extension for 32-bit integer arguments. */ - assert(-2147483648 <= opcode); + assert((-2147483647-1) <= opcode); assert(opcode <= 2147483647); off = compiler_next_instr(c, c->u->u_curblock); -- cgit v1.2.1 From 5aa0b2c1cc58cc9ce131fa5ca9324a23c5c2fa91 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Nov 2013 23:56:34 +0100 Subject: Issue #9566, #19617: Fix more compiler warnings in compile.c on Windows 64-bit --- Python/compile.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 78841d37da..de55687a62 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -120,8 +120,8 @@ struct compiler_unit { PyObject *u_private; /* for private name mangling */ - int u_argcount; /* number of arguments for block */ - int u_kwonlyargcount; /* number of keyword only arguments for block */ + Py_ssize_t u_argcount; /* number of arguments for block */ + Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ /* Pointer to the most recently allocated block. By following b_list members, you can reach all early allocated blocks. */ basicblock *u_blocks; @@ -170,7 +170,7 @@ static basicblock *compiler_new_block(struct compiler *); static int compiler_next_instr(struct compiler *, basicblock *); static int compiler_addop(struct compiler *, int); static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *); -static int compiler_addop_i(struct compiler *, Py_ssize_t, Py_ssize_t); +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 *); @@ -1074,7 +1074,7 @@ compiler_addop(struct compiler *c, int opcode) return 1; } -static int +static Py_ssize_t compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) { PyObject *t, *v; @@ -1176,22 +1176,22 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, */ static int -compiler_addop_i(struct compiler *c, Py_ssize_t opcode, Py_ssize_t oparg) +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) <= opcode); - assert(opcode <= 2147483647); + assert((-2147483647-1) <= oparg); + assert(oparg <= 2147483647); off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) return 0; i = &c->u->u_curblock->b_instr[off]; - i->i_opcode = Py_SAFE_DOWNCAST(opcode, Py_ssize_t, int); - i->i_oparg = oparg; + 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; @@ -4213,6 +4213,7 @@ makecode(struct compiler *c, struct assembler *a) Py_ssize_t nlocals; int nlocals_int; int flags; + int argcount, kwonlyargcount; tmp = dict_keys_inorder(c->u->u_consts, 0); if (!tmp) @@ -4250,7 +4251,9 @@ makecode(struct compiler *c, struct assembler *a) Py_DECREF(consts); consts = tmp; - co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount, + argcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int); + kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int); + co = PyCode_New(argcount, kwonlyargcount, nlocals_int, stackdepth(c), flags, bytecode, consts, names, varnames, freevars, cellvars, -- cgit v1.2.1 From 5340ce2bfc039502eb07fa62adbaee1924f46ece Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Sat, 23 Nov 2013 14:49:22 -0800 Subject: Issue #19722: Added opcode.stack_effect(), which accurately computes the stack effect of bytecode instructions. --- Python/compile.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index de55687a62..0fc91864ff 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -853,8 +853,8 @@ compiler_set_lineno(struct compiler *c, int off) b->b_instr[off].i_lineno = c->u->u_lineno; } -static int -opcode_stack_effect(int opcode, int oparg) +int +PyCompile_OpcodeStackEffect(int opcode, int oparg) { switch (opcode) { case POP_TOP: @@ -1044,11 +1044,9 @@ opcode_stack_effect(int opcode, int oparg) case DELETE_DEREF: return 0; default: - fprintf(stderr, "opcode = %d\n", opcode); - Py_FatalError("opcode_stack_effect()"); - + return PY_INVALID_STACK_EFFECT; } - return 0; /* not reachable */ + return PY_INVALID_STACK_EFFECT; /* not reachable */ } /* Add an opcode with no argument. @@ -3829,7 +3827,7 @@ dfs(struct compiler *c, basicblock *b, struct assembler *a) static int stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) { - int i, target_depth; + int i, target_depth, effect; struct instr *instr; if (b->b_seen || b->b_startdepth >= depth) return maxdepth; @@ -3837,7 +3835,13 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) b->b_startdepth = depth; for (i = 0; i < b->b_iused; i++) { instr = &b->b_instr[i]; - depth += opcode_stack_effect(instr->i_opcode, instr->i_oparg); + effect = PyCompile_OpcodeStackEffect(instr->i_opcode, instr->i_oparg); + if (effect == PY_INVALID_STACK_EFFECT) { + fprintf(stderr, "opcode = %d\n", instr->i_opcode); + Py_FatalError("PyCompile_OpcodeStackEffect()"); + } + depth += effect; + if (depth > maxdepth) maxdepth = depth; assert(depth >= 0); /* invalid code or bug in stackdepth() */ -- cgit v1.2.1 From 4b58a23d4fcf4cb6d96404c4db2f40fcab494efd Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 4 Dec 2013 08:42:46 +0100 Subject: upcast int to size_t to silence two autological-constant-out-of-range-compare warnings with clang. --- Python/compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 0fc91864ff..a7ddc5a11a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3899,7 +3899,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 (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { + if ((size_t)nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { PyErr_NoMemory(); return 0; } -- cgit v1.2.1 From 4feb97d3923c246e9ee39c326309ec206b200a49 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Tue, 18 Feb 2014 12:49:41 -0500 Subject: Mangle __parameters in __annotations__ dict properly. Issue #20625. --- Python/compile.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index a7ddc5a11a..57a232919d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1533,8 +1533,14 @@ compiler_visit_argannotation(struct compiler *c, identifier id, { if (annotation) { VISIT(c, expr, annotation); - if (PyList_Append(names, id)) + PyObject *mangled = _Py_Mangle(c->u->u_private, id); + if (!mangled) return -1; + if (PyList_Append(names, mangled) < 0) { + Py_DECREF(mangled); + return -1; + } + Py_DECREF(mangled); } return 0; } -- cgit v1.2.1 From 3dc624a9d37e4623547d80ea8fb3c0e369498b2f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 18 Feb 2014 22:07:56 +0100 Subject: Issue #20625: Fix compilation issue --- Python/compile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 57a232919d..9978eb3a1d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1532,8 +1532,9 @@ compiler_visit_argannotation(struct compiler *c, identifier id, expr_ty annotation, PyObject *names) { if (annotation) { + PyObject *mangled; VISIT(c, expr, annotation); - PyObject *mangled = _Py_Mangle(c->u->u_private, id); + mangled = _Py_Mangle(c->u->u_private, id); if (!mangled) return -1; if (PyList_Append(names, mangled) < 0) { -- cgit v1.2.1 From 5fee46c5717b4d9d86cdbe10252195a1989d4313 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 23 May 2014 11:46:03 +0200 Subject: Issue #21523: Fix over-pessimistic computation of the stack effect of some opcodes in the compiler. This also fixes a quadratic compilation time issue noticeable when compiling code with a large number of "and" and "or" operators. --- Python/compile.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 9978eb3a1d..69419ecddc 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3856,12 +3856,16 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) target_depth = depth; if (instr->i_opcode == FOR_ITER) { target_depth = depth-2; - } else if (instr->i_opcode == SETUP_FINALLY || - instr->i_opcode == SETUP_EXCEPT) { + } + else if (instr->i_opcode == SETUP_FINALLY || + instr->i_opcode == SETUP_EXCEPT) { target_depth = depth+3; if (target_depth > maxdepth) maxdepth = target_depth; } + else if (instr->i_opcode == JUMP_IF_TRUE_OR_POP || + instr->i_opcode == JUMP_IF_FALSE_OR_POP) + depth = depth - 1; maxdepth = stackdepth_walk(c, instr->i_target, target_depth, maxdepth); if (instr->i_opcode == JUMP_ABSOLUTE || -- cgit v1.2.1