summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c190
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: