summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c1081
1 files changed, 492 insertions, 589 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 1d6e38c..531bed4 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -25,8 +25,10 @@
#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"
@@ -38,9 +40,8 @@ int Py_OptimizeFlag = 0;
#define DEFAULT_LNOTAB_SIZE 16
#define COMP_GENEXP 0
-#define COMP_LISTCOMP 1
-#define COMP_SETCOMP 2
-#define COMP_DICTCOMP 3
+#define COMP_SETCOMP 1
+#define COMP_DICTCOMP 2
struct instr {
unsigned i_jabs : 1;
@@ -110,7 +111,6 @@ 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,8 +121,7 @@ struct compiler_unit {
int u_firstlineno; /* the first lineno of the block */
int u_lineno; /* the lineno for the current stmt */
- int u_col_offset; /* the offset of the current stmt */
- int u_lineno_set; /* boolean to indicate whether instr
+ bool u_lineno_set; /* boolean to indicate whether instr
has been generated with current lineno */
};
@@ -139,7 +138,6 @@ 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;
@@ -176,14 +174,9 @@ 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(struct compiler *, expr_ty);
+static int expr_constant(expr_ty e);
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__;
@@ -195,16 +188,16 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
{
/* Name mangling: __private becomes _classname__private.
This is independent from how the name is used. */
- const Py_UNICODE *p, *name = PyUnicode_AS_UNICODE(ident);
- Py_UNICODE *buffer;
+ const char *p, *name = PyString_AsString(ident);
+ char *buffer;
size_t nlen, plen;
- if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
+ if (privateobj == NULL || !PyString_Check(privateobj) ||
name == NULL || name[0] != '_' || name[1] != '_') {
Py_INCREF(ident);
return ident;
}
- p = PyUnicode_AS_UNICODE(privateobj);
- nlen = Py_UNICODE_strlen(name);
+ p = PyString_AsString(privateobj);
+ nlen = strlen(name);
/* Don't mangle __id__ or names with dots.
The only time a name with a dot can occur is when
@@ -215,30 +208,30 @@ _Py_Mangle(PyObject *privateobj, PyObject *ident)
mangling of the module name, e.g. __M.X.
*/
if ((name[nlen-1] == '_' && name[nlen-2] == '_')
- || Py_UNICODE_strchr(name, '.')) {
+ || 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 = Py_UNICODE_strlen(p);
+ plen = strlen(p);
assert(1 <= PY_SSIZE_T_MAX - nlen);
assert(1 + nlen <= PY_SSIZE_T_MAX - plen);
- ident = PyUnicode_FromStringAndSize(NULL, 1 + nlen + plen);
+ ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
if (!ident)
return 0;
/* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
- buffer = PyUnicode_AS_UNICODE(ident);
+ buffer = PyString_AS_STRING(ident);
buffer[0] = '_';
- Py_UNICODE_strncpy(buffer+1, p, plen);
- Py_UNICODE_strcpy(buffer+1+plen, name);
+ strncpy(buffer+1, p, plen);
+ strcpy(buffer+1+plen, name);
return ident;
}
@@ -255,8 +248,8 @@ compiler_init(struct compiler *c)
}
PyCodeObject *
-PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
- int optimize, PyArena *arena)
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+ PyArena *arena)
{
struct compiler c;
PyCodeObject *co = NULL;
@@ -264,7 +257,7 @@ PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
int merged;
if (!__doc__) {
- __doc__ = PyUnicode_InternFromString("__doc__");
+ __doc__ = PyString_InternFromString("__doc__");
if (!__doc__)
return NULL;
}
@@ -284,7 +277,6 @@ PyAST_CompileEx(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);
@@ -337,7 +329,7 @@ list2dict(PyObject *list)
n = PyList_Size(list);
for (i = 0; i < n; i++) {
- v = PyLong_FromLong(i);
+ v = PyInt_FromLong(i);
if (!v) {
Py_DECREF(dict);
return NULL;
@@ -367,29 +359,46 @@ each key.
static PyObject *
dictbytype(PyObject *src, int scope_type, int flag, int offset)
{
- Py_ssize_t pos = 0, i = offset, scope;
+ Py_ssize_t i = offset, scope, num_keys, key_i;
PyObject *k, *v, *dest = PyDict_New();
+ PyObject *sorted_keys;
assert(offset >= 0);
if (dest == NULL)
return NULL;
- while (PyDict_Next(src, &pos, &k, &v)) {
+ /* Sort the keys so that we have a deterministic order on the indexes
+ saved in the returned dictionary. These indexes are used as indexes
+ into the free and cell var storage. Therefore if they aren't
+ deterministic, then the generated bytecode is not deterministic.
+ */
+ sorted_keys = PyDict_Keys(src);
+ if (sorted_keys == NULL)
+ return NULL;
+ if (PyList_Sort(sorted_keys) != 0) {
+ Py_DECREF(sorted_keys);
+ return NULL;
+ }
+ num_keys = PyList_GET_SIZE(sorted_keys);
+
+ for (key_i = 0; key_i < num_keys; key_i++) {
+ k = PyList_GET_ITEM(sorted_keys, key_i);
+ v = PyDict_GetItem(src, k);
/* XXX this should probably be a macro in symtable.h */
- long vi;
- assert(PyLong_Check(v));
- vi = PyLong_AS_LONG(v);
- scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
+ assert(PyInt_Check(v));
+ scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
- if (scope == scope_type || vi & flag) {
- PyObject *tuple, *item = PyLong_FromLong(i);
+ if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
+ PyObject *tuple, *item = PyInt_FromLong(i);
if (item == NULL) {
+ Py_DECREF(sorted_keys);
Py_DECREF(dest);
return NULL;
}
i++;
tuple = PyTuple_Pack(2, k, k->ob_type);
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
+ Py_DECREF(sorted_keys);
Py_DECREF(item);
Py_DECREF(dest);
Py_XDECREF(tuple);
@@ -399,6 +408,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
Py_DECREF(tuple);
}
}
+ Py_DECREF(sorted_keys);
return dest;
}
@@ -461,7 +471,6 @@ 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);
@@ -487,8 +496,7 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key,
u->u_nfblocks = 0;
u->u_firstlineno = lineno;
u->u_lineno = 0;
- u->u_col_offset = 0;
- u->u_lineno_set = 0;
+ u->u_lineno_set = false;
u->u_consts = PyDict_New();
if (!u->u_consts) {
compiler_unit_free(u);
@@ -666,7 +674,7 @@ compiler_set_lineno(struct compiler *c, int off)
basicblock *b;
if (c->u->u_lineno_set)
return;
- c->u->u_lineno_set = 1;
+ c->u->u_lineno_set = true;
b = c->u->u_curblock;
b->b_instr[off].i_lineno = c->u->u_lineno;
}
@@ -682,23 +690,26 @@ opcode_stack_effect(int opcode, int oparg)
return 0;
case DUP_TOP:
return 1;
- case DUP_TOP_TWO:
- return 2;
+ case ROT_FOUR:
+ return 0;
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:
@@ -710,9 +721,37 @@ 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:
@@ -735,8 +774,14 @@ opcode_stack_effect(int opcode, int oparg)
case PRINT_EXPR:
return -1;
- case LOAD_BUILD_CLASS:
- 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 INPLACE_LSHIFT:
case INPLACE_RSHIFT:
case INPLACE_AND:
@@ -746,24 +791,27 @@ opcode_stack_effect(int opcode, int oparg)
case BREAK_LOOP:
return 0;
case SETUP_WITH:
- return 7;
+ return 4;
case WITH_CLEANUP:
return -1; /* XXX Sometimes more */
- case STORE_LOCALS:
- return -1;
+ case LOAD_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 -1; /* or -2 or -3 if exception occurred */
+ return -3; /* or -1 or -2 if no exception occurred or
+ return/break/continue */
+ case BUILD_CLASS:
+ return -2;
case STORE_NAME:
return -1;
@@ -771,8 +819,6 @@ 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 */
@@ -784,6 +830,8 @@ 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:
@@ -819,11 +867,9 @@ opcode_stack_effect(int opcode, int oparg)
case CONTINUE_LOOP:
return 0;
case SETUP_LOOP:
- return 0;
case SETUP_EXCEPT:
case SETUP_FINALLY:
- return 6; /* can push 3 values for the new exception
- + 3 others for the previous exception state */
+ return 0;
case LOAD_FAST:
return 1;
@@ -834,7 +880,7 @@ opcode_stack_effect(int opcode, int oparg)
case RAISE_VARARGS:
return -oparg;
-#define NARGS(o) (((o) % 256) + 2*(((o) / 256) % 256))
+#define NARGS(o) (((o) % 256) + 2*((o) / 256))
case CALL_FUNCTION:
return -NARGS(oparg);
case CALL_FUNCTION_VAR:
@@ -842,25 +888,23 @@ opcode_stack_effect(int opcode, int oparg)
return -NARGS(oparg)-1;
case CALL_FUNCTION_VAR_KW:
return -NARGS(oparg)-2;
- case MAKE_FUNCTION:
- return -NARGS(oparg) - ((oparg >> 16) & 0xffff);
- case MAKE_CLOSURE:
- return -1 - NARGS(oparg) - ((oparg >> 16) & 0xffff);
#undef NARGS
+ case MAKE_FUNCTION:
+ return -oparg;
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()");
@@ -911,6 +955,7 @@ 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;
@@ -935,6 +980,7 @@ 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);
}
@@ -943,10 +989,8 @@ 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 = PyLong_FromLong(arg);
+ v = PyInt_FromLong(arg);
if (!v) {
Py_DECREF(t);
return -1;
@@ -959,7 +1003,7 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
Py_DECREF(v);
}
else
- arg = PyLong_AsLong(v);
+ arg = PyInt_AsLong(v);
Py_DECREF(t);
return arg;
}
@@ -1151,7 +1195,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) && c->c_optimize < 2) {
+ if (compiler_isdocstring(st) && Py_OptimizeFlag < 2) {
/* don't generate docstrings if -OO */
i = 1;
VISIT(c, expr, st->v.Expr.value);
@@ -1170,7 +1214,7 @@ compiler_mod(struct compiler *c, mod_ty mod)
int addNone = 1;
static PyObject *module;
if (!module) {
- module = PyUnicode_InternFromString("<module>");
+ module = PyString_InternFromString("<module>");
if (!module)
return NULL;
}
@@ -1222,8 +1266,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",
- PyBytes_AS_STRING(name),
- PyBytes_AS_STRING(c->u->u_name),
+ PyString_AS_STRING(name),
+ PyString_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),
@@ -1247,7 +1291,7 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
Py_DECREF(k);
if (v == NULL)
return -1;
- return PyLong_AS_LONG(v);
+ return PyInt_AS_LONG(v);
}
static int
@@ -1278,13 +1322,12 @@ 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) {
- fprintf(stderr,
- "lookup %s in %s %d %d\n"
+ printf("lookup %s in %s %d %d\n"
"freevars of %s: %s\n",
PyObject_REPR(name),
- PyBytes_AS_STRING(c->u->u_name),
+ PyString_AS_STRING(c->u->u_name),
reftype, arg,
- _PyUnicode_AsString(co->co_name),
+ PyString_AS_STRING(co->co_name),
PyObject_REPR(co->co_freevars));
Py_FatalError("compiler_make_closure()");
}
@@ -1311,122 +1354,27 @@ compiler_decorators(struct compiler *c, asdl_seq* decos)
}
static int
-compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
- asdl_seq *kw_defaults)
+compiler_arguments(struct compiler *c, arguments_ty args)
{
- 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_) {
- ADDOP_O(c, LOAD_CONST, arg->arg, consts);
- if (!compiler_visit_expr(c, default_)) {
- return -1;
+ 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;
}
- default_count++;
+ if (!compiler_nameop(c, id, Load)) {
+ Py_DECREF(id);
+ return 0;
+ }
+ Py_DECREF(id);
+ VISIT(c, expr, arg);
}
}
- 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;
+ return 1;
}
static int
@@ -1435,45 +1383,33 @@ 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, kw_default_count = 0, arglength;
- int num_annotations;
+ int i, n, docstring;
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 && c->c_optimize < 2)
+ if (docstring && Py_OptimizeFlag < 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++) {
@@ -1485,13 +1421,9 @@ compiler_function(struct compiler *c, stmt_ty s)
if (co == NULL)
return 0;
- arglength = asdl_seq_LEN(args->defaults);
- arglength |= kw_default_count << 8;
- arglength |= num_annotations << 16;
- compiler_make_closure(c, co, arglength);
+ compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
Py_DECREF(co);
- /* decorators */
for (i = 0; i < asdl_seq_LEN(decos); i++) {
ADDOP_I(c, CALL_FUNCTION, 1);
}
@@ -1502,113 +1434,64 @@ 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;
- /* 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.
- */
+ /* 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;
+ }
- /* 1. compile the class body into a code object */
- if (!compiler_enter_scope(c, s->v.ClassDef.name, (void *)s, s->lineno))
+ 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);
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);
}
- /* leave the new scope */
+
+ ADDOP_IN_SCOPE(c, LOAD_LOCALS);
+ ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ co = assemble(c, 1);
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);
- /* 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 */
+ ADDOP_I(c, CALL_FUNCTION, 0);
+ ADDOP(c, BUILD_CLASS);
+ /* 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;
@@ -1641,34 +1524,29 @@ 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 = PyUnicode_InternFromString("<lambda>");
+ name = PyString_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);
@@ -1681,15 +1559,50 @@ compiler_lambda(struct compiler *c, expr_ty e)
if (co == NULL)
return 0;
- arglength = asdl_seq_LEN(args->defaults);
- arglength |= kw_default_count << 8;
- compiler_make_closure(c, co, arglength);
+ compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
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;
@@ -1699,7 +1612,7 @@ compiler_if(struct compiler *c, stmt_ty s)
if (end == NULL)
return 0;
- constant = expr_constant(c, s->v.If.test);
+ constant = expr_constant(s->v.If.test);
/* constant = 0: "if 0"
* constant = 1: "if 1", "if 2", ...
* constant = -1: rest */
@@ -1761,7 +1674,7 @@ static int
compiler_while(struct compiler *c, stmt_ty s)
{
basicblock *loop, *orelse, *end, *anchor = NULL;
- int constant = expr_constant(c, s->v.While.test);
+ int constant = expr_constant(s->v.While.test);
if (constant == 0) {
if (s->v.While.orelse)
@@ -1908,7 +1821,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
}
/*
- Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
+ Code generated for "try: S except E1, V1: S1 except E2, 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.)
@@ -1965,9 +1878,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
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 = 0;
+ c->u->u_lineno_set = false;
c->u->u_lineno = handler->lineno;
- c->u->u_col_offset = handler->col_offset;
except = compiler_new_block(c);
if (except == NULL)
return 0;
@@ -1979,71 +1891,13 @@ compiler_try_except(struct compiler *c, stmt_ty s)
}
ADDOP(c, POP_TOP);
if (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);
+ VISIT(c, expr, handler->v.ExceptHandler.name);
}
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);
}
@@ -2063,17 +1917,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 Py_UNICODE *src = PyUnicode_AS_UNICODE(name);
- const Py_UNICODE *dot = Py_UNICODE_strchr(src, '.');
+ const char *src = PyString_AS_STRING(name);
+ const char *dot = 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 = Py_UNICODE_strchr(src, '.');
- attr = PyUnicode_FromUnicode(src,
- dot ? dot - src : Py_UNICODE_strlen(src));
+ dot = strchr(src, '.');
+ attr = PyString_FromStringAndSize(src,
+ dot ? dot - src : strlen(src));
if (!attr)
return -1;
ADDOP_O(c, LOAD_ATTR, attr, names);
@@ -2101,7 +1955,11 @@ compiler_import(struct compiler *c, stmt_ty s)
int r;
PyObject *level;
- level = PyLong_FromLong(0);
+ if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSOLUTE_IMPORT))
+ level = PyInt_FromLong(0);
+ else
+ level = PyInt_FromLong(-1);
+
if (level == NULL)
return 0;
@@ -2117,11 +1975,11 @@ compiler_import(struct compiler *c, stmt_ty s)
}
else {
identifier tmp = alias->name;
- const Py_UNICODE *base = PyUnicode_AS_UNICODE(alias->name);
- Py_UNICODE *dot = Py_UNICODE_strchr(base, '.');
+ const char *base = PyString_AS_STRING(alias->name);
+ char *dot = strchr(base, '.');
if (dot)
- tmp = PyUnicode_FromUnicode(base,
- dot - base);
+ tmp = PyString_FromStringAndSize(base,
+ dot - base);
r = compiler_nameop(c, tmp, Store);
if (dot) {
Py_DECREF(tmp);
@@ -2143,7 +2001,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
static PyObject *empty_string;
if (!empty_string) {
- empty_string = PyUnicode_FromString("");
+ empty_string = PyString_FromString("");
if (!empty_string)
return 0;
}
@@ -2151,7 +2009,12 @@ compiler_from_import(struct compiler *c, stmt_ty s)
if (!names)
return 0;
- level = PyLong_FromLong(s->v.ImportFrom.level);
+ 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);
+
if (!level) {
Py_DECREF(names);
return 0;
@@ -2165,7 +2028,7 @@ compiler_from_import(struct compiler *c, stmt_ty s)
}
if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
- !PyUnicode_CompareWithASCIIString(s->v.ImportFrom.module, "__future__")) {
+ !strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) {
Py_DECREF(level);
Py_DECREF(names);
return compiler_error(c, "from __future__ imports must occur "
@@ -2186,7 +2049,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 && *PyUnicode_AS_UNICODE(alias->name) == '*') {
+ if (i == 0 && *PyString_AS_STRING(alias->name) == '*') {
assert(n == 1);
ADDOP(c, IMPORT_STAR);
return 1;
@@ -2213,10 +2076,10 @@ compiler_assert(struct compiler *c, stmt_ty s)
static PyObject *assertion_error = NULL;
basicblock *end;
- if (c->c_optimize)
+ if (Py_OptimizeFlag)
return 1;
if (assertion_error == NULL) {
- assertion_error = PyUnicode_InternFromString("AssertionError");
+ assertion_error = PyString_InternFromString("AssertionError");
if (assertion_error == NULL)
return 0;
}
@@ -2250,8 +2113,7 @@ 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_col_offset = s->col_offset;
- c->u->u_lineno_set = 0;
+ c->u->u_lineno_set = false;
switch (s->kind) {
case FunctionDef_kind:
@@ -2283,6 +2145,8 @@ 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:
@@ -2291,13 +2155,17 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
return compiler_if(c, s);
case Raise_kind:
n = 0;
- if (s->v.Raise.exc) {
- VISIT(c, expr, s->v.Raise.exc);
+ if (s->v.Raise.type) {
+ VISIT(c, expr, s->v.Raise.type);
n++;
- if (s->v.Raise.cause) {
- VISIT(c, expr, s->v.Raise.cause);
- 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++;
+ }
+ }
}
ADDOP_I(c, RAISE_VARARGS, n);
break;
@@ -2311,8 +2179,22 @@ 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) {
@@ -2370,7 +2252,10 @@ binop(struct compiler *c, operator_ty op)
case Mult:
return BINARY_MULTIPLY;
case Div:
- return BINARY_TRUE_DIVIDE;
+ if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
+ return BINARY_TRUE_DIVIDE;
+ else
+ return BINARY_DIVIDE;
case Mod:
return BINARY_MODULO;
case Pow:
@@ -2434,7 +2319,10 @@ inplace_binop(struct compiler *c, operator_ty op)
case Mult:
return INPLACE_MULTIPLY;
case Div:
- return INPLACE_TRUE_DIVIDE;
+ if (c->c_flags && c->c_flags->cf_flags & CO_FUTURE_DIVISION)
+ return INPLACE_TRUE_DIVIDE;
+ else
+ return INPLACE_DIVIDE;
case Mod:
return INPLACE_MODULO;
case Pow:
@@ -2502,7 +2390,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 || PyUnicode_AS_UNICODE(name)[0] == '_');
+ assert(scope || PyString_AS_STRING(name)[0] == '_');
switch (optype) {
case OP_DEREF:
@@ -2512,7 +2400,13 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
case AugLoad:
case AugStore:
break;
- case Del: op = DELETE_DEREF; 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 Param:
default:
PyErr_SetString(PyExc_SystemError,
@@ -2609,26 +2503,7 @@ compiler_list(struct compiler *c, expr_ty e)
{
int 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++) {
- 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);
- }
+ ADDOP_I(c, UNPACK_SEQUENCE, n);
}
VISIT_SEQ(c, expr, e->v.List.elts);
if (e->v.List.ctx == Load) {
@@ -2642,26 +2517,7 @@ compiler_tuple(struct compiler *c, expr_ty e)
{
int 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++) {
- 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);
- }
+ ADDOP_I(c, UNPACK_SEQUENCE, n);
}
VISIT_SEQ(c, expr, e->v.Tuple.elts);
if (e->v.Tuple.ctx == Load) {
@@ -2718,37 +2574,21 @@ compiler_compare(struct compiler *c, expr_ty e)
static int
compiler_call(struct compiler *c, expr_ty e)
{
- VISIT(c, expr, e->v.Call.func);
- return compiler_call_helper(c, 0,
- e->v.Call.args,
- e->v.Call.keywords,
- e->v.Call.starargs,
- e->v.Call.kwargs);
-}
+ int n, code = 0;
-/* 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);
+ 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);
code |= 1;
}
- if (kwargs) {
- VISIT(c, expr, kwargs);
+ if (e->v.Call.kwargs) {
+ VISIT(c, expr, e->v.Call.kwargs);
code |= 2;
}
switch (code) {
@@ -2768,19 +2608,82 @@ compiler_call_helper(struct compiler *c,
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 */
-/* 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.
+ comprehension_ty l;
+ basicblock *start, *anchor, *skip, *if_cleanup;
+ int i, n;
- Possible cleanups:
+ 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;
+}
+
+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:
- iterate over the generator sequence instead of using recursion
*/
@@ -2846,10 +2749,6 @@ 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);
@@ -2890,9 +2789,6 @@ 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;
@@ -2941,7 +2837,7 @@ compiler_genexp(struct compiler *c, expr_ty e)
{
static identifier name;
if (!name) {
- name = PyUnicode_FromString("<genexpr>");
+ name = PyString_FromString("<genexpr>");
if (!name)
return 0;
}
@@ -2952,26 +2848,11 @@ 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 = PyUnicode_FromString("<setcomp>");
+ name = PyString_FromString("<setcomp>");
if (!name)
return 0;
}
@@ -2981,13 +2862,12 @@ 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 = PyUnicode_FromString("<dictcomp>");
+ name = PyString_FromString("<dictcomp>");
if (!name)
return 0;
}
@@ -2997,7 +2877,6 @@ 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)
{
@@ -3013,25 +2892,19 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
*/
static int
-expr_constant(struct compiler *c, expr_ty e)
+expr_constant(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:
- /* 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;
+ /* __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;
/* fall through */
default:
return -1;
@@ -3079,6 +2952,9 @@ 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;
}
@@ -3124,10 +3000,8 @@ 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 = 0;
+ c->u->u_lineno_set = false;
}
- /* 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);
@@ -3160,14 +3034,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");
@@ -3183,18 +3057,16 @@ 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)
@@ -3250,18 +3122,6 @@ 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 */
@@ -3361,7 +3221,7 @@ compiler_in_loop(struct compiler *c) {
static int
compiler_error(struct compiler *c, const char *errstr)
{
- PyObject *loc, *filename;
+ PyObject *loc;
PyObject *u = NULL, *v = NULL;
loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno);
@@ -3369,17 +3229,8 @@ compiler_error(struct compiler *c, const char *errstr)
Py_INCREF(Py_None);
loc = Py_None;
}
- 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);
+ u = Py_BuildValue("(ziOO)", c->c_filename, c->u->u_lineno,
+ Py_None, loc);
if (!u)
goto exit;
v = Py_BuildValue("(zO)", errstr, u);
@@ -3413,7 +3264,7 @@ compiler_handle_subscr(struct compiler *c, const char *kind,
return 0;
}
if (ctx == AugLoad) {
- ADDOP(c, DUP_TOP_TWO);
+ ADDOP_I(c, DUP_TOPX, 2);
}
else if (ctx == AugStore) {
ADDOP(c, ROT_THREE);
@@ -3452,10 +3303,64 @@ 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:
@@ -3481,8 +3386,16 @@ 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;
@@ -3509,6 +3422,7 @@ 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.
@@ -3610,10 +3524,10 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno)
{
memset(a, 0, sizeof(struct assembler));
a->a_lineno = firstlineno;
- a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
+ a->a_bytecode = PyString_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
if (!a->a_bytecode)
return 0;
- a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
+ a->a_lnotab = PyString_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
if (!a->a_lnotab)
return 0;
if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) {
@@ -3684,7 +3598,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 = PyBytes_GET_SIZE(a->a_lnotab);
+ len = PyString_GET_SIZE(a->a_lnotab);
if (nbytes >= len) {
if ((len <= INT_MAX / 2) && (len * 2 < nbytes))
len = nbytes;
@@ -3694,11 +3608,11 @@ assemble_lnotab(struct assembler *a, struct instr *i)
PyErr_NoMemory();
return 0;
}
- if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
+ if (_PyString_Resize(&a->a_lnotab, len) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
for (j = 0; j < ncodes; j++) {
*lnotab++ = 255;
*lnotab++ = 0;
@@ -3710,7 +3624,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 = PyBytes_GET_SIZE(a->a_lnotab);
+ len = PyString_GET_SIZE(a->a_lnotab);
if (nbytes >= len) {
if ((len <= INT_MAX / 2) && len * 2 < nbytes)
len = nbytes;
@@ -3720,11 +3634,11 @@ assemble_lnotab(struct assembler *a, struct instr *i)
PyErr_NoMemory();
return 0;
}
- if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
+ if (_PyString_Resize(&a->a_lnotab, len) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
*lnotab++ = d_bytecode;
*lnotab++ = 255;
d_bytecode = 0;
@@ -3736,13 +3650,13 @@ assemble_lnotab(struct assembler *a, struct instr *i)
a->a_lnotab_off += ncodes * 2;
}
- len = PyBytes_GET_SIZE(a->a_lnotab);
+ len = PyString_GET_SIZE(a->a_lnotab);
if (a->a_lnotab_off + 2 >= len) {
- if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0)
+ if (_PyString_Resize(&a->a_lnotab, len * 2) < 0)
return 0;
}
lnotab = (unsigned char *)
- PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
+ PyString_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
a->a_lnotab_off += 2;
if (d_bytecode) {
@@ -3767,7 +3681,7 @@ static int
assemble_emit(struct assembler *a, struct instr *i)
{
int size, arg = 0, ext = 0;
- Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
+ Py_ssize_t len = PyString_GET_SIZE(a->a_bytecode);
char *code;
size = instrsize(i);
@@ -3780,10 +3694,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 (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0)
+ if (_PyString_Resize(&a->a_bytecode, len * 2) < 0)
return 0;
}
- code = PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
+ code = PyString_AS_STRING(a->a_bytecode) + a->a_offset;
a->a_offset += size;
if (size == 6) {
assert(i->i_hasarg);
@@ -3869,7 +3783,7 @@ dict_keys_inorder(PyObject *dict, int offset)
if (tuple == NULL)
return NULL;
while (PyDict_Next(dict, &pos, &k, &v)) {
- i = PyLong_AS_LONG(v);
+ i = PyInt_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);
@@ -3951,7 +3865,7 @@ makecode(struct compiler *c, struct assembler *a)
freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars));
if (!freevars)
goto error;
- filename = PyUnicode_DecodeFSDefault(c->c_filename);
+ filename = PyString_FromString(c->c_filename);
if (!filename)
goto error;
@@ -3970,8 +3884,7 @@ makecode(struct compiler *c, struct assembler *a)
Py_DECREF(consts);
consts = tmp;
- co = PyCode_New(c->u->u_argcount, c->u->u_kwonlyargcount,
- nlocals, stackdepth(c), flags,
+ co = PyCode_New(c->u->u_argcount, nlocals, stackdepth(c), flags,
bytecode, consts, names, varnames,
freevars, cellvars,
filename, c->u->u_name,
@@ -4072,9 +3985,9 @@ assemble(struct compiler *c, int addNone)
goto error;
}
- if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
+ if (_PyString_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
goto error;
- if (_PyBytes_Resize(&a.a_bytecode, a.a_offset) < 0)
+ if (_PyString_Resize(&a.a_bytecode, a.a_offset) < 0)
goto error;
co = makecode(c, &a);
@@ -4082,13 +3995,3 @@ 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);
-}
-
-