Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 93a569d

Browse files
committed
Fix computation of stack depth for classdef and closures.
Also minor tweaks to internal routines. Use PyCF_MASK instead of explicit list of flags. For the MAKE_CLOSURE opcode, the number of items popped off the stack depends on both the oparg and the number of free variables for the code object. Fix the code so it accounts for the free variables. In com_classdef(), record an extra pop to account for the STORE call after the BUILD_CLASS. Get rid of some commented out debugging code in com_push() and com_pop(). Factor string resize logic into helper routine com_check_size(). In com_addbyte(), remove redudant if statement after assert. (They test the same condition.) In several routines, use string macros instead of string functions.
1 parent 4bf1fb6 commit 93a569d

1 file changed

Lines changed: 44 additions & 44 deletions

File tree

Python/compile.c

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -668,20 +668,21 @@ static void
668668
com_push(struct compiling *c, int n)
669669
{
670670
c->c_stacklevel += n;
671-
if (c->c_stacklevel > c->c_maxstacklevel)
671+
if (c->c_stacklevel > c->c_maxstacklevel) {
672672
c->c_maxstacklevel = c->c_stacklevel;
673+
/*
674+
fprintf(stderr, "%s:%s:%d max stack nexti=%d level=%d n=%d\n",
675+
c->c_filename, c->c_name, c->c_lineno,
676+
c->c_nexti, c->c_stacklevel, n);
677+
*/
678+
}
673679
}
674680

675681
static void
676682
com_pop(struct compiling *c, int n)
677683
{
678-
if (c->c_stacklevel < n) {
679-
/* fprintf(stderr,
680-
"%s:%d: underflow! nexti=%d, level=%d, n=%d\n",
681-
c->c_filename, c->c_lineno,
682-
c->c_nexti, c->c_stacklevel, n); */
684+
if (c->c_stacklevel < n)
683685
c->c_stacklevel = 0;
684-
}
685686
else
686687
c->c_stacklevel -= n;
687688
}
@@ -695,26 +696,26 @@ com_done(struct compiling *c)
695696
_PyString_Resize(&c->c_lnotab, c->c_lnotab_next);
696697
}
697698

