Commit 93a569d6 authored by Jeremy Hylton's avatar Jeremy Hylton

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.
parent 4bf1fb63
...@@ -668,20 +668,21 @@ static void ...@@ -668,20 +668,21 @@ static void
com_push(struct compiling *c, int n) com_push(struct compiling *c, int n)
{ {
c->c_stacklevel += n; c->c_stacklevel += n;
if (c->c_stacklevel > c->c_maxstacklevel) if (c->c_stacklevel > c->c_maxstacklevel) {
c->c_maxstacklevel = c->c_stacklevel; c->c_maxstacklevel = c->c_stacklevel;
/*
fprintf(stderr, "%s:%s:%d max stack nexti=%d level=%d n=%d\n",
c->c_filename, c->c_name, c->c_lineno,
c->c_nexti, c->c_stacklevel, n);
*/
}
} }
static void static void
com_pop(struct compiling *c, int n) com_pop(struct compiling *c, int n)
{ {
if (c->c_stacklevel < n) { if (c->c_stacklevel < n)
/* fprintf(stderr,
"%s:%d: underflow! nexti=%d, level=%d, n=%d\n",
c->c_filename, c->c_lineno,
c->c_nexti, c->c_stacklevel, n); */
c->c_stacklevel = 0; c->c_stacklevel = 0;
}
else else
c->c_stacklevel -= n; c->c_stacklevel -= n;
} }
...@@ -695,26 +696,26 @@ com_done(struct compiling *c) ...@@ -695,26 +696,26 @@ com_done(struct compiling *c)
_PyString_Resize(&c->c_lnotab, c->c_lnotab_next); _PyString_Resize(&c->c_lnotab, c->c_lnotab_next);
} }
static int
com_check_size(PyObject **s, int offset)
{
int len = PyString_GET_SIZE(*s);
if (offset >= len)
return _PyString_Resize(s, len * 2);
return 0;
}
static void static void
com_addbyte(struct compiling *c, int byte) com_addbyte(struct compiling *c, int byte)
{ {
int len;
/*fprintf(stderr, "%3d: %3d\n", c->c_nexti, byte);*/ /*fprintf(stderr, "%3d: %3d\n", c->c_nexti, byte);*/
assert(byte >= 0 && byte <= 255); assert(byte >= 0 && byte <= 255);
if (byte < 0 || byte > 255) { assert(c->c_code);
com_error(c, PyExc_SystemError, if (com_check_size(&c->c_code, c->c_nexti)) {
"com_addbyte: byte out of range"); c->c_errors++;
}
if (c->c_code == NULL)
return; return;
len = PyString_Size(c->c_code);
if (c->c_nexti >= len) {
if (_PyString_Resize(&c->c_code, len+1000) != 0) {
c->c_errors++;
return;
}
} }
PyString_AsString(c->c_code)[c->c_nexti++] = byte; PyString_AS_STRING(c->c_code)[c->c_nexti++] = byte;
} }
static void static void
...@@ -727,18 +728,14 @@ com_addint(struct compiling *c, int x) ...@@ -727,18 +728,14 @@ com_addint(struct compiling *c, int x)
static void static void
com_add_lnotab(struct compiling *c, int addr, int line) com_add_lnotab(struct compiling *c, int addr, int line)
{ {
int size;
char *p; char *p;
if (c->c_lnotab == NULL) if (c->c_lnotab == NULL)
return; return;
size = PyString_Size(c->c_lnotab); if (com_check_size(&c->c_lnotab, c->c_lnotab_next + 2)) {
if (c->c_lnotab_next+2 > size) { c->c_errors++;
if (_PyString_Resize(&c->c_lnotab, size + 1000) < 0) { return;
c->c_errors++;
return;
}
} }
p = PyString_AsString(c->c_lnotab) + c->c_lnotab_next; p = PyString_AS_STRING(c->c_lnotab) + c->c_lnotab_next;
*p++ = addr; *p++ = addr;
*p++ = line; *p++ = line;
c->c_lnotab_next += 2; c->c_lnotab_next += 2;
...@@ -804,7 +801,7 @@ com_addfwref(struct compiling *c, int op, int *p_anchor) ...@@ -804,7 +801,7 @@ com_addfwref(struct compiling *c, int op, int *p_anchor)
static void static void
com_backpatch(struct compiling *c, int anchor) com_backpatch(struct compiling *c, int anchor)
{ {
unsigned char *code = (unsigned char *) PyString_AsString(c->c_code); unsigned char *code = (unsigned char *) PyString_AS_STRING(c->c_code);
int target = c->c_nexti; int target = c->c_nexti;
int dist; int dist;
int prev; int prev;
...@@ -2326,26 +2323,27 @@ com_test(struct compiling *c, node *n) ...@@ -2326,26 +2323,27 @@ com_test(struct compiling *c, node *n)
{ {
REQ(n, test); /* and_test ('or' and_test)* | lambdef */ REQ(n, test); /* and_test ('or' and_test)* | lambdef */
if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) { if (NCH(n) == 1 && TYPE(CHILD(n, 0)) == lambdef) {
PyObject *co; PyCodeObject *co;
int i, closure; int i, closure;
int ndefs = com_argdefs(c, CHILD(n, 0)); int ndefs = com_argdefs(c, CHILD(n, 0));
symtable_enter_scope(c->c_symtable, "lambda", lambdef, symtable_enter_scope(c->c_symtable, "lambda", lambdef,
n->n_lineno); n->n_lineno);
co = (PyObject *) icompile(CHILD(n, 0), c); co = icompile(CHILD(n, 0), c);
if (co == NULL) { if (co == NULL) {
c->c_errors++; c->c_errors++;
return; return;
} }
symtable_exit_scope(c->c_symtable); symtable_exit_scope(c->c_symtable);
i = com_addconst(c, co); i = com_addconst(c, (PyObject *)co);
closure = com_make_closure(c, (PyCodeObject *)co); closure = com_make_closure(c, co);
Py_DECREF(co);
com_addoparg(c, LOAD_CONST, i); com_addoparg(c, LOAD_CONST, i);
com_push(c, 1); com_push(c, 1);
if (closure) if (closure) {
com_addoparg(c, MAKE_CLOSURE, ndefs); com_addoparg(c, MAKE_CLOSURE, ndefs);
else com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
} else
com_addoparg(c, MAKE_FUNCTION, ndefs); com_addoparg(c, MAKE_FUNCTION, ndefs);
Py_DECREF(co);
com_pop(c, ndefs); com_pop(c, ndefs);
} }
else { else {
...@@ -3564,7 +3562,8 @@ static void ...@@ -3564,7 +3562,8 @@ static void
com_classdef(struct compiling *c, node *n) com_classdef(struct compiling *c, node *n)
{ {
int i; int i;
PyObject *co, *v; PyObject *v;
PyCodeObject *co;
char *name; char *name;
REQ(n, classdef); REQ(n, classdef);
...@@ -3587,23 +3586,25 @@ com_classdef(struct compiling *c, node *n) ...@@ -3587,23 +3586,25 @@ com_classdef(struct compiling *c, node *n)
com_bases(c, CHILD(n, 3)); com_bases(c, CHILD(n, 3));
name = STR(CHILD(n, 1)); name = STR(CHILD(n, 1));
symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno); symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno);
co = (PyObject *)icompile(n, c); co = icompile(n, c);
symtable_exit_scope(c->c_symtable); symtable_exit_scope(c->c_symtable);
if (co == NULL) if (co == NULL)
c->c_errors++; c->c_errors++;
else { else {
int closure = com_make_closure(c, (PyCodeObject *)co); int closure = com_make_closure(c, co);
i = com_addconst(c, co); i = com_addconst(c, (PyObject *)co);
com_addoparg(c, LOAD_CONST, i); com_addoparg(c, LOAD_CONST, i);
com_push(c, 1); com_push(c, 1);
if (closure) if (closure) {
com_addoparg(c, MAKE_CLOSURE, 0); com_addoparg(c, MAKE_CLOSURE, 0);
else com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
} else
com_addoparg(c, MAKE_FUNCTION, 0); com_addoparg(c, MAKE_FUNCTION, 0);
com_addoparg(c, CALL_FUNCTION, 0); com_addoparg(c, CALL_FUNCTION, 0);
com_addbyte(c, BUILD_CLASS); com_addbyte(c, BUILD_CLASS);
com_pop(c, 2); com_pop(c, 2);
com_addop_varname(c, VAR_STORE, STR(CHILD(n, 1))); com_addop_varname(c, VAR_STORE, STR(CHILD(n, 1)));
com_pop(c, 1);
Py_DECREF(co); Py_DECREF(co);
} }
} }
...@@ -4082,8 +4083,7 @@ jcompile(node *n, char *filename, struct compiling *base, ...@@ -4082,8 +4083,7 @@ jcompile(node *n, char *filename, struct compiling *base,
if (base->c_nested if (base->c_nested
|| (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION)) || (sc.c_symtable->st_cur->ste_type == TYPE_FUNCTION))
sc.c_nested = 1; sc.c_nested = 1;
sc.c_flags |= base->c_flags & (CO_GENERATOR_ALLOWED | sc.c_flags |= base->c_flags & PyCF_MASK;
CO_FUTURE_DIVISION);
} else { } else {
sc.c_private = NULL; sc.c_private = NULL;
sc.c_future = PyNode_Future(n, filename); sc.c_future = PyNode_Future(n, filename);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment