Commit fab779a4 authored by Neil Schemenauer's avatar Neil Schemenauer

Fix private name mangling. The symtable also must do mangles so that

the scope of names can be correctly determined.
parent b34c38cc
......@@ -17,7 +17,7 @@ struct symtable {
PyObject *st_stack; /* stack of namespace info */
PyObject *st_global; /* borrowed ref to MODULE in st_symbols */
int st_nblocks; /* number of blocks */
char *st_private; /* name of current class or NULL */
PyObject *st_private; /* name of current class or NULL */
int st_tmpname; /* temporary name counter */
PyFutureFeatures *st_future; /* module's future features */
};
......
......@@ -2701,10 +2701,11 @@ inplace_binop(struct compiler *c, operator_ty op)
static int
compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
{
int op, scope;
int op, scope, r, arg;
enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
PyObject *dict = c->u->u_names;
PyObject *mangled;
/* XXX AugStore isn't used anywhere! */
/* First check for assignment to __debug__. Param? */
......@@ -2713,9 +2714,13 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
return compiler_error(c, "can not assign to __debug__");
}
mangled = _Py_Mangle(c->u->u_private, name);
if (!mangled)
return 0;
op = 0;
optype = OP_NAME;
scope = PyST_GetScope(c->u->u_ste, name);
scope = PyST_GetScope(c->u->u_ste, mangled);
switch (scope) {
case FREE:
dict = c->u->u_freevars;
......@@ -2755,6 +2760,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
"can not delete variable '%s' referenced "
"in nested scope",
PyString_AS_STRING(name));
Py_DECREF(mangled);
return 0;
break;
case Param:
......@@ -2772,7 +2778,8 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
case Param:
assert(0); /* impossible */
}
ADDOP_O(c, op, name, varnames);
ADDOP_O(c, op, mangled, varnames);
Py_DECREF(mangled);
return 1;
case OP_GLOBAL:
switch (ctx) {
......@@ -2801,7 +2808,12 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx)
}
assert(op);
return compiler_addop_name(c, op, dict, name);
arg = compiler_add_o(c, dict, mangled);
if (arg < 0)
return 0;
r = compiler_addop_i(c, op, arg);
Py_DECREF(mangled);
return r;
}
static int
......
......@@ -740,8 +740,11 @@ static int
symtable_lookup(struct symtable *st, PyObject *name)
{
PyObject *o;
o = PyDict_GetItem(st->st_cur->ste_symbols, name);
PyObject *mangled = _Py_Mangle(st->st_private, name);
if (!mangled)
return 0;
o = PyDict_GetItem(st->st_cur->ste_symbols, mangled);
Py_DECREF(mangled);
if (!o)
return 0;
return PyInt_AsLong(o);
......@@ -753,49 +756,57 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag)
PyObject *o;
PyObject *dict;
int val;
PyObject *mangled = _Py_Mangle(st->st_private, name);
if (!mangled)
return 0;
dict = st->st_cur->ste_symbols;
if ((o = PyDict_GetItem(dict, name))) {
if ((o = PyDict_GetItem(dict, mangled))) {
val = PyInt_AS_LONG(o);
if ((flag & DEF_PARAM) && (val & DEF_PARAM)) {
/* Is it better to use 'mangled' or 'name' here? */
PyErr_Format(PyExc_SyntaxError, DUPLICATE_ARGUMENT,
PyString_AsString(name));
PyErr_SyntaxLocation(st->st_filename,
st->st_cur->ste_lineno);
return 0;
goto error;
}
val |= flag;
} else
val = flag;
o = PyInt_FromLong(val);
if (o == NULL)
return 0;
if (PyDict_SetItem(dict, name, o) < 0) {
goto error;
if (PyDict_SetItem(dict, mangled, o) < 0) {
Py_DECREF(o);
return 0;
goto error;
}
Py_DECREF(o);
if (flag & DEF_PARAM) {
if (PyList_Append(st->st_cur->ste_varnames, name) < 0)
return 0;
if (PyList_Append(st->st_cur->ste_varnames, mangled) < 0)
goto error;
} else if (flag & DEF_GLOBAL) {
/* XXX need to update DEF_GLOBAL for other flags too;
perhaps only DEF_FREE_GLOBAL */
val = flag;
if ((o = PyDict_GetItem(st->st_global, name))) {
if ((o = PyDict_GetItem(st->st_global, mangled))) {
val |= PyInt_AS_LONG(o);
}
o = PyInt_FromLong(val);
if (o == NULL)
return 0;
if (PyDict_SetItem(st->st_global, name, o) < 0) {
goto error;
if (PyDict_SetItem(st->st_global, mangled, o) < 0) {
Py_DECREF(o);
return 0;
goto error;
}
Py_DECREF(o);
}
return 1;
error:
Py_DECREF(mangled);
return 0;
}
/* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
......@@ -849,17 +860,22 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (!symtable_exit_block(st, s))
return 0;
break;
case ClassDef_kind:
case ClassDef_kind: {
PyObject *tmp;
if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL))
return 0;
VISIT_SEQ(st, expr, s->v.ClassDef.bases);
if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
(void *)s, s->lineno))
return 0;
tmp = st->st_private;
st->st_private = s->v.ClassDef.name;
VISIT_SEQ(st, stmt, s->v.ClassDef.body);
st->st_private = tmp;
if (!symtable_exit_block(st, s))
return 0;
break;
}
case Return_kind:
if (s->v.Return.value)
VISIT(st, expr, s->v.Return.value);
......
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