summaryrefslogtreecommitdiff
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c1065
1 files changed, 593 insertions, 472 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 531bed43c4..d6f640fabb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -25,10 +25,8 @@
#include "Python-ast.h"
#include "node.h"
-#include "pyarena.h"
#include "ast.h"
#include "code.h"
-#include "compile.h"
#include "symtable.h"
#include "opcode.h"
@@ -40,8 +38,9 @@ int Py_OptimizeFlag = 0;
#define DEFAULT_LNOTAB_SIZE 16
#define COMP_GENEXP 0
-#define COMP_SETCOMP 1
-#define COMP_DICTCOMP 2
+#define COMP_LISTCOMP 1
+#define COMP_SETCOMP 2
+#define COMP_DICTCOMP 3
struct instr {
unsigned i_jabs : 1;
@@ -111,6 +110,7 @@ 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 */
/* Pointer to the most recently allocated block. By following b_list
members, you can reach all early allocated blocks. */
basicblock *u_blocks;
@@ -121,7 +121,8 @@ struct compiler_unit {
int u_firstlineno; /* the first lineno of the block */
int u_lineno; /* the lineno for the current stmt */
- bool u_lineno_set; /* boolean to indicate whether instr
+ int u_col_offset; /* the offset of the current stmt */
+ int u_lineno_set; /* boolean to indicate whether instr
has been generated with current lineno */
};
@@ -138,6 +139,7 @@ struct compiler {
PyFutureFeatures *c_future; /* pointer to module's __future__ */
PyCompilerFlags *c_flags;
+ int c_optimize; /* optimization level */
int c_interactive; /* true if in interactive mode */
int c_nestlevel;
@@ -174,9 +176,14 @@ static void compiler_pop_fblock(struct compiler *, enum fblocktype,
static int compiler_in_loop(struct compiler *);
static int inplace_binop(struct compiler *, operator_ty);
-static int expr_constant(expr_ty e);
+static int expr_constant(struct compiler *, expr_ty);
static int compiler_with(struct compiler *, stmt_ty);
+static int compiler_call_helper(struct compiler *c, int n,
+ asdl_seq *args,
+ asdl_seq *keywords,
+ expr_ty starargs,
+ expr_ty kwargs);
static PyCodeObject *assemble(struct compiler *, int addNone);
static PyObject *__doc__;
@@ -188,16 +195,16 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
{
/* Name mangling: __private becomes _classname__private.
This is independent from how the name is used. */
- const char *p, *name = PyString_AsString(ident);
- char *buffer;
+ const Py_UNICODE *p, *name = PyUnicode_AS_UNICODE(ident);
+ Py_UNICODE *buffer;
size_t nlen, plen;
- if (privateobj == NULL || !PyString_Check(privateobj) ||
+ if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
name == NULL || name[0] != '_' || name[1] != '_') {
Py_INCREF(ident);
return ident;
}
- p = PyString_AsString(privateobj);
- nlen = strlen(name);
+ p = PyUnicode_AS_UNICODE(privateobj);
+ nlen = Py_UNICODE_strlen(name);
/* Don't mangle __id__ or names with dots.
The only time a name with a dot can occur is when
@@ -208,30 +215,30 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
mangling of the module name, e.g. __M.X.
*/
if ((name[nlen-1] == '_' && name[nlen-2] == '_')
- || strchr(name, '.')) {
+ || Py_UNICODE_strchr(name, '.')) {
Py_INCREF(ident);
return ident; /* Don't mangle __whatever__ */
}
/* Strip leading underscores from class name */
while (*p == '_')
p++;
- if (*p == '\0') {
+ if (*p == 0) {
Py_INCREF(ident);
return ident; /* Don't mangle if class is just underscores */
}
- plen = strlen(p);
+ plen = Py_UNICODE_strlen(p);
assert(1 <= PY_SSIZE_T_MAX - nlen);
assert(1 + nlen <= PY_SSIZE_T_MAX - plen);
- ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
+ ident = PyUnicode_FromStringAndSize(NULL, 1 + nlen + plen);
if (!ident)
return 0;
/* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
- buffer = PyString_AS_STRING(ident);
+ buffer = PyUnicode_AS_UNICODE(ident);
buffer[0] = '_';
- strncpy(buffer+1, p, plen);
- strcpy(buffer+1+plen, name);
+ Py_UNICODE_strncpy(buffer+1, p, plen);
+ Py_UNICODE_strcpy(buffer+1+plen, name);
return ident;
}
@@ -248,8 +255,8 @@ compiler_init(struct compiler *c)
}
PyCodeObject *
-PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
- PyArena *arena)
+PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+ int optimize, PyArena *arena)
{
struct compiler c;
PyCodeObject *co = NULL;
@@ -257,7 +264,7 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
int merged;
if (!__doc__) {
- __doc__ = PyString_InternFromString("__doc__");
+ __doc__ = PyUnicode_InternFromString("__doc__");
if (!__doc__)
return NULL;
}
@@ -277,6 +284,7 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
c.c_future->ff_features = merged;
flags->cf_flags = merged;
c.c_flags = flags;
+ c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;
c.c_nestlevel = 0;
c.c_st = PySymtable_Build(mod, filename, c.c_future);
@@ -329,7 +337,7 @@ list2dict(PyObject *list)
n = PyList_Size(list);
for (i = 0; i < n; i++) {
- v = PyInt_FromLong(i);
+ v = PyLong_FromLong(i);
if (!v) {
Py_DECREF(dict);
return NULL;
@@ -382,14 +390,16 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
num_keys = PyList_GET_SIZE(sorted_keys);
for (key_i = 0; key_i < num_keys; key_i++) {
+ /* XXX this should probably be a macro in symtable.h */
+ long vi;
k = PyList_GET_ITEM(sorted_keys, key_i);
v = PyDict_GetItem(src, k);
- /* XXX this should probably be a macro in symtable.h */
- assert(PyInt_Check(v));
- scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
+ assert(PyLong_Check(v));
+ vi = PyLong_AS_LONG(v);
+ scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
- if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
- PyObject *tuple, *item = PyInt_FromLong(i);
+ if (scope == scope_type || vi & flag) {
+ PyObject *tuple, *item = PyLong_FromLong(i);
if (item == NULL) {
Py_DECREF(sorted_keys);
Py_DECREF(dest);
@@ -471,6 +481,7 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key,
}
memset(u, 0, sizeof(struct compiler_unit));
u->u_argcount = 0;
+ u->u_kwonlyargcount = 0;
u->u_ste = PySymtable_Lookup(c->c_st, key);
if (!u->u_ste) {
compiler_unit_free(u);
@@ -496,7 +507,8 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key,
u->u_nfblocks = 0;
u->u_firstlineno = lineno;
u->u_lineno = 0;
- u->u_lineno_set = false;
+ u->u_col_offset = 0;
+ u->u_lineno_set = 0;
u->u_consts = PyDict_New();
if (!u->u_consts) {
compiler_unit_free(u);
@@ -674,7 +686,7 @@ compiler_set_lineno(struct compiler *c, int off)
basicblock *b;
if (c->u->u_lineno_set)
return;
- c->u->u_lineno_set = true;
+ c->u->u_lineno_set = 1;
b = c->u->u_curblock;
b->b_instr[off].i_lineno = c->u->u_lineno;
}
@@ -690,26 +702,23 @@ opcode_stack_effect(int opcode, int oparg)
return 0;
case DUP_TOP:
return 1;
- case ROT_FOUR:
- return 0;
+ case DUP_TOP_TWO:
+ return 2;
case UNARY_POSITIVE:
case UNARY_NEGATIVE:
case UNARY_NOT:
- case UNARY_CONVERT:
case UNARY_INVERT:
return 0;
case SET_ADD:
case LIST_APPEND:
return -1;
-
case MAP_ADD:
return -2;
case BINARY_POWER:
case BINARY_MULTIPLY:
- case BINARY_DIVIDE:
case BINARY_MODULO:
case BINARY_ADD:
case BINARY_SUBTRACT:
@@ -721,37 +730,9 @@ opcode_stack_effect(int opcode, int oparg)
case INPLACE_TRUE_DIVIDE:
return -1;
- case SLICE+0:
- return 0;
- case SLICE+1:
- return -1;
- case SLICE+2:
- return -1;
- case SLICE+3:
- return -2;
-
- case STORE_SLICE+0:
- return -2;
- case STORE_SLICE+1:
- return -3;
- case STORE_SLICE+2:
- return -3;
- case STORE_SLICE+3:
- return -4;
-
- case DELETE_SLICE+0:
- return -1;
- case DELETE_SLICE+1:
- return -2;
- case DELETE_SLICE+2:
- return -2;
- case DELETE_SLICE+3:
- return -3;
-
case INPLACE_ADD:
case INPLACE_SUBTRACT:
case INPLACE_MULTIPLY:
- case INPLACE_DIVIDE:
case INPLACE_MODULO:
return -1;
case STORE_SUBSCR:
@@ -774,14 +755,8 @@ opcode_stack_effect(int opcode, int oparg)
case PRINT_EXPR:
return -1;
- case PRINT_ITEM:
- return -1;
- case PRINT_NEWLINE:
- return 0;
- case PRINT_ITEM_TO:
- return -2;
- case PRINT_NEWLINE_TO:
- return -1;
+ case LOAD_BUILD_CLASS:
+ return 1;
case INPLACE_LSHIFT:
case INPLACE_RSHIFT:
case INPLACE_AND:
@@ -791,27 +766,24 @@ opcode_stack_effect(int opcode, int oparg)
case BREAK_LOOP:
return 0;
case SETUP_WITH:
- return 4;
+ return 7;
case WITH_CLEANUP:
return -1; /* XXX Sometimes more */
- case LOAD_LOCALS:
- return 1;
+ case STORE_LOCALS:
+ return -1;
case RETURN_VALUE:
return -1;
case IMPORT_STAR:
return -1;
- case EXEC_STMT:
- return -3;
case YIELD_VALUE:
return 0;
case POP_BLOCK:
return 0;
+ case POP_EXCEPT:
+ return 0; /* -3 except if bad bytecode */
case END_FINALLY:
- return -3; /* or -1 or -2 if no exception occurred or
- return/break/continue */
- case BUILD_CLASS:
- return -2;
+ return -1; /* or -2 or -3 if exception occurred */
case STORE_NAME:
return -1;
@@ -819,6 +791,8 @@ opcode_stack_effect(int opcode, int oparg)
return 0;
case UNPACK_SEQUENCE:
return oparg-1;
+ case UNPACK_EX:
+ return (oparg&0xFF) + (oparg>>8);
case FOR_ITER:
return 1; /* or -1, at end of iterator */
@@ -830,8 +804,6 @@ opcode_stack_effect(int opcode, int oparg)
return -1;
case DELETE_GLOBAL:
return 0;
- case DUP_TOPX:
- return oparg;
case LOAD_CONST:
return 1;
case LOAD_NAME:
@@ -867,9 +839,11 @@ opcode_stack_effect(int opcode, int oparg)
case CONTINUE_LOOP:
return 0;
case SETUP_LOOP:
+ return 0;
case SETUP_EXCEPT:
case SETUP_FINALLY:
- return 0;
+ return 6; /* can push 3 values for the new exception
+ + 3 others for the previous exception state */
case LOAD_FAST:
return 1;
@@ -880,7 +854,7 @@ opcode_stack_effect(int opcode, int oparg)
case RAISE_VARARGS:
return -oparg;
-#define NARGS(o) (((o) % 256) + 2*((o) / 256))
+#define NARGS(o) (((o) % 256) + 2*(((o) / 256) % 256))
case CALL_FUNCTION:
return -NARGS(oparg);
case CALL_FUNCTION_VAR:
@@ -888,23 +862,25 @@ opcode_stack_effect(int opcode, int oparg)
return -NARGS(oparg)-1;
case CALL_FUNCTION_VAR_KW:
return -NARGS(oparg)-2;
-#undef NARGS
case MAKE_FUNCTION:
- return -oparg;
+ return -NARGS(oparg) - ((oparg >> 16) & 0xffff);
+ case MAKE_CLOSURE:
+ return -1 - NARGS(oparg) - ((oparg >> 16) & 0xffff);
+#undef NARGS
case BUILD_SLICE:
if (oparg == 3)
return -2;
else
return -1;
- case MAKE_CLOSURE:
- return -oparg-1;
case LOAD_CLOSURE:
return 1;
case LOAD_DEREF:
return 1;
case STORE_DEREF:
return -1;
+ case DELETE_DEREF:
+ return 0;
default:
fprintf(stderr, "opcode = %d\n", opcode);
Py_FatalError("opcode_stack_effect()");
@@ -955,7 +931,6 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
else
t = PyTuple_Pack(2, o, o->ob_type);
}
-#ifndef WITHOUT_COMPLEX
else if (PyComplex_Check(o)) {
Py_complex z;
int real_negzero, imag_negzero;
@@ -980,7 +955,6 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
t = PyTuple_Pack(2, o, o->ob_type);
}
}
-#endif /* WITHOUT_COMPLEX */
else {
t = PyTuple_Pack(2, o, o->ob_type);
}
@@ -989,8 +963,10 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
v = PyDict_GetItem(dict, t);
if (!v) {
+ if (PyErr_Occurred())
+ return -1;
arg = PyDict_Size(dict);
- v = PyInt_FromLong(arg);
+ v = PyLong_FromLong(arg);
if (!v) {
Py_DECREF(t);
return -1;
@@ -1003,7 +979,7 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
Py_DECREF(v);
}
else
- arg = PyInt_AsLong(v);
+ arg = PyLong_AsLong(v);
Py_DECREF(t);
return arg;
}
@@ -1195,7 +1171,7 @@ compiler_body(struct compiler *c, asdl_seq *stmts)
if (!asdl_seq_LEN(stmts))
return 1;
st = (stmt_ty)asdl_seq_GET(stmts, 0);
- if (compiler_isdocstring(st) && Py_OptimizeFlag < 2) {
+ if (compiler_isdocstring(st) && c->c_optimize < 2) {
/* don't generate docstrings if -OO */
i = 1;
VISIT(c, expr, st->v.Expr.value);
@@ -1214,7 +1190,7 @@ compiler_mod(struct compiler *c, mod_ty mod)
int addNone = 1;
static PyObject *module;
if (!module) {
- module = PyString_InternFromString("<module>");
+ module = PyUnicode_InternFromString("<module>");
if (!module)
return NULL;
}
@@ -1266,8 +1242,8 @@ get_ref_type(struct compiler *c, PyObject *name)
PyOS_snprintf(buf, sizeof(buf),
"unknown scope for %.100s in %.100s(%s) in %s\n"
"symbols: %s\nlocals: %s\nglobals: %s",
- PyString_AS_STRING(name),
- PyString_AS_STRING(c->u->u_name),
+ 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),
@@ -1291,7 +1267,7 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
Py_DECREF(k);
if (v == NULL)
return -1;
- return PyInt_AS_LONG(v);
+ return PyLong_AS_LONG(v);
}
static int
@@ -1322,12 +1298,13 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, int args)
else /* (reftype == FREE) */
arg = compiler_lookup_arg(c->u->u_freevars, name);
if (arg == -1) {
- printf("lookup %s in %s %d %d\n"
+ fprintf(stderr,
+ "lookup %s in %s %d %d\n"
"freevars of %s: %s\n",
PyObject_REPR(name),
- PyString_AS_STRING(c->u->u_name),
+ PyBytes_AS_STRING(c->u->u_name),
reftype, arg,
- PyString_AS_STRING(co->co_name),
+ _PyUnicode_AsString(co->co_name),
PyObject_REPR(co->co_freevars));
Py_FatalError("compiler_make_closure()");
}
@@ -1354,27 +1331,126 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
}
static int
-compiler_arguments(struct compiler *c, arguments_ty args)
+compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
+ asdl_seq *kw_defaults)
{
- int i;
- int n = asdl_seq_LEN(args->args);
- /* Correctly handle nested argument lists */
- for (i = 0; i < n; i++) {
- expr_ty arg = (expr_ty)asdl_seq_GET(args->args, i);
- if (arg->kind == Tuple_kind) {
- PyObject *id = PyString_FromFormat(".%d", i);
- if (id == NULL) {
- return 0;
- }
- if (!compiler_nameop(c, id, Load)) {
- Py_DECREF(id);
- return 0;
+ int i, default_count = 0;
+ for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
+ arg_ty arg = asdl_seq_GET(kwonlyargs, i);
+ expr_ty default_ = asdl_seq_GET(kw_defaults, i);
+ if (default_) {
+ PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
+ if (!mangled)
+ return -1;
+ ADDOP_O(c, LOAD_CONST, mangled, consts);
+ Py_DECREF(mangled);
+ if (!compiler_visit_expr(c, default_)) {
+ return -1;
}
- Py_DECREF(id);
- VISIT(c, expr, arg);
+ default_count++;
}
}
- return 1;
+ return default_count;
+}
+
+static int
+compiler_visit_argannotation(struct compiler *c, identifier id,
+ expr_ty annotation, PyObject *names)
+{
+ if (annotation) {
+ VISIT(c, expr, annotation);
+ if (PyList_Append(names, id))
+ return -1;
+ }
+ return 0;
+}
+
+static int
+compiler_visit_argannotations(struct compiler *c, asdl_seq* args,
+ PyObject *names)
+{
+ int i, error;
+ for (i = 0; i < asdl_seq_LEN(args); i++) {
+ arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
+ error = compiler_visit_argannotation(
+ c,
+ arg->arg,
+ arg->annotation,
+ names);
+ if (error)
+ return error;
+ }
+ return 0;
+}
+
+static int
+compiler_visit_annotations(struct compiler *c, arguments_ty args,
+ expr_ty returns)
+{
+ /* Push arg annotations and a list of the argument names. Return the #
+ of items pushed. The expressions are evaluated out-of-order wrt the
+ source code.
+
+ More than 2^16-1 annotations is a SyntaxError. Returns -1 on error.
+ */
+ static identifier return_str;
+ PyObject *names;
+ int len;
+ names = PyList_New(0);
+ if (!names)
+ return -1;
+
+ if (compiler_visit_argannotations(c, args->args, names))
+ goto error;
+ if (args->varargannotation &&
+ compiler_visit_argannotation(c, args->vararg,
+ args->varargannotation, 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))
+ goto error;
+
+ if (!return_str) {
+ return_str = PyUnicode_InternFromString("return");
+ if (!return_str)
+ goto error;
+ }
+ if (compiler_visit_argannotation(c, return_str, returns, names)) {
+ goto error;
+ }
+
+ len = PyList_GET_SIZE(names);
+ if (len > 65534) {
+ /* len must fit in 16 bits, and len is incremented below */
+ PyErr_SetString(PyExc_SyntaxError,
+ "too many annotations");
+ goto error;
+ }
+ if (len) {
+ /* convert names to a tuple and place on stack */
+ PyObject *elt;
+ int i;
+ PyObject *s = PyTuple_New(len);
+ if (!s)
+ goto error;
+ for (i = 0; i < len; i++) {
+ elt = PyList_GET_ITEM(names, i);
+ Py_INCREF(elt);
+ PyTuple_SET_ITEM(s, i, elt);
+ }
+ ADDOP_O(c, LOAD_CONST, s, consts);
+ Py_DECREF(s);
+ len++; /* include the just-pushed tuple */
+ }
+ Py_DECREF(names);
+ return len;
+
+error:
+ Py_DECREF(names);
+ return -1;
}
static int
@@ -1383,33 +1459,45 @@ compiler_function(struct compiler *c, stmt_ty s)
PyCodeObject *co;
PyObject *first_const = Py_None;
arguments_ty args = s->v.FunctionDef.args;
+ expr_ty returns = s->v.FunctionDef.returns;
asdl_seq* decos = s->v.FunctionDef.decorator_list;
stmt_ty st;
- int i, n, docstring;
+ int i, n, docstring, kw_default_count = 0, arglength;
+ int num_annotations;
assert(s->kind == FunctionDef_kind);
if (!compiler_decorators(c, decos))
return 0;
+ 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);
+ num_annotations = compiler_visit_annotations(c, args, returns);
+ if (num_annotations < 0)
+ return 0;
+ assert((num_annotations & 0xFFFF) == num_annotations);
+
if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s,
s->lineno))
return 0;
st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0);
docstring = compiler_isdocstring(st);
- if (docstring && Py_OptimizeFlag < 2)
+ if (docstring && c->c_optimize < 2)
first_const = st->v.Expr.value->v.Str.s;
if (compiler_add_o(c, c->u->u_consts, first_const) < 0) {
compiler_exit_scope(c);
return 0;
}
- /* unpack nested arguments */
- compiler_arguments(c, args);
-
c->u->u_argcount = asdl_seq_LEN(args->args);
+ c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
n = asdl_seq_LEN(s->v.FunctionDef.body);
/* if there was a docstring, we need to skip the first statement */
for (i = docstring; i < n; i++) {
@@ -1421,9 +1509,13 @@ compiler_function(struct compiler *c, stmt_ty s)
if (co == NULL)
return 0;
- compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
+ arglength = asdl_seq_LEN(args->defaults);
+ arglength |= kw_default_count << 8;
+ arglength |= num_annotations << 16;
+ compiler_make_closure(c, co, arglength);
Py_DECREF(co);
+ /* decorators */
for (i = 0; i < asdl_seq_LEN(decos); i++) {
ADDOP_I(c, CALL_FUNCTION, 1);
}
@@ -1434,64 +1526,113 @@ compiler_function(struct compiler *c, stmt_ty s)
static int
compiler_class(struct compiler *c, stmt_ty s)
{
- int n, i;
PyCodeObject *co;
PyObject *str;
+ int i;
asdl_seq* decos = s->v.ClassDef.decorator_list;
if (!compiler_decorators(c, decos))
return 0;
- /* push class name on stack, needed by BUILD_CLASS */
- ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts);
- /* push the tuple of base classes on the stack */
- n = asdl_seq_LEN(s->v.ClassDef.bases);
- if (n > 0)
- VISIT_SEQ(c, expr, s->v.ClassDef.bases);
- ADDOP_I(c, BUILD_TUPLE, n);
- if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s,
- s->lineno))
- return 0;
- Py_XDECREF(c->u->u_private);
- c->u->u_private = s->v.ClassDef.name;
- Py_INCREF(c->u->u_private);
- str = PyString_InternFromString("__name__");
- if (!str || !compiler_nameop(c, str, Load)) {
- Py_XDECREF(str);
- compiler_exit_scope(c);
- return 0;
- }
+ /* ultimately generate code for:
+ <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
+ where:
+ <func> is a function/closure created from the class body;
+ it has a single argument (__locals__) where the dict
+ (or MutableSequence) representing the locals is passed
+ <name> is the class name
+ <bases> is the positional arguments and *varargs argument
+ <keywords> is the keyword arguments and **kwds argument
+ This borrows from compiler_call.
+ */
- Py_DECREF(str);
- str = PyString_InternFromString("__module__");
- if (!str || !compiler_nameop(c, str, Store)) {
- Py_XDECREF(str);
- compiler_exit_scope(c);
- return 0;
- }
- Py_DECREF(str);
-
- if (!compiler_body(c, s->v.ClassDef.body)) {
- compiler_exit_scope(c);
+ /* 1. compile the class body into a code object */
+ if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, s->lineno))
return 0;
+ /* this block represents what we do in the new scope */
+ {
+ /* use the class name for name mangling */
+ 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)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ /* ... and store it as __module__ */
+ str = PyUnicode_InternFromString("__module__");
+ if (!str || !compiler_nameop(c, str, Store)) {
+ Py_XDECREF(str);
+ compiler_exit_scope(c);
+ return 0;
+ }
+ Py_DECREF(str);
+ /* compile the body proper */
+ if (!compiler_body(c, s->v.ClassDef.body)) {
+ 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 {
+ /* Return the cell where to store __class__ */
+ ADDOP_I(c, LOAD_CLOSURE, i);
+ }
+ ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ /* create the code object */
+ co = assemble(c, 1);
}
-
- ADDOP_IN_SCOPE(c, LOAD_LOCALS);
- ADDOP_IN_SCOPE(c, RETURN_VALUE);
- co = assemble(c, 1);
+ /* leave the new scope */
compiler_exit_scope(c);
if (co == NULL)
return 0;
+ /* 2. load the 'build_class' function */
+ ADDOP(c, LOAD_BUILD_CLASS);
+
+ /* 3. load a function (or closure) made from the code object */
compiler_make_closure(c, co, 0);
Py_DECREF(co);
- ADDOP_I(c, CALL_FUNCTION, 0);
- ADDOP(c, BUILD_CLASS);
- /* apply decorators */
+ /* 4. load class name */
+ ADDOP_O(c, LOAD_CONST, s->v.ClassDef.name, consts);
+
+ /* 5. generate the rest of the code for the call */
+ if (!compiler_call_helper(c, 2,
+ s->v.ClassDef.bases,
+ s->v.ClassDef.keywords,
+ s->v.ClassDef.starargs,
+ s->v.ClassDef.kwargs))
+ return 0;
+
+ /* 6. apply decorators */
for (i = 0; i < asdl_seq_LEN(decos); i++) {
ADDOP_I(c, CALL_FUNCTION, 1);
}
+
+ /* 7. store into <name> */
if (!compiler_nameop(c, s->v.ClassDef.name, Store))
return 0;
return 1;
@@ -1524,29 +1665,34 @@ compiler_lambda(struct compiler *c, expr_ty e)
{
PyCodeObject *co;
static identifier name;
+ int kw_default_count = 0, arglength;
arguments_ty args = e->v.Lambda.args;
assert(e->kind == Lambda_kind);
if (!name) {
- name = PyString_InternFromString("<lambda>");
+ name = PyUnicode_InternFromString("<lambda>");
if (!name)
return 0;
}
+ 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, (void *)e, e->lineno))
return 0;
- /* unpack nested arguments */
- compiler_arguments(c, args);
-
/* Make None the first constant, so the lambda can't have a
docstring. */
if (compiler_add_o(c, c->u->u_consts, Py_None) < 0)
return 0;
c->u->u_argcount = asdl_seq_LEN(args->args);
+ c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
if (c->u->u_ste->ste_generator) {
ADDOP_IN_SCOPE(c, POP_TOP);
@@ -1559,50 +1705,15 @@ compiler_lambda(struct compiler *c, expr_ty e)
if (co == NULL)
return 0;
- compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
+ arglength = asdl_seq_LEN(args->defaults);
+ arglength |= kw_default_count << 8;
+ compiler_make_closure(c, co, arglength);
Py_DECREF(co);
return 1;
}
static int
-compiler_print(struct compiler *c, stmt_ty s)
-{
- int i, n;
- bool dest;
-
- assert(s->kind == Print_kind);
- n = asdl_seq_LEN(s->v.Print.values);
- dest = false;
- if (s->v.Print.dest) {
- VISIT(c, expr, s->v.Print.dest);
- dest = true;
- }
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(s->v.Print.values, i);
- if (dest) {
- ADDOP(c, DUP_TOP);
- VISIT(c, expr, e);
- ADDOP(c, ROT_TWO);
- ADDOP(c, PRINT_ITEM_TO);
- }
- else {
- VISIT(c, expr, e);
- ADDOP(c, PRINT_ITEM);
- }
- }
- if (s->v.Print.nl) {
- if (dest)
- ADDOP(c, PRINT_NEWLINE_TO)
- else
- ADDOP(c, PRINT_NEWLINE)
- }
- else if (dest)
- ADDOP(c, POP_TOP);
- return 1;
-}
-
-static int
compiler_if(struct compiler *c, stmt_ty s)
{
basicblock *end, *next;
@@ -1612,7 +1723,7 @@ compiler_if(struct compiler *c, stmt_ty s)
if (end == NULL)
return 0;
- constant = expr_constant(s->v.If.test);
+ constant = expr_constant(c, s->v.If.test);
/* constant = 0: "if 0"
* constant = 1: "if 1", "if 2", ...
* constant = -1: rest */
@@ -1674,7 +1785,7 @@ static int
compiler_while(struct compiler *c, stmt_ty s)
{
basicblock *loop, *orelse, *end, *anchor = NULL;
- int constant = expr_constant(s->v.While.test);
+ int constant = expr_constant(c, s->v.While.test);
if (constant == 0) {
if (s->v.While.orelse)
@@ -1821,7 +1932,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
}
/*
- Code generated for "try: S except E1, V1: S1 except E2, V2: S2 ...":
+ Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
(The contents of the value stack is shown in [], with the top
at the right; 'tb' is trace-back info, 'val' the exception's
associated value, and 'exc' the exception.)
@@ -1875,11 +1986,12 @@ compiler_try_except(struct compiler *c, stmt_ty s)
compiler_use_next_block(c, except);
for (i = 0; i < n; i++) {
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
- s->v.TryExcept.handlers, i);
+ s->v.TryExcept.handlers, i);
if (!handler->v.ExceptHandler.type && i < n-1)
return compiler_error(c, "default 'except:' must be last");
- c->u->u_lineno_set = false;
+ c->u->u_lineno_set = 0;
c->u->u_lineno = handler->lineno;
+ c->u->u_col_offset = handler->col_offset;
except = compiler_new_block(c);
if (except == NULL)
return 0;
@@ -1891,13 +2003,71 @@ compiler_try_except(struct compiler *c, stmt_ty s)
}
ADDOP(c, POP_TOP);
if (handler->v.ExceptHandler.name) {
- VISIT(c, expr, handler->v.ExceptHandler.name);
+ basicblock *cleanup_end, *cleanup_body;
+
+ cleanup_end = compiler_new_block(c);
+ cleanup_body = compiler_new_block(c);
+ if (!(cleanup_end || cleanup_body))
+ return 0;
+
+ compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ ADDOP(c, POP_TOP);
+
+ /*
+ try:
+ # body
+ except type as name:
+ try:
+ # body
+ finally:
+ name = None
+ del name
+ */
+
+ /* second try: */
+ ADDOP_JREL(c, SETUP_FINALLY, cleanup_end);
+ compiler_use_next_block(c, cleanup_body);
+ if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body))
+ return 0;
+
+ /* second # body */
+ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ ADDOP(c, POP_BLOCK);
+ ADDOP(c, POP_EXCEPT);
+ compiler_pop_fblock(c, FINALLY_TRY, cleanup_body);
+
+ /* finally: */
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
+ compiler_use_next_block(c, cleanup_end);
+ if (!compiler_push_fblock(c, FINALLY_END, cleanup_end))
+ return 0;
+
+ /* name = None */
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
+ compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+
+ /* del name */
+ compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+
+ ADDOP(c, END_FINALLY);
+ compiler_pop_fblock(c, FINALLY_END, cleanup_end);
}
else {
+ basicblock *cleanup_body;
+
+ cleanup_body = compiler_new_block(c);
+ if (!cleanup_body)
+ return 0;
+
+ ADDOP(c, POP_TOP);
ADDOP(c, POP_TOP);
+ compiler_use_next_block(c, cleanup_body);
+ if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body))
+ return 0;
+ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
+ ADDOP(c, POP_EXCEPT);
+ compiler_pop_fblock(c, FINALLY_TRY, cleanup_body);
}
- ADDOP(c, POP_TOP);
- VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
ADDOP_JREL(c, JUMP_FORWARD, end);
compiler_use_next_block(c, except);
}
@@ -1917,17 +2087,17 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname)
If there is a dot in name, we need to split it and emit a
LOAD_ATTR for each name.
*/
- const char *src = PyString_AS_STRING(name);
- const char *dot = strchr(src, '.');
+ const Py_UNICODE *src = PyUnicode_AS_UNICODE(name);
+ const Py_UNICODE *dot = Py_UNICODE_strchr(src, '.');
if (dot) {
/* Consume the base module name to get the first attribute */
src = dot + 1;
while (dot) {
/* NB src is only defined when dot != NULL */
PyObject *attr;
- dot = strchr(src, '.');
- attr = PyString_FromStringAndSize(src,
- dot ? dot - src : strlen(src));
+ dot = Py_UNICODE_strchr(src, '.');
+ attr = PyUnicode_FromUnicode(src,
+ dot ? dot - src : Py_UNICODE_strlen(src));
if (!attr)
return -1;
ADDOP_O(c, LOAD_ATTR, attr, names);
@@ -1955,11 +2125,7 @@ compiler_import(struct compiler *c, stmt_ty s)
int r;
PyObject *level;
- if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
- level = PyInt_FromLong(0);
- else
- level = PyInt_FromLong(-1);
-
+ level = PyLong_FromLong(0);
if (level == NULL)
return 0;
@@ -1975,11 +2141,11 @@ compiler_import(struct compiler *c, stmt_ty s)
}
else {
identifier tmp = alias->name;
- const char *base = PyString_AS_STRING(alias->name);
- char *dot = strchr(base, '.');
+ const Py_UNICODE *base = PyUnicode_AS_UNICODE(alias->name);
+ Py_UNICODE *dot = Py_UNICODE_strchr(base, '.');
if (dot)
- tmp = PyString_FromStringAndSize(base,
- dot - base);
+ tmp = PyUnicode_FromUnicode(base,
+ dot - base);
r = compiler_nameop(c, tmp, Store);
if (dot) {
Py_DECREF(tmp);
@@ -2001,7 +2167,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
static PyObject *empty_string;
if (!empty_string) {
- empty_string = PyString_FromString("");
+ empty_string = PyUnicode_FromString("");
if (!empty_string)
return 0;
}
@@ -2009,12 +2175,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
if (!names)
return 0;
- if (s->v.ImportFrom.level == 0 && c->c_flags &&
- !(c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
- level = PyInt_FromLong(-1);
- else
- level = PyInt_FromLong(s->v.ImportFrom.level);
-
+ level = PyLong_FromLong(s->v.ImportFrom.level);
if (!level) {
Py_DECREF(names);
return 0;
@@ -2028,7 +2189,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
}
if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
- !strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) {
+ !PyUnicode_CompareWithASCIIString(s->v.ImportFrom.module, "__future__")) {
Py_DECREF(level);
Py_DECREF(names);
return compiler_error(c, "from __future__ imports must occur "
@@ -2049,7 +2210,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
identifier store_name;
- if (i == 0 && *PyString_AS_STRING(alias->name) == '*') {
+ if (i == 0 && *PyUnicode_AS_UNICODE(alias->name) == '*') {
assert(n == 1);
ADDOP(c, IMPORT_STAR);
return 1;
@@ -2076,10 +2237,10 @@ compiler_assert(struct compiler *c, stmt_ty s)
static PyObject *assertion_error = NULL;
basicblock *end;
- if (Py_OptimizeFlag)
+ if (c->c_optimize)
return 1;
if (assertion_error == NULL) {
- assertion_error = PyString_InternFromString("AssertionError");
+ assertion_error = PyUnicode_InternFromString("AssertionError");
if (assertion_error == NULL)
return 0;
}
@@ -2113,7 +2274,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
/* Always assign a lineno to the next instruction for a stmt. */
c->u->u_lineno = s->lineno;
- c->u->u_lineno_set = false;
+ c->u->u_col_offset = s->col_offset;
+ c->u->u_lineno_set = 0;
switch (s->kind) {
case FunctionDef_kind:
@@ -2145,8 +2307,6 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
break;
case AugAssign_kind:
return compiler_augassign(c, s);
- case Print_kind:
- return compiler_print(c, s);
case For_kind:
return compiler_for(c, s);
case While_kind:
@@ -2155,17 +2315,13 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
return compiler_if(c, s);
case Raise_kind:
n = 0;
- if (s->v.Raise.type) {
- VISIT(c, expr, s->v.Raise.type);
+ if (s->v.Raise.exc) {
+ VISIT(c, expr, s->v.Raise.exc);
n++;
- if (s->v.Raise.inst) {
- VISIT(c, expr, s->v.Raise.inst);
- n++;
- if (s->v.Raise.tback) {
- VISIT(c, expr, s->v.Raise.tback);
- n++;
- }
- }
+ if (s->v.Raise.cause) {
+ VISIT(c, expr, s->v.Raise.cause);
+ n++;
+ }
}
ADDOP_I(c, RAISE_VARARGS, n);
break;
@@ -2179,22 +2335,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
return compiler_import(c, s);
case ImportFrom_kind:
return compiler_from_import(c, s);
- case Exec_kind:
- VISIT(c, expr, s->v.Exec.body);
- if (s->v.Exec.globals) {
- VISIT(c, expr, s->v.Exec.globals);
- if (s->v.Exec.locals) {
- VISIT(c, expr, s->v.Exec.locals);
- } else {
- ADDOP(c, DUP_TOP);
- }
- } else {
- ADDOP_O(c, LOAD_CONST, Py_None, consts);
- ADDOP(c, DUP_TOP);
- }
- ADDOP(c, EXEC_STMT);
- break;
case Global_kind:
+ case Nonlocal_kind:
break;
case Expr_kind:
if (c->c_interactive && c->c_nestlevel <= 1) {
@@ -2252,10 +2394,7 @@ binop(struct compiler *c, operator_ty op)
case Mult:
return BINARY_MULTIPLY;
case Div:
- if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
- return BINARY_TRUE_DIVIDE;
- else
- return BINARY_DIVIDE;
+ return BINARY_TRUE_DIVIDE;
case Mod:
return BINARY_MODULO;
case Pow:
@@ -2319,10 +2458,7 @@ inplace_binop(struct compiler *c, operator_ty op)
case Mult:
return INPLACE_MULTIPLY;
case Div:
- if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
- return INPLACE_TRUE_DIVIDE;
- else
- return INPLACE_DIVIDE;
+ return INPLACE_TRUE_DIVIDE;
case Mod:
return INPLACE_MODULO;
case Pow:
@@ -2390,7 +2526,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
}
/* XXX Leave assert here, but handle __doc__ and the like better */
- assert(scope || PyString_AS_STRING(name)[0] == '_');
+ assert(scope || PyUnicode_AS_UNICODE(name)[0] == '_');
switch (optype) {
case OP_DEREF:
@@ -2400,13 +2536,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
case AugLoad:
case AugStore:
break;
- case Del:
- PyErr_Format(PyExc_SyntaxError,
- "can not delete variable '%s' referenced "
- "in nested scope",
- PyString_AS_STRING(name));
- Py_DECREF(mangled);
- return 0;
+ case Del: op = DELETE_DEREF; break;
case Param:
default:
PyErr_SetString(PyExc_SystemError,
@@ -2503,7 +2633,26 @@ compiler_list(struct compiler *c, expr_ty e)
{
int n = asdl_seq_LEN(e->v.List.elts);
if (e->v.List.ctx == Store) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
+ int i, seen_star = 0;
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(e->v.List.elts, i);
+ if (elt->kind == Starred_kind && !seen_star) {
+ if ((i >= (1 << 8)) ||
+ (n-i-1 >= (INT_MAX >> 8)))
+ return compiler_error(c,
+ "too many expressions in "
+ "star-unpacking assignment");
+ ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
+ seen_star = 1;
+ asdl_seq_SET(e->v.List.elts, i, elt->v.Starred.value);
+ } else if (elt->kind == Starred_kind) {
+ return compiler_error(c,
+ "two starred expressions in assignment");
+ }
+ }
+ if (!seen_star) {
+ ADDOP_I(c, UNPACK_SEQUENCE, n);
+ }
}
VISIT_SEQ(c, expr, e->v.List.elts);
if (e->v.List.ctx == Load) {
@@ -2517,7 +2666,26 @@ compiler_tuple(struct compiler *c, expr_ty e)
{
int n = asdl_seq_LEN(e->v.Tuple.elts);
if (e->v.Tuple.ctx == Store) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
+ int i, seen_star = 0;
+ for (i = 0; i < n; i++) {
+ expr_ty elt = asdl_seq_GET(e->v.Tuple.elts, i);
+ if (elt->kind == Starred_kind && !seen_star) {
+ if ((i >= (1 << 8)) ||
+ (n-i-1 >= (INT_MAX >> 8)))
+ return compiler_error(c,
+ "too many expressions in "
+ "star-unpacking assignment");
+ ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
+ seen_star = 1;
+ asdl_seq_SET(e->v.Tuple.elts, i, elt->v.Starred.value);
+ } else if (elt->kind == Starred_kind) {
+ return compiler_error(c,
+ "two starred expressions in assignment");
+ }
+ }
+ if (!seen_star) {
+ ADDOP_I(c, UNPACK_SEQUENCE, n);
+ }
}
VISIT_SEQ(c, expr, e->v.Tuple.elts);
if (e->v.Tuple.ctx == Load) {
@@ -2574,21 +2742,37 @@ compiler_compare(struct compiler *c, expr_ty e)
static int
compiler_call(struct compiler *c, expr_ty e)
{
- int n, code = 0;
-
VISIT(c, expr, e->v.Call.func);
- n = asdl_seq_LEN(e->v.Call.args);
- VISIT_SEQ(c, expr, e->v.Call.args);
- if (e->v.Call.keywords) {
- VISIT_SEQ(c, keyword, e->v.Call.keywords);
- n |= asdl_seq_LEN(e->v.Call.keywords) << 8;
- }
- if (e->v.Call.starargs) {
- VISIT(c, expr, e->v.Call.starargs);
+ return compiler_call_helper(c, 0,
+ e->v.Call.args,
+ e->v.Call.keywords,
+ e->v.Call.starargs,
+ e->v.Call.kwargs);
+}
+
+/* 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)
+{
+ int code = 0;
+
+ n += asdl_seq_LEN(args);
+ VISIT_SEQ(c, expr, args);
+ if (keywords) {
+ VISIT_SEQ(c, keyword, keywords);
+ n |= asdl_seq_LEN(keywords) << 8;
+ }
+ if (starargs) {
+ VISIT(c, expr, starargs);
code |= 1;
}
- if (e->v.Call.kwargs) {
- VISIT(c, expr, e->v.Call.kwargs);
+ if (kwargs) {
+ VISIT(c, expr, kwargs);
code |= 2;
}
switch (code) {
@@ -2608,82 +2792,19 @@ compiler_call(struct compiler *c, expr_ty e)
return 1;
}
-static int
-compiler_listcomp_generator(struct compiler *c, asdl_seq *generators,
- int gen_index, expr_ty elt)
-{
- /* generate code for the iterator, then each of the ifs,
- and then write to the element */
-
- comprehension_ty l;
- basicblock *start, *anchor, *skip, *if_cleanup;
- int i, n;
-
- start = compiler_new_block(c);
- skip = compiler_new_block(c);
- if_cleanup = compiler_new_block(c);
- anchor = compiler_new_block(c);
-
- if (start == NULL || skip == NULL || if_cleanup == NULL ||
- anchor == NULL)
- return 0;
-
- l = (comprehension_ty)asdl_seq_GET(generators, gen_index);
- VISIT(c, expr, l->iter);
- ADDOP(c, GET_ITER);
- compiler_use_next_block(c, start);
- ADDOP_JREL(c, FOR_ITER, anchor);
- NEXT_BLOCK(c);
- VISIT(c, expr, l->target);
-
- /* XXX this needs to be cleaned up...a lot! */
- n = asdl_seq_LEN(l->ifs);
- for (i = 0; i < n; i++) {
- expr_ty e = (expr_ty)asdl_seq_GET(l->ifs, i);
- VISIT(c, expr, e);
- ADDOP_JABS(c, POP_JUMP_IF_FALSE, if_cleanup);
- NEXT_BLOCK(c);
- }
-
- if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_listcomp_generator(c, generators, gen_index, elt))
- return 0;
-
- /* only append after the last for generator */
- if (gen_index >= asdl_seq_LEN(generators)) {
- VISIT(c, expr, elt);
- ADDOP_I(c, LIST_APPEND, gen_index+1);
-
- compiler_use_next_block(c, skip);
- }
- compiler_use_next_block(c, if_cleanup);
- ADDOP_JABS(c, JUMP_ABSOLUTE, start);
- compiler_use_next_block(c, anchor);
- return 1;
-}
+/* List and set comprehensions and generator expressions work by creating a
+ nested function to perform the actual iteration. This means that the
+ iteration variables don't leak into the current scope.
+ The defined function is called immediately following its definition, with the
+ result of that call being the result of the expression.
+ The LC/SC version returns the populated container, while the GE version is
+ flagged in symtable.c as a generator, so it returns the generator object
+ when the function is called.
+ This code *knows* that the loop cannot contain break, continue, or return,
+ so it cheats and skips the SETUP_LOOP/POP_BLOCK steps used in normal loops.
-static int
-compiler_listcomp(struct compiler *c, expr_ty e)
-{
- assert(e->kind == ListComp_kind);
- ADDOP_I(c, BUILD_LIST, 0);
- return compiler_listcomp_generator(c, e->v.ListComp.generators, 0,
- e->v.ListComp.elt);
-}
-
-/* Dict and set comprehensions and generator expressions work by creating a
- nested function to perform the actual iteration. This means that the
- iteration variables don't leak into the current scope.
- The defined function is called immediately following its definition, with the
- result of that call being the result of the expression.
- The LC/SC version returns the populated container, while the GE version is
- flagged in symtable.c as a generator, so it returns the generator object
- when the function is called.
- This code *knows* that the loop cannot contain break, continue, or return,
- so it cheats and skips the SETUP_LOOP/POP_BLOCK steps used in normal loops.
-
- Possible cleanups:
+ Possible cleanups:
- iterate over the generator sequence instead of using recursion
*/
@@ -2749,6 +2870,10 @@ compiler_comprehension_generator(struct compiler *c,
ADDOP(c, YIELD_VALUE);
ADDOP(c, POP_TOP);
break;
+ case COMP_LISTCOMP:
+ VISIT(c, expr, elt);
+ ADDOP_I(c, LIST_APPEND, gen_index + 1);
+ break;
case COMP_SETCOMP:
VISIT(c, expr, elt);
ADDOP_I(c, SET_ADD, gen_index + 1);
@@ -2789,6 +2914,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name,
if (type != COMP_GENEXP) {
int op;
switch (type) {
+ case COMP_LISTCOMP:
+ op = BUILD_LIST;
+ break;
case COMP_SETCOMP:
op = BUILD_SET;
break;
@@ -2837,7 +2965,7 @@ compiler_genexp(struct compiler *c, expr_ty e)
{
static identifier name;
if (!name) {
- name = PyString_FromString("<genexpr>");
+ name = PyUnicode_FromString("<genexpr>");
if (!name)
return 0;
}
@@ -2848,11 +2976,26 @@ compiler_genexp(struct compiler *c, expr_ty e)
}
static int
+compiler_listcomp(struct compiler *c, expr_ty e)
+{
+ static identifier name;
+ if (!name) {
+ name = PyUnicode_FromString("<listcomp>");
+ if (!name)
+ return 0;
+ }
+ assert(e->kind == ListComp_kind);
+ return compiler_comprehension(c, e, COMP_LISTCOMP, name,
+ e->v.ListComp.generators,
+ e->v.ListComp.elt, NULL);
+}
+
+static int
compiler_setcomp(struct compiler *c, expr_ty e)
{
static identifier name;
if (!name) {
- name = PyString_FromString("<setcomp>");
+ name = PyUnicode_FromString("<setcomp>");
if (!name)
return 0;
}
@@ -2862,12 +3005,13 @@ compiler_setcomp(struct compiler *c, expr_ty e)
e->v.SetComp.elt, NULL);
}
+
static int
compiler_dictcomp(struct compiler *c, expr_ty e)
{
static identifier name;
if (!name) {
- name = PyString_FromString("<dictcomp>");
+ name = PyUnicode_FromString("<dictcomp>");
if (!name)
return 0;
}
@@ -2877,6 +3021,7 @@ compiler_dictcomp(struct compiler *c, expr_ty e)
e->v.DictComp.key, e->v.DictComp.value);
}
+
static int
compiler_visit_keyword(struct compiler *c, keyword_ty k)
{
@@ -2892,19 +3037,25 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
*/
static int
-expr_constant(expr_ty e)
+expr_constant(struct compiler *c, expr_ty e)
{
+ char *id;
switch (e->kind) {
+ case Ellipsis_kind:
+ return 1;
case Num_kind:
return PyObject_IsTrue(e->v.Num.n);
case Str_kind:
return PyObject_IsTrue(e->v.Str.s);
case Name_kind:
- /* __debug__ is not assignable, so we can optimize
- * it away in if and while statements */
- if (strcmp(PyString_AS_STRING(e->v.Name.id),
- "__debug__") == 0)
- return ! Py_OptimizeFlag;
+ /* optimize away names that can't be reassigned */
+ id = PyBytes_AS_STRING(
+ _PyUnicode_AsDefaultEncodedString(e->v.Name.id, NULL));
+ 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 */
default:
return -1;
@@ -2952,9 +3103,6 @@ compiler_with(struct compiler *c, stmt_ty s)
/* SETUP_WITH pushes a finally block. */
compiler_use_next_block(c, block);
- /* Note that the block is actually called SETUP_WITH in ceval.c, but
- functions the same as SETUP_FINALLY except that exceptions are
- normalized. */
if (!compiler_push_fblock(c, FINALLY_TRY, block)) {
return 0;
}
@@ -3000,8 +3148,10 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
*/
if (e->lineno > c->u->u_lineno) {
c->u->u_lineno = e->lineno;
- c->u->u_lineno_set = false;
+ c->u->u_lineno_set = 0;
}
+ /* Updating the column offset is always harmless. */
+ c->u->u_col_offset = e->col_offset;
switch (e->kind) {
case BoolOp_kind:
return compiler_boolop(c, e);
@@ -3034,14 +3184,14 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
VISIT_SEQ(c, expr, e->v.Set.elts);
ADDOP_I(c, BUILD_SET, n);
break;
+ case GeneratorExp_kind:
+ return compiler_genexp(c, e);
case ListComp_kind:
return compiler_listcomp(c, e);
case SetComp_kind:
return compiler_setcomp(c, e);
case DictComp_kind:
return compiler_dictcomp(c, e);
- case GeneratorExp_kind:
- return compiler_genexp(c, e);
case Yield_kind:
if (c->u->u_ste->ste_type != FunctionBlock)
return compiler_error(c, "'yield' outside function");
@@ -3057,16 +3207,18 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
return compiler_compare(c, e);
case Call_kind:
return compiler_call(c, e);
- case Repr_kind:
- VISIT(c, expr, e->v.Repr.value);
- ADDOP(c, UNARY_CONVERT);
- break;
case Num_kind:
ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts);
break;
case Str_kind:
ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts);
break;
+ case Bytes_kind:
+ ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts);
+ break;
+ case Ellipsis_kind:
+ ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
+ break;
/* The following exprs can be assignment targets. */
case Attribute_kind:
if (e->v.Attribute.ctx != AugStore)
@@ -3122,6 +3274,18 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
return 0;
}
break;
+ case Starred_kind:
+ switch (e->v.Starred.ctx) {
+ case Store:
+ /* In all legitimate cases, the Starred node was already replaced
+ * by compiler_list/compiler_tuple. XXX: is that okay? */
+ return compiler_error(c,
+ "starred assignment target must be in a list or tuple");
+ default:
+ return compiler_error(c,
+ "can use starred expression only as assignment target");
+ }
+ break;
case Name_kind:
return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
/* child nodes of List and Tuple will have expr_context set */
@@ -3221,7 +3385,7 @@ compiler_in_loop(struct compiler *c) {
static int
compiler_error(struct compiler *c, const char *errstr)
{
- PyObject *loc;
+ PyObject *loc, *filename;
PyObject *u = NULL, *v = NULL;
loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);
@@ -3229,8 +3393,17 @@ compiler_error(struct compiler *c, const char *errstr)
Py_INCREF(Py_None);
loc = Py_None;
}
- u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno,
- Py_None, loc);
+ if (c->c_filename != NULL) {
+ filename = PyUnicode_DecodeFSDefault(c->c_filename);
+ if (!filename)
+ goto exit;
+ }
+ else {
+ Py_INCREF(Py_None);
+ filename = Py_None;
+ }
+ u = Py_BuildValue("(NiiO)", filename, c->u->u_lineno,
+ c->u->u_col_offset, loc);
if (!u)
goto exit;
v = Py_BuildValue("(zO)", errstr, u);
@@ -3264,7 +3437,7 @@ compiler_handle_subscr(struct compiler *c, const char *kind,
return 0;
}
if (ctx == AugLoad) {
- ADDOP_I(c, DUP_TOPX, 2);
+ ADDOP(c, DUP_TOP_TWO);
}
else if (ctx == AugStore) {
ADDOP(c, ROT_THREE);
@@ -3303,64 +3476,10 @@ compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
}
static int
-compiler_simple_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
-{
- int op = 0, slice_offset = 0, stack_count = 0;
-
- assert(s->v.Slice.step == NULL);
- if (s->v.Slice.lower) {
- slice_offset++;
- stack_count++;
- if (ctx != AugStore)
- VISIT(c, expr, s->v.Slice.lower);
- }
- if (s->v.Slice.upper) {
- slice_offset += 2;
- stack_count++;
- if (ctx != AugStore)
- VISIT(c, expr, s->v.Slice.upper);
- }
-
- if (ctx == AugLoad) {
- switch (stack_count) {
- case 0: ADDOP(c, DUP_TOP); break;
- case 1: ADDOP_I(c, DUP_TOPX, 2); break;
- case 2: ADDOP_I(c, DUP_TOPX, 3); break;
- }
- }
- else if (ctx == AugStore) {
- switch (stack_count) {
- case 0: ADDOP(c, ROT_TWO); break;
- case 1: ADDOP(c, ROT_THREE); break;
- case 2: ADDOP(c, ROT_FOUR); break;
- }
- }
-
- switch (ctx) {
- case AugLoad: /* fall through to Load */
- case Load: op = SLICE; break;
- case AugStore:/* fall through to Store */
- case Store: op = STORE_SLICE; break;
- case Del: op = DELETE_SLICE; break;
- case Param:
- default:
- PyErr_SetString(PyExc_SystemError,
- "param invalid in simple slice");
- return 0;
- }
-
- ADDOP(c, op + slice_offset);
- return 1;
-}
-
-static int
compiler_visit_nested_slice(struct compiler *c, slice_ty s,
expr_context_ty ctx)
{
switch (s->kind) {
- case Ellipsis_kind:
- ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
- break;
case Slice_kind:
return compiler_slice(c, s, ctx);
case Index_kind:
@@ -3386,16 +3505,8 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
VISIT(c, expr, s->v.Index.value);
}
break;
- case Ellipsis_kind:
- kindname = "ellipsis";
- if (ctx != AugStore) {
- ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
- }
- break;
case Slice_kind:
kindname = "slice";
- if (!s->v.Slice.step)
- return compiler_simple_slice(c, s, ctx);
if (ctx != AugStore) {
if (!compiler_slice(c, s, ctx))
return 0;
@@ -3422,7 +3533,6 @@ compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx)
return compiler_handle_subscr(c, kindname, ctx);
}
-
/* End of the compiler section, beginning of the assembler section */
/* do depth-first search of basic block graph, starting with block.
@@ -3524,10 +3634,10 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)
{
memset(a, 0, sizeof(struct assembler));
a->a_lineno = firstlineno;
- a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
+ a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
if (!a->a_bytecode)
return 0;
- a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
+ a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
if (!a->a_lnotab)
return 0;
if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) {
@@ -3598,7 +3708,7 @@ assemble_lnotab(struct assembler *a, struct instr *i)
if (d_bytecode > 255) {
int j, nbytes, ncodes = d_bytecode / 255;
nbytes = a->a_lnotab_off + 2 * ncodes;
- len = PyString_GET_SIZE(a->a_lnotab);
+ len = PyBytes_GET_SIZE(a->a_lnotab);
if (nbytes >= len) {
if ((len <= INT_MAX / 2) && (len * 2 < nbytes))
len = nbytes;
@@ -3608,11 +3718,11 @@ assemble_lnotab(struct assembler *a, struct instr *i)
PyErr_NoMemory();
return 0;
}
- if (_PyString_Resize(&a->a_lnotab, len) < 0)
+ if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
for (j = 0; j < ncodes; j++) {
*lnotab++ = 255;
*lnotab++ = 0;
@@ -3624,7 +3734,7 @@ assemble_lnotab(struct assembler *a, struct instr *i)
if (d_lineno > 255) {
int j, nbytes, ncodes = d_lineno / 255;
nbytes = a->a_lnotab_off + 2 * ncodes;
- len = PyString_GET_SIZE(a->a_lnotab);
+ len = PyBytes_GET_SIZE(a->a_lnotab);
if (nbytes >= len) {
if ((len <= INT_MAX / 2) && len * 2 < nbytes)
len = nbytes;
@@ -3634,11 +3744,11 @@ assemble_lnotab(struct assembler *a, struct instr *i)
PyErr_NoMemory();
return 0;
}
- if (_PyString_Resize(&a->a_lnotab, len) < 0)
+ if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
*lnotab++ = d_bytecode;
*lnotab++ = 255;
d_bytecode = 0;
@@ -3650,13 +3760,13 @@ assemble_lnotab(struct assembler *a, struct instr *i)
a->a_lnotab_off += ncodes * 2;
}
- len = PyString_GET_SIZE(a->a_lnotab);
+ len = PyBytes_GET_SIZE(a->a_lnotab);
if (a->a_lnotab_off + 2 >= len) {
- if (_PyString_Resize(&a->a_lnotab, len * 2) < 0)
+ if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
a->a_lnotab_off += 2;
if (d_bytecode) {
@@ -3681,7 +3791,7 @@ static int
assemble_emit(struct assembler *a, struct instr *i)
{
int size, arg = 0, ext = 0;
- Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode);
+ Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
char *code;
size = instrsize(i);
@@ -3694,10 +3804,10 @@ assemble_emit(struct assembler *a, struct instr *i)
if (a->a_offset + size >= len) {
if (len > PY_SSIZE_T_MAX / 2)
return 0;
- if (_PyString_Resize(&a->a_bytecode, len * 2) < 0)
+ if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
return 0;
}
- code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
+ code = PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
a->a_offset += size;
if (size == 6) {
assert(i->i_hasarg);
@@ -3783,7 +3893,7 @@ dict_keys_inorder(PyObject *dict, int offset)
if (tuple == NULL)
return NULL;
while (PyDict_Next(dict, &pos, &k, &v)) {
- i = PyInt_AS_LONG(v);
+ i = PyLong_AS_LONG(v);
/* The keys of the dictionary are tuples. (see compiler_add_o)
The object we want is always first, though. */
k = PyTuple_GET_ITEM(k, 0);
@@ -3865,7 +3975,7 @@ makecode(struct compiler *c, struct assembler *a)
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
if (!freevars)
goto error;
- filename = PyString_FromString(c->c_filename);
+ filename = PyUnicode_DecodeFSDefault(c->c_filename);
if (!filename)
goto error;
@@ -3884,7 +3994,8 @@ makecode(struct compiler *c, struct assembler *a)
Py_DECREF(consts);
consts = tmp;
- co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags,
+ co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount,
+ nlocals, stackdepth(c), flags,
bytecode, consts, names, varnames,
freevars, cellvars,
filename, c->u->u_name,
@@ -3985,9 +4096,9 @@ assemble(struct compiler *c, int addNone)
goto error;
}
- if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
+ if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
goto error;
- if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0)
+ if (_PyBytes_Resize(&a.a_bytecode, a.a_offset) < 0)
goto error;
co = makecode(c, &a);
@@ -3995,3 +4106,13 @@ assemble(struct compiler *c, int addNone)
assemble_free(&a);
return co;
}
+
+#undef PyAST_Compile
+PyAPI_FUNC(PyCodeObject *)
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+ PyArena *arena)
+{
+ return PyAST_CompileEx(mod, filename, flags, -1, arena);
+}
+
+