diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2007-06-10 09:51:05 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2007-06-10 09:51:05 (GMT) |
commit | 5b222135f8d2492713994f2cb003980e87ce6a72 (patch) | |
tree | 3ac3a6a1d7805360ed779e884ca6c4b3f000321f /Include | |
parent | 38e43c25eede3fa77d90ac8183cc0335f4861f4a (diff) | |
download | cpython-5b222135f8d2492713994f2cb003980e87ce6a72.zip cpython-5b222135f8d2492713994f2cb003980e87ce6a72.tar.gz cpython-5b222135f8d2492713994f2cb003980e87ce6a72.tar.bz2 |
Make identifiers str (not str8) objects throughout.
This affects the parser, various object implementations,
and all places that put identifiers into C string literals.
In testing, a number of crashes occurred as code would
fail when the recursion limit was reached (such as the
Unicode interning dictionary having key/value pairs where
key is not value). To solve these, I added an overflowed
flag, which allows for 50 more recursions after the
limit was reached and the exception was raised, and
a recursion_critical flag, which indicates that recursion
absolutely must be allowed, i.e. that a certain call
must not cause a stack overflow exception.
There are still some places where both str and str8 are
accepted as identifiers; these should eventually be
removed.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/ceval.h | 13 | ||||
-rw-r--r-- | Include/pystate.h | 4 | ||||
-rw-r--r-- | Include/stringobject.h | 4 | ||||
-rw-r--r-- | Include/unicodeobject.h | 36 |
4 files changed, 50 insertions, 7 deletions
diff --git a/Include/ceval.h b/Include/ceval.h index 15b29c6..c9c59eb 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -50,7 +50,10 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ _Py_CheckRecursiveCall(where)) #define Py_LeaveRecursiveCall() \ - (--PyThreadState_GET()->recursion_depth) + do{ if((--PyThreadState_GET()->recursion_depth) < \ + _Py_CheckRecursionLimit - 50); \ + PyThreadState_GET()->overflowed = 0; \ + } while(0) PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where); PyAPI_DATA(int) _Py_CheckRecursionLimit; #ifdef USE_STACKCHECK @@ -59,6 +62,14 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit; # define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) #endif +#define Py_ALLOW_RECURSION \ + do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ + PyThreadState_GET()->recursion_critical = 1; + +#define Py_END_ALLOW_RECURSION \ + PyThreadState_GET()->recursion_critical = _old; \ + } while(0); + PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); diff --git a/Include/pystate.h b/Include/pystate.h index 4919d99..0681e65 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -61,6 +61,10 @@ typedef struct _ts { struct _frame *frame; int recursion_depth; + char overflowed; /* The stack has overflowed. Allow 50 more calls + to handle the runtime error. */ + char recursion_critical; /* The current calls must not cause + a stack overflow. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. This is to prevent the actual trace/profile code from being recorded in the trace/profile. */ diff --git a/Include/stringobject.h b/Include/stringobject.h index 2b8cc2f..0a932f0 100644 --- a/Include/stringobject.h +++ b/Include/stringobject.h @@ -84,8 +84,8 @@ PyAPI_FUNC(void) _Py_ReleaseInternedStrings(void); #define PyString_CHECK_INTERNED(op) (((PyStringObject *)(op))->ob_sstate) /* Macro, trading safety for speed */ -#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval) -#define PyString_GET_SIZE(op) (((PyStringObject *)(op))->ob_size) +#define PyString_AS_STRING(op) (assert(PyString_Check(op)),(((PyStringObject *)(op))->ob_sval)) +#define PyString_GET_SIZE(op) (assert(PyString_Check(op)),(((PyStringObject *)(op))->ob_size)) /* _PyString_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, x must be an iterable object. */ diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 2a27dbc..1f6b729 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -410,13 +410,13 @@ PyAPI_DATA(PyTypeObject) PyUnicode_Type; /* Fast access macros */ #define PyUnicode_GET_SIZE(op) \ - (((PyUnicodeObject *)(op))->length) + (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length)) #define PyUnicode_GET_DATA_SIZE(op) \ - (((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE)) + (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE))) #define PyUnicode_AS_UNICODE(op) \ - (((PyUnicodeObject *)(op))->str) + (assert(PyUnicode_Check(op)),(((PyUnicodeObject *)(op))->str)) #define PyUnicode_AS_DATA(op) \ - ((const char *)((PyUnicodeObject *)(op))->str) + (assert(PyUnicode_Check(op)),((const char *)((PyUnicodeObject *)(op))->str)) /* --- Constants ---------------------------------------------------------- */ @@ -627,6 +627,13 @@ PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString( PyObject *, const char *); +/* Return a char* holding the default encoded value of the + Unicode object. +*/ + +PyAPI_FUNC(char *) PyUnicode_AsString(PyObject*); + + /* Returns the currently active default encoding. The default encoding is currently implemented as run-time settable @@ -1193,6 +1200,11 @@ PyAPI_FUNC(int) PyUnicode_Compare( PyObject *right /* Right string */ ); +PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( + PyObject *left, + const char *right + ); + /* Rich compare two strings and return one of the following: - NULL in case an exception was raised @@ -1310,6 +1322,22 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UNICODE ch /* Unicode character */ ); +PyAPI_FUNC(size_t) Py_UNICODE_strlen(const Py_UNICODE *u); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy( + Py_UNICODE *s1, const Py_UNICODE *s2); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy( + Py_UNICODE *s1, const Py_UNICODE *s2, size_t n); + +PyAPI_FUNC(int) Py_UNICODE_strcmp( + const Py_UNICODE *s1, const Py_UNICODE *s2); + +PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr( + const Py_UNICODE *s, Py_UNICODE c + ); + + #ifdef __cplusplus } #endif |