From 8b528b28f15a78c116fc90303194ad8b1476034d Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Sun, 23 Oct 2005 18:37:42 +0000 Subject: Fix private name mangling. The symtable also must do mangles so that the scope of names can be correctly determined. --- Include/symtable.h | 2 +- Python/compile.c | 20 ++++++++++++++++---- Python/symtable.c | 44 ++++++++++++++++++++++++++++++-------------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Include/symtable.h b/Include/symtable.h index c8d8636..ad7334b 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -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 */ }; diff --git a/Python/compile.c b/Python/compile.c index 5e7f35d..fe6fd50 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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 diff --git a/Python/symtable.c b/Python/symtable.c index 49d153b..cbf0344 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -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); -- cgit v0.12