Remove st_nested_scopes from struct symtable,
because nested scopes are always enabled. (Accidentally checked in one small change along this path yesterday, wreaking havoc in the Windows build.)
This commit is contained in:
parent
d5d8fc559c
commit
1abf610b15
|
@ -20,7 +20,6 @@ struct _symtable_entry;
|
||||||
|
|
||||||
struct symtable {
|
struct symtable {
|
||||||
int st_pass; /* pass == 1 or 2 */
|
int st_pass; /* pass == 1 or 2 */
|
||||||
int st_nested_scopes; /* true if nested scopes are enabled */
|
|
||||||
char *st_filename; /* name of file being compiled */
|
char *st_filename; /* name of file being compiled */
|
||||||
struct _symtable_entry *st_cur; /* current symbol table entry */
|
struct _symtable_entry *st_cur; /* current symbol table entry */
|
||||||
PyObject *st_symbols; /* dictionary of symbol table entries */
|
PyObject *st_symbols; /* dictionary of symbol table entries */
|
||||||
|
|
174
Python/compile.c
174
Python/compile.c
|
@ -2158,9 +2158,6 @@ static int
|
||||||
com_make_closure(struct compiling *c, PyCodeObject *co)
|
com_make_closure(struct compiling *c, PyCodeObject *co)
|
||||||
{
|
{
|
||||||
int i, free = PyTuple_GET_SIZE(co->co_freevars);
|
int i, free = PyTuple_GET_SIZE(co->co_freevars);
|
||||||
/* If the code is compiled with st->st_nested_scopes == 0,
|
|
||||||
then no variable will ever be added to co_freevars.
|
|
||||||
*/
|
|
||||||
if (free == 0)
|
if (free == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < free; ++i) {
|
for (i = 0; i < free; ++i) {
|
||||||
|
@ -3928,7 +3925,7 @@ PyNode_CompileSymtable(node *n, char *filename)
|
||||||
symtable_node(st, n);
|
symtable_node(st, n);
|
||||||
if (st->st_errors > 0)
|
if (st->st_errors > 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
fail:
|
fail:
|
||||||
PyMem_Free((void *)ff);
|
PyMem_Free((void *)ff);
|
||||||
|
@ -4056,50 +4053,36 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
|
||||||
static int
|
static int
|
||||||
get_ref_type(struct compiling *c, char *name)
|
get_ref_type(struct compiling *c, char *name)
|
||||||
{
|
{
|
||||||
|
char buf[350];
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
if (c->c_symtable->st_nested_scopes) {
|
|
||||||
if (PyDict_GetItemString(c->c_cellvars, name) != NULL)
|
|
||||||
return CELL;
|
|
||||||
if (PyDict_GetItemString(c->c_locals, name) != NULL)
|
|
||||||
return LOCAL;
|
|
||||||
if (PyDict_GetItemString(c->c_freevars, name) != NULL)
|
|
||||||
return FREE;
|
|
||||||
v = PyDict_GetItemString(c->c_globals, name);
|
|
||||||
if (v) {
|
|
||||||
if (v == Py_None)
|
|
||||||
return GLOBAL_EXPLICIT;
|
|
||||||
else {
|
|
||||||
return GLOBAL_IMPLICIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (PyDict_GetItemString(c->c_locals, name) != NULL)
|
|
||||||
return LOCAL;
|
|
||||||
v = PyDict_GetItemString(c->c_globals, name);
|
|
||||||
if (v) {
|
|
||||||
if (v == Py_None)
|
|
||||||
return GLOBAL_EXPLICIT;
|
|
||||||
else {
|
|
||||||
return GLOBAL_IMPLICIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
char buf[350];
|
|
||||||
sprintf(buf,
|
|
||||||
"unknown scope for %.100s in %.100s(%s) "
|
|
||||||
"in %s\nsymbols: %s\nlocals: %s\nglobals: %s\n",
|
|
||||||
name, c->c_name,
|
|
||||||
PyObject_REPR(c->c_symtable->st_cur->ste_id),
|
|
||||||
c->c_filename,
|
|
||||||
PyObject_REPR(c->c_symtable->st_cur->ste_symbols),
|
|
||||||
PyObject_REPR(c->c_locals),
|
|
||||||
PyObject_REPR(c->c_globals)
|
|
||||||
);
|
|
||||||
|
|
||||||
Py_FatalError(buf);
|
if (PyDict_GetItemString(c->c_cellvars, name) != NULL)
|
||||||
|
return CELL;
|
||||||
|
if (PyDict_GetItemString(c->c_locals, name) != NULL)
|
||||||
|
return LOCAL;
|
||||||
|
if (PyDict_GetItemString(c->c_freevars, name) != NULL)
|
||||||
|
return FREE;
|
||||||
|
v = PyDict_GetItemString(c->c_globals, name);
|
||||||
|
if (v) {
|
||||||
|
if (v == Py_None)
|
||||||
|
return GLOBAL_EXPLICIT;
|
||||||
|
else {
|
||||||
|
return GLOBAL_IMPLICIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1; /* can't get here */
|
sprintf(buf,
|
||||||
|
"unknown scope for %.100s in %.100s(%s) "
|
||||||
|
"in %s\nsymbols: %s\nlocals: %s\nglobals: %s\n",
|
||||||
|
name, c->c_name,
|
||||||
|
PyObject_REPR(c->c_symtable->st_cur->ste_id),
|
||||||
|
c->c_filename,
|
||||||
|
PyObject_REPR(c->c_symtable->st_cur->ste_symbols),
|
||||||
|
PyObject_REPR(c->c_locals),
|
||||||
|
PyObject_REPR(c->c_globals)
|
||||||
|
);
|
||||||
|
|
||||||
|
Py_FatalError(buf);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper functions to issue warnings */
|
/* Helper functions to issue warnings */
|
||||||
|
@ -4375,60 +4358,10 @@ symtable_check_unoptimized(struct compiling *c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->c_symtable->st_nested_scopes) {
|
PyErr_SetString(PyExc_SyntaxError, buf);
|
||||||
PyErr_SetString(PyExc_SyntaxError, buf);
|
PyErr_SyntaxLocation(c->c_symtable->st_filename,
|
||||||
PyErr_SyntaxLocation(c->c_symtable->st_filename,
|
ste->ste_opt_lineno);
|
||||||
ste->ste_opt_lineno);
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return issue_warning(buf, c->c_filename, ste->ste_lineno);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
symtable_check_shadow(struct symtable *st, PyObject *name, int flags)
|
|
||||||
{
|
|
||||||
char buf[500];
|
|
||||||
PyObject *children, *v;
|
|
||||||
PySymtableEntryObject *child = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!(flags & DEF_BOUND))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* The semantics of this code will change with nested scopes.
|
|
||||||
It is defined in the current scope and referenced in a
|
|
||||||
child scope. Under the old rules, the child will see a
|
|
||||||
global. Under the new rules, the child will see the
|
|
||||||
binding in the current scope.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Find name of child function that has free variable */
|
|
||||||
children = st->st_cur->ste_children;
|
|
||||||
for (i = 0; i < PyList_GET_SIZE(children); i++) {
|
|
||||||
int cflags;
|
|
||||||
child = (PySymtableEntryObject *)PyList_GET_ITEM(children, i);
|
|
||||||
v = PyDict_GetItem(child->ste_symbols, name);
|
|
||||||
if (v == NULL)
|
|
||||||
continue;
|
|
||||||
cflags = PyInt_AS_LONG(v);
|
|
||||||
if (!(cflags & DEF_BOUND))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(child != NULL);
|
|
||||||
|
|
||||||
sprintf(buf, "local name '%.100s' in '%.100s' shadows "
|
|
||||||
"use of '%.100s' as global in nested scope '%.100s'",
|
|
||||||
PyString_AS_STRING(name),
|
|
||||||
PyString_AS_STRING(st->st_cur->ste_name),
|
|
||||||
PyString_AS_STRING(name),
|
|
||||||
PyString_AS_STRING(child->ste_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
return symtable_warn(st, buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -4489,26 +4422,17 @@ symtable_load_symbols(struct compiling *c)
|
||||||
while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
|
while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
|
||||||
flags = PyInt_AS_LONG(v);
|
flags = PyInt_AS_LONG(v);
|
||||||
|
|
||||||
if (st->st_nested_scopes == 0
|
|
||||||
&& (flags & (DEF_FREE | DEF_FREE_CLASS))) {
|
|
||||||
if (symtable_check_shadow(st, name, flags) < 0)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & DEF_FREE_GLOBAL)
|
if (flags & DEF_FREE_GLOBAL)
|
||||||
/* undo the original DEF_FREE */
|
/* undo the original DEF_FREE */
|
||||||
flags &= ~(DEF_FREE | DEF_FREE_CLASS);
|
flags &= ~(DEF_FREE | DEF_FREE_CLASS);
|
||||||
|
|
||||||
/* Deal with names that need two actions:
|
/* Deal with names that need two actions:
|
||||||
1. Cell variables, which are also locals.
|
1. Cell variables that are also locals.
|
||||||
2. Free variables in methods that are also class
|
2. Free variables in methods that are also class
|
||||||
variables or declared global.
|
variables or declared global.
|
||||||
*/
|
*/
|
||||||
if (st->st_nested_scopes) {
|
if (flags & (DEF_FREE | DEF_FREE_CLASS))
|
||||||
if (flags & (DEF_FREE | DEF_FREE_CLASS)) {
|
|
||||||
symtable_resolve_free(c, name, flags, &si);
|
symtable_resolve_free(c, name, flags, &si);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & DEF_STAR) {
|
if (flags & DEF_STAR) {
|
||||||
c->c_argcount--;
|
c->c_argcount--;
|
||||||
|
@ -4544,7 +4468,7 @@ symtable_load_symbols(struct compiling *c)
|
||||||
if (PyList_Append(c->c_varnames, name) < 0)
|
if (PyList_Append(c->c_varnames, name) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (is_free(flags)) {
|
} else if (is_free(flags)) {
|
||||||
if (ste->ste_nested && st->st_nested_scopes) {
|
if (ste->ste_nested) {
|
||||||
v = PyInt_FromLong(si.si_nfrees++);
|
v = PyInt_FromLong(si.si_nfrees++);
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -4553,25 +4477,22 @@ symtable_load_symbols(struct compiling *c)
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
} else {
|
} else {
|
||||||
si.si_nimplicit++;
|
si.si_nimplicit++;
|
||||||
if (PyDict_SetItem(c->c_globals, name,
|
if (PyDict_SetItem(c->c_globals, name,
|
||||||
implicit) < 0)
|
implicit) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (st->st_nscopes != 1) {
|
if (st->st_nscopes != 1) {
|
||||||
v = PyInt_FromLong(flags);
|
v = PyInt_FromLong(flags);
|
||||||
if (PyDict_SetItem(st->st_global,
|
if (PyDict_SetItem(st->st_global,
|
||||||
name, v))
|
name, v))
|
||||||
goto fail;
|
goto fail;
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(PyDict_Size(c->c_freevars) == si.si_nfrees);
|
assert(PyDict_Size(c->c_freevars) == si.si_nfrees);
|
||||||
|
|
||||||
if (st->st_nested_scopes == 0)
|
|
||||||
assert(si.si_nfrees == 0);
|
|
||||||
|
|
||||||
if (si.si_ncells > 1) { /* one cell is always in order */
|
if (si.si_ncells > 1) { /* one cell is always in order */
|
||||||
if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount,
|
if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount,
|
||||||
c->c_varnames, c->c_flags) < 0)
|
c->c_varnames, c->c_flags) < 0)
|
||||||
|
@ -4596,11 +4517,6 @@ symtable_init()
|
||||||
return NULL;
|
return NULL;
|
||||||
st->st_pass = 1;
|
st->st_pass = 1;
|
||||||
|
|
||||||
/* XXX Tim: Jeremy deleted the next line and everything went to hell.
|
|
||||||
XXX It should probably get fixed by getting rid of st_nested_scopes
|
|
||||||
XXX entirely. */
|
|
||||||
st->st_nested_scopes = 1;
|
|
||||||
|
|
||||||
st->st_filename = NULL;
|
st->st_filename = NULL;
|
||||||
if ((st->st_stack = PyList_New(0)) == NULL)
|
if ((st->st_stack = PyList_New(0)) == NULL)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
Loading…
Reference in New Issue