[Python-checkins] gh-93691: Compiler's code-gen passes location around instead of holding it on the global compiler state (GH-98001)
iritkatriel
webhook-mailer at python.org
Mon Oct 17 09:29:30 EDT 2022
https://github.com/python/cpython/commit/6da1a2e993c955aa69158871b8c8792cef3094c3
commit: 6da1a2e993c955aa69158871b8c8792cef3094c3
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2022-10-17T14:28:51+01:00
summary:
gh-93691: Compiler's code-gen passes location around instead of holding it on the global compiler state (GH-98001)
files:
M Python/compile.c
diff --git a/Python/compile.c b/Python/compile.c
index 2da36d0f6316..5fbf6fe10d13 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -118,17 +118,17 @@
(c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
&& (c->u->u_ste->ste_type == ModuleBlock))
-struct location {
+typedef struct location_ {
int lineno;
int end_lineno;
int col_offset;
int end_col_offset;
-};
+} location;
#define LOCATION(LNO, END_LNO, COL, END_COL) \
- ((const struct location){(LNO), (END_LNO), (COL), (END_COL)})
+ ((const location){(LNO), (END_LNO), (COL), (END_COL)})
-static struct location NO_LOCATION = {-1, -1, -1, -1};
+static location NO_LOCATION = {-1, -1, -1, -1};
typedef struct jump_target_label_ {
int id;
@@ -153,7 +153,7 @@ static struct jump_target_label_ NO_LABEL = {-1};
struct instr {
int i_opcode;
int i_oparg;
- struct location i_loc;
+ location i_loc;
/* The following fields should not be set by the front-end: */
struct basicblock_ *i_target; /* target block (if jump instruction) */
struct basicblock_ *i_except; /* target block when exception is raised */
@@ -386,7 +386,6 @@ struct compiler_unit {
struct fblockinfo u_fblock[CO_MAXBLOCKS];
int u_firstlineno; /* the first lineno of the block */
- struct location u_loc; /* line/column info of the current stmt */
};
/* This struct captures the global state of a compilation.
@@ -418,7 +417,7 @@ struct compiler {
};
#define CFG_BUILDER(c) (&((c)->u->u_cfg_builder))
-#define COMPILER_LOC(c) ((c)->u->u_loc)
+
typedef struct {
// A list of strings corresponding to name captures. It is used to track:
@@ -449,12 +448,12 @@ static int basicblock_next_instr(basicblock *);
static basicblock *cfg_builder_new_block(cfg_builder *g);
static int cfg_builder_maybe_start_new_block(cfg_builder *g);
-static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct location loc);
+static int cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc);
static void compiler_free(struct compiler *);
-static int compiler_error(struct compiler *, const char *, ...);
-static int compiler_warn(struct compiler *, const char *, ...);
-static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
+static int compiler_error(struct compiler *, location loc, const char *, ...);
+static int compiler_warn(struct compiler *, location loc, const char *, ...);
+static int compiler_nameop(struct compiler *, location, identifier, expr_context_ty);
static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
static int compiler_visit_stmt(struct compiler *, stmt_ty);
@@ -472,31 +471,33 @@ static int compiler_with(struct compiler *, stmt_ty, int);
static int compiler_async_with(struct compiler *, stmt_ty, int);
static int compiler_async_for(struct compiler *, stmt_ty);
static int compiler_call_simple_kw_helper(struct compiler *c,
+ location loc,
asdl_keyword_seq *keywords,
Py_ssize_t nkwelts);
-static int compiler_call_helper(struct compiler *c, int n,
- asdl_expr_seq *args,
+static int compiler_call_helper(struct compiler *c, location loc,
+ int n, asdl_expr_seq *args,
asdl_keyword_seq *keywords);
static int compiler_try_except(struct compiler *, stmt_ty);
static int compiler_try_star_except(struct compiler *, stmt_ty);
static int compiler_set_qualname(struct compiler *);
static int compiler_sync_comprehension_generator(
- struct compiler *c,
+ struct compiler *c, location *ploc,
asdl_comprehension_seq *generators, int gen_index,
int depth,
expr_ty elt, expr_ty val, int type);
static int compiler_async_comprehension_generator(
- struct compiler *c,
+ struct compiler *c, location *ploc,
asdl_comprehension_seq *generators, int gen_index,
int depth,
expr_ty elt, expr_ty val, int type);
-static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *);
+static int compiler_pattern(struct compiler *, location *,
+ pattern_ty, pattern_context *);
static int compiler_match(struct compiler *, stmt_ty);
-static int compiler_pattern_subpattern(struct compiler *, pattern_ty,
- pattern_context *);
+static int compiler_pattern_subpattern(struct compiler *, location *,
+ pattern_ty, pattern_context *);
static void remove_redundant_nops(basicblock *bb);
@@ -997,18 +998,15 @@ basicblock_next_instr(basicblock *b)
- before the "except" and "finally" clauses
*/
-#define SET_LOC(c, x) \
- (c)->u->u_loc.lineno = (x)->lineno; \
- (c)->u->u_loc.end_lineno = (x)->end_lineno; \
- (c)->u->u_loc.col_offset = (x)->col_offset; \
- (c)->u->u_loc.end_col_offset = (x)->end_col_offset;
+#define SET_LOC(c, x)
// Artificial instructions
-#define UNSET_LOC(c) \
- (c)->u->u_loc.lineno = -1; \
- (c)->u->u_loc.end_lineno = -1; \
- (c)->u->u_loc.col_offset = -1; \
- (c)->u->u_loc.end_col_offset = -1;
+#define UNSET_LOC(c)
+
+#define LOC(x) LOCATION((x)->lineno, \
+ (x)->end_lineno, \
+ (x)->col_offset, \
+ (x)->end_col_offset)
/* Return the stack effect of opcode with argument oparg.
@@ -1290,7 +1288,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
*/
static int
-basicblock_addop(basicblock *b, int opcode, int oparg, struct location loc)
+basicblock_addop(basicblock *b, int opcode, int oparg, location loc)
{
assert(IS_WITHIN_OPCODE_RANGE(opcode));
assert(!IS_ASSEMBLER_OPCODE(opcode));
@@ -1336,7 +1334,7 @@ cfg_builder_maybe_start_new_block(cfg_builder *g)
}
static int
-cfg_builder_addop(cfg_builder *g, int opcode, int oparg, struct location loc)
+cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
{
if (cfg_builder_maybe_start_new_block(g) != 0) {
return -1;
@@ -1345,7 +1343,7 @@ cfg_builder_addop(cfg_builder *g, int opcode, int oparg, struct location loc)
}
static int
-cfg_builder_addop_noarg(cfg_builder *g, int opcode, struct location loc)
+cfg_builder_addop_noarg(cfg_builder *g, int opcode, location loc)
{
assert(!HAS_ARG(opcode));
return cfg_builder_addop(g, opcode, 0, loc);
@@ -1503,27 +1501,27 @@ compiler_add_const(struct compiler *c, PyObject *o)
}
static int
-compiler_addop_load_const(struct compiler *c, PyObject *o)
+compiler_addop_load_const(struct compiler *c, location loc, PyObject *o)
{
Py_ssize_t arg = compiler_add_const(c, o);
if (arg < 0)
return 0;
- return cfg_builder_addop_i(CFG_BUILDER(c), LOAD_CONST, arg, COMPILER_LOC(c));
+ return cfg_builder_addop_i(CFG_BUILDER(c), LOAD_CONST, arg, loc);
}
static int
-compiler_addop_o(struct compiler *c, int opcode, PyObject *dict,
- PyObject *o)
+compiler_addop_o(struct compiler *c, location loc,
+ int opcode, PyObject *dict, PyObject *o)
{
Py_ssize_t arg = dict_add_o(dict, o);
if (arg < 0)
return 0;
- return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, COMPILER_LOC(c));
+ return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc);
}
static int
-compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
- PyObject *o)
+compiler_addop_name(struct compiler *c, location loc,
+ int opcode, PyObject *dict, PyObject *o)
{
Py_ssize_t arg;
@@ -1542,14 +1540,14 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict,
arg <<= 1;
arg |= 1;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, COMPILER_LOC(c));
+ return cfg_builder_addop_i(CFG_BUILDER(c), opcode, arg, loc);
}
/* Add an opcode with an integer argument.
Returns 0 on failure, 1 on success.
*/
static int
-cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct location loc)
+cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, location loc)
{
/* oparg value is unsigned, but a signed C int is usually used to store
it in the C code (like Python/ceval.c).
@@ -1564,7 +1562,8 @@ cfg_builder_addop_i(cfg_builder *g, int opcode, Py_ssize_t oparg, struct locatio
}
static int
-cfg_builder_addop_j(cfg_builder *g, int opcode, jump_target_label target, struct location loc)
+cfg_builder_addop_j(cfg_builder *g, location loc,
+ int opcode, jump_target_label target)
{
assert(IS_LABEL(target));
assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
@@ -1572,102 +1571,84 @@ cfg_builder_addop_j(cfg_builder *g, int opcode, jump_target_label target, struct
}
-#define ADDOP(C, OP) { \
- if (!cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), COMPILER_LOC(C))) \
+#define ADDOP(C, LOC, OP) { \
+ if (!cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC))) \
return 0; \
}
-#define ADDOP_NOLINE(C, OP) { \
- if (!cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), NO_LOCATION)) \
- return 0; \
-}
-
-#define ADDOP_IN_SCOPE(C, OP) { \
- if (!cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), COMPILER_LOC(C))) { \
+#define ADDOP_IN_SCOPE(C, LOC, OP) { \
+ if (!cfg_builder_addop_noarg(CFG_BUILDER(C), (OP), (LOC))) { \
compiler_exit_scope(c); \
return 0; \
} \
}
-#define ADDOP_LOAD_CONST(C, O) { \
- if (!compiler_addop_load_const((C), (O))) \
+#define ADDOP_LOAD_CONST(C, LOC, O) { \
+ if (!compiler_addop_load_const((C), (LOC), (O))) \
return 0; \
}
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
-#define ADDOP_LOAD_CONST_NEW(C, O) { \
+#define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \
PyObject *__new_const = (O); \
if (__new_const == NULL) { \
return 0; \
} \
- if (!compiler_addop_load_const((C), __new_const)) { \
+ if (!compiler_addop_load_const((C), (LOC), __new_const)) { \
Py_DECREF(__new_const); \
return 0; \
} \
Py_DECREF(__new_const); \
}
-#define ADDOP_N(C, OP, O, TYPE) { \
+#define ADDOP_N(C, LOC, OP, O, TYPE) { \
assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
- if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
+ if (!compiler_addop_o((C), (LOC), (OP), (C)->u->u_ ## TYPE, (O))) { \
Py_DECREF((O)); \
return 0; \
} \
Py_DECREF((O)); \
}
-#define ADDOP_NAME(C, OP, O, TYPE) { \
- if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
+#define ADDOP_NAME(C, LOC, OP, O, TYPE) { \
+ if (!compiler_addop_name((C), (LOC), (OP), (C)->u->u_ ## TYPE, (O))) \
return 0; \
}
-#define ADDOP_I(C, OP, O) { \
- if (!cfg_builder_addop_i(CFG_BUILDER(C), (OP), (O), COMPILER_LOC(C))) \
+#define ADDOP_I(C, LOC, OP, O) { \
+ if (!cfg_builder_addop_i(CFG_BUILDER(C), (OP), (O), (LOC))) \
return 0; \
}
-#define ADDOP_I_NOLINE(C, OP, O) { \
- if (!cfg_builder_addop_i(CFG_BUILDER(C), (OP), (O), NO_LOCATION)) \
+#define ADDOP_JUMP(C, LOC, OP, O) { \
+ if (!cfg_builder_addop_j(CFG_BUILDER(C), (LOC), (OP), (O))) \
return 0; \
}
-#define ADDOP_JUMP(C, OP, O) { \
- if (!cfg_builder_addop_j(CFG_BUILDER(C), (OP), (O), COMPILER_LOC(C))) \
+#define ADDOP_COMPARE(C, LOC, CMP) { \
+ if (!compiler_addcompare((C), (LOC), (cmpop_ty)(CMP))) \
return 0; \
}
-/* Add a jump with no line number.
- * Used for artificial jumps that have no corresponding
- * token in the source code. */
-#define ADDOP_JUMP_NOLINE(C, OP, O) { \
- if (!cfg_builder_addop_j(CFG_BUILDER(C), (OP), (O), NO_LOCATION)) \
- return 0; \
-}
+#define ADDOP_BINARY(C, LOC, BINOP) \
+ RETURN_IF_FALSE(addop_binary((C), (LOC), (BINOP), false))
-#define ADDOP_COMPARE(C, CMP) { \
- if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \
- return 0; \
-}
+#define ADDOP_INPLACE(C, LOC, BINOP) \
+ RETURN_IF_FALSE(addop_binary((C), (LOC), (BINOP), true))
+
+#define ADD_YIELD_FROM(C, LOC, await) \
+ RETURN_IF_FALSE(compiler_add_yield_from((C), (LOC), (await)))
-#define ADDOP_BINARY(C, BINOP) \
- RETURN_IF_FALSE(addop_binary((C), (BINOP), false))
+#define POP_EXCEPT_AND_RERAISE(C, LOC) \
+ RETURN_IF_FALSE(compiler_pop_except_and_reraise((C), (LOC)))
-#define ADDOP_INPLACE(C, BINOP) \
- RETURN_IF_FALSE(addop_binary((C), (BINOP), true))
+#define ADDOP_YIELD(C, LOC) \
+ RETURN_IF_FALSE(addop_yield((C), (LOC)))
/* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use
the ASDL name to synthesize the name of the C type and the visit function.
*/
-#define ADD_YIELD_FROM(C, await) \
- RETURN_IF_FALSE(compiler_add_yield_from((C), (await)))
-
-#define POP_EXCEPT_AND_RERAISE(C) \
- RETURN_IF_FALSE(compiler_pop_except_and_reraise((C)))
-
-#define ADDOP_YIELD(C) \
- RETURN_IF_FALSE(addop_yield(C))
-
#define VISIT(C, TYPE, V) {\
if (!compiler_visit_ ## TYPE((C), (V))) \
return 0; \
@@ -1711,6 +1692,8 @@ static int
compiler_enter_scope(struct compiler *c, identifier name,
int scope_type, void *key, int lineno)
{
+ location loc = LOCATION(lineno, lineno, 0, 0);
+
struct compiler_unit *u;
u = (struct compiler_unit *)PyObject_Calloc(1, sizeof(
@@ -1758,7 +1741,6 @@ compiler_enter_scope(struct compiler *c, identifier name,
u->u_nfblocks = 0;
u->u_firstlineno = lineno;
- u->u_loc = LOCATION(lineno, lineno, 0, 0);
u->u_consts = PyDict_New();
if (!u->u_consts) {
compiler_unit_free(u);
@@ -1794,16 +1776,16 @@ compiler_enter_scope(struct compiler *c, identifier name,
}
if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
- c->u->u_loc.lineno = 0;
+ loc.lineno = 0;
}
else {
if (!compiler_set_qualname(c))
return 0;
}
- ADDOP_I(c, RESUME, 0);
+ ADDOP_I(c, loc, RESUME, 0);
if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
- c->u->u_loc.lineno = -1;
+ loc.lineno = -1;
}
return 1;
}
@@ -1911,12 +1893,13 @@ find_ann(asdl_stmt_seq *stmts)
*/
static int
-compiler_push_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label,
+compiler_push_fblock(struct compiler *c, location loc,
+ enum fblocktype t, jump_target_label block_label,
jump_target_label exit, void *datum)
{
struct fblockinfo *f;
if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
- return compiler_error(c, "too many statically nested blocks");
+ return compiler_error(c, loc, "too many statically nested blocks");
}
f = &c->u->u_fblock[c->u->u_nfblocks++];
f->fb_type = t;
@@ -1937,40 +1920,41 @@ compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label blo
}
static int
-compiler_call_exit_with_nones(struct compiler *c) {
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_I(c, CALL, 2);
+compiler_call_exit_with_nones(struct compiler *c, location loc)
+{
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADDOP_I(c, loc, CALL, 2);
return 1;
}
static int
-compiler_add_yield_from(struct compiler *c, int await)
+compiler_add_yield_from(struct compiler *c, location loc, int await)
{
NEW_JUMP_TARGET_LABEL(c, send);
NEW_JUMP_TARGET_LABEL(c, fail);
NEW_JUMP_TARGET_LABEL(c, exit);
USE_LABEL(c, send);
- ADDOP_JUMP(c, SEND, exit);
+ ADDOP_JUMP(c, loc, SEND, exit);
// Set up a virtual try/except to handle when StopIteration is raised during
// a close or throw call. The only way YIELD_VALUE raises if they do!
- ADDOP_JUMP(c, SETUP_FINALLY, fail);
- ADDOP_I(c, YIELD_VALUE, 0);
- ADDOP_NOLINE(c, POP_BLOCK);
- ADDOP_I(c, RESUME, await ? 3 : 2);
- ADDOP_JUMP(c, JUMP_NO_INTERRUPT, send);
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
+ ADDOP_I(c, loc, YIELD_VALUE, 0);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP_I(c, loc, RESUME, await ? 3 : 2);
+ ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
USE_LABEL(c, fail);
- ADDOP(c, CLEANUP_THROW);
+ ADDOP(c, loc, CLEANUP_THROW);
USE_LABEL(c, exit);
return 1;
}
static int
-compiler_pop_except_and_reraise(struct compiler *c)
+compiler_pop_except_and_reraise(struct compiler *c, location loc)
{
/* Stack contents
* [exc_info, lasti, exc] COPY 3
@@ -1979,9 +1963,9 @@ compiler_pop_except_and_reraise(struct compiler *c)
* (exception_unwind clears the stack)
*/
- ADDOP_I(c, COPY, 3);
- ADDOP(c, POP_EXCEPT);
- ADDOP_I(c, RERAISE, 1);
+ ADDOP_I(c, loc, COPY, 3);
+ ADDOP(c, loc, POP_EXCEPT);
+ ADDOP_I(c, loc, RERAISE, 1);
return 1;
}
@@ -1991,8 +1975,8 @@ compiler_pop_except_and_reraise(struct compiler *c)
* be popped.
*/
static int
-compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
- int preserve_tos)
+compiler_unwind_fblock(struct compiler *c, location *ploc,
+ struct fblockinfo *info, int preserve_tos)
{
switch (info->fb_type) {
case WHILE_LOOP:
@@ -2004,20 +1988,20 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
case FOR_LOOP:
/* Pop the iterator */
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
return 1;
case TRY_EXCEPT:
- ADDOP(c, POP_BLOCK);
+ ADDOP(c, *ploc, POP_BLOCK);
return 1;
case FINALLY_TRY:
/* This POP_BLOCK gets the line number of the unwinding statement */
- ADDOP(c, POP_BLOCK);
+ ADDOP(c, *ploc, POP_BLOCK);
if (preserve_tos) {
- if (!compiler_push_fblock(c, POP_VALUE, NO_LABEL, NO_LABEL, NULL)) {
+ if (!compiler_push_fblock(c, *ploc, POP_VALUE, NO_LABEL, NO_LABEL, NULL)) {
return 0;
}
}
@@ -2030,78 +2014,84 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info,
* statement causing the unwinding, so make the unwinding
* instruction artificial */
UNSET_LOC(c);
+ *ploc = NO_LOCATION;
return 1;
case FINALLY_END:
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- ADDOP(c, POP_TOP); /* exc_value */
+ ADDOP(c, *ploc, POP_TOP); /* exc_value */
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
+ ADDOP(c, *ploc, POP_BLOCK);
+ ADDOP(c, *ploc, POP_EXCEPT);
return 1;
case WITH:
case ASYNC_WITH:
SET_LOC(c, (stmt_ty)info->fb_datum);
- ADDOP(c, POP_BLOCK);
+ *ploc = LOC((stmt_ty)info->fb_datum);
+ ADDOP(c, *ploc, POP_BLOCK);
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- if(!compiler_call_exit_with_nones(c)) {
+ if(!compiler_call_exit_with_nones(c, *ploc)) {
return 0;
}
if (info->fb_type == ASYNC_WITH) {
- ADDOP_I(c, GET_AWAITABLE, 2);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
+ ADDOP_LOAD_CONST(c, *ploc, Py_None);
+ ADD_YIELD_FROM(c, *ploc, 1);
}
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
/* The exit block should appear to execute after the
* statement causing the unwinding, so make the unwinding
* instruction artificial */
UNSET_LOC(c);
+ *ploc = NO_LOCATION;
return 1;
- case HANDLER_CLEANUP:
+ case HANDLER_CLEANUP: {
if (info->fb_datum) {
- ADDOP(c, POP_BLOCK);
+ ADDOP(c, *ploc, POP_BLOCK);
}
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
+ ADDOP(c, *ploc, POP_BLOCK);
+ ADDOP(c, *ploc, POP_EXCEPT);
if (info->fb_datum) {
- ADDOP_LOAD_CONST(c, Py_None);
- compiler_nameop(c, info->fb_datum, Store);
- compiler_nameop(c, info->fb_datum, Del);
+ ADDOP_LOAD_CONST(c, *ploc, Py_None);
+ compiler_nameop(c, *ploc, info->fb_datum, Store);
+ compiler_nameop(c, *ploc, info->fb_datum, Del);
}
return 1;
-
- case POP_VALUE:
+ }
+ case POP_VALUE: {
if (preserve_tos) {
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, *ploc, SWAP, 2);
}
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
return 1;
+ }
}
Py_UNREACHABLE();
}
/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
static int
-compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) {
+compiler_unwind_fblock_stack(struct compiler *c, location *ploc,
+ int preserve_tos, struct fblockinfo **loop)
+{
if (c->u->u_nfblocks == 0) {
return 1;
}
struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1];
if (top->fb_type == EXCEPTION_GROUP_HANDLER) {
return compiler_error(
- c, "'break', 'continue' and 'return' cannot appear in an except* block");
+ c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block");
}
if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) {
*loop = top;
@@ -2109,10 +2099,10 @@ compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblock
}
struct fblockinfo copy = *top;
c->u->u_nfblocks--;
- if (!compiler_unwind_fblock(c, ©, preserve_tos)) {
+ if (!compiler_unwind_fblock(c, ploc, ©, preserve_tos)) {
return 0;
}
- if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) {
+ if (!compiler_unwind_fblock_stack(c, ploc, preserve_tos, loop)) {
return 0;
}
c->u->u_fblock[c->u->u_nfblocks] = copy;
@@ -2124,7 +2114,7 @@ compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblock
and for annotations. */
static int
-compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
+compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
{
int i = 0;
stmt_ty st;
@@ -2137,10 +2127,11 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
st = (stmt_ty)asdl_seq_GET(stmts, 0);
SET_LOC(c, st);
+ loc = LOC(st);
}
/* Every annotated class and module should have __annotations__. */
if (find_ann(stmts)) {
- ADDOP(c, SETUP_ANNOTATIONS);
+ ADDOP(c, loc, SETUP_ANNOTATIONS);
}
if (!asdl_seq_LEN(stmts))
return 1;
@@ -2153,7 +2144,7 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts)
assert(st->kind == Expr_kind);
VISIT(c, expr, st->v.Expr.value);
UNSET_LOC(c);
- if (!compiler_nameop(c, &_Py_ID(__doc__), Store))
+ if (!compiler_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store))
return 0;
}
}
@@ -2172,17 +2163,17 @@ compiler_mod(struct compiler *c, mod_ty mod)
mod, 1)) {
return NULL;
}
- c->u->u_loc.lineno = 1;
+ location loc = LOCATION(1, 1, 0, 0);
switch (mod->kind) {
case Module_kind:
- if (!compiler_body(c, mod->v.Module.body)) {
+ if (!compiler_body(c, loc, mod->v.Module.body)) {
compiler_exit_scope(c);
return 0;
}
break;
case Interactive_kind:
if (find_ann(mod->v.Interactive.body)) {
- ADDOP(c, SETUP_ANNOTATIONS);
+ ADDOP(c, loc, SETUP_ANNOTATIONS);
}
c->c_interactive = 1;
VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
@@ -2239,8 +2230,8 @@ compiler_lookup_arg(PyObject *dict, PyObject *name)
}
static int
-compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
- PyObject *qualname)
+compiler_make_closure(struct compiler *c, location loc,
+ PyCodeObject *co, Py_ssize_t flags, PyObject *qualname)
{
if (qualname == NULL)
qualname = co->co_name;
@@ -2286,13 +2277,13 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags,
Py_DECREF(freevars);
return 0;
}
- ADDOP_I(c, LOAD_CLOSURE, arg);
+ ADDOP_I(c, loc, LOAD_CLOSURE, arg);
}
flags |= 0x08;
- ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars);
+ ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
}
- ADDOP_LOAD_CONST(c, (PyObject*)co);
- ADDOP_I(c, MAKE_FUNCTION, flags);
+ ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
+ ADDOP_I(c, loc, MAKE_FUNCTION, flags);
return 1;
}
@@ -2316,18 +2307,17 @@ compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos)
if (!decos)
return 1;
- struct location old_loc = c->u->u_loc;
for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
SET_LOC(c, (expr_ty)asdl_seq_GET(decos, i));
- ADDOP_I(c, CALL, 0);
+ location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
+ ADDOP_I(c, loc, CALL, 0);
}
- c->u->u_loc = old_loc;
return 1;
}
static int
-compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs,
- asdl_expr_seq *kw_defaults)
+compiler_visit_kwonlydefaults(struct compiler *c, location loc,
+ asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
{
/* Push a dict of keyword-only default values.
@@ -2368,8 +2358,8 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs,
Py_ssize_t default_count = PyList_GET_SIZE(keys);
PyObject *keys_tuple = PyList_AsTuple(keys);
Py_DECREF(keys);
- ADDOP_LOAD_CONST_NEW(c, keys_tuple);
- ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
+ ADDOP_LOAD_CONST_NEW(c, loc, keys_tuple);
+ ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, default_count);
assert(default_count > 0);
return 1;
}
@@ -2385,23 +2375,23 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs,
static int
compiler_visit_annexpr(struct compiler *c, expr_ty annotation)
{
- ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation));
+ location loc = LOC(annotation);
+ ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
return 1;
}
static int
compiler_visit_argannotation(struct compiler *c, identifier id,
- expr_ty annotation, Py_ssize_t *annotations_len)
+ expr_ty annotation, Py_ssize_t *annotations_len, location loc)
{
if (!annotation) {
return 1;
}
-
PyObject *mangled = _Py_Mangle(c->u->u_private, id);
if (!mangled) {
return 0;
}
- ADDOP_LOAD_CONST(c, mangled);
+ ADDOP_LOAD_CONST(c, loc, mangled);
Py_DECREF(mangled);
if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) {
@@ -2414,7 +2404,7 @@ compiler_visit_argannotation(struct compiler *c, identifier id,
// (Note that in theory we could end up here even for an argument
// other than *args, but in practice the grammar doesn't allow it.)
VISIT(c, expr, annotation->v.Starred.value);
- ADDOP_I(c, UNPACK_SEQUENCE, (Py_ssize_t) 1);
+ ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
}
else {
VISIT(c, expr, annotation);
@@ -2426,7 +2416,7 @@ compiler_visit_argannotation(struct compiler *c, identifier id,
static int
compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args,
- Py_ssize_t *annotations_len)
+ Py_ssize_t *annotations_len, location loc)
{
int i;
for (i = 0; i < asdl_seq_LEN(args); i++) {
@@ -2435,15 +2425,16 @@ compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args,
c,
arg->arg,
arg->annotation,
- annotations_len))
+ annotations_len,
+ loc))
return 0;
}
return 1;
}
static int
-compiler_visit_annotations(struct compiler *c, arguments_ty args,
- expr_ty returns)
+compiler_visit_annotations(struct compiler *c, location loc,
+ arguments_ty args, expr_ty returns)
{
/* Push arg annotation names and values.
The expressions are evaluated out-of-order wrt the source code.
@@ -2452,28 +2443,28 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
*/
Py_ssize_t annotations_len = 0;
- if (!compiler_visit_argannotations(c, args->args, &annotations_len))
+ if (!compiler_visit_argannotations(c, args->args, &annotations_len, loc))
return 0;
- if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len))
+ if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len, loc))
return 0;
if (args->vararg && args->vararg->annotation &&
!compiler_visit_argannotation(c, args->vararg->arg,
- args->vararg->annotation, &annotations_len))
+ args->vararg->annotation, &annotations_len, loc))
return 0;
- if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len))
+ if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len, loc))
return 0;
if (args->kwarg && args->kwarg->annotation &&
!compiler_visit_argannotation(c, args->kwarg->arg,
- args->kwarg->annotation, &annotations_len))
+ args->kwarg->annotation, &annotations_len, loc))
return 0;
if (!compiler_visit_argannotation(c, &_Py_ID(return), returns,
- &annotations_len)) {
+ &annotations_len, loc)) {
return 0;
}
if (annotations_len) {
- ADDOP_I(c, BUILD_TUPLE, annotations_len);
+ ADDOP_I(c, loc, BUILD_TUPLE, annotations_len);
return 1;
}
@@ -2481,24 +2472,27 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
}
static int
-compiler_visit_defaults(struct compiler *c, arguments_ty args)
+compiler_visit_defaults(struct compiler *c, arguments_ty args,
+ location loc)
{
VISIT_SEQ(c, expr, args->defaults);
- ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
+ ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
return 1;
}
static Py_ssize_t
-compiler_default_arguments(struct compiler *c, arguments_ty args)
+compiler_default_arguments(struct compiler *c, location loc,
+ arguments_ty args)
{
Py_ssize_t funcflags = 0;
if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
- if (!compiler_visit_defaults(c, args))
+ if (!compiler_visit_defaults(c, args, loc))
return -1;
funcflags |= 0x01;
}
if (args->kwonlyargs) {
- int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
+ int res = compiler_visit_kwonlydefaults(c, loc,
+ args->kwonlyargs,
args->kw_defaults);
if (res == 0) {
return -1;
@@ -2511,15 +2505,15 @@ compiler_default_arguments(struct compiler *c, arguments_ty args)
}
static int
-forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx)
+forbidden_name(struct compiler *c, location loc, identifier name,
+ expr_context_ty ctx)
{
-
if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
- compiler_error(c, "cannot assign to __debug__");
+ compiler_error(c, loc, "cannot assign to __debug__");
return 1;
}
if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
- compiler_error(c, "cannot delete __debug__");
+ compiler_error(c, loc, "cannot delete __debug__");
return 1;
}
return 0;
@@ -2529,7 +2523,7 @@ static int
compiler_check_debug_one_arg(struct compiler *c, arg_ty arg)
{
if (arg != NULL) {
- if (forbidden_name(c, arg->arg, Store))
+ if (forbidden_name(c, LOC(arg), arg->arg, Store))
return 0;
}
return 1;
@@ -2611,12 +2605,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
}
- funcflags = compiler_default_arguments(c, args);
+ location loc = LOC(s);
+ funcflags = compiler_default_arguments(c, loc, args);
if (funcflags == -1) {
return 0;
}
-
- annotations = compiler_visit_annotations(c, args, returns);
+ annotations = compiler_visit_annotations(c, loc, args, returns);
if (annotations == 0) {
return 0;
}
@@ -2652,8 +2646,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
Py_XDECREF(co);
return 0;
}
-
- if (!compiler_make_closure(c, co, funcflags, qualname)) {
+ if (!compiler_make_closure(c, loc, co, funcflags, qualname)) {
Py_DECREF(qualname);
Py_DECREF(co);
return 0;
@@ -2663,7 +2656,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
if (!compiler_apply_decorators(c, decos))
return 0;
- return compiler_nameop(c, name, Store);
+ return compiler_nameop(c, loc, name, Store);
}
static int
@@ -2691,7 +2684,6 @@ compiler_class(struct compiler *c, stmt_ty s)
<keywords> is the keyword arguments and **kwds argument
This borrows from compiler_call.
*/
-
/* 1. compile the class body into a code object */
if (!compiler_enter_scope(c, s->v.ClassDef.name,
COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) {
@@ -2699,27 +2691,28 @@ compiler_class(struct compiler *c, stmt_ty s)
}
/* this block represents what we do in the new scope */
{
+ location loc = LOCATION(firstlineno, firstlineno, 0, 0);
/* use the class name for name mangling */
Py_INCREF(s->v.ClassDef.name);
Py_XSETREF(c->u->u_private, s->v.ClassDef.name);
/* load (global) __name__ ... */
- if (!compiler_nameop(c, &_Py_ID(__name__), Load)) {
+ if (!compiler_nameop(c, loc, &_Py_ID(__name__), Load)) {
compiler_exit_scope(c);
return 0;
}
/* ... and store it as __module__ */
- if (!compiler_nameop(c, &_Py_ID(__module__), Store)) {
+ if (!compiler_nameop(c, loc, &_Py_ID(__module__), Store)) {
compiler_exit_scope(c);
return 0;
}
assert(c->u->u_qualname);
- ADDOP_LOAD_CONST(c, c->u->u_qualname);
- if (!compiler_nameop(c, &_Py_ID(__qualname__), Store)) {
+ ADDOP_LOAD_CONST(c, loc, c->u->u_qualname);
+ if (!compiler_nameop(c, loc, &_Py_ID(__qualname__), Store)) {
compiler_exit_scope(c);
return 0;
}
/* compile the body proper */
- if (!compiler_body(c, s->v.ClassDef.body)) {
+ if (!compiler_body(c, loc, s->v.ClassDef.body)) {
compiler_exit_scope(c);
return 0;
}
@@ -2734,10 +2727,9 @@ compiler_class(struct compiler *c, stmt_ty s)
return 0;
}
assert(i == 0);
-
- ADDOP_I(c, LOAD_CLOSURE, i);
- ADDOP_I(c, COPY, 1);
- if (!compiler_nameop(c, &_Py_ID(__classcell__), Store)) {
+ ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
+ ADDOP_I(c, NO_LOCATION, COPY, 1);
+ if (!compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store)) {
compiler_exit_scope(c);
return 0;
}
@@ -2745,9 +2737,9 @@ compiler_class(struct compiler *c, stmt_ty s)
else {
/* No methods referenced __class__, so just return None */
assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0);
- ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
}
- ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
/* create the code object */
co = assemble(c, 1);
}
@@ -2756,29 +2748,32 @@ compiler_class(struct compiler *c, stmt_ty s)
if (co == NULL)
return 0;
+ location loc = LOC(s);
/* 2. load the 'build_class' function */
- ADDOP(c, PUSH_NULL);
- ADDOP(c, LOAD_BUILD_CLASS);
+ ADDOP(c, loc, PUSH_NULL);
+ ADDOP(c, loc, LOAD_BUILD_CLASS);
/* 3. load a function (or closure) made from the code object */
- if (!compiler_make_closure(c, co, 0, NULL)) {
+ if (!compiler_make_closure(c, loc, co, 0, NULL)) {
Py_DECREF(co);
return 0;
}
Py_DECREF(co);
/* 4. load class name */
- ADDOP_LOAD_CONST(c, s->v.ClassDef.name);
+ ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
/* 5. generate the rest of the code for the call */
- if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords))
+ if (!compiler_call_helper(c, loc, 2,
+ s->v.ClassDef.bases,
+ s->v.ClassDef.keywords))
return 0;
/* 6. apply decorators */
if (!compiler_apply_decorators(c, decos))
return 0;
/* 7. store into <name> */
- if (!compiler_nameop(c, s->v.ClassDef.name, Store))
+ if (!compiler_nameop(c, loc, s->v.ClassDef.name, Store))
return 0;
return 1;
}
@@ -2816,7 +2811,7 @@ check_compare(struct compiler *c, expr_ty e)
const char *msg = (op == Is)
? "\"is\" with a literal. Did you mean \"==\"?"
: "\"is not\" with a literal. Did you mean \"!=\"?";
- return compiler_warn(c, msg);
+ return compiler_warn(c, LOC(e), msg);
}
}
left = right;
@@ -2824,7 +2819,8 @@ check_compare(struct compiler *c, expr_ty e)
return 1;
}
-static int compiler_addcompare(struct compiler *c, cmpop_ty op)
+static int compiler_addcompare(struct compiler *c, location loc,
+ cmpop_ty op)
{
int cmp;
switch (op) {
@@ -2847,33 +2843,34 @@ static int compiler_addcompare(struct compiler *c, cmpop_ty op)
cmp = Py_GE;
break;
case Is:
- ADDOP_I(c, IS_OP, 0);
+ ADDOP_I(c, loc, IS_OP, 0);
return 1;
case IsNot:
- ADDOP_I(c, IS_OP, 1);
+ ADDOP_I(c, loc, IS_OP, 1);
return 1;
case In:
- ADDOP_I(c, CONTAINS_OP, 0);
+ ADDOP_I(c, loc, CONTAINS_OP, 0);
return 1;
case NotIn:
- ADDOP_I(c, CONTAINS_OP, 1);
+ ADDOP_I(c, loc, CONTAINS_OP, 1);
return 1;
default:
Py_UNREACHABLE();
}
- ADDOP_I(c, COMPARE_OP, cmp);
+ ADDOP_I(c, loc, COMPARE_OP, cmp);
return 1;
}
static int
-compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond)
+compiler_jump_if(struct compiler *c, location *ploc,
+ expr_ty e, jump_target_label next, int cond)
{
switch (e->kind) {
case UnaryOp_kind:
if (e->v.UnaryOp.op == Not)
- return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond);
+ return compiler_jump_if(c, ploc, e->v.UnaryOp.operand, next, !cond);
/* fallback to general implementation */
break;
case BoolOp_kind: {
@@ -2887,10 +2884,10 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
next2 = new_next2;
}
for (i = 0; i < n; ++i) {
- if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2))
+ if (!compiler_jump_if(c, ploc, (expr_ty)asdl_seq_GET(s, i), next2, cond2))
return 0;
}
- if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond))
+ if (!compiler_jump_if(c, ploc, (expr_ty)asdl_seq_GET(s, n), next, cond))
return 0;
if (!SAME_LABEL(next2, next)) {
USE_LABEL(c, next2);
@@ -2900,14 +2897,14 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
case IfExp_kind: {
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, next2);
- if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0))
+ if (!compiler_jump_if(c, ploc, e->v.IfExp.test, next2, 0))
return 0;
- if (!compiler_jump_if(c, e->v.IfExp.body, next, cond))
+ if (!compiler_jump_if(c, ploc, e->v.IfExp.body, next, cond))
return 0;
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, next2);
- if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond))
+ if (!compiler_jump_if(c, ploc, e->v.IfExp.orelse, next, cond))
return 0;
USE_LABEL(c, end);
@@ -2915,6 +2912,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
}
case Compare_kind: {
SET_LOC(c, e);
+ *ploc = LOC(e);
Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1;
if (n > 0) {
if (!check_compare(c, e)) {
@@ -2925,21 +2923,21 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
for (i = 0; i < n; i++) {
VISIT(c, expr,
(expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
- ADDOP_I(c, SWAP, 2);
- ADDOP_I(c, COPY, 2);
- ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
- ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup);
+ ADDOP_I(c, *ploc, SWAP, 2);
+ ADDOP_I(c, *ploc, COPY, 2);
+ ADDOP_COMPARE(c, *ploc, asdl_seq_GET(e->v.Compare.ops, i));
+ ADDOP_JUMP(c, *ploc, POP_JUMP_IF_FALSE, cleanup);
}
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
- ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
- ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
+ ADDOP_COMPARE(c, *ploc, asdl_seq_GET(e->v.Compare.ops, n));
+ ADDOP_JUMP(c, *ploc, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
NEW_JUMP_TARGET_LABEL(c, end);
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, cleanup);
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
if (!cond) {
- ADDOP_JUMP_NOLINE(c, JUMP, next);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, next);
}
USE_LABEL(c, end);
@@ -2955,7 +2953,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, jump_target_label next, int cond
/* general implementation */
VISIT(c, expr, e);
- ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
+ ADDOP_JUMP(c, *ploc, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
return 1;
}
@@ -2966,10 +2964,12 @@ compiler_ifexp(struct compiler *c, expr_ty e)
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, next);
- if (!compiler_jump_if(c, e->v.IfExp.test, next, 0))
+ location loc = LOC(e);
+ if (!compiler_jump_if(c, &loc, e->v.IfExp.test, next, 0)) {
return 0;
+ }
VISIT(c, expr, e->v.IfExp.body);
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, next);
VISIT(c, expr, e->v.IfExp.orelse);
@@ -2990,7 +2990,8 @@ compiler_lambda(struct compiler *c, expr_ty e)
if (!compiler_check_debug_args(c, args))
return 0;
- funcflags = compiler_default_arguments(c, args);
+ location loc = LOC(e);
+ funcflags = compiler_default_arguments(c, loc, args);
if (funcflags == -1) {
return 0;
}
@@ -3013,7 +3014,8 @@ compiler_lambda(struct compiler *c, expr_ty e)
co = assemble(c, 0);
}
else {
- ADDOP_IN_SCOPE(c, RETURN_VALUE);
+ location loc = LOCATION(e->lineno, e->lineno, 0, 0);
+ ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
co = assemble(c, 1);
}
qualname = c->u->u_qualname;
@@ -3024,7 +3026,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
return 0;
}
- if (!compiler_make_closure(c, co, funcflags, qualname)) {
+ if (!compiler_make_closure(c, loc, co, funcflags, qualname)) {
Py_DECREF(qualname);
Py_DECREF(co);
return 0;
@@ -3048,12 +3050,13 @@ compiler_if(struct compiler *c, stmt_ty s)
else {
next = end;
}
- if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
+ location loc = LOC(s);
+ if (!compiler_jump_if(c, &loc, s->v.If.test, next, 0)) {
return 0;
}
VISIT_SEQ(c, stmt, s->v.If.body);
if (asdl_seq_LEN(s->v.If.orelse)) {
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, next);
VISIT_SEQ(c, stmt, s->v.If.orelse);
@@ -3066,26 +3069,27 @@ compiler_if(struct compiler *c, stmt_ty s)
static int
compiler_for(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
NEW_JUMP_TARGET_LABEL(c, start);
NEW_JUMP_TARGET_LABEL(c, body);
NEW_JUMP_TARGET_LABEL(c, cleanup);
NEW_JUMP_TARGET_LABEL(c, end);
- if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
+ if (!compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)) {
return 0;
}
VISIT(c, expr, s->v.For.iter);
- ADDOP(c, GET_ITER);
+ ADDOP(c, loc, GET_ITER);
USE_LABEL(c, start);
- ADDOP_JUMP(c, FOR_ITER, cleanup);
+ ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
USE_LABEL(c, body);
VISIT(c, expr, s->v.For.target);
VISIT_SEQ(c, stmt, s->v.For.body);
/* Mark jump as artificial */
UNSET_LOC(c);
- ADDOP_JUMP(c, JUMP, start);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
USE_LABEL(c, cleanup);
@@ -3101,10 +3105,11 @@ compiler_for(struct compiler *c, stmt_ty s)
static int
compiler_async_for(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
if (IS_TOP_LEVEL_AWAIT(c)){
c->u->u_ste->ste_coroutine = 1;
} else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
- return compiler_error(c, "'async for' outside async function");
+ return compiler_error(c, loc, "'async for' outside async function");
}
NEW_JUMP_TARGET_LABEL(c, start);
@@ -3112,25 +3117,25 @@ compiler_async_for(struct compiler *c, stmt_ty s)
NEW_JUMP_TARGET_LABEL(c, end);
VISIT(c, expr, s->v.AsyncFor.iter);
- ADDOP(c, GET_AITER);
+ ADDOP(c, loc, GET_AITER);
USE_LABEL(c, start);
- if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) {
+ if (!compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)) {
return 0;
}
/* SETUP_FINALLY to guard the __anext__ call */
- ADDOP_JUMP(c, SETUP_FINALLY, except);
- ADDOP(c, GET_ANEXT);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
- ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
+ ADDOP(c, loc, GET_ANEXT);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
+ ADDOP(c, loc, POP_BLOCK); /* for SETUP_FINALLY */
/* Success block for __anext__ */
VISIT(c, expr, s->v.AsyncFor.target);
VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
/* Mark jump as artificial */
UNSET_LOC(c);
- ADDOP_JUMP(c, JUMP, start);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
compiler_pop_fblock(c, FOR_LOOP, start);
@@ -3140,7 +3145,8 @@ compiler_async_for(struct compiler *c, stmt_ty s)
/* Use same line number as the iterator,
* as the END_ASYNC_FOR succeeds the `for`, not the body. */
SET_LOC(c, s->v.AsyncFor.iter);
- ADDOP(c, END_ASYNC_FOR);
+ loc = LOC(s->v.AsyncFor.iter);
+ ADDOP(c, loc, END_ASYNC_FOR);
/* `else` block */
VISIT_SEQ(c, stmt, s->v.For.orelse);
@@ -3152,23 +3158,25 @@ compiler_async_for(struct compiler *c, stmt_ty s)
static int
compiler_while(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
NEW_JUMP_TARGET_LABEL(c, loop);
NEW_JUMP_TARGET_LABEL(c, body);
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, anchor);
USE_LABEL(c, loop);
- if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) {
+ if (!compiler_push_fblock(c, loc, WHILE_LOOP, loop, end, NULL)) {
return 0;
}
- if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
+ if (!compiler_jump_if(c, &loc, s->v.While.test, anchor, 0)) {
return 0;
}
USE_LABEL(c, body);
VISIT_SEQ(c, stmt, s->v.While.body);
SET_LOC(c, s);
- if (!compiler_jump_if(c, s->v.While.test, body, 1)) {
+ loc = LOC(s);
+ if (!compiler_jump_if(c, &loc, s->v.While.test, body, 1)) {
return 0;
}
@@ -3186,79 +3194,95 @@ compiler_while(struct compiler *c, stmt_ty s)
static int
compiler_return(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
int preserve_tos = ((s->v.Return.value != NULL) &&
(s->v.Return.value->kind != Constant_kind));
if (c->u->u_ste->ste_type != FunctionBlock)
- return compiler_error(c, "'return' outside function");
+ return compiler_error(c, loc, "'return' outside function");
if (s->v.Return.value != NULL &&
c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
{
return compiler_error(
- c, "'return' with value in async generator");
+ c, loc, "'return' with value in async generator");
}
+
if (preserve_tos) {
VISIT(c, expr, s->v.Return.value);
} else {
/* Emit instruction with line number for return value */
if (s->v.Return.value != NULL) {
SET_LOC(c, s->v.Return.value);
- ADDOP(c, NOP);
+ loc = LOC(s->v.Return.value);
+ ADDOP(c, loc, NOP);
}
}
if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
SET_LOC(c, s);
- ADDOP(c, NOP);
+ loc = LOC(s);
+ ADDOP(c, loc, NOP);
}
- if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL))
+ if (!compiler_unwind_fblock_stack(c, &loc, preserve_tos, NULL))
return 0;
if (s->v.Return.value == NULL) {
- ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
}
else if (!preserve_tos) {
- ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value);
+ ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
}
- ADDOP(c, RETURN_VALUE);
+ ADDOP(c, loc, RETURN_VALUE);
return 1;
}
static int
-compiler_break(struct compiler *c)
+compiler_break(struct compiler *c, location loc)
{
struct fblockinfo *loop = NULL;
/* Emit instruction with line number */
- ADDOP(c, NOP);
- if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
+ ADDOP(c, loc, NOP);
+ if (!compiler_unwind_fblock_stack(c, &loc, 0, &loop)) {
return 0;
}
if (loop == NULL) {
- return compiler_error(c, "'break' outside loop");
+ return compiler_error(c, loc, "'break' outside loop");
}
- if (!compiler_unwind_fblock(c, loop, 0)) {
+ if (!compiler_unwind_fblock(c, &loc, loop, 0)) {
return 0;
}
- ADDOP_JUMP(c, JUMP, loop->fb_exit);
+ ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
return 1;
}
static int
-compiler_continue(struct compiler *c)
+compiler_continue(struct compiler *c, location loc)
{
struct fblockinfo *loop = NULL;
/* Emit instruction with line number */
- ADDOP(c, NOP);
- if (!compiler_unwind_fblock_stack(c, 0, &loop)) {
+ ADDOP(c, loc, NOP);
+ if (!compiler_unwind_fblock_stack(c, &loc, 0, &loop)) {
return 0;
}
if (loop == NULL) {
- return compiler_error(c, "'continue' not properly in loop");
+ return compiler_error(c, loc, "'continue' not properly in loop");
}
- ADDOP_JUMP(c, JUMP, loop->fb_block);
+ ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
return 1;
}
+static location
+location_of_last_executing_statement(asdl_stmt_seq *stmts)
+{
+ for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) {
+ location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i));
+ if (loc.lineno > 0) {
+ return loc;
+ }
+ }
+ return NO_LOCATION;
+}
+
/* Code generated for "try: <body> finally: <finalbody>" is as follows:
SETUP_FINALLY L
@@ -3291,16 +3315,18 @@ compiler_continue(struct compiler *c)
static int
compiler_try_finally(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
+
NEW_JUMP_TARGET_LABEL(c, body);
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, exit);
NEW_JUMP_TARGET_LABEL(c, cleanup);
/* `try` block */
- ADDOP_JUMP(c, SETUP_FINALLY, end);
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
USE_LABEL(c, body);
- if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody))
+ if (!compiler_push_fblock(c, loc, FINALLY_TRY, body, end, s->v.Try.finalbody))
return 0;
if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
if (!compiler_try_except(c, s))
@@ -3309,25 +3335,29 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
else {
VISIT_SEQ(c, stmt, s->v.Try.body);
}
- ADDOP_NOLINE(c, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
compiler_pop_fblock(c, FINALLY_TRY, body);
VISIT_SEQ(c, stmt, s->v.Try.finalbody);
- ADDOP_JUMP_NOLINE(c, JUMP, exit);
+
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
/* `finally` block */
USE_LABEL(c, end);
UNSET_LOC(c);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
- if (!compiler_push_fblock(c, FINALLY_END, end, NO_LABEL, NULL))
+ loc = NO_LOCATION;
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
+ ADDOP(c, loc, PUSH_EXC_INFO);
+ if (!compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL))
return 0;
VISIT_SEQ(c, stmt, s->v.Try.finalbody);
+ loc = location_of_last_executing_statement(s->v.Try.finalbody);
compiler_pop_fblock(c, FINALLY_END, end);
- ADDOP_I(c, RERAISE, 0);
+
+ ADDOP_I(c, loc, RERAISE, 0);
USE_LABEL(c, cleanup);
- POP_EXCEPT_AND_RERAISE(c);
+ POP_EXCEPT_AND_RERAISE(c, loc);
USE_LABEL(c, exit);
return 1;
@@ -3336,15 +3366,17 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
static int
compiler_try_star_finally(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
+
NEW_JUMP_TARGET_LABEL(c, body);
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, exit);
NEW_JUMP_TARGET_LABEL(c, cleanup);
/* `try` block */
- ADDOP_JUMP(c, SETUP_FINALLY, end);
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
USE_LABEL(c, body);
- if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.TryStar.finalbody)) {
+ if (!compiler_push_fblock(c, loc, FINALLY_TRY, body, end, s->v.TryStar.finalbody)) {
return 0;
}
if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
@@ -3355,26 +3387,30 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s)
else {
VISIT_SEQ(c, stmt, s->v.TryStar.body);
}
- ADDOP_NOLINE(c, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
compiler_pop_fblock(c, FINALLY_TRY, body);
VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
- ADDOP_JUMP_NOLINE(c, JUMP, exit);
+
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
/* `finally` block */
USE_LABEL(c, end);
UNSET_LOC(c);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
- if (!compiler_push_fblock(c, FINALLY_END, end, NO_LABEL, NULL)) {
+ loc = NO_LOCATION;
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
+ ADDOP(c, loc, PUSH_EXC_INFO);
+ if (!compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)) {
return 0;
}
VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
+ loc = location_of_last_executing_statement(s->v.Try.finalbody);
+
compiler_pop_fblock(c, FINALLY_END, end);
- ADDOP_I(c, RERAISE, 0);
+ ADDOP_I(c, loc, RERAISE, 0);
USE_LABEL(c, cleanup);
- POP_EXCEPT_AND_RERAISE(c);
+ POP_EXCEPT_AND_RERAISE(c, loc);
USE_LABEL(c, exit);
return 1;
@@ -3412,6 +3448,7 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s)
static int
compiler_try_except(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
Py_ssize_t i, n;
NEW_JUMP_TARGET_LABEL(c, body);
@@ -3419,47 +3456,48 @@ compiler_try_except(struct compiler *c, stmt_ty s)
NEW_JUMP_TARGET_LABEL(c, end);
NEW_JUMP_TARGET_LABEL(c, cleanup);
- ADDOP_JUMP(c, SETUP_FINALLY, except);
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
USE_LABEL(c, body);
- if (!compiler_push_fblock(c, TRY_EXCEPT, body, NO_LABEL, NULL))
+ if (!compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL))
return 0;
VISIT_SEQ(c, stmt, s->v.Try.body);
compiler_pop_fblock(c, TRY_EXCEPT, body);
- ADDOP_NOLINE(c, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
VISIT_SEQ(c, stmt, s->v.Try.orelse);
}
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
n = asdl_seq_LEN(s->v.Try.handlers);
USE_LABEL(c, except);
UNSET_LOC(c);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
+ ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
+ ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
/* Runtime will push a block here, so we need to account for that */
- if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL))
+ if (!compiler_push_fblock(c, loc, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL))
return 0;
for (i = 0; i < n; i++) {
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
s->v.Try.handlers, i);
SET_LOC(c, handler);
+ location loc = LOC(handler);
if (!handler->v.ExceptHandler.type && i < n-1) {
- return compiler_error(c, "default 'except:' must be last");
+ return compiler_error(c, loc, "default 'except:' must be last");
}
NEW_JUMP_TARGET_LABEL(c, next_except);
except = next_except;
if (handler->v.ExceptHandler.type) {
VISIT(c, expr, handler->v.ExceptHandler.type);
- ADDOP(c, CHECK_EXC_MATCH);
- ADDOP_JUMP(c, POP_JUMP_IF_FALSE, except);
+ ADDOP(c, loc, CHECK_EXC_MATCH);
+ ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
}
if (handler->v.ExceptHandler.name) {
NEW_JUMP_TARGET_LABEL(c, cleanup_end);
NEW_JUMP_TARGET_LABEL(c, cleanup_body);
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store);
/*
try:
@@ -3473,24 +3511,26 @@ compiler_try_except(struct compiler *c, stmt_ty s)
*/
/* second try: */
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end);
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
USE_LABEL(c, cleanup_body);
- if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, handler->v.ExceptHandler.name))
+ if (!compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
+ NO_LABEL, handler->v.ExceptHandler.name)) {
return 0;
+ }
/* second # body */
VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
/* name = None; del name; # Mark as artificial */
UNSET_LOC(c);
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
- ADDOP_LOAD_CONST(c, Py_None);
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
- compiler_nameop(c, handler->v.ExceptHandler.name, Del);
- ADDOP_JUMP(c, JUMP, end);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_EXCEPT);
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
/* except: */
USE_LABEL(c, cleanup_end);
@@ -3498,26 +3538,26 @@ compiler_try_except(struct compiler *c, stmt_ty s)
/* name = None; del name; # Mark as artificial */
UNSET_LOC(c);
- ADDOP_LOAD_CONST(c, Py_None);
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
- compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del);
- ADDOP_I(c, RERAISE, 1);
+ ADDOP_I(c, NO_LOCATION, RERAISE, 1);
}
else {
NEW_JUMP_TARGET_LABEL(c, cleanup_body);
- ADDOP(c, POP_TOP); /* exc_value */
+ ADDOP(c, loc, POP_TOP); /* exc_value */
USE_LABEL(c, cleanup_body);
- if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, NULL))
+ if (!compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, NO_LABEL, NULL))
return 0;
VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
UNSET_LOC(c);
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
- ADDOP_JUMP(c, JUMP, end);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_EXCEPT);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
}
USE_LABEL(c, except);
@@ -3525,10 +3565,10 @@ compiler_try_except(struct compiler *c, stmt_ty s)
/* Mark as artificial */
UNSET_LOC(c);
compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL);
- ADDOP_I(c, RERAISE, 0);
+ ADDOP_I(c, NO_LOCATION, RERAISE, 0);
USE_LABEL(c, cleanup);
- POP_EXCEPT_AND_RERAISE(c);
+ POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
USE_LABEL(c, end);
return 1;
@@ -3586,6 +3626,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
static int
compiler_try_star_except(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
+
NEW_JUMP_TARGET_LABEL(c, body);
NEW_JUMP_TARGET_LABEL(c, except);
NEW_JUMP_TARGET_LABEL(c, orelse);
@@ -3593,25 +3635,25 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
NEW_JUMP_TARGET_LABEL(c, cleanup);
NEW_JUMP_TARGET_LABEL(c, reraise_star);
- ADDOP_JUMP(c, SETUP_FINALLY, except);
+ ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
USE_LABEL(c, body);
- if (!compiler_push_fblock(c, TRY_EXCEPT, body, NO_LABEL, NULL)) {
+ if (!compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL)) {
return 0;
}
VISIT_SEQ(c, stmt, s->v.TryStar.body);
compiler_pop_fblock(c, TRY_EXCEPT, body);
- ADDOP_NOLINE(c, POP_BLOCK);
- ADDOP_JUMP_NOLINE(c, JUMP, orelse);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse);
Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
USE_LABEL(c, except);
UNSET_LOC(c);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
+ ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
+ ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
/* Runtime will push a block here, so we need to account for that */
- if (!compiler_push_fblock(c, EXCEPTION_GROUP_HANDLER,
+ if (!compiler_push_fblock(c, loc, EXCEPTION_GROUP_HANDLER,
NO_LABEL, NO_LABEL, "except handler")) {
return 0;
}
@@ -3619,6 +3661,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
s->v.TryStar.handlers, i);
SET_LOC(c, handler);
+ location loc = LOC(handler);
NEW_JUMP_TARGET_LABEL(c, next_except);
except = next_except;
NEW_JUMP_TARGET_LABEL(c, handle_match);
@@ -3628,7 +3671,7 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
[exc] COPY 1
[orig, exc]
*/
- ADDOP_I(c, COPY, 1);
+ ADDOP_I(c, loc, COPY, 1);
/* create empty list for exceptions raised/reraise in the except* blocks */
/*
@@ -3636,16 +3679,16 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
[orig, exc, []] SWAP 2
[orig, [], exc]
*/
- ADDOP_I(c, BUILD_LIST, 0);
- ADDOP_I(c, SWAP, 2);
+ ADDOP_I(c, loc, BUILD_LIST, 0);
+ ADDOP_I(c, loc, SWAP, 2);
}
if (handler->v.ExceptHandler.type) {
VISIT(c, expr, handler->v.ExceptHandler.type);
- ADDOP(c, CHECK_EG_MATCH);
- ADDOP_I(c, COPY, 1);
- ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, handle_match);
- ADDOP(c, POP_TOP); // match
- ADDOP_JUMP(c, JUMP, except);
+ ADDOP(c, loc, CHECK_EG_MATCH);
+ ADDOP_I(c, loc, COPY, 1);
+ ADDOP_JUMP(c, loc, POP_JUMP_IF_NOT_NONE, handle_match);
+ ADDOP(c, loc, POP_TOP); // match
+ ADDOP_JUMP(c, loc, JUMP, except);
}
USE_LABEL(c, handle_match);
@@ -3654,10 +3697,10 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
NEW_JUMP_TARGET_LABEL(c, cleanup_body);
if (handler->v.ExceptHandler.name) {
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store);
}
else {
- ADDOP(c, POP_TOP); // match
+ ADDOP(c, loc, POP_TOP); // match
}
/*
@@ -3671,24 +3714,25 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
del name
*/
/* second try: */
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end);
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
USE_LABEL(c, cleanup_body);
- if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NO_LABEL, handler->v.ExceptHandler.name))
+ if (!compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, NO_LABEL, handler->v.ExceptHandler.name)) {
return 0;
+ }
/* second # body */
VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
/* name = None; del name; # Mark as artificial */
UNSET_LOC(c);
- ADDOP(c, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
if (handler->v.ExceptHandler.name) {
- ADDOP_LOAD_CONST(c, Py_None);
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
- compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del);
}
- ADDOP_JUMP(c, JUMP, except);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
/* except: */
USE_LABEL(c, cleanup_end);
@@ -3697,22 +3741,22 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
UNSET_LOC(c);
if (handler->v.ExceptHandler.name) {
- ADDOP_LOAD_CONST(c, Py_None);
- compiler_nameop(c, handler->v.ExceptHandler.name, Store);
- compiler_nameop(c, handler->v.ExceptHandler.name, Del);
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store);
+ compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del);
}
/* add exception raised to the res list */
- ADDOP_I(c, LIST_APPEND, 3); // exc
- ADDOP(c, POP_TOP); // lasti
- ADDOP_JUMP(c, JUMP, except);
+ ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
+ ADDOP(c, NO_LOCATION, POP_TOP); // lasti
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
USE_LABEL(c, except);
if (i == n - 1) {
/* Add exc to the list (if not None it's the unhandled part of the EG) */
- ADDOP_I(c, LIST_APPEND, 1);
- ADDOP_JUMP(c, JUMP, reraise_star);
+ ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star);
}
}
/* Mark as artificial */
@@ -3721,24 +3765,24 @@ compiler_try_star_except(struct compiler *c, stmt_ty s)
NEW_JUMP_TARGET_LABEL(c, reraise);
USE_LABEL(c, reraise_star);
- ADDOP(c, PREP_RERAISE_STAR);
- ADDOP_I(c, COPY, 1);
- ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, reraise);
+ ADDOP(c, NO_LOCATION, PREP_RERAISE_STAR);
+ ADDOP_I(c, NO_LOCATION, COPY, 1);
+ ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
/* Nothing to reraise */
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
- ADDOP_JUMP(c, JUMP, end);
+ ADDOP(c, NO_LOCATION, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_EXCEPT);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, reraise);
- ADDOP(c, POP_BLOCK);
- ADDOP_I(c, SWAP, 2);
- ADDOP(c, POP_EXCEPT);
- ADDOP_I(c, RERAISE, 0);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP_I(c, NO_LOCATION, SWAP, 2);
+ ADDOP(c, NO_LOCATION, POP_EXCEPT);
+ ADDOP_I(c, NO_LOCATION, RERAISE, 0);
USE_LABEL(c, cleanup);
- POP_EXCEPT_AND_RERAISE(c);
+ POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
USE_LABEL(c, orelse);
VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
@@ -3767,7 +3811,8 @@ compiler_try_star(struct compiler *c, stmt_ty s)
}
static int
-compiler_import_as(struct compiler *c, identifier name, identifier asname)
+compiler_import_as(struct compiler *c, location loc,
+ identifier name, identifier asname)
{
/* The IMPORT_NAME opcode was already generated. This function
merely needs to bind the result to a name.
@@ -3790,25 +3835,26 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname)
attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
if (!attr)
return 0;
- ADDOP_N(c, IMPORT_FROM, attr, names);
+ ADDOP_N(c, loc, IMPORT_FROM, attr, names);
if (dot == -1) {
break;
}
- ADDOP_I(c, SWAP, 2);
- ADDOP(c, POP_TOP);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP(c, loc, POP_TOP);
}
- if (!compiler_nameop(c, asname, Store)) {
+ if (!compiler_nameop(c, loc, asname, Store)) {
return 0;
}
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
return 1;
}
- return compiler_nameop(c, asname, Store);
+ return compiler_nameop(c, loc, asname, Store);
}
static int
compiler_import(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
/* The Import node stores a module name like a.b.c as a single
string. This is convenient for all cases except
import a.b.c as d
@@ -3823,12 +3869,12 @@ compiler_import(struct compiler *c, stmt_ty s)
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
int r;
- ADDOP_LOAD_CONST(c, zero);
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
+ ADDOP_LOAD_CONST(c, loc, zero);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
if (alias->asname) {
- r = compiler_import_as(c, alias->name, alias->asname);
+ r = compiler_import_as(c, loc, alias->name, alias->asname);
if (!r)
return r;
}
@@ -3841,7 +3887,7 @@ compiler_import(struct compiler *c, stmt_ty s)
if (tmp == NULL)
return 0;
}
- r = compiler_nameop(c, tmp, Store);
+ r = compiler_nameop(c, loc, tmp, Store);
if (dot != -1) {
Py_DECREF(tmp);
}
@@ -3855,10 +3901,11 @@ compiler_import(struct compiler *c, stmt_ty s)
static int
compiler_from_import(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names);
PyObject *names;
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level));
+ ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(s->v.ImportFrom.level));
names = PyTuple_New(n);
if (!names)
@@ -3874,17 +3921,17 @@ compiler_from_import(struct compiler *c, stmt_ty s)
if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
_PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) {
Py_DECREF(names);
- return compiler_error(c, "from __future__ imports must occur "
+ return compiler_error(c, loc, "from __future__ imports must occur "
"at the beginning of the file");
}
- ADDOP_LOAD_CONST_NEW(c, names);
+ ADDOP_LOAD_CONST_NEW(c, loc, names);
if (s->v.ImportFrom.module) {
- ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
+ ADDOP_NAME(c, loc, IMPORT_NAME, s->v.ImportFrom.module, names);
}
else {
_Py_DECLARE_STR(empty, "");
- ADDOP_NAME(c, IMPORT_NAME, &_Py_STR(empty), names);
+ ADDOP_NAME(c, loc, IMPORT_NAME, &_Py_STR(empty), names);
}
for (i = 0; i < n; i++) {
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
@@ -3892,27 +3939,28 @@ compiler_from_import(struct compiler *c, stmt_ty s)
if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
assert(n == 1);
- ADDOP(c, IMPORT_STAR);
+ ADDOP(c, loc, IMPORT_STAR);
return 1;
}
- ADDOP_NAME(c, IMPORT_FROM, alias->name, names);
+ ADDOP_NAME(c, loc, IMPORT_FROM, alias->name, names);
store_name = alias->name;
if (alias->asname)
store_name = alias->asname;
- if (!compiler_nameop(c, store_name, Store)) {
+ if (!compiler_nameop(c, loc, store_name, Store)) {
return 0;
}
}
/* remove imported module */
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
return 1;
}
static int
compiler_assert(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
/* Always emit a warning if the test is a non-zero length tuple */
if ((s->v.Assert.test->kind == Tuple_kind &&
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
@@ -3920,8 +3968,8 @@ compiler_assert(struct compiler *c, stmt_ty s)
PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
{
- if (!compiler_warn(c, "assertion is always true, "
- "perhaps remove parentheses?"))
+ if (!compiler_warn(c, loc, "assertion is always true, "
+ "perhaps remove parentheses?"))
{
return 0;
}
@@ -3929,38 +3977,38 @@ compiler_assert(struct compiler *c, stmt_ty s)
if (c->c_optimize)
return 1;
NEW_JUMP_TARGET_LABEL(c, end);
- if (!compiler_jump_if(c, s->v.Assert.test, end, 1))
+ if (!compiler_jump_if(c, &loc, s->v.Assert.test, end, 1))
return 0;
- ADDOP(c, LOAD_ASSERTION_ERROR);
+ ADDOP(c, loc, LOAD_ASSERTION_ERROR);
if (s->v.Assert.msg) {
VISIT(c, expr, s->v.Assert.msg);
- ADDOP_I(c, CALL, 0);
+ ADDOP_I(c, loc, CALL, 0);
}
- ADDOP_I(c, RAISE_VARARGS, 1);
+ ADDOP_I(c, loc, RAISE_VARARGS, 1);
USE_LABEL(c, end);
return 1;
}
static int
-compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
+compiler_stmt_expr(struct compiler *c, location loc, expr_ty value)
{
if (c->c_interactive && c->c_nestlevel <= 1) {
VISIT(c, expr, value);
- ADDOP(c, PRINT_EXPR);
+ ADDOP(c, loc, PRINT_EXPR);
return 1;
}
if (value->kind == Constant_kind) {
/* ignore constant statement */
- ADDOP(c, NOP);
+ ADDOP(c, loc, NOP);
return 1;
}
VISIT(c, expr, value);
/* Mark POP_TOP as artificial */
UNSET_LOC(c);
- ADDOP(c, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_TOP);
return 1;
}
@@ -3968,7 +4016,6 @@ static int
compiler_visit_stmt(struct compiler *c, stmt_ty s)
{
Py_ssize_t i, n;
-
/* Always assign a lineno to the next instruction for a stmt. */
SET_LOC(c, s);
@@ -3983,16 +4030,19 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
VISIT_SEQ(c, expr, s->v.Delete.targets)
break;
case Assign_kind:
+ {
n = asdl_seq_LEN(s->v.Assign.targets);
VISIT(c, expr, s->v.Assign.value);
+ location loc = LOC(s);
for (i = 0; i < n; i++) {
if (i < n - 1) {
- ADDOP_I(c, COPY, 1);
+ ADDOP_I(c, loc, COPY, 1);
}
VISIT(c, expr,
(expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
}
break;
+ }
case AugAssign_kind:
return compiler_augassign(c, s);
case AnnAssign_kind:
@@ -4006,6 +4056,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
case Match_kind:
return compiler_match(c, s);
case Raise_kind:
+ {
n = 0;
if (s->v.Raise.exc) {
VISIT(c, expr, s->v.Raise.exc);
@@ -4015,8 +4066,10 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
n++;
}
}
- ADDOP_I(c, RAISE_VARARGS, (int)n);
+ location loc = LOC(s);
+ ADDOP_I(c, loc, RAISE_VARARGS, (int)n);
break;
+ }
case Try_kind:
return compiler_try(c, s);
case TryStar_kind:
@@ -4031,14 +4084,26 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
case Nonlocal_kind:
break;
case Expr_kind:
- return compiler_visit_stmt_expr(c, s->v.Expr.value);
+ {
+ location loc = LOC(s);
+ return compiler_stmt_expr(c, loc, s->v.Expr.value);
+ }
case Pass_kind:
- ADDOP(c, NOP);
+ {
+ location loc = LOC(s);
+ ADDOP(c, loc, NOP);
break;
+ }
case Break_kind:
- return compiler_break(c);
+ {
+ location loc = LOC(s);
+ return compiler_break(c, loc);
+ }
case Continue_kind:
- return compiler_continue(c);
+ {
+ location loc = LOC(s);
+ return compiler_continue(c, loc);
+ }
case With_kind:
return compiler_with(c, s, 0);
case AsyncFunctionDef_kind:
@@ -4072,7 +4137,8 @@ unaryop(unaryop_ty op)
}
static int
-addop_binary(struct compiler *c, operator_ty binop, bool inplace)
+addop_binary(struct compiler *c, location loc, operator_ty binop,
+ bool inplace)
{
int oparg;
switch (binop) {
@@ -4120,23 +4186,24 @@ addop_binary(struct compiler *c, operator_ty binop, bool inplace)
inplace ? "inplace" : "binary", binop);
return 0;
}
- ADDOP_I(c, BINARY_OP, oparg);
+ ADDOP_I(c, loc, BINARY_OP, oparg);
return 1;
}
static int
-addop_yield(struct compiler *c) {
+addop_yield(struct compiler *c, location loc) {
if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
- ADDOP(c, ASYNC_GEN_WRAP);
+ ADDOP(c, loc, ASYNC_GEN_WRAP);
}
- ADDOP_I(c, YIELD_VALUE, 0);
- ADDOP_I(c, RESUME, 1);
+ ADDOP_I(c, loc, YIELD_VALUE, 0);
+ ADDOP_I(c, loc, RESUME, 1);
return 1;
}
static int
-compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
+compiler_nameop(struct compiler *c, location loc,
+ identifier name, expr_context_ty ctx)
{
int op, scope;
Py_ssize_t arg;
@@ -4149,7 +4216,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
!_PyUnicode_EqualToASCIIString(name, "True") &&
!_PyUnicode_EqualToASCIIString(name, "False"));
- if (forbidden_name(c, name, ctx))
+ if (forbidden_name(c, loc, name, ctx))
return 0;
mangled = _Py_Mangle(c->u->u_private, name);
@@ -4203,7 +4270,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
case Store: op = STORE_FAST; break;
case Del: op = DELETE_FAST; break;
}
- ADDOP_N(c, op, mangled, varnames);
+ ADDOP_N(c, loc, op, mangled, varnames);
return 1;
case OP_GLOBAL:
switch (ctx) {
@@ -4230,7 +4297,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
if (op == LOAD_GLOBAL) {
arg <<= 1;
}
- return cfg_builder_addop_i(CFG_BUILDER(c), op, arg, COMPILER_LOC(c));
+ return cfg_builder_addop_i(CFG_BUILDER(c), op, arg, loc);
}
static int
@@ -4240,6 +4307,7 @@ compiler_boolop(struct compiler *c, expr_ty e)
Py_ssize_t i, n;
asdl_expr_seq *s;
+ location loc = LOC(e);
assert(e->kind == BoolOp_kind);
if (e->v.BoolOp.op == And)
jumpi = JUMP_IF_FALSE_OR_POP;
@@ -4251,7 +4319,7 @@ compiler_boolop(struct compiler *c, expr_ty e)
assert(n >= 0);
for (i = 0; i < n; ++i) {
VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
- ADDOP_JUMP(c, jumpi, end);
+ ADDOP_JUMP(c, loc, jumpi, end);
NEW_JUMP_TARGET_LABEL(c, next);
USE_LABEL(c, next);
@@ -4263,7 +4331,8 @@ compiler_boolop(struct compiler *c, expr_ty e)
}
static int
-starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed,
+starunpack_helper(struct compiler *c, location loc,
+ asdl_expr_seq *elts, int pushed,
int build, int add, int extend, int tuple)
{
Py_ssize_t n = asdl_seq_LEN(elts);
@@ -4279,7 +4348,7 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed,
PyTuple_SET_ITEM(folded, i, val);
}
if (tuple && !pushed) {
- ADDOP_LOAD_CONST_NEW(c, folded);
+ ADDOP_LOAD_CONST_NEW(c, loc, folded);
} else {
if (add == SET_ADD) {
Py_SETREF(folded, PyFrozenSet_New(folded));
@@ -4287,11 +4356,11 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed,
return 0;
}
}
- ADDOP_I(c, build, pushed);
- ADDOP_LOAD_CONST_NEW(c, folded);
- ADDOP_I(c, extend, 1);
+ ADDOP_I(c, loc, build, pushed);
+ ADDOP_LOAD_CONST_NEW(c, loc, folded);
+ ADDOP_I(c, loc, extend, 1);
if (tuple) {
- ADDOP(c, LIST_TO_TUPLE);
+ ADDOP(c, loc, LIST_TO_TUPLE);
}
}
return 1;
@@ -4312,43 +4381,43 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed,
VISIT(c, expr, elt);
}
if (tuple) {
- ADDOP_I(c, BUILD_TUPLE, n+pushed);
+ ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
} else {
- ADDOP_I(c, build, n+pushed);
+ ADDOP_I(c, loc, build, n+pushed);
}
return 1;
}
int sequence_built = 0;
if (big) {
- ADDOP_I(c, build, pushed);
+ ADDOP_I(c, loc, build, pushed);
sequence_built = 1;
}
for (Py_ssize_t i = 0; i < n; i++) {
expr_ty elt = asdl_seq_GET(elts, i);
if (elt->kind == Starred_kind) {
if (sequence_built == 0) {
- ADDOP_I(c, build, i+pushed);
+ ADDOP_I(c, loc, build, i+pushed);
sequence_built = 1;
}
VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, extend, 1);
+ ADDOP_I(c, loc, extend, 1);
}
else {
VISIT(c, expr, elt);
if (sequence_built) {
- ADDOP_I(c, add, 1);
+ ADDOP_I(c, loc, add, 1);
}
}
}
assert(sequence_built);
if (tuple) {
- ADDOP(c, LIST_TO_TUPLE);
+ ADDOP(c, loc, LIST_TO_TUPLE);
}
return 1;
}
static int
-unpack_helper(struct compiler *c, asdl_expr_seq *elts)
+unpack_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
{
Py_ssize_t n = asdl_seq_LEN(elts);
int seen_star = 0;
@@ -4357,28 +4426,28 @@ unpack_helper(struct compiler *c, asdl_expr_seq *elts)
if (elt->kind == Starred_kind && !seen_star) {
if ((i >= (1 << 8)) ||
(n-i-1 >= (INT_MAX >> 8)))
- return compiler_error(c,
+ return compiler_error(c, loc,
"too many expressions in "
"star-unpacking assignment");
- ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
+ ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
seen_star = 1;
}
else if (elt->kind == Starred_kind) {
- return compiler_error(c,
+ return compiler_error(c, loc,
"multiple starred expressions in assignment");
}
}
if (!seen_star) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
+ ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
}
return 1;
}
static int
-assignment_helper(struct compiler *c, asdl_expr_seq *elts)
+assignment_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
{
Py_ssize_t n = asdl_seq_LEN(elts);
- RETURN_IF_FALSE(unpack_helper(c, elts));
+ RETURN_IF_FALSE(unpack_helper(c, loc, elts));
for (Py_ssize_t i = 0; i < n; i++) {
expr_ty elt = asdl_seq_GET(elts, i);
VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
@@ -4389,13 +4458,14 @@ assignment_helper(struct compiler *c, asdl_expr_seq *elts)
static int
compiler_list(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
asdl_expr_seq *elts = e->v.List.elts;
if (e->v.List.ctx == Store) {
- return assignment_helper(c, elts);
+ return assignment_helper(c, loc, elts);
}
else if (e->v.List.ctx == Load) {
- return starunpack_helper(c, elts, 0, BUILD_LIST,
- LIST_APPEND, LIST_EXTEND, 0);
+ return starunpack_helper(c, loc, elts, 0,
+ BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
}
else
VISIT_SEQ(c, expr, elts);
@@ -4405,13 +4475,14 @@ compiler_list(struct compiler *c, expr_ty e)
static int
compiler_tuple(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
asdl_expr_seq *elts = e->v.Tuple.elts;
if (e->v.Tuple.ctx == Store) {
- return assignment_helper(c, elts);
+ return assignment_helper(c, loc, elts);
}
else if (e->v.Tuple.ctx == Load) {
- return starunpack_helper(c, elts, 0, BUILD_LIST,
- LIST_APPEND, LIST_EXTEND, 1);
+ return starunpack_helper(c, loc, elts, 0,
+ BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
}
else
VISIT_SEQ(c, expr, elts);
@@ -4421,8 +4492,9 @@ compiler_tuple(struct compiler *c, expr_ty e)
static int
compiler_set(struct compiler *c, expr_ty e)
{
- return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET,
- SET_ADD, SET_UPDATE, 0);
+ location loc = LOC(e);
+ return starunpack_helper(c, loc, e->v.Set.elts, 0,
+ BUILD_SET, SET_ADD, SET_UPDATE, 0);
}
static int
@@ -4443,6 +4515,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
Py_ssize_t i, n = end - begin;
PyObject *keys, *key;
int big = n*2 > STACK_USE_GUIDELINE;
+ location loc = LOC(e);
if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) {
for (i = begin; i < end; i++) {
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
@@ -4456,22 +4529,22 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
Py_INCREF(key);
PyTuple_SET_ITEM(keys, i - begin, key);
}
- ADDOP_LOAD_CONST_NEW(c, keys);
- ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
+ ADDOP_LOAD_CONST_NEW(c, loc, keys);
+ ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
return 1;
}
if (big) {
- ADDOP_I(c, BUILD_MAP, 0);
+ ADDOP_I(c, loc, BUILD_MAP, 0);
}
for (i = begin; i < end; i++) {
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
if (big) {
- ADDOP_I(c, MAP_ADD, 1);
+ ADDOP_I(c, loc, MAP_ADD, 1);
}
}
if (!big) {
- ADDOP_I(c, BUILD_MAP, n);
+ ADDOP_I(c, loc, BUILD_MAP, n);
}
return 1;
}
@@ -4479,6 +4552,7 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end
static int
compiler_dict(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
Py_ssize_t i, n, elements;
int have_dict;
int is_unpacking = 0;
@@ -4493,17 +4567,17 @@ compiler_dict(struct compiler *c, expr_ty e)
return 0;
}
if (have_dict) {
- ADDOP_I(c, DICT_UPDATE, 1);
+ ADDOP_I(c, loc, DICT_UPDATE, 1);
}
have_dict = 1;
elements = 0;
}
if (have_dict == 0) {
- ADDOP_I(c, BUILD_MAP, 0);
+ ADDOP_I(c, loc, BUILD_MAP, 0);
have_dict = 1;
}
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
- ADDOP_I(c, DICT_UPDATE, 1);
+ ADDOP_I(c, loc, DICT_UPDATE, 1);
}
else {
if (elements*2 > STACK_USE_GUIDELINE) {
@@ -4511,7 +4585,7 @@ compiler_dict(struct compiler *c, expr_ty e)
return 0;
}
if (have_dict) {
- ADDOP_I(c, DICT_UPDATE, 1);
+ ADDOP_I(c, loc, DICT_UPDATE, 1);
}
have_dict = 1;
elements = 0;
@@ -4526,12 +4600,12 @@ compiler_dict(struct compiler *c, expr_ty e)
return 0;
}
if (have_dict) {
- ADDOP_I(c, DICT_UPDATE, 1);
+ ADDOP_I(c, loc, DICT_UPDATE, 1);
}
have_dict = 1;
}
if (!have_dict) {
- ADDOP_I(c, BUILD_MAP, 0);
+ ADDOP_I(c, loc, BUILD_MAP, 0);
}
return 1;
}
@@ -4539,6 +4613,7 @@ compiler_dict(struct compiler *c, expr_ty e)
static int
compiler_compare(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
Py_ssize_t i, n;
if (!check_compare(c, e)) {
@@ -4549,26 +4624,26 @@ compiler_compare(struct compiler *c, expr_ty e)
n = asdl_seq_LEN(e->v.Compare.ops) - 1;
if (n == 0) {
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
- ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0));
+ ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
}
else {
NEW_JUMP_TARGET_LABEL(c, cleanup);
for (i = 0; i < n; i++) {
VISIT(c, expr,
(expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
- ADDOP_I(c, SWAP, 2);
- ADDOP_I(c, COPY, 2);
- ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i));
- ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP_I(c, loc, COPY, 2);
+ ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
+ ADDOP_JUMP(c, loc, JUMP_IF_FALSE_OR_POP, cleanup);
}
VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
- ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n));
+ ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
NEW_JUMP_TARGET_LABEL(c, end);
- ADDOP_JUMP_NOLINE(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
USE_LABEL(c, cleanup);
- ADDOP_I(c, SWAP, 2);
- ADDOP(c, POP_TOP);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP(c, loc, POP_TOP);
USE_LABEL(c, end);
}
@@ -4618,10 +4693,12 @@ check_caller(struct compiler *c, expr_ty e)
case SetComp_kind:
case GeneratorExp_kind:
case JoinedStr_kind:
- case FormattedValue_kind:
- return compiler_warn(c, "'%.200s' object is not callable; "
- "perhaps you missed a comma?",
- infer_type(e)->tp_name);
+ case FormattedValue_kind: {
+ location loc = LOC(e);
+ return compiler_warn(c, loc, "'%.200s' object is not callable; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name);
+ }
default:
return 1;
}
@@ -4645,10 +4722,12 @@ check_subscripter(struct compiler *c, expr_ty e)
case Set_kind:
case SetComp_kind:
case GeneratorExp_kind:
- case Lambda_kind:
- return compiler_warn(c, "'%.200s' object is not subscriptable; "
- "perhaps you missed a comma?",
- infer_type(e)->tp_name);
+ case Lambda_kind: {
+ location loc = LOC(e);
+ return compiler_warn(c, loc, "'%.200s' object is not subscriptable; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name);
+ }
default:
return 1;
}
@@ -4677,12 +4756,14 @@ check_index(struct compiler *c, expr_ty e, expr_ty s)
case List_kind:
case ListComp_kind:
case JoinedStr_kind:
- case FormattedValue_kind:
- return compiler_warn(c, "%.200s indices must be integers or slices, "
- "not %.200s; "
- "perhaps you missed a comma?",
- infer_type(e)->tp_name,
- index_type->tp_name);
+ case FormattedValue_kind: {
+ location loc = LOC(e);
+ return compiler_warn(c, loc, "%.200s indices must be integers "
+ "or slices, not %.200s; "
+ "perhaps you missed a comma?",
+ infer_type(e)->tp_name,
+ index_type->tp_name);
+ }
default:
return 1;
}
@@ -4707,29 +4788,30 @@ is_import_originated(struct compiler *c, expr_ty e)
// If an attribute access spans multiple lines, update the current start
// location to point to the attribute name.
-static void
-update_start_location_to_match_attr(struct compiler *c, expr_ty attr)
+static location
+update_start_location_to_match_attr(struct compiler *c, location loc,
+ expr_ty attr)
{
assert(attr->kind == Attribute_kind);
- struct location *loc = &c->u->u_loc;
- if (loc->lineno != attr->end_lineno) {
- loc->lineno = attr->end_lineno;
+ if (loc.lineno != attr->end_lineno) {
+ loc.lineno = attr->end_lineno;
int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
if (len <= attr->end_col_offset) {
- loc->col_offset = attr->end_col_offset - len;
+ loc.col_offset = attr->end_col_offset - len;
}
else {
// GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
- loc->col_offset = -1;
- loc->end_col_offset = -1;
+ loc.col_offset = -1;
+ loc.end_col_offset = -1;
}
// Make sure the end position still follows the start position, even for
// weird ASTs:
- loc->end_lineno = Py_MAX(loc->lineno, loc->end_lineno);
- if (loc->lineno == loc->end_lineno) {
- loc->end_col_offset = Py_MAX(loc->col_offset, loc->end_col_offset);
+ loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
+ if (loc.lineno == loc.end_lineno) {
+ loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
}
}
+ return loc;
}
// Return 1 if the method call was optimized, -1 if not, and 0 on error.
@@ -4774,19 +4856,21 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
/* Alright, we can optimize the code. */
VISIT(c, expr, meth->v.Attribute.value);
SET_LOC(c, meth);
- update_start_location_to_match_attr(c, meth);
- ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names);
+ location loc = LOC(meth);
+ loc = update_start_location_to_match_attr(c, loc, meth);
+ ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
VISIT_SEQ(c, expr, e->v.Call.args);
if (kwdsl) {
VISIT_SEQ(c, keyword, kwds);
- if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) {
+ if (!compiler_call_simple_kw_helper(c, loc, kwds, kwdsl)) {
return 0;
};
}
SET_LOC(c, e);
- update_start_location_to_match_attr(c, meth);
- ADDOP_I(c, CALL, argsl + kwdsl);
+ loc = LOC(e);
+ loc = update_start_location_to_match_attr(c, loc, meth);
+ ADDOP_I(c, loc, CALL, argsl + kwdsl);
return 1;
}
@@ -4799,14 +4883,15 @@ validate_keywords(struct compiler *c, asdl_keyword_seq *keywords)
if (key->arg == NULL) {
continue;
}
- if (forbidden_name(c, key->arg, Store)) {
+ location loc = LOC(key);
+ if (forbidden_name(c, loc, key->arg, Store)) {
return -1;
}
for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
SET_LOC(c, other);
- compiler_error(c, "keyword argument repeated: %U", key->arg);
+ compiler_error(c, LOC(other), "keyword argument repeated: %U", key->arg);
return -1;
}
}
@@ -4828,10 +4913,12 @@ compiler_call(struct compiler *c, expr_ty e)
return 0;
}
SET_LOC(c, e->v.Call.func);
- ADDOP(c, PUSH_NULL);
+ location loc = LOC(e->v.Call.func);
+ ADDOP(c, loc, PUSH_NULL);
SET_LOC(c, e);
VISIT(c, expr, e->v.Call.func);
- return compiler_call_helper(c, 0,
+ loc = LOC(e);
+ return compiler_call_helper(c, loc, 0,
e->v.Call.args,
e->v.Call.keywords);
}
@@ -4839,23 +4926,23 @@ compiler_call(struct compiler *c, expr_ty e)
static int
compiler_joined_str(struct compiler *c, expr_ty e)
{
-
+ location loc = LOC(e);
Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
if (value_count > STACK_USE_GUIDELINE) {
_Py_DECLARE_STR(empty, "");
- ADDOP_LOAD_CONST_NEW(c, Py_NewRef(&_Py_STR(empty)));
- ADDOP_NAME(c, LOAD_METHOD, &_Py_ID(join), names);
- ADDOP_I(c, BUILD_LIST, 0);
+ ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
+ ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
+ ADDOP_I(c, loc, BUILD_LIST, 0);
for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
- ADDOP_I(c, LIST_APPEND, 1);
+ ADDOP_I(c, loc, LIST_APPEND, 1);
}
- ADDOP_I(c, CALL, 1);
+ ADDOP_I(c, loc, CALL, 1);
}
else {
VISIT_SEQ(c, expr, e->v.JoinedStr.values);
if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) {
- ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
+ ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
}
}
return 1;
@@ -4902,13 +4989,16 @@ compiler_formatted_value(struct compiler *c, expr_ty e)
}
/* And push our opcode and oparg */
- ADDOP_I(c, FORMAT_VALUE, oparg);
+ location loc = LOC(e);
+ ADDOP_I(c, loc, FORMAT_VALUE, oparg);
return 1;
}
static int
-compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end)
+compiler_subkwargs(struct compiler *c, location loc,
+ asdl_keyword_seq *keywords,
+ Py_ssize_t begin, Py_ssize_t end)
{
Py_ssize_t i, n = end - begin;
keyword_ty kw;
@@ -4929,23 +5019,23 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be
Py_INCREF(key);
PyTuple_SET_ITEM(keys, i - begin, key);
}
- ADDOP_LOAD_CONST_NEW(c, keys);
- ADDOP_I(c, BUILD_CONST_KEY_MAP, n);
+ ADDOP_LOAD_CONST_NEW(c, loc, keys);
+ ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
return 1;
}
if (big) {
- ADDOP_I_NOLINE(c, BUILD_MAP, 0);
+ ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
}
for (i = begin; i < end; i++) {
kw = asdl_seq_GET(keywords, i);
- ADDOP_LOAD_CONST(c, kw->arg);
+ ADDOP_LOAD_CONST(c, loc, kw->arg);
VISIT(c, expr, kw->value);
if (big) {
- ADDOP_I_NOLINE(c, MAP_ADD, 1);
+ ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
}
}
if (!big) {
- ADDOP_I(c, BUILD_MAP, n);
+ ADDOP_I(c, loc, BUILD_MAP, n);
}
return 1;
}
@@ -4955,9 +5045,8 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be
* Returns 1 on success, 0 on error.
*/
static int
-compiler_call_simple_kw_helper(struct compiler *c,
- asdl_keyword_seq *keywords,
- Py_ssize_t nkwelts)
+compiler_call_simple_kw_helper(struct compiler *c, location loc,
+ asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
{
PyObject *names;
names = PyTuple_New(nkwelts);
@@ -4974,14 +5063,14 @@ compiler_call_simple_kw_helper(struct compiler *c,
return 0;
}
Py_DECREF(names);
- ADDOP_I(c, KW_NAMES, arg);
+ ADDOP_I(c, loc, KW_NAMES, arg);
return 1;
}
/* shared code between compiler_call and compiler_class */
static int
-compiler_call_helper(struct compiler *c,
+compiler_call_helper(struct compiler *c, location loc,
int n, /* Args already pushed */
asdl_expr_seq *args,
asdl_keyword_seq *keywords)
@@ -5019,11 +5108,11 @@ compiler_call_helper(struct compiler *c,
}
if (nkwelts) {
VISIT_SEQ(c, keyword, keywords);
- if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) {
+ if (!compiler_call_simple_kw_helper(c, loc, keywords, nkwelts)) {
return 0;
};
}
- ADDOP_I(c, CALL, n + nelts + nkwelts);
+ ADDOP_I(c, loc, CALL, n + nelts + nkwelts);
return 1;
ex_call:
@@ -5032,7 +5121,7 @@ compiler_call_helper(struct compiler *c,
if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
}
- else if (starunpack_helper(c, args, n, BUILD_LIST,
+ else if (starunpack_helper(c, loc, args, n, BUILD_LIST,
LIST_APPEND, LIST_EXTEND, 1) == 0) {
return 0;
}
@@ -5047,21 +5136,21 @@ compiler_call_helper(struct compiler *c,
if (kw->arg == NULL) {
/* A keyword argument unpacking. */
if (nseen) {
- if (!compiler_subkwargs(c, keywords, i - nseen, i)) {
+ if (!compiler_subkwargs(c, loc, keywords, i - nseen, i)) {
return 0;
}
if (have_dict) {
- ADDOP_I(c, DICT_MERGE, 1);
+ ADDOP_I(c, loc, DICT_MERGE, 1);
}
have_dict = 1;
nseen = 0;
}
if (!have_dict) {
- ADDOP_I(c, BUILD_MAP, 0);
+ ADDOP_I(c, loc, BUILD_MAP, 0);
have_dict = 1;
}
VISIT(c, expr, kw->value);
- ADDOP_I(c, DICT_MERGE, 1);
+ ADDOP_I(c, loc, DICT_MERGE, 1);
}
else {
nseen++;
@@ -5069,17 +5158,17 @@ compiler_call_helper(struct compiler *c,
}
if (nseen) {
/* Pack up any trailing keyword arguments. */
- if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) {
+ if (!compiler_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts)) {
return 0;
}
if (have_dict) {
- ADDOP_I(c, DICT_MERGE, 1);
+ ADDOP_I(c, loc, DICT_MERGE, 1);
}
have_dict = 1;
}
assert(have_dict);
}
- ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0);
+ ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
return 1;
}
@@ -5099,7 +5188,7 @@ compiler_call_helper(struct compiler *c,
static int
-compiler_comprehension_generator(struct compiler *c,
+compiler_comprehension_generator(struct compiler *c, location *ploc,
asdl_comprehension_seq *generators, int gen_index,
int depth,
expr_ty elt, expr_ty val, int type)
@@ -5108,15 +5197,15 @@ compiler_comprehension_generator(struct compiler *c,
gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
if (gen->is_async) {
return compiler_async_comprehension_generator(
- c, generators, gen_index, depth, elt, val, type);
+ c, ploc, generators, gen_index, depth, elt, val, type);
} else {
return compiler_sync_comprehension_generator(
- c, generators, gen_index, depth, elt, val, type);
+ c, ploc, generators, gen_index, depth, elt, val, type);
}
}
static int
-compiler_sync_comprehension_generator(struct compiler *c,
+compiler_sync_comprehension_generator(struct compiler *c, location *ploc,
asdl_comprehension_seq *generators, int gen_index,
int depth,
expr_ty elt, expr_ty val, int type)
@@ -5136,7 +5225,7 @@ compiler_sync_comprehension_generator(struct compiler *c,
if (gen_index == 0) {
/* Receive outermost iter as an implicit argument */
c->u->u_argcount = 1;
- ADDOP_I(c, LOAD_FAST, 0);
+ ADDOP_I(c, *ploc, LOAD_FAST, 0);
}
else {
/* Sub-iter - calculate on the fly */
@@ -5163,13 +5252,13 @@ compiler_sync_comprehension_generator(struct compiler *c,
}
if (IS_LABEL(start)) {
VISIT(c, expr, gen->iter);
- ADDOP(c, GET_ITER);
+ ADDOP(c, *ploc, GET_ITER);
}
}
if (IS_LABEL(start)) {
depth++;
USE_LABEL(c, start);
- ADDOP_JUMP(c, FOR_ITER, anchor);
+ ADDOP_JUMP(c, *ploc, FOR_ITER, anchor);
}
VISIT(c, expr, gen->target);
@@ -5177,12 +5266,12 @@ compiler_sync_comprehension_generator(struct compiler *c,
n = asdl_seq_LEN(gen->ifs);
for (i = 0; i < n; i++) {
expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
- if (!compiler_jump_if(c, e, if_cleanup, 0))
+ if (!compiler_jump_if(c, ploc, e, if_cleanup, 0))
return 0;
}
if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_comprehension_generator(c,
+ if (!compiler_comprehension_generator(c, ploc,
generators, gen_index, depth,
elt, val, type))
return 0;
@@ -5193,23 +5282,23 @@ compiler_sync_comprehension_generator(struct compiler *c,
switch (type) {
case COMP_GENEXP:
VISIT(c, expr, elt);
- ADDOP_YIELD(c);
- ADDOP(c, POP_TOP);
+ ADDOP_YIELD(c, *ploc);
+ ADDOP(c, *ploc, POP_TOP);
break;
case COMP_LISTCOMP:
VISIT(c, expr, elt);
- ADDOP_I(c, LIST_APPEND, depth + 1);
+ ADDOP_I(c, *ploc, LIST_APPEND, depth + 1);
break;
case COMP_SETCOMP:
VISIT(c, expr, elt);
- ADDOP_I(c, SET_ADD, depth + 1);
+ ADDOP_I(c, *ploc, SET_ADD, depth + 1);
break;
case COMP_DICTCOMP:
/* With '{k: v}', k is evaluated before v, so we do
the same. */
VISIT(c, expr, elt);
VISIT(c, expr, val);
- ADDOP_I(c, MAP_ADD, depth + 1);
+ ADDOP_I(c, *ploc, MAP_ADD, depth + 1);
break;
default:
return 0;
@@ -5218,7 +5307,7 @@ compiler_sync_comprehension_generator(struct compiler *c,
USE_LABEL(c, if_cleanup);
if (IS_LABEL(start)) {
- ADDOP_JUMP(c, JUMP, start);
+ ADDOP_JUMP(c, *ploc, JUMP, start);
USE_LABEL(c, anchor);
}
@@ -5227,7 +5316,7 @@ compiler_sync_comprehension_generator(struct compiler *c,
}
static int
-compiler_async_comprehension_generator(struct compiler *c,
+compiler_async_comprehension_generator(struct compiler *c, location *ploc,
asdl_comprehension_seq *generators, int gen_index,
int depth,
expr_ty elt, expr_ty val, int type)
@@ -5243,38 +5332,38 @@ compiler_async_comprehension_generator(struct compiler *c,
if (gen_index == 0) {
/* Receive outermost iter as an implicit argument */
c->u->u_argcount = 1;
- ADDOP_I(c, LOAD_FAST, 0);
+ ADDOP_I(c, *ploc, LOAD_FAST, 0);
}
else {
/* Sub-iter - calculate on the fly */
VISIT(c, expr, gen->iter);
- ADDOP(c, GET_AITER);
+ ADDOP(c, *ploc, GET_AITER);
}
USE_LABEL(c, start);
/* Runtime will push a block here, so we need to account for that */
- if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start,
- NO_LABEL, NULL)) {
+ if (!compiler_push_fblock(c, *ploc, ASYNC_COMPREHENSION_GENERATOR,
+ start, NO_LABEL, NULL)) {
return 0;
}
- ADDOP_JUMP(c, SETUP_FINALLY, except);
- ADDOP(c, GET_ANEXT);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
- ADDOP(c, POP_BLOCK);
+ ADDOP_JUMP(c, *ploc, SETUP_FINALLY, except);
+ ADDOP(c, *ploc, GET_ANEXT);
+ ADDOP_LOAD_CONST(c, *ploc, Py_None);
+ ADD_YIELD_FROM(c, *ploc, 1);
+ ADDOP(c, *ploc, POP_BLOCK);
VISIT(c, expr, gen->target);
n = asdl_seq_LEN(gen->ifs);
for (i = 0; i < n; i++) {
expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
- if (!compiler_jump_if(c, e, if_cleanup, 0))
+ if (!compiler_jump_if(c, ploc, e, if_cleanup, 0))
return 0;
}
depth++;
if (++gen_index < asdl_seq_LEN(generators))
- if (!compiler_comprehension_generator(c,
+ if (!compiler_comprehension_generator(c, ploc,
generators, gen_index, depth,
elt, val, type))
return 0;
@@ -5285,23 +5374,23 @@ compiler_async_comprehension_generator(struct compiler *c,
switch (type) {
case COMP_GENEXP:
VISIT(c, expr, elt);
- ADDOP_YIELD(c);
- ADDOP(c, POP_TOP);
+ ADDOP_YIELD(c, *ploc);
+ ADDOP(c, *ploc, POP_TOP);
break;
case COMP_LISTCOMP:
VISIT(c, expr, elt);
- ADDOP_I(c, LIST_APPEND, depth + 1);
+ ADDOP_I(c, *ploc, LIST_APPEND, depth + 1);
break;
case COMP_SETCOMP:
VISIT(c, expr, elt);
- ADDOP_I(c, SET_ADD, depth + 1);
+ ADDOP_I(c, *ploc, SET_ADD, depth + 1);
break;
case COMP_DICTCOMP:
/* With '{k: v}', k is evaluated before v, so we do
the same. */
VISIT(c, expr, elt);
VISIT(c, expr, val);
- ADDOP_I(c, MAP_ADD, depth + 1);
+ ADDOP_I(c, *ploc, MAP_ADD, depth + 1);
break;
default:
return 0;
@@ -5309,14 +5398,14 @@ compiler_async_comprehension_generator(struct compiler *c,
}
USE_LABEL(c, if_cleanup);
- ADDOP_JUMP(c, JUMP, start);
+ ADDOP_JUMP(c, *ploc, JUMP, start);
compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start);
USE_LABEL(c, except);
//UNSET_LOC(c);
- ADDOP(c, END_ASYNC_FOR);
+ ADDOP(c, *ploc, END_ASYNC_FOR);
return 1;
}
@@ -5340,6 +5429,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
goto error;
}
SET_LOC(c, e);
+ location loc = LOC(e);
is_async_generator = c->u->u_ste->ste_coroutine;
@@ -5348,8 +5438,8 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
scope_type != COMPILER_SCOPE_COMPREHENSION &&
!is_top_level_await)
{
- compiler_error(c, "asynchronous comprehension outside of "
- "an asynchronous function");
+ compiler_error(c, loc, "asynchronous comprehension outside of "
+ "an asynchronous function");
goto error_in_scope;
}
@@ -5371,15 +5461,15 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
goto error_in_scope;
}
- ADDOP_I(c, op, 0);
+ ADDOP_I(c, loc, op, 0);
}
- if (!compiler_comprehension_generator(c, generators, 0, 0, elt,
- val, type))
+ if (!compiler_comprehension_generator(c, &loc, generators, 0, 0,
+ elt, val, type))
goto error_in_scope;
if (type != COMP_GENEXP) {
- ADDOP(c, RETURN_VALUE);
+ ADDOP(c, loc, RETURN_VALUE);
}
co = assemble(c, 1);
@@ -5392,7 +5482,8 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
if (co == NULL)
goto error;
- if (!compiler_make_closure(c, co, 0, qualname)) {
+ loc = LOC(e);
+ if (!compiler_make_closure(c, loc, co, 0, qualname)) {
goto error;
}
Py_DECREF(qualname);
@@ -5400,18 +5491,19 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
VISIT(c, expr, outermost->iter);
+ loc = LOC(e);
if (outermost->is_async) {
- ADDOP(c, GET_AITER);
+ ADDOP(c, loc, GET_AITER);
} else {
- ADDOP(c, GET_ITER);
+ ADDOP(c, loc, GET_ITER);
}
- ADDOP_I(c, CALL, 0);
+ ADDOP_I(c, loc, CALL, 0);
if (is_async_generator && type != COMP_GENEXP) {
- ADDOP_I(c, GET_AWAITABLE, 0);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP_I(c, loc, GET_AWAITABLE, 0);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
}
return 1;
@@ -5477,20 +5569,20 @@ static int
compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) {
UNSET_LOC(c);
NEW_JUMP_TARGET_LABEL(c, suppress);
- ADDOP_JUMP(c, POP_JUMP_IF_TRUE, suppress);
- ADDOP_I(c, RERAISE, 2);
+ ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
+ ADDOP_I(c, NO_LOCATION, RERAISE, 2);
USE_LABEL(c, suppress);
- ADDOP(c, POP_TOP); /* exc_value */
- ADDOP(c, POP_BLOCK);
- ADDOP(c, POP_EXCEPT);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_EXCEPT);
+ ADDOP(c, NO_LOCATION, POP_TOP);
+ ADDOP(c, NO_LOCATION, POP_TOP);
NEW_JUMP_TARGET_LABEL(c, exit);
- ADDOP_JUMP(c, JUMP, exit);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
USE_LABEL(c, cleanup);
- POP_EXCEPT_AND_RERAISE(c);
+ POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
USE_LABEL(c, exit);
return 1;
@@ -5523,13 +5615,14 @@ compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) {
static int
compiler_async_with(struct compiler *c, stmt_ty s, int pos)
{
+ location loc = LOC(s);
withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
assert(s->kind == AsyncWith_kind);
if (IS_TOP_LEVEL_AWAIT(c)){
c->u->u_ste->ste_coroutine = 1;
} else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
- return compiler_error(c, "'async with' outside async function");
+ return compiler_error(c, loc, "'async with' outside async function");
}
NEW_JUMP_TARGET_LABEL(c, block);
@@ -5540,16 +5633,16 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
/* Evaluate EXPR */
VISIT(c, expr, item->context_expr);
- ADDOP(c, BEFORE_ASYNC_WITH);
- ADDOP_I(c, GET_AWAITABLE, 1);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP(c, loc, BEFORE_ASYNC_WITH);
+ ADDOP_I(c, loc, GET_AWAITABLE, 1);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
- ADDOP_JUMP(c, SETUP_WITH, final);
+ ADDOP_JUMP(c, loc, SETUP_WITH, final);
/* SETUP_WITH pushes a finally block. */
USE_LABEL(c, block);
- if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) {
+ if (!compiler_push_fblock(c, loc, ASYNC_WITH, block, final, s)) {
return 0;
}
@@ -5558,43 +5651,46 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
}
else {
/* Discard result from context.__aenter__() */
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
}
pos++;
- if (pos == asdl_seq_LEN(s->v.AsyncWith.items))
+ if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
/* BLOCK code */
VISIT_SEQ(c, stmt, s->v.AsyncWith.body)
- else if (!compiler_async_with(c, s, pos))
+ }
+ else if (!compiler_async_with(c, s, pos)) {
return 0;
+ }
compiler_pop_fblock(c, ASYNC_WITH, block);
- ADDOP(c, POP_BLOCK);
+
+ SET_LOC(c, s);
+ ADDOP(c, loc, POP_BLOCK);
/* End of body; start the cleanup */
/* For successful outcome:
* call __exit__(None, None, None)
*/
- SET_LOC(c, s);
- if(!compiler_call_exit_with_nones(c))
+ if(!compiler_call_exit_with_nones(c, loc))
return 0;
- ADDOP_I(c, GET_AWAITABLE, 2);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP_I(c, loc, GET_AWAITABLE, 2);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
- ADDOP_JUMP(c, JUMP, exit);
+ ADDOP_JUMP(c, loc, JUMP, exit);
/* For exceptional outcome: */
USE_LABEL(c, final);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
- ADDOP(c, WITH_EXCEPT_START);
- ADDOP_I(c, GET_AWAITABLE, 2);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
+ ADDOP(c, loc, PUSH_EXC_INFO);
+ ADDOP(c, loc, WITH_EXCEPT_START);
+ ADDOP_I(c, loc, GET_AWAITABLE, 2);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
compiler_with_except_finish(c, cleanup);
USE_LABEL(c, exit);
@@ -5638,12 +5734,13 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
/* Evaluate EXPR */
VISIT(c, expr, item->context_expr);
/* Will push bound __exit__ */
- ADDOP(c, BEFORE_WITH);
- ADDOP_JUMP(c, SETUP_WITH, final);
+ location loc = LOC(s);
+ ADDOP(c, loc, BEFORE_WITH);
+ ADDOP_JUMP(c, loc, SETUP_WITH, final);
/* SETUP_WITH pushes a finally block. */
USE_LABEL(c, block);
- if (!compiler_push_fblock(c, WITH, block, final, s)) {
+ if (!compiler_push_fblock(c, loc, WITH, block, final, s)) {
return 0;
}
@@ -5652,7 +5749,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
}
else {
/* Discard result from context.__enter__() */
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
}
pos++;
@@ -5665,7 +5762,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
/* Mark all following code as artificial */
UNSET_LOC(c);
- ADDOP(c, POP_BLOCK);
+ ADDOP(c, NO_LOCATION, POP_BLOCK);
compiler_pop_fblock(c, WITH, block);
/* End of body; start the cleanup. */
@@ -5674,17 +5771,18 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
* call __exit__(None, None, None)
*/
SET_LOC(c, s);
- if (!compiler_call_exit_with_nones(c))
+ loc = LOC(s);
+ if (!compiler_call_exit_with_nones(c, loc))
return 0;
- ADDOP(c, POP_TOP);
- ADDOP_JUMP(c, JUMP, exit);
+ ADDOP(c, loc, POP_TOP);
+ ADDOP_JUMP(c, loc, JUMP, exit);
/* For exceptional outcome: */
USE_LABEL(c, final);
- ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
- ADDOP(c, PUSH_EXC_INFO);
- ADDOP(c, WITH_EXCEPT_START);
+ ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
+ ADDOP(c, loc, PUSH_EXC_INFO);
+ ADDOP(c, loc, WITH_EXCEPT_START);
compiler_with_except_finish(c, cleanup);
USE_LABEL(c, exit);
@@ -5694,10 +5792,11 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
static int
compiler_visit_expr1(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
switch (e->kind) {
case NamedExpr_kind:
VISIT(c, expr, e->v.NamedExpr.value);
- ADDOP_I(c, COPY, 1);
+ ADDOP_I(c, loc, COPY, 1);
VISIT(c, expr, e->v.NamedExpr.target);
break;
case BoolOp_kind:
@@ -5705,11 +5804,11 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
case BinOp_kind:
VISIT(c, expr, e->v.BinOp.left);
VISIT(c, expr, e->v.BinOp.right);
- ADDOP_BINARY(c, e->v.BinOp.op);
+ ADDOP_BINARY(c, loc, e->v.BinOp.op);
break;
case UnaryOp_kind:
VISIT(c, expr, e->v.UnaryOp.operand);
- ADDOP(c, unaryop(e->v.UnaryOp.op));
+ ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
break;
case Lambda_kind:
return compiler_lambda(c, e);
@@ -5729,50 +5828,50 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
return compiler_dictcomp(c, e);
case Yield_kind:
if (c->u->u_ste->ste_type != FunctionBlock)
- return compiler_error(c, "'yield' outside function");
+ return compiler_error(c, loc, "'yield' outside function");
if (e->v.Yield.value) {
VISIT(c, expr, e->v.Yield.value);
}
else {
- ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
}
- ADDOP_YIELD(c);
+ ADDOP_YIELD(c, loc);
break;
case YieldFrom_kind:
if (c->u->u_ste->ste_type != FunctionBlock)
- return compiler_error(c, "'yield' outside function");
+ return compiler_error(c, loc, "'yield' outside function");
if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION)
- return compiler_error(c, "'yield from' inside async function");
+ return compiler_error(c, loc, "'yield from' inside async function");
VISIT(c, expr, e->v.YieldFrom.value);
- ADDOP(c, GET_YIELD_FROM_ITER);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 0);
+ ADDOP(c, loc, GET_YIELD_FROM_ITER);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 0);
break;
case Await_kind:
if (!IS_TOP_LEVEL_AWAIT(c)){
if (c->u->u_ste->ste_type != FunctionBlock){
- return compiler_error(c, "'await' outside function");
+ return compiler_error(c, loc, "'await' outside function");
}
if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){
- return compiler_error(c, "'await' outside async function");
+ return compiler_error(c, loc, "'await' outside async function");
}
}
VISIT(c, expr, e->v.Await.value);
- ADDOP_I(c, GET_AWAITABLE, 0);
- ADDOP_LOAD_CONST(c, Py_None);
- ADD_YIELD_FROM(c, 1);
+ ADDOP_I(c, loc, GET_AWAITABLE, 0);
+ ADDOP_LOAD_CONST(c, loc, Py_None);
+ ADD_YIELD_FROM(c, loc, 1);
break;
case Compare_kind:
return compiler_compare(c, e);
case Call_kind:
return compiler_call(c, e);
case Constant_kind:
- ADDOP_LOAD_CONST(c, e->v.Constant.value);
+ ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
break;
case JoinedStr_kind:
return compiler_joined_str(c, e);
@@ -5781,21 +5880,20 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
/* The following exprs can be assignment targets. */
case Attribute_kind:
VISIT(c, expr, e->v.Attribute.value);
- update_start_location_to_match_attr(c, e);
+ loc = LOC(e);
+ loc = update_start_location_to_match_attr(c, loc, e);
switch (e->v.Attribute.ctx) {
case Load:
- {
- ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
+ ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
break;
- }
case Store:
- if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) {
+ if (forbidden_name(c, loc, e->v.Attribute.attr, e->v.Attribute.ctx)) {
return 0;
}
- ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+ ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
break;
case Del:
- ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names);
+ ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
break;
}
break;
@@ -5806,10 +5904,10 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
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,
+ return compiler_error(c, loc,
"starred assignment target must be in a list or tuple");
default:
- return compiler_error(c,
+ return compiler_error(c, loc,
"can't use starred expression here");
}
break;
@@ -5819,11 +5917,11 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
if (n == 0) {
return 0;
}
- ADDOP_I(c, BUILD_SLICE, n);
+ ADDOP_I(c, loc, BUILD_SLICE, n);
break;
}
case Name_kind:
- return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx);
+ return compiler_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
/* child nodes of List and Tuple will have expr_context set */
case List_kind:
return compiler_list(c, e);
@@ -5836,10 +5934,8 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
static int
compiler_visit_expr(struct compiler *c, expr_ty e)
{
- struct location old_loc = c->u->u_loc;
SET_LOC(c, e);
int res = compiler_visit_expr1(c, e);
- c->u->u_loc = old_loc;
return res;
}
@@ -5856,15 +5952,15 @@ compiler_augassign(struct compiler *c, stmt_ty s)
assert(s->kind == AugAssign_kind);
expr_ty e = s->v.AugAssign.target;
- struct location old_loc = c->u->u_loc;
+ location loc = LOC(e);
SET_LOC(c, e);
switch (e->kind) {
case Attribute_kind:
VISIT(c, expr, e->v.Attribute.value);
- ADDOP_I(c, COPY, 1);
- update_start_location_to_match_attr(c, e);
- ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names);
+ ADDOP_I(c, loc, COPY, 1);
+ loc = update_start_location_to_match_attr(c, loc, e);
+ ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
break;
case Subscript_kind:
VISIT(c, expr, e->v.Subscript.value);
@@ -5872,20 +5968,20 @@ compiler_augassign(struct compiler *c, stmt_ty s)
if (!compiler_slice(c, e->v.Subscript.slice)) {
return 0;
}
- ADDOP_I(c, COPY, 3);
- ADDOP_I(c, COPY, 3);
- ADDOP_I(c, COPY, 3);
- ADDOP(c, BINARY_SLICE);
+ ADDOP_I(c, loc, COPY, 3);
+ ADDOP_I(c, loc, COPY, 3);
+ ADDOP_I(c, loc, COPY, 3);
+ ADDOP(c, loc, BINARY_SLICE);
}
else {
VISIT(c, expr, e->v.Subscript.slice);
- ADDOP_I(c, COPY, 2);
- ADDOP_I(c, COPY, 2);
- ADDOP(c, BINARY_SUBSCR);
+ ADDOP_I(c, loc, COPY, 2);
+ ADDOP_I(c, loc, COPY, 2);
+ ADDOP(c, loc, BINARY_SUBSCR);
}
break;
case Name_kind:
- if (!compiler_nameop(c, e->v.Name.id, Load))
+ if (!compiler_nameop(c, loc, e->v.Name.id, Load))
return 0;
break;
default:
@@ -5895,34 +5991,35 @@ compiler_augassign(struct compiler *c, stmt_ty s)
return 0;
}
- c->u->u_loc = old_loc;
+ loc = LOC(s);
VISIT(c, expr, s->v.AugAssign.value);
- ADDOP_INPLACE(c, s->v.AugAssign.op);
+ ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
SET_LOC(c, e);
+ loc = LOC(e);
switch (e->kind) {
case Attribute_kind:
- update_start_location_to_match_attr(c, e);
- ADDOP_I(c, SWAP, 2);
- ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names);
+ loc = update_start_location_to_match_attr(c, loc, e);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
break;
case Subscript_kind:
if (is_two_element_slice(e->v.Subscript.slice)) {
- ADDOP_I(c, SWAP, 4);
- ADDOP_I(c, SWAP, 3);
- ADDOP_I(c, SWAP, 2);
- ADDOP(c, STORE_SLICE);
+ ADDOP_I(c, loc, SWAP, 4);
+ ADDOP_I(c, loc, SWAP, 3);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP(c, loc, STORE_SLICE);
}
else {
- ADDOP_I(c, SWAP, 3);
- ADDOP_I(c, SWAP, 2);
- ADDOP(c, STORE_SUBSCR);
+ ADDOP_I(c, loc, SWAP, 3);
+ ADDOP_I(c, loc, SWAP, 2);
+ ADDOP(c, loc, STORE_SUBSCR);
}
break;
case Name_kind:
- return compiler_nameop(c, e->v.Name.id, Store);
+ return compiler_nameop(c, loc, e->v.Name.id, Store);
default:
Py_UNREACHABLE();
}
@@ -5933,7 +6030,7 @@ static int
check_ann_expr(struct compiler *c, expr_ty e)
{
VISIT(c, expr, e);
- ADDOP(c, POP_TOP);
+ ADDOP(c, LOC(e), POP_TOP);
return 1;
}
@@ -5989,6 +6086,7 @@ check_ann_subscr(struct compiler *c, expr_ty e)
static int
compiler_annassign(struct compiler *c, stmt_ty s)
{
+ location loc = LOC(s);
expr_ty targ = s->v.AnnAssign.target;
PyObject* mangled;
@@ -6001,7 +6099,7 @@ compiler_annassign(struct compiler *c, stmt_ty s)
}
switch (targ->kind) {
case Name_kind:
- if (forbidden_name(c, targ->v.Name.id, Store))
+ if (forbidden_name(c, loc, targ->v.Name.id, Store))
return 0;
/* If we have a simple name in a module or class, store annotation. */
if (s->v.AnnAssign.simple &&
@@ -6013,14 +6111,14 @@ compiler_annassign(struct compiler *c, stmt_ty s)
else {
VISIT(c, expr, s->v.AnnAssign.annotation);
}
- ADDOP_NAME(c, LOAD_NAME, &_Py_ID(__annotations__), names);
+ ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
- ADDOP_LOAD_CONST_NEW(c, mangled);
- ADDOP(c, STORE_SUBSCR);
+ ADDOP_LOAD_CONST_NEW(c, loc, mangled);
+ ADDOP(c, loc, STORE_SUBSCR);
}
break;
case Attribute_kind:
- if (forbidden_name(c, targ->v.Attribute.attr, Store))
+ if (forbidden_name(c, loc, targ->v.Attribute.attr, Store))
return 0;
if (!s->v.AnnAssign.value &&
!check_ann_expr(c, targ->v.Attribute.value)) {
@@ -6052,7 +6150,8 @@ compiler_annassign(struct compiler *c, stmt_ty s)
*/
static int
-compiler_error(struct compiler *c, const char *format, ...)
+compiler_error(struct compiler *c, location loc,
+ const char *format, ...)
{
va_list vargs;
va_start(vargs, format);
@@ -6061,22 +6160,21 @@ compiler_error(struct compiler *c, const char *format, ...)
if (msg == NULL) {
return 0;
}
- PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_loc.lineno);
- if (loc == NULL) {
+ PyObject *loc_obj = PyErr_ProgramTextObject(c->c_filename, loc.lineno);
+ if (loc_obj == NULL) {
Py_INCREF(Py_None);
- loc = Py_None;
+ loc_obj = Py_None;
}
- struct location u_loc = c->u->u_loc;
PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename,
- u_loc.lineno, u_loc.col_offset + 1, loc,
- u_loc.end_lineno, u_loc.end_col_offset + 1);
+ loc.lineno, loc.col_offset + 1, loc_obj,
+ loc.end_lineno, loc.end_col_offset + 1);
Py_DECREF(msg);
if (args == NULL) {
goto exit;
}
PyErr_SetObject(PyExc_SyntaxError, args);
exit:
- Py_DECREF(loc);
+ Py_DECREF(loc_obj);
Py_XDECREF(args);
return 0;
}
@@ -6086,7 +6184,8 @@ compiler_error(struct compiler *c, const char *format, ...)
and returns 0.
*/
static int
-compiler_warn(struct compiler *c, const char *format, ...)
+compiler_warn(struct compiler *c, location loc,
+ const char *format, ...)
{
va_list vargs;
va_start(vargs, format);
@@ -6096,14 +6195,14 @@ compiler_warn(struct compiler *c, const char *format, ...)
return 0;
}
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
- c->u->u_loc.lineno, NULL, NULL) < 0)
+ loc.lineno, NULL, NULL) < 0)
{
if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
/* Replace the SyntaxWarning exception with a SyntaxError
to get a more accurate error report */
PyErr_Clear();
assert(PyUnicode_AsUTF8(msg) != NULL);
- compiler_error(c, PyUnicode_AsUTF8(msg));
+ compiler_error(c, loc, PyUnicode_AsUTF8(msg));
}
Py_DECREF(msg);
return 0;
@@ -6115,6 +6214,7 @@ compiler_warn(struct compiler *c, const char *format, ...)
static int
compiler_subscript(struct compiler *c, expr_ty e)
{
+ location loc = LOC(e);
expr_context_ty ctx = e->v.Subscript.ctx;
int op = 0;
@@ -6133,11 +6233,11 @@ compiler_subscript(struct compiler *c, expr_ty e)
return 0;
}
if (ctx == Load) {
- ADDOP(c, BINARY_SLICE);
+ ADDOP(c, loc, BINARY_SLICE);
}
else {
assert(ctx == Store);
- ADDOP(c, STORE_SLICE);
+ ADDOP(c, loc, STORE_SLICE);
}
}
else {
@@ -6148,7 +6248,7 @@ compiler_subscript(struct compiler *c, expr_ty e)
case Del: op = DELETE_SUBSCR; break;
}
assert(op);
- ADDOP(c, op);
+ ADDOP(c, loc, op);
}
return 1;
}
@@ -6166,14 +6266,14 @@ compiler_slice(struct compiler *c, expr_ty s)
VISIT(c, expr, s->v.Slice.lower);
}
else {
- ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_LOAD_CONST(c, LOC(s), Py_None);
}
if (s->v.Slice.upper) {
VISIT(c, expr, s->v.Slice.upper);
}
else {
- ADDOP_LOAD_CONST(c, Py_None);
+ ADDOP_LOAD_CONST(c, LOC(s), Py_None);
}
if (s->v.Slice.step) {
@@ -6230,19 +6330,21 @@ ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n)
// Use op to jump to the correct fail_pop block.
static int
-jump_to_fail_pop(struct compiler *c, pattern_context *pc, int op)
+jump_to_fail_pop(struct compiler *c, location loc,
+ pattern_context *pc, int op)
{
// Pop any items on the top of the stack, plus any objects we were going to
// capture on success:
Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
RETURN_IF_FALSE(ensure_fail_pop(c, pc, pops));
- ADDOP_JUMP(c, op, pc->fail_pop[pops]);
+ ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
return 1;
}
// Build all of the fail_pop blocks and reset fail_pop.
static int
-emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc)
+emit_and_reset_fail_pop(struct compiler *c, location loc,
+ pattern_context *pc)
{
if (!pc->fail_pop_size) {
assert(pc->fail_pop == NULL);
@@ -6250,7 +6352,7 @@ emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc)
}
while (--pc->fail_pop_size) {
USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
- if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, COMPILER_LOC(c))) {
+ if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, loc)) {
pc->fail_pop_size = 0;
PyObject_Free(pc->fail_pop);
pc->fail_pop = NULL;
@@ -6264,29 +6366,31 @@ emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc)
}
static int
-compiler_error_duplicate_store(struct compiler *c, identifier n)
+compiler_error_duplicate_store(struct compiler *c, location loc, identifier n)
{
- return compiler_error(c, "multiple assignments to name %R in pattern", n);
+ return compiler_error(c, loc,
+ "multiple assignments to name %R in pattern", n);
}
// Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
static int
-pattern_helper_rotate(struct compiler *c, Py_ssize_t count)
+pattern_helper_rotate(struct compiler *c, location loc, Py_ssize_t count)
{
while (1 < count) {
- ADDOP_I(c, SWAP, count--);
+ ADDOP_I(c, loc, SWAP, count--);
}
return 1;
}
static int
-pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc)
+pattern_helper_store_name(struct compiler *c, location loc,
+ identifier n, pattern_context *pc)
{
if (n == NULL) {
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
return 1;
}
- if (forbidden_name(c, n, Store)) {
+ if (forbidden_name(c, loc, n, Store)) {
return 0;
}
// Can't assign to the same name twice:
@@ -6295,17 +6399,18 @@ pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc)
return 0;
}
if (duplicate) {
- return compiler_error_duplicate_store(c, n);
+ return compiler_error_duplicate_store(c, loc, n);
}
// Rotate this object underneath any items we need to preserve:
Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
- RETURN_IF_FALSE(pattern_helper_rotate(c, rotations));
+ RETURN_IF_FALSE(pattern_helper_rotate(c, loc, rotations));
return !PyList_Append(pc->stores, n);
}
static int
-pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts)
+pattern_unpack_helper(struct compiler *c, location loc,
+ asdl_pattern_seq *elts)
{
Py_ssize_t n = asdl_seq_LEN(elts);
int seen_star = 0;
@@ -6314,28 +6419,29 @@ pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts)
if (elt->kind == MatchStar_kind && !seen_star) {
if ((i >= (1 << 8)) ||
(n-i-1 >= (INT_MAX >> 8)))
- return compiler_error(c,
+ return compiler_error(c, loc,
"too many expressions in "
"star-unpacking sequence pattern");
- ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8)));
+ ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
seen_star = 1;
}
else if (elt->kind == MatchStar_kind) {
- return compiler_error(c,
+ return compiler_error(c, loc,
"multiple starred expressions in sequence pattern");
}
}
if (!seen_star) {
- ADDOP_I(c, UNPACK_SEQUENCE, n);
+ ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
}
return 1;
}
static int
-pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns,
- Py_ssize_t star, pattern_context *pc)
+pattern_helper_sequence_unpack(struct compiler *c, location *ploc,
+ asdl_pattern_seq *patterns, Py_ssize_t star,
+ pattern_context *pc)
{
- RETURN_IF_FALSE(pattern_unpack_helper(c, patterns));
+ RETURN_IF_FALSE(pattern_unpack_helper(c, *ploc, patterns));
Py_ssize_t size = asdl_seq_LEN(patterns);
// We've now got a bunch of new subjects on the stack. They need to remain
// there after each subpattern match:
@@ -6344,7 +6450,7 @@ pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns,
// One less item to keep track of each time we loop through:
pc->on_top--;
pattern_ty pattern = asdl_seq_GET(patterns, i);
- RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
+ RETURN_IF_FALSE(compiler_pattern_subpattern(c, ploc, pattern, pc));
}
return 1;
}
@@ -6353,8 +6459,9 @@ pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns,
// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
static int
-pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns,
- Py_ssize_t star, pattern_context *pc)
+pattern_helper_sequence_subscr(struct compiler *c, location *ploc,
+ asdl_pattern_seq *patterns, Py_ssize_t star,
+ pattern_context *pc)
{
// We need to keep the subject around for extracting elements:
pc->on_top++;
@@ -6368,39 +6475,41 @@ pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns,
assert(WILDCARD_STAR_CHECK(pattern));
continue;
}
- ADDOP_I(c, COPY, 1);
+ ADDOP_I(c, *ploc, COPY, 1);
if (i < star) {
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i));
+ ADDOP_LOAD_CONST_NEW(c, *ploc, PyLong_FromSsize_t(i));
}
else {
// The subject may not support negative indexing! Compute a
// nonnegative index:
- ADDOP(c, GET_LEN);
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - i));
- ADDOP_BINARY(c, Sub);
+ ADDOP(c, *ploc, GET_LEN);
+ ADDOP_LOAD_CONST_NEW(c, *ploc, PyLong_FromSsize_t(size - i));
+ ADDOP_BINARY(c, *ploc, Sub);
}
- ADDOP(c, BINARY_SUBSCR);
- RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
+ ADDOP(c, *ploc, BINARY_SUBSCR);
+ RETURN_IF_FALSE(compiler_pattern_subpattern(c, ploc, pattern, pc));
}
// Pop the subject, we're done with it:
pc->on_top--;
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
return 1;
}
// Like compiler_pattern, but turn off checks for irrefutability.
static int
-compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_subpattern(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
int allow_irrefutable = pc->allow_irrefutable;
pc->allow_irrefutable = 1;
- RETURN_IF_FALSE(compiler_pattern(c, p, pc));
+ RETURN_IF_FALSE(compiler_pattern(c, ploc, p, pc));
pc->allow_irrefutable = allow_irrefutable;
return 1;
}
static int
-compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_as(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchAs_kind);
if (p->v.MatchAs.pattern == NULL) {
@@ -6408,20 +6517,20 @@ compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc)
if (!pc->allow_irrefutable) {
if (p->v.MatchAs.name) {
const char *e = "name capture %R makes remaining patterns unreachable";
- return compiler_error(c, e, p->v.MatchAs.name);
+ return compiler_error(c, *ploc, e, p->v.MatchAs.name);
}
const char *e = "wildcard makes remaining patterns unreachable";
- return compiler_error(c, e);
+ return compiler_error(c, *ploc, e);
}
- return pattern_helper_store_name(c, p->v.MatchAs.name, pc);
+ return pattern_helper_store_name(c, *ploc, p->v.MatchAs.name, pc);
}
// Need to make a copy for (possibly) storing later:
pc->on_top++;
- ADDOP_I(c, COPY, 1);
- RETURN_IF_FALSE(compiler_pattern(c, p->v.MatchAs.pattern, pc));
+ ADDOP_I(c, *ploc, COPY, 1);
+ RETURN_IF_FALSE(compiler_pattern(c, ploc, p->v.MatchAs.pattern, pc));
// Success! Store it:
pc->on_top--;
- RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchAs.name, pc));
+ RETURN_IF_FALSE(pattern_helper_store_name(c, *ploc, p->v.MatchAs.name, pc));
return 1;
}
@@ -6429,7 +6538,8 @@ static int
compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchStar_kind);
- RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc));
+ location loc = LOC(p);
+ RETURN_IF_FALSE(pattern_helper_store_name(c, loc, p->v.MatchStar.name, pc));
return 1;
}
@@ -6442,14 +6552,16 @@ validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_
for (Py_ssize_t i = 0; i < nattrs; i++) {
identifier attr = ((identifier)asdl_seq_GET(attrs, i));
SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i)));
- if (forbidden_name(c, attr, Store)) {
+ location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
+ if (forbidden_name(c, loc, attr, Store)) {
return -1;
}
for (Py_ssize_t j = i + 1; j < nattrs; j++) {
identifier other = ((identifier)asdl_seq_GET(attrs, j));
if (!PyUnicode_Compare(attr, other)) {
+ location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, j)));
- compiler_error(c, "attribute name repeated in class pattern: %U", attr);
+ compiler_error(c, loc, "attribute name repeated in class pattern: %U", attr);
return -1;
}
}
@@ -6458,7 +6570,8 @@ validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_
}
static int
-compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_class(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchClass_kind);
asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
@@ -6471,11 +6584,11 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
// AST validator shouldn't let this happen, but if it does,
// just fail, don't crash out of the interpreter
const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
- return compiler_error(c, e, nattrs, nkwd_patterns);
+ return compiler_error(c, *ploc, e, nattrs, nkwd_patterns);
}
if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
const char *e = "too many sub-patterns in class pattern %R";
- return compiler_error(c, e, p->v.MatchClass.cls);
+ return compiler_error(c, *ploc, e, p->v.MatchClass.cls);
}
if (nattrs) {
RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
@@ -6490,15 +6603,15 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
Py_INCREF(name);
PyTuple_SET_ITEM(attr_names, i, name);
}
- ADDOP_LOAD_CONST_NEW(c, attr_names);
- ADDOP_I(c, MATCH_CLASS, nargs);
- ADDOP_I(c, COPY, 1);
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_I(c, IS_OP, 1);
+ ADDOP_LOAD_CONST_NEW(c, *ploc, attr_names);
+ ADDOP_I(c, *ploc, MATCH_CLASS, nargs);
+ ADDOP_I(c, *ploc, COPY, 1);
+ ADDOP_LOAD_CONST(c, *ploc, Py_None);
+ ADDOP_I(c, *ploc, IS_OP, 1);
// TOS is now a tuple of (nargs + nattrs) attributes (or None):
pc->on_top++;
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
- ADDOP_I(c, UNPACK_SEQUENCE, nargs + nattrs);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
+ ADDOP_I(c, *ploc, UNPACK_SEQUENCE, nargs + nattrs);
pc->on_top += nargs + nattrs - 1;
for (i = 0; i < nargs + nattrs; i++) {
pc->on_top--;
@@ -6512,17 +6625,19 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
pattern = asdl_seq_GET(kwd_patterns, i - nargs);
}
if (WILDCARD_CHECK(pattern)) {
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
continue;
}
- RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
+ *ploc = LOC(pattern);
+ RETURN_IF_FALSE(compiler_pattern_subpattern(c, ploc, pattern, pc));
}
// Success! Pop the tuple of attributes:
return 1;
}
static int
-compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_mapping(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchMapping_kind);
asdl_expr_seq *keys = p->v.MatchMapping.keys;
@@ -6533,29 +6648,29 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
// AST validator shouldn't let this happen, but if it does,
// just fail, don't crash out of the interpreter
const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
- return compiler_error(c, e, size, npatterns);
+ return compiler_error(c, *ploc, e, size, npatterns);
}
// We have a double-star target if "rest" is set
PyObject *star_target = p->v.MatchMapping.rest;
// We need to keep the subject on top during the mapping and length checks:
pc->on_top++;
- ADDOP(c, MATCH_MAPPING);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP(c, *ploc, MATCH_MAPPING);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
if (!size && !star_target) {
// If the pattern is just "{}", we're done! Pop the subject:
pc->on_top--;
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
return 1;
}
if (size) {
// If the pattern has any keys in it, perform a length check:
- ADDOP(c, GET_LEN);
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size));
- ADDOP_COMPARE(c, GtE);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP(c, *ploc, GET_LEN);
+ ADDOP_LOAD_CONST_NEW(c, *ploc, PyLong_FromSsize_t(size));
+ ADDOP_COMPARE(c, *ploc, GtE);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
}
if (INT_MAX < size - 1) {
- return compiler_error(c, "too many sub-patterns in mapping pattern");
+ return compiler_error(c, *ploc, "too many sub-patterns in mapping pattern");
}
// Collect all of the keys into a tuple for MATCH_KEYS and
// **rest. They can either be dotted names or literals:
@@ -6573,8 +6688,9 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
if (key == NULL) {
const char *e = "can't use NULL keys in MatchMapping "
"(set 'rest' parameter instead)";
- SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i)));
- compiler_error(c, e);
+ location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
+ SET_LOC(c, (pattern_ty) asdl_seq_GET(patterns, i));
+ compiler_error(c, loc, e);
goto error;
}
@@ -6585,7 +6701,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
}
if (in_seen) {
const char *e = "mapping pattern checks duplicate key (%R)";
- compiler_error(c, e, key->v.Constant.value);
+ compiler_error(c, *ploc, e, key->v.Constant.value);
goto error;
}
if (PySet_Add(seen, key->v.Constant.value)) {
@@ -6595,7 +6711,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
else if (key->kind != Attribute_kind) {
const char *e = "mapping pattern keys may only match literals and attribute lookups";
- compiler_error(c, e);
+ compiler_error(c, *ploc, e);
goto error;
}
if (!compiler_visit_expr(c, key)) {
@@ -6606,22 +6722,22 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
// all keys have been checked; there are no duplicates
Py_DECREF(seen);
- ADDOP_I(c, BUILD_TUPLE, size);
- ADDOP(c, MATCH_KEYS);
+ ADDOP_I(c, *ploc, BUILD_TUPLE, size);
+ ADDOP(c, *ploc, MATCH_KEYS);
// There's now a tuple of keys and a tuple of values on top of the subject:
pc->on_top += 2;
- ADDOP_I(c, COPY, 1);
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP_I(c, IS_OP, 1);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP_I(c, *ploc, COPY, 1);
+ ADDOP_LOAD_CONST(c, *ploc, Py_None);
+ ADDOP_I(c, *ploc, IS_OP, 1);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
// So far so good. Use that tuple of values on the stack to match
// sub-patterns against:
- ADDOP_I(c, UNPACK_SEQUENCE, size);
+ ADDOP_I(c, *ploc, UNPACK_SEQUENCE, size);
pc->on_top += size - 1;
for (Py_ssize_t i = 0; i < size; i++) {
pc->on_top--;
pattern_ty pattern = asdl_seq_GET(patterns, i);
- RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc));
+ RETURN_IF_FALSE(compiler_pattern_subpattern(c, ploc, pattern, pc));
}
// If we get this far, it's a match! Whatever happens next should consume
// the tuple of keys and the subject:
@@ -6633,20 +6749,20 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
// rest = dict(TOS1)
// for key in TOS:
// del rest[key]
- ADDOP_I(c, BUILD_MAP, 0); // [subject, keys, empty]
- ADDOP_I(c, SWAP, 3); // [empty, keys, subject]
- ADDOP_I(c, DICT_UPDATE, 2); // [copy, keys]
- ADDOP_I(c, UNPACK_SEQUENCE, size); // [copy, keys...]
+ ADDOP_I(c, *ploc, BUILD_MAP, 0); // [subject, keys, empty]
+ ADDOP_I(c, *ploc, SWAP, 3); // [empty, keys, subject]
+ ADDOP_I(c, *ploc, DICT_UPDATE, 2); // [copy, keys]
+ ADDOP_I(c, *ploc, UNPACK_SEQUENCE, size); // [copy, keys...]
while (size) {
- ADDOP_I(c, COPY, 1 + size--); // [copy, keys..., copy]
- ADDOP_I(c, SWAP, 2); // [copy, keys..., copy, key]
- ADDOP(c, DELETE_SUBSCR); // [copy, keys...]
+ ADDOP_I(c, *ploc, COPY, 1 + size--); // [copy, keys..., copy]
+ ADDOP_I(c, *ploc, SWAP, 2); // [copy, keys..., copy, key]
+ ADDOP(c, *ploc, DELETE_SUBSCR); // [copy, keys...]
}
- RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc));
+ RETURN_IF_FALSE(pattern_helper_store_name(c, *ploc, star_target, pc));
}
else {
- ADDOP(c, POP_TOP); // Tuple of keys.
- ADDOP(c, POP_TOP); // Subject.
+ ADDOP(c, *ploc, POP_TOP); // Tuple of keys.
+ ADDOP(c, *ploc, POP_TOP); // Subject.
}
return 1;
@@ -6656,7 +6772,8 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc)
}
static int
-compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_or(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchOr_kind);
NEW_JUMP_TARGET_LABEL(c, end);
@@ -6683,8 +6800,9 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
pc->fail_pop = NULL;
pc->fail_pop_size = 0;
pc->on_top = 0;
- if (!cfg_builder_addop_i(CFG_BUILDER(c), COPY, 1, COMPILER_LOC(c)) ||
- !compiler_pattern(c, alt, pc)) {
+ *ploc = LOC(alt);
+ if (!cfg_builder_addop_i(CFG_BUILDER(c), COPY, 1, *ploc) ||
+ !compiler_pattern(c, ploc, alt, pc)) {
goto error;
}
// Success!
@@ -6739,7 +6857,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
// Do the same thing to the stack, using several
// rotations:
while (rotations--) {
- if (!pattern_helper_rotate(c, icontrol + 1)){
+ if (!pattern_helper_rotate(c, *ploc, icontrol + 1)){
goto error;
}
}
@@ -6747,8 +6865,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
}
}
assert(control);
- if (!cfg_builder_addop_j(CFG_BUILDER(c), JUMP, end, COMPILER_LOC(c)) ||
- !emit_and_reset_fail_pop(c, pc))
+ if (!cfg_builder_addop_j(CFG_BUILDER(c), *ploc, JUMP, end) ||
+ !emit_and_reset_fail_pop(c, *ploc, pc))
{
goto error;
}
@@ -6759,7 +6877,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
// Need to NULL this for the PyObject_Free call in the error block.
old_pc.fail_pop = NULL;
// No match. Pop the remaining copy of the subject and fail:
- if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, COMPILER_LOC(c)) || !jump_to_fail_pop(c, pc, JUMP)) {
+ if (!cfg_builder_addop_noarg(CFG_BUILDER(c), POP_TOP, *ploc) ||
+ !jump_to_fail_pop(c, *ploc, pc, JUMP)) {
goto error;
}
@@ -6774,7 +6893,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
for (Py_ssize_t i = 0; i < nstores; i++) {
// Rotate this capture to its proper place on the stack:
- if (!pattern_helper_rotate(c, nrots)) {
+ if (!pattern_helper_rotate(c, *ploc, nrots)) {
goto error;
}
// Update the list of previous stores with this new name, checking for
@@ -6785,7 +6904,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
goto error;
}
if (dupe) {
- compiler_error_duplicate_store(c, name);
+ compiler_error_duplicate_store(c, *ploc, name);
goto error;
}
if (PyList_Append(pc->stores, name)) {
@@ -6796,10 +6915,10 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
Py_DECREF(control);
// NOTE: Returning macros are safe again.
// Pop the copy of the subject:
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
return 1;
diff:
- compiler_error(c, "alternative patterns bind different names");
+ compiler_error(c, *ploc, "alternative patterns bind different names");
error:
PyObject_Free(old_pc.fail_pop);
Py_DECREF(old_pc.stores);
@@ -6809,7 +6928,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
static int
-compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern_sequence(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchSequence_kind);
asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
@@ -6823,7 +6943,7 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc)
if (pattern->kind == MatchStar_kind) {
if (star >= 0) {
const char *e = "multiple starred names in sequence pattern";
- return compiler_error(c, e);
+ return compiler_error(c, *ploc, e);
}
star_wildcard = WILDCARD_STAR_CHECK(pattern);
only_wildcard &= star_wildcard;
@@ -6834,33 +6954,33 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc)
}
// We need to keep the subject on top during the sequence and length checks:
pc->on_top++;
- ADDOP(c, MATCH_SEQUENCE);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP(c, *ploc, MATCH_SEQUENCE);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
if (star < 0) {
// No star: len(subject) == size
- ADDOP(c, GET_LEN);
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size));
- ADDOP_COMPARE(c, Eq);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP(c, *ploc, GET_LEN);
+ ADDOP_LOAD_CONST_NEW(c, *ploc, PyLong_FromSsize_t(size));
+ ADDOP_COMPARE(c, *ploc, Eq);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
}
else if (size > 1) {
// Star: len(subject) >= size - 1
- ADDOP(c, GET_LEN);
- ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - 1));
- ADDOP_COMPARE(c, GtE);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP(c, *ploc, GET_LEN);
+ ADDOP_LOAD_CONST_NEW(c, *ploc, PyLong_FromSsize_t(size - 1));
+ ADDOP_COMPARE(c, *ploc, GtE);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, *ploc, pc, POP_JUMP_IF_FALSE));
}
// Whatever comes next should consume the subject:
pc->on_top--;
if (only_wildcard) {
// Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
- ADDOP(c, POP_TOP);
+ ADDOP(c, *ploc, POP_TOP);
}
else if (star_wildcard) {
- RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc));
+ RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, ploc, patterns, star, pc));
}
else {
- RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc));
+ RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, ploc, patterns, star, pc));
}
return 1;
}
@@ -6869,14 +6989,15 @@ static int
compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchValue_kind);
+ location loc = LOC(p);
expr_ty value = p->v.MatchValue.value;
if (!MATCH_VALUE_EXPR(value)) {
const char *e = "patterns may only match literals and attribute lookups";
- return compiler_error(c, e);
+ return compiler_error(c, loc, e);
}
VISIT(c, expr, value);
- ADDOP_COMPARE(c, Eq);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ ADDOP_COMPARE(c, loc, Eq);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, loc, pc, POP_JUMP_IF_FALSE));
return 1;
}
@@ -6884,38 +7005,41 @@ static int
compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc)
{
assert(p->kind == MatchSingleton_kind);
- ADDOP_LOAD_CONST(c, p->v.MatchSingleton.value);
- ADDOP_COMPARE(c, Is);
- RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE));
+ location loc = LOC(p);
+ ADDOP_LOAD_CONST(c, loc, p->v.MatchSingleton.value);
+ ADDOP_COMPARE(c, loc, Is);
+ RETURN_IF_FALSE(jump_to_fail_pop(c, loc, pc, POP_JUMP_IF_FALSE));
return 1;
}
static int
-compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc)
+compiler_pattern(struct compiler *c, location *ploc,
+ pattern_ty p, pattern_context *pc)
{
SET_LOC(c, p);
+ *ploc = LOC(p);
switch (p->kind) {
case MatchValue_kind:
return compiler_pattern_value(c, p, pc);
case MatchSingleton_kind:
return compiler_pattern_singleton(c, p, pc);
case MatchSequence_kind:
- return compiler_pattern_sequence(c, p, pc);
+ return compiler_pattern_sequence(c, ploc, p, pc);
case MatchMapping_kind:
- return compiler_pattern_mapping(c, p, pc);
+ return compiler_pattern_mapping(c, ploc, p, pc);
case MatchClass_kind:
- return compiler_pattern_class(c, p, pc);
+ return compiler_pattern_class(c, ploc, p, pc);
case MatchStar_kind:
return compiler_pattern_star(c, p, pc);
case MatchAs_kind:
- return compiler_pattern_as(c, p, pc);
+ return compiler_pattern_as(c, ploc, p, pc);
case MatchOr_kind:
- return compiler_pattern_or(c, p, pc);
+ return compiler_pattern_or(c, ploc, p, pc);
}
// AST validator shouldn't let this happen, but if it does,
// just fail, don't crash out of the interpreter
const char *e = "invalid match pattern node in AST (kind=%d)";
- return compiler_error(c, e, p->kind);
+ return compiler_error(c, *ploc, e, p->kind);
}
static int
@@ -6931,8 +7055,9 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
m = asdl_seq_GET(s->v.Match.cases, i);
SET_LOC(c, m->pattern);
// Only copy the subject if we're *not* on the last case:
+ location loc = LOC(m->pattern);
if (i != cases - has_default - 1) {
- ADDOP_I(c, COPY, 1);
+ ADDOP_I(c, loc, COPY, 1);
}
RETURN_IF_FALSE(pc->stores = PyList_New(0));
// Irrefutable cases must be either guarded, last, or both:
@@ -6941,7 +7066,7 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
pc->fail_pop_size = 0;
pc->on_top = 0;
// NOTE: Can't use returning macros here (they'll leak pc->stores)!
- if (!compiler_pattern(c, m->pattern, pc)) {
+ if (!compiler_pattern(c, &loc, m->pattern, pc)) {
Py_DECREF(pc->stores);
return 0;
}
@@ -6950,7 +7075,7 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
for (Py_ssize_t n = 0; n < nstores; n++) {
PyObject *name = PyList_GET_ITEM(pc->stores, n);
- if (!compiler_nameop(c, name, Store)) {
+ if (!compiler_nameop(c, loc, name, Store)) {
Py_DECREF(pc->stores);
return 0;
}
@@ -6959,35 +7084,36 @@ compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
// NOTE: Returning macros are safe again.
if (m->guard) {
RETURN_IF_FALSE(ensure_fail_pop(c, pc, 0));
- RETURN_IF_FALSE(compiler_jump_if(c, m->guard, pc->fail_pop[0], 0));
+ RETURN_IF_FALSE(compiler_jump_if(c, &loc, m->guard, pc->fail_pop[0], 0));
}
// Success! Pop the subject off, we're done with it:
if (i != cases - has_default - 1) {
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
}
VISIT_SEQ(c, stmt, m->body);
- ADDOP_JUMP(c, JUMP, end);
+ ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
// If the pattern fails to match, we want the line number of the
// cleanup to be associated with the failed pattern, not the last line
// of the body
SET_LOC(c, m->pattern);
- RETURN_IF_FALSE(emit_and_reset_fail_pop(c, pc));
+ RETURN_IF_FALSE(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
}
if (has_default) {
// A trailing "case _" is common, and lets us save a bit of redundant
// pushing and popping in the loop above:
m = asdl_seq_GET(s->v.Match.cases, cases - 1);
SET_LOC(c, m->pattern);
+ location loc = LOC(m->pattern);
if (cases == 1) {
// No matches. Done with the subject:
- ADDOP(c, POP_TOP);
+ ADDOP(c, loc, POP_TOP);
}
else {
// Show line coverage for default case (it doesn't create bytecode)
- ADDOP(c, NOP);
+ ADDOP(c, loc, NOP);
}
if (m->guard) {
- RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0));
+ RETURN_IF_FALSE(compiler_jump_if(c, &loc, m->guard, end, 0));
}
VISIT_SEQ(c, stmt, m->body);
}
@@ -8585,9 +8711,10 @@ assemble(struct compiler *c, int addNone)
/* Make sure every block that falls off the end returns None. */
if (!basicblock_returns(CFG_BUILDER(c)->g_curblock)) {
UNSET_LOC(c);
- if (addNone)
- ADDOP_LOAD_CONST(c, Py_None);
- ADDOP(c, RETURN_VALUE);
+ if (addNone) {
+ ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+ }
+ ADDOP(c, NO_LOCATION, RETURN_VALUE);
}
assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
@@ -9437,7 +9564,7 @@ propagate_line_numbers(basicblock *entryblock) {
continue;
}
- struct location prev_location = NO_LOCATION;
+ location prev_location = NO_LOCATION;
for (int i = 0; i < b->b_iused; i++) {
if (b->b_instr[i].i_loc.lineno < 0) {
b->b_instr[i].i_loc = prev_location;
@@ -9695,7 +9822,7 @@ instructions_to_cfg(PyObject *instructions, cfg_builder *g)
if (PyErr_Occurred()) {
return -1;
}
- struct location loc;
+ location loc;
loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
if (PyErr_Occurred()) {
return -1;
@@ -9743,7 +9870,7 @@ cfg_to_instructions(cfg_builder *g)
Py_DECREF(lbl);
for (int i = 0; i < b->b_iused; i++) {
struct instr *instr = &b->b_instr[i];
- struct location loc = instr->i_loc;
+ location loc = instr->i_loc;
int arg = HAS_TARGET(instr->i_opcode) ? instr->i_target->b_label : instr->i_oparg;
PyObject *inst_tuple = Py_BuildValue(
"(iiiiii)", instr->i_opcode, arg,
More information about the Python-checkins
mailing list