mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
gh-102371: move _Py_Mangle from compile.c to symtable.c (#102372)
This commit is contained in:
parent
73250000ac
commit
71db5dbcd7
5 changed files with 76 additions and 76 deletions
|
@ -19,12 +19,6 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
|
||||||
int optimize,
|
int optimize,
|
||||||
struct _arena *arena);
|
struct _arena *arena);
|
||||||
|
|
||||||
int _PyFuture_FromAST(
|
|
||||||
struct _mod * mod,
|
|
||||||
PyObject *filename,
|
|
||||||
PyFutureFeatures* futures);
|
|
||||||
|
|
||||||
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int optimize;
|
int optimize;
|
||||||
|
|
|
@ -90,6 +90,8 @@ PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
|
||||||
|
|
||||||
extern void _PySymtable_Free(struct symtable *);
|
extern void _PySymtable_Free(struct symtable *);
|
||||||
|
|
||||||
|
extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
|
||||||
|
|
||||||
/* Flags for def-use information */
|
/* Flags for def-use information */
|
||||||
|
|
||||||
#define DEF_GLOBAL 1 /* global stmt */
|
#define DEF_GLOBAL 1 /* global stmt */
|
||||||
|
@ -128,6 +130,11 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
|
||||||
int start,
|
int start,
|
||||||
PyCompilerFlags *flags);
|
PyCompilerFlags *flags);
|
||||||
|
|
||||||
|
int _PyFuture_FromAST(
|
||||||
|
struct _mod * mod,
|
||||||
|
PyObject *filename,
|
||||||
|
PyFutureFeatures* futures);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_call.h"
|
#include "pycore_call.h"
|
||||||
#include "pycore_code.h" // CO_FAST_FREE
|
#include "pycore_code.h" // CO_FAST_FREE
|
||||||
#include "pycore_compile.h" // _Py_Mangle()
|
#include "pycore_symtable.h" // _Py_Mangle()
|
||||||
#include "pycore_dict.h" // _PyDict_KeysSize()
|
#include "pycore_dict.h" // _PyDict_KeysSize()
|
||||||
#include "pycore_initconfig.h" // _PyStatus_OK()
|
#include "pycore_initconfig.h" // _PyStatus_OK()
|
||||||
#include "pycore_moduleobject.h" // _PyModule_GetDef()
|
#include "pycore_moduleobject.h" // _PyModule_GetDef()
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ast.h" // _PyAST_GetDocString()
|
#include "pycore_ast.h" // _PyAST_GetDocString()
|
||||||
#include "pycore_code.h" // _PyCode_New()
|
#include "pycore_code.h" // _PyCode_New()
|
||||||
#include "pycore_compile.h" // _PyFuture_FromAST()
|
#include "pycore_compile.h"
|
||||||
#include "pycore_intrinsics.h"
|
#include "pycore_intrinsics.h"
|
||||||
#include "pycore_long.h" // _PyLong_GetZero()
|
#include "pycore_long.h" // _PyLong_GetZero()
|
||||||
#include "pycore_opcode.h" // _PyOpcode_Caches
|
#include "pycore_opcode.h" // _PyOpcode_Caches
|
||||||
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
|
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
|
||||||
#include "pycore_symtable.h" // PySTEntryObject
|
#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST()
|
||||||
|
|
||||||
#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
|
#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
|
||||||
|
|
||||||
|
@ -569,72 +569,6 @@ static PyCodeObject *assemble(struct compiler *, int addNone);
|
||||||
|
|
||||||
#define CAPSULE_NAME "compile.c compiler unit"
|
#define CAPSULE_NAME "compile.c compiler unit"
|
||||||
|
|
||||||
PyObject *
|
|
||||||
_Py_Mangle(PyObject *privateobj, PyObject *ident)
|
|
||||||
{
|
|
||||||
/* Name mangling: __private becomes _classname__private.
|
|
||||||
This is independent from how the name is used. */
|
|
||||||
PyObject *result;
|
|
||||||
size_t nlen, plen, ipriv;
|
|
||||||
Py_UCS4 maxchar;
|
|
||||||
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
|
|
||||||
PyUnicode_READ_CHAR(ident, 0) != '_' ||
|
|
||||||
PyUnicode_READ_CHAR(ident, 1) != '_') {
|
|
||||||
return Py_NewRef(ident);
|
|
||||||
}
|
|
||||||
nlen = PyUnicode_GET_LENGTH(ident);
|
|
||||||
plen = PyUnicode_GET_LENGTH(privateobj);
|
|
||||||
/* Don't mangle __id__ or names with dots.
|
|
||||||
|
|
||||||
The only time a name with a dot can occur is when
|
|
||||||
we are compiling an import statement that has a
|
|
||||||
package name.
|
|
||||||
|
|
||||||
TODO(jhylton): Decide whether we want to support
|
|
||||||
mangling of the module name, e.g. __M.X.
|
|
||||||
*/
|
|
||||||
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
|
|
||||||
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
|
|
||||||
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
|
|
||||||
return Py_NewRef(ident); /* Don't mangle __whatever__ */
|
|
||||||
}
|
|
||||||
/* Strip leading underscores from class name */
|
|
||||||
ipriv = 0;
|
|
||||||
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_')
|
|
||||||
ipriv++;
|
|
||||||
if (ipriv == plen) {
|
|
||||||
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
|
|
||||||
}
|
|
||||||
plen -= ipriv;
|
|
||||||
|
|
||||||
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
|
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
|
||||||
"private identifier too large to be mangled");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
|
|
||||||
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar)
|
|
||||||
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
|
|
||||||
|
|
||||||
result = PyUnicode_New(1 + nlen + plen, maxchar);
|
|
||||||
if (!result) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
|
|
||||||
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
|
|
||||||
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
|
|
||||||
Py_DECREF(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
|
|
||||||
Py_DECREF(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
assert(_PyUnicode_CheckConsistency(result, 1));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,
|
compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ast.h" // identifier, stmt_ty
|
#include "pycore_ast.h" // identifier, stmt_ty
|
||||||
#include "pycore_compile.h" // _Py_Mangle(), _PyFuture_FromAST()
|
|
||||||
#include "pycore_parser.h" // _PyParser_ASTFromString()
|
#include "pycore_parser.h" // _PyParser_ASTFromString()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
#include "pycore_symtable.h" // PySTEntryObject
|
#include "pycore_symtable.h" // PySTEntryObject
|
||||||
|
@ -2152,3 +2151,69 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename,
|
||||||
_PyArena_Free(arena);
|
_PyArena_Free(arena);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_Py_Mangle(PyObject *privateobj, PyObject *ident)
|
||||||
|
{
|
||||||
|
/* Name mangling: __private becomes _classname__private.
|
||||||
|
This is independent from how the name is used. */
|
||||||
|
if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
|
||||||
|
PyUnicode_READ_CHAR(ident, 0) != '_' ||
|
||||||
|
PyUnicode_READ_CHAR(ident, 1) != '_') {
|
||||||
|
return Py_NewRef(ident);
|
||||||
|
}
|
||||||
|
size_t nlen = PyUnicode_GET_LENGTH(ident);
|
||||||
|
size_t plen = PyUnicode_GET_LENGTH(privateobj);
|
||||||
|
/* Don't mangle __id__ or names with dots.
|
||||||
|
|
||||||
|
The only time a name with a dot can occur is when
|
||||||
|
we are compiling an import statement that has a
|
||||||
|
package name.
|
||||||
|
|
||||||
|
TODO(jhylton): Decide whether we want to support
|
||||||
|
mangling of the module name, e.g. __M.X.
|
||||||
|
*/
|
||||||
|
if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' &&
|
||||||
|
PyUnicode_READ_CHAR(ident, nlen-2) == '_') ||
|
||||||
|
PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) {
|
||||||
|
return Py_NewRef(ident); /* Don't mangle __whatever__ */
|
||||||
|
}
|
||||||
|
/* Strip leading underscores from class name */
|
||||||
|
size_t ipriv = 0;
|
||||||
|
while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') {
|
||||||
|
ipriv++;
|
||||||
|
}
|
||||||
|
if (ipriv == plen) {
|
||||||
|
return Py_NewRef(ident); /* Don't mangle if class is just underscores */
|
||||||
|
}
|
||||||
|
plen -= ipriv;
|
||||||
|
|
||||||
|
if (plen + nlen >= PY_SSIZE_T_MAX - 1) {
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"private identifier too large to be mangled");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(ident);
|
||||||
|
if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) {
|
||||||
|
maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *result = PyUnicode_New(1 + nlen + plen, maxchar);
|
||||||
|
if (!result) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
|
||||||
|
PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_');
|
||||||
|
if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) {
|
||||||
|
Py_DECREF(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
assert(_PyUnicode_CheckConsistency(result, 1));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue