mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +00:00
bpo-42246: Partial implementation of PEP 626. (GH-23113)
* Implement new line number table format, as defined in PEP 626.
This commit is contained in:
parent
cda99b4022
commit
877df851c3
19 changed files with 5364 additions and 5000 deletions
|
@ -66,8 +66,8 @@ static void call_exc_trace(Py_tracefunc, PyObject *,
|
|||
PyThreadState *, PyFrameObject *);
|
||||
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
|
||||
PyThreadState *, PyFrameObject *,
|
||||
int *, int *, int *);
|
||||
static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *);
|
||||
PyCodeAddressRange *, int *);
|
||||
static void maybe_dtrace_line(PyFrameObject *, PyCodeAddressRange *, int *);
|
||||
static void dtrace_function_entry(PyFrameObject *);
|
||||
static void dtrace_function_return(PyFrameObject *);
|
||||
|
||||
|
@ -976,7 +976,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
|||
is true when the line being executed has changed. The
|
||||
initial values are such as to make this false the first
|
||||
time it is tested. */
|
||||
int instr_ub = -1, instr_lb = 0, instr_prev = -1;
|
||||
|
||||
const _Py_CODEUNIT *first_instr;
|
||||
PyObject *names;
|
||||
|
@ -1390,6 +1389,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
|||
dtrace_function_entry(f);
|
||||
|
||||
co = f->f_code;
|
||||
PyCodeAddressRange bounds;
|
||||
_PyCode_InitAddressRange(co, &bounds);
|
||||
int instr_prev = -1;
|
||||
|
||||
names = co->co_names;
|
||||
consts = co->co_consts;
|
||||
fastlocals = f->f_localsplus;
|
||||
|
@ -1514,7 +1517,7 @@ main_loop:
|
|||
f->f_lasti = INSTR_OFFSET();
|
||||
|
||||
if (PyDTrace_LINE_ENABLED())
|
||||
maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev);
|
||||
maybe_dtrace_line(f, &bounds, &instr_prev);
|
||||
|
||||
/* line-by-line tracing support */
|
||||
|
||||
|
@ -1528,7 +1531,7 @@ main_loop:
|
|||
err = maybe_call_line_trace(tstate->c_tracefunc,
|
||||
tstate->c_traceobj,
|
||||
tstate, f,
|
||||
&instr_lb, &instr_ub, &instr_prev);
|
||||
&bounds, &instr_prev);
|
||||
/* Reload possibly changed frame fields */
|
||||
JUMPTO(f->f_lasti);
|
||||
stack_pointer = f->f_valuestack+f->f_stackdepth;
|
||||
|
@ -4039,14 +4042,7 @@ exception_unwind:
|
|||
PUSH(exc);
|
||||
JUMPTO(handler);
|
||||
if (_Py_TracingPossible(ceval2)) {
|
||||
int needs_new_execution_window = (f->f_lasti < instr_lb || f->f_lasti >= instr_ub);
|
||||
int needs_line_update = (f->f_lasti == instr_lb || f->f_lasti < instr_prev);
|
||||
/* Make sure that we trace line after exception if we are in a new execution
|
||||
* window or we don't need a line update and we are not in the first instruction
|
||||
* of the line. */
|
||||
if (needs_new_execution_window || (!needs_line_update && instr_lb > 0)) {
|
||||
instr_prev = INT_MAX;
|
||||
}
|
||||
instr_prev = INT_MAX;
|
||||
}
|
||||
/* Resume normal execution */
|
||||
f->f_state = FRAME_EXECUTING;
|
||||
|
@ -4960,7 +4956,7 @@ _PyEval_CallTracing(PyObject *func, PyObject *args)
|
|||
static int
|
||||
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
||||
PyThreadState *tstate, PyFrameObject *frame,
|
||||
int *instr_lb, int *instr_ub, int *instr_prev)
|
||||
PyCodeAddressRange *bounds, int *instr_prev)
|
||||
{
|
||||
int result = 0;
|
||||
int line = frame->f_lineno;
|
||||
|
@ -4968,21 +4964,17 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
|
|||
/* If the last instruction executed isn't in the current
|
||||
instruction window, reset the window.
|
||||
*/
|
||||
if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
|
||||
PyAddrPair bounds;
|
||||
line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
|
||||
&bounds);
|
||||
*instr_lb = bounds.ap_lower;
|
||||
*instr_ub = bounds.ap_upper;
|
||||
}
|
||||
line = _PyCode_CheckLineNumber(frame->f_lasti, bounds);
|
||||
/* If the last instruction falls at the start of a line or if it
|
||||
represents a jump backwards, update the frame's line number and
|
||||
then call the trace function if we're tracing source lines.
|
||||
*/
|
||||
if ((frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev)) {
|
||||
frame->f_lineno = line;
|
||||
if (frame->f_trace_lines) {
|
||||
result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None);
|
||||
if ((line != frame->f_lineno || frame->f_lasti < *instr_prev)) {
|
||||
if (line != -1) {
|
||||
frame->f_lineno = line;
|
||||
if (frame->f_trace_lines) {
|
||||
result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Always emit an opcode event if we're tracing all opcodes. */
|
||||
|
@ -5907,33 +5899,28 @@ dtrace_function_return(PyFrameObject *f)
|
|||
/* DTrace equivalent of maybe_call_line_trace. */
|
||||
static void
|
||||
maybe_dtrace_line(PyFrameObject *frame,
|
||||
int *instr_lb, int *instr_ub, int *instr_prev)
|
||||
PyCodeAddressRange *bounds, int *instr_prev)
|
||||
{
|
||||
int line = frame->f_lineno;
|
||||
const char *co_filename, *co_name;
|
||||
|
||||
/* If the last instruction executed isn't in the current
|
||||
instruction window, reset the window.
|
||||
*/
|
||||
if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
|
||||
PyAddrPair bounds;
|
||||
line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
|
||||
&bounds);
|
||||
*instr_lb = bounds.ap_lower;
|
||||
*instr_ub = bounds.ap_upper;
|
||||
}
|
||||
int line = _PyCode_CheckLineNumber(frame->f_lasti, bounds);
|
||||
/* If the last instruction falls at the start of a line or if
|
||||
it represents a jump backwards, update the frame's line
|
||||
number and call the trace function. */
|
||||
if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
|
||||
frame->f_lineno = line;
|
||||
co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||||
if (!co_filename)
|
||||
co_filename = "?";
|
||||
co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
|
||||
if (!co_name)
|
||||
co_name = "?";
|
||||
PyDTrace_LINE(co_filename, co_name, line);
|
||||
if (line != frame->f_lineno || frame->f_lasti < *instr_prev) {
|
||||
if (line != -1) {
|
||||
frame->f_lineno = line;
|
||||
co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
|
||||
if (!co_filename)
|
||||
co_filename = "?";
|
||||
co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
|
||||
if (!co_name)
|
||||
co_name = "?";
|
||||
PyDTrace_LINE(co_filename, co_name, line);
|
||||
}
|
||||
}
|
||||
*instr_prev = frame->f_lasti;
|
||||
}
|
||||
|
|
220
Python/compile.c
220
Python/compile.c
|
@ -1827,7 +1827,7 @@ compiler_mod(struct compiler *c, mod_ty mod)
|
|||
return NULL;
|
||||
}
|
||||
/* Use 0 for firstlineno initially, will fixup in assemble(). */
|
||||
if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 0))
|
||||
if (!compiler_enter_scope(c, module, COMPILER_SCOPE_MODULE, mod, 1))
|
||||
return NULL;
|
||||
switch (mod->kind) {
|
||||
case Module_kind:
|
||||
|
@ -2271,7 +2271,9 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
|
|||
c->u->u_argcount = asdl_seq_LEN(args->args);
|
||||
c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
|
||||
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
|
||||
VISIT_SEQ_IN_SCOPE(c, stmt, body);
|
||||
for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
|
||||
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
|
||||
}
|
||||
co = assemble(c, 1);
|
||||
qualname = c->u->u_qualname;
|
||||
Py_INCREF(qualname);
|
||||
|
@ -2808,6 +2810,8 @@ compiler_async_for(struct compiler *c, stmt_ty s)
|
|||
|
||||
/* Except block for __anext__ */
|
||||
compiler_use_next_block(c, except);
|
||||
|
||||
c->u->u_lineno = -1;
|
||||
ADDOP(c, END_ASYNC_FOR);
|
||||
|
||||
/* `else` block */
|
||||
|
@ -3115,7 +3119,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
|
||||
ADDOP(c, POP_BLOCK);
|
||||
ADDOP(c, POP_EXCEPT);
|
||||
/* name = None; del name */
|
||||
/* name = None; del name; # Mark as artificial */
|
||||
c->u->u_lineno = -1;
|
||||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
compiler_nameop(c, handler->v.ExceptHandler.name, Store);
|
||||
compiler_nameop(c, handler->v.ExceptHandler.name, Del);
|
||||
|
@ -3124,7 +3129,8 @@ compiler_try_except(struct compiler *c, stmt_ty s)
|
|||
/* except: */
|
||||
compiler_use_next_block(c, cleanup_end);
|
||||
|
||||
/* name = None; del name */
|
||||
/* name = None; del name; # Mark as artificial */
|
||||
c->u->u_lineno = -1;
|
||||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
compiler_nameop(c, handler->v.ExceptHandler.name, Store);
|
||||
compiler_nameop(c, handler->v.ExceptHandler.name, Del);
|
||||
|
@ -3359,6 +3365,7 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
|
|||
|
||||
if (value->kind == Constant_kind) {
|
||||
/* ignore constant statement */
|
||||
ADDOP(c, NOP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3431,6 +3438,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
|
|||
case Expr_kind:
|
||||
return compiler_visit_stmt_expr(c, s->v.Expr.value);
|
||||
case Pass_kind:
|
||||
ADDOP(c, NOP);
|
||||
break;
|
||||
case Break_kind:
|
||||
return compiler_break(c);
|
||||
|
@ -5429,8 +5437,9 @@ struct assembler {
|
|||
basicblock **a_reverse_postorder; /* list of blocks in dfs postorder */
|
||||
PyObject *a_lnotab; /* string containing lnotab */
|
||||
int a_lnotab_off; /* offset into lnotab */
|
||||
int a_lineno; /* last lineno of emitted instruction */
|
||||
int a_lineno_off; /* bytecode offset of last lineno */
|
||||
int a_prevlineno; /* lineno of last emitted line in line table */
|
||||
int a_lineno; /* lineno of last emitted instruction */
|
||||
int a_lineno_start; /* bytecode start offset of current lineno */
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -5533,7 +5542,7 @@ static int
|
|||
assemble_init(struct assembler *a, int nblocks, int firstlineno)
|
||||
{
|
||||
memset(a, 0, sizeof(struct assembler));
|
||||
a->a_lineno = firstlineno;
|
||||
a->a_prevlineno = a->a_lineno = firstlineno;
|
||||
a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
|
||||
if (!a->a_bytecode)
|
||||
return 0;
|
||||
|
@ -5573,114 +5582,82 @@ blocksize(basicblock *b)
|
|||
return size;
|
||||
}
|
||||
|
||||
/* Appends a pair to the end of the line number table, a_lnotab, representing
|
||||
the instruction's bytecode offset and line number. See
|
||||
Objects/lnotab_notes.txt for the description of the line number table. */
|
||||
|
||||
static int
|
||||
assemble_lnotab(struct assembler *a, struct instr *i)
|
||||
assemble_emit_linetable_pair(struct assembler *a, int bdelta, int ldelta)
|
||||
{
|
||||
int d_bytecode, d_lineno;
|
||||
Py_ssize_t len;
|
||||
unsigned char *lnotab;
|
||||
|
||||
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 > 255) {
|
||||
int j, nbytes, ncodes = d_bytecode / 255;
|
||||
nbytes = a->a_lnotab_off + 2 * ncodes;
|
||||
len = PyBytes_GET_SIZE(a->a_lnotab);
|
||||
if (nbytes >= len) {
|
||||
if ((len <= INT_MAX / 2) && (len * 2 < nbytes))
|
||||
len = nbytes;
|
||||
else if (len <= INT_MAX / 2)
|
||||
len *= 2;
|
||||
else {
|
||||
PyErr_NoMemory();
|
||||
return 0;
|
||||
}
|
||||
if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
|
||||
return 0;
|
||||
}
|
||||
lnotab = (unsigned char *)
|
||||
PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
|
||||
for (j = 0; j < ncodes; j++) {
|
||||
*lnotab++ = 255;
|
||||
*lnotab++ = 0;
|
||||
}
|
||||
d_bytecode -= ncodes * 255;
|
||||
a->a_lnotab_off += ncodes * 2;
|
||||
}
|
||||
assert(0 <= d_bytecode && d_bytecode <= 255);
|
||||
|
||||
if (d_lineno < -128 || 127 < d_lineno) {
|
||||
int j, nbytes, ncodes, k;
|
||||
if (d_lineno < 0) {
|
||||
k = -128;
|
||||
/* use division on positive numbers */
|
||||
ncodes = (-d_lineno) / 128;
|
||||
}
|
||||
else {
|
||||
k = 127;
|
||||
ncodes = d_lineno / 127;
|
||||
}
|
||||
d_lineno -= ncodes * k;
|
||||
assert(ncodes >= 1);
|
||||
nbytes = a->a_lnotab_off + 2 * ncodes;
|
||||
len = PyBytes_GET_SIZE(a->a_lnotab);
|
||||
if (nbytes >= len) {
|
||||
if ((len <= INT_MAX / 2) && len * 2 < nbytes)
|
||||
len = nbytes;
|
||||
else if (len <= INT_MAX / 2)
|
||||
len *= 2;
|
||||
else {
|
||||
PyErr_NoMemory();
|
||||
return 0;
|
||||
}
|
||||
if (_PyBytes_Resize(&a->a_lnotab, len) < 0)
|
||||
return 0;
|
||||
}
|
||||
lnotab = (unsigned char *)
|
||||
PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
|
||||
*lnotab++ = d_bytecode;
|
||||
*lnotab++ = k;
|
||||
d_bytecode = 0;
|
||||
for (j = 1; j < ncodes; j++) {
|
||||
*lnotab++ = 0;
|
||||
*lnotab++ = k;
|
||||
}
|
||||
a->a_lnotab_off += ncodes * 2;
|
||||
}
|
||||
assert(-128 <= d_lineno && d_lineno <= 127);
|
||||
|
||||
len = PyBytes_GET_SIZE(a->a_lnotab);
|
||||
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)
|
||||
return 0;
|
||||
}
|
||||
lnotab = (unsigned char *)
|
||||
unsigned char *lnotab = (unsigned char *)
|
||||
PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off;
|
||||
|
||||
a->a_lnotab_off += 2;
|
||||
if (d_bytecode) {
|
||||
*lnotab++ = d_bytecode;
|
||||
*lnotab++ = d_lineno;
|
||||
}
|
||||
else { /* First line of a block; def stmt, etc. */
|
||||
*lnotab++ = 0;
|
||||
*lnotab++ = d_lineno;
|
||||
}
|
||||
a->a_lineno = i->i_lineno;
|
||||
a->a_lineno_off = a->a_offset;
|
||||
*lnotab++ = bdelta;
|
||||
*lnotab++ = ldelta;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Appends a range to the end of the line number table. See
|
||||
* Objects/lnotab_notes.txt for the description of the line number table. */
|
||||
|
||||
static int
|
||||
assemble_line_range(struct assembler *a)
|
||||
{
|
||||
int ldelta, bdelta;
|
||||
bdelta = (a->a_offset - a->a_lineno_start) * 2;
|
||||
if (bdelta == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (a->a_lineno < 0) {
|
||||
ldelta = -128;
|
||||
}
|
||||
else {
|
||||
ldelta = a->a_lineno - a->a_prevlineno;
|
||||
a->a_prevlineno = a->a_lineno;
|
||||
while (ldelta > 127) {
|
||||
if (!assemble_emit_linetable_pair(a, 0, 127)) {
|
||||
return 0;
|
||||
}
|
||||
ldelta -= 127;
|
||||
}
|
||||
while (ldelta < -127) {
|
||||
if (!assemble_emit_linetable_pair(a, 0, -127)) {
|
||||
return 0;
|
||||
}
|
||||
ldelta += 127;
|
||||
}
|
||||
}
|
||||
assert(-128 <= ldelta && ldelta < 128);
|
||||
while (bdelta > 254) {
|
||||
if (!assemble_emit_linetable_pair(a, 254, ldelta)) {
|
||||
return 0;
|
||||
}
|
||||
ldelta = a->a_lineno < 0 ? -128 : 0;
|
||||
bdelta -= 254;
|
||||
}
|
||||
if (!assemble_emit_linetable_pair(a, bdelta, ldelta)) {
|
||||
return 0;
|
||||
}
|
||||
a->a_lineno_start = a->a_offset;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
assemble_lnotab(struct assembler *a, struct instr *i)
|
||||
{
|
||||
if (i->i_lineno == a->a_lineno) {
|
||||
return 1;
|
||||
}
|
||||
if (!assemble_line_range(a)) {
|
||||
return 0;
|
||||
}
|
||||
a->a_lineno = i->i_lineno;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* assemble_emit()
|
||||
Extend the bytecode with a new instruction.
|
||||
Update lnotab if necessary.
|
||||
|
@ -5998,7 +5975,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) {
|
||||
NEXT_BLOCK(c);
|
||||
c->u->u_lineno = -1;
|
||||
if (addNone)
|
||||
ADDOP_LOAD_CONST(c, Py_None);
|
||||
ADDOP(c, RETURN_VALUE);
|
||||
|
@ -6015,7 +5992,7 @@ assemble(struct compiler *c, int addNone)
|
|||
if (!c->u->u_firstlineno) {
|
||||
if (entryblock && entryblock->b_instr && entryblock->b_instr->i_lineno)
|
||||
c->u->u_firstlineno = entryblock->b_instr->i_lineno;
|
||||
else
|
||||
else
|
||||
c->u->u_firstlineno = 1;
|
||||
}
|
||||
if (!assemble_init(&a, nblocks, c->u->u_firstlineno))
|
||||
|
@ -6040,6 +6017,13 @@ assemble(struct compiler *c, int addNone)
|
|||
if (!assemble_emit(&a, &b->b_instr[j]))
|
||||
goto error;
|
||||
}
|
||||
if (!assemble_line_range(&a)) {
|
||||
return 0;
|
||||
}
|
||||
/* Emit sentinel at end of line number table */
|
||||
if (!assemble_emit_linetable_pair(&a, 255, -128)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (_PyBytes_Resize(&a.a_lnotab, a.a_lnotab_off) < 0)
|
||||
goto error;
|
||||
|
@ -6280,22 +6264,42 @@ static void
|
|||
clean_basic_block(basicblock *bb) {
|
||||
/* Remove NOPs and any code following a return or re-raise. */
|
||||
int dest = 0;
|
||||
int prev_lineno = -1;
|
||||
for (int src = 0; src < bb->b_iused; src++) {
|
||||
int lineno = bb->b_instr[src].i_lineno;
|
||||
switch(bb->b_instr[src].i_opcode) {
|
||||
case NOP:
|
||||
/* skip */
|
||||
break;
|
||||
case RETURN_VALUE:
|
||||
case RERAISE:
|
||||
bb->b_next = NULL;
|
||||
bb->b_instr[dest] = bb->b_instr[src];
|
||||
dest++;
|
||||
goto end;
|
||||
case NOP:
|
||||
{
|
||||
/* Eliminate no-op if it doesn't have a line number, or
|
||||
* if the next instruction has same line number or no line number, or
|
||||
* if the previous instruction had the same line number. */
|
||||
if (lineno < 0) {
|
||||
break;
|
||||
}
|
||||
if (prev_lineno == lineno) {
|
||||
break;
|
||||
}
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fallthrough */
|
||||
default:
|
||||
if (dest != src) {
|
||||
bb->b_instr[dest] = bb->b_instr[src];
|
||||
}
|
||||
dest++;
|
||||
prev_lineno = lineno;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
3051
Python/importlib.h
generated
3051
Python/importlib.h
generated
File diff suppressed because it is too large
Load diff
4666
Python/importlib_external.h
generated
4666
Python/importlib_external.h
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -524,7 +524,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
|
|||
w_object(co->co_filename, p);
|
||||
w_object(co->co_name, p);
|
||||
w_long(co->co_firstlineno, p);
|
||||
w_object(co->co_lnotab, p);
|
||||
w_object(co->co_linetable, p);
|
||||
}
|
||||
else if (PyObject_CheckBuffer(v)) {
|
||||
/* Write unknown bytes-like objects as a bytes object */
|
||||
|
@ -1312,7 +1312,7 @@ r_object(RFILE *p)
|
|||
PyObject *filename = NULL;
|
||||
PyObject *name = NULL;
|
||||
int firstlineno;
|
||||
PyObject *lnotab = NULL;
|
||||
PyObject *linetable = NULL;
|
||||
|
||||
idx = r_ref_reserve(flag, p);
|
||||
if (idx < 0)
|
||||
|
@ -1367,8 +1367,8 @@ r_object(RFILE *p)
|
|||
firstlineno = (int)r_long(p);
|
||||
if (firstlineno == -1 && PyErr_Occurred())
|
||||
break;
|
||||
lnotab = r_object(p);
|
||||
if (lnotab == NULL)
|
||||
linetable = r_object(p);
|
||||
if (linetable == NULL)
|
||||
goto code_error;
|
||||
|
||||
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
||||
|
@ -1382,7 +1382,7 @@ r_object(RFILE *p)
|
|||
nlocals, stacksize, flags,
|
||||
code, consts, names, varnames,
|
||||
freevars, cellvars, filename, name,
|
||||
firstlineno, lnotab);
|
||||
firstlineno, linetable);
|
||||
v = r_ref_insert(v, idx, flag, p);
|
||||
|
||||
code_error:
|
||||
|
@ -1394,7 +1394,7 @@ r_object(RFILE *p)
|
|||
Py_XDECREF(cellvars);
|
||||
Py_XDECREF(filename);
|
||||
Py_XDECREF(name);
|
||||
Py_XDECREF(lnotab);
|
||||
Py_XDECREF(linetable);
|
||||
}
|
||||
retval = v;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue