diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2020-03-17 16:07:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-17 16:07:30 (GMT) |
commit | 61cb3d02b83e746e59bb1351a0865e3b8714b2d6 (patch) | |
tree | 63e06427fc956988ca3f4c45b2aecb6ad189eff7 /Python/compile.c | |
parent | eb886db1e99a15f15a2342aa496197a5f88fa9c8 (diff) | |
download | cpython-61cb3d02b83e746e59bb1351a0865e3b8714b2d6.zip cpython-61cb3d02b83e746e59bb1351a0865e3b8714b2d6.tar.gz cpython-61cb3d02b83e746e59bb1351a0865e3b8714b2d6.tar.bz2 |
bpo-39987: Simplify setting lineno in the compiler. (GH-19037)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 68 |
1 files changed, 18 insertions, 50 deletions
diff --git a/Python/compile.c b/Python/compile.c index dd14023..d98caba 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -142,8 +142,6 @@ struct compiler_unit { int u_firstlineno; /* the first lineno of the block */ int u_lineno; /* the lineno for the current stmt */ int u_col_offset; /* the offset of the current stmt */ - int u_lineno_set; /* boolean to indicate whether instr - has been generated with current lineno */ }; /* This struct captures the global state of a compilation. @@ -614,7 +612,6 @@ compiler_enter_scope(struct compiler *c, identifier name, u->u_firstlineno = lineno; u->u_lineno = 0; u->u_col_offset = 0; - u->u_lineno_set = 0; u->u_consts = PyDict_New(); if (!u->u_consts) { compiler_unit_free(u); @@ -849,28 +846,18 @@ compiler_next_instr(basicblock *b) return b->b_iused++; } -/* Set the i_lineno member of the instruction at offset off if the - line number for the current expression/statement has not - already been set. If it has been set, the call has no effect. +/* Set the line number and column offset for the following instructions. The line number is reset in the following cases: - when entering a new scope - on each statement - - on each expression that start a new line + - on each expression and sub-expression - before the "except" and "finally" clauses - - before the "for" and "while" expressions */ -static void -compiler_set_lineno(struct compiler *c, int off) -{ - basicblock *b; - if (c->u->u_lineno_set) - return; - c->u->u_lineno_set = 1; - b = c->u->u_curblock; - b->b_instr[off].i_lineno = c->u->u_lineno; -} +#define SET_LOC(c, x) \ + (c)->u->u_lineno = (x)->lineno; \ + (c)->u->u_col_offset = (x)->col_offset; /* Return the stack effect of opcode with argument oparg. @@ -1172,7 +1159,7 @@ compiler_addop(struct compiler *c, int opcode) i->i_oparg = 0; if (opcode == RETURN_VALUE) b->b_return = 1; - compiler_set_lineno(c, off); + i->i_lineno = c->u->u_lineno; return 1; } @@ -1407,7 +1394,7 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) i = &c->u->u_curblock->b_instr[off]; i->i_opcode = opcode; i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - compiler_set_lineno(c, off); + i->i_lineno = c->u->u_lineno; return 1; } @@ -1433,7 +1420,7 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) i->i_jabs = 1; else i->i_jrel = 1; - compiler_set_lineno(c, off); + i->i_lineno = c->u->u_lineno; return 1; } @@ -1706,7 +1693,6 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, int saved_lineno = c->u->u_lineno; VISIT_SEQ(c, stmt, info->fb_datum); c->u->u_lineno = saved_lineno; - c->u->u_lineno_set = 0; if (preserve_tos) { compiler_pop_fblock(c, POP_VALUE, NULL); } @@ -1805,10 +1791,9 @@ compiler_body(struct compiler *c, asdl_seq *stmts) This way line number for SETUP_ANNOTATIONS will always coincide with the line number of first "real" statement in module. If body is empty, then lineno will be set later in assemble. */ - if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && - !c->u->u_lineno && asdl_seq_LEN(stmts)) { + if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) { st = (stmt_ty)asdl_seq_GET(stmts, 0); - c->u->u_lineno = st->lineno; + SET_LOC(c, st); } /* Every annotated class and module should have __annotations__. */ if (find_ann(stmts)) { @@ -3043,9 +3028,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) s->v.Try.handlers, i); if (!handler->v.ExceptHandler.type && i < n-1) return compiler_error(c, "default 'except:' must be last"); - c->u->u_lineno_set = 0; - c->u->u_lineno = handler->lineno; - c->u->u_col_offset = handler->col_offset; + SET_LOC(c, handler); except = compiler_new_block(c); if (except == NULL) return 0; @@ -3345,9 +3328,7 @@ 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. */ - c->u->u_lineno = s->lineno; - c->u->u_col_offset = s->col_offset; - c->u->u_lineno_set = 0; + SET_LOC(c, s); switch (s->kind) { case FunctionDef_kind: @@ -5095,24 +5076,11 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) static int compiler_visit_expr(struct compiler *c, expr_ty e) { - /* If expr e has a different line number than the last expr/stmt, - set a new line number for the next instruction. - */ int old_lineno = c->u->u_lineno; int old_col_offset = c->u->u_col_offset; - if (e->lineno != c->u->u_lineno) { - c->u->u_lineno = e->lineno; - c->u->u_lineno_set = 0; - } - /* Updating the column offset is always harmless. */ - c->u->u_col_offset = e->col_offset; - + SET_LOC(c, e); int res = compiler_visit_expr1(c, e); - - if (old_lineno != c->u->u_lineno) { - c->u->u_lineno = old_lineno; - c->u->u_lineno_set = 0; - } + c->u->u_lineno = old_lineno; c->u->u_col_offset = old_col_offset; return res; } @@ -5590,14 +5558,14 @@ assemble_lnotab(struct assembler *a, struct instr *i) Py_ssize_t len; unsigned char *lnotab; - d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT); d_lineno = i->i_lineno - a->a_lineno; + if (d_lineno == 0) { + return 1; + } + d_bytecode = (a->a_offset - a->a_lineno_off) * sizeof(_Py_CODEUNIT); assert(d_bytecode >= 0); - if(d_bytecode == 0 && d_lineno == 0) - return 1; - if (d_bytecode > 255) { int j, nbytes, ncodes = d_bytecode / 255; nbytes = a->a_lnotab_off + 2 * ncodes; |