699+
static int
700+
com_check_size(PyObject **s, int offset)
701+
{
702+
int len = PyString_GET_SIZE(*s);
703+
if (offset >= len)
704+
return _PyString_Resize(s, len * 2);
705+
return 0;
706+
}
707+
698708
static void
699709
com_addbyte(struct compiling *c, int byte)
700710
{
701-
int len;
702711
/*fprintf(stderr, "%3d: %3d\n", c->c_nexti, byte);*/
703712
assert(byte >= 0 && byte <= 255);
704-
if (byte < 0 || byte > 255) {
705-
com_error(c, PyExc_SystemError,
706-
"com_addbyte: byte out of range");
707-
}
708-
if (c->c_code == NULL)
713+
assert(c->c_code);
714+
if (com_check_size(&c->c_code, c->c_nexti)) {
715+
c->c_errors++;
709716
return;
710-
len = PyString_Size(c->c_code);
711-
if (c->c_nexti >= len) {
712-
if (_PyString_Resize(&c->c_code, len+1000) != 0) {
713-
c->c_errors++;
714-
return;
715-
}
716717
}
717-
PyString_AsString(c->c_code)[c->c_nexti++] = byte;
718+
PyString_AS_STRING(c->c_code)[c->c_nexti++] = byte;
718719
}
719720

720721
static void
@@ -727,18 +728,14 @@ com_addint(struct compiling *c, int x)
727728
static void
728729
com_add_lnotab(struct compiling *c, int addr, int line)
729730
{
730-
int size;
731731
char *p;
732732
if (c->c_lnotab == NULL)
733733
return;
734-
size = PyString_Size(c->c_lnotab);
735-
if (c->c_lnotab_next+2 > size) {
736-
if (_PyString_Resize(&c->c_lnotab, size + 1000) < 0) {
737-
c->c_errors++;
738-
return;
739-
}
734+
if (com_check_size(&c->c_lnotab, c->c_lnotab_next + 2)) {
735+
c->c_errors++;
736+
return;
740737
}
741-
p = PyString_AsString(c->c_lnotab) + c->c_lnotab_next;
738+
p = PyString_AS_STRING(c->c_lnotab) + c->c_lnotab_next;
742739
*p++ = addr;
743740
*p++ = line;
744741
c->c_lnotab_next += 2;
@@ -804,7 +801,7 @@ com_addfwref(struct compiling *c, int op, int *p_anchor)
804801
static void
805802
com_backpatch(struct compiling *c, int anchor)
806803
{
807-
unsigned char *code = (unsigned char *) PyString_AsString(c->c_code);
804+
unsigned char *code = (unsigned char *) PyString_AS_STRING(c->c_code);
808805
int target = c->c_nexti;
809806
int dist;
810807
int prev;
@@ -2326,26 +2323,27 @@ com_test(struct compiling *c, node *n)
23262323
{
23272324
REQ(n, test); /* and_test ('or' and_test)* | lambdef */
23282325
if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) {
2329-
PyObject *co;
2326+
PyCodeObject *co;
23302327
int i, closure;
23312328
int ndefs = com_argdefs(c, CHILD(n, 0));
23322329
symtable_enter_scope(c->c_symtable, "lambda", lambdef,
23332330
n->n_lineno);
2334-
co = (PyObject *) icompile(CHILD(n, 0), c);
2331+
co = icompile(CHILD(n, 0), c);
23352332
if (co == NULL) {
23362333
c->c_errors++;
23372334
return;
23382335
}
23392336
symtable_exit_scope(c->c_symtable);
2340-
i = com_addconst(c, co);
2341-
closure = com_make_closure(c, (PyCodeObject *)co);
2342-
Py_DECREF(co);
2337+
i = com_addconst(c, (PyObject *)co);
2338+
closure = com_make_closure(c, co);
23432339
com_addoparg(c, LOAD_CONST, i);
23442340
com_push(c, 1);
2345-
if (closure)
2341+
if (closure) {
23462342
com_addoparg(c, MAKE_CLOSURE, ndefs);
2347-
else
2343+
com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
2344+
} else
23482345
com_addoparg(c, MAKE_FUNCTION, ndefs);
2346+
Py_DECREF(co);
23492347
com_pop(c, ndefs);
23502348
}
23512349
else {
@@ -3564,7 +3562,8 @@ static void
35643562
com_classdef(struct compiling *c, node *n)
35653563
{
35663564
int i;
3567-
PyObject *co, *v;
3565+
PyObject *v;
3566+
PyCodeObject *co;
35683567
char *name;
35693568

35703569
REQ(n, classdef);
@@ -3587,23 +3586,25 @@ com_classdef(struct compiling *c, node *n)
35873586
com_bases(c, CHILD(n, 3));
35883587
name = STR(CHILD(n, 1));
35893588
symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno);
3590-
co = (PyObject *)icompile(n, c);
3589+
co = icompile(n, c);
35913590
symtable_exit_scope(c->c_symtable);
35923591
if (co == NULL)
35933592
c->c_errors++;
35943593
else {
3595-
int closure = com_make_closure(c, (PyCodeObject *)co);
3596-
i = com_addconst(c, co);
3594+
int closure = com_make_closure(c, co);
3595+
i = com_addconst(c, (PyObject *)co);
35973596
com_addoparg(c, LOAD_CONST, i);
35983597
com_push(c, 1);
3599-
if (closure)
3598+
if (closure) {
36003599
com_addoparg(c, MAKE_CLOSURE, 0);
3601-
else
3600+
com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
3601+
} else
36023602
com_addoparg(c, MAKE_FUNCTION, 0);
36033603
com_addoparg(c, CALL_FUNCTION, 0);
36043604
com_addbyte(c, BUILD_CLASS);
36053605
com_pop(c, 2);
36063606
com_addop_varname(c, VAR_STORE, STR(CHILD(n, 1)));
3607+
com_pop(c, 1);
36073608
Py_DECREF(co);
36083609
}
36093610
}
@@ -4082,8 +4083,7 @@ jcompile(node *n, char *filename, struct compiling *base,
40824083
if (base->c_nested
40834084
|| (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION))
40844085
sc.c_nested = 1;
4085-
sc.c_flags |= base->c_flags & (CO_GENERATOR_ALLOWED |
4086-
CO_FUTURE_DIVISION);
4086+
sc.c_flags |= base->c_flags & PyCF_MASK;
40874087
} else {
40884088
sc.c_private = NULL;
40894089
sc.c_future = PyNode_Future(n, filename);

0 commit comments

Comments
 (0)