diff options
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 271 |
1 files changed, 208 insertions, 63 deletions
diff --git a/Python/compile.c b/Python/compile.c index 99e500f..0bce6ce 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -40,6 +40,7 @@ #define DEFAULT_BLOCKS 8 #define DEFAULT_CODE_SIZE 128 #define DEFAULT_LNOTAB_SIZE 16 +#define DEFAULT_CNOTAB_SIZE 0 #define COMP_GENEXP 0 #define COMP_LISTCOMP 1 @@ -90,6 +91,9 @@ struct instr { /* target block when exception is raised, should not be set by front-end. */ struct basicblock_ *i_except; int i_lineno; + int i_end_lineno; + int i_col_offset; + int i_end_col_offset; }; typedef struct excepthandler { @@ -963,6 +967,19 @@ compiler_next_instr(basicblock *b) (c)->u->u_end_lineno = (x)->end_lineno; \ (c)->u->u_end_col_offset = (x)->end_col_offset; +// Artificial instructions +#define UNSET_LOC(c) \ + (c)->u->u_lineno = -1; \ + (c)->u->u_col_offset = -1; \ + (c)->u->u_end_lineno = -1; \ + (c)->u->u_end_col_offset = -1; + +#define COPY_INSTR_LOC(old, new) \ + (new).i_lineno = (old).i_lineno; \ + (new).i_col_offset = (old).i_col_offset; \ + (new).i_end_lineno = (old).i_end_lineno; \ + (new).i_end_col_offset = (old).i_end_col_offset; + /* Return the stack effect of opcode with argument oparg. Some opcodes have different stack effect when jump to the target and @@ -1266,7 +1283,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) */ static int -compiler_addop_line(struct compiler *c, int opcode, int line) +compiler_addop_line(struct compiler *c, int opcode, int line, + int end_line, int col_offset, int end_col_offset) { basicblock *b; struct instr *i; @@ -1282,19 +1300,23 @@ compiler_addop_line(struct compiler *c, int opcode, int line) if (opcode == RETURN_VALUE) b->b_return = 1; i->i_lineno = line; + i->i_end_lineno = end_line; + i->i_col_offset = col_offset; + i->i_end_col_offset = end_col_offset; return 1; } static int compiler_addop(struct compiler *c, int opcode) { - return compiler_addop_line(c, opcode, c->u->u_lineno); + return compiler_addop_line(c, opcode, c->u->u_lineno, c->u->u_end_lineno, + c->u->u_col_offset, c->u->u_end_col_offset); } static int compiler_addop_noline(struct compiler *c, int opcode) { - return compiler_addop_line(c, opcode, -1); + return compiler_addop_line(c, opcode, -1, 0, 0, 0); } @@ -1488,7 +1510,9 @@ compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, */ static int -compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, int lineno) +compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, + int lineno, int end_lineno, + int col_offset, int end_col_offset) { struct instr *i; int off; @@ -1510,22 +1534,30 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, int line i->i_opcode = opcode; i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); i->i_lineno = lineno; + i->i_end_lineno = end_lineno; + i->i_col_offset = col_offset; + i->i_end_col_offset = end_col_offset; return 1; } static int compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) { - return compiler_addop_i_line(c, opcode, oparg, c->u->u_lineno); + return compiler_addop_i_line(c, opcode, oparg, + c->u->u_lineno, c->u->u_end_lineno, + c->u->u_col_offset, c->u->u_end_col_offset); } static int compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg) { - return compiler_addop_i_line(c, opcode, oparg, -1); + return compiler_addop_i_line(c, opcode, oparg, -1, 0, 0, 0); } -static int add_jump_to_block(basicblock *b, int opcode, int lineno, basicblock *target) +static int add_jump_to_block(basicblock *b, int opcode, + int lineno, int end_lineno, + int col_offset, int end_col_offset, + basicblock *target) { assert(HAS_ARG(opcode)); assert(b != NULL); @@ -1539,19 +1571,24 @@ static int add_jump_to_block(basicblock *b, int opcode, int lineno, basicblock * i->i_opcode = opcode; i->i_target = target; i->i_lineno = lineno; + i->i_end_lineno = end_lineno; + i->i_col_offset = col_offset; + i->i_end_col_offset = end_col_offset; return 1; } static int compiler_addop_j(struct compiler *c, int opcode, basicblock *b) { - return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, b); + return add_jump_to_block(c->u->u_curblock, opcode, c->u->u_lineno, + c->u->u_end_lineno, c->u->u_col_offset, + c->u->u_end_col_offset, b); } static int compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) { - return add_jump_to_block(c->u->u_curblock, opcode, -1, b); + return add_jump_to_block(c->u->u_curblock, opcode, -1, 0, 0, 0, b); } /* NEXT_BLOCK() creates an implicit jump from the current block @@ -1834,7 +1871,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, /* The finally block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); return 1; case FINALLY_END: @@ -1870,7 +1907,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, /* The exit block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); return 1; case HANDLER_CLEANUP: @@ -2522,7 +2559,7 @@ compiler_class(struct compiler *c, stmt_ty s) return 0; } /* The following code is artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); /* Return __classcell__ if it is referenced, otherwise return None */ if (c->u->u_ste->ste_needs_class_closure) { /* Store __classcell__ into class namespace & return it */ @@ -2913,7 +2950,7 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP_JUMP(c, JUMP_ABSOLUTE, start); compiler_use_next_block(c, cleanup); @@ -2966,7 +3003,7 @@ compiler_async_for(struct compiler *c, stmt_ty s) /* Except block for __anext__ */ compiler_use_next_block(c, except); - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP(c, END_ASYNC_FOR); /* `else` block */ @@ -3153,7 +3190,7 @@ compiler_try_finally(struct compiler *c, stmt_ty s) /* `finally` block */ compiler_use_next_block(c, end); - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) @@ -3221,7 +3258,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); ADDOP(c, PUSH_EXC_INFO); /* Runtime will push a block here, so we need to account for that */ @@ -3280,7 +3317,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); /* name = None; del name; # Mark as artificial */ - c->u->u_lineno = -1; + 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); @@ -3290,7 +3327,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) compiler_use_next_block(c, cleanup_end); /* name = None; del name; # Mark as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP_LOAD_CONST(c, Py_None); compiler_nameop(c, handler->v.ExceptHandler.name, Store); @@ -3313,7 +3350,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); /* name = None; del name; # Mark as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP(c, POP_BLOCK); ADDOP(c, POP_EXCEPT); ADDOP_JUMP(c, JUMP_FORWARD, end); @@ -3321,7 +3358,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) compiler_use_next_block(c, except); } /* Mark as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); ADDOP_I(c, RERAISE, 0); compiler_use_next_block(c, cleanup); @@ -3542,7 +3579,7 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value) VISIT(c, expr, value); /* Mark POP_TOP as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP(c, POP_TOP); return 1; } @@ -4896,7 +4933,7 @@ compiler_async_comprehension_generator(struct compiler *c, compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); compiler_use_next_block(c, except); - //c->u->u_lineno = -1; + //UNSET_LOC(c); ADDOP(c, END_ASYNC_FOR); @@ -5076,7 +5113,7 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k) static int compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { - c->u->u_lineno = -1; + UNSET_LOC(c); basicblock *exit; exit = compiler_new_block(c); if (exit == NULL) @@ -5271,7 +5308,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* Mark all following code as artificial */ - c->u->u_lineno = -1; + UNSET_LOC(c); ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, WITH, block); @@ -6546,12 +6583,18 @@ struct assembler { int a_offset; /* offset into bytecode */ int a_nblocks; /* number of reachable blocks */ PyObject *a_lnotab; /* bytes containing lnotab */ + PyObject* a_enotab; /* bytes containing enotab */ + PyObject* a_cnotab; /* bytes containing cnotab */ int a_lnotab_off; /* offset into lnotab */ + int a_enotab_off; /* offset into enotab */ PyObject *a_except_table; /* bytes containing exception table */ int a_except_table_off; /* offset into exception table */ int a_prevlineno; /* lineno of last emitted line in line table */ + int a_prev_end_lineno; /* end_lineno of last emitted line in line table */ int a_lineno; /* lineno of last emitted instruction */ + int a_end_lineno; /* end_lineno of last emitted instruction */ int a_lineno_start; /* bytecode start offset of current lineno */ + int a_end_lineno_start; /* bytecode start offset of current end_lineno */ basicblock *a_entry; }; @@ -6649,7 +6692,10 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) { memset(a, 0, sizeof(struct assembler)); a->a_prevlineno = a->a_lineno = firstlineno; + a->a_prev_end_lineno = a->a_end_lineno = firstlineno; a->a_lnotab = NULL; + a->a_enotab = NULL; + a->a_cnotab = NULL; a->a_except_table = NULL; a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); if (a->a_bytecode == NULL) { @@ -6659,6 +6705,14 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) if (a->a_lnotab == NULL) { goto error; } + a->a_enotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); + if (a->a_enotab == NULL) { + goto error; + } + a->a_cnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); + if (a->a_cnotab == NULL) { + goto error; + } a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (a->a_except_table == NULL) { goto error; @@ -6671,6 +6725,8 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) error: Py_XDECREF(a->a_bytecode); Py_XDECREF(a->a_lnotab); + Py_XDECREF(a->a_enotab); + Py_XDECREF(a->a_cnotab); Py_XDECREF(a->a_except_table); return 0; } @@ -6680,6 +6736,8 @@ assemble_free(struct assembler *a) { Py_XDECREF(a->a_bytecode); Py_XDECREF(a->a_lnotab); + Py_XDECREF(a->a_enotab); + Py_XDECREF(a->a_cnotab); Py_XDECREF(a->a_except_table); } @@ -6695,18 +6753,21 @@ blocksize(basicblock *b) } static int -assemble_emit_linetable_pair(struct assembler *a, int bdelta, int ldelta) +assemble_emit_table_pair(struct assembler* a, PyObject** table, int* offset, + int left, int right) { - Py_ssize_t len = PyBytes_GET_SIZE(a->a_lnotab); - if (a->a_lnotab_off + 2 >= len) { - if (_PyBytes_Resize(&a->a_lnotab, len * 2) < 0) + Py_ssize_t len = PyBytes_GET_SIZE(*table); + if (*offset + 2 >= len) { + if (_PyBytes_Resize(table, len * 2) < 0) return 0; } - unsigned char *lnotab = (unsigned char *) PyBytes_AS_STRING(a->a_lnotab); - lnotab += a->a_lnotab_off; - a->a_lnotab_off += 2; - *lnotab++ = bdelta; - *lnotab++ = ldelta; + unsigned char* table_entry = (unsigned char*)PyBytes_AS_STRING(*table); + + table_entry += *offset; + *offset += 2; + + *table_entry++ = left; + *table_entry++ = right; return 1; } @@ -6961,27 +7022,28 @@ assemble_exception_table(struct assembler *a) * Objects/lnotab_notes.txt for the description of the line number table. */ static int -assemble_line_range(struct assembler *a) +assemble_line_range(struct assembler* a, int current, PyObject** table, + int* prev, int* start, int* offset) { int ldelta, bdelta; - bdelta = (a->a_offset - a->a_lineno_start) * 2; + bdelta = (a->a_offset - *start) * 2; if (bdelta == 0) { return 1; } - if (a->a_lineno < 0) { + if (current < 0) { ldelta = -128; } else { - ldelta = a->a_lineno - a->a_prevlineno; - a->a_prevlineno = a->a_lineno; + ldelta = current - *prev; + *prev = current; while (ldelta > 127) { - if (!assemble_emit_linetable_pair(a, 0, 127)) { + if (!assemble_emit_table_pair(a, table, offset, 0, 127)) { return 0; } ldelta -= 127; } while (ldelta < -127) { - if (!assemble_emit_linetable_pair(a, 0, -127)) { + if (!assemble_emit_table_pair(a, table, offset, 0, -127)) { return 0; } ldelta += 127; @@ -6989,32 +7051,82 @@ assemble_line_range(struct assembler *a) } assert(-128 <= ldelta && ldelta < 128); while (bdelta > 254) { - if (!assemble_emit_linetable_pair(a, 254, ldelta)) { + if (!assemble_emit_table_pair(a, table, offset, 254, ldelta)) { return 0; } - ldelta = a->a_lineno < 0 ? -128 : 0; + ldelta = current < 0 ? -128 : 0; bdelta -= 254; } - if (!assemble_emit_linetable_pair(a, bdelta, ldelta)) { + if (!assemble_emit_table_pair(a, table, offset, bdelta, ldelta)) { return 0; } - a->a_lineno_start = a->a_offset; + *start = a->a_offset; return 1; } static int -assemble_lnotab(struct assembler *a, struct instr *i) +assemble_start_line_range(struct assembler* a) { + return assemble_line_range(a, a->a_lineno, &a->a_lnotab, + &a->a_prevlineno, &a->a_lineno_start, &a->a_lnotab_off); +} + +static int +assemble_end_line_range(struct assembler* a) { + return assemble_line_range(a, a->a_end_lineno, &a->a_enotab, + &a->a_prev_end_lineno, &a->a_end_lineno_start, &a->a_enotab_off); +} + +static int +assemble_lnotab(struct assembler* a, struct instr* i) { if (i->i_lineno == a->a_lineno) { return 1; } - if (!assemble_line_range(a)) { + if (!assemble_start_line_range(a)) { return 0; } a->a_lineno = i->i_lineno; return 1; } +static int +assemble_enotab(struct assembler* a, struct instr* i) +{ + if (i->i_end_lineno == a->a_end_lineno) { + return 1; + } + if (!assemble_end_line_range(a)) { + return 0; + } + a->a_end_lineno = i->i_end_lineno; + return 1; +} + +static int +assemble_cnotab(struct assembler* a, struct instr* i, int instr_size) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_cnotab); + // TODO: Allocate more memory than just what we immediately need + // like a_lnotab does. + if (_PyBytes_Resize(&a->a_cnotab, len + (instr_size * 2)) < 0) { + return 0; + } + + unsigned char* cnotab = (unsigned char*)PyBytes_AS_STRING(a->a_cnotab); + cnotab += len; + + for (int j = 0; j < instr_size; j++) { + if (i->i_col_offset > 255 || i->i_end_col_offset > 255) { + *cnotab++ = 0; + *cnotab++ = 0; + continue; + } + *cnotab++ = i->i_col_offset + 1; + *cnotab++ = i->i_end_col_offset + 1; + } + return 1; +} + /* assemble_emit() Extend the bytecode with a new instruction. @@ -7030,8 +7142,15 @@ assemble_emit(struct assembler *a, struct instr *i) arg = i->i_oparg; size = instrsize(arg); - if (i->i_lineno && !assemble_lnotab(a, i)) + if (i->i_lineno && !assemble_lnotab(a, i)) { return 0; + } + if (!assemble_enotab(a, i)) { + return 0; + } + if (!assemble_cnotab(a, i, size)) { + return 0; + } if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { if (len > PY_SSIZE_T_MAX / 2) return 0; @@ -7315,6 +7434,8 @@ makecode(struct compiler *c, struct assembler *a, PyObject *constslist, .code = a->a_bytecode, .firstlineno = c->u->u_firstlineno, .linetable = a->a_lnotab, + .endlinetable = a->a_enotab, + .columntable = a->a_cnotab, .consts = consts, .names = names, @@ -7478,6 +7599,9 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock, // This will get fixed in offset_derefs(). .i_oparg = oldindex, .i_lineno = -1, + .i_col_offset = -1, + .i_end_lineno = -1, + .i_end_col_offset = -1, .i_target = NULL, }; if (insert_instruction(entryblock, ncellsused, &make_cell) < 0) { @@ -7505,6 +7629,9 @@ insert_prefix_instructions(struct compiler *c, basicblock *entryblock, .i_opcode = GEN_START, .i_oparg = kind, .i_lineno = -1, + .i_col_offset = -1, + .i_end_lineno = -1, + .i_end_col_offset = -1, .i_target = NULL, }; if (insert_instruction(entryblock, 0, &gen_start) < 0) { @@ -7602,7 +7729,7 @@ assemble(struct compiler *c, int addNone) block ends with a jump or return b_next shouldn't set. */ if (!c->u->u_curblock->b_return) { - c->u->u_lineno = -1; + UNSET_LOC(c); if (addNone) ADDOP_LOAD_CONST(c, Py_None); ADDOP(c, RETURN_VALUE); @@ -7707,19 +7834,25 @@ assemble(struct compiler *c, int addNone) if (!assemble_exception_table(&a)) { goto error; } - if (!assemble_line_range(&a)) { + if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) { goto error; } - + if (!assemble_start_line_range(&a)) { + return 0; + } if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0) { goto error; } - - if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) { + if (!merge_const_one(c, &a.a_lnotab)) { goto error; } - - if (!merge_const_one(c, &a.a_lnotab)) { + if (!assemble_end_line_range(&a)) { + return 0; + } + if (_PyBytes_Resize(&a.a_enotab, a.a_enotab_off) < 0) { + goto error; + } + if (!merge_const_one(c, &a.a_enotab)) { goto error; } if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { @@ -7848,7 +7981,11 @@ eliminate_jump_to_jump(basicblock *bb, int opcode) { return 0; } int lineno = target->i_lineno; - if (add_jump_to_block(bb, opcode, lineno, target->i_target) == 0) { + int end_lineno = target->i_end_lineno; + int col_offset = target->i_col_offset; + int end_col_offset = target->i_end_col_offset; + if (add_jump_to_block(bb, opcode, lineno, end_lineno, col_offset, + end_col_offset, target->i_target) == 0) { return -1; } assert (bb->b_iused >= 2); @@ -8127,7 +8264,7 @@ clean_basic_block(basicblock *bb) { if (src < bb->b_iused - 1) { int next_lineno = bb->b_instr[src+1].i_lineno; if (next_lineno < 0 || next_lineno == lineno) { - bb->b_instr[src+1].i_lineno = lineno; + COPY_INSTR_LOC(bb->b_instr[src], bb->b_instr[src+1]); continue; } } @@ -8262,19 +8399,27 @@ propogate_line_numbers(struct assembler *a) { if (b->b_iused == 0) { continue; } - int prev_lineno = -1; + + // Not a real instruction, only to store positions + // from previous instructions and propagate them. + struct instr prev_instr = { + .i_lineno = -1, + .i_col_offset = -1, + .i_end_lineno = -1, + .i_end_col_offset = -1, + }; for (int i = 0; i < b->b_iused; i++) { if (b->b_instr[i].i_lineno < 0) { - b->b_instr[i].i_lineno = prev_lineno; + COPY_INSTR_LOC(prev_instr, b->b_instr[i]); } else { - prev_lineno = b->b_instr[i].i_lineno; + COPY_INSTR_LOC(b->b_instr[i], prev_instr); } } if (!b->b_nofallthrough && b->b_next->b_predecessors == 1) { assert(b->b_next->b_iused); if (b->b_next->b_instr[0].i_lineno < 0) { - b->b_next->b_instr[0].i_lineno = prev_lineno; + COPY_INSTR_LOC(prev_instr, b->b_next->b_instr[0]); } } if (is_jump(&b->b_instr[b->b_iused-1])) { @@ -8288,7 +8433,7 @@ propogate_line_numbers(struct assembler *a) { basicblock *target = b->b_instr[b->b_iused-1].i_target; if (target->b_predecessors == 1) { if (target->b_instr[0].i_lineno < 0) { - target->b_instr[0].i_lineno = prev_lineno; + COPY_INSTR_LOC(prev_instr, target->b_instr[0]); } } } @@ -8391,7 +8536,7 @@ ensure_exits_have_lineno(struct compiler *c) if (new_target == NULL) { return -1; } - new_target->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; + COPY_INSTR_LOC(b->b_instr[b->b_iused-1], new_target->b_instr[0]); b->b_instr[b->b_iused-1].i_target = new_target; } } @@ -8412,7 +8557,7 @@ ensure_exits_have_lineno(struct compiler *c) if (!b->b_nofallthrough && b->b_next && b->b_iused > 0) { if (is_exit_without_lineno(b->b_next)) { assert(b->b_next->b_iused > 0); - b->b_next->b_instr[0].i_lineno = b->b_instr[b->b_iused-1].i_lineno; + COPY_INSTR_LOC(b->b_instr[b->b_iused-1], b->b_next->b_instr[0]); } } } |