diff options
| author | AlexSm <[email protected]> | 2024-02-16 11:51:30 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-16 11:51:30 +0100 |
| commit | 506ecaee93b52cc12c2e2f97c3d42e3ca2a7f59e (patch) | |
| tree | d096fb9eb988fbb0ca1ba970041773207ce3aa70 /contrib/tools/python3/src/Objects | |
| parent | 4749b9e5d260714490997e6f5ee1ee8c1c8fc46c (diff) | |
| parent | f200f72c9d7a89c1018e3dc6b46c49fe2ecf84fb (diff) | |
Merge pull request #1940 from dcherednik/importlib
Library import 14
Diffstat (limited to 'contrib/tools/python3/src/Objects')
80 files changed, 14282 insertions, 9217 deletions
diff --git a/contrib/tools/python3/src/Objects/abstract.c b/contrib/tools/python3/src/Objects/abstract.c index 93987c201b5..e95785900c9 100644 --- a/contrib/tools/python3/src/Objects/abstract.c +++ b/contrib/tools/python3/src/Objects/abstract.c @@ -5,6 +5,7 @@ #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _Py_CheckSlotResult() +#include "pycore_long.h" // _Py_IsNegative #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_unionobject.h" // _PyUnion_Check() @@ -45,8 +46,7 @@ PyObject_Type(PyObject *o) } v = (PyObject *)Py_TYPE(o); - Py_INCREF(v); - return v; + return Py_NewRef(v); } Py_ssize_t @@ -526,18 +526,12 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) Py_ssize_t PyBuffer_SizeFromFormat(const char *format) { - PyObject *structmodule = NULL; PyObject *calcsize = NULL; PyObject *res = NULL; PyObject *fmt = NULL; Py_ssize_t itemsize = -1; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) { - return itemsize; - } - - calcsize = PyObject_GetAttrString(structmodule, "calcsize"); + calcsize = _PyImport_GetModuleAttrString("struct", "calcsize"); if (calcsize == NULL) { goto done; } @@ -558,7 +552,6 @@ PyBuffer_SizeFromFormat(const char *format) } done: - Py_DECREF(structmodule); Py_XDECREF(calcsize); Py_XDECREF(fmt); Py_XDECREF(res); @@ -729,9 +722,7 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, return -1; } - view->obj = obj; - if (obj) - Py_INCREF(obj); + view->obj = Py_XNewRef(obj); view->buf = buf; view->len = len; view->readonly = readonly; @@ -783,8 +774,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* Fast path for common types. */ if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { if (PyUnicode_CheckExact(obj)) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyLong_CheckExact(obj)) { return PyObject_Str(obj); @@ -817,8 +807,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyErr_Format(PyExc_TypeError, "__format__ must return a str, not %.200s", Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto done; } @@ -1412,8 +1401,7 @@ _PyNumber_Index(PyObject *item) } if (PyLong_Check(item)) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } if (!_PyIndex_Check(item)) { PyErr_Format(PyExc_TypeError, @@ -1496,7 +1484,7 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) /* Whether or not it is less than or equal to zero is determined by the sign of ob_size */ - if (_PyLong_Sign(value) < 0) + if (_PyLong_IsNegative((PyLongObject *)value)) result = PY_SSIZE_T_MIN; else result = PY_SSIZE_T_MAX; @@ -1527,8 +1515,7 @@ PyNumber_Long(PyObject *o) } if (PyLong_CheckExact(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ @@ -2052,8 +2039,7 @@ PySequence_Tuple(PyObject *v) a tuple *subclass* instance as-is, hence the restriction to exact tuples here. In contrast, lists always make a copy, so there's no need for exactness below. */ - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyList_CheckExact(v)) return PyList_AsTuple(v); @@ -2151,8 +2137,7 @@ PySequence_Fast(PyObject *v, const char *m) } if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } it = PyObject_GetIter(v); @@ -2806,8 +2791,7 @@ PyObject_GetIter(PyObject *o) "iter() returned non-iterator " "of type '%.100s'", Py_TYPE(res)->tp_name); - Py_DECREF(res); - res = NULL; + Py_SETREF(res, NULL); } return res; } @@ -2827,8 +2811,7 @@ PyObject_GetAIter(PyObject *o) { PyErr_Format(PyExc_TypeError, "aiter() returned not an async iterator of type '%.100s'", Py_TYPE(it)->tp_name); - Py_DECREF(it); - it = NULL; + Py_SETREF(it, NULL); } return it; } diff --git a/contrib/tools/python3/src/Objects/accu.c b/contrib/tools/python3/src/Objects/accu.c deleted file mode 100644 index c8b5d382e38..00000000000 --- a/contrib/tools/python3/src/Objects/accu.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Accumulator struct implementation */ - -#include "Python.h" -#include "pycore_accu.h" - -static PyObject * -join_list_unicode(PyObject *lst) -{ - /* return ''.join(lst) */ - PyObject *sep, *ret; - sep = PyUnicode_FromStringAndSize("", 0); - ret = PyUnicode_Join(sep, lst); - Py_DECREF(sep); - return ret; -} - -int -_PyAccu_Init(_PyAccu *acc) -{ - /* Lazily allocated */ - acc->large = NULL; - acc->small = PyList_New(0); - if (acc->small == NULL) - return -1; - return 0; -} - -static int -flush_accumulator(_PyAccu *acc) -{ - Py_ssize_t nsmall = PyList_GET_SIZE(acc->small); - if (nsmall) { - int ret; - PyObject *joined; - if (acc->large == NULL) { - acc->large = PyList_New(0); - if (acc->large == NULL) - return -1; - } - joined = join_list_unicode(acc->small); - if (joined == NULL) - return -1; - if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) { - Py_DECREF(joined); - return -1; - } - ret = PyList_Append(acc->large, joined); - Py_DECREF(joined); - return ret; - } - return 0; -} - -int -_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode) -{ - Py_ssize_t nsmall; - assert(PyUnicode_Check(unicode)); - - if (PyList_Append(acc->small, unicode)) - return -1; - nsmall = PyList_GET_SIZE(acc->small); - /* Each item in a list of unicode objects has an overhead (in 64-bit - * builds) of: - * - 8 bytes for the list slot - * - 56 bytes for the header of the unicode object - * that is, 64 bytes. 100000 such objects waste more than 6 MiB - * compared to a single concatenated string. - */ - if (nsmall < 100000) - return 0; - return flush_accumulator(acc); -} - -PyObject * -_PyAccu_FinishAsList(_PyAccu *acc) -{ - int ret; - PyObject *res; - - ret = flush_accumulator(acc); - Py_CLEAR(acc->small); - if (ret) { - Py_CLEAR(acc->large); - return NULL; - } - res = acc->large; - acc->large = NULL; - return res; -} - -PyObject * -_PyAccu_Finish(_PyAccu *acc) -{ - PyObject *list, *res; - if (acc->large == NULL) { - list = acc->small; - acc->small = NULL; - } - else { - list = _PyAccu_FinishAsList(acc); - if (!list) - return NULL; - } - res = join_list_unicode(list); - Py_DECREF(list); - return res; -} - -void -_PyAccu_Destroy(_PyAccu *acc) -{ - Py_CLEAR(acc->small); - Py_CLEAR(acc->large); -} diff --git a/contrib/tools/python3/src/Objects/boolobject.c b/contrib/tools/python3/src/Objects/boolobject.c index 8a20e368d4a..f43e26f3f24 100644 --- a/contrib/tools/python3/src/Objects/boolobject.c +++ b/contrib/tools/python3/src/Objects/boolobject.c @@ -2,8 +2,11 @@ #include "Python.h" #include "pycore_object.h" // _Py_FatalRefcountError() +#include "pycore_long.h" // FALSE_TAG TRUE_TAG #include "pycore_runtime.h" // _Py_ID() +#include <stddef.h> + /* We define bool_repr to return "False" or "True" */ static PyObject * @@ -17,14 +20,7 @@ bool_repr(PyObject *self) PyObject *PyBool_FromLong(long ok) { - PyObject *result; - - if (ok) - result = Py_True; - else - result = Py_False; - Py_INCREF(result); - return result; + return ok ? Py_True : Py_False; } /* We define bool_new to always return either Py_True or Py_False */ @@ -72,6 +68,22 @@ bool_vectorcall(PyObject *type, PyObject * const*args, /* Arithmetic operations redefined to return bool if both args are bool. */ static PyObject * +bool_invert(PyObject *v) +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Bitwise inversion '~' on bool is deprecated. This " + "returns the bitwise inversion of the underlying int " + "object and is usually not what you expect from negating " + "a bool. Use the 'not' operator for boolean negation or " + "~int(x) if you really want the bitwise inversion of the " + "underlying int.", + 1) < 0) { + return NULL; + } + return PyLong_Type.tp_as_number->nb_invert(v); +} + +static PyObject * bool_and(PyObject *a, PyObject *b) { if (!PyBool_Check(a) || !PyBool_Check(b)) @@ -117,7 +129,7 @@ static PyNumberMethods bool_as_number = { 0, /* nb_positive */ 0, /* nb_absolute */ 0, /* nb_bool */ - 0, /* nb_invert */ + (unaryfunc)bool_invert, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ bool_and, /* nb_and */ @@ -143,10 +155,14 @@ static PyNumberMethods bool_as_number = { 0, /* nb_index */ }; -static void _Py_NO_RETURN -bool_dealloc(PyObject* Py_UNUSED(ignore)) +static void +bool_dealloc(PyObject *boolean) { - _Py_FatalRefcountError("deallocating True or False"); + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref Booleans out of existence. Instead, + * since bools are immortal, re-set the reference count. + */ + _Py_SetImmortal(boolean); } /* The type object for bool. Note that this cannot be subclassed! */ @@ -154,8 +170,8 @@ bool_dealloc(PyObject* Py_UNUSED(ignore)) PyTypeObject PyBool_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bool", - sizeof(struct _longobject), - 0, + offsetof(struct _longobject, long_value.ob_digit), /* tp_basicsize */ + sizeof(digit), /* tp_itemsize */ bool_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ @@ -196,11 +212,15 @@ PyTypeObject PyBool_Type = { /* The objects representing bool values False and True */ struct _longobject _Py_FalseStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 0) - { 0 } + PyObject_HEAD_INIT(&PyBool_Type) + { .lv_tag = _PyLong_FALSE_TAG, + { 0 } + } }; struct _longobject _Py_TrueStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 1) - { 1 } + PyObject_HEAD_INIT(&PyBool_Type) + { .lv_tag = _PyLong_TRUE_TAG, + { 1 } + } }; diff --git a/contrib/tools/python3/src/Objects/bytearrayobject.c b/contrib/tools/python3/src/Objects/bytearrayobject.c index 1c502030842..07c20ac6316 100644 --- a/contrib/tools/python3/src/Objects/bytearrayobject.c +++ b/contrib/tools/python3/src/Objects/bytearrayobject.c @@ -61,6 +61,7 @@ static void bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { obj->ob_exports--; + assert(obj->ob_exports >= 0); } static int @@ -313,8 +314,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) } memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len); PyBuffer_Release(&vo); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -340,8 +340,7 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) if (count < 0) count = 0; else if (count == 1) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } const Py_ssize_t mysize = Py_SIZE(self); @@ -354,8 +353,7 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) char* buf = PyByteArray_AS_STRING(self); _PyBytes_Repeat(buf, size, buf, mysize); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -1110,6 +1108,7 @@ bytearray_dealloc(PyByteArrayObject *self) #define STRINGLIB_ISSPACE Py_ISSPACE #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_MUTABLE 1 #include "stringlib/fastsearch.h" @@ -2017,7 +2016,7 @@ bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) /*[clinic input] bytearray.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytearray, breaking at line boundaries. @@ -2027,7 +2026,7 @@ true. static PyObject * bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) -/*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/ +/*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/ { return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), @@ -2156,10 +2155,9 @@ static PyObject * bytearray_sizeof_impl(PyByteArrayObject *self) /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->ob_alloc * sizeof(char); + return PyLong_FromSize_t(res); } static PySequenceMethods bytearray_as_sequence = { @@ -2484,8 +2482,7 @@ bytearray_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyByteArrayObject *)seq; + it->it_seq = (PyByteArrayObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/contrib/tools/python3/src/Objects/bytes_methods.c b/contrib/tools/python3/src/Objects/bytes_methods.c index 994fb8a73c6..33aa9c3db6e 100644 --- a/contrib/tools/python3/src/Objects/bytes_methods.c +++ b/contrib/tools/python3/src/Objects/bytes_methods.c @@ -258,9 +258,12 @@ _Py_bytes_istitle(const char *cptr, Py_ssize_t len) const unsigned char *e; int cased, previous_is_cased; - /* Shortcut for single character strings */ - if (len == 1) - return PyBool_FromLong(Py_ISUPPER(*p)); + if (len == 1) { + if (Py_ISUPPER(*p)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + } /* Special case for empty strings */ if (len == 0) @@ -431,6 +434,7 @@ _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) #define STRINGLIB(F) stringlib_##F #define STRINGLIB_CHAR char #define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_FAST_MEMCHR memchr #include "stringlib/fastsearch.h" #include "stringlib/count.h" @@ -773,7 +777,7 @@ _Py_bytes_tailmatch(const char *str, Py_ssize_t len, { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; + PyObject *subobj = NULL; int result; if (!stringlib_parse_args_finds(function_name, args, &subobj, &start, &end)) diff --git a/contrib/tools/python3/src/Objects/bytesobject.c b/contrib/tools/python3/src/Objects/bytesobject.c index 279579f6341..f3a978c86c3 100644 --- a/contrib/tools/python3/src/Objects/bytesobject.c +++ b/contrib/tools/python3/src/Objects/bytesobject.c @@ -53,8 +53,7 @@ static inline PyObject* bytes_get_empty(void) // Return a strong reference to the empty bytes string singleton. static inline PyObject* bytes_new_empty(void) { - Py_INCREF(EMPTY); - return (PyObject *)EMPTY; + return Py_NewRef(EMPTY); } @@ -126,8 +125,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) } if (size == 1 && str != NULL) { op = CHARACTER(*str & 255); - Py_INCREF(op); - return (PyObject *)op; + return Py_NewRef(op); } if (size == 0) { return bytes_new_empty(); @@ -162,8 +160,7 @@ PyBytes_FromString(const char *str) } else if (size == 1) { op = CHARACTER(*str & 255); - Py_INCREF(op); - return (PyObject *)op; + return Py_NewRef(op); } /* Inline PyObject_NewVar */ @@ -377,11 +374,7 @@ PyBytes_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyBytes_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -530,14 +523,12 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) if (PyBytes_Check(v)) { *pbuf = PyBytes_AS_STRING(v); *plen = PyBytes_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyByteArray_Check(v)) { *pbuf = PyByteArray_AS_STRING(v); *plen = PyByteArray_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } /* does it support __bytes__? */ func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); @@ -1430,13 +1421,11 @@ bytes_concat(PyObject *a, PyObject *b) /* Optimize end cases */ if (va.len == 0 && PyBytes_CheckExact(b)) { - result = b; - Py_INCREF(result); + result = Py_NewRef(b); goto done; } if (vb.len == 0 && PyBytes_CheckExact(a)) { - result = a; - Py_INCREF(result); + result = Py_NewRef(a); goto done; } @@ -1477,8 +1466,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) } size = Py_SIZE(a) * n; if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } nbytes = (size_t)size; if (nbytes + PyBytesObject_SIZE <= nbytes) { @@ -1644,8 +1632,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyBytes_GET_SIZE(self) && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else if (step == 1) { return PyBytes_FromStringAndSize( @@ -1715,8 +1702,7 @@ bytes___bytes___impl(PyBytesObject *self) /*[clinic end generated code: output=63a306a9bc0caac5 input=34ec5ddba98bd6bb]*/ { if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyBytes_FromStringAndSize(self->ob_sval, Py_SIZE(self)); @@ -1941,8 +1927,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) PyBuffer_Release(&vsep); if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -1971,8 +1956,7 @@ do_strip(PyBytesObject *self, int striptype) } if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -2140,9 +2124,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, changed = 1; } if (!changed && PyBytes_CheckExact(input_obj)) { - Py_INCREF(input_obj); - Py_DECREF(result); - result = input_obj; + Py_SETREF(result, Py_NewRef(input_obj)); } PyBuffer_Release(&del_table_view); PyBuffer_Release(&table_view); @@ -2171,8 +2153,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, } if (!changed && PyBytes_CheckExact(input_obj)) { Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; + return Py_NewRef(input_obj); } /* Fix the size of the resulting byte string */ if (inlen > 0) @@ -2264,8 +2245,7 @@ bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2303,8 +2283,7 @@ bytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2350,7 +2329,7 @@ bytes_decode_impl(PyBytesObject *self, const char *encoding, /*[clinic input] bytes.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytes, breaking at line boundaries. @@ -2360,7 +2339,7 @@ true. static PyObject * bytes_splitlines_impl(PyBytesObject *self, int keepends) -/*[clinic end generated code: output=3484149a5d880ffb input=a8b32eb01ff5a5ed]*/ +/*[clinic end generated code: output=3484149a5d880ffb input=5d7b898af2fe55c0]*/ { return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), @@ -2411,7 +2390,7 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray) if (!PyUnicode_IS_ASCII(string)) { const void *data = PyUnicode_DATA(string); - unsigned int kind = PyUnicode_KIND(string); + int kind = PyUnicode_KIND(string); Py_ssize_t i; /* search for the first non-ASCII character */ @@ -2863,8 +2842,7 @@ PyBytes_FromObject(PyObject *x) } if (PyBytes_CheckExact(x)) { - Py_INCREF(x); - return x; + return Py_NewRef(x); } /* Use the modern buffer interface */ @@ -3095,21 +3073,20 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) Py_DECREF(v); return 0; } - /* XXX UNREF/NEWREF interface should be more symmetrical */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif #ifdef Py_TRACE_REFS _Py_ForgetReference(v); #endif *pv = (PyObject *) PyObject_Realloc(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { +#ifdef Py_REF_DEBUG + _Py_DecRefTotal(_PyInterpreterState_GET()); +#endif PyObject_Free(v); PyErr_NoMemory(); return -1; } - _Py_NewReference(*pv); + _Py_NewReferenceNoTotal(*pv); sv = (PyBytesObject *) *pv; Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; @@ -3126,25 +3103,6 @@ error: } -PyStatus -_PyBytes_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyBytes_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes type"); - } - - if (PyType_Ready(&PyBytesIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes iterator type"); - } - - return _PyStatus_OK(); -} - - /*********************** Bytes Iterator ****************************/ typedef struct { @@ -3293,8 +3251,7 @@ bytes_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; + it->it_seq = (PyBytesObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/contrib/tools/python3/src/Objects/call.c b/contrib/tools/python3/src/Objects/call.c index 678d16269f2..0d548dcd5e1 100644 --- a/contrib/tools/python3/src/Objects/call.c +++ b/contrib/tools/python3/src/Objects/call.c @@ -1,21 +1,11 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgsTstate() -#include "pycore_ceval.h" // _PyEval_EvalFrame() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_dict.h" // _PyDict_FromItems() +#include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "frameobject.h" // _PyFrame_New_NoTrack() - - -static PyObject *const * -_PyStack_UnpackDict(PyThreadState *tstate, - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject **p_kwnames); - -static void -_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, - PyObject *kwnames); static PyObject * @@ -109,7 +99,9 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) PyObject * PyObject_CallNoArgs(PyObject *func) { - return _PyObject_CallNoArgs(func); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -165,6 +157,42 @@ PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs); } +static void +object_is_not_callable(PyThreadState *tstate, PyObject *callable) +{ + if (Py_IS_TYPE(callable, &PyModule_Type)) { + // >>> import pprint + // >>> pprint(thing) + // Traceback (most recent call last): + // File "<stdin>", line 1, in <module> + // TypeError: 'module' object is not callable. Did you mean: 'pprint.pprint(...)'? + PyObject *name = PyModule_GetNameObject(callable); + if (name == NULL) { + _PyErr_Clear(tstate); + goto basic_type_error; + } + PyObject *attr; + int res = _PyObject_LookupAttr(callable, name, &attr); + if (res < 0) { + _PyErr_Clear(tstate); + } + else if (res > 0 && PyCallable_Check(attr)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not callable. " + "Did you mean: '%U.%U(...)'?", + Py_TYPE(callable)->tp_name, name, name); + Py_DECREF(attr); + Py_DECREF(name); + return; + } + Py_XDECREF(attr); + Py_DECREF(name); + } +basic_type_error: + _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not callable", + Py_TYPE(callable)->tp_name); +} + PyObject * _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, @@ -179,9 +207,7 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; if (call == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not callable", - Py_TYPE(callable)->tp_name); + object_is_not_callable(tstate, callable); return NULL; } @@ -322,7 +348,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, assert(!_PyErr_Occurred(tstate)); assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); vectorcallfunc vector_func = _PyVectorcall_Function(callable); if (vector_func != NULL) { return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs); @@ -330,9 +356,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, else { call = Py_TYPE(callable)->tp_call; if (call == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not callable", - Py_TYPE(callable)->tp_name); + object_is_not_callable(tstate, callable); return NULL; } @@ -367,6 +391,7 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) PyObject * PyObject_CallOneArg(PyObject *func, PyObject *arg) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); assert(arg != NULL); PyObject *_args[2]; PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET @@ -389,6 +414,7 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, assert(nargs >= 0); PyThreadState *tstate = _PyThreadState_GET(); assert(nargs == 0 || stack != NULL); + EVAL_CALL_STAT_INC(EVAL_CALL_FUNCTION_VECTORCALL); if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) { return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); } @@ -520,7 +546,7 @@ _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, if (stack == NULL) { return NULL; } - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); if (nargs == 1 && PyTuple_Check(stack[0])) { /* Special cases for backward compatibility: - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) @@ -815,6 +841,11 @@ object_vacall(PyThreadState *tstate, PyObject *base, stack[i] = va_arg(vargs, PyObject *); } +#ifdef Py_STATS + if (PyFunction_Check(callable)) { + EVAL_CALL_STAT_INC(EVAL_CALL_API); + } +#endif /* Call the function */ result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); @@ -852,6 +883,7 @@ PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, args++; nargsf--; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD, callable); PyObject *result = _PyObject_VectorcallTstate(tstate, callable, args, nargsf, kwnames); Py_DECREF(callable); @@ -955,7 +987,7 @@ _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET. When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ -static PyObject *const * +PyObject *const * _PyStack_UnpackDict(PyThreadState *tstate, PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, PyObject **p_kwnames) @@ -991,8 +1023,7 @@ _PyStack_UnpackDict(PyThreadState *tstate, /* Copy positional arguments */ for (Py_ssize_t i = 0; i < nargs; i++) { - Py_INCREF(args[i]); - stack[i] = args[i]; + stack[i] = Py_NewRef(args[i]); } PyObject **kwstack = stack + nargs; @@ -1004,10 +1035,8 @@ _PyStack_UnpackDict(PyThreadState *tstate, unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; while (PyDict_Next(kwargs, &pos, &key, &value)) { keys_are_strings &= Py_TYPE(key)->tp_flags; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(kwnames, i, key); - kwstack[i] = value; + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(key)); + kwstack[i] = Py_NewRef(value); i++; } @@ -1027,7 +1056,7 @@ _PyStack_UnpackDict(PyThreadState *tstate, return stack; } -static void +void _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, PyObject *kwnames) { @@ -1035,6 +1064,20 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, for (Py_ssize_t i = 0; i < n; i++) { Py_DECREF(stack[i]); } + _PyStack_UnpackDict_FreeNoDecRef(stack, kwnames); +} + +void +_PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames) +{ PyMem_Free((PyObject **)stack - 1); Py_DECREF(kwnames); } + +// Export for the stable ABI +#undef PyVectorcall_NARGS +Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return _PyVectorcall_NARGS(n); +} diff --git a/contrib/tools/python3/src/Objects/capsule.c b/contrib/tools/python3/src/Objects/capsule.c index e4c3c6b4be3..a28e0304e83 100644 --- a/contrib/tools/python3/src/Objects/capsule.c +++ b/contrib/tools/python3/src/Objects/capsule.c @@ -225,8 +225,7 @@ PyCapsule_Import(const char *name, int no_block) } } else { PyObject *object2 = PyObject_GetAttrString(object, trace); - Py_DECREF(object); - object = object2; + Py_SETREF(object, object2); } if (!object) { goto EXIT; diff --git a/contrib/tools/python3/src/Objects/cellobject.c b/contrib/tools/python3/src/Objects/cellobject.c index 86a89f02e60..f516707f6f8 100644 --- a/contrib/tools/python3/src/Objects/cellobject.c +++ b/contrib/tools/python3/src/Objects/cellobject.c @@ -11,8 +11,7 @@ PyCell_New(PyObject *obj) op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); if (op == NULL) return NULL; - op->ob_ref = obj; - Py_XINCREF(obj); + op->ob_ref = Py_XNewRef(obj); _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -56,22 +55,20 @@ PyCell_Get(PyObject *op) PyErr_BadInternalCall(); return NULL; } - Py_XINCREF(((PyCellObject*)op)->ob_ref); - return PyCell_GET(op); + PyObject *value = PyCell_GET(op); + return Py_XNewRef(value); } int -PyCell_Set(PyObject *op, PyObject *obj) +PyCell_Set(PyObject *op, PyObject *value) { - PyObject* oldobj; if (!PyCell_Check(op)) { PyErr_BadInternalCall(); return -1; } - oldobj = PyCell_GET(op); - Py_XINCREF(obj); - PyCell_SET(op, obj); - Py_XDECREF(oldobj); + PyObject *old_value = PyCell_GET(op); + PyCell_SET(op, Py_XNewRef(value)); + Py_XDECREF(old_value); return 0; } @@ -136,15 +133,13 @@ cell_get_contents(PyCellObject *op, void *closure) PyErr_SetString(PyExc_ValueError, "Cell is empty"); return NULL; } - Py_INCREF(op->ob_ref); - return op->ob_ref; + return Py_NewRef(op->ob_ref); } static int cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored)) { - Py_XINCREF(obj); - Py_XSETREF(op->ob_ref, obj); + Py_XSETREF(op->ob_ref, Py_XNewRef(obj)); return 0; } diff --git a/contrib/tools/python3/src/Objects/classobject.c b/contrib/tools/python3/src/Objects/classobject.c index b9708ba0e41..12dc276f289 100644 --- a/contrib/tools/python3/src/Objects/classobject.c +++ b/contrib/tools/python3/src/Objects/classobject.c @@ -48,6 +48,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, PyObject *self = PyMethod_GET_SELF(method); PyObject *func = PyMethod_GET_FUNCTION(method); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + assert(nargs == 0 || args[nargs-1]); PyObject *result; if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { @@ -56,6 +57,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, nargs += 1; PyObject *tmp = newargs[0]; newargs[0] = self; + assert(newargs[nargs-1]); result = _PyObject_VectorcallTstate(tstate, func, newargs, nargs, kwnames); newargs[0] = tmp; @@ -113,10 +115,8 @@ PyMethod_New(PyObject *func, PyObject *self) return NULL; } im->im_weakreflist = NULL; - Py_INCREF(func); - im->im_func = func; - Py_INCREF(self); - im->im_self = self; + im->im_func = Py_NewRef(func); + im->im_self = Py_NewRef(self); im->vectorcall = method_vectorcall; _PyObject_GC_TRACK(im); return (PyObject *)im; @@ -183,7 +183,7 @@ method_getattro(PyObject *obj, PyObject *name) PyObject *descr = NULL; { - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } @@ -195,8 +195,7 @@ method_getattro(PyObject *obj, PyObject *name) if (f != NULL) return f(descr, obj, (PyObject *)Py_TYPE(obj)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } @@ -267,8 +266,7 @@ method_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -287,8 +285,7 @@ method_repr(PyMethodObject *a) } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } /* XXX Shouldn't use repr()/%R here! */ @@ -359,8 +356,7 @@ PyInstanceMethod_New(PyObject *func) { method = PyObject_GC_New(PyInstanceMethodObject, &PyInstanceMethod_Type); if (method == NULL) return NULL; - Py_INCREF(func); - method->func = func; + method->func = Py_NewRef(func); _PyObject_GC_TRACK(method); return (PyObject *)method; } @@ -401,7 +397,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) PyTypeObject *tp = Py_TYPE(self); PyObject *descr = NULL; - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } @@ -412,8 +408,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) if (f != NULL) return f(descr, self, (PyObject *)Py_TYPE(self)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } @@ -443,8 +438,7 @@ static PyObject * instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); if (obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } else return PyMethod_New(func, obj); @@ -472,8 +466,7 @@ instancemethod_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -492,8 +485,7 @@ instancemethod_repr(PyObject *self) return NULL; } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } result = PyUnicode_FromFormat("<instancemethod %V at %p>", diff --git a/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h b/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h index 0b5c01a83db..e7bf3183af8 100644 --- a/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, const char *encoding, const char *errors); @@ -10,8 +16,31 @@ static int bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytearray", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytearray", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -210,8 +239,31 @@ static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -390,8 +442,31 @@ static PyObject * bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -489,8 +564,31 @@ static PyObject * bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -843,8 +941,31 @@ static PyObject * bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -927,8 +1048,31 @@ static PyObject * bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -940,8 +1084,8 @@ bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1019,8 +1163,31 @@ static PyObject * bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -1120,4 +1287,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=033e9eb5f2bb0139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=022698e8b0faa272 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h b/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h index 7e857203417..060056dafbd 100644 --- a/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/bytesobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" "--\n" @@ -44,8 +50,31 @@ static PyObject * bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -195,8 +224,31 @@ static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -374,8 +426,31 @@ static PyObject * bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -634,8 +709,31 @@ static PyObject * bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -705,8 +803,31 @@ static PyObject * bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -718,8 +839,8 @@ bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -797,8 +918,31 @@ static PyObject * bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -836,8 +980,31 @@ static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -896,4 +1063,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=5727702e63a0a8b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31a9e4af85562612 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/classobject.c.h b/contrib/tools/python3/src/Objects/clinic/classobject.c.h index a4f190015a0..a7bac63052b 100644 --- a/contrib/tools/python3/src/Objects/clinic/classobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/classobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(method___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -32,11 +38,11 @@ static PyObject * method_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyMethod_Type; PyObject *function; PyObject *instance; - if ((type == &PyMethod_Type || - type->tp_init == PyMethod_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("method", kwargs)) { goto exit; } @@ -64,10 +70,10 @@ static PyObject * instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyInstanceMethod_Type; PyObject *function; - if ((type == &PyInstanceMethod_Type || - type->tp_init == PyInstanceMethod_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("instancemethod", kwargs)) { goto exit; } @@ -80,4 +86,4 @@ instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a230fe125f664416 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2a5e7fa5947a86cb input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/codeobject.c.h b/contrib/tools/python3/src/Objects/clinic/codeobject.c.h index 9bf9e14b17e..1034627edd7 100644 --- a/contrib/tools/python3/src/Objects/clinic/codeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/codeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" @@ -24,6 +30,7 @@ static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyCode_Type; int argcount; int posonlyargcount; int kwonlyargcount; @@ -43,8 +50,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *freevars = NULL; PyObject *cellvars = NULL; - if ((type == &PyCode_Type || - type->tp_init == PyCode_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("code", kwargs)) { goto exit; } @@ -180,8 +186,31 @@ static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 18 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_argcount), &_Py_ID(co_posonlyargcount), &_Py_ID(co_kwonlyargcount), &_Py_ID(co_nlocals), &_Py_ID(co_stacksize), &_Py_ID(co_flags), &_Py_ID(co_firstlineno), &_Py_ID(co_code), &_Py_ID(co_consts), &_Py_ID(co_names), &_Py_ID(co_varnames), &_Py_ID(co_freevars), &_Py_ID(co_cellvars), &_Py_ID(co_filename), &_Py_ID(co_name), &_Py_ID(co_qualname), &_Py_ID(co_linetable), &_Py_ID(co_exceptiontable), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_exceptiontable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[18]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int co_argcount = self->co_argcount; @@ -412,8 +441,31 @@ static PyObject * code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(oparg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"oparg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_varname_from_oparg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_varname_from_oparg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int oparg; @@ -430,4 +482,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=d1bbf51b746ca2d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ff40f7bdd3851de3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/complexobject.c.h b/contrib/tools/python3/src/Objects/clinic/complexobject.c.h index e7d8065e874..e92c6e98585 100644 --- a/contrib/tools/python3/src/Objects/clinic/complexobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/complexobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" "--\n" @@ -102,8 +108,31 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(real), &_Py_ID(imag), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"real", "imag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -131,4 +160,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=6d85094ace15677e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52e85a1e258425d6 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/descrobject.c.h b/contrib/tools/python3/src/Objects/clinic/descrobject.c.h index d248b91bf48..75706437df8 100644 --- a/contrib/tools/python3/src/Objects/clinic/descrobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/descrobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -9,8 +15,31 @@ static PyObject * mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mapping), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"mapping", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mappingproxy", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mappingproxy", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -72,8 +101,31 @@ static int property_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fget), &_Py_ID(fset), &_Py_ID(fdel), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "property", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "property", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -115,4 +167,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=916624e717862abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dc1ddfcf764ac8e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/dictobject.c.h b/contrib/tools/python3/src/Objects/clinic/dictobject.c.h index eda86c31fcc..bc2452330e4 100644 --- a/contrib/tools/python3/src/Objects/clinic/dictobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/dictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -191,4 +197,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=582766ac0154c8bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c0064abbea6091c5 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/enumobject.c.h b/contrib/tools/python3/src/Objects/clinic/enumobject.c.h index 7513c9526ac..adf78efd0d6 100644 --- a/contrib/tools/python3/src/Objects/clinic/enumobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/enumobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" "--\n" @@ -24,8 +30,31 @@ static PyObject * enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enumerate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enumerate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -62,10 +91,10 @@ static PyObject * reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyReversed_Type; PyObject *seq; - if ((type == &PyReversed_Type || - type->tp_init == PyReversed_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("reversed", kwargs)) { goto exit; } @@ -78,4 +107,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a3937b6b33499560 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aba0ddbeab1601e3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/floatobject.c.h b/contrib/tools/python3/src/Objects/clinic/floatobject.c.h index bf0748f3b3d..a99fd74e4b6 100644 --- a/contrib/tools/python3/src/Objects/clinic/floatobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/floatobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -167,12 +173,10 @@ PyDoc_STRVAR(float_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" "\n" -"Return integer ratio.\n" -"\n" -"Return a pair of integers, whose ratio is exactly equal to the original float\n" -"and with a positive denominator.\n" +"Return a pair of integers, whose ratio is exactly equal to the original float.\n" "\n" -"Raise OverflowError on infinities and a ValueError on NaNs.\n" +"The ratio is in lowest terms and has a positive denominator. Raise\n" +"OverflowError on infinities and a ValueError on NaNs.\n" "\n" ">>> (10.0).as_integer_ratio()\n" "(10, 1)\n" @@ -206,10 +210,10 @@ static PyObject * float_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyFloat_Type; PyObject *x = NULL; - if ((type == &PyFloat_Type || - type->tp_init == PyFloat_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("float", kwargs)) { goto exit; } @@ -321,4 +325,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a6e6467624a92a43 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea329577074911b9 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/funcobject.c.h b/contrib/tools/python3/src/Objects/clinic/funcobject.c.h index 17fb13fe085..c3a3a8edc39 100644 --- a/contrib/tools/python3/src/Objects/clinic/funcobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/funcobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" "--\n" @@ -27,8 +33,31 @@ static PyObject * func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(code), &_Py_ID(globals), &_Py_ID(name), &_Py_ID(argdefs), &_Py_ID(closure), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -75,4 +104,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=777cead7b1f6fad3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/listobject.c.h b/contrib/tools/python3/src/Objects/clinic/listobject.c.h index 2499383cc26..e3d6ffa9f76 100644 --- a/contrib/tools/python3/src/Objects/clinic/listobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/listobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" "--\n" @@ -166,8 +172,31 @@ static PyObject * list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(reverse), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "reverse", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sort", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sort", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *keyfunc = Py_None; @@ -186,8 +215,8 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_kwonly; } } - reverse = _PyLong_AsInt(args[1]); - if (reverse == -1 && PyErr_Occurred()) { + reverse = PyObject_IsTrue(args[1]); + if (reverse < 0) { goto exit; } skip_optional_kwonly: @@ -297,10 +326,11 @@ static int list___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + PyTypeObject *base_tp = &PyList_Type; PyObject *iterable = NULL; - if ((Py_IS_TYPE(self, &PyList_Type) || - Py_TYPE(self)->tp_new == PyList_Type.tp_new) && + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && !_PyArg_NoKeywords("list", kwargs)) { goto exit; } @@ -353,4 +383,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=eab97a76b1568a03 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2ca109d8acc775bc input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/longobject.c.h b/contrib/tools/python3/src/Objects/clinic/longobject.c.h index 59b79636bee..c26ceafbc2b 100644 --- a/contrib/tools/python3/src/Objects/clinic/longobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/longobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -9,8 +15,31 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "base", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "int", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "int", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -59,7 +88,8 @@ int___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(int___format____doc__, "__format__($self, format_spec, /)\n" "--\n" -"\n"); +"\n" +"Convert to a string according to format_spec."); #define INT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)int___format__, METH_O, int___format____doc__}, @@ -201,10 +231,9 @@ PyDoc_STRVAR(int_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" "\n" -"Return integer ratio.\n" +"Return a pair of integers, whose ratio is equal to the original int.\n" "\n" -"Return a pair of integers, whose ratio is exactly equal to the original int\n" -"and with a positive denominator.\n" +"The ratio is in lowest terms and has a positive denominator.\n" "\n" ">>> (10).as_integer_ratio()\n" "(10, 1)\n" @@ -257,8 +286,31 @@ static PyObject * int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "to_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t length = 1; @@ -348,8 +400,31 @@ static PyObject * int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(bytes), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "from_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *bytes_obj; @@ -391,4 +466,22 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=899e57c41861a8e9 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(int_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Returns True. Exists for duck type compatibility with float.is_integer."); + +#define INT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, + +static PyObject * +int_is_integer_impl(PyObject *self); + +static PyObject * +int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_is_integer_impl(self); +} +/*[clinic end generated code: output=cfdf35d916158d4f input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h b/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h index 73ef8d143b5..25a22341185 100644 --- a/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/memoryobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" "--\n" @@ -15,8 +21,31 @@ static PyObject * memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memoryview", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,6 +62,66 @@ exit: return return_value; } +PyDoc_STRVAR(memoryview__from_flags__doc__, +"_from_flags($type, /, object, flags)\n" +"--\n" +"\n" +"Create a new memoryview object which references the given object."); + +#define MEMORYVIEW__FROM_FLAGS_METHODDEF \ + {"_from_flags", _PyCFunction_CAST(memoryview__from_flags), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, memoryview__from_flags__doc__}, + +static PyObject * +memoryview__from_flags_impl(PyTypeObject *type, PyObject *object, int flags); + +static PyObject * +memoryview__from_flags(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"object", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_from_flags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *object; + int flags; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + object = args[0]; + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = memoryview__from_flags_impl(type, object, flags); + +exit: + return return_value; +} + PyDoc_STRVAR(memoryview_release__doc__, "release($self, /)\n" "--\n" @@ -68,8 +157,31 @@ static PyObject * memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(shape), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", "shape", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cast", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *format; @@ -156,8 +268,31 @@ static PyObject * memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(order), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"order", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tobytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *order = NULL; @@ -228,8 +363,31 @@ static PyObject * memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -258,4 +416,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=48be570b5e6038e3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=01613814112cedd7 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/moduleobject.c.h b/contrib/tools/python3/src/Objects/clinic/moduleobject.c.h index c1534eaee25..861bcea6215 100644 --- a/contrib/tools/python3/src/Objects/clinic/moduleobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/moduleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" "--\n" @@ -17,8 +23,31 @@ static int module___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -48,4 +77,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f897c9e4721f03f input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/odictobject.c.h b/contrib/tools/python3/src/Objects/clinic/odictobject.c.h index 5bb9952caa2..115a134e3f7 100644 --- a/contrib/tools/python3/src/Objects/clinic/odictobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/odictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" "--\n" @@ -18,8 +24,31 @@ static PyObject * OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromkeys", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromkeys", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *seq; @@ -60,8 +89,31 @@ static PyObject * OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setdefault", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -103,8 +155,31 @@ static PyObject * OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pop", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -144,8 +219,31 @@ static PyObject * OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "popitem", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popitem", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int last = 1; @@ -186,8 +284,31 @@ static PyObject * OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move_to_end", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move_to_end", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -211,4 +332,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=4182a5dab66963d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=76d85a9162d62ca8 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/structseq.c.h b/contrib/tools/python3/src/Objects/clinic/structseq.c.h index b3b4836543d..40ba18a544f 100644 --- a/contrib/tools/python3/src/Objects/clinic/structseq.c.h +++ b/contrib/tools/python3/src/Objects/clinic/structseq.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -9,8 +15,31 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sequence), &_Py_ID(dict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sequence", "dict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "structseq", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "structseq", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,4 +62,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=ed3019acf49b656c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=802d5663c7d01024 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/tupleobject.c.h b/contrib/tools/python3/src/Objects/clinic/tupleobject.c.h index 224fc0c374f..3de95759a13 100644 --- a/contrib/tools/python3/src/Objects/clinic/tupleobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/tupleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -75,10 +81,10 @@ static PyObject * tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyTuple_Type; PyObject *iterable = NULL; - if ((type == &PyTuple_Type || - type->tp_init == PyTuple_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("tuple", kwargs)) { goto exit; } @@ -112,4 +118,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=044496dc917f8a97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48a9e0834b300ac3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/typeobject.c.h b/contrib/tools/python3/src/Objects/clinic/typeobject.c.h index dee3139bd3d..dc9746abfbe 100644 --- a/contrib/tools/python3/src/Objects/clinic/typeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/typeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -198,7 +204,9 @@ PyDoc_STRVAR(object___format____doc__, "__format__($self, format_spec, /)\n" "--\n" "\n" -"Default object formatter."); +"Default object formatter.\n" +"\n" +"Return str(self) if format_spec is empty. Raise TypeError otherwise."); #define OBJECT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)object___format__, METH_O, object___format____doc__}, @@ -261,4 +269,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=a30090032b8e6195 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d2fc52440a89f2fa input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/typevarobject.c.h b/contrib/tools/python3/src/Objects/clinic/typevarobject.c.h new file mode 100644 index 00000000000..54189b98446 --- /dev/null +++ b/contrib/tools/python3/src/Objects/clinic/typevarobject.c.h @@ -0,0 +1,786 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(typevar_new__doc__, +"typevar(name, *constraints, *, bound=None, covariant=False,\n" +" contravariant=False, infer_variance=False)\n" +"--\n" +"\n" +"Create a TypeVar."); + +static PyObject * +typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, + PyObject *bound, int covariant, int contravariant, + int infer_variance); + +static PyObject * +typevar_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typevar", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[6]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; + PyObject *name; + PyObject *constraints = NULL; + PyObject *bound = Py_None; + int covariant = 0; + int contravariant = 0; + int infer_variance = 0; + + fastargs = _PyArg_UnpackKeywordsWithVararg(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, 1, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typevar", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + constraints = fastargs[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[2]) { + bound = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + covariant = PyObject_IsTrue(fastargs[3]); + if (covariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[4]) { + contravariant = PyObject_IsTrue(fastargs[4]); + if (contravariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + infer_variance = PyObject_IsTrue(fastargs[5]); + if (infer_variance < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = typevar_new_impl(type, name, constraints, bound, covariant, contravariant, infer_variance); + +exit: + Py_XDECREF(constraints); + return return_value; +} + +PyDoc_STRVAR(typevar_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define TYPEVAR_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(typevar_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevar_typing_subst__doc__}, + +static PyObject * +typevar_typing_subst_impl(typevarobject *self, PyObject *arg); + +static PyObject * +typevar_typing_subst(typevarobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = typevar_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevar_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEVAR_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typevar_reduce, METH_NOARGS, typevar_reduce__doc__}, + +static PyObject * +typevar_reduce_impl(typevarobject *self); + +static PyObject * +typevar_reduce(typevarobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typevar_reduce_impl(self); +} + +PyDoc_STRVAR(paramspecargs_new__doc__, +"paramspecargs(origin)\n" +"--\n" +"\n" +"Create a ParamSpecArgs object."); + +static PyObject * +paramspecargs_new_impl(PyTypeObject *type, PyObject *origin); + +static PyObject * +paramspecargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(origin), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"origin", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspecargs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *origin; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + origin = fastargs[0]; + return_value = paramspecargs_new_impl(type, origin); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspeckwargs_new__doc__, +"paramspeckwargs(origin)\n" +"--\n" +"\n" +"Create a ParamSpecKwargs object."); + +static PyObject * +paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin); + +static PyObject * +paramspeckwargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(origin), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"origin", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspeckwargs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *origin; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + origin = fastargs[0]; + return_value = paramspeckwargs_new_impl(type, origin); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_new__doc__, +"paramspec(name, *, bound=None, covariant=False, contravariant=False,\n" +" infer_variance=False)\n" +"--\n" +"\n" +"Create a ParamSpec object."); + +static PyObject * +paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound, + int covariant, int contravariant, int infer_variance); + +static PyObject * +paramspec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspec", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; + PyObject *name; + PyObject *bound = Py_None; + int covariant = 0; + int contravariant = 0; + int infer_variance = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("paramspec", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + bound = fastargs[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + covariant = PyObject_IsTrue(fastargs[2]); + if (covariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + contravariant = PyObject_IsTrue(fastargs[3]); + if (contravariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + infer_variance = PyObject_IsTrue(fastargs[4]); + if (infer_variance < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = paramspec_new_impl(type, name, bound, covariant, contravariant, infer_variance); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define PARAMSPEC_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(paramspec_typing_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_subst__doc__}, + +static PyObject * +paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg); + +static PyObject * +paramspec_typing_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = paramspec_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_typing_prepare_subst__doc__, +"__typing_prepare_subst__($self, /, alias, args)\n" +"--\n" +"\n"); + +#define PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF \ + {"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_prepare_subst__doc__}, + +static PyObject * +paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, + PyObject *args); + +static PyObject * +paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"alias", "args", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_prepare_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *alias; + PyObject *__clinic_args; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + alias = args[0]; + __clinic_args = args[1]; + return_value = paramspec_typing_prepare_subst_impl(self, alias, __clinic_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define PARAMSPEC_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)paramspec_reduce, METH_NOARGS, paramspec_reduce__doc__}, + +static PyObject * +paramspec_reduce_impl(paramspecobject *self); + +static PyObject * +paramspec_reduce(paramspecobject *self, PyObject *Py_UNUSED(ignored)) +{ + return paramspec_reduce_impl(self); +} + +PyDoc_STRVAR(typevartuple__doc__, +"typevartuple(name)\n" +"--\n" +"\n" +"Create a new TypeVarTuple with the given name."); + +static PyObject * +typevartuple_impl(PyTypeObject *type, PyObject *name); + +static PyObject * +typevartuple(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typevartuple", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *name; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typevartuple", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + return_value = typevartuple_impl(type, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(typevartuple_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_subst__doc__}, + +static PyObject * +typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg); + +static PyObject * +typevartuple_typing_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = typevartuple_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_typing_prepare_subst__doc__, +"__typing_prepare_subst__($self, /, alias, args)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF \ + {"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_prepare_subst__doc__}, + +static PyObject * +typevartuple_typing_prepare_subst_impl(typevartupleobject *self, + PyObject *alias, PyObject *args); + +static PyObject * +typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"alias", "args", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_prepare_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *alias; + PyObject *__clinic_args; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + alias = args[0]; + __clinic_args = args[1]; + return_value = typevartuple_typing_prepare_subst_impl(self, alias, __clinic_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typevartuple_reduce, METH_NOARGS, typevartuple_reduce__doc__}, + +static PyObject * +typevartuple_reduce_impl(typevartupleobject *self); + +static PyObject * +typevartuple_reduce(typevartupleobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typevartuple_reduce_impl(self); +} + +PyDoc_STRVAR(typealias_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEALIAS_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typealias_reduce, METH_NOARGS, typealias_reduce__doc__}, + +static PyObject * +typealias_reduce_impl(typealiasobject *self); + +static PyObject * +typealias_reduce(typealiasobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typealias_reduce_impl(self); +} + +PyDoc_STRVAR(typealias_new__doc__, +"typealias(name, value, *, type_params=<unrepresentable>)\n" +"--\n" +"\n" +"Create a TypeAliasType."); + +static PyObject * +typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, + PyObject *type_params); + +static PyObject * +typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(value), &_Py_ID(type_params), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "value", "type_params", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typealias", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2; + PyObject *name; + PyObject *value; + PyObject *type_params = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typealias", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + value = fastargs[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + type_params = fastargs[2]; +skip_optional_kwonly: + return_value = typealias_new_impl(type, name, value, type_params); + +exit: + return return_value; +} +/*[clinic end generated code: output=807bcd30ebd10ac3 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h b/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h index 0f1dd7c2b92..27cbf9d1543 100644 --- a/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h +++ b/contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EncodingMap_size__doc__, "size($self, /)\n" "--\n" @@ -154,8 +160,31 @@ static PyObject * unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -224,8 +253,31 @@ static PyObject * unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -904,8 +956,31 @@ static PyObject * unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1003,8 +1078,31 @@ static PyObject * unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1061,8 +1159,31 @@ static PyObject * unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -1074,8 +1195,8 @@ unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1295,8 +1416,31 @@ static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "str", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "str", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -1355,4 +1499,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=c25ec2c388409c94 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d8f67f37fdbe21c4 input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/codeobject.c b/contrib/tools/python3/src/Objects/codeobject.c index 58817117243..5e358825d89 100644 --- a/contrib/tools/python3/src/Objects/codeobject.c +++ b/contrib/tools/python3/src/Objects/codeobject.c @@ -4,12 +4,108 @@ #include "opcode.h" #include "structmember.h" // PyMemberDef #include "pycore_code.h" // _PyCodeConstructor +#include "pycore_frame.h" // FRAME_SPECIALS_SIZE #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs #include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" +static PyObject* code_repr(PyCodeObject *co); + +static const char * +code_event_name(PyCodeEvent event) { + switch (event) { + #define CASE(op) \ + case PY_CODE_EVENT_##op: \ + return "PY_CODE_EVENT_" #op; + PY_FOREACH_CODE_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +static void +notify_code_watchers(PyCodeEvent event, PyCodeObject *co) +{ + assert(Py_REFCNT(co) > 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + uint8_t bits = interp->active_code_watchers; + int i = 0; + while (bits) { + assert(i < CODE_MAX_WATCHERS); + if (bits & 1) { + PyCode_WatchCallback cb = interp->code_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, co) < 0) { + // Don't risk resurrecting the object if an unraisablehook keeps + // a reference; pass a string as context. + PyObject *context = NULL; + PyObject *repr = code_repr(co); + if (repr) { + context = PyUnicode_FromFormat( + "%s watcher callback for %U", + code_event_name(event), repr); + Py_DECREF(repr); + } + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + i++; + bits >>= 1; + } +} + +int +PyCode_AddWatcher(PyCode_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + + for (int i = 0; i < CODE_MAX_WATCHERS; i++) { + if (!interp->code_watchers[i]) { + interp->code_watchers[i] = callback; + interp->active_code_watchers |= (1 << i); + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more code watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= CODE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid code watcher ID %d", watcher_id); + return -1; + } + if (!interp->code_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No code watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyCode_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->code_watchers[watcher_id] = NULL; + interp->active_code_watchers &= ~(1 << watcher_id); + return 0; +} /****************** * generic helpers @@ -149,7 +245,22 @@ validate_and_copy_tuple(PyObject *tup) return newtuple; } +static int +init_co_cached(PyCodeObject *self) { + if (self->_co_cached == NULL) { + self->_co_cached = PyMem_New(_PyCoCached, 1); + if (self->_co_cached == NULL) { + PyErr_NoMemory(); + return -1; + } + self->_co_cached->_co_code = NULL; + self->_co_cached->_co_cellvars = NULL; + self->_co_cached->_co_freevars = NULL; + self->_co_cached->_co_varnames = NULL; + } + return 0; +} /****************** * _PyCode_New() ******************/ @@ -159,18 +270,16 @@ void _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind, PyObject *names, PyObject *kinds) { - Py_INCREF(name); - PyTuple_SET_ITEM(names, offset, name); + PyTuple_SET_ITEM(names, offset, Py_NewRef(name)); _PyLocals_SetKind(kinds, offset, kind); } static void get_localsplus_counts(PyObject *names, PyObject *kinds, - int *pnlocals, int *pnplaincellvars, int *pncellvars, + int *pnlocals, int *pncellvars, int *pnfreevars) { int nlocals = 0; - int nplaincellvars = 0; int ncellvars = 0; int nfreevars = 0; Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names); @@ -184,7 +293,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, } else if (kind & CO_FAST_CELL) { ncellvars += 1; - nplaincellvars += 1; } else if (kind & CO_FAST_FREE) { nfreevars += 1; @@ -193,9 +301,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, if (pnlocals != NULL) { *pnlocals = nlocals; } - if (pnplaincellvars != NULL) { - *pnplaincellvars = nplaincellvars; - } if (pncellvars != NULL) { *pncellvars = ncellvars; } @@ -219,8 +324,7 @@ get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num) } assert(index < num); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset); - Py_INCREF(name); - PyTuple_SET_ITEM(names, index, name); + PyTuple_SET_ITEM(names, index, Py_NewRef(name)); index += 1; } assert(index == num); @@ -271,7 +375,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con) * here to avoid the possibility of overflow (however remote). */ int nlocals; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, NULL, NULL, NULL); + &nlocals, NULL, NULL); int nplainlocals = nlocals - con->argcount - con->kwonlyargcount - @@ -285,35 +389,29 @@ _PyCode_Validate(struct _PyCodeConstructor *con) return 0; } +extern void _PyCode_Quicken(PyCodeObject *code); + static void init_code(PyCodeObject *co, struct _PyCodeConstructor *con) { int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames); - int nlocals, nplaincellvars, ncellvars, nfreevars; + int nlocals, ncellvars, nfreevars; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, &nplaincellvars, &ncellvars, &nfreevars); + &nlocals, &ncellvars, &nfreevars); - Py_INCREF(con->filename); - co->co_filename = con->filename; - Py_INCREF(con->name); - co->co_name = con->name; - Py_INCREF(con->qualname); - co->co_qualname = con->qualname; + co->co_filename = Py_NewRef(con->filename); + co->co_name = Py_NewRef(con->name); + co->co_qualname = Py_NewRef(con->qualname); co->co_flags = con->flags; co->co_firstlineno = con->firstlineno; - Py_INCREF(con->linetable); - co->co_linetable = con->linetable; + co->co_linetable = Py_NewRef(con->linetable); - Py_INCREF(con->consts); - co->co_consts = con->consts; - Py_INCREF(con->names); - co->co_names = con->names; + co->co_consts = Py_NewRef(con->consts); + co->co_names = Py_NewRef(con->names); - Py_INCREF(con->localsplusnames); - co->co_localsplusnames = con->localsplusnames; - Py_INCREF(con->localspluskinds); - co->co_localspluskinds = con->localspluskinds; + co->co_localsplusnames = Py_NewRef(con->localsplusnames); + co->co_localspluskinds = Py_NewRef(con->localspluskinds); co->co_argcount = con->argcount; co->co_posonlyargcount = con->posonlyargcount; @@ -321,32 +419,35 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_stacksize = con->stacksize; - Py_INCREF(con->exceptiontable); - co->co_exceptiontable = con->exceptiontable; + co->co_exceptiontable = Py_NewRef(con->exceptiontable); /* derived values */ co->co_nlocalsplus = nlocalsplus; co->co_nlocals = nlocals; - co->co_nplaincellvars = nplaincellvars; + co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE; co->co_ncellvars = ncellvars; co->co_nfreevars = nfreevars; - + co->co_version = _Py_next_func_version; + if (_Py_next_func_version != 0) { + _Py_next_func_version++; + } + co->_co_monitoring = NULL; + co->_co_instrumentation_version = 0; /* not set */ co->co_weakreflist = NULL; co->co_extra = NULL; - co->_co_code = NULL; + co->_co_cached = NULL; - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; - co->_co_linearray_entry_size = 0; - co->_co_linearray = NULL; memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code), PyBytes_GET_SIZE(con->code)); int entry_point = 0; while (entry_point < Py_SIZE(co) && - _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) { + _PyCode_CODE(co)[entry_point].op.code != RESUME) { entry_point++; } co->_co_firsttraceable = entry_point; + _PyCode_Quicken(co); + notify_code_watchers(PY_CODE_EVENT_CREATE, co); } static int @@ -495,7 +596,8 @@ _PyCode_New(struct _PyCodeConstructor *con) ******************/ PyCodeObject * -PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, +PyUnstable_Code_NewWithPosOnlyArgs( + int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -563,6 +665,35 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, _Py_set_localsplus_info(offset, name, CO_FAST_FREE, localsplusnames, localspluskinds); } + + // gh-110543: Make sure the CO_FAST_HIDDEN flag is set correctly. + if (!(flags & CO_OPTIMIZED)) { + Py_ssize_t code_len = PyBytes_GET_SIZE(code); + _Py_CODEUNIT *code_data = (_Py_CODEUNIT *)PyBytes_AS_STRING(code); + Py_ssize_t num_code_units = code_len / sizeof(_Py_CODEUNIT); + int extended_arg = 0; + for (int i = 0; i < num_code_units; i += 1 + _PyOpcode_Caches[code_data[i].op.code]) { + _Py_CODEUNIT *instr = &code_data[i]; + uint8_t opcode = instr->op.code; + if (opcode == EXTENDED_ARG) { + extended_arg = extended_arg << 8 | instr->op.arg; + continue; + } + if (opcode == LOAD_FAST_AND_CLEAR) { + int oparg = extended_arg << 8 | instr->op.arg; + if (oparg >= nlocalsplus) { + PyErr_Format(PyExc_ValueError, + "code: LOAD_FAST_AND_CLEAR oparg %d out of range", + oparg); + goto error; + } + _PyLocals_Kind kind = _PyLocals_GetKind(localspluskinds, oparg); + _PyLocals_SetKind(localspluskinds, oparg, kind | CO_FAST_HIDDEN); + } + extended_arg = 0; + } + } + // If any cells were args then nlocalsplus will have shrunk. if (nlocalsplus != PyTuple_GET_SIZE(localsplusnames)) { if (_PyTuple_Resize(&localsplusnames, nlocalsplus) < 0 @@ -619,7 +750,7 @@ error: } PyCodeObject * -PyCode_New(int argcount, int kwonlyargcount, +PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -714,54 +845,6 @@ failed: * source location tracking (co_lines/co_positions) ******************/ -/* Use co_linetable to compute the line number from a bytecode index, addrq. See - lnotab_notes.txt for the details of the lnotab representation. -*/ - -int -_PyCode_CreateLineArray(PyCodeObject *co) -{ - assert(co->_co_linearray == NULL); - PyCodeAddressRange bounds; - int size; - int max_line = 0; - _PyCode_InitAddressRange(co, &bounds); - while(_PyLineTable_NextAddressRange(&bounds)) { - if (bounds.ar_line > max_line) { - max_line = bounds.ar_line; - } - } - if (max_line < (1 << 15)) { - size = 2; - } - else { - size = 4; - } - co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size); - if (co->_co_linearray == NULL) { - PyErr_NoMemory(); - return -1; - } - co->_co_linearray_entry_size = size; - _PyCode_InitAddressRange(co, &bounds); - while(_PyLineTable_NextAddressRange(&bounds)) { - int start = bounds.ar_start / sizeof(_Py_CODEUNIT); - int end = bounds.ar_end / sizeof(_Py_CODEUNIT); - for (int index = start; index < end; index++) { - assert(index < (int)Py_SIZE(co)); - if (size == 2) { - assert(((int16_t)bounds.ar_line) == bounds.ar_line); - ((int16_t *)co->_co_linearray)[index] = bounds.ar_line; - } - else { - assert(size == 4); - ((int32_t *)co->_co_linearray)[index] = bounds.ar_line; - } - } - } - return 0; -} - int PyCode_Addr2Line(PyCodeObject *co, int addrq) { @@ -769,9 +852,6 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) return co->co_firstlineno; } assert(addrq >= 0 && addrq <= _PyCode_NBYTES(co)); - if (co->_co_linearray) { - return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT)); - } PyCodeAddressRange bounds; _PyCode_InitAddressRange(co, &bounds); return _PyCode_CheckLineNumber(addrq, &bounds); @@ -1025,33 +1105,6 @@ _PyLineTable_NextAddressRange(PyCodeAddressRange *range) return 1; } -int -_PyLineTable_StartsLine(PyCodeAddressRange *range) -{ - if (range->ar_start <= 0) { - return 0; - } - const uint8_t *ptr = range->opaque.lo_next; - do { - ptr--; - } while (((*ptr) & 128) == 0); - int code = ((*ptr)>> 3) & 15; - switch(code) { - case PY_CODE_LOCATION_INFO_LONG: - return 0; - case PY_CODE_LOCATION_INFO_NO_COLUMNS: - case PY_CODE_LOCATION_INFO_NONE: - return ptr[1] != 0; - case PY_CODE_LOCATION_INFO_ONE_LINE0: - return 0; - case PY_CODE_LOCATION_INFO_ONE_LINE1: - case PY_CODE_LOCATION_INFO_ONE_LINE2: - return 1; - default: - return 0; - } -} - static int emit_pair(PyObject **bytes, int *offset, int a, int b) { @@ -1139,41 +1192,34 @@ lineiter_dealloc(lineiterator *li) } static PyObject * +_source_offset_converter(int *value) { + if (*value == -1) { + Py_RETURN_NONE; + } + return PyLong_FromLong(*value); +} + +static PyObject * lineiter_next(lineiterator *li) { PyCodeAddressRange *bounds = &li->li_line; if (!_PyLineTable_NextAddressRange(bounds)) { return NULL; } - PyObject *start = NULL; - PyObject *end = NULL; - PyObject *line = NULL; - PyObject *result = PyTuple_New(3); - start = PyLong_FromLong(bounds->ar_start); - end = PyLong_FromLong(bounds->ar_end); - if (bounds->ar_line < 0) { - Py_INCREF(Py_None); - line = Py_None; - } - else { - line = PyLong_FromLong(bounds->ar_line); - } - if (result == NULL || start == NULL || end == NULL || line == NULL) { - goto error; + int start = bounds->ar_start; + int line = bounds->ar_line; + // Merge overlapping entries: + while (_PyLineTable_NextAddressRange(bounds)) { + if (bounds->ar_line != line) { + _PyLineTable_PreviousAddressRange(bounds); + break; + } } - PyTuple_SET_ITEM(result, 0, start); - PyTuple_SET_ITEM(result, 1, end); - PyTuple_SET_ITEM(result, 2, line); - return result; -error: - Py_XDECREF(start); - Py_XDECREF(end); - Py_XDECREF(line); - Py_XDECREF(result); - return result; + return Py_BuildValue("iiO&", start, bounds->ar_end, + _source_offset_converter, &line); } -static PyTypeObject LineIterator = { +PyTypeObject _PyLineIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "line_iterator", /* tp_name */ sizeof(lineiterator), /* tp_basicsize */ @@ -1219,12 +1265,11 @@ static PyTypeObject LineIterator = { static lineiterator * new_linesiterator(PyCodeObject *code) { - lineiterator *li = (lineiterator *)PyType_GenericAlloc(&LineIterator, 0); + lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0); if (li == NULL) { return NULL; } - Py_INCREF(code); - li->li_code = code; + li->li_code = (PyCodeObject*)Py_NewRef(code); _PyCode_InitAddressRange(code, &li->li_line); return li; } @@ -1248,14 +1293,6 @@ positionsiter_dealloc(positionsiterator* pi) } static PyObject* -_source_offset_converter(int* value) { - if (*value == -1) { - Py_RETURN_NONE; - } - return PyLong_FromLong(*value); -} - -static PyObject* positionsiter_next(positionsiterator* pi) { if (pi->pi_offset >= pi->pi_range.ar_end) { @@ -1273,7 +1310,7 @@ positionsiter_next(positionsiterator* pi) _source_offset_converter, &pi->pi_endcolumn); } -static PyTypeObject PositionsIterator = { +PyTypeObject _PyPositionsIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "positions_iterator", /* tp_name */ sizeof(positionsiterator), /* tp_basicsize */ @@ -1319,12 +1356,11 @@ static PyTypeObject PositionsIterator = { static PyObject* code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args)) { - positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&PositionsIterator, 0); + positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0); if (pi == NULL) { return NULL; } - Py_INCREF(code); - pi->pi_code = code; + pi->pi_code = (PyCodeObject*)Py_NewRef(code); _PyCode_InitAddressRange(code, &pi->pi_range); pi->pi_offset = pi->pi_range.ar_end; return (PyObject*)pi; @@ -1343,7 +1379,7 @@ typedef struct { int -_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) +PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra) { if (!PyCode_Check(code)) { PyErr_BadInternalCall(); @@ -1364,7 +1400,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) int -_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) +PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra) { PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -1409,10 +1445,31 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) * other PyCodeObject accessor functions ******************/ +static PyObject * +get_cached_locals(PyCodeObject *co, PyObject **cached_field, + _PyLocals_Kind kind, int num) +{ + assert(cached_field != NULL); + assert(co->_co_cached != NULL); + if (*cached_field != NULL) { + return Py_NewRef(*cached_field); + } + assert(*cached_field == NULL); + PyObject *varnames = get_localsplus_names(co, kind, num); + if (varnames == NULL) { + return NULL; + } + *cached_field = Py_NewRef(varnames); + return varnames; +} + PyObject * _PyCode_GetVarnames(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_varnames, CO_FAST_LOCAL, co->co_nlocals); } PyObject * @@ -1424,7 +1481,10 @@ PyCode_GetVarnames(PyCodeObject *code) PyObject * _PyCode_GetCellvars(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_cellvars, CO_FAST_CELL, co->co_ncellvars); } PyObject * @@ -1436,7 +1496,10 @@ PyCode_GetCellvars(PyCodeObject *code) PyObject * _PyCode_GetFreevars(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_freevars, CO_FAST_FREE, co->co_nfreevars); } PyObject * @@ -1446,33 +1509,37 @@ PyCode_GetFreevars(PyCodeObject *code) } static void -deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) +deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions) { + Py_ssize_t len = Py_SIZE(code); for (int i = 0; i < len; i++) { - _Py_CODEUNIT instruction = instructions[i]; - int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + int opcode = _Py_GetBaseOpcode(code, i); int caches = _PyOpcode_Caches[opcode]; - instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction)); - while (caches--) { - instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0); + instructions[i].op.code = opcode; + for (int j = 1; j <= caches; j++) { + instructions[i+j].cache = 0; } + i += caches; } } PyObject * _PyCode_GetCode(PyCodeObject *co) { - if (co->_co_code != NULL) { - return Py_NewRef(co->_co_code); + if (init_co_cached(co)) { + return NULL; + } + if (co->_co_cached->_co_code != NULL) { + return Py_NewRef(co->_co_cached->_co_code); } PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co), _PyCode_NBYTES(co)); if (code == NULL) { return NULL; } - deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co)); - assert(co->_co_code == NULL); - co->_co_code = Py_NewRef(code); + deopt_code(co, (_Py_CODEUNIT *)PyBytes_AS_STRING(code)); + assert(co->_co_cached->_co_code == NULL); + co->_co_cached->_co_code = Py_NewRef(code); return code; } @@ -1605,8 +1672,41 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, } static void +free_monitoring_data(_PyCoMonitoringData *data) +{ + if (data == NULL) { + return; + } + if (data->tools) { + PyMem_Free(data->tools); + } + if (data->lines) { + PyMem_Free(data->lines); + } + if (data->line_tools) { + PyMem_Free(data->line_tools); + } + if (data->per_instruction_opcodes) { + PyMem_Free(data->per_instruction_opcodes); + } + if (data->per_instruction_tools) { + PyMem_Free(data->per_instruction_tools); + } + PyMem_Free(data); +} + +static void code_dealloc(PyCodeObject *co) { + assert(Py_REFCNT(co) == 0); + Py_SET_REFCNT(co, 1); + notify_code_watchers(PY_CODE_EVENT_DESTROY, co); + if (Py_REFCNT(co) > 1) { + Py_SET_REFCNT(co, Py_REFCNT(co) - 1); + return; + } + Py_SET_REFCNT(co, 0); + if (co->co_extra != NULL) { PyInterpreterState *interp = _PyInterpreterState_GET(); _PyCodeObjectExtra *co_extra = co->co_extra; @@ -1631,16 +1731,17 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_qualname); Py_XDECREF(co->co_linetable); Py_XDECREF(co->co_exceptiontable); - Py_XDECREF(co->_co_code); + if (co->_co_cached != NULL) { + Py_XDECREF(co->_co_cached->_co_code); + Py_XDECREF(co->_co_cached->_co_cellvars); + Py_XDECREF(co->_co_cached->_co_freevars); + Py_XDECREF(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + } if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)co); } - if (co->_co_linearray) { - PyMem_Free(co->_co_linearray); - } - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } + free_monitoring_data(co->_co_monitoring); PyObject_Free(co); } @@ -1699,13 +1800,13 @@ code_richcompare(PyObject *self, PyObject *other, int op) for (int i = 0; i < Py_SIZE(co); i++) { _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; - _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]); - _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]); - eq = co_instr == cp_instr; + co_instr.op.code = _Py_GetBaseOpcode(co, i); + cp_instr.op.code = _Py_GetBaseOpcode(cp, i); + eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal; } - i += _PyOpcode_Caches[_Py_OPCODE(co_instr)]; + i += _PyOpcode_Caches[co_instr.op.code]; } /* compare constants */ @@ -1752,35 +1853,47 @@ code_richcompare(PyObject *self, PyObject *other, int op) res = Py_False; done: - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t code_hash(PyCodeObject *co) { - Py_hash_t h, h0, h1, h2, h3; - h0 = PyObject_Hash(co->co_name); - if (h0 == -1) return -1; - h1 = PyObject_Hash(co->co_consts); - if (h1 == -1) return -1; - h2 = PyObject_Hash(co->co_names); - if (h2 == -1) return -1; - h3 = PyObject_Hash(co->co_localsplusnames); - if (h3 == -1) return -1; - Py_hash_t h4 = PyObject_Hash(co->co_linetable); - if (h4 == -1) { - return -1; + Py_uhash_t uhash = 20221211; + #define SCRAMBLE_IN(H) do { \ + uhash ^= (Py_uhash_t)(H); \ + uhash *= _PyHASH_MULTIPLIER; \ + } while (0) + #define SCRAMBLE_IN_HASH(EXPR) do { \ + Py_hash_t h = PyObject_Hash(EXPR); \ + if (h == -1) { \ + return -1; \ + } \ + SCRAMBLE_IN(h); \ + } while (0) + + SCRAMBLE_IN_HASH(co->co_name); + SCRAMBLE_IN_HASH(co->co_consts); + SCRAMBLE_IN_HASH(co->co_names); + SCRAMBLE_IN_HASH(co->co_localsplusnames); + SCRAMBLE_IN_HASH(co->co_linetable); + SCRAMBLE_IN_HASH(co->co_exceptiontable); + SCRAMBLE_IN(co->co_argcount); + SCRAMBLE_IN(co->co_posonlyargcount); + SCRAMBLE_IN(co->co_kwonlyargcount); + SCRAMBLE_IN(co->co_flags); + SCRAMBLE_IN(co->co_firstlineno); + SCRAMBLE_IN(Py_SIZE(co)); + for (int i = 0; i < Py_SIZE(co); i++) { + int deop = _Py_GetBaseOpcode(co, i); + SCRAMBLE_IN(deop); + SCRAMBLE_IN(_PyCode_CODE(co)[i].op.arg); + i += _PyOpcode_Caches[deop]; } - Py_hash_t h5 = PyObject_Hash(co->co_exceptiontable); - if (h5 == -1) { - return -1; + if ((Py_hash_t)uhash == -1) { + return -2; } - h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ - co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ - co->co_flags; - if (h == -1) h = -2; - return h; + return (Py_hash_t)uhash; } @@ -1808,6 +1921,11 @@ static PyMemberDef code_memberlist[] = { static PyObject * code_getlnotab(PyCodeObject *code, void *closure) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "co_lnotab is deprecated, use co_lines instead.", + 1) < 0) { + return NULL; + } return decode_linetable(code); } @@ -1857,15 +1975,13 @@ static PyGetSetDef code_getsetlist[] = { static PyObject * code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { - Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); - + size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; if (co_extra != NULL) { - res += sizeof(_PyCodeObjectExtra) + - (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); + res += sizeof(_PyCodeObjectExtra); + res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]); } - - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static PyObject * @@ -2006,8 +2122,7 @@ code__varname_from_oparg_impl(PyCodeObject *self, int oparg) if (name == NULL) { return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } /* XXX code objects need to participate in GC? */ @@ -2082,8 +2197,7 @@ _PyCode_ConstantKey(PyObject *op) { /* Objects of these types are always different from object of other * type and from tuples. */ - Py_INCREF(op); - key = op; + key = Py_NewRef(op); } else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { /* Make booleans different from integers 0 and 1. @@ -2199,28 +2313,29 @@ _PyCode_ConstantKey(PyObject *op) } void -_PyStaticCode_Dealloc(PyCodeObject *co) +_PyStaticCode_Fini(PyCodeObject *co) { - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } - deopt_code(_PyCode_CODE(co), Py_SIZE(co)); - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; + deopt_code(co, _PyCode_CODE(co)); PyMem_Free(co->co_extra); - Py_CLEAR(co->_co_code); + if (co->_co_cached != NULL) { + Py_CLEAR(co->_co_cached->_co_code); + Py_CLEAR(co->_co_cached->_co_cellvars); + Py_CLEAR(co->_co_cached->_co_freevars); + Py_CLEAR(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + co->_co_cached = NULL; + } co->co_extra = NULL; if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *)co); co->co_weakreflist = NULL; } - if (co->_co_linearray) { - PyMem_Free(co->_co_linearray); - co->_co_linearray = NULL; - } + free_monitoring_data(co->_co_monitoring); + co->_co_monitoring = NULL; } int -_PyStaticCode_InternStrings(PyCodeObject *co) +_PyStaticCode_Init(PyCodeObject *co) { int res = intern_strings(co->co_names); if (res < 0) { @@ -2234,5 +2349,81 @@ _PyStaticCode_InternStrings(PyCodeObject *co) if (res < 0) { return -1; } + _PyCode_Quicken(co); return 0; } + +#define MAX_CODE_UNITS_PER_LOC_ENTRY 8 + +PyCodeObject * +_Py_MakeShimCode(const _PyShimCodeDef *codedef) +{ + PyObject *name = NULL; + PyObject *co_code = NULL; + PyObject *lines = NULL; + PyCodeObject *codeobj = NULL; + uint8_t *loc_table = NULL; + + name = _PyUnicode_FromASCII(codedef->cname, strlen(codedef->cname)); + if (name == NULL) { + goto cleanup; + } + co_code = PyBytes_FromStringAndSize( + (const char *)codedef->code, codedef->codelen); + if (co_code == NULL) { + goto cleanup; + } + int code_units = codedef->codelen / sizeof(_Py_CODEUNIT); + int loc_entries = (code_units + MAX_CODE_UNITS_PER_LOC_ENTRY - 1) / + MAX_CODE_UNITS_PER_LOC_ENTRY; + loc_table = PyMem_Malloc(loc_entries); + if (loc_table == NULL) { + PyErr_NoMemory(); + goto cleanup; + } + for (int i = 0; i < loc_entries-1; i++) { + loc_table[i] = 0x80 | (PY_CODE_LOCATION_INFO_NONE << 3) | 7; + code_units -= MAX_CODE_UNITS_PER_LOC_ENTRY; + } + assert(loc_entries > 0); + assert(code_units > 0 && code_units <= MAX_CODE_UNITS_PER_LOC_ENTRY); + loc_table[loc_entries-1] = 0x80 | + (PY_CODE_LOCATION_INFO_NONE << 3) | (code_units-1); + lines = PyBytes_FromStringAndSize((const char *)loc_table, loc_entries); + PyMem_Free(loc_table); + if (lines == NULL) { + goto cleanup; + } + _Py_DECLARE_STR(shim_name, "<shim>"); + struct _PyCodeConstructor con = { + .filename = &_Py_STR(shim_name), + .name = name, + .qualname = name, + .flags = CO_NEWLOCALS | CO_OPTIMIZED, + + .code = co_code, + .firstlineno = 1, + .linetable = lines, + + .consts = (PyObject *)&_Py_SINGLETON(tuple_empty), + .names = (PyObject *)&_Py_SINGLETON(tuple_empty), + + .localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty), + .localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty), + + .argcount = 0, + .posonlyargcount = 0, + .kwonlyargcount = 0, + + .stacksize = codedef->stacksize, + + .exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty), + }; + + codeobj = _PyCode_New(&con); +cleanup: + Py_XDECREF(name); + Py_XDECREF(co_code); + Py_XDECREF(lines); + return codeobj; +} diff --git a/contrib/tools/python3/src/Objects/complexobject.c b/contrib/tools/python3/src/Objects/complexobject.c index 9bd68d50c30..aee03ddfb07 100644 --- a/contrib/tools/python3/src/Objects/complexobject.c +++ b/contrib/tools/python3/src/Objects/complexobject.c @@ -449,8 +449,7 @@ to_complex(PyObject **pobj, Py_complex *pc) pc->real = PyFloat_AsDouble(obj); return 0; } - Py_INCREF(Py_NotImplemented); - *pobj = Py_NotImplemented; + *pobj = Py_NewRef(Py_NotImplemented); return -1; } @@ -553,8 +552,7 @@ static PyObject * complex_pos(PyComplexObject *v) { if (PyComplex_CheckExact(v)) { - Py_INCREF(v); - return (PyObject *)v; + return Py_NewRef(v); } else return PyComplex_FromCComplex(v->cval); @@ -631,8 +629,7 @@ complex_richcompare(PyObject *v, PyObject *w, int op) else res = Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); Unimplemented: Py_RETURN_NOTIMPLEMENTED; @@ -705,8 +702,7 @@ complex___complex___impl(PyComplexObject *self) /*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/ { if (PyComplex_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyComplex_FromCComplex(self->cval); @@ -917,8 +913,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) to exact complexes here. If either the input or the output is a complex subclass, it will be handled below as a non-orthogonal vector. */ - Py_INCREF(r); - return r; + return Py_NewRef(r); } if (PyUnicode_Check(r)) { if (i != NULL) { diff --git a/contrib/tools/python3/src/Objects/descrobject.c b/contrib/tools/python3/src/Objects/descrobject.c index 885131fb3dc..d5e88dcf1c8 100644 --- a/contrib/tools/python3/src/Objects/descrobject.c +++ b/contrib/tools/python3/src/Objects/descrobject.c @@ -6,6 +6,7 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef +#include "pycore_descrobject.h" /*[clinic input] class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" @@ -621,8 +622,7 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) { if (descr->d_qualname == NULL) descr->d_qualname = calculate_qualname(descr); - Py_XINCREF(descr->d_qualname); - return descr->d_qualname; + return Py_XNewRef(descr->d_qualname); } static PyObject * @@ -903,12 +903,10 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); if (descr != NULL) { - Py_XINCREF(type); - descr->d_type = type; + descr->d_type = (PyTypeObject*)Py_XNewRef(type); descr->d_name = PyUnicode_InternFromString(name); if (descr->d_name == NULL) { - Py_DECREF(descr); - descr = NULL; + Py_SETREF(descr, NULL); } else { descr->d_qualname = NULL; @@ -980,6 +978,12 @@ PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) { PyMemberDescrObject *descr; + if (member->flags & Py_RELATIVE_OFFSET) { + PyErr_SetString( + PyExc_SystemError, + "PyDescr_NewMember used with Py_RELATIVE_OFFSET"); + return NULL; + } descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, type, member->name); if (descr != NULL) @@ -1177,6 +1181,12 @@ mappingproxy_getiter(mappingproxyobject *pp) return PyObject_GetIter(pp->mapping); } +static Py_hash_t +mappingproxy_hash(mappingproxyobject *pp) +{ + return PyObject_Hash(pp->mapping); +} + static PyObject * mappingproxy_str(mappingproxyobject *pp) { @@ -1237,8 +1247,7 @@ mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping) mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (mappingproxy == NULL) return NULL; - Py_INCREF(mapping); - mappingproxy->mapping = mapping; + mappingproxy->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(mappingproxy); return (PyObject *)mappingproxy; } @@ -1253,8 +1262,7 @@ PyDictProxy_New(PyObject *mapping) pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (pp != NULL) { - Py_INCREF(mapping); - pp->mapping = mapping; + pp->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(pp); } return (PyObject *)pp; @@ -1354,8 +1362,7 @@ wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored)) { PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); - Py_INCREF(c); - return c; + return Py_NewRef(c); } static PyObject * @@ -1459,10 +1466,8 @@ PyWrapper_New(PyObject *d, PyObject *self) wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); if (wp != NULL) { - Py_INCREF(descr); - wp->descr = descr; - Py_INCREF(self); - wp->self = self; + wp->descr = (PyWrapperDescrObject*)Py_NewRef(descr); + wp->self = Py_NewRef(self); _PyObject_GC_TRACK(wp); } return (PyObject *)wp; @@ -1480,7 +1485,10 @@ class property(object): self.__get = fget self.__set = fset self.__del = fdel - self.__doc__ = doc + try: + self.__doc__ = doc + except AttributeError: # read-only or dict-less class + pass def __get__(self, inst, type=None): if inst is None: @@ -1501,16 +1509,6 @@ class property(object): */ -typedef struct { - PyObject_HEAD - PyObject *prop_get; - PyObject *prop_set; - PyObject *prop_del; - PyObject *prop_doc; - PyObject *prop_name; - int getter_doc; -} propertyobject; - static PyObject * property_copy(PyObject *, PyObject *, PyObject *, PyObject *); @@ -1569,8 +1567,7 @@ property_set_name(PyObject *self, PyObject *args) { propertyobject *prop = (propertyobject *)self; PyObject *name = PyTuple_GET_ITEM(args, 1); - Py_XINCREF(name); - Py_XSETREF(prop->prop_name, name); + Py_XSETREF(prop->prop_name, Py_XNewRef(name)); Py_RETURN_NONE; } @@ -1602,8 +1599,7 @@ static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == NULL || obj == Py_None) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } propertyobject *gs = (propertyobject *)self; @@ -1677,6 +1673,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) res = PyObject_CallOneArg(func, obj); } else { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); PyObject *args[] = { obj, value }; res = PyObject_Vectorcall(func, args, 2, NULL); } @@ -1723,9 +1720,9 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) Py_DECREF(type); if (new == NULL) return NULL; + if (PyObject_TypeCheck((new), &PyProperty_Type)) { - Py_XINCREF(pold->prop_name); - Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name); + Py_XSETREF(((propertyobject *) new)->prop_name, Py_XNewRef(pold->prop_name)); } return new; } @@ -1779,41 +1776,78 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, if (fdel == Py_None) fdel = NULL; - Py_XINCREF(fget); - Py_XINCREF(fset); - Py_XINCREF(fdel); - Py_XINCREF(doc); - - Py_XSETREF(self->prop_get, fget); - Py_XSETREF(self->prop_set, fset); - Py_XSETREF(self->prop_del, fdel); - Py_XSETREF(self->prop_doc, doc); + Py_XSETREF(self->prop_get, Py_XNewRef(fget)); + Py_XSETREF(self->prop_set, Py_XNewRef(fset)); + Py_XSETREF(self->prop_del, Py_XNewRef(fdel)); + Py_XSETREF(self->prop_doc, NULL); Py_XSETREF(self->prop_name, NULL); self->getter_doc = 0; + PyObject *prop_doc = NULL; + if (doc != NULL && doc != Py_None) { + prop_doc = Py_XNewRef(doc); + } /* if no docstring given and the getter has one, use that one */ - if ((doc == NULL || doc == Py_None) && fget != NULL) { - PyObject *get_doc; - int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &get_doc); + else if (fget != NULL) { + int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc); if (rc <= 0) { return rc; } - if (Py_IS_TYPE(self, &PyProperty_Type)) { - Py_XSETREF(self->prop_doc, get_doc); - } - else { - /* If this is a property subclass, put __doc__ - in dict of the subclass instance instead, - otherwise it gets shadowed by __doc__ in the - class's dict. */ + if (!Py_IS_TYPE(self, &PyProperty_Type) && + prop_doc != NULL && prop_doc != Py_None) { + // This oddity preserves the long existing behavior of surfacing + // an AttributeError when using a dict-less (__slots__) property + // subclass as a decorator on a getter method with a docstring. + // See PropertySubclassTest.test_slots_docstring_copy_exception. int err = PyObject_SetAttr( - (PyObject *)self, &_Py_ID(__doc__), get_doc); - Py_DECREF(get_doc); - if (err < 0) + (PyObject *)self, &_Py_ID(__doc__), prop_doc); + if (err < 0) { + Py_DECREF(prop_doc); // release our new reference. + return -1; + } + } + if (prop_doc == Py_None) { + prop_doc = NULL; + Py_DECREF(Py_None); + } + if (prop_doc != NULL){ + self->getter_doc = 1; + } + } + + /* At this point `prop_doc` is either NULL or + a non-None object with incremented ref counter */ + + if (Py_IS_TYPE(self, &PyProperty_Type)) { + Py_XSETREF(self->prop_doc, prop_doc); + } else { + /* If this is a property subclass, put __doc__ in the dict + or designated slot of the subclass instance instead, otherwise + it gets shadowed by __doc__ in the class's dict. */ + + if (prop_doc == NULL) { + prop_doc = Py_NewRef(Py_None); + } + int err = PyObject_SetAttr( + (PyObject *)self, &_Py_ID(__doc__), prop_doc); + Py_DECREF(prop_doc); + if (err < 0) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + // https://github.com/python/cpython/issues/98963#issuecomment-1574413319 + // Python silently dropped this doc assignment through 3.11. + // We preserve that behavior for backwards compatibility. + // + // If we ever want to deprecate this behavior, only raise a + // warning or error when proc_doc is not None so that + // property without a specific doc= still works. + return 0; + } else { return -1; + } } - self->getter_doc = 1; } return 0; @@ -1893,7 +1927,7 @@ PyTypeObject PyDictProxy_Type = { &mappingproxy_as_number, /* tp_as_number */ &mappingproxy_as_sequence, /* tp_as_sequence */ &mappingproxy_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ + (hashfunc)mappingproxy_hash, /* tp_hash */ 0, /* tp_call */ (reprfunc)mappingproxy_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/contrib/tools/python3/src/Objects/dictobject.c b/contrib/tools/python3/src/Objects/dictobject.c index 69a4a865103..254cd9ad2f9 100644 --- a/contrib/tools/python3/src/Objects/dictobject.c +++ b/contrib/tools/python3/src/Objects/dictobject.c @@ -119,7 +119,7 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_dict.h" // PyDictKeysObject #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK() -#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyThreadState_GET() #include "stringlib/eq.h" // unicode_eq() @@ -232,23 +232,18 @@ equally good collision statistics, needed less code & used less memory. */ -static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode); +static int dictresize(PyInterpreterState *interp, PyDictObject *mp, + uint8_t log_newsize, int unicode); static PyObject* dict_iter(PyDictObject *dict); -/*Global counter used to set ma_version_tag field of dictionary. - * It is incremented each time that a dictionary is created and each - * time that a dictionary is modified. */ -uint64_t _pydict_global_version = 0; - #include "clinic/dictobject.c.h" #if PyDict_MAXFREELIST > 0 static struct _Py_dict_state * -get_dict_state(void) +get_dict_state(PyInterpreterState *interp) { - PyInterpreterState *interp = _PyInterpreterState_GET(); return &interp->dict_state; } #endif @@ -294,7 +289,8 @@ void _PyDict_DebugMallocStats(FILE *out) { #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_dict_state *state = get_dict_state(interp); _PyDebugAllocatorStats(out, "free PyDictObject", state->numfree, sizeof(PyDictObject)); #endif @@ -302,26 +298,39 @@ _PyDict_DebugMallocStats(FILE *out) #define DK_MASK(dk) (DK_SIZE(dk)-1) -static void free_keys_object(PyDictKeysObject *keys); +static void free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys); + +/* PyDictKeysObject has refcounts like PyObject does, so we have the + following two functions to mirror what Py_INCREF() and Py_DECREF() do. + (Keep in mind that PyDictKeysObject isn't actually a PyObject.) + Likewise a PyDictKeysObject can be immortal (e.g. Py_EMPTY_KEYS), + so we apply a naive version of what Py_INCREF() and Py_DECREF() do + for immortal objects. */ static inline void dictkeys_incref(PyDictKeysObject *dk) { + if (dk->dk_refcnt == _Py_IMMORTAL_REFCNT) { + return; + } #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif dk->dk_refcnt++; } static inline void -dictkeys_decref(PyDictKeysObject *dk) +dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk) { + if (dk->dk_refcnt == _Py_IMMORTAL_REFCNT) { + return; + } assert(dk->dk_refcnt > 0); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DecRefTotal(_PyInterpreterState_GET()); #endif if (--dk->dk_refcnt == 0) { - free_keys_object(dk); + free_keys_object(interp, dk); } } @@ -451,7 +460,7 @@ estimate_log2_keysize(Py_ssize_t n) * (which cannot fail and thus can do no allocation). */ static PyDictKeysObject empty_keys_struct = { - 1, /* dk_refcnt */ + _Py_IMMORTAL_REFCNT, /* dk_refcnt */ 0, /* dk_log2_size */ 0, /* dk_log2_index_bytes */ DICT_KEYS_UNICODE, /* dk_kind */ @@ -591,7 +600,7 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) static PyDictKeysObject* -new_keys_object(uint8_t log2_size, bool unicode) +new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode) { PyDictKeysObject *dk; Py_ssize_t usable; @@ -617,7 +626,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -638,7 +647,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } } #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif dk->dk_refcnt = 1; dk->dk_log2_size = log2_size; @@ -653,7 +662,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } static void -free_keys_object(PyDictKeysObject *keys) +free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys) { assert(keys != Py_EMPTY_KEYS); if (DK_IS_UNICODE(keys)) { @@ -673,7 +682,7 @@ free_keys_object(PyDictKeysObject *keys) } } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // free_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -690,9 +699,9 @@ free_keys_object(PyDictKeysObject *keys) } static inline PyDictValues* -new_values(Py_ssize_t size) +new_values(size_t size) { - assert(size > 0); + assert(size >= 1); size_t prefix_size = _Py_SIZE_ROUND_UP(size+2, sizeof(PyObject *)); assert(prefix_size < 256); size_t n = prefix_size + size * sizeof(PyObject *); @@ -714,12 +723,14 @@ free_values(PyDictValues *values) /* Consumes a reference to the keys object */ static PyObject * -new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free_values_on_failure) +new_dict(PyInterpreterState *interp, + PyDictKeysObject *keys, PyDictValues *values, + Py_ssize_t used, int free_values_on_failure) { PyDictObject *mp; assert(keys != NULL); #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_dict() must not be called after _PyDict_Fini() assert(state->numfree != -1); @@ -736,7 +747,7 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free { mp = PyObject_GC_New(PyDictObject, &PyDict_Type); if (mp == NULL) { - dictkeys_decref(keys); + dictkeys_decref(interp, keys); if (free_values_on_failure) { free_values(values); } @@ -746,35 +757,32 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free mp->ma_keys = keys; mp->ma_values = values; mp->ma_used = used; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = DICT_NEXT_VERSION(interp); ASSERT_CONSISTENT(mp); return (PyObject *)mp; } -static inline Py_ssize_t +static inline size_t shared_keys_usable_size(PyDictKeysObject *keys) { - return keys->dk_nentries + keys->dk_usable; + return (size_t)keys->dk_nentries + (size_t)keys->dk_usable; } /* Consumes a reference to the keys object */ static PyObject * -new_dict_with_shared_keys(PyDictKeysObject *keys) +new_dict_with_shared_keys(PyInterpreterState *interp, PyDictKeysObject *keys) { - PyDictValues *values; - Py_ssize_t i, size; - - size = shared_keys_usable_size(keys); - values = new_values(size); + size_t size = shared_keys_usable_size(keys); + PyDictValues *values = new_values(size); if (values == NULL) { - dictkeys_decref(keys); + dictkeys_decref(interp, keys); return PyErr_NoMemory(); } ((char *)values)[-2] = 0; - for (i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - return new_dict(keys, values, 0, 1); + return new_dict(interp, keys, values, 0, 1); } @@ -784,9 +792,10 @@ clone_combined_dict_keys(PyDictObject *orig) assert(PyDict_Check(orig)); assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter); assert(orig->ma_values == NULL); + assert(orig->ma_keys != Py_EMPTY_KEYS); assert(orig->ma_keys->dk_refcnt == 1); - Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys); + size_t keys_size = _PyDict_KeysSize(orig->ma_keys); PyDictKeysObject *keys = PyObject_Malloc(keys_size); if (keys == NULL) { PyErr_NoMemory(); @@ -829,7 +838,7 @@ clone_combined_dict_keys(PyDictObject *orig) we have it now; calling dictkeys_incref would be an error as keys->dk_refcnt is already set to 1 (after memcpy). */ #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif return keys; } @@ -837,8 +846,9 @@ clone_combined_dict_keys(PyDictObject *orig) PyObject * PyDict_New(void) { - dictkeys_incref(Py_EMPTY_KEYS); - return new_dict(Py_EMPTY_KEYS, NULL, 0, 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + /* We don't incref Py_EMPTY_KEYS here because it is immortal. */ + return new_dict(interp, Py_EMPTY_KEYS, NULL, 0, 0); } /* Search index of hash table from offset of entry table */ @@ -934,6 +944,7 @@ unicodekeys_lookup_unicode(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) } perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); + // Manual loop unrolling ix = dictkeys_get_index(dk, i); if (ix >= 0) { PyDictUnicodeEntry *ep = &ep0[ix]; @@ -1178,9 +1189,9 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) } static int -insertion_resize(PyDictObject *mp, int unicode) +insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode) { - return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); + return dictresize(interp, mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); } static Py_ssize_t @@ -1200,7 +1211,6 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) if (keys->dk_usable <= 0) { return DKIX_EMPTY; } - Py_INCREF(name); /* Insert into new slot. */ keys->dk_version = 0; Py_ssize_t hashpos = find_empty_slot(keys, hash); @@ -1208,7 +1218,7 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(keys)[ix]; dictkeys_set_index(keys, hashpos, ix); assert(ep->me_key == NULL); - ep->me_key = name; + ep->me_key = Py_NewRef(name); keys->dk_usable--; keys->dk_nentries++; } @@ -1223,12 +1233,13 @@ Returns -1 if an error occurred, or 0 on success. Consumes key and value references. */ static int -insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) +insertdict(PyInterpreterState *interp, PyDictObject *mp, + PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp, 0) < 0) + if (insertion_resize(interp, mp, 0) < 0) goto Fail; assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); } @@ -1240,12 +1251,14 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) MAINTAIN_TRACKING(mp, key, value); if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, value); /* Insert into new slot. */ mp->ma_keys->dk_version = 0; assert(old_value == NULL); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ - if (insertion_resize(mp, 1) < 0) + if (insertion_resize(interp, mp, 1) < 0) goto Fail; } @@ -1274,7 +1287,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) ep->me_value = value; } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); @@ -1283,6 +1296,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } if (old_value != value) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_MODIFIED, mp, key, value); if (_PyDict_HasSplitTable(mp)) { mp->ma_values->values[ix] = value; if (old_value == NULL) { @@ -1299,7 +1314,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) DK_ENTRIES(mp->ma_keys)[ix].me_value = value; } } - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ ASSERT_CONSISTENT(mp); @@ -1315,19 +1330,23 @@ Fail: // Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS. // Consumes key and value references. static int -insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, - PyObject *value) +insert_to_emptydict(PyInterpreterState *interp, PyDictObject *mp, + PyObject *key, Py_hash_t hash, PyObject *value) { assert(mp->ma_keys == Py_EMPTY_KEYS); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, value); + int unicode = PyUnicode_CheckExact(key); - PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE, unicode); + PyDictKeysObject *newkeys = new_keys_object( + interp, PyDict_LOG_MINSIZE, unicode); if (newkeys == NULL) { Py_DECREF(key); Py_DECREF(value); return -1; } - dictkeys_decref(Py_EMPTY_KEYS); + /* We don't decref Py_EMPTY_KEYS here because it is immortal. */ mp->ma_keys = newkeys; mp->ma_values = NULL; @@ -1347,7 +1366,7 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, ep->me_value = value; } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; return 0; @@ -1402,7 +1421,8 @@ This function supports: - Generic -> Generic */ static int -dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) +dictresize(PyInterpreterState *interp, PyDictObject *mp, + uint8_t log2_newsize, int unicode) { PyDictKeysObject *oldkeys; PyDictValues *oldvalues; @@ -1426,7 +1446,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) */ /* Allocate a new table. */ - mp->ma_keys = new_keys_object(log2_newsize, unicode); + mp->ma_keys = new_keys_object(interp, log2_newsize, unicode); if (mp->ma_keys == NULL) { mp->ma_keys = oldkeys; return -1; @@ -1449,8 +1469,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) int index = get_index_from_order(mp, i); PyDictUnicodeEntry *ep = &oldentries[index]; assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; + newentries[i].me_key = Py_NewRef(ep->me_key); newentries[i].me_hash = unicode_get_hash(ep->me_key); newentries[i].me_value = oldvalues->values[index]; } @@ -1463,13 +1482,12 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) int index = get_index_from_order(mp, i); PyDictUnicodeEntry *ep = &oldentries[index]; assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; + newentries[i].me_key = Py_NewRef(ep->me_key); newentries[i].me_value = oldvalues->values[index]; } build_indices_unicode(mp->ma_keys, newentries, numentries); } - dictkeys_decref(oldkeys); + dictkeys_decref(interp, oldkeys); mp->ma_values = NULL; free_values(oldvalues); } @@ -1526,18 +1544,14 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) // We can not use free_keys_object here because key's reference // are moved already. + if (oldkeys != Py_EMPTY_KEYS) { #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DecRefTotal(_PyInterpreterState_GET()); #endif - if (oldkeys == Py_EMPTY_KEYS) { - oldkeys->dk_refcnt--; - assert(oldkeys->dk_refcnt > 0); - } - else { assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); assert(oldkeys->dk_refcnt == 1); #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // dictresize() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -1564,7 +1578,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) } static PyObject * -dict_new_presized(Py_ssize_t minused, bool unicode) +dict_new_presized(PyInterpreterState *interp, Py_ssize_t minused, bool unicode) { const uint8_t log2_max_presize = 17; const Py_ssize_t max_presize = ((Py_ssize_t)1) << log2_max_presize; @@ -1585,16 +1599,17 @@ dict_new_presized(Py_ssize_t minused, bool unicode) log2_newsize = estimate_log2_keysize(minused); } - new_keys = new_keys_object(log2_newsize, unicode); + new_keys = new_keys_object(interp, log2_newsize, unicode); if (new_keys == NULL) return NULL; - return new_dict(new_keys, NULL, 0, 0); + return new_dict(interp, new_keys, NULL, 0, 0); } PyObject * _PyDict_NewPresized(Py_ssize_t minused) { - return dict_new_presized(minused, false); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_new_presized(interp, minused, false); } PyObject * @@ -1604,6 +1619,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, { bool unicode = true; PyObject *const *ks = keys; + PyInterpreterState *interp = _PyInterpreterState_GET(); for (Py_ssize_t i = 0; i < length; i++) { if (!PyUnicode_CheckExact(*ks)) { @@ -1613,7 +1629,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, ks += keys_offset; } - PyObject *dict = dict_new_presized(length, unicode); + PyObject *dict = dict_new_presized(interp, length, unicode); if (dict == NULL) { return NULL; } @@ -1670,15 +1686,15 @@ PyDict_GetItem(PyObject *op, PyObject *key) #endif /* Preserve the existing exception */ - PyObject *exc_type, *exc_value, *exc_tb; PyObject *value; Py_ssize_t ix; (void)ix; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + PyObject *exc = _PyErr_GetRaisedException(tstate); ix = _Py_dict_lookup(mp, key, hash, &value); /* Ignore any exception raised by the lookup */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(tstate, exc); assert(ix >= 0 || value == NULL); @@ -1686,50 +1702,12 @@ PyDict_GetItem(PyObject *op, PyObject *key) } Py_ssize_t -_PyDict_GetItemHint(PyDictObject *mp, PyObject *key, - Py_ssize_t hint, PyObject **value) +_PyDict_LookupIndex(PyDictObject *mp, PyObject *key) { - assert(*value == NULL); + PyObject *value; assert(PyDict_CheckExact((PyObject*)mp)); assert(PyUnicode_CheckExact(key)); - if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { - PyObject *res = NULL; - - if (DK_IS_UNICODE(mp->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - } - Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyObject_Hash(key); @@ -1738,7 +1716,7 @@ _PyDict_GetItemHint(PyDictObject *mp, PyObject *key, } } - return _Py_dict_lookup(mp, key, hash, value); + return _Py_dict_lookup(mp, key, hash, &value); } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. @@ -1879,11 +1857,12 @@ _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) return -1; } } + PyInterpreterState *interp = _PyInterpreterState_GET(); if (mp->ma_keys == Py_EMPTY_KEYS) { - return insert_to_emptydict(mp, key, hash, value); + return insert_to_emptydict(interp, mp, key, hash, value); } /* insertdict() handles any resizing that might be necessary */ - return insertdict(mp, key, hash, value); + return insertdict(interp, mp, key, hash, value); } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the @@ -1901,9 +1880,8 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) } assert(key); assert(value); - Py_INCREF(key); - Py_INCREF(value); - return _PyDict_SetItem_Take2((PyDictObject *)op, key, value); + return _PyDict_SetItem_Take2((PyDictObject *)op, + Py_NewRef(key), Py_NewRef(value)); } int @@ -1921,13 +1899,12 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, assert(hash != -1); mp = (PyDictObject *)op; - Py_INCREF(key); - Py_INCREF(value); + PyInterpreterState *interp = _PyInterpreterState_GET(); if (mp->ma_keys == Py_EMPTY_KEYS) { - return insert_to_emptydict(mp, key, hash, value); + return insert_to_emptydict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value)); } /* insertdict() handles any resizing that might be necessary */ - return insertdict(mp, key, hash, value); + return insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value)); } static void @@ -1948,7 +1925,7 @@ delete_index_from_values(PyDictValues *values, Py_ssize_t ix) static int delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, - PyObject *old_value) + PyObject *old_value, uint64_t new_version) { PyObject *old_key; @@ -1956,7 +1933,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, assert(hashpos >= 0); mp->ma_used--; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; if (mp->ma_values) { assert(old_value == mp->ma_values->values[ix]); mp->ma_values->values[ix] = NULL; @@ -2025,7 +2002,10 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) return -1; } - return delitem_common(mp, hash, ix, old_value); + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hash, ix, old_value, new_version); } /* This function promises that the predicate -> deletion sequence is atomic @@ -2066,10 +2046,14 @@ _PyDict_DelItemIf(PyObject *op, PyObject *key, hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); - if (res > 0) - return delitem_common(mp, hashpos, ix, old_value); - else + if (res > 0) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hashpos, ix, old_value, new_version); + } else { return 0; + } } @@ -2090,22 +2074,25 @@ PyDict_Clear(PyObject *op) return; } /* Empty the dict... */ + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_CLEARED, mp, NULL, NULL); dictkeys_incref(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; mp->ma_values = NULL; mp->ma_used = 0; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; /* ...then clear the keys and values */ if (oldvalues != NULL) { n = oldkeys->dk_nentries; for (i = 0; i < n; i++) Py_CLEAR(oldvalues->values[i]); free_values(oldvalues); - dictkeys_decref(oldkeys); + dictkeys_decref(interp, oldkeys); } else { - assert(oldkeys->dk_refcnt == 1); - dictkeys_decref(oldkeys); + assert(oldkeys->dk_refcnt == 1); + dictkeys_decref(interp, oldkeys); } ASSERT_CONSISTENT(mp); } @@ -2209,14 +2196,14 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d Py_ssize_t ix; PyObject *old_value; PyDictObject *mp; + PyInterpreterState *interp = _PyInterpreterState_GET(); assert(PyDict_Check(dict)); mp = (PyDictObject *)dict; if (mp->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; @@ -2226,15 +2213,15 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d return NULL; if (ix == DKIX_EMPTY || old_value == NULL) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; } assert(old_value != NULL); - Py_INCREF(old_value); - delitem_common(mp, hash, ix, old_value); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + delitem_common(mp, hash, ix, Py_NewRef(old_value), new_version); ASSERT_CONSISTENT(mp); return old_value; @@ -2247,8 +2234,7 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) if (((PyDictObject *)dict)->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; @@ -2269,6 +2255,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; PyObject *d; int status; + PyInterpreterState *interp = _PyInterpreterState_GET(); d = _PyObject_CallNoArgs(cls); if (d == NULL) @@ -2283,15 +2270,16 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) Py_hash_t hash; int unicode = DK_IS_UNICODE(((PyDictObject*)iterable)->ma_keys); - if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)), unicode)) { + if (dictresize(interp, mp, + estimate_log2_keysize(PyDict_GET_SIZE(iterable)), + unicode)) { Py_DECREF(d); return NULL; } while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -2304,15 +2292,14 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { + if (dictresize(interp, mp, + estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { Py_DECREF(d); return NULL; } while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -2359,6 +2346,15 @@ Fail: static void dict_dealloc(PyDictObject *mp) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(Py_REFCNT(mp) == 0); + Py_SET_REFCNT(mp, 1); + _PyDict_NotifyEvent(interp, PyDict_EVENT_DEALLOCATED, mp, NULL, NULL); + if (Py_REFCNT(mp) > 1) { + Py_SET_REFCNT(mp, Py_REFCNT(mp) - 1); + return; + } + Py_SET_REFCNT(mp, 0); PyDictValues *values = mp->ma_values; PyDictKeysObject *keys = mp->ma_keys; Py_ssize_t i, n; @@ -2371,14 +2367,14 @@ dict_dealloc(PyDictObject *mp) Py_XDECREF(values->values[i]); } free_values(values); - dictkeys_decref(keys); + dictkeys_decref(interp, keys); } else if (keys != NULL) { assert(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); - dictkeys_decref(keys); + dictkeys_decref(interp, keys); } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_dict() must not be called after _PyDict_Fini() assert(state->numfree != -1); @@ -2517,8 +2513,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) _PyErr_SetKeyError(key); return NULL; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } static int @@ -2560,8 +2555,7 @@ dict_keys(PyDictObject *mp) PyObject *key; while (_PyDict_Next((PyObject*)mp, &pos, &key, NULL, NULL)) { assert(j < n); - Py_INCREF(key); - PyList_SET_ITEM(v, j, key); + PyList_SET_ITEM(v, j, Py_NewRef(key)); j++; } assert(j == n); @@ -2592,8 +2586,7 @@ dict_values(PyDictObject *mp) PyObject *value; while (_PyDict_Next((PyObject*)mp, &pos, NULL, &value, NULL)) { assert(j < n); - Py_INCREF(value); - PyList_SET_ITEM(v, j, value); + PyList_SET_ITEM(v, j, Py_NewRef(value)); j++; } assert(j == n); @@ -2638,10 +2631,8 @@ dict_items(PyDictObject *mp) while (_PyDict_Next((PyObject*)mp, &pos, &key, &value, NULL)) { assert(j < n); PyObject *item = PyList_GET_ITEM(v, j); - Py_INCREF(key); - PyTuple_SET_ITEM(item, 0, key); - Py_INCREF(value); - PyTuple_SET_ITEM(item, 1, value); + PyTuple_SET_ITEM(item, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(item, 1, Py_NewRef(value)); j++; } assert(j == n); @@ -2813,7 +2804,7 @@ Return: } static int -dict_merge(PyObject *a, PyObject *b, int override) +dict_merge(PyInterpreterState *interp, PyObject *a, PyObject *b, int override) { PyDictObject *mp, *other; @@ -2847,12 +2838,14 @@ dict_merge(PyObject *a, PyObject *b, int override) other->ma_used == okeys->dk_nentries && (DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE || USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_CLONED, mp, b, NULL); PyDictKeysObject *keys = clone_combined_dict_keys(other); if (keys == NULL) { return -1; } - dictkeys_decref(mp->ma_keys); + dictkeys_decref(interp, mp->ma_keys); mp->ma_keys = keys; if (mp->ma_values != NULL) { free_values(mp->ma_values); @@ -2860,7 +2853,7 @@ dict_merge(PyObject *a, PyObject *b, int override) } mp->ma_used = other->ma_used; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; ASSERT_CONSISTENT(mp); if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) { @@ -2877,7 +2870,9 @@ dict_merge(PyObject *a, PyObject *b, int override) */ if (USABLE_FRACTION(DK_SIZE(mp->ma_keys)) < other->ma_used) { int unicode = DK_IS_UNICODE(other->ma_keys); - if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used), unicode)) { + if (dictresize(interp, mp, + estimate_log2_keysize(mp->ma_used + other->ma_used), + unicode)) { return -1; } } @@ -2892,16 +2887,14 @@ dict_merge(PyObject *a, PyObject *b, int override) Py_INCREF(key); Py_INCREF(value); if (override == 1) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); + err = insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value)); } else { err = _PyDict_Contains_KnownHash(a, key, hash); if (err == 0) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); + err = insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value)); } else if (err > 0) { if (override != 0) { @@ -2987,20 +2980,23 @@ dict_merge(PyObject *a, PyObject *b, int override) int PyDict_Update(PyObject *a, PyObject *b) { - return dict_merge(a, b, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_merge(interp, a, b, 1); } int PyDict_Merge(PyObject *a, PyObject *b, int override) { + PyInterpreterState *interp = _PyInterpreterState_GET(); /* XXX Deprecate override not in (0, 1). */ - return dict_merge(a, b, override != 0); + return dict_merge(interp, a, b, override != 0); } int _PyDict_MergeEx(PyObject *a, PyObject *b, int override) { - return dict_merge(a, b, override); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_merge(interp, a, b, override); } static PyObject * @@ -3014,7 +3010,7 @@ PyDict_Copy(PyObject *o) { PyObject *copy; PyDictObject *mp; - Py_ssize_t i, n; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (o == NULL || !PyDict_Check(o)) { PyErr_BadInternalCall(); @@ -3029,9 +3025,8 @@ PyDict_Copy(PyObject *o) if (_PyDict_HasSplitTable(mp)) { PyDictObject *split_copy; - Py_ssize_t size = shared_keys_usable_size(mp->ma_keys); - PyDictValues *newvalues; - newvalues = new_values(size); + size_t size = shared_keys_usable_size(mp->ma_keys); + PyDictValues *newvalues = new_values(size); if (newvalues == NULL) return PyErr_NoMemory(); split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); @@ -3044,12 +3039,11 @@ PyDict_Copy(PyObject *o) split_copy->ma_values = newvalues; split_copy->ma_keys = mp->ma_keys; split_copy->ma_used = mp->ma_used; - split_copy->ma_version_tag = DICT_NEXT_VERSION(); + split_copy->ma_version_tag = DICT_NEXT_VERSION(interp); dictkeys_incref(mp->ma_keys); - for (i = 0, n = size; i < n; i++) { + for (size_t i = 0; i < size; i++) { PyObject *value = mp->ma_values->values[i]; - Py_XINCREF(value); - split_copy->ma_values->values[i] = value; + split_copy->ma_values->values[i] = Py_XNewRef(value); } if (_PyObject_GC_IS_TRACKED(mp)) _PyObject_GC_TRACK(split_copy); @@ -3078,7 +3072,7 @@ PyDict_Copy(PyObject *o) if (keys == NULL) { return NULL; } - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL, 0, 0); + PyDictObject *new = (PyDictObject *)new_dict(interp, keys, NULL, 0, 0); if (new == NULL) { /* In case of an error, `new_dict()` takes care of cleaning up `keys`. */ @@ -3098,7 +3092,7 @@ PyDict_Copy(PyObject *o) copy = PyDict_New(); if (copy == NULL) return NULL; - if (dict_merge(copy, o, 1) == 0) + if (dict_merge(interp, copy, o, 1) == 0) return copy; Py_DECREF(copy); return NULL; @@ -3224,8 +3218,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) } else res = Py_NotImplemented; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -3290,8 +3283,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) if (ix == DKIX_EMPTY || val == NULL) { val = default_value; } - Py_INCREF(val); - return val; + return Py_NewRef(val); } PyObject * @@ -3300,6 +3292,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) PyDictObject *mp = (PyDictObject *)d; PyObject *value; Py_hash_t hash; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (!PyDict_Check(d)) { PyErr_BadInternalCall(); @@ -3313,16 +3306,15 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) } if (mp->ma_keys == Py_EMPTY_KEYS) { - Py_INCREF(key); - Py_INCREF(defaultobj); - if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) { + if (insert_to_emptydict(interp, mp, Py_NewRef(key), hash, + Py_NewRef(defaultobj)) < 0) { return NULL; } return defaultobj; } if (!PyUnicode_CheckExact(key) && DK_IS_UNICODE(mp->ma_keys)) { - if (insertion_resize(mp, 0) < 0) { + if (insertion_resize(interp, mp, 0) < 0) { return NULL; } } @@ -3332,10 +3324,12 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, defaultobj); mp->ma_keys->dk_version = 0; value = defaultobj; if (mp->ma_keys->dk_usable <= 0) { - if (insertion_resize(mp, 1) < 0) { + if (insertion_resize(interp, mp, 1) < 0) { return NULL; } } @@ -3344,43 +3338,42 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) if (DK_IS_UNICODE(mp->ma_keys)) { assert(PyUnicode_CheckExact(key)); PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; - ep->me_key = key; + ep->me_key = Py_NewRef(key); if (_PyDict_HasSplitTable(mp)) { Py_ssize_t index = (int)mp->ma_keys->dk_nentries; assert(index < SHARED_KEYS_MAX_SIZE); assert(mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; + mp->ma_values->values[index] = Py_NewRef(value); _PyDictValues_AddToInsertionOrder(mp->ma_values, index); } else { - ep->me_value = value; + ep->me_value = Py_NewRef(value); } } else { PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; - ep->me_key = key; + ep->me_key = Py_NewRef(key); ep->me_hash = hash; - ep->me_value = value; + ep->me_value = Py_NewRef(value); } - Py_INCREF(key); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); } else if (value == NULL) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, defaultobj); value = defaultobj; assert(_PyDict_HasSplitTable(mp)); assert(mp->ma_values->values[ix] == NULL); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); - mp->ma_values->values[ix] = value; + mp->ma_values->values[ix] = Py_NewRef(value); _PyDictValues_AddToInsertionOrder(mp->ma_values, ix); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } ASSERT_CONSISTENT(mp); @@ -3407,8 +3400,7 @@ dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *val; val = PyDict_SetDefault((PyObject *)self, key, default_value); - Py_XINCREF(val); - return val; + return Py_XNewRef(val); } static PyObject * @@ -3453,6 +3445,8 @@ dict_popitem_impl(PyDictObject *self) { Py_ssize_t i, j; PyObject *res; + uint64_t new_version; + PyInterpreterState *interp = _PyInterpreterState_GET(); /* Allocate the result tuple before checking the size. Believe it * or not, this allocation could trigger a garbage collection which @@ -3473,7 +3467,7 @@ dict_popitem_impl(PyDictObject *self) } /* Convert split table to combined table */ if (self->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - if (dictresize(self, DK_LOG_SIZE(self->ma_keys), 1)) { + if (dictresize(interp, self, DK_LOG_SIZE(self->ma_keys), 1)) { Py_DECREF(res); return NULL; } @@ -3492,6 +3486,8 @@ dict_popitem_impl(PyDictObject *self) assert(i >= 0); key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, self, key, NULL); hash = unicode_get_hash(key); value = ep0[i].me_value; ep0[i].me_key = NULL; @@ -3506,6 +3502,8 @@ dict_popitem_impl(PyDictObject *self) assert(i >= 0); key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, self, key, NULL); hash = ep0[i].me_hash; value = ep0[i].me_value; ep0[i].me_key = NULL; @@ -3523,7 +3521,7 @@ dict_popitem_impl(PyDictObject *self) /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ self->ma_keys->dk_nentries = i; self->ma_used--; - self->ma_version_tag = DICT_NEXT_VERSION(); + self->ma_version_tag = new_version; ASSERT_CONSISTENT(self); return res; } @@ -3572,9 +3570,7 @@ static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(mp)); + size_t res = _PyObject_SIZE(Py_TYPE(mp)); if (mp->ma_values) { res += shared_keys_usable_size(mp->ma_keys) * sizeof(PyObject*); } @@ -3583,17 +3579,19 @@ _PyDict_SizeOf(PyDictObject *mp) if (mp->ma_keys->dk_refcnt == 1) { res += _PyDict_KeysSize(mp->ma_keys); } - return res; + assert(res <= (size_t)PY_SSIZE_T_MAX); + return (Py_ssize_t)res; } -Py_ssize_t +size_t _PyDict_KeysSize(PyDictKeysObject *keys) { - size_t es = keys->dk_kind == DICT_KEYS_GENERAL - ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry); - return (sizeof(PyDictKeysObject) - + ((size_t)1 << keys->dk_log2_index_bytes) - + USABLE_FRACTION(DK_SIZE(keys)) * es); + size_t es = (keys->dk_kind == DICT_KEYS_GENERAL + ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry)); + size_t size = sizeof(PyDictKeysObject); + size += (size_t)1 << keys->dk_log2_index_bytes; + size += USABLE_FRACTION((size_t)DK_SIZE(keys)) * es; + return size; } static PyObject * @@ -3625,11 +3623,11 @@ dict_ior(PyObject *self, PyObject *other) if (dict_update_arg(self, other)) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } -PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); +PyDoc_STRVAR(getitem__doc__, +"__getitem__($self, key, /)\n--\n\nReturn self[key]."); PyDoc_STRVAR(sizeof__doc__, "D.__sizeof__() -> size of D in memory, in bytes"); @@ -3764,7 +3762,8 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyDictObject *d = (PyDictObject *)self; d->ma_used = 0; - d->ma_version_tag = DICT_NEXT_VERSION(); + d->ma_version_tag = DICT_NEXT_VERSION( + _PyInterpreterState_GET()); dictkeys_incref(Py_EMPTY_KEYS); d->ma_keys = Py_EMPTY_KEYS; d->ma_values = NULL; @@ -3963,8 +3962,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) if (di == NULL) { return NULL; } - Py_INCREF(dict); - di->di_dict = dict; + di->di_dict = (PyDictObject*)Py_NewRef(dict); di->di_used = dict->ma_used; di->len = dict->ma_used; if (itertype == &PyDictRevIterKey_Type || @@ -4098,8 +4096,7 @@ dictiter_iternextkey(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: di->di_dict = NULL; @@ -4198,8 +4195,7 @@ dictiter_iternextvalue(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(value); - return value; + return Py_NewRef(value); fail: di->di_dict = NULL; @@ -4301,14 +4297,12 @@ dictiter_iternextitem(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -4322,8 +4316,8 @@ dictiter_iternextitem(dictiterobject *di) result = PyTuple_New(2); if (result == NULL) return NULL; - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; @@ -4427,22 +4421,18 @@ dictreviter_iternext(dictiterobject *di) di->len--; if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) { - Py_INCREF(key); - return key; + return Py_NewRef(key); } else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) { - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -4457,8 +4447,8 @@ dictreviter_iternext(dictiterobject *di) if (result == NULL) { return NULL; } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; } @@ -4505,7 +4495,6 @@ dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)) /* copy the iterator state */ dictiterobject tmp = *di; Py_XINCREF(tmp.di_dict); - PyObject *list = PySequence_List((PyObject*)&tmp); Py_XDECREF(tmp.di_dict); if (list == NULL) { @@ -4587,8 +4576,7 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) dv = PyObject_GC_New(_PyDictViewObject, type); if (dv == NULL) return NULL; - Py_INCREF(dict); - dv->dv_dict = (PyDictObject *)dict; + dv->dv_dict = (PyDictObject *)Py_NewRef(dict); _PyObject_GC_TRACK(dv); return (PyObject *)dv; } @@ -4699,8 +4687,7 @@ dictview_richcompare(PyObject *self, PyObject *other, int op) if (ok < 0) return NULL; result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4756,7 +4743,7 @@ static PySequenceMethods dictkeys_as_sequence = { (objobjproc)dictkeys_contains, /* sq_contains */ }; -// Create an set object from dictviews object. +// Create a set object from dictviews object. // Returns a new reference. // This utility function is used by set operations. static PyObject* @@ -5330,7 +5317,9 @@ dictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) PyDictKeysObject * _PyDict_NewKeysForClass(void) { - PyDictKeysObject *keys = new_keys_object(NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyDictKeysObject *keys = new_keys_object( + interp, NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); if (keys == NULL) { PyErr_Clear(); } @@ -5356,25 +5345,25 @@ init_inline_values(PyObject *obj, PyTypeObject *tp) if (keys->dk_usable > 1) { keys->dk_usable--; } - Py_ssize_t size = shared_keys_usable_size(keys); - assert(size > 0); + size_t size = shared_keys_usable_size(keys); PyDictValues *values = new_values(size); if (values == NULL) { PyErr_NoMemory(); return -1; } - assert(((uint8_t *)values)[-1] >= size+2); + assert(((uint8_t *)values)[-1] >= (size + 2)); ((uint8_t *)values)[-2] = 0; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - *_PyObject_ValuesPointer(obj) = values; + _PyDictOrValues_SetValues(_PyObject_DictOrValuesPointer(obj), values); return 0; } int _PyObject_InitializeDict(PyObject *obj) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PyTypeObject *tp = Py_TYPE(obj); if (tp->tp_dictoffset == 0) { return 0; @@ -5386,7 +5375,7 @@ _PyObject_InitializeDict(PyObject *obj) PyObject *dict; if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { dictkeys_incref(CACHED_KEYS(tp)); - dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); } else { dict = PyDict_New(); @@ -5394,25 +5383,27 @@ _PyObject_InitializeDict(PyObject *obj) if (dict == NULL) { return -1; } - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); *dictptr = dict; return 0; } static PyObject * -make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) +make_dict_from_instance_attributes(PyInterpreterState *interp, + PyDictKeysObject *keys, PyDictValues *values) { dictkeys_incref(keys); Py_ssize_t used = 0; Py_ssize_t track = 0; - for (Py_ssize_t i = 0; i < shared_keys_usable_size(keys); i++) { + size_t size = shared_keys_usable_size(keys); + for (size_t i = 0; i < size; i++) { PyObject *val = values->values[i]; if (val != NULL) { used += 1; track += _PyObject_GC_MAY_BE_TRACKED(val); } } - PyObject *res = new_dict(keys, values, used, 0); + PyObject *res = new_dict(interp, keys, values, used, 0); if (track && res) { _PyObject_GC_TRACK(res); } @@ -5422,16 +5413,17 @@ make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) PyObject * _PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyInterpreterState *interp = _PyInterpreterState_GET(); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); OBJECT_STAT_INC(dict_materialized_on_request); - return make_dict_from_instance_attributes(keys, values); + return make_dict_from_instance_attributes(interp, keys, values); } int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); @@ -5454,12 +5446,12 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, OBJECT_STAT_INC(dict_materialized_str_subclass); } #endif - PyObject *dict = make_dict_from_instance_attributes(keys, values); + PyObject *dict = make_dict_from_instance_attributes( + interp, keys, values); if (dict == NULL) { return -1; } - *_PyObject_ValuesPointer(obj) = NULL; - *_PyObject_ManagedDictPointer(obj) = dict; + _PyObject_DictOrValuesPointer(obj)->dict = dict; if (value == NULL) { return PyDict_DelItem(dict, name); } @@ -5468,8 +5460,7 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, } } PyObject *old_value = values->values[ix]; - Py_XINCREF(value); - values->values[ix] = value; + values->values[ix] = Py_XNewRef(value); if (old_value == NULL) { if (value == NULL) { PyErr_Format(PyExc_AttributeError, @@ -5488,6 +5479,37 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, return 0; } +/* Sanity check for managed dicts */ +#if 0 +#define CHECK(val) assert(val); if (!(val)) { return 0; } + +int +_PyObject_ManagedDictValidityCheck(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + int size = ((uint8_t *)values)[-2]; + int count = 0; + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + if (values->values[i] != NULL) { + count++; + } + } + CHECK(size == count); + } + else { + if (dorv_ptr->dict != NULL) { + CHECK(PyDict_Check(dorv_ptr->dict)); + } + } + return 1; +} +#endif + PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name) @@ -5500,8 +5522,7 @@ _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, return NULL; } PyObject *value = values->values[ix]; - Py_XINCREF(value); - return value; + return Py_XNewRef(value); } int @@ -5511,105 +5532,124 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (tp->tp_dictoffset == 0) { return 1; } - PyObject **dictptr; + PyObject *dict; if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictValues *values = *_PyObject_ValuesPointer(obj); - if (values) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - if (values->values[i] != NULL) { + if (_PyDictOrValues_GetValues(dorv)->values[i] != NULL) { return 0; } } return 1; } - dictptr = _PyObject_ManagedDictPointer(obj); + dict = _PyDictOrValues_GetDict(dorv); } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + dict = *dictptr; } - PyObject *dict = *dictptr; if (dict == NULL) { return 1; } return ((PyDictObject *)dict)->ma_used == 0; } - -int -_PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg) +void +_PyObject_FreeInstanceAttributes(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return 0; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + if (!_PyDictOrValues_IsValues(dorv)) { + return; } + PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_VISIT((*values_ptr)->values[i]); + Py_XDECREF(values->values[i]); } - return 0; + free_values(values); } -void -_PyObject_ClearInstanceAttributes(PyObject *self) +int +_PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return; + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + return 0; } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_CLEAR((*values_ptr)->values[i]); + assert(tp->tp_dictoffset); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_VISIT(values->values[i]); + } } + else { + PyObject *dict = _PyDictOrValues_GetDict(dorv); + Py_VISIT(dict); + } + return 0; } void -_PyObject_FreeInstanceAttributes(PyObject *self) +_PyObject_ClearManagedDict(PyObject *obj) { - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - PyDictValues *values = *values_ptr; - if (values == NULL) { + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return; } - *values_ptr = NULL; - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_XDECREF(values->values[i]); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_CLEAR(values->values[i]); + } + dorv_ptr->dict = NULL; + free_values(values); + } + else { + PyObject *dict = dorv_ptr->dict; + if (dict) { + dorv_ptr->dict = NULL; + Py_DECREF(dict); + } } - free_values(values); } PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) { PyObject *dict; + PyInterpreterState *interp = _PyInterpreterState_GET(); PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - PyObject **dictptr = _PyObject_ManagedDictPointer(obj); - if (*values_ptr) { - assert(*dictptr == NULL); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); OBJECT_STAT_INC(dict_materialized_on_request); - *dictptr = dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), *values_ptr); + dict = make_dict_from_instance_attributes( + interp, CACHED_KEYS(tp), values); if (dict != NULL) { - *values_ptr = NULL; + dorv_ptr->dict = dict; } } - else if (*dictptr == NULL) { - *dictptr = dict = PyDict_New(); - } else { - dict = *dictptr; + dict = _PyDictOrValues_GetDict(*dorv_ptr); + if (dict == NULL) { + dictkeys_incref(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); + dorv_ptr->dict = dict; + } } } else { - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr == NULL) { PyErr_SetString(PyExc_AttributeError, "This object has no __dict__"); @@ -5620,15 +5660,15 @@ PyObject_GenericGetDict(PyObject *obj, void *context) PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { dictkeys_incref(CACHED_KEYS(tp)); - *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + *dictptr = dict = new_dict_with_shared_keys( + interp, CACHED_KEYS(tp)); } else { *dictptr = dict = PyDict_New(); } } } - Py_XINCREF(dict); - return dict; + return Py_XNewRef(dict); } int @@ -5638,6 +5678,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *dict; int res; PyDictKeysObject *cached; + PyInterpreterState *interp = _PyInterpreterState_GET(); assert(dictptr != NULL); if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) { @@ -5645,7 +5686,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, dict = *dictptr; if (dict == NULL) { dictkeys_incref(cached); - dict = new_dict_with_shared_keys(cached); + dict = new_dict_with_shared_keys(interp, cached); if (dict == NULL) return -1; *dictptr = dict; @@ -5677,20 +5718,133 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, void _PyDictKeys_DecRef(PyDictKeysObject *keys) { - dictkeys_decref(keys); + PyInterpreterState *interp = _PyInterpreterState_GET(); + dictkeys_decref(interp, keys); } -static uint32_t next_dict_keys_version = 2; - -uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys) +uint32_t _PyDictKeys_GetVersionForCurrentState(PyInterpreterState *interp, + PyDictKeysObject *dictkeys) { if (dictkeys->dk_version != 0) { return dictkeys->dk_version; } - if (next_dict_keys_version == 0) { + if (interp->dict_state.next_keys_version == 0) { return 0; } - uint32_t v = next_dict_keys_version++; + uint32_t v = interp->dict_state.next_keys_version++; dictkeys->dk_version = v; return v; } + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= DICT_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id); + return -1; + } + if (!interp->dict_state.watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyDict_Watch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag |= (1LL << watcher_id); + return 0; +} + +int +PyDict_Unwatch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag &= ~(1LL << watcher_id); + return 0; +} + +int +PyDict_AddWatcher(PyDict_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (!interp->dict_state.watchers[i]) { + interp->dict_state.watchers[i] = callback; + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more dict watcher IDs available"); + return -1; +} + +int +PyDict_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + interp->dict_state.watchers[watcher_id] = NULL; + return 0; +} + +static const char * +dict_event_name(PyDict_WatchEvent event) { + switch (event) { + #define CASE(op) \ + case PyDict_EVENT_##op: \ + return "PyDict_EVENT_" #op; + PY_FOREACH_DICT_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +void +_PyDict_SendEvent(int watcher_bits, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (watcher_bits & 1) { + PyDict_WatchCallback cb = interp->dict_state.watchers[i]; + if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) { + // We don't want to resurrect the dict by potentially having an + // unraisablehook keep a reference to it, so we don't pass the + // dict as context, just an informative string message. Dict + // repr can call arbitrary code, so we invent a simpler version. + PyObject *context = PyUnicode_FromFormat( + "%s watcher callback for <dict at %p>", + dict_event_name(event), mp); + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + watcher_bits >>= 1; + } +} diff --git a/contrib/tools/python3/src/Objects/enumobject.c b/contrib/tools/python3/src/Objects/enumobject.c index d84bac6f4c9..c9d90584c26 100644 --- a/contrib/tools/python3/src/Objects/enumobject.c +++ b/contrib/tools/python3/src/Objects/enumobject.c @@ -389,8 +389,7 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return NULL; ro->index = n-1; - Py_INCREF(seq); - ro->seq = seq; + ro->seq = Py_NewRef(seq); return (PyObject *)ro; } diff --git a/contrib/tools/python3/src/Objects/exceptions.c b/contrib/tools/python3/src/Objects/exceptions.c index 86cabbf3f17..e3217c922ee 100644 --- a/contrib/tools/python3/src/Objects/exceptions.c +++ b/contrib/tools/python3/src/Objects/exceptions.c @@ -8,6 +8,7 @@ #include <Python.h> #include <stdbool.h> #include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_pyerrors.h" // struct _PyErr_SetRaisedException #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_initconfig.h" #include "pycore_object.h" @@ -53,8 +54,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->suppress_context = 0; if (args) { - self->args = args; - Py_INCREF(args); + self->args = Py_NewRef(args); return (PyObject *)self; } @@ -73,9 +73,7 @@ BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) return -1; - Py_INCREF(args); - Py_XSETREF(self->args, args); - + Py_XSETREF(self->args, Py_NewRef(args)); return 0; } @@ -185,8 +183,7 @@ BaseException_with_traceback(PyObject *self, PyObject *tb) { if (PyException_SetTraceback(self, tb)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyDoc_STRVAR(with_traceback_doc, @@ -257,8 +254,7 @@ BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->args == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->args); - return self->args; + return Py_NewRef(self->args); } static int @@ -282,8 +278,7 @@ BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->traceback == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->traceback); - return self->traceback; + return Py_NewRef(self->traceback); } static int @@ -293,14 +288,17 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED( PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); return -1; } - else if (!(tb == Py_None || PyTraceBack_Check(tb))) { + if (PyTraceBack_Check(tb)) { + Py_XSETREF(self->traceback, Py_NewRef(tb)); + } + else if (tb == Py_None) { + Py_CLEAR(self->traceback); + } + else { PyErr_SetString(PyExc_TypeError, "__traceback__ must be a traceback or None"); return -1; } - - Py_INCREF(tb); - Py_XSETREF(self->traceback, tb); return 0; } @@ -379,8 +377,7 @@ PyObject * PyException_GetTraceback(PyObject *self) { PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self); - Py_XINCREF(base_self->traceback); - return base_self->traceback; + return Py_XNewRef(base_self->traceback); } @@ -394,8 +391,7 @@ PyObject * PyException_GetCause(PyObject *self) { PyObject *cause = _PyBaseExceptionObject_cast(self)->cause; - Py_XINCREF(cause); - return cause; + return Py_XNewRef(cause); } /* Steals a reference to cause */ @@ -411,8 +407,7 @@ PyObject * PyException_GetContext(PyObject *self) { PyObject *context = _PyBaseExceptionObject_cast(self)->context; - Py_XINCREF(context); - return context; + return Py_XNewRef(context); } /* Steals a reference to context */ @@ -422,6 +417,20 @@ PyException_SetContext(PyObject *self, PyObject *context) Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context); } +PyObject * +PyException_GetArgs(PyObject *self) +{ + PyObject *args = _PyBaseExceptionObject_cast(self)->args; + return Py_NewRef(args); +} + +void +PyException_SetArgs(PyObject *self, PyObject *args) +{ + Py_INCREF(args); + Py_XSETREF(_PyBaseExceptionObject_cast(self)->args, args); +} + const char * PyExceptionClass_Name(PyObject *ob) { @@ -578,8 +587,7 @@ StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds) value = PyTuple_GET_ITEM(args, 0); else value = Py_None; - Py_INCREF(value); - self->value = value; + self->value = Py_NewRef(value); return 0; } @@ -605,17 +613,9 @@ StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg) return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } -ComplexExtendsException( - PyExc_Exception, /* base */ - StopIteration, /* name */ - StopIteration, /* prefix for *_init, etc */ - 0, /* new */ - 0, /* methods */ - StopIteration_members, /* members */ - 0, /* getset */ - 0, /* str */ - "Signal the end from iterator.__next__()." -); +ComplexExtendsException(PyExc_Exception, StopIteration, StopIteration, + 0, 0, StopIteration_members, 0, 0, + "Signal the end from iterator.__next__()."); /* @@ -640,12 +640,10 @@ SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) if (size == 0) return 0; if (size == 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->code, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } else { /* size > 1 */ - Py_INCREF(args); - Py_XSETREF(self->code, args); + Py_XSETREF(self->code, Py_NewRef(args)); } return 0; } @@ -1352,7 +1350,10 @@ is_same_exception_metadata(PyObject *exc1, PyObject *exc2) PyObject * _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs) { + /* orig must be a raised & caught exception, so it has a traceback */ assert(PyExceptionInstance_Check(orig)); + assert(_PyBaseExceptionObject_cast(orig)->traceback != NULL); + assert(PyList_Check(excs)); Py_ssize_t numexcs = PyList_GET_SIZE(excs); @@ -1439,6 +1440,42 @@ done: return result; } +PyObject * +PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs) +{ + if (orig == NULL || !PyExceptionInstance_Check(orig)) { + PyErr_SetString(PyExc_TypeError, "orig must be an exception instance"); + return NULL; + } + if (excs == NULL || !PyList_Check(excs)) { + PyErr_SetString(PyExc_TypeError, + "excs must be a list of exception instances"); + return NULL; + } + Py_ssize_t numexcs = PyList_GET_SIZE(excs); + for (Py_ssize_t i = 0; i < numexcs; i++) { + PyObject *exc = PyList_GET_ITEM(excs, i); + if (exc == NULL || !(PyExceptionInstance_Check(exc) || Py_IsNone(exc))) { + PyErr_Format(PyExc_TypeError, + "item %d of excs is not an exception", i); + return NULL; + } + } + + /* Make sure that orig has something as traceback, in the interpreter + * it always does becuase it's a raised exception. + */ + PyObject *tb = PyException_GetTraceback(orig); + + if (tb == NULL) { + PyErr_Format(PyExc_ValueError, "orig must be a raised exception"); + return NULL; + } + Py_DECREF(tb); + + return _PyExc_PrepReraiseStar(orig, excs); +} + static PyMemberDef BaseExceptionGroup_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY, PyDoc_STR("exception message")}, @@ -1497,11 +1534,12 @@ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, static int ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"name", "path", 0}; + static char *kwlist[] = {"name", "path", "name_from", 0}; PyObject *empty_tuple; PyObject *msg = NULL; PyObject *name = NULL; PyObject *path = NULL; + PyObject *name_from = NULL; if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) return -1; @@ -1509,22 +1547,19 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) empty_tuple = PyTuple_New(0); if (!empty_tuple) return -1; - if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist, - &name, &path)) { + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist, + &name, &path, &name_from)) { Py_DECREF(empty_tuple); return -1; } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(path); - Py_XSETREF(self->path, path); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->path, Py_XNewRef(path)); + Py_XSETREF(self->name_from, Py_XNewRef(name_from)); if (PyTuple_GET_SIZE(args) == 1) { - msg = PyTuple_GET_ITEM(args, 0); - Py_INCREF(msg); + msg = Py_NewRef(PyTuple_GET_ITEM(args, 0)); } Py_XSETREF(self->msg, msg); @@ -1537,6 +1572,7 @@ ImportError_clear(PyImportErrorObject *self) Py_CLEAR(self->msg); Py_CLEAR(self->name); Py_CLEAR(self->path); + Py_CLEAR(self->name_from); return BaseException_clear((PyBaseExceptionObject *)self); } @@ -1554,6 +1590,7 @@ ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) Py_VISIT(self->msg); Py_VISIT(self->name); Py_VISIT(self->path); + Py_VISIT(self->name_from); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } @@ -1561,8 +1598,7 @@ static PyObject * ImportError_str(PyImportErrorObject *self) { if (self->msg && PyUnicode_CheckExact(self->msg)) { - Py_INCREF(self->msg); - return self->msg; + return Py_NewRef(self->msg); } else { return BaseException_str((PyBaseExceptionObject *)self); @@ -1573,7 +1609,7 @@ static PyObject * ImportError_getstate(PyImportErrorObject *self) { PyObject *dict = ((PyBaseExceptionObject *)self)->dict; - if (self->name || self->path) { + if (self->name || self->path || self->name_from) { dict = dict ? PyDict_Copy(dict) : PyDict_New(); if (dict == NULL) return NULL; @@ -1585,11 +1621,14 @@ ImportError_getstate(PyImportErrorObject *self) Py_DECREF(dict); return NULL; } + if (self->name_from && PyDict_SetItem(dict, &_Py_ID(name_from), self->name_from) < 0) { + Py_DECREF(dict); + return NULL; + } return dict; } else if (dict) { - Py_INCREF(dict); - return dict; + return Py_NewRef(dict); } else { Py_RETURN_NONE; @@ -1621,6 +1660,8 @@ static PyMemberDef ImportError_members[] = { PyDoc_STR("module name")}, {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0, PyDoc_STR("module path")}, + {"name_from", T_OBJECT, offsetof(PyImportErrorObject, name_from), 0, + PyDoc_STR("name imported from module")}, {NULL} /* Sentinel */ }; @@ -1714,8 +1755,7 @@ oserror_parse_args(PyObject **p_args, PyTuple_SET_ITEM(newargs, 0, *myerrno); for (i = 1; i < nargs; i++) { PyObject *val = PyTuple_GET_ITEM(args, i); - Py_INCREF(val); - PyTuple_SET_ITEM(newargs, i, val); + PyTuple_SET_ITEM(newargs, i, Py_NewRef(val)); } Py_DECREF(args); args = *p_args = newargs; @@ -1750,12 +1790,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, return -1; } else { - Py_INCREF(filename); - self->filename = filename; + self->filename = Py_NewRef(filename); if (filename2 && filename2 != Py_None) { - Py_INCREF(filename2); - self->filename2 = filename2; + self->filename2 = Py_NewRef(filename2); } if (nargs >= 2 && nargs <= 5) { @@ -1770,15 +1808,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, } } } - Py_XINCREF(myerrno); - self->myerrno = myerrno; - - Py_XINCREF(strerror); - self->strerror = strerror; - + self->myerrno = Py_XNewRef(myerrno); + self->strerror = Py_XNewRef(strerror); #ifdef MS_WINDOWS - Py_XINCREF(winerror); - self->winerror = winerror; + self->winerror = Py_XNewRef(winerror); #endif /* Steals the reference to args */ @@ -2004,7 +2037,7 @@ static PyObject * OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args = self->args; - PyObject *res = NULL, *tmp; + PyObject *res = NULL; /* self->args is only the first two real arguments if there was a * file name given to OSError. */ @@ -2014,16 +2047,9 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) if (!args) return NULL; - tmp = PyTuple_GET_ITEM(self->args, 0); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 0, tmp); - - tmp = PyTuple_GET_ITEM(self->args, 1); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 1, tmp); - - Py_INCREF(self->filename); - PyTuple_SET_ITEM(args, 2, self->filename); + PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0))); + PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1))); + PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename)); if (self->filename2) { /* @@ -2031,12 +2057,10 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) * So, to recreate filename2, we need to pass in * winerror as well. */ - Py_INCREF(Py_None); - PyTuple_SET_ITEM(args, 3, Py_None); + PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None)); /* filename2 */ - Py_INCREF(self->filename2); - PyTuple_SET_ITEM(args, 4, self->filename2); + PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2)); } } else Py_INCREF(args); @@ -2197,8 +2221,7 @@ NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); + Py_XSETREF(self->name, Py_XNewRef(name)); return 0; } @@ -2272,11 +2295,8 @@ AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(obj); - Py_XSETREF(self->obj, obj); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->obj, Py_XNewRef(obj)); return 0; } @@ -2305,6 +2325,48 @@ AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } +/* Pickling support */ +static PyObject * +AttributeError_getstate(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *dict = ((PyAttributeErrorObject *)self)->dict; + if (self->name || self->args) { + dict = dict ? PyDict_Copy(dict) : PyDict_New(); + if (dict == NULL) { + return NULL; + } + if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) { + Py_DECREF(dict); + return NULL; + } + /* We specifically are not pickling the obj attribute since there are many + cases where it is unlikely to be picklable. See GH-103352. + */ + if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) { + Py_DECREF(dict); + return NULL; + } + return dict; + } + else if (dict) { + return Py_NewRef(dict); + } + Py_RETURN_NONE; +} + +static PyObject * +AttributeError_reduce(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *state = AttributeError_getstate(self, NULL); + if (state == NULL) { + return NULL; + } + + PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state); + Py_DECREF(state); + return return_value; +} + static PyMemberDef AttributeError_members[] = { {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, @@ -2312,7 +2374,9 @@ static PyMemberDef AttributeError_members[] = { }; static PyMethodDef AttributeError_methods[] = { - {NULL} /* Sentinel */ + {"__getstate__", (PyCFunction)AttributeError_getstate, METH_NOARGS}, + {"__reduce__", (PyCFunction)AttributeError_reduce, METH_NOARGS }, + {NULL} }; ComplexExtendsException(PyExc_Exception, AttributeError, @@ -2334,8 +2398,7 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) return -1; if (lenargs >= 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); @@ -2431,8 +2494,7 @@ my_basename(PyObject *name) return PyUnicode_Substring(name, offset, size); } else { - Py_INCREF(name); - return name; + return Py_NewRef(name); } } @@ -2584,8 +2646,7 @@ get_string(PyObject *attr, const char *name) PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static PyObject * @@ -2601,8 +2662,7 @@ get_unicode(PyObject *attr, const char *name) "%.200s attribute must be unicode", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static int @@ -3235,19 +3295,18 @@ SimpleExtendsException(PyExc_Exception, ReferenceError, #define MEMERRORS_SAVE 16 static PyObject * -MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; - - /* If this is a subclass of MemoryError, don't use the freelist - * and just return a fresh object */ - if (type != (PyTypeObject *) PyExc_MemoryError) { - return BaseException_new(type, args, kwds); - } - struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_freelist == NULL) { - return BaseException_new(type, args, kwds); + if (!allow_allocation) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + return Py_NewRef( + &_Py_INTERP_SINGLETON(interp, last_resort_memory_error)); + } + PyObject *result = BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds); + return result; } /* Fetch object from freelist and revive it */ @@ -3267,6 +3326,33 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } +static PyObject * +MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + /* If this is a subclass of MemoryError, don't use the freelist + * and just return a fresh object */ + if (type != (PyTypeObject *) PyExc_MemoryError) { + return BaseException_new(type, args, kwds); + } + return get_memory_error(1, args, kwds); +} + +PyObject * +_PyErr_NoMemory(PyThreadState *tstate) +{ + if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { + /* PyErr_NoMemory() has been called before PyExc_MemoryError has been + initialized by _PyExc_Init() */ + Py_FatalError("Out of memory and PyExc_MemoryError is not " + "initialized yet"); + } + PyObject *err = get_memory_error(0, NULL, NULL); + if (err != NULL) { + _PyErr_SetRaisedException(tstate, err); + } + return NULL; +} + static void MemoryError_dealloc(PyBaseExceptionObject *self) { @@ -3298,6 +3384,7 @@ preallocate_memerrors(void) /* We create enough MemoryErrors and then decref them, which will fill up the freelist. */ int i; + PyObject *errors[MEMERRORS_SAVE]; for (i = 0; i < MEMERRORS_SAVE; i++) { errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError, @@ -3323,7 +3410,7 @@ free_preallocated_memerrors(struct _Py_exc_state *state) } -static PyTypeObject _PyExc_MemoryError = { +PyTypeObject _PyExc_MemoryError = { PyVarObject_HEAD_INIT(NULL, 0) "MemoryError", sizeof(PyBaseExceptionObject), @@ -3591,14 +3678,9 @@ static struct static_exception static_exceptions[] = { int _PyExc_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return 0; - } - for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { PyTypeObject *exc = static_exceptions[i].exc; - - if (PyType_Ready(exc) < 0) { + if (_PyStaticType_InitBuiltin(interp, exc) < 0) { return -1; } } @@ -3609,13 +3691,9 @@ _PyExc_InitTypes(PyInterpreterState *interp) static void _PyExc_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) { PyTypeObject *exc = static_exceptions[i].exc; - _PyStaticType_Dealloc(exc); + _PyStaticType_Dealloc(interp, exc); } } @@ -3623,10 +3701,6 @@ _PyExc_FiniTypes(PyInterpreterState *interp) PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - if (preallocate_memerrors() < 0) { return _PyStatus_NO_MEMORY(); } @@ -3750,130 +3824,18 @@ _PyExc_Fini(PyInterpreterState *interp) _PyExc_FiniTypes(interp); } -/* Helper to do the equivalent of "raise X from Y" in C, but always using - * the current exception rather than passing one in. - * - * We currently limit this to *only* exceptions that use the BaseException - * tp_init and tp_new methods, since we can be reasonably sure we can wrap - * those correctly without losing data and without losing backwards - * compatibility. - * - * We also aim to rule out *all* exceptions that might be storing additional - * state, whether by having a size difference relative to BaseException, - * additional arguments passed in during construction or by having a - * non-empty instance dict. - * - * We need to be very careful with what we wrap, since changing types to - * a broader exception type would be backwards incompatible for - * existing codecs, and with different init or new method implementations - * may either not support instantiation with PyErr_Format or lose - * information when instantiated that way. - * - * XXX (ncoghlan): This could be made more comprehensive by exploiting the - * fact that exceptions are expected to support pickling. If more builtin - * exceptions (e.g. AttributeError) start to be converted to rich - * exceptions with additional attributes, that's probably a better approach - * to pursue over adding special cases for particular stateful subclasses. - * - * Returns a borrowed reference to the new exception (if any), NULL if the - * existing exception was left in place. - */ -PyObject * -_PyErr_TrySetFromCause(const char *format, ...) +int +_PyException_AddNote(PyObject *exc, PyObject *note) { - PyObject* msg_prefix; - PyObject *exc, *val, *tb; - PyTypeObject *caught_type; - PyObject *instance_args; - Py_ssize_t num_args, caught_type_size, base_exc_size; - PyObject *new_exc, *new_val, *new_tb; - va_list vargs; - int same_basic_size; - - PyErr_Fetch(&exc, &val, &tb); - caught_type = (PyTypeObject *)exc; - /* Ensure type info indicates no extra state is stored at the C level - * and that the type can be reinstantiated using PyErr_Format - */ - caught_type_size = caught_type->tp_basicsize; - base_exc_size = _PyExc_BaseException.tp_basicsize; - same_basic_size = ( - caught_type_size == base_exc_size || - (_PyType_SUPPORTS_WEAKREFS(caught_type) && - (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) - ) - ); - if (caught_type->tp_init != (initproc)BaseException_init || - caught_type->tp_new != BaseException_new || - !same_basic_size || - caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) { - /* We can't be sure we can wrap this safely, since it may contain - * more state than just the exception type. Accordingly, we just - * leave it alone. - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* Check the args are empty or contain a single string */ - PyErr_NormalizeException(&exc, &val, &tb); - instance_args = ((PyBaseExceptionObject *)val)->args; - num_args = PyTuple_GET_SIZE(instance_args); - if (num_args > 1 || - (num_args == 1 && - !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) { - /* More than 1 arg, or the one arg we do have isn't a string - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* Ensure the instance dict is also empty */ - if (!_PyObject_IsInstanceDictEmpty(val)) { - /* While we could potentially copy a non-empty instance dictionary - * to the replacement exception, for now we take the more - * conservative path of leaving exceptions with attributes set - * alone. - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* For exceptions that we can wrap safely, we chain the original - * exception to a new one of the exact same type with an - * error message that mentions the additional details and the - * original exception. - * - * It would be nice to wrap OSError and various other exception - * types as well, but that's quite a bit trickier due to the extra - * state potentially stored on OSError instances. - */ - /* Ensure the traceback is set correctly on the existing exception */ - if (tb != NULL) { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - msg_prefix = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - if (msg_prefix == NULL) { - Py_DECREF(exc); - Py_DECREF(val); - return NULL; + if (!PyExceptionInstance_Check(exc)) { + PyErr_Format(PyExc_TypeError, + "exc must be an exception, not '%s'", + Py_TYPE(exc)->tp_name); + return -1; } - - PyErr_Format(exc, "%U (%s: %S)", - msg_prefix, Py_TYPE(val)->tp_name, val); - Py_DECREF(exc); - Py_DECREF(msg_prefix); - PyErr_Fetch(&new_exc, &new_val, &new_tb); - PyErr_NormalizeException(&new_exc, &new_val, &new_tb); - PyException_SetCause(new_val, val); - PyErr_Restore(new_exc, new_val, new_tb); - return new_val; + PyObject *r = BaseException_add_note(exc, note); + int res = r == NULL ? -1 : 0; + Py_XDECREF(r); + return res; } + diff --git a/contrib/tools/python3/src/Objects/fileobject.c b/contrib/tools/python3/src/Objects/fileobject.c index ffe55eb7c37..e99e155f2b8 100644 --- a/contrib/tools/python3/src/Objects/fileobject.c +++ b/contrib/tools/python3/src/Objects/fileobject.c @@ -32,16 +32,16 @@ PyObject * PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) { - PyObject *io, *stream; + PyObject *open, *stream; /* import _io in case we are being used to open io.py */ - io = PyImport_ImportModule("_io"); - if (io == NULL) + open = _PyImport_GetModuleAttrString("_io", "open"); + if (open == NULL) return NULL; - stream = _PyObject_CallMethod(io, &_Py_ID(open), "isisssO", fd, mode, + stream = PyObject_CallFunction(open, "isisssO", fd, mode, buffering, encoding, errors, newline, closefd ? Py_True : Py_False); - Py_DECREF(io); + Py_DECREF(open); if (stream == NULL) return NULL; /* ignore name attribute because the name attribute of _BufferedIOMixin @@ -67,8 +67,7 @@ PyFile_GetLine(PyObject *f, int n) } if (result != NULL && !PyBytes_Check(result) && !PyUnicode_Check(result)) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_TypeError, "object.readline() returned non-string"); } @@ -77,8 +76,7 @@ PyFile_GetLine(PyObject *f, int n) const char *s = PyBytes_AS_STRING(result); Py_ssize_t len = PyBytes_GET_SIZE(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } @@ -88,24 +86,21 @@ PyFile_GetLine(PyObject *f, int n) else { PyObject *v; v = PyBytes_FromStringAndSize(s, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } } if (n < 0 && result != NULL && PyUnicode_Check(result)) { Py_ssize_t len = PyUnicode_GET_LENGTH(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } else if (PyUnicode_READ_CHAR(result, len-1) == '\n') { PyObject *v; v = PyUnicode_Substring(result, 0, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } return result; @@ -499,7 +494,7 @@ PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { PyObject * PyFile_OpenCodeObject(PyObject *path) { - PyObject *iomod, *f = NULL; + PyObject *f = NULL; if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", @@ -511,10 +506,10 @@ PyFile_OpenCodeObject(PyObject *path) if (hook) { f = hook(path, _PyRuntime.open_code_userdata); } else { - iomod = PyImport_ImportModule("_io"); - if (iomod) { - f = _PyObject_CallMethod(iomod, &_Py_ID(open), "Os", path, "rb"); - Py_DECREF(iomod); + PyObject *open = _PyImport_GetModuleAttrString("_io", "open"); + if (open) { + f = PyObject_CallFunction(open, "Os", path, "rb"); + Py_DECREF(open); } } diff --git a/contrib/tools/python3/src/Objects/floatobject.c b/contrib/tools/python3/src/Objects/floatobject.c index be6024659ab..83a263c0d9c 100644 --- a/contrib/tools/python3/src/Objects/floatobject.c +++ b/contrib/tools/python3/src/Objects/floatobject.c @@ -12,7 +12,7 @@ #include "pycore_object.h" // _PyObject_Init() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include <ctype.h> #include <float.h> @@ -371,8 +371,7 @@ convert_to_double(PyObject **v, double *dbl) } } else { - Py_INCREF(Py_NotImplemented); - *v = Py_NotImplemented; + *v = Py_NewRef(Py_NotImplemented); return -1; } return 0; @@ -532,20 +531,17 @@ float_richcompare(PyObject *v, PyObject *w, int op) temp = _PyLong_Lshift(ww, 1); if (temp == NULL) goto Error; - Py_DECREF(ww); - ww = temp; + Py_SETREF(ww, temp); temp = _PyLong_Lshift(vv, 1); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); temp = PyNumber_Or(vv, _PyLong_GetOne()); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); } r = PyObject_RichCompareBool(vv, ww, op); @@ -904,8 +900,7 @@ float_is_integer_impl(PyObject *self) PyExc_ValueError); return NULL; } - Py_INCREF(o); - return o; + return Py_NewRef(o); } /*[clinic input] @@ -1124,11 +1119,12 @@ float___round___impl(PyObject *self, PyObject *o_ndigits) static PyObject * float_float(PyObject *v) { - if (PyFloat_CheckExact(v)) - Py_INCREF(v); - else - v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); - return v; + if (PyFloat_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); + } } /*[clinic input] @@ -1550,12 +1546,10 @@ float_fromhex(PyTypeObject *type, PyObject *string) /*[clinic input] float.as_integer_ratio -Return integer ratio. +Return a pair of integers, whose ratio is exactly equal to the original float. -Return a pair of integers, whose ratio is exactly equal to the original float -and with a positive denominator. - -Raise OverflowError on infinities and a ValueError on NaNs. +The ratio is in lowest terms and has a positive denominator. Raise +OverflowError on infinities and a ValueError on NaNs. >>> (10.0).as_integer_ratio() (10, 1) @@ -1567,7 +1561,7 @@ Raise OverflowError on infinities and a ValueError on NaNs. static PyObject * float_as_integer_ratio_impl(PyObject *self) -/*[clinic end generated code: output=65f25f0d8d30a712 input=e21d08b4630c2e44]*/ +/*[clinic end generated code: output=65f25f0d8d30a712 input=d5ba7765655d75bd]*/ { double self_double; double float_part; @@ -1724,12 +1718,14 @@ float___getnewargs___impl(PyObject *self) } /* this is for the benefit of the pack/unpack routines below */ +typedef enum _py_float_format_type float_format_type; +#define unknown_format _py_float_format_unknown +#define ieee_big_endian_format _py_float_format_ieee_big_endian +#define ieee_little_endian_format _py_float_format_ieee_little_endian -typedef enum { - unknown_format, ieee_big_endian_format, ieee_little_endian_format -} float_format_type; +#define float_format (_PyRuntime.float_state.float_format) +#define double_format (_PyRuntime.float_state.double_format) -static float_format_type double_format, float_format; /*[clinic input] @classmethod @@ -1930,13 +1926,9 @@ PyTypeObject PyFloat_Type = { .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; -void -_PyFloat_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - float_format_type detected_double_format, detected_float_format; /* We attempt to determine if this machine is using IEEE @@ -1986,22 +1978,23 @@ _PyFloat_InitState(PyInterpreterState *interp) float_format = detected_float_format; } -PyStatus -_PyFloat_InitTypes(PyInterpreterState *interp) +void +_PyFloat_InitState(PyInterpreterState *interp) { if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyFloat_Type) < 0) { - return _PyStatus_ERR("Can't initialize float type"); + return; } + _init_global_state(); +} +PyStatus +_PyFloat_InitTypes(PyInterpreterState *interp) +{ /* Init float info */ - if (FloatInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { - return _PyStatus_ERR("can't init float info type"); - } + if (_PyStructSequence_InitBuiltin(interp, &FloatInfoType, + &floatinfo_desc) < 0) + { + return _PyStatus_ERR("can't init float info type"); } return _PyStatus_OK(); @@ -2036,9 +2029,7 @@ _PyFloat_Fini(PyInterpreterState *interp) void _PyFloat_FiniType(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - _PyStructSequence_FiniType(&FloatInfoType); - } + _PyStructSequence_FiniBuiltin(interp, &FloatInfoType); } /* Print summary info about the state of the optimized allocator */ @@ -2433,25 +2424,14 @@ PyFloat_Unpack2(const char *data, int le) f |= *p; if (e == 0x1f) { -#if _PY_SHORT_FLOAT_REPR == 0 if (f == 0) { /* Infinity */ return sign ? -Py_HUGE_VAL : Py_HUGE_VAL; } else { /* NaN */ - return sign ? -Py_NAN : Py_NAN; - } -#else // _PY_SHORT_FLOAT_REPR == 1 - if (f == 0) { - /* Infinity */ - return _Py_dg_infinity(sign); - } - else { - /* NaN */ - return _Py_dg_stdnan(sign); + return sign ? -fabs(Py_NAN) : fabs(Py_NAN); } -#endif // _PY_SHORT_FLOAT_REPR == 1 } x = (double)f / 1024.0; diff --git a/contrib/tools/python3/src/Objects/frameobject.c b/contrib/tools/python3/src/Objects/frameobject.c index c95e8711880..d33c3cde526 100644 --- a/contrib/tools/python3/src/Objects/frameobject.c +++ b/contrib/tools/python3/src/Objects/frameobject.c @@ -17,7 +17,6 @@ static PyMemberDef frame_memberlist[] = { {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, - {"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0}, {NULL} /* Sentinel */ }; @@ -25,10 +24,15 @@ static PyMemberDef frame_memberlist[] = { static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - if (PyFrame_FastToLocalsWithError(f) < 0) + if (f == NULL) { + PyErr_BadInternalCall(); return NULL; - PyObject *locals = f->f_frame->f_locals; - Py_INCREF(locals); + } + assert(!_PyFrame_IsIncomplete(f->f_frame)); + PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1); + if (locals) { + f->f_fast_as_locals = 1; + } return locals; } @@ -40,7 +44,7 @@ PyFrame_GetLineNumber(PyFrameObject *f) return f->f_lineno; } else { - return _PyInterpreterFrame_GetLine(f->f_frame); + return PyUnstable_InterpreterFrame_GetLine(f->f_frame); } } @@ -73,8 +77,7 @@ frame_getglobals(PyFrameObject *f, void *closure) if (globals == NULL) { globals = Py_None; } - Py_INCREF(globals); - return globals; + return Py_NewRef(globals); } static PyObject * @@ -84,8 +87,7 @@ frame_getbuiltins(PyFrameObject *f, void *closure) if (builtins == NULL) { builtins = Py_None; } - Py_INCREF(builtins); - return builtins; + return Py_NewRef(builtins); } static PyObject * @@ -107,24 +109,29 @@ frame_getback(PyFrameObject *f, void *closure) return res; } -// Given the index of the effective opcode, scan back to construct the oparg -// with EXTENDED_ARG. This only works correctly with *unquickened* code, -// obtained via a call to _PyCode_GetCode! -static unsigned int -get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) +static PyObject * +frame_gettrace_opcodes(PyFrameObject *f, void *closure) { - _Py_CODEUNIT word; - unsigned int oparg = _Py_OPARG(codestr[i]); - if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 8; - if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 16; - if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 24; - } - } + PyObject *result = f->f_trace_opcodes ? Py_True : Py_False; + return Py_NewRef(result); +} + +static int +frame_settrace_opcodes(PyFrameObject *f, PyObject* value, void *Py_UNUSED(ignored)) +{ + if (!PyBool_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "attribute value type must be bool"); + return -1; + } + if (value == Py_True) { + f->f_trace_opcodes = 1; + _PyInterpreterState_GET()->f_opcode_trace_set = true; + } + else { + f->f_trace_opcodes = 0; } - return oparg; + return 0; } /* Model the evaluation stack, to determine which jumps @@ -302,77 +309,54 @@ mark_stacks(PyCodeObject *code_obj, int len) while (todo) { todo = 0; /* Scan instructions */ - for (i = 0; i < len; i++) { + for (i = 0; i < len;) { int64_t next_stack = stacks[i]; + opcode = _Py_GetBaseOpcode(code_obj, i); + int oparg = 0; + while (opcode == EXTENDED_ARG) { + oparg = (oparg << 8) | code[i].op.arg; + i++; + opcode = _Py_GetBaseOpcode(code_obj, i); + stacks[i] = next_stack; + } + int next_i = i + _PyOpcode_Caches[opcode] + 1; if (next_stack == UNINITIALIZED) { + i = next_i; continue; } - opcode = _Py_OPCODE(code[i]); + oparg = (oparg << 8) | code[i].op.arg; switch (opcode) { - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_FORWARD_IF_FALSE: - case POP_JUMP_BACKWARD_IF_FALSE: - case POP_JUMP_FORWARD_IF_TRUE: - case POP_JUMP_BACKWARD_IF_TRUE: - case POP_JUMP_FORWARD_IF_NONE: - case POP_JUMP_BACKWARD_IF_NONE: - case POP_JUMP_FORWARD_IF_NOT_NONE: - case POP_JUMP_BACKWARD_IF_NOT_NONE: + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: { int64_t target_stack; - int j = get_arg(code, i); - if (opcode == POP_JUMP_FORWARD_IF_FALSE || - opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == JUMP_IF_FALSE_OR_POP || - opcode == JUMP_IF_TRUE_OR_POP || - opcode == POP_JUMP_FORWARD_IF_NONE || - opcode == POP_JUMP_FORWARD_IF_NOT_NONE) - { - j += i + 1; - } - else { - assert(opcode == POP_JUMP_BACKWARD_IF_FALSE || - opcode == POP_JUMP_BACKWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_NONE || - opcode == POP_JUMP_BACKWARD_IF_NOT_NONE); - j = i + 1 - j; - } + int j = next_i + oparg; assert(j < len); - if (stacks[j] == UNINITIALIZED && j < i) { - todo = 1; - } - if (opcode == JUMP_IF_FALSE_OR_POP || - opcode == JUMP_IF_TRUE_OR_POP) - { - target_stack = next_stack; - next_stack = pop_value(next_stack); - } - else { - next_stack = pop_value(next_stack); - target_stack = next_stack; - } + next_stack = pop_value(next_stack); + target_stack = next_stack; assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack); stacks[j] = target_stack; - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case SEND: - j = get_arg(code, i) + i + 1; + j = oparg + i + INLINE_CACHE_ENTRIES_SEND + 1; assert(j < len); - assert(stacks[j] == UNINITIALIZED || stacks[j] == pop_value(next_stack)); - stacks[j] = pop_value(next_stack); - stacks[i+1] = next_stack; + assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); + stacks[j] = next_stack; + stacks[next_i] = next_stack; break; case JUMP_FORWARD: - j = get_arg(code, i) + i + 1; + j = oparg + i + 1; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); stacks[j] = next_stack; break; case JUMP_BACKWARD: case JUMP_BACKWARD_NO_INTERRUPT: - j = i + 1 - get_arg(code, i); + j = i + 1 - oparg; assert(j >= 0); assert(j < len); if (stacks[j] == UNINITIALIZED && j < i) { @@ -384,13 +368,13 @@ mark_stacks(PyCodeObject *code_obj, int len) case GET_ITER: case GET_AITER: next_stack = push_value(pop_value(next_stack), Iterator); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case FOR_ITER: { - int64_t target_stack = pop_value(next_stack); - stacks[i+1] = push_value(next_stack, Object); - j = get_arg(code, i) + i + 1; + int64_t target_stack = push_value(next_stack, Object); + stacks[next_i] = target_stack; + j = oparg + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + i; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack); stacks[j] = target_stack; @@ -398,21 +382,23 @@ mark_stacks(PyCodeObject *code_obj, int len) } case END_ASYNC_FOR: next_stack = pop_value(pop_value(next_stack)); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case PUSH_EXC_INFO: next_stack = push_value(next_stack, Except); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case POP_EXCEPT: assert(top_of_stack(next_stack) == Except); next_stack = pop_value(next_stack); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case RETURN_VALUE: assert(pop_value(next_stack) == EMPTY_STACK); assert(top_of_stack(next_stack) == Object); break; + case RETURN_CONST: + break; case RAISE_VARARGS: break; case RERAISE: @@ -421,46 +407,62 @@ mark_stacks(PyCodeObject *code_obj, int len) break; case PUSH_NULL: next_stack = push_value(next_stack, Null); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case LOAD_GLOBAL: - if (_Py_OPARG(code[i]) & 1) { + { + int j = oparg; + if (j & 1) { next_stack = push_value(next_stack, Null); } next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; - case LOAD_METHOD: + } + case LOAD_ATTR: + { assert(top_of_stack(next_stack) == Object); - next_stack = pop_value(next_stack); - next_stack = push_value(next_stack, Null); - next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + int j = oparg; + if (j & 1) { + next_stack = pop_value(next_stack); + next_stack = push_value(next_stack, Null); + next_stack = push_value(next_stack, Object); + } + stacks[next_i] = next_stack; break; + } case CALL: { - next_stack = pop_value(pop_value(next_stack)); + int args = oparg; + for (int j = 0; j < args+2; j++) { + next_stack = pop_value(next_stack); + } next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case SWAP: { - int n = get_arg(code, i); + int n = oparg; next_stack = stack_swap(next_stack, n); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case COPY: { - int n = get_arg(code, i); + int n = oparg; next_stack = push_value(next_stack, peek(next_stack, n)); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } + case CACHE: + case RESERVED: + { + assert(0); + } default: { - int delta = PyCompile_OpcodeStackEffect(opcode, get_arg(code, i)); + int delta = PyCompile_OpcodeStackEffect(opcode, oparg); assert(delta != PY_INVALID_STACK_EFFECT); while (delta < 0) { next_stack = pop_value(next_stack); @@ -470,9 +472,10 @@ mark_stacks(PyCodeObject *code_obj, int len) next_stack = push_value(next_stack, Object); delta--; } - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; } } + i = next_i; } /* Scan exception table */ unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code_obj->co_exceptiontable); @@ -613,7 +616,7 @@ _PyFrame_GetState(PyFrameObject *frame) if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { return FRAME_CREATED; } - switch (_PyOpcode_Deopt[_Py_OPCODE(*frame->f_frame->prev_instr)]) + switch (frame->f_frame->prev_instr->op.code) { case COPY_FREE_VARS: case MAKE_CELL: @@ -630,7 +633,6 @@ _PyFrame_GetState(PyFrameObject *frame) Py_UNREACHABLE(); } - /* Setter for f_lineno - you can set f_lineno from within a trace function in * order to jump to a given line of code, subject to some restrictions. Most * lines are OK to jump to because they don't make any assumptions about the @@ -668,31 +670,43 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore * In addition, jumps are forbidden when not tracing, * as this is a debugging feature. */ - switch(PyThreadState_GET()->tracing_what) { - case PyTrace_EXCEPTION: - PyErr_SetString(PyExc_ValueError, - "can only jump from a 'line' trace event"); - return -1; - case PyTrace_CALL: + int what_event = PyThreadState_GET()->what_event; + if (what_event < 0) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set in a trace function"); + return -1; + } + switch (what_event) { + case PY_MONITORING_EVENT_PY_RESUME: + case PY_MONITORING_EVENT_JUMP: + case PY_MONITORING_EVENT_BRANCH: + case PY_MONITORING_EVENT_LINE: + case PY_MONITORING_EVENT_PY_YIELD: + /* Setting f_lineno is allowed for the above events */ + break; + case PY_MONITORING_EVENT_PY_START: PyErr_Format(PyExc_ValueError, "can't jump from the 'call' trace event of a new frame"); return -1; - case PyTrace_LINE: - break; - case PyTrace_RETURN: - if (state == FRAME_SUSPENDED) { - break; - } - /* fall through */ - default: + case PY_MONITORING_EVENT_CALL: + case PY_MONITORING_EVENT_C_RETURN: PyErr_SetString(PyExc_ValueError, + "can't jump during a call"); + return -1; + case PY_MONITORING_EVENT_PY_RETURN: + case PY_MONITORING_EVENT_PY_UNWIND: + case PY_MONITORING_EVENT_PY_THROW: + case PY_MONITORING_EVENT_RAISE: + case PY_MONITORING_EVENT_C_RAISE: + case PY_MONITORING_EVENT_INSTRUCTION: + case PY_MONITORING_EVENT_EXCEPTION_HANDLED: + PyErr_Format(PyExc_ValueError, "can only jump from a 'line' trace event"); return -1; - } - if (!f->f_trace) { - PyErr_Format(PyExc_ValueError, - "f_lineno can only be set by a trace function"); - return -1; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected event type"); + return -1; } int new_lineno; @@ -778,6 +792,31 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore PyErr_SetString(PyExc_ValueError, msg); return -1; } + // Populate any NULL locals that the compiler might have "proven" to exist + // in the new location. Rather than crashing or changing co_code, just bind + // None instead: + int unbound = 0; + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + // Counting every unbound local is overly-cautious, but a full flow + // analysis (like we do in the compiler) is probably too expensive: + unbound += f->f_frame->localsplus[i] == NULL; + } + if (unbound) { + const char *e = "assigning None to %d unbound local%s"; + const char *s = (unbound == 1) ? "" : "s"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, unbound, s)) { + return -1; + } + // Do this in a second pass to avoid writing a bunch of Nones when + // warnings are being treated as errors and the previous bit raises: + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + if (f->f_frame->localsplus[i] == NULL) { + f->f_frame->localsplus[i] = Py_NewRef(Py_None); + unbound--; + } + } + assert(unbound == 0); + } if (state == FRAME_SUSPENDED) { /* Account for value popped by yield */ start_stack = pop_value(start_stack); @@ -809,13 +848,9 @@ static PyObject * frame_gettrace(PyFrameObject *f, void *closure) { PyObject* trace = f->f_trace; - if (trace == NULL) trace = Py_None; - - Py_INCREF(trace); - - return trace; + return Py_NewRef(trace); } static int @@ -824,9 +859,9 @@ frame_settrace(PyFrameObject *f, PyObject* v, void *closure) if (v == Py_None) { v = NULL; } - Py_XINCREF(v); - Py_XSETREF(f->f_trace, v); - + if (v != f->f_trace) { + Py_XSETREF(f->f_trace, Py_XNewRef(v)); + } return 0; } @@ -841,18 +876,10 @@ static PyGetSetDef frame_getsetlist[] = { {"f_globals", (getter)frame_getglobals, NULL, NULL}, {"f_builtins", (getter)frame_getbuiltins, NULL, NULL}, {"f_code", (getter)frame_getcode, NULL, NULL}, + {"f_trace_opcodes", (getter)frame_gettrace_opcodes, (setter)frame_settrace_opcodes, NULL}, {0} }; -/* Stack frames are allocated and deallocated at a considerable rate. - In an attempt to improve the speed of function calls, we maintain - a separate free list of stack frames (just like floats are - allocated in a special way -- see floatobject.c). When a stack - frame is on the free list, only the following members have a meaning: - ob_type == &Frametype - f_back next item on free list, or NULL -*/ - static void frame_dealloc(PyFrameObject *f) { @@ -877,7 +904,7 @@ frame_dealloc(PyFrameObject *f) /* Don't clear code object until the end */ co = frame->f_code; frame->f_code = NULL; - Py_CLEAR(frame->f_func); + Py_CLEAR(frame->f_funcobj); Py_CLEAR(frame->f_locals); PyObject **locals = _PyFrame_GetLocalsArray(frame); for (int i = 0; i < frame->stacktop; i++) { @@ -951,7 +978,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) Py_ssize_t res; res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus); PyCodeObject *code = f->f_frame->f_code; - res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *); + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); return PyLong_FromSsize_t(res); } @@ -1015,14 +1042,10 @@ PyTypeObject PyFrame_Type = { static void init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals) { - /* _PyFrame_InitializeSpecials consumes reference to func */ - Py_INCREF(func); PyCodeObject *code = (PyCodeObject *)func->func_code; - _PyFrame_InitializeSpecials(frame, func, locals, code->co_nlocalsplus); + _PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func), + Py_XNewRef(locals), code, 0); frame->previous = NULL; - for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) { - frame->localsplus[i] = NULL; - } } PyFrameObject* @@ -1091,8 +1114,8 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) for (_Py_CODEUNIT *instruction = _PyCode_CODE(frame->f_code); instruction < frame->prev_instr; instruction++) { - int check_opcode = _PyOpcode_Deopt[_Py_OPCODE(*instruction)]; - check_oparg |= _Py_OPARG(*instruction); + int check_opcode = _PyOpcode_Deopt[instruction->op.code]; + check_oparg |= instruction->op.arg; if (check_opcode == opcode && check_oparg == oparg) { return 1; } @@ -1107,79 +1130,127 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) return 0; } -int -_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { + +// Initialize frame free variables if needed +static void +frame_init_get_vars(_PyInterpreterFrame *frame) +{ + // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + PyCodeObject *co = frame->f_code; + int lasti = _PyInterpreterFrame_LASTI(frame); + if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS + && PyFunction_Check(frame->f_funcobj))) + { + /* Free vars are initialized */ + return; + } + + /* Free vars have not been initialized -- Do that */ + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + int offset = PyCode_GetFirstFree(co); + for (int i = 0; i < co->co_nfreevars; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + // COPY_FREE_VARS doesn't have inline CACHEs, either: + frame->prev_instr = _PyCode_CODE(frame->f_code); +} + + +static int +frame_get_var(_PyInterpreterFrame *frame, PyCodeObject *co, int i, + PyObject **pvalue) +{ + _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); + + /* If the namespace is unoptimized, then one of the + following cases applies: + 1. It does not contain free variables, because it + uses import * or is a top-level namespace. + 2. It is a class namespace. + We don't want to accidentally copy free variables + into the locals dict used by the class. + */ + if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + return 0; + } + + PyObject *value = frame->localsplus[i]; + if (frame->stacktop) { + if (kind & CO_FAST_FREE) { + // The cell was set by COPY_FREE_VARS. + assert(value != NULL && PyCell_Check(value)); + value = PyCell_GET(value); + } + else if (kind & CO_FAST_CELL) { + // Note that no *_DEREF ops can happen before MAKE_CELL + // executes. So there's no need to duplicate the work + // that MAKE_CELL would otherwise do later, if it hasn't + // run yet. + if (value != NULL) { + if (PyCell_Check(value) && + _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { + // (likely) MAKE_CELL must have executed already. + value = PyCell_GET(value); + } + // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), + // with the initial value set when the frame was created... + // (unlikely) ...or it was set to some initial value by + // an earlier call to PyFrame_LocalsToFast(). + } + } + } + else { + assert(value == NULL); + } + *pvalue = value; + return 1; +} + + +PyObject * +_PyFrame_GetLocals(_PyInterpreterFrame *frame, int include_hidden) +{ /* Merge fast locals into f->f_locals */ - PyObject *locals; - PyObject **fast; - PyCodeObject *co; - locals = frame->f_locals; + PyObject *locals = frame->f_locals; if (locals == NULL) { locals = frame->f_locals = PyDict_New(); - if (locals == NULL) - return -1; + if (locals == NULL) { + return NULL; + } } - co = frame->f_code; - fast = _PyFrame_GetLocalsArray(frame); - // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt - // here: - int lasti = _PyInterpreterFrame_LASTI(frame); - if (lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS) { - /* Free vars have not been initialized -- Do that */ - PyCodeObject *co = frame->f_code; - PyObject *closure = frame->f_func->func_closure; - int offset = co->co_nlocals + co->co_nplaincellvars; - for (int i = 0; i < co->co_nfreevars; ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); - Py_INCREF(o); - frame->localsplus[offset + i] = o; + PyObject *hidden = NULL; + + /* If include_hidden, "hidden" fast locals (from inlined comprehensions in + module/class scopes) will be included in the returned dict, but not in + frame->f_locals; the returned dict will be a modified copy. Non-hidden + locals will still be updated in frame->f_locals. */ + if (include_hidden) { + hidden = PyDict_New(); + if (hidden == NULL) { + return NULL; } - // COPY_FREE_VARS doesn't have inline CACHEs, either: - frame->prev_instr = _PyCode_CODE(frame->f_code); } - for (int i = 0; i < co->co_nlocalsplus; i++) { - _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); - /* If the namespace is unoptimized, then one of the - following cases applies: - 1. It does not contain free variables, because it - uses import * or is a top-level namespace. - 2. It is a class namespace. - We don't want to accidentally copy free variables - into the locals dict used by the class. - */ - if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { continue; } PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); - PyObject *value = fast[i]; - if (frame->stacktop) { - if (kind & CO_FAST_FREE) { - // The cell was set by COPY_FREE_VARS. - assert(value != NULL && PyCell_Check(value)); - value = PyCell_GET(value); - } - else if (kind & CO_FAST_CELL) { - // Note that no *_DEREF ops can happen before MAKE_CELL - // executes. So there's no need to duplicate the work - // that MAKE_CELL would otherwise do later, if it hasn't - // run yet. - if (value != NULL) { - if (PyCell_Check(value) && - _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { - // (likely) MAKE_CELL must have executed already. - value = PyCell_GET(value); - } - // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), - // with the initial value set when the frame was created... - // (unlikely) ...or it was set to some initial value by - // an earlier call to PyFrame_LocalsToFast(). + _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); + if (kind & CO_FAST_HIDDEN) { + if (include_hidden && value != NULL) { + if (PyObject_SetItem(hidden, name, value) != 0) { + goto error; } } - } - else { - assert(value == NULL); + continue; } if (value == NULL) { if (PyObject_DelItem(locals, name) != 0) { @@ -1187,27 +1258,112 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { PyErr_Clear(); } else { - return -1; + goto error; } } } else { if (PyObject_SetItem(locals, name, value) != 0) { - return -1; + goto error; } } } + + if (include_hidden && PyDict_Size(hidden)) { + PyObject *innerlocals = PyDict_New(); + if (innerlocals == NULL) { + goto error; + } + if (PyDict_Merge(innerlocals, locals, 1) != 0) { + Py_DECREF(innerlocals); + goto error; + } + if (PyDict_Merge(innerlocals, hidden, 1) != 0) { + Py_DECREF(innerlocals); + goto error; + } + locals = innerlocals; + } + else { + Py_INCREF(locals); + } + Py_CLEAR(hidden); + + return locals; + + error: + Py_XDECREF(hidden); + return NULL; +} + + +int +_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) +{ + PyObject *locals = _PyFrame_GetLocals(frame, 0); + if (locals == NULL) { + return -1; + } + Py_DECREF(locals); return 0; } + +PyObject * +PyFrame_GetVar(PyFrameObject *frame_obj, PyObject *name) +{ + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, "name must be str, not %s", + Py_TYPE(name)->tp_name); + return NULL; + } + + _PyInterpreterFrame *frame = frame_obj->f_frame; + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *var_name = PyTuple_GET_ITEM(co->co_localsplusnames, i); + if (!_PyUnicode_Equal(var_name, name)) { + continue; + } + + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { + break; + } + if (value == NULL) { + break; + } + return Py_NewRef(value); + } + + PyErr_Format(PyExc_NameError, "variable %R does not exist", name); + return NULL; +} + + +PyObject * +PyFrame_GetVarString(PyFrameObject *frame, const char *name) +{ + PyObject *name_obj = PyUnicode_FromString(name); + if (name_obj == NULL) { + return NULL; + } + PyObject *value = PyFrame_GetVar(frame, name_obj); + Py_DECREF(name_obj); + return value; +} + + int PyFrame_FastToLocalsWithError(PyFrameObject *f) { - assert(!_PyFrame_IsIncomplete(f->f_frame)); if (f == NULL) { PyErr_BadInternalCall(); return -1; } + assert(!_PyFrame_IsIncomplete(f->f_frame)); int err = _PyFrame_FastToLocalsWithError(f->f_frame); if (err == 0) { f->f_fast_as_locals = 1; @@ -1233,7 +1389,6 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) /* Merge locals into fast locals */ PyObject *locals; PyObject **fast; - PyObject *error_type, *error_value, *error_traceback; PyCodeObject *co; locals = frame->f_locals; if (locals == NULL) { @@ -1242,7 +1397,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) fast = _PyFrame_GetLocalsArray(frame); co = frame->f_code; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); for (int i = 0; i < co->co_nlocalsplus; i++) { _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); @@ -1280,18 +1435,26 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) if (cell != NULL) { oldvalue = PyCell_GET(cell); if (value != oldvalue) { + PyCell_SET(cell, Py_XNewRef(value)); Py_XDECREF(oldvalue); - Py_XINCREF(value); - PyCell_SET(cell, value); } } else if (value != oldvalue) { - Py_XINCREF(value); - Py_XSETREF(fast[i], value); + if (value == NULL) { + // Probably can't delete this, since the compiler's flow + // analysis may have already "proven" that it exists here: + const char *e = "assigning None to unbound local %R"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, name)) { + // It's okay if frame_obj is NULL, just try anyways: + PyErr_WriteUnraisable((PyObject *)frame->frame_obj); + } + value = Py_NewRef(Py_None); + } + Py_XSETREF(fast[i], Py_NewRef(value)); } Py_XDECREF(value); } - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } void @@ -1304,15 +1467,15 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) } } - -int _PyFrame_IsEntryFrame(PyFrameObject *frame) +int +_PyFrame_IsEntryFrame(PyFrameObject *frame) { assert(frame != NULL); - assert(!_PyFrame_IsIncomplete(frame->f_frame)); - return frame->f_frame->is_entry; + _PyInterpreterFrame *f = frame->f_frame; + assert(!_PyFrame_IsIncomplete(f)); + return f->previous && f->previous->owner == FRAME_OWNED_BY_CSTACK; } - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) { @@ -1320,8 +1483,7 @@ PyFrame_GetCode(PyFrameObject *frame) assert(!_PyFrame_IsIncomplete(frame->f_frame)); PyCodeObject *code = frame->f_frame->f_code; assert(code != NULL); - Py_INCREF(code); - return code; + return (PyCodeObject*)Py_NewRef(code); } @@ -1333,15 +1495,12 @@ PyFrame_GetBack(PyFrameObject *frame) PyFrameObject *back = frame->f_back; if (back == NULL) { _PyInterpreterFrame *prev = frame->f_frame->previous; - while (prev && _PyFrame_IsIncomplete(prev)) { - prev = prev->previous; - } + prev = _PyFrame_GetFirstComplete(prev); if (prev) { back = _PyFrame_GetFrameObject(prev); } } - Py_XINCREF(back); - return back; + return (PyFrameObject*)Py_XNewRef(back); } PyObject* @@ -1404,5 +1563,3 @@ _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) return _PyEval_GetBuiltins(tstate); } - - diff --git a/contrib/tools/python3/src/Objects/funcobject.c b/contrib/tools/python3/src/Objects/funcobject.c index 3a0553261bf..f43e3a2787b 100644 --- a/contrib/tools/python3/src/Objects/funcobject.c +++ b/contrib/tools/python3/src/Objects/funcobject.c @@ -3,45 +3,137 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_code.h" // _Py_next_func_version #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "structmember.h" // PyMemberDef -static uint32_t next_func_version = 1; +static PyObject* func_repr(PyFunctionObject *op); +static const char * +func_event_name(PyFunction_WatchEvent event) { + switch (event) { + #define CASE(op) \ + case PyFunction_EVENT_##op: \ + return "PyFunction_EVENT_" #op; + PY_FOREACH_FUNC_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +static void +notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + uint8_t bits = interp->active_func_watchers; + int i = 0; + while (bits) { + assert(i < FUNC_MAX_WATCHERS); + if (bits & 1) { + PyFunction_WatchCallback cb = interp->func_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, func, new_value) < 0) { + // Don't risk resurrecting the func if an unraisablehook keeps a + // reference; pass a string as context. + PyObject *context = NULL; + PyObject *repr = func_repr(func); + if (repr != NULL) { + context = PyUnicode_FromFormat( + "%s watcher callback for %U", + func_event_name(event), repr); + Py_DECREF(repr); + } + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + i++; + bits >>= 1; + } +} + +static inline void +handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + assert(Py_REFCNT(func) > 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (interp->active_func_watchers) { + notify_func_watchers(interp, event, func, new_value); + } +} + +int +PyFunction_AddWatcher(PyFunction_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + for (int i = 0; i < FUNC_MAX_WATCHERS; i++) { + if (interp->func_watchers[i] == NULL) { + interp->func_watchers[i] = callback; + interp->active_func_watchers |= (1 << i); + return i; + } + } + PyErr_SetString(PyExc_RuntimeError, "no more func watcher IDs available"); + return -1; +} + +int +PyFunction_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (watcher_id < 0 || watcher_id >= FUNC_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "invalid func watcher ID %d", + watcher_id); + return -1; + } + if (!interp->func_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "no func watcher set for ID %d", + watcher_id); + return -1; + } + interp->func_watchers[watcher_id] = NULL; + interp->active_func_watchers &= ~(1 << watcher_id); + return 0; +} PyFunctionObject * _PyFunction_FromConstructor(PyFrameConstructor *constr) { + PyObject *module = Py_XNewRef(PyDict_GetItemWithError(constr->fc_globals, &_Py_ID(__name__))); + if (!module && PyErr_Occurred()) { + return NULL; + } PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); if (op == NULL) { + Py_XDECREF(module); return NULL; } - Py_INCREF(constr->fc_globals); - op->func_globals = constr->fc_globals; - Py_INCREF(constr->fc_builtins); - op->func_builtins = constr->fc_builtins; - Py_INCREF(constr->fc_name); - op->func_name = constr->fc_name; - Py_INCREF(constr->fc_qualname); - op->func_qualname = constr->fc_qualname; - Py_INCREF(constr->fc_code); - op->func_code = constr->fc_code; - Py_XINCREF(constr->fc_defaults); - op->func_defaults = constr->fc_defaults; - Py_XINCREF(constr->fc_kwdefaults); - op->func_kwdefaults = constr->fc_kwdefaults; - Py_XINCREF(constr->fc_closure); - op->func_closure = constr->fc_closure; - Py_INCREF(Py_None); - op->func_doc = Py_None; + op->func_globals = Py_NewRef(constr->fc_globals); + op->func_builtins = Py_NewRef(constr->fc_builtins); + op->func_name = Py_NewRef(constr->fc_name); + op->func_qualname = Py_NewRef(constr->fc_qualname); + op->func_code = Py_NewRef(constr->fc_code); + op->func_defaults = Py_XNewRef(constr->fc_defaults); + op->func_kwdefaults = Py_XNewRef(constr->fc_kwdefaults); + op->func_closure = Py_XNewRef(constr->fc_closure); + op->func_doc = Py_NewRef(Py_None); op->func_dict = NULL; op->func_weakreflist = NULL; - op->func_module = NULL; + op->func_module = module; op->func_annotations = NULL; + op->func_typeparams = NULL; op->vectorcall = _PyFunction_Vectorcall; op->func_version = 0; _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); return op; } @@ -54,12 +146,10 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *code_obj = (PyCodeObject *)code; - Py_INCREF(code_obj); + PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code); - PyObject *name = code_obj->co_name; - assert(name != NULL); - Py_INCREF(name); + assert(code_obj->co_name != NULL); + PyObject *name = Py_NewRef(code_obj->co_name); if (!qualname) { qualname = code_obj->co_qualname; @@ -115,9 +205,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname op->func_weakreflist = NULL; op->func_module = module; op->func_annotations = NULL; + op->func_typeparams = NULL; op->vectorcall = _PyFunction_Vectorcall; op->func_version = 0; _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); return (PyObject *)op; error: @@ -136,10 +228,14 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) if (func->func_version != 0) { return func->func_version; } - if (next_func_version == 0) { + if (func->vectorcall != _PyFunction_Vectorcall) { + return 0; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp->func_state.next_version == 0) { return 0; } - uint32_t v = next_func_version++; + uint32_t v = interp->func_state.next_version++; func->func_version = v; return v; } @@ -206,11 +302,21 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults) PyErr_SetString(PyExc_SystemError, "non-tuple default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults); return 0; } +void +PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall) +{ + assert(func != NULL); + func->func_version = 0; + func->vectorcall = vectorcall; +} + PyObject * PyFunction_GetKwDefaults(PyObject *op) { @@ -238,6 +344,8 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) "non-dict keyword only default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults); return 0; @@ -358,8 +466,7 @@ func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored)) return NULL; } - Py_INCREF(op->func_code); - return op->func_code; + return Py_NewRef(op->func_code); } static int @@ -392,17 +499,16 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) nclosure, nfree); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value); op->func_version = 0; - Py_INCREF(value); - Py_XSETREF(op->func_code, value); + Py_XSETREF(op->func_code, Py_NewRef(value)); return 0; } static PyObject * func_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_name); - return op->func_name; + return Py_NewRef(op->func_name); } static int @@ -415,16 +521,14 @@ func_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_name, value); + Py_XSETREF(op->func_name, Py_NewRef(value)); return 0; } static PyObject * func_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_qualname); - return op->func_qualname; + return Py_NewRef(op->func_qualname); } static int @@ -437,8 +541,7 @@ func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_qualname, value); + Py_XSETREF(op->func_qualname, Py_NewRef(value)); return 0; } @@ -451,8 +554,7 @@ func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_defaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_defaults); - return op->func_defaults; + return Py_NewRef(op->func_defaults); } static int @@ -477,9 +579,9 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_defaults, value); + Py_XSETREF(op->func_defaults, Py_XNewRef(value)); return 0; } @@ -493,8 +595,7 @@ func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_kwdefaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_kwdefaults); - return op->func_kwdefaults; + return Py_NewRef(op->func_kwdefaults); } static int @@ -519,9 +620,9 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignor return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_kwdefaults, value); + Py_XSETREF(op->func_kwdefaults, Py_XNewRef(value)); return 0; } @@ -534,10 +635,7 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored)) return NULL; } PyObject *d = func_get_annotation_dict(op); - if (d) { - Py_INCREF(d); - } - return d; + return Py_XNewRef(d); } static int @@ -554,11 +652,46 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno return -1; } op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_annotations, value); + Py_XSETREF(op->func_annotations, Py_XNewRef(value)); return 0; } +static PyObject * +func_get_type_params(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (op->func_typeparams == NULL) { + return PyTuple_New(0); + } + + assert(PyTuple_Check(op->func_typeparams)); + return Py_NewRef(op->func_typeparams); +} + +static int +func_set_type_params(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del f.__type_params__ or to set it to anything + * other than a tuple object. */ + if (value == NULL || !PyTuple_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__type_params__ must be set to a tuple"); + return -1; + } + Py_XSETREF(op->func_typeparams, Py_NewRef(value)); + return 0; +} + +PyObject * +_Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func, + PyObject *type_params) +{ + assert(PyFunction_Check(func)); + assert(PyTuple_Check(type_params)); + PyFunctionObject *f = (PyFunctionObject *)func; + Py_XSETREF(f->func_typeparams, Py_NewRef(type_params)); + return Py_NewRef(func); +} + static PyGetSetDef func_getsetlist[] = { {"__code__", (getter)func_get_code, (setter)func_set_code}, {"__defaults__", (getter)func_get_defaults, @@ -570,6 +703,8 @@ static PyGetSetDef func_getsetlist[] = { {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, {"__name__", (getter)func_get_name, (setter)func_set_name}, {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname}, + {"__type_params__", (getter)func_get_type_params, + (setter)func_set_type_params}, {NULL} /* Sentinel */ }; @@ -665,16 +800,13 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, return NULL; } if (name != Py_None) { - Py_INCREF(name); - Py_SETREF(newfunc->func_name, name); + Py_SETREF(newfunc->func_name, Py_NewRef(name)); } if (defaults != Py_None) { - Py_INCREF(defaults); - newfunc->func_defaults = defaults; + newfunc->func_defaults = Py_NewRef(defaults); } if (closure != Py_None) { - Py_INCREF(closure); - newfunc->func_closure = closure; + newfunc->func_closure = Py_NewRef(closure); } return (PyObject *)newfunc; @@ -693,6 +825,7 @@ func_clear(PyFunctionObject *op) Py_CLEAR(op->func_dict); Py_CLEAR(op->func_closure); Py_CLEAR(op->func_annotations); + Py_CLEAR(op->func_typeparams); // Don't Py_CLEAR(op->func_code), since code is always required // to be non-NULL. Similarly, name and qualname shouldn't be NULL. // However, name and qualname could be str subclasses, so they @@ -706,6 +839,14 @@ func_clear(PyFunctionObject *op) static void func_dealloc(PyFunctionObject *op) { + assert(Py_REFCNT(op) == 0); + Py_SET_REFCNT(op, 1); + handle_func_event(PyFunction_EVENT_DESTROY, op, NULL); + if (Py_REFCNT(op) > 1) { + Py_SET_REFCNT(op, Py_REFCNT(op) - 1); + return; + } + Py_SET_REFCNT(op, 0); _PyObject_GC_UNTRACK(op); if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); @@ -739,6 +880,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg) Py_VISIT(f->func_dict); Py_VISIT(f->func_closure); Py_VISIT(f->func_annotations); + Py_VISIT(f->func_typeparams); Py_VISIT(f->func_qualname); return 0; } @@ -748,8 +890,7 @@ static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } return PyMethod_New(func, obj); } @@ -918,8 +1059,7 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(cm->cm_callable, callable); + Py_XSETREF(cm->cm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) { return -1; @@ -1029,8 +1169,7 @@ PyClassMethod_New(PyObject *callable) classmethod *cm = (classmethod *) PyType_GenericAlloc(&PyClassMethod_Type, 0); if (cm != NULL) { - Py_INCREF(callable); - cm->cm_callable = callable; + cm->cm_callable = Py_NewRef(callable); } return (PyObject *)cm; } @@ -1095,8 +1234,7 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) "uninitialized staticmethod object"); return NULL; } - Py_INCREF(sm->sm_callable); - return sm->sm_callable; + return Py_NewRef(sm->sm_callable); } static int @@ -1109,8 +1247,7 @@ sm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(sm->sm_callable, callable); + Py_XSETREF(sm->sm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) { return -1; @@ -1225,8 +1362,7 @@ PyStaticMethod_New(PyObject *callable) staticmethod *sm = (staticmethod *) PyType_GenericAlloc(&PyStaticMethod_Type, 0); if (sm != NULL) { - Py_INCREF(callable); - sm->sm_callable = callable; + sm->sm_callable = Py_NewRef(callable); } return (PyObject *)sm; } diff --git a/contrib/tools/python3/src/Objects/genericaliasobject.c b/contrib/tools/python3/src/Objects/genericaliasobject.c index 139bab7e6c0..117b4e8dfb9 100644 --- a/contrib/tools/python3/src/Objects/genericaliasobject.c +++ b/contrib/tools/python3/src/Objects/genericaliasobject.c @@ -121,6 +121,36 @@ done: return err; } +static int +ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p) +{ + assert(PyList_CheckExact(p)); + + Py_ssize_t len = PyList_GET_SIZE(p); + + if (_PyUnicodeWriter_WriteASCIIString(writer, "[", 1) < 0) { + return -1; + } + + for (Py_ssize_t i = 0; i < len; i++) { + if (i > 0) { + if (_PyUnicodeWriter_WriteASCIIString(writer, ", ", 2) < 0) { + return -1; + } + } + PyObject *item = PyList_GET_ITEM(p, i); + if (ga_repr_item(writer, item) < 0) { + return -1; + } + } + + if (_PyUnicodeWriter_WriteASCIIString(writer, "]", 1) < 0) { + return -1; + } + + return 0; +} + static PyObject * ga_repr(PyObject *self) { @@ -148,7 +178,13 @@ ga_repr(PyObject *self) } } PyObject *p = PyTuple_GET_ITEM(alias->args, i); - if (ga_repr_item(&writer, p) < 0) { + if (PyList_CheckExact(p)) { + // Looks like we are working with ParamSpec's list of type args: + if (ga_repr_items_list(&writer, p) < 0) { + goto error; + } + } + else if (ga_repr_item(&writer, p) < 0) { goto error; } } @@ -183,8 +219,7 @@ static int tuple_add(PyObject *self, Py_ssize_t len, PyObject *item) { if (tuple_index(self, len, item) < 0) { - Py_INCREF(item); - PyTuple_SET_ITEM(self, len, item); + PyTuple_SET_ITEM(self, len, Py_NewRef(item)); return 1; } return 0; @@ -201,8 +236,7 @@ tuple_extend(PyObject **dst, Py_ssize_t dstindex, assert(dstindex + count <= PyTuple_GET_SIZE(*dst)); for (Py_ssize_t i = 0; i < count; ++i) { PyObject *item = src[i]; - Py_INCREF(item); - PyTuple_SET_ITEM(*dst, dstindex + i, item); + PyTuple_SET_ITEM(*dst, dstindex + i, Py_NewRef(item)); } return dstindex + count; } @@ -304,8 +338,7 @@ subs_tvars(PyObject *obj, PyObject *params, continue; } } - Py_INCREF(arg); - PyTuple_SET_ITEM(subargs, j, arg); + PyTuple_SET_ITEM(subargs, j, Py_NewRef(arg)); j++; } assert(j == PyTuple_GET_SIZE(subargs)); @@ -347,8 +380,7 @@ _unpacked_tuple_args(PyObject *arg) ((gaobject *)arg)->origin == (PyObject *)&PyTuple_Type) { result = ((gaobject *)arg)->args; - Py_INCREF(result); - return result; + return Py_NewRef(result); } if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_unpacked_tuple_args__), &result) > 0) { @@ -459,8 +491,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje for (Py_ssize_t iarg = 0, jarg = 0; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(args, iarg); if (PyType_Check(arg)) { - Py_INCREF(arg); - PyTuple_SET_ITEM(newargs, jarg, arg); + PyTuple_SET_ITEM(newargs, jarg, Py_NewRef(arg)); jarg++; continue; } @@ -767,8 +798,7 @@ ga_parameters(PyObject *self, void *unused) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); } static PyObject * @@ -776,8 +806,7 @@ ga_unpacked_tuple_args(PyObject *self, void *unused) { gaobject *alias = (gaobject *)self; if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) { - Py_INCREF(alias->args); - return alias->args; + return Py_NewRef(alias->args); } Py_RETURN_NONE; } @@ -803,8 +832,7 @@ setup_ga(gaobject *alias, PyObject *origin, PyObject *args) { Py_INCREF(args); } - Py_INCREF(origin); - alias->origin = origin; + alias->origin = Py_NewRef(origin); alias->args = args; alias->parameters = NULL; alias->weakreflist = NULL; diff --git a/contrib/tools/python3/src/Objects/genobject.c b/contrib/tools/python3/src/Objects/genobject.c index b9a0c30c411..3b9e4a60367 100644 --- a/contrib/tools/python3/src/Objects/genobject.c +++ b/contrib/tools/python3/src/Objects/genobject.c @@ -1,16 +1,19 @@ /* Generator object implementation */ +#define _PY_INTERPRETER + #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() #include "structmember.h" // PyMemberDef #include "opcode.h" // SEND +#include "frameobject.h" // _PyInterpreterFrame_GetLine +#include "pystats.h" static PyObject *gen_close(PyGenObject *, PyObject *); static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); @@ -22,6 +25,21 @@ static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " static const char *ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit"; +/* Returns a borrowed reference */ +static inline PyCodeObject * +_PyGen_GetCode(PyGenObject *gen) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe); + return frame->f_code; +} + +PyCodeObject * +PyGen_GetCode(PyGenObject *gen) { + assert(PyGen_Check(gen)); + PyCodeObject *res = _PyGen_GetCode(gen); + Py_INCREF(res); + return res; +} + static inline int exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) { @@ -32,7 +50,6 @@ exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) static int gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { - Py_VISIT(gen->gi_code); Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); if (gen->gi_frame_state < FRAME_CLEARED) { @@ -53,8 +70,6 @@ void _PyGen_Finalize(PyObject *self) { PyGenObject *gen = (PyGenObject *)self; - PyObject *res = NULL; - PyObject *error_type, *error_value, *error_traceback; if (gen->gi_frame_state >= FRAME_COMPLETED) { /* Generator isn't paused, so no need to close */ @@ -66,47 +81,45 @@ _PyGen_Finalize(PyObject *self) PyObject *finalizer = agen->ag_origin_or_finalizer; if (finalizer && !agen->ag_closed) { /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - res = PyObject_CallOneArg(finalizer, self); + PyObject *exc = PyErr_GetRaisedException(); + PyObject *res = PyObject_CallOneArg(finalizer, self); if (res == NULL) { PyErr_WriteUnraisable(self); } else { Py_DECREF(res); } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); return; } } /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); /* If `gen` is a coroutine, and if it was never awaited on, issue a RuntimeWarning. */ - if (gen->gi_code != NULL && - ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && + assert(_PyGen_GetCode(gen) != NULL); + if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE && gen->gi_frame_state == FRAME_CREATED) { _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); } else { - res = gen_close(gen, NULL); - } - - if (res == NULL) { - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(self); + PyObject *res = gen_close(gen, NULL); + if (res == NULL) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(self); + } + } + else { + Py_DECREF(res); } - } - else { - Py_DECREF(res); } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } static void @@ -135,12 +148,12 @@ gen_dealloc(PyGenObject *gen) _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; - _PyFrame_Clear(frame); + _PyFrame_ClearExceptCode(frame); } - if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { + if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE) { Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer); } - Py_CLEAR(gen->gi_code); + Py_DECREF(_PyGen_GetCode(gen)); Py_CLEAR(gen->gi_name); Py_CLEAR(gen->gi_qualname); _PyErr_ClearExcState(&gen->gi_exc_state); @@ -192,8 +205,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, else if (arg && !exc) { /* `gen` is an exhausted generator: only return value if called from send(). */ - *presult = Py_None; - Py_INCREF(*presult); + *presult = Py_NewRef(Py_None); return PYGEN_RETURN; } return PYGEN_ERROR; @@ -202,12 +214,10 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, assert(gen->gi_frame_state < FRAME_EXECUTING); /* Push arg onto the frame's value stack */ result = arg ? arg : Py_None; - Py_INCREF(result); - _PyFrame_StackPush(frame, result); - - frame->previous = tstate->cframe->current_frame; + _PyFrame_StackPush(frame, Py_NewRef(result)); - gen->gi_exc_state.previous_item = tstate->exc_info; + _PyErr_StackItem *prev_exc_info = tstate->exc_info; + gen->gi_exc_state.previous_item = prev_exc_info; tstate->exc_info = &gen->gi_exc_state; if (exc) { @@ -216,18 +226,12 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } gen->gi_frame_state = FRAME_EXECUTING; + EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR); result = _PyEval_EvalFrame(tstate, frame, exc); - if (gen->gi_frame_state == FRAME_EXECUTING) { - gen->gi_frame_state = FRAME_COMPLETED; - } - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - - assert(tstate->cframe->current_frame == frame->previous); - /* Don't keep the reference to previous any longer than necessary. It - * may keep a chain of frames alive or it could create a reference - * cycle. */ - frame->previous = NULL; + assert(tstate->exc_info == prev_exc_info); + assert(gen->gi_exc_state.previous_item == NULL); + assert(gen->gi_frame_state != FRAME_EXECUTING); + assert(frame->previous == NULL); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ @@ -243,33 +247,16 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } } else { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - const char *msg = "generator raised StopIteration"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine raised StopIteration"; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "async generator raised StopIteration"; - } - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } - else if (PyAsyncGen_CheckExact(gen) && - PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) - { - /* code in `gen` raised a StopAsyncIteration error: - raise a RuntimeError. - */ - const char *msg = "async generator raised StopAsyncIteration"; - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } + assert(!PyErr_ExceptionMatches(PyExc_StopIteration)); + assert(!PyAsyncGen_CheckExact(gen) || + !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); - gen->gi_frame_state = FRAME_CLEARED; - _PyFrame_Clear(frame); + assert(gen->gi_frame_state == FRAME_CLEARED); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; } @@ -344,6 +331,18 @@ gen_close_iter(PyObject *yf) return 0; } +static inline bool +is_resume(_Py_CODEUNIT *instr) +{ + return instr->op.code == RESUME || instr->op.code == INSTRUMENTED_RESUME; +} + +static inline bool +is_yield(_Py_CODEUNIT *instr) +{ + return instr->op.code == YIELD_VALUE || instr->op.code == INSTRUMENTED_YIELD_VALUE; +} + PyObject * _PyGen_yf(PyGenObject *gen) { @@ -356,17 +355,16 @@ _PyGen_yf(PyGenObject *gen) /* Return immediately if the frame didn't start yet. SEND always come after LOAD_CONST: a code object should not start with SEND */ - assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND); + assert(_PyCode_CODE(_PyGen_GetCode(gen))[0].op.code != SEND); return NULL; } _Py_CODEUNIT next = frame->prev_instr[1]; - if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2) + if (!is_resume(&next) || next.op.arg < 2) { /* Not in a yield from */ return NULL; } - yf = _PyFrame_StackPeek(frame); - Py_INCREF(yf); + yf = Py_NewRef(_PyFrame_StackPeek(frame)); } return yf; @@ -379,6 +377,13 @@ gen_close(PyGenObject *gen, PyObject *args) PyObject *yf = _PyGen_yf(gen); int err = 0; + if (gen->gi_frame_state == FRAME_CREATED) { + gen->gi_frame_state = FRAME_COMPLETED; + Py_RETURN_NONE; + } + if (gen->gi_frame_state >= FRAME_COMPLETED) { + Py_RETURN_NONE; + } if (yf) { PyFrameState state = gen->gi_frame_state; gen->gi_frame_state = FRAME_EXECUTING; @@ -386,8 +391,23 @@ gen_close(PyGenObject *gen, PyObject *args) gen->gi_frame_state = state; Py_DECREF(yf); } - if (err == 0) + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; + /* It is possible for the previous instruction to not be a + * YIELD_VALUE if the debugger has changed the lineno. */ + if (err == 0 && is_yield(frame->prev_instr)) { + assert(is_resume(frame->prev_instr + 1)); + int exception_handler_depth = frame->prev_instr[0].op.code; + assert(exception_handler_depth > 0); + /* We can safely ignore the outermost try block + * as it automatically generated to handle + * StopIteration. */ + if (exception_handler_depth == 1) { + Py_RETURN_NONE; + } + } + if (err == 0) { PyErr_SetNone(PyExc_GeneratorExit); + } retval = gen_send_ex(gen, Py_None, 1, 1); if (retval) { const char *msg = "generator ignored GeneratorExit"; @@ -414,7 +434,9 @@ PyDoc_STRVAR(throw_doc, throw(type[,value[,tb]])\n\ \n\ Raise exception in generator, return next yielded value or raise\n\ -StopIteration."); +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -481,26 +503,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } Py_DECREF(yf); if (!ret) { - PyObject *val; - /* Pop subiterator from stack */ - assert(gen->gi_frame_state < FRAME_CLEARED); - ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); - assert(ret == yf); - Py_DECREF(ret); - // XXX: Performing this jump ourselves is awkward and problematic. - // See https://github.com/python/cpython/pull/31968. - /* Termination repetition of SEND loop */ - assert(_PyInterpreterFrame_LASTI(frame) >= 0); - /* Backup to SEND */ - assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND); - int jump = _Py_OPARG(frame->prev_instr[-1]); - frame->prev_instr += jump - 1; - if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send(gen, val); - Py_DECREF(val); - } else { - ret = gen_send_ex(gen, Py_None, 1, 0); - } + ret = gen_send_ex(gen, Py_None, 1, 0); } return ret; } @@ -533,10 +536,8 @@ throw_here: } else { /* Normalize to raise <class>, <instance> */ - Py_XDECREF(val); - val = typ; - typ = PyExceptionInstance_Class(typ); - Py_INCREF(typ); + Py_XSETREF(val, typ); + typ = Py_NewRef(PyExceptionInstance_Class(typ)); if (tb == NULL) /* Returns NULL if there's no traceback */ @@ -574,6 +575,14 @@ gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; } + if (nargs > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of throw() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } typ = args[0]; if (nargs == 3) { val = args[1]; @@ -648,47 +657,16 @@ _PyGen_SetStopIterationValue(PyObject *value) int _PyGen_FetchStopIterationValue(PyObject **pvalue) { - PyObject *et, *ev, *tb; PyObject *value = NULL; - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - PyErr_Fetch(&et, &ev, &tb); - if (ev) { - /* exception will usually be normalised already */ - if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) { - /* Avoid normalisation and take ev as value. - * - * Normalization is required if the value is a tuple, in - * that case the value of StopIteration would be set to - * the first element of the tuple. - * - * (See _PyErr_CreateException code for details.) - */ - value = ev; - } else { - /* normalisation required */ - PyErr_NormalizeException(&et, &ev, &tb); - if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) { - PyErr_Restore(et, ev, tb); - return -1; - } - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } - } - Py_XDECREF(et); - Py_XDECREF(tb); + PyObject *exc = PyErr_GetRaisedException(); + value = Py_NewRef(((PyStopIterationObject *)exc)->value); + Py_DECREF(exc); } else if (PyErr_Occurred()) { return -1; } if (value == NULL) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } *pvalue = value; return 0; @@ -704,8 +682,7 @@ gen_repr(PyGenObject *gen) static PyObject * gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_name); - return op->gi_name; + return Py_NewRef(op->gi_name); } static int @@ -718,16 +695,14 @@ gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_name, value); + Py_XSETREF(op->gi_name, Py_NewRef(value)); return 0; } static PyObject * gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_qualname); - return op->gi_qualname; + return Py_NewRef(op->gi_qualname); } static int @@ -740,8 +715,7 @@ gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_qualname, value); + Py_XSETREF(op->gi_qualname, Py_NewRef(value)); return 0; } @@ -776,7 +750,7 @@ _gen_getframe(PyGenObject *gen, const char *const name) if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { return NULL; } - if (gen->gi_frame_state == FRAME_CLEARED) { + if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { Py_RETURN_NONE; } return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe)); @@ -788,6 +762,21 @@ gen_getframe(PyGenObject *gen, void *Py_UNUSED(ignored)) return _gen_getframe(gen, "gi_frame"); } +static PyObject * +_gen_getcode(PyGenObject *gen, const char *const name) +{ + if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { + return NULL; + } + return Py_NewRef(_PyGen_GetCode(gen)); +} + +static PyObject * +gen_getcode(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + return _gen_getcode(gen, "gi_code"); +} + static PyGetSetDef gen_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the generator")}, @@ -798,11 +787,11 @@ static PyGetSetDef gen_getsetlist[] = { {"gi_running", (getter)gen_getrunning, NULL, NULL}, {"gi_frame", (getter)gen_getframe, NULL, NULL}, {"gi_suspended", (getter)gen_getsuspended, NULL, NULL}, + {"gi_code", (getter)gen_getcode, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef gen_memberlist[] = { - {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; @@ -811,8 +800,8 @@ gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res; res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus); - PyCodeObject *code = gen->gi_code; - res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *); + PyCodeObject *code = _PyGen_GetCode(gen); + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); return PyLong_FromSsize_t(res); } @@ -893,14 +882,12 @@ static PyObject * make_gen(PyTypeObject *type, PyFunctionObject *func) { PyCodeObject *code = (PyCodeObject *)func->func_code; - int slots = code->co_nlocalsplus + code->co_stacksize; + int slots = _PyFrame_NumSlotsForCodeObject(code); PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots); if (gen == NULL) { return NULL; } gen->gi_frame_state = FRAME_CLEARED; - gen->gi_code = (PyCodeObject *)func->func_code; - Py_INCREF(gen->gi_code); gen->gi_weakreflist = NULL; gen->gi_exc_state.exc_value = NULL; gen->gi_exc_state.previous_item = NULL; @@ -947,8 +934,11 @@ _Py_MakeCoro(PyFunctionObject *func) if (origin_depth == 0) { ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL; } else { - assert(_PyEval_GetFrame()); - PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()->previous); + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + assert(frame); + assert(_PyFrame_IsIncomplete(frame)); + frame = _PyFrame_GetFirstComplete(frame->previous); + PyObject *cr_origin = compute_cr_origin(origin_depth, frame); ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin; if (!cr_origin) { Py_DECREF(coro); @@ -979,22 +969,18 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, f->f_frame = frame; frame->owner = FRAME_OWNED_BY_GENERATOR; assert(PyObject_GC_IsTracked((PyObject *)f)); - gen->gi_code = PyFrame_GetCode(f); - Py_INCREF(gen->gi_code); Py_DECREF(f); gen->gi_weakreflist = NULL; gen->gi_exc_state.exc_value = NULL; gen->gi_exc_state.previous_item = NULL; if (name != NULL) - gen->gi_name = name; + gen->gi_name = Py_NewRef(name); else - gen->gi_name = gen->gi_code->co_name; - Py_INCREF(gen->gi_name); + gen->gi_name = Py_NewRef(_PyGen_GetCode(gen)->co_name); if (qualname != NULL) - gen->gi_qualname = qualname; + gen->gi_qualname = Py_NewRef(qualname); else - gen->gi_qualname = gen->gi_code->co_qualname; - Py_INCREF(gen->gi_qualname); + gen->gi_qualname = Py_NewRef(_PyGen_GetCode(gen)->co_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; } @@ -1022,7 +1008,7 @@ static int gen_is_coroutine(PyObject *o) { if (PyGen_CheckExact(o)) { - PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code; + PyCodeObject *code = _PyGen_GetCode((PyGenObject*)o); if (code->co_flags & CO_ITERABLE_COROUTINE) { return 1; } @@ -1046,8 +1032,7 @@ _PyCoro_GetAwaitableIter(PyObject *o) if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { /* 'o' is a coroutine. */ - Py_INCREF(o); - return o; + return Py_NewRef(o); } ot = Py_TYPE(o); @@ -1094,8 +1079,7 @@ coro_await(PyCoroObject *coro) if (cw == NULL) { return NULL; } - Py_INCREF(coro); - cw->cw_coroutine = coro; + cw->cw_coroutine = (PyCoroObject*)Py_NewRef(coro); _PyObject_GC_TRACK(cw); return (PyObject *)cw; } @@ -1133,6 +1117,12 @@ cr_getframe(PyCoroObject *coro, void *Py_UNUSED(ignored)) return _gen_getframe((PyGenObject *)coro, "cr_frame"); } +static PyObject * +cr_getcode(PyCoroObject *coro, void *Py_UNUSED(ignored)) +{ + return _gen_getcode((PyGenObject *)coro, "cr_code"); +} + static PyGetSetDef coro_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, @@ -1143,12 +1133,12 @@ static PyGetSetDef coro_getsetlist[] = { PyDoc_STR("object being awaited on, or None")}, {"cr_running", (getter)cr_getrunning, NULL, NULL}, {"cr_frame", (getter)cr_getframe, NULL, NULL}, + {"cr_code", (getter)cr_getcode, NULL, NULL}, {"cr_suspended", (getter)cr_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef coro_memberlist[] = { - {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|PY_AUDIT_READ}, {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), READONLY}, {NULL} /* Sentinel */ }; @@ -1162,7 +1152,10 @@ PyDoc_STRVAR(coro_throw_doc, throw(type[,value[,traceback]])\n\ \n\ Raise exception in coroutine, return next iterated value or raise\n\ -StopIteration."); +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); + PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); @@ -1331,7 +1324,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) /* First count how many frames we have */ int frame_count = 0; for (; frame && frame_count < origin_depth; ++frame_count) { - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } /* Now collect them */ @@ -1342,7 +1335,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) frame = current_frame; for (int i = 0; i < frame_count; ++i) { PyCodeObject *code = frame->f_code; - int line = _PyInterpreterFrame_GetLine(frame); + int line = PyUnstable_InterpreterFrame_GetLine(frame); PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line, code->co_name); if (!frameinfo) { @@ -1350,7 +1343,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) return NULL; } PyTuple_SET_ITEM(cr_origin, i, frameinfo); - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } return cr_origin; @@ -1425,9 +1418,6 @@ typedef struct _PyAsyncGenWrappedValue { #define _PyAsyncGenWrappedValue_CheckExact(o) \ Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type) -#define PyAsyncGenASend_CheckExact(o) \ - Py_IS_TYPE(o, &_PyAsyncGenASend_Type) - static int async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg) @@ -1462,8 +1452,7 @@ async_gen_init_hooks(PyAsyncGenObject *o) finalizer = tstate->async_gen_finalizer; if (finalizer) { - Py_INCREF(finalizer); - o->ag_origin_or_finalizer = finalizer; + o->ag_origin_or_finalizer = Py_NewRef(finalizer); } firstiter = tstate->async_gen_firstiter; @@ -1515,6 +1504,14 @@ async_gen_aclose(PyAsyncGenObject *o, PyObject *arg) static PyObject * async_gen_athrow(PyAsyncGenObject *o, PyObject *args) { + if (PyTuple_GET_SIZE(args) > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of athrow() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } if (async_gen_init_hooks(o)) { return NULL; } @@ -1527,6 +1524,21 @@ ag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored)) return _gen_getframe((PyGenObject *)ag, "ag_frame"); } +static PyObject * +ag_getcode(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + return _gen_getcode(gen, "ag_code"); +} + +static PyObject * +ag_getsuspended(PyAsyncGenObject *ag, void *Py_UNUSED(ignored)) +{ + if (ag->ag_frame_state == FRAME_SUSPENDED) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + static PyGetSetDef async_gen_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the async generator")}, @@ -1535,13 +1547,14 @@ static PyGetSetDef async_gen_getsetlist[] = { {"ag_await", (getter)coro_get_cr_await, NULL, PyDoc_STR("object being awaited on, or None")}, {"ag_frame", (getter)ag_getframe, NULL, NULL}, + {"ag_code", (getter)ag_getcode, NULL, NULL}, + {"ag_suspended", (getter)ag_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef async_gen_memberlist[] = { {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), READONLY}, - {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; @@ -1552,7 +1565,12 @@ PyDoc_STRVAR(async_asend_doc, "asend(v) -> send 'v' in generator."); PyDoc_STRVAR(async_athrow_doc, -"athrow(typ[,val[,tb]]) -> raise exception in generator."); +"athrow(value)\n\ +athrow(type[,value[,tb]])\n\ +\n\ +raise exception in generator.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyMethodDef async_gen_methods[] = { {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, @@ -1912,11 +1930,9 @@ async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) } } - Py_INCREF(gen); - o->ags_gen = gen; + o->ags_gen = (PyAsyncGenObject*)Py_NewRef(gen); - Py_XINCREF(sendval); - o->ags_sendval = sendval; + o->ags_sendval = Py_XNewRef(sendval); o->ags_state = AWAITABLE_STATE_INIT; @@ -2005,13 +2021,13 @@ PyTypeObject _PyAsyncGenWrappedValue_Type = { PyObject * -_PyAsyncGenValueWrapperNew(PyObject *val) +_PyAsyncGenValueWrapperNew(PyThreadState *tstate, PyObject *val) { _PyAsyncGenWrappedValue *o; assert(val); #if _PyAsyncGen_MAXFREELIST > 0 - struct _Py_async_gen_state *state = get_async_gen_state(); + struct _Py_async_gen_state *state = &tstate->interp->async_gen; #ifdef Py_DEBUG // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini() assert(state->value_numfree != -1); @@ -2032,8 +2048,7 @@ _PyAsyncGenValueWrapperNew(PyObject *val) return NULL; } } - o->agw_val = val; - Py_INCREF(val); + o->agw_val = Py_NewRef(val); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } @@ -2316,11 +2331,9 @@ async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args) if (o == NULL) { return NULL; } - o->agt_gen = gen; - o->agt_args = args; + o->agt_gen = (PyAsyncGenObject*)Py_NewRef(gen); + o->agt_args = Py_XNewRef(args); o->agt_state = AWAITABLE_STATE_INIT; - Py_INCREF(gen); - Py_XINCREF(args); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } diff --git a/contrib/tools/python3/src/Objects/interpreteridobject.c b/contrib/tools/python3/src/Objects/interpreteridobject.c index 7b3e31beded..46239100dcb 100644 --- a/contrib/tools/python3/src/Objects/interpreteridobject.c +++ b/contrib/tools/python3/src/Objects/interpreteridobject.c @@ -3,7 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_interp.h" // _PyInterpreterState_LookUpID() -#include "pycore_interpreteridobject.h" +#include "interpreteridobject.h" typedef struct interpid { diff --git a/contrib/tools/python3/src/Objects/iterobject.c b/contrib/tools/python3/src/Objects/iterobject.c index 822f9e293e2..7cb17a6ca4a 100644 --- a/contrib/tools/python3/src/Objects/iterobject.c +++ b/contrib/tools/python3/src/Objects/iterobject.c @@ -23,8 +23,7 @@ PySeqIter_New(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -188,10 +187,8 @@ PyCallIter_New(PyObject *callable, PyObject *sentinel) it = PyObject_GC_New(calliterobject, &PyCallIter_Type); if (it == NULL) return NULL; - Py_INCREF(callable); - it->it_callable = callable; - Py_INCREF(sentinel); - it->it_sentinel = sentinel; + it->it_callable = Py_NewRef(callable); + it->it_sentinel = Py_NewRef(sentinel); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -438,8 +435,13 @@ return next yielded value or raise StopIteration."); PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in the wrapped iterator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(typ[,val[,tb]])\n\ +\n\ +raise exception in the wrapped iterator, return next yielded value\n\ +or raise StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); PyDoc_STRVAR(close_doc, @@ -501,10 +503,8 @@ PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value) if (anext == NULL) { return NULL; } - Py_INCREF(awaitable); - anext->wrapped = awaitable; - Py_INCREF(default_value); - anext->default_value = default_value; + anext->wrapped = Py_NewRef(awaitable); + anext->default_value = Py_NewRef(default_value); _PyObject_GC_TRACK(anext); return (PyObject *)anext; } diff --git a/contrib/tools/python3/src/Objects/listobject.c b/contrib/tools/python3/src/Objects/listobject.c index 0d4e4741fdf..f1edfb3a9a0 100644 --- a/contrib/tools/python3/src/Objects/listobject.c +++ b/contrib/tools/python3/src/Objects/listobject.c @@ -3,7 +3,8 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_interp.h" // PyInterpreterState.list -#include "pycore_list.h" // struct _Py_list_state +#include "pycore_list.h" // struct _Py_list_state, _PyListIterObject +#include "pycore_long.h" // _PyLong_DigitCount #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_tuple.h" // _PyTuple_FromArray() #include <stddef.h> @@ -299,8 +300,7 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) items = self->ob_item; for (i = n; --i >= where; ) items[i+1] = items[i]; - Py_INCREF(v); - items[where] = v; + items[where] = Py_NewRef(v); return 0; } @@ -332,8 +332,7 @@ int PyList_Append(PyObject *op, PyObject *newitem) { if (PyList_Check(op) && (newitem != NULL)) { - Py_INCREF(newitem); - return _PyList_AppendTakeRef((PyListObject *)op, newitem); + return _PyList_AppendTakeRef((PyListObject *)op, Py_NewRef(newitem)); } PyErr_BadInternalCall(); return -1; @@ -461,8 +460,7 @@ list_item(PyListObject *a, Py_ssize_t i) PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err)); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } static PyObject * @@ -483,8 +481,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) dest = np->ob_item; for (i = 0; i < len; i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, len); return (PyObject *)np; @@ -539,15 +536,13 @@ list_concat(PyListObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, size); return (PyObject *)np; @@ -557,47 +552,41 @@ list_concat(PyListObject *a, PyObject *bb) static PyObject * list_repeat(PyListObject *a, Py_ssize_t n) { - Py_ssize_t size; - PyListObject *np; - if (n < 0) - n = 0; - if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) - return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - if (size == 0) + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n <= 0) return PyList_New(0); - np = (PyListObject *) list_new_prealloc(size); + assert(n > 0); + + if (input_size > PY_SSIZE_T_MAX / n) + return PyErr_NoMemory(); + Py_ssize_t output_size = input_size * n; + + PyListObject *np = (PyListObject *) list_new_prealloc(output_size); if (np == NULL) return NULL; + PyObject **dest = np->ob_item; - PyObject **dest_end = dest + size; - if (Py_SIZE(a) == 1) { + if (input_size == 1) { PyObject *elem = a->ob_item[0]; - Py_SET_REFCNT(elem, Py_REFCNT(elem) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; while (dest < dest_end) { *dest++ = elem; } } else { PyObject **src = a->ob_item; - PyObject **src_end = src + Py_SIZE(a); + PyObject **src_end = src + input_size; while (src < src_end) { - Py_SET_REFCNT(*src, Py_REFCNT(*src) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif - *dest++ = *src++; - } - // Now src chases after dest in the same buffer - src = np->ob_item; - while (dest < dest_end) { + _Py_RefcntAdd(*src, n); *dest++ = *src++; } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); } - Py_SET_SIZE(np, size); + + Py_SET_SIZE(np, output_size); return (PyObject *) np; } @@ -722,8 +711,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) } for (k = 0; k < n; k++, ilow++) { PyObject *w = vitem[k]; - Py_XINCREF(w); - item[ilow] = w; + item[ilow] = Py_XNewRef(w); } for (k = norig - 1; k >= 0; --k) Py_XDECREF(recycle[k]); @@ -749,40 +737,32 @@ PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) static PyObject * list_inplace_repeat(PyListObject *self, Py_ssize_t n) { - PyObject **items; - Py_ssize_t size, i, j, p; - - - size = PyList_GET_SIZE(self); - if (size == 0 || n == 1) { - Py_INCREF(self); - return (PyObject *)self; + Py_ssize_t input_size = PyList_GET_SIZE(self); + if (input_size == 0 || n == 1) { + return Py_NewRef(self); } if (n < 1) { (void)_list_clear(self); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } - if (size > PY_SSIZE_T_MAX / n) { + if (input_size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); } + Py_ssize_t output_size = input_size * n; - if (list_resize(self, size*n) < 0) + if (list_resize(self, output_size) < 0) return NULL; - p = size; - items = self->ob_item; - for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */ - for (j = 0; j < size; j++) { - PyObject *o = items[j]; - Py_INCREF(o); - items[p++] = o; - } + PyObject **items = self->ob_item; + for (Py_ssize_t j = 0; j < input_size; j++) { + _Py_RefcntAdd(items[j], n-1); } - Py_INCREF(self); - return (PyObject *)self; + _Py_memory_repeat((char *)items, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); + + return Py_NewRef(self); } static int @@ -795,8 +775,7 @@ list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v) } if (v == NULL) return list_ass_slice(a, i, i+1, v); - Py_INCREF(v); - Py_SETREF(a->ob_item[i], v); + Py_SETREF(a->ob_item[i], Py_NewRef(v)); return 0; } @@ -924,8 +903,7 @@ list_extend(PyListObject *self, PyObject *iterable) dest = self->ob_item + m; for (i = 0; i < n; i++) { PyObject *o = src[i]; - Py_INCREF(o); - dest[i] = o; + dest[i] = Py_NewRef(o); } Py_DECREF(iterable); Py_RETURN_NONE; @@ -1013,8 +991,7 @@ list_inplace_concat(PyListObject *self, PyObject *other) if (result == NULL) return result; Py_DECREF(result); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1046,21 +1023,29 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } - v = self->ob_item[index]; - if (index == Py_SIZE(self) - 1) { - status = list_resize(self, Py_SIZE(self) - 1); - if (status >= 0) - return v; /* and v now owns the reference the list had */ - else - return NULL; + + PyObject **items = self->ob_item; + v = items[index]; + const Py_ssize_t size_after_pop = Py_SIZE(self) - 1; + if (size_after_pop == 0) { + Py_INCREF(v); + status = _list_clear(self); } - Py_INCREF(v); - status = list_ass_slice(self, index, index+1, (PyObject *)NULL); - if (status < 0) { - Py_DECREF(v); + else { + if ((size_after_pop - index) > 0) { + memmove(&items[index], &items[index+1], (size_after_pop - index) * sizeof(PyObject *)); + } + status = list_resize(self, size_after_pop); + } + if (status >= 0) { + return v; // and v now owns the reference the list had + } + else { + // list resize failed, need to restore + memmove(&items[index+1], &items[index], (size_after_pop - index)* sizeof(PyObject *)); + items[index] = v; return NULL; } - return v; } /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ @@ -2160,24 +2145,21 @@ unsafe_latin_compare(PyObject *v, PyObject *w, MergeState *ms) static int unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms) { - PyLongObject *vl, *wl; sdigit v0, w0; int res; + PyLongObject *vl, *wl; + intptr_t v0, w0; + int res; /* Modified from Objects/longobject.c:long_compare, assuming: */ assert(Py_IS_TYPE(v, &PyLong_Type)); assert(Py_IS_TYPE(w, &PyLong_Type)); - assert(Py_ABS(Py_SIZE(v)) <= 1); - assert(Py_ABS(Py_SIZE(w)) <= 1); + assert(_PyLong_IsCompact((PyLongObject *)v)); + assert(_PyLong_IsCompact((PyLongObject *)w)); vl = (PyLongObject*)v; wl = (PyLongObject*)w; - v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; - w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; - - if (Py_SIZE(vl) < 0) - v0 = -v0; - if (Py_SIZE(wl) < 0) - w0 = -w0; + v0 = _PyLong_CompactValue(vl); + w0 = _PyLong_CompactValue(wl); res = v0 < w0; assert(res == PyObject_RichCompareBool(v, w, Py_LT)); @@ -2251,7 +2233,7 @@ list.sort * key as keyfunc: object = None - reverse: bool(accept={int}) = False + reverse: bool = False Sort the list in ascending order and return None. @@ -2266,7 +2248,7 @@ The reverse flag can be set to sort in descending order. static PyObject * list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) -/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/ +/*[clinic end generated code: output=57b9f9c5e23fbe42 input=a74c4cd3ec6b5c08]*/ { MergeState ms; Py_ssize_t nremaining; @@ -2375,7 +2357,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) if (keys_are_all_same_type) { if (key_type == &PyLong_Type && ints_are_bounded && - Py_ABS(Py_SIZE(key)) > 1) { + !_PyLong_IsCompact((PyLongObject *)key)) { ints_are_bounded = 0; } @@ -2523,8 +2505,7 @@ keyfunc_fail: } PyMem_Free(final_ob_item); } - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } #undef IFLT #undef ISLT @@ -2582,6 +2563,27 @@ PyList_AsTuple(PyObject *v) return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); } +PyObject * +_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n) +{ + if (n == 0) { + return PyList_New(0); + } + + PyListObject *list = (PyListObject *)PyList_New(n); + if (list == NULL) { + for (Py_ssize_t i = 0; i < n; i++) { + Py_DECREF(src[i]); + } + return NULL; + } + + PyObject **dst = list->ob_item; + memcpy(dst, src, n * sizeof(PyObject *)); + + return (PyObject *)list; +} + /*[clinic input] list.index @@ -2831,17 +2833,17 @@ static PyObject * list___sizeof___impl(PyListObject *self) /*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->allocated * sizeof(void*); + return PyLong_FromSize_t(res); } static PyObject *list_iter(PyObject *seq); static PyObject *list_subscript(PyListObject*, PyObject*); static PyMethodDef list_methods[] = { - {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"}, + {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, + PyDoc_STR("__getitem__($self, index, /)\n--\n\nReturn self[index].")}, LIST___REVERSED___METHODDEF LIST___SIZEOF___METHODDEF LIST_CLEAR_METHODDEF @@ -2911,8 +2913,7 @@ list_subscript(PyListObject* self, PyObject* item) dest = ((PyListObject *)result)->ob_item; for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } Py_SET_SIZE(result, slicelength); @@ -3067,8 +3068,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { garbage[i] = selfitems[cur]; - ins = seqitems[i]; - Py_INCREF(ins); + ins = Py_NewRef(seqitems[i]); selfitems[cur] = ins; } @@ -3143,19 +3143,13 @@ PyTypeObject PyList_Type = { /*********************** List Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ -} listiterobject; - -static void listiter_dealloc(listiterobject *); -static int listiter_traverse(listiterobject *, visitproc, void *); -static PyObject *listiter_next(listiterobject *); -static PyObject *listiter_len(listiterobject *, PyObject *); +static void listiter_dealloc(_PyListIterObject *); +static int listiter_traverse(_PyListIterObject *, visitproc, void *); +static PyObject *listiter_next(_PyListIterObject *); +static PyObject *listiter_len(_PyListIterObject *, PyObject *); static PyObject *listiter_reduce_general(void *_it, int forward); -static PyObject *listiter_reduce(listiterobject *, PyObject *); -static PyObject *listiter_setstate(listiterobject *, PyObject *state); +static PyObject *listiter_reduce(_PyListIterObject *, PyObject *); +static PyObject *listiter_setstate(_PyListIterObject *, PyObject *state); PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -3171,7 +3165,7 @@ static PyMethodDef listiter_methods[] = { PyTypeObject PyListIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "list_iterator", /* tp_name */ - sizeof(listiterobject), /* tp_basicsize */ + sizeof(_PyListIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)listiter_dealloc, /* tp_dealloc */ @@ -3205,24 +3199,23 @@ PyTypeObject PyListIter_Type = { static PyObject * list_iter(PyObject *seq) { - listiterobject *it; + _PyListIterObject *it; if (!PyList_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(listiterobject, &PyListIter_Type); + it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyListObject *)seq; + it->it_seq = (PyListObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } static void -listiter_dealloc(listiterobject *it) +listiter_dealloc(_PyListIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3230,14 +3223,14 @@ listiter_dealloc(listiterobject *it) } static int -listiter_traverse(listiterobject *it, visitproc visit, void *arg) +listiter_traverse(_PyListIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -listiter_next(listiterobject *it) +listiter_next(_PyListIterObject *it) { PyListObject *seq; PyObject *item; @@ -3251,8 +3244,7 @@ listiter_next(listiterobject *it) if (it->it_index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -3261,7 +3253,7 @@ listiter_next(listiterobject *it) } static PyObject * -listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_len(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len; if (it->it_seq) { @@ -3273,13 +3265,13 @@ listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) } static PyObject * -listiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_reduce(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { return listiter_reduce_general(it, 1); } static PyObject * -listiter_setstate(listiterobject *it, PyObject *state) +listiter_setstate(_PyListIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -3366,8 +3358,7 @@ list___reversed___impl(PyListObject *self) return NULL; assert(PyList_Check(self)); it->it_index = PyList_GET_SIZE(self) - 1; - Py_INCREF(self); - it->it_seq = self; + it->it_seq = (PyListObject*)Py_NewRef(self); PyObject_GC_Track(it); return (PyObject *)it; } @@ -3405,8 +3396,7 @@ listreviter_next(listreviterobject *it) if (index>=0 && index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, index); it->it_index--; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_index = -1; it->it_seq = NULL; @@ -3462,7 +3452,7 @@ listiter_reduce_general(void *_it, int forward) if (!iter) { return NULL; } - listiterobject *it = (listiterobject *)_it; + _PyListIterObject *it = (_PyListIterObject *)_it; if (it->it_seq) { return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } diff --git a/contrib/tools/python3/src/Objects/longobject.c b/contrib/tools/python3/src/Objects/longobject.c index 84c05e8aabd..5d9b4138614 100644 --- a/contrib/tools/python3/src/Objects/longobject.c +++ b/contrib/tools/python3/src/Objects/longobject.c @@ -6,10 +6,9 @@ #include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _Py_SmallInts -#include "pycore_object.h" // _PyObject_InitVar() -#include "pycore_pystate.h" // _Py_IsMainInterpreter() +#include "pycore_object.h" // _PyObject_Init() #include "pycore_runtime.h" // _PY_NSMALLPOSINTS -#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include <ctype.h> #include <float.h> @@ -22,16 +21,7 @@ class int "PyObject *" "&PyLong_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ -/* Is this PyLong of size 1, 0 or -1? */ -#define IS_MEDIUM_VALUE(x) (((size_t)Py_SIZE(x)) + 1U < 3U) - -/* convert a PyLong of size 1, 0 or -1 to a C integer */ -static inline stwodigits -medium_value(PyLongObject *x) -{ - assert(IS_MEDIUM_VALUE(x)); - return ((stwodigits)Py_SIZE(x)) * x->ob_digit[0]; -} +#define medium_value(x) ((stwodigits)_PyLong_CompactValue(x)) #define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < _PY_NSMALLPOSINTS) @@ -39,6 +29,9 @@ medium_value(PyLongObject *x) #define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d digits) for integer string conversion: value has %zd digits; use sys.set_int_max_str_digits() to increase the limit" #define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit" +/* If defined, use algorithms from the _pylong.py module */ +#define WITH_PYLONG_MODULE 1 + static inline void _Py_DECREF_INT(PyLongObject *op) { @@ -58,15 +51,13 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyObject *v = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival]; - Py_INCREF(v); - return v; + return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival]; } static PyLongObject * maybe_small_long(PyLongObject *v) { - if (v && IS_MEDIUM_VALUE(v)) { + if (v && _PyLong_IsCompact(v)) { stwodigits ival = medium_value(v); if (IS_SMALL_INT(ival)) { _Py_DECREF_INT(v); @@ -124,13 +115,18 @@ maybe_small_long(PyLongObject *v) static PyLongObject * long_normalize(PyLongObject *v) { - Py_ssize_t j = Py_ABS(Py_SIZE(v)); + Py_ssize_t j = _PyLong_DigitCount(v); Py_ssize_t i = j; - while (i > 0 && v->ob_digit[i-1] == 0) + while (i > 0 && v->long_value.ob_digit[i-1] == 0) --i; if (i != j) { - Py_SET_SIZE(v, (Py_SIZE(v) < 0) ? -(i) : i); + if (i == 0) { + _PyLong_SetSignAndDigitCount(v, 0, 0); + } + else { + _PyLong_SetDigitCount(v, i); + } } return v; } @@ -139,11 +135,12 @@ long_normalize(PyLongObject *v) Return NULL and set exception if we run out of memory. */ #define MAX_LONG_DIGITS \ - ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) + ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit))/sizeof(digit)) PyLongObject * _PyLong_New(Py_ssize_t size) { + assert(size >= 0); PyLongObject *result; if (size > (Py_ssize_t)MAX_LONG_DIGITS) { PyErr_SetString(PyExc_OverflowError, @@ -155,43 +152,53 @@ _PyLong_New(Py_ssize_t size) Py_ssize_t ndigits = size ? size : 1; /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + sizeof(digit)*size. Previous incarnations of this code used - sizeof(PyVarObject) instead of the offsetof, but this risks being - incorrect in the presence of padding between the PyVarObject header + sizeof() instead of the offsetof, but this risks being + incorrect in the presence of padding between the header and the digits. */ - result = PyObject_Malloc(offsetof(PyLongObject, ob_digit) + + result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) + ndigits*sizeof(digit)); if (!result) { PyErr_NoMemory(); return NULL; } - _PyObject_InitVar((PyVarObject*)result, &PyLong_Type, size); + _PyLong_SetSignAndDigitCount(result, size != 0, size); + _PyObject_Init((PyObject*)result, &PyLong_Type); + /* The digit has to be initialized explicitly to avoid + * use-of-uninitialized-value. */ + result->long_value.ob_digit[0] = 0; + return result; +} + +PyLongObject * +_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits) +{ + assert(digit_count >= 0); + if (digit_count == 0) { + return (PyLongObject *)Py_NewRef(_PyLong_GetZero()); + } + PyLongObject *result = _PyLong_New(digit_count); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + _PyLong_SetSignAndDigitCount(result, negative?-1:1, digit_count); + memcpy(result->long_value.ob_digit, digits, digit_count * sizeof(digit)); return result; } PyObject * _PyLong_Copy(PyLongObject *src) { - PyLongObject *result; - Py_ssize_t i; - assert(src != NULL); - i = Py_SIZE(src); - if (i < 0) - i = -(i); - if (i < 2) { + + if (_PyLong_IsCompact(src)) { stwodigits ival = medium_value(src); if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } } - result = _PyLong_New(i); - if (result != NULL) { - Py_SET_SIZE(result, Py_SIZE(src)); - while (--i >= 0) { - result->ob_digit[i] = src->ob_digit[i]; - } - } - return (PyObject *)result; + Py_ssize_t size = _PyLong_DigitCount(src); + return (PyObject *)_PyLong_FromDigits(_PyLong_IsNegative(src), size, src->long_value.ob_digit); } static PyObject * @@ -205,10 +212,10 @@ _PyLong_FromMedium(sdigit x) PyErr_NoMemory(); return NULL; } - Py_ssize_t sign = x < 0 ? -1: 1; digit abs_x = x < 0 ? -x : x; - _PyObject_InitVar((PyVarObject*)v, &PyLong_Type, sign); - v->ob_digit[0] = abs_x; + _PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1); + _PyObject_Init((PyObject*)v, &PyLong_Type); + v->long_value.ob_digit[0] = abs_x; return (PyObject*)v; } @@ -239,8 +246,8 @@ _PyLong_FromLarge(stwodigits ival) } PyLongObject *v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ndigits * sign); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, sign, ndigits); t = abs_ival; while (t) { *p++ = Py_SAFE_DOWNCAST( @@ -274,7 +281,7 @@ _PyLong_Negate(PyLongObject **x_p) x = (PyLongObject *)*x_p; if (Py_REFCNT(x) == 1) { - Py_SET_SIZE(x, -Py_SIZE(x)); + _PyLong_FlipSign(x); return; } @@ -312,8 +319,8 @@ PyLong_FromLong(long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -339,7 +346,7 @@ PyLong_FromLong(long ival) if (v == NULL) { \ return NULL; \ } \ - digit *p = v->ob_digit; \ + digit *p = v->long_value.ob_digit; \ while ((ival)) { \ *p++ = (digit)((ival) & PyLong_MASK); \ (ival) >>= PyLong_SHIFT; \ @@ -418,12 +425,12 @@ PyLong_FromDouble(double dval) frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); for (i = ndig; --i >= 0; ) { digit bits = (digit)frac; - v->ob_digit[i] = bits; + v->long_value.ob_digit[i] = bits; frac = frac - (double)bits; frac = ldexp(frac, PyLong_SHIFT); } if (neg) { - Py_SET_SIZE(v, -(Py_SIZE(v))); + _PyLong_FlipSign(v); } return (PyObject *)v; } @@ -476,38 +483,33 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) return -1; do_decref = 1; } - - res = -1; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); + if (_PyLong_IsCompact(v)) { +#if SIZEOF_LONG < SIZEOF_VOID_P + intptr_t tmp = _PyLong_CompactValue(v); + res = (long)tmp; + if (res != tmp) { + *overflow = tmp < 0 ? -1 : 1; } +#else + res = _PyLong_CompactValue(v); +#endif + } + else { + res = -1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; goto exit; } } /* Haven't lost any bits, but casting to long requires extra - * care (see comment above). - */ + * care (see comment above). + */ if (x <= (unsigned long)LONG_MAX) { res = (long)x * sign; } @@ -581,21 +583,15 @@ PyLong_AsSsize_t(PyObject *vv) { } v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return _PyLong_CompactValue(v); } - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) goto overflow; } @@ -636,28 +632,37 @@ PyLong_AsUnsignedLong(PyObject *vv) } v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { + if (_PyLong_IsNonNegativeCompact(v)) { +#if SIZEOF_LONG < SIZEOF_VOID_P + intptr_t tmp = _PyLong_CompactValue(v); + unsigned long res = (unsigned long)tmp; + if (res != tmp) { + goto overflow; + } +#else + return _PyLong_CompactValue(v); +#endif + } + if (_PyLong_IsNegative(v)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned int"); return (unsigned long) -1; } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } + i = _PyLong_DigitCount(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert " - "to C unsigned long"); - return (unsigned long) -1; + goto overflow; } } return x; +overflow: + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert " + "to C unsigned long"); + return (unsigned long) -1; } /* Get a C size_t from an int object. Returns (size_t)-1 and sets @@ -680,20 +685,19 @@ PyLong_AsSize_t(PyObject *vv) } v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { + if (_PyLong_IsNonNegativeCompact(v)) { + return _PyLong_CompactValue(v); + } + if (_PyLong_IsNegative(v)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to size_t"); return (size_t) -1; } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } + i = _PyLong_DigitCount(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C size_t"); @@ -712,26 +716,20 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) PyLongObject *v; unsigned long x; Py_ssize_t i; - int sign; if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return (unsigned long) -1; } v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return (unsigned long)_PyLong_CompactValue(v); } - sign = 1; + i = _PyLong_DigitCount(v); + int sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -i; - } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -767,8 +765,10 @@ _PyLong_Sign(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - - return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); + if (_PyLong_IsCompact(v)) { + return _PyLong_CompactSign(v); + } + return _PyLong_NonCompactSign(v); } static int @@ -791,10 +791,10 @@ _PyLong_NumBits(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = Py_ABS(Py_SIZE(v)); - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + ndigits = _PyLong_DigitCount(v); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); if (ndigits > 0) { - digit msd = v->ob_digit[ndigits - 1]; + digit msd = v->long_value.ob_digit[ndigits - 1]; if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; @@ -821,7 +821,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, size_t numsignificantbytes; /* number of bytes that matter */ Py_ssize_t ndigits; /* number of Python int digits */ PyLongObject* v; /* result */ - Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ + Py_ssize_t idigit = 0; /* next free index in v->long_value.ob_digit */ if (n == 0) return PyLong_FromLong(0L); @@ -903,7 +903,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, if (accumbits >= PyLong_SHIFT) { /* There's enough to fill a Python digit. */ assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); + v->long_value.ob_digit[idigit] = (digit)(accum & PyLong_MASK); ++idigit; accum >>= PyLong_SHIFT; accumbits -= PyLong_SHIFT; @@ -913,12 +913,16 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, assert(accumbits < PyLong_SHIFT); if (accumbits) { assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)accum; + v->long_value.ob_digit[idigit] = (digit)accum; ++idigit; } } - Py_SET_SIZE(v, is_signed ? -idigit : idigit); + int sign = is_signed ? -1: 1; + if (idigit == 0) { + sign = 0; + } + _PyLong_SetSignAndDigitCount(v, sign, idigit); return (PyObject *)maybe_small_long(long_normalize(v)); } @@ -927,8 +931,8 @@ _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) { - Py_ssize_t i; /* index into v->ob_digit */ - Py_ssize_t ndigits; /* |v->ob_size| */ + Py_ssize_t i; /* index into v->long_value.ob_digit */ + Py_ssize_t ndigits; /* number of digits */ twodigits accum; /* sliding register */ unsigned int accumbits; /* # bits in accum */ int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ @@ -939,8 +943,8 @@ _PyLong_AsByteArray(PyLongObject* v, assert(v != NULL && PyLong_Check(v)); - if (Py_SIZE(v) < 0) { - ndigits = -(Py_SIZE(v)); + ndigits = _PyLong_DigitCount(v); + if (_PyLong_IsNegative(v)) { if (!is_signed) { PyErr_SetString(PyExc_OverflowError, "can't convert negative int to unsigned"); @@ -949,7 +953,6 @@ _PyLong_AsByteArray(PyLongObject* v, do_twos_comp = 1; } else { - ndigits = Py_SIZE(v); do_twos_comp = 0; } @@ -966,13 +969,13 @@ _PyLong_AsByteArray(PyLongObject* v, It's crucial that every Python digit except for the MSD contribute exactly PyLong_SHIFT bits to the total, so first assert that the int is normalized. */ - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); j = 0; accum = 0; accumbits = 0; carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { - digit thisdigit = v->ob_digit[i]; + digit thisdigit = v->long_value.ob_digit[i]; if (do_twos_comp) { thisdigit = (thisdigit ^ PyLong_MASK) + carry; carry = thisdigit >> PyLong_SHIFT; @@ -1080,10 +1083,12 @@ PyLong_AsVoidPtr(PyObject *vv) #if SIZEOF_VOID_P <= SIZEOF_LONG long x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) { x = PyLong_AsLong(vv); - else + } + else { x = PyLong_AsUnsignedLong(vv); + } #else #if SIZEOF_LONG_LONG < SIZEOF_VOID_P @@ -1091,10 +1096,12 @@ PyLong_AsVoidPtr(PyObject *vv) #endif long long x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) { x = PyLong_AsLongLong(vv); - else + } + else { x = PyLong_AsUnsignedLongLong(vv); + } #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ @@ -1139,8 +1146,8 @@ PyLong_FromLongLong(long long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1182,8 +1189,8 @@ PyLong_FromSsize_t(Py_ssize_t ival) } v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, negative ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, negative ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1219,18 +1226,11 @@ PyLong_AsLongLong(PyObject *vv) do_decref = 1; } - res = 0; - switch(Py_SIZE(v)) { - case -1: - bytes = -(sdigit)v->ob_digit[0]; - break; - case 0: - bytes = 0; - break; - case 1: - bytes = v->ob_digit[0]; - break; - default: + if (_PyLong_IsCompact(v)) { + res = 0; + bytes = _PyLong_CompactValue(v); + } + else { res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); } @@ -1265,13 +1265,14 @@ PyLong_AsUnsignedLongLong(PyObject *vv) } v = (PyLongObject*)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsNonNegativeCompact(v)) { + res = 0; + bytes = _PyLong_CompactValue(v); } - - res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + else { + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); + } /* Plan 9 can't handle long long in ? : expressions */ if (res < 0) @@ -1296,19 +1297,14 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) return (unsigned long long) -1; } v = (PyLongObject *)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return (unsigned long long)(signed long long)_PyLong_CompactValue(v); } - i = Py_SIZE(v); - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -i; - } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -1373,32 +1369,19 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) return -1; do_decref = 1; } - - res = -1; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; + if (_PyLong_IsCompact(v)) { + res = _PyLong_CompactValue(v); + } + else { + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; + res = -1; goto exit; } } @@ -1413,7 +1396,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) } else { *overflow = sign; - /* res is already set to -1 */ + res = -1; } } exit: @@ -1428,7 +1411,7 @@ _PyLong_UnsignedShort_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1450,7 +1433,7 @@ _PyLong_UnsignedInt_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1472,7 +1455,7 @@ _PyLong_UnsignedLong_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1489,7 +1472,7 @@ _PyLong_UnsignedLongLong_Converter(PyObject *obj, void *ptr) { unsigned long long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1506,7 +1489,7 @@ _PyLong_Size_t_Converter(PyObject *obj, void *ptr) { size_t uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1660,14 +1643,14 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + const Py_ssize_t size = _PyLong_DigitCount(a); PyLongObject *z; assert(n > 0 && n <= PyLong_MASK); z = _PyLong_New(size); if (z == NULL) return NULL; - *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); + *prem = inplace_divrem1(z->long_value.ob_digit, a->long_value.ob_digit, size, n); return long_normalize(z); } @@ -1692,14 +1675,80 @@ inplace_rem1(digit *pin, Py_ssize_t size, digit n) static PyLongObject * rem1(PyLongObject *a, digit n) { - const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + const Py_ssize_t size = _PyLong_DigitCount(a); assert(n > 0 && n <= PyLong_MASK); return (PyLongObject *)PyLong_FromLong( - (long)inplace_rem1(a->ob_digit, size, n) + (long)inplace_rem1(a->long_value.ob_digit, size, n) ); } +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster long_to_decimal_string, using _pylong.py */ +static int +pylong_int_to_decimal_string(PyObject *aa, + PyObject **p_output, + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) +{ + PyObject *s = NULL; + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + s = PyObject_CallMethod(mod, "int_to_decimal_string", "O", aa); + if (s == NULL) { + goto error; + } + if (!PyUnicode_Check(s)) { + PyErr_SetString(PyExc_TypeError, + "_pylong.int_to_decimal_string did not return a str"); + goto error; + } + if (writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(writer, s) < 0) { + goto error; + } + goto success; + } + else if (bytes_writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + const void *data = PyUnicode_DATA(s); + int kind = PyUnicode_KIND(s); + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size); + if (*bytes_str == NULL) { + goto error; + } + char *p = *bytes_str; + for (Py_ssize_t i=0; i < size; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + *p++ = (char) ch; + } + (*bytes_str) = p; + goto success; + } + else { + *p_output = Py_NewRef(s); + goto success; + } + +error: + Py_DECREF(mod); + Py_XDECREF(s); + return -1; + +success: + Py_DECREF(mod); + Py_DECREF(s); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* Convert an integer to a base 10 string. Returns a new non-shared string. (Return value is non-shared so that callers can modify the returned value if necessary.) */ @@ -1717,15 +1766,15 @@ long_to_decimal_string_internal(PyObject *aa, digit *pout, *pin, rem, tenpow; int negative; int d; - enum PyUnicode_Kind kind; + int kind; a = (PyLongObject *)aa; if (a == NULL || !PyLong_Check(a)) { PyErr_BadInternalCall(); return -1; } - size_a = Py_ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + negative = _PyLong_IsNegative(a); /* quick and dirty pre-check for overflowing the decimal digit limit, based on the inequality 10/3 >= log2(10) @@ -1735,7 +1784,7 @@ long_to_decimal_string_internal(PyObject *aa, if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD / (3 * PyLong_SHIFT) + 2) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; if ((max_str_digits > 0) && (max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) { PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR, @@ -1744,6 +1793,17 @@ long_to_decimal_string_internal(PyObject *aa, } } +#if WITH_PYLONG_MODULE + if (size_a > 1000) { + /* Switch to _pylong.int_to_decimal_string(). */ + return pylong_int_to_decimal_string(aa, + p_output, + writer, + bytes_writer, + bytes_str); + } +#endif + /* quick and dirty upper bound for the number of digits required to express a in base _PyLong_DECIMAL_BASE: @@ -1769,8 +1829,8 @@ long_to_decimal_string_internal(PyObject *aa, /* convert array of base _PyLong_BASE digits in pin to an array of base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, Volume 2 (3rd edn), section 4.4, Method 1b). */ - pin = a->ob_digit; - pout = scratch->ob_digit; + pin = a->long_value.ob_digit; + pout = scratch->long_value.ob_digit; size = 0; for (i = size_a; --i >= 0; ) { digit hi = pin[i]; @@ -1805,7 +1865,7 @@ long_to_decimal_string_internal(PyObject *aa, } if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; Py_ssize_t strlen_nosign = strlen - negative; if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) { Py_DECREF(scratch); @@ -1935,7 +1995,7 @@ long_format_binary(PyObject *aa, int base, int alternate, PyObject *v = NULL; Py_ssize_t sz; Py_ssize_t size_a; - enum PyUnicode_Kind kind; + int kind; int negative; int bits; @@ -1944,8 +2004,8 @@ long_format_binary(PyObject *aa, int base, int alternate, PyErr_BadInternalCall(); return -1; } - size_a = Py_ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + negative = _PyLong_IsNegative(a); /* Compute a rough upper bound for the length of the string */ switch (base) { @@ -1975,7 +2035,7 @@ long_format_binary(PyObject *aa, int base, int alternate, return -1; } size_a_in_bits = (size_a - 1) * PyLong_SHIFT + - bit_length_digit(a->ob_digit[size_a - 1]); + bit_length_digit(a->long_value.ob_digit[size_a - 1]); /* Allow 1 character for a '-' sign. */ sz = negative + (size_a_in_bits + (bits - 1)) / bits; } @@ -2012,7 +2072,7 @@ long_format_binary(PyObject *aa, int base, int alternate, int accumbits = 0; /* # of bits in accum */ \ Py_ssize_t i; \ for (i = 0; i < size_a; ++i) { \ - accum |= (twodigits)a->ob_digit[i] << accumbits; \ + accum |= (twodigits)a->long_value.ob_digit[i] << accumbits; \ accumbits += PyLong_SHIFT; \ assert(accumbits >= bits); \ do { \ @@ -2161,23 +2221,23 @@ unsigned char _PyLong_DigitValue[256] = { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, }; -/* *str points to the first digit in a string of base `base` digits. base - * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first - * non-digit (which may be *str!). A normalized int is returned. - * The point to this routine is that it takes time linear in the number of - * string characters. +/* `start` and `end` point to the start and end of a string of base `base` + * digits. base is a power of 2 (2, 4, 8, 16, or 32). An unnormalized int is + * returned in *res. The string should be already validated by the caller and + * consists only of valid digit characters and underscores. `digits` gives the + * number of digit characters. + * + * The point to this routine is that it takes time linear in the + * number of string characters. * * Return values: * -1 on syntax error (exception needs to be set, *res is untouched) * 0 else (exception may be set, in that case *res is set to NULL) */ static int -long_from_binary_base(const char **str, int base, PyLongObject **res) +long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) { - const char *p = *str; - const char *start = p; - char prev = 0; - Py_ssize_t digits = 0; + const char *p; int bits_per_char; Py_ssize_t n; PyLongObject *z; @@ -2190,26 +2250,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) for (bits_per_char = -1; n; ++bits_per_char) { n >>= 1; } - /* count digits and set p to end-of-string */ - while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { - if (*p == '_') { - if (prev == '_') { - *str = p - 1; - return -1; - } - } else { - ++digits; - } - prev = *p; - ++p; - } - if (prev == '_') { - /* Trailing underscore not allowed. */ - *str = p - 1; - return -1; - } - *str = p; /* n <- the number of Python digits needed, = ceiling((digits * bits_per_char) / PyLong_SHIFT). */ if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) { @@ -2229,7 +2270,8 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) */ accum = 0; bits_in_accum = 0; - pdigit = z->ob_digit; + pdigit = z->long_value.ob_digit; + p = end; while (--p >= start) { int k; if (*p == '_') { @@ -2241,7 +2283,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) bits_in_accum += bits_per_char; if (bits_in_accum >= PyLong_SHIFT) { *pdigit++ = (digit)(accum & PyLong_MASK); - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); accum >>= PyLong_SHIFT; bits_in_accum -= PyLong_SHIFT; assert(bits_in_accum < PyLong_SHIFT); @@ -2250,92 +2292,54 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) if (bits_in_accum) { assert(bits_in_accum <= PyLong_SHIFT); *pdigit++ = (digit)accum; - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); } - while (pdigit - z->ob_digit < n) + while (pdigit - z->long_value.ob_digit < n) *pdigit++ = 0; - *res = long_normalize(z); + *res = z; return 0; } -/* Parses an int from a bytestring. Leading and trailing whitespace will be - * ignored. - * - * If successful, a PyLong object will be returned and 'pend' will be pointing - * to the first unused byte unless it's NULL. - * - * If unsuccessful, NULL will be returned. - */ -PyObject * -PyLong_FromString(const char *str, char **pend, int base) -{ - int sign = 1, error_if_nonzero = 0; - const char *start, *orig_str = str; - PyLongObject *z = NULL; - PyObject *strobj; - Py_ssize_t slen; +static PyObject *long_neg(PyLongObject *v); - if ((base != 0 && base < 2) || base > 36) { - PyErr_SetString(PyExc_ValueError, - "int() arg 2 must be >= 2 and <= 36"); - return NULL; - } - while (*str != '\0' && Py_ISSPACE(*str)) { - str++; - } - if (*str == '+') { - ++str; - } - else if (*str == '-') { - ++str; - sign = -1; +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster str-to-long conversion for base 10, using _pylong.py */ +static int +pylong_int_from_string(const char *start, const char *end, PyLongObject **res) +{ + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + goto error; } - if (base == 0) { - if (str[0] != '0') { - base = 10; - } - else if (str[1] == 'x' || str[1] == 'X') { - base = 16; - } - else if (str[1] == 'o' || str[1] == 'O') { - base = 8; - } - else if (str[1] == 'b' || str[1] == 'B') { - base = 2; - } - else { - /* "old" (C-style) octal literal, now invalid. - it might still be zero though */ - error_if_nonzero = 1; - base = 10; - } + PyObject *s = PyUnicode_FromStringAndSize(start, end-start); + if (s == NULL) { + Py_DECREF(mod); + goto error; } - if (str[0] == '0' && - ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || - (base == 8 && (str[1] == 'o' || str[1] == 'O')) || - (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { - str += 2; - /* One underscore allowed here. */ - if (*str == '_') { - ++str; - } + PyObject *result = PyObject_CallMethod(mod, "int_from_string", "O", s); + Py_DECREF(s); + Py_DECREF(mod); + if (result == NULL) { + goto error; } - if (str[0] == '_') { - /* May not start with underscores. */ - goto onError; + if (!PyLong_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_TypeError, + "_pylong.int_from_string did not return an int"); + goto error; } + *res = (PyLongObject *)result; + return 0; +error: + *res = NULL; + return 0; // See the long_from_string_base() API comment. +} +#endif /* WITH_PYLONG_MODULE */ - start = str; - if ((base & (base - 1)) == 0) { - /* binary bases are not limited by int_max_str_digits */ - int res = long_from_binary_base(&str, base, &z); - if (res < 0) { - /* Syntax error. */ - goto onError; - } - } - else { /*** +long_from_non_binary_base: parameters and return values are the same as +long_from_binary_base. + Binary bases can be converted in time linear in the number of digits, because Python's representation base is binary. Other bases (including decimal!) use the simple quadratic-time algorithm below, complicated by some speed tricks. @@ -2420,198 +2424,336 @@ that triggers it(!). Instead the code was tested by artificially allocating just 1 digit at the start, so that the copying code was exercised for every digit beyond the first. ***/ - twodigits c; /* current input character */ - Py_ssize_t size_z; - Py_ssize_t digits = 0; - int i; - int convwidth; - twodigits convmultmax, convmult; - digit *pz, *pzstop; - const char *scan, *lastdigit; - char prev = 0; +static int +long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) +{ + twodigits c; /* current input character */ + Py_ssize_t size_z; + int i; + int convwidth; + twodigits convmultmax, convmult; + digit *pz, *pzstop; + PyLongObject *z; + const char *p; - static double log_base_BASE[37] = {0.0e0,}; - static int convwidth_base[37] = {0,}; - static twodigits convmultmax_base[37] = {0,}; + static double log_base_BASE[37] = {0.0e0,}; + static int convwidth_base[37] = {0,}; + static twodigits convmultmax_base[37] = {0,}; - if (log_base_BASE[base] == 0.0) { - twodigits convmax = base; - int i = 1; + if (log_base_BASE[base] == 0.0) { + twodigits convmax = base; + int i = 1; - log_base_BASE[base] = (log((double)base) / - log((double)PyLong_BASE)); - for (;;) { - twodigits next = convmax * base; - if (next > PyLong_BASE) { - break; - } - convmax = next; - ++i; + log_base_BASE[base] = (log((double)base) / + log((double)PyLong_BASE)); + for (;;) { + twodigits next = convmax * base; + if (next > PyLong_BASE) { + break; } - convmultmax_base[base] = convmax; - assert(i > 0); - convwidth_base[base] = i; + convmax = next; + ++i; } + convmultmax_base[base] = convmax; + assert(i > 0); + convwidth_base[base] = i; + } - /* Find length of the string of numeric characters. */ - scan = str; - lastdigit = str; + /* Create an int object that can contain the largest possible + * integer with this base and length. Note that there's no + * need to initialize z->long_value.ob_digit -- no slot is read up before + * being stored into. + */ + double fsize_z = (double)digits * log_base_BASE[base] + 1.0; + if (fsize_z > (double)MAX_LONG_DIGITS) { + /* The same exception as in _PyLong_New(). */ + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + *res = NULL; + return 0; + } + size_z = (Py_ssize_t)fsize_z; + /* Uncomment next line to test exceedingly rare copy code */ + /* size_z = 1; */ + assert(size_z > 0); + z = _PyLong_New(size_z); + if (z == NULL) { + *res = NULL; + return 0; + } + _PyLong_SetSignAndDigitCount(z, 0, 0); - while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base || *scan == '_') { - if (*scan == '_') { - if (prev == '_') { - /* Only one underscore allowed. */ - str = lastdigit + 1; - goto onError; - } + /* `convwidth` consecutive input digits are treated as a single + * digit in base `convmultmax`. + */ + convwidth = convwidth_base[base]; + convmultmax = convmultmax_base[base]; + + /* Work ;-) */ + p = start; + while (p < end) { + if (*p == '_') { + p++; + continue; + } + /* grab up to convwidth digits from the input string */ + c = (digit)_PyLong_DigitValue[Py_CHARMASK(*p++)]; + for (i = 1; i < convwidth && p != end; ++p) { + if (*p == '_') { + continue; + } + i++; + c = (twodigits)(c * base + + (int)_PyLong_DigitValue[Py_CHARMASK(*p)]); + assert(c < PyLong_BASE); + } + + convmult = convmultmax; + /* Calculate the shift only if we couldn't get + * convwidth digits. + */ + if (i != convwidth) { + convmult = base; + for ( ; i > 1; --i) { + convmult *= base; + } + } + + /* Multiply z by convmult, and add c. */ + pz = z->long_value.ob_digit; + pzstop = pz + _PyLong_DigitCount(z); + for (; pz < pzstop; ++pz) { + c += (twodigits)*pz * convmult; + *pz = (digit)(c & PyLong_MASK); + c >>= PyLong_SHIFT; + } + /* carry off the current end? */ + if (c) { + assert(c < PyLong_BASE); + if (_PyLong_DigitCount(z) < size_z) { + *pz = (digit)c; + assert(!_PyLong_IsNegative(z)); + _PyLong_SetSignAndDigitCount(z, 1, _PyLong_DigitCount(z) + 1); } else { - ++digits; - lastdigit = scan; + PyLongObject *tmp; + /* Extremely rare. Get more space. */ + assert(_PyLong_DigitCount(z) == size_z); + tmp = _PyLong_New(size_z + 1); + if (tmp == NULL) { + Py_DECREF(z); + *res = NULL; + return 0; + } + memcpy(tmp->long_value.ob_digit, + z->long_value.ob_digit, + sizeof(digit) * size_z); + Py_SETREF(z, tmp); + z->long_value.ob_digit[size_z] = (digit)c; + ++size_z; } - prev = *scan; - ++scan; } - if (prev == '_') { - /* Trailing underscore not allowed. */ - /* Set error pointer to first underscore. */ - str = lastdigit + 1; - goto onError; + } + *res = z; + return 0; +} + +/* *str points to the first digit in a string of base `base` digits. base is an + * integer from 2 to 36 inclusive. Here we don't need to worry about prefixes + * like 0x or leading +- signs. The string should be null terminated consisting + * of ASCII digits and separating underscores possibly with trailing whitespace + * but we have to validate all of those points here. + * + * If base is a power of 2 then the complexity is linear in the number of + * characters in the string. Otherwise a quadratic algorithm is used for + * non-binary bases. + * + * Return values: + * + * - Returns -1 on syntax error (exception needs to be set, *res is untouched) + * - Returns 0 and sets *res to NULL for MemoryError, OverflowError, or + * _pylong.int_from_string() errors. + * - Returns 0 and sets *res to an unsigned, unnormalized PyLong (success!). + * + * Afterwards *str is set to point to the first non-digit (which may be *str!). + */ +static int +long_from_string_base(const char **str, int base, PyLongObject **res) +{ + const char *start, *end, *p; + char prev = 0; + Py_ssize_t digits = 0; + int is_binary_base = (base & (base - 1)) == 0; + + /* Here we do four things: + * + * - Find the `end` of the string. + * - Validate the string. + * - Count the number of `digits` (rather than underscores) + * - Point *str to the end-of-string or first invalid character. + */ + start = p = *str; + /* Leading underscore not allowed. */ + if (*start == '_') { + return -1; + } + /* Verify all characters are digits and underscores. */ + while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { + if (*p == '_') { + /* Double underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + } else { + ++digits; } + prev = *p; + ++p; + } + /* Trailing underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + *str = end = p; + /* Reject empty strings */ + if (start == end) { + return -1; + } + /* Allow only trailing whitespace after `end` */ + while (*p && Py_ISSPACE(*p)) { + p++; + } + *str = p; + if (*p != '\0') { + return -1; + } - /* Limit the size to avoid excessive computation attacks. */ + /* + * Pass a validated string consisting of only valid digits and underscores + * to long_from_xxx_base. + */ + if (is_binary_base) { + /* Use the linear algorithm for binary bases. */ + return long_from_binary_base(start, end, digits, base, res); + } + else { + /* Limit the size to avoid excessive computation attacks exploiting the + * quadratic algorithm. */ if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; if ((max_str_digits > 0) && (digits > max_str_digits)) { PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT, max_str_digits, digits); - return NULL; + *res = NULL; + return 0; } } - - /* Create an int object that can contain the largest possible - * integer with this base and length. Note that there's no - * need to initialize z->ob_digit -- no slot is read up before - * being stored into. - */ - double fsize_z = (double)digits * log_base_BASE[base] + 1.0; - if (fsize_z > (double)MAX_LONG_DIGITS) { - /* The same exception as in _PyLong_New(). */ - PyErr_SetString(PyExc_OverflowError, - "too many digits in integer"); - return NULL; - } - size_z = (Py_ssize_t)fsize_z; - /* Uncomment next line to test exceedingly rare copy code */ - /* size_z = 1; */ - assert(size_z > 0); - z = _PyLong_New(size_z); - if (z == NULL) { - return NULL; +#if WITH_PYLONG_MODULE + if (digits > 6000 && base == 10) { + /* Switch to _pylong.int_from_string() */ + return pylong_int_from_string(start, end, res); } - Py_SET_SIZE(z, 0); - - /* `convwidth` consecutive input digits are treated as a single - * digit in base `convmultmax`. - */ - convwidth = convwidth_base[base]; - convmultmax = convmultmax_base[base]; - - /* Work ;-) */ - while (str < scan) { - if (*str == '_') { - str++; - continue; - } - /* grab up to convwidth digits from the input string */ - c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; - for (i = 1; i < convwidth && str != scan; ++str) { - if (*str == '_') { - continue; - } - i++; - c = (twodigits)(c * base + - (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); - assert(c < PyLong_BASE); - } +#endif + /* Use the quadratic algorithm for non binary bases. */ + return long_from_non_binary_base(start, end, digits, base, res); + } +} - convmult = convmultmax; - /* Calculate the shift only if we couldn't get - * convwidth digits. - */ - if (i != convwidth) { - convmult = base; - for ( ; i > 1; --i) { - convmult *= base; - } - } +/* Parses an int from a bytestring. Leading and trailing whitespace will be + * ignored. + * + * If successful, a PyLong object will be returned and 'pend' will be pointing + * to the first unused byte unless it's NULL. + * + * If unsuccessful, NULL will be returned. + */ +PyObject * +PyLong_FromString(const char *str, char **pend, int base) +{ + int sign = 1, error_if_nonzero = 0; + const char *orig_str = str; + PyLongObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; - /* Multiply z by convmult, and add c. */ - pz = z->ob_digit; - pzstop = pz + Py_SIZE(z); - for (; pz < pzstop; ++pz) { - c += (twodigits)*pz * convmult; - *pz = (digit)(c & PyLong_MASK); - c >>= PyLong_SHIFT; - } - /* carry off the current end? */ - if (c) { - assert(c < PyLong_BASE); - if (Py_SIZE(z) < size_z) { - *pz = (digit)c; - Py_SET_SIZE(z, Py_SIZE(z) + 1); - } - else { - PyLongObject *tmp; - /* Extremely rare. Get more space. */ - assert(Py_SIZE(z) == size_z); - tmp = _PyLong_New(size_z + 1); - if (tmp == NULL) { - Py_DECREF(z); - return NULL; - } - memcpy(tmp->ob_digit, - z->ob_digit, - sizeof(digit) * size_z); - Py_DECREF(z); - z = tmp; - z->ob_digit[size_z] = (digit)c; - ++size_z; - } - } + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + while (*str != '\0' && Py_ISSPACE(*str)) { + ++str; + } + if (*str == '+') { + ++str; + } + else if (*str == '-') { + ++str; + sign = -1; + } + if (base == 0) { + if (str[0] != '0') { + base = 10; + } + else if (str[1] == 'x' || str[1] == 'X') { + base = 16; + } + else if (str[1] == 'o' || str[1] == 'O') { + base = 8; } + else if (str[1] == 'b' || str[1] == 'B') { + base = 2; + } + else { + /* "old" (C-style) octal literal, now invalid. + it might still be zero though */ + error_if_nonzero = 1; + base = 10; + } + } + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { + str += 2; + /* One underscore allowed here. */ + if (*str == '_') { + ++str; + } + } + + /* long_from_string_base is the main workhorse here. */ + int ret = long_from_string_base(&str, base, &z); + if (ret == -1) { + /* Syntax error. */ + goto onError; } if (z == NULL) { + /* Error. exception already set. */ return NULL; } + if (error_if_nonzero) { /* reset the base to 0, else the exception message doesn't make too much sense */ base = 0; - if (Py_SIZE(z) != 0) { + if (!_PyLong_IsZero(z)) { goto onError; } /* there might still be other problems, therefore base remains zero here for the same reason */ } - if (str == start) { - goto onError; - } + + /* Set sign and normalize */ if (sign < 0) { - Py_SET_SIZE(z, -(Py_SIZE(z))); - } - while (*str && Py_ISSPACE(*str)) { - str++; - } - if (*str != '\0') { - goto onError; + _PyLong_FlipSign(z); } long_normalize(z); z = maybe_small_long(z); - if (z == NULL) { - return NULL; - } + if (pend != NULL) { *pend = (char *)str; } @@ -2699,7 +2841,7 @@ static int long_divrem(PyLongObject *a, PyLongObject *b, PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; if (size_b == 0) { @@ -2709,20 +2851,19 @@ long_divrem(PyLongObject *a, PyLongObject *b, } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); if (*prem == NULL) { return -1; } PyObject *zero = _PyLong_GetZero(); - Py_INCREF(zero); - *pdiv = (PyLongObject*)zero; + *pdiv = (PyLongObject*)Py_NewRef(zero); return 0; } if (size_b == 1) { digit rem = 0; - z = divrem1(a, b->ob_digit[0], &rem); + z = divrem1(a, b->long_value.ob_digit[0], &rem); if (z == NULL) return -1; *prem = (PyLongObject *) PyLong_FromLong((long)rem); @@ -2741,14 +2882,14 @@ long_divrem(PyLongObject *a, PyLongObject *b, The quotient z has the sign of a*b; the remainder r has the sign of a, so a = b*z + r. */ - if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) { + if ((_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b))) { _PyLong_Negate(&z); if (z == NULL) { Py_CLEAR(*prem); return -1; } } - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) { _PyLong_Negate(prem); if (*prem == NULL) { Py_DECREF(z); @@ -2765,7 +2906,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, static int long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); if (size_b == 0) { PyErr_SetString(PyExc_ZeroDivisionError, @@ -2774,13 +2915,13 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); return -(*prem == NULL); } if (size_b == 1) { - *prem = rem1(a, b->ob_digit[0]); + *prem = rem1(a, b->long_value.ob_digit[0]); if (*prem == NULL) return -1; } @@ -2792,7 +2933,7 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) return -1; } /* Set the sign. */ - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) { _PyLong_Negate(prem); if (*prem == NULL) { Py_CLEAR(*prem); @@ -2803,7 +2944,7 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) } /* Unsigned int division with remainder -- the algorithm. The arguments v1 - and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */ + and w1 should satisfy 2 <= _PyLong_DigitCount(w1) <= _PyLong_DigitCount(v1). */ static PyLongObject * x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) @@ -2823,8 +2964,8 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) that won't overflow a digit. */ /* allocate space; w will also be used to hold the final remainder */ - size_v = Py_ABS(Py_SIZE(v1)); - size_w = Py_ABS(Py_SIZE(w1)); + size_v = _PyLong_DigitCount(v1); + size_w = _PyLong_DigitCount(w1); assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ v = _PyLong_New(size_v+1); if (v == NULL) { @@ -2840,16 +2981,16 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. shift v1 left by the same amount. Results go into w and v. */ - d = PyLong_SHIFT - bit_length_digit(w1->ob_digit[size_w-1]); - carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); + d = PyLong_SHIFT - bit_length_digit(w1->long_value.ob_digit[size_w-1]); + carry = v_lshift(w->long_value.ob_digit, w1->long_value.ob_digit, size_w, d); assert(carry == 0); - carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); - if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { - v->ob_digit[size_v] = carry; + carry = v_lshift(v->long_value.ob_digit, v1->long_value.ob_digit, size_v, d); + if (carry != 0 || v->long_value.ob_digit[size_v-1] >= w->long_value.ob_digit[size_w-1]) { + v->long_value.ob_digit[size_v] = carry; size_v++; } - /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has + /* Now v->long_value.ob_digit[size_v-1] < w->long_value.ob_digit[size_w-1], so quotient has at most (and usually exactly) k = size_v - size_w digits. */ k = size_v - size_w; assert(k >= 0); @@ -2860,11 +3001,11 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) *prem = NULL; return NULL; } - v0 = v->ob_digit; - w0 = w->ob_digit; + v0 = v->long_value.ob_digit; + w0 = w->long_value.ob_digit; wm1 = w0[size_w-1]; wm2 = w0[size_w-2]; - for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { + for (vk = v0+k, ak = a->long_value.ob_digit + k; vk-- > v0;) { /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving single-digit quotient q, remainder in vk[0:size_w]. */ @@ -2963,13 +3104,13 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) multiple of 4, rounding ties to a multiple of 8. */ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; - a_size = Py_ABS(Py_SIZE(a)); + a_size = _PyLong_DigitCount(a); if (a_size == 0) { /* Special case for 0: significand 0.0, exponent 0. */ *e = 0; return 0.0; } - a_bits = bit_length_digit(a->ob_digit[a_size-1]); + a_bits = bit_length_digit(a->long_value.ob_digit[a_size-1]); /* The following is an overflow-free version of the check "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && @@ -3007,7 +3148,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; x_size = shift_digits; - rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + rem = v_lshift(x_digits + x_size, a->long_value.ob_digit, a_size, (int)shift_bits); x_size += a_size; x_digits[x_size++] = rem; @@ -3015,7 +3156,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) else { shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; - rem = v_rshift(x_digits, a->ob_digit + shift_digits, + rem = v_rshift(x_digits, a->long_value.ob_digit + shift_digits, a_size - shift_digits, (int)shift_bits); x_size = a_size - shift_digits; /* For correct rounding below, we need the least significant @@ -3026,7 +3167,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) x_digits[0] |= 1; else while (shift_digits > 0) - if (a->ob_digit[--shift_digits]) { + if (a->long_value.ob_digit[--shift_digits]) { x_digits[0] |= 1; break; } @@ -3049,7 +3190,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) } *e = a_bits; - return Py_SIZE(a) < 0 ? -dx : dx; + return _PyLong_IsNegative(a) ? -dx : dx; overflow: /* exponent > PY_SSIZE_T_MAX */ @@ -3076,7 +3217,7 @@ PyLong_AsDouble(PyObject *v) PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1.0; } - if (IS_MEDIUM_VALUE(v)) { + if (_PyLong_IsCompact((PyLongObject *)v)) { /* Fast path; single digit long (31 bits) will cast safely to double. This improves performance of FP/long operations by 20%. @@ -3101,17 +3242,20 @@ PyLong_AsDouble(PyObject *v) static Py_ssize_t long_compare(PyLongObject *a, PyLongObject *b) { - Py_ssize_t sign = Py_SIZE(a) - Py_SIZE(b); + if (_PyLong_BothAreCompact(a, b)) { + return _PyLong_CompactValue(a) - _PyLong_CompactValue(b); + } + Py_ssize_t sign = _PyLong_SignedDigitCount(a) - _PyLong_SignedDigitCount(b); if (sign == 0) { - Py_ssize_t i = Py_ABS(Py_SIZE(a)); + Py_ssize_t i = _PyLong_DigitCount(a); sdigit diff = 0; while (--i >= 0) { - diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i]; + diff = (sdigit) a->long_value.ob_digit[i] - (sdigit) b->long_value.ob_digit[i]; if (diff) { break; } } - sign = Py_SIZE(a) < 0 ? -diff : diff; + sign = _PyLong_IsNegative(a) ? -diff : diff; } return sign; } @@ -3128,6 +3272,27 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } +static void +long_dealloc(PyObject *self) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref small Ints out of existence. Instead, + * since small Ints are immortal, re-set the reference count. + */ + PyLongObject *pylong = (PyLongObject*)self; + if (pylong && _PyLong_IsCompact(pylong)) { + stwodigits ival = medium_value(pylong); + if (IS_SMALL_INT(ival)) { + PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival); + if (pylong == small_pylong) { + _Py_SetImmortal(self); + return; + } + } + } + Py_TYPE(self)->tp_free(self); +} + static Py_hash_t long_hash(PyLongObject *v) { @@ -3135,21 +3300,19 @@ long_hash(PyLongObject *v) Py_ssize_t i; int sign; - i = Py_SIZE(v); - switch(i) { - case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + x = _PyLong_CompactValue(v); + if (x == (Py_uhash_t)-1) { + x = (Py_uhash_t)-2; + } + return x; } - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we - want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo _PyHASH_MODULUS. The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS @@ -3175,7 +3338,7 @@ long_hash(PyLongObject *v) _PyHASH_MODULUS. */ x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | (x >> (_PyHASH_BITS - PyLong_SHIFT)); - x += v->ob_digit[i]; + x += v->long_value.ob_digit[i]; if (x >= _PyHASH_MODULUS) x -= _PyHASH_MODULUS; } @@ -3191,7 +3354,7 @@ long_hash(PyLongObject *v) static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; Py_ssize_t i; digit carry = 0; @@ -3207,16 +3370,16 @@ x_add(PyLongObject *a, PyLongObject *b) if (z == NULL) return NULL; for (i = 0; i < size_b; ++i) { - carry += a->ob_digit[i] + b->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i] + b->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } for (; i < size_a; ++i) { - carry += a->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } - z->ob_digit[i] = carry; + z->long_value.ob_digit[i] = carry; return long_normalize(z); } @@ -3225,7 +3388,7 @@ x_add(PyLongObject *a, PyLongObject *b) static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; Py_ssize_t i; int sign = 1; @@ -3242,11 +3405,11 @@ x_sub(PyLongObject *a, PyLongObject *b) else if (size_a == size_b) { /* Find highest digit where a and b differ: */ i = size_a; - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + while (--i >= 0 && a->long_value.ob_digit[i] == b->long_value.ob_digit[i]) ; if (i < 0) return (PyLongObject *)PyLong_FromLong(0); - if (a->ob_digit[i] < b->ob_digit[i]) { + if (a->long_value.ob_digit[i] < b->long_value.ob_digit[i]) { sign = -1; { PyLongObject *temp = a; a = b; b = temp; } } @@ -3258,20 +3421,20 @@ x_sub(PyLongObject *a, PyLongObject *b) for (i = 0; i < size_b; ++i) { /* The following assumes unsigned arithmetic works module 2**N for some N>PyLong_SHIFT. */ - borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - b->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } for (; i < size_a; ++i) { - borrow = a->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } assert(borrow == 0); if (sign < 0) { - Py_SET_SIZE(z, -Py_SIZE(z)); + _PyLong_FlipSign(z); } return maybe_small_long(long_normalize(z)); } @@ -3279,13 +3442,13 @@ x_sub(PyLongObject *a, PyLongObject *b) PyObject * _PyLong_Add(PyLongObject *a, PyLongObject *b) { - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { return _PyLong_FromSTwoDigits(medium_value(a) + medium_value(b)); } PyLongObject *z; - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(a)) { + if (_PyLong_IsNegative(b)) { z = x_add(a, b); if (z != NULL) { /* x_add received at least one multiple-digit int, @@ -3293,14 +3456,14 @@ _PyLong_Add(PyLongObject *a, PyLongObject *b) That also means z is not an element of small_ints, so negating it in-place is safe. */ assert(Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -(Py_SIZE(z))); + _PyLong_FlipSign(z); } } else z = x_sub(b, a); } else { - if (Py_SIZE(b) < 0) + if (_PyLong_IsNegative(b)) z = x_sub(a, b); else z = x_add(a, b); @@ -3320,23 +3483,23 @@ _PyLong_Subtract(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b)); } - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(a)) { + if (_PyLong_IsNegative(b)) { z = x_sub(b, a); } else { z = x_add(a, b); if (z != NULL) { - assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -(Py_SIZE(z))); + assert(_PyLong_IsZero(z) || Py_REFCNT(z) == 1); + _PyLong_FlipSign(z); } } } else { - if (Py_SIZE(b) < 0) + if (_PyLong_IsNegative(b)) z = x_add(a, b); else z = x_sub(a, b); @@ -3358,15 +3521,15 @@ static PyLongObject * x_mul(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)); - Py_ssize_t size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a); + Py_ssize_t size_b = _PyLong_DigitCount(b); Py_ssize_t i; z = _PyLong_New(size_a + size_b); if (z == NULL) return NULL; - memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); + memset(z->long_value.ob_digit, 0, _PyLong_DigitCount(z) * sizeof(digit)); if (a == b) { /* Efficient squaring per HAC, Algorithm 14.16: * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf @@ -3374,12 +3537,12 @@ x_mul(PyLongObject *a, PyLongObject *b) * via exploiting that each entry in the multiplication * pyramid appears twice (except for the size_a squares). */ - digit *paend = a->ob_digit + size_a; + digit *paend = a->long_value.ob_digit + size_a; for (i = 0; i < size_a; ++i) { twodigits carry; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + (i << 1); - digit *pa = a->ob_digit + i + 1; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + (i << 1); + digit *pa = a->long_value.ob_digit + i + 1; SIGCHECK({ Py_DECREF(z); @@ -3428,10 +3591,10 @@ x_mul(PyLongObject *a, PyLongObject *b) else { /* a is not the same as b -- gradeschool int mult */ for (i = 0; i < size_a; ++i) { twodigits carry = 0; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + i; - digit *pb = b->ob_digit; - digit *pbend = b->ob_digit + size_b; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + i; + digit *pb = b->long_value.ob_digit; + digit *pbend = b->long_value.ob_digit + size_b; SIGCHECK({ Py_DECREF(z); @@ -3467,7 +3630,7 @@ kmul_split(PyLongObject *n, { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = Py_ABS(Py_SIZE(n)); + const Py_ssize_t size_n = _PyLong_DigitCount(n); size_lo = Py_MIN(size_n, size); size_hi = size_n - size_lo; @@ -3479,8 +3642,8 @@ kmul_split(PyLongObject *n, return -1; } - memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); - memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); + memcpy(lo->long_value.ob_digit, n->long_value.ob_digit, size_lo * sizeof(digit)); + memcpy(hi->long_value.ob_digit, n->long_value.ob_digit + size_lo, size_hi * sizeof(digit)); *high = long_normalize(hi); *low = long_normalize(lo); @@ -3496,8 +3659,8 @@ static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = Py_ABS(Py_SIZE(a)); - Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + Py_ssize_t asize = _PyLong_DigitCount(a); + Py_ssize_t bsize = _PyLong_DigitCount(b); PyLongObject *ah = NULL; PyLongObject *al = NULL; PyLongObject *bh = NULL; @@ -3540,7 +3703,7 @@ k_mul(PyLongObject *a, PyLongObject *b) /* If a is small compared to b, splitting on b gives a degenerate * case with ah==0, and Karatsuba may be (even much) less efficient * than "grade school" then. However, we can still win, by viewing - * b as a string of "big digits", each of width a->ob_size. That + * b as a string of "big digits", each of the same width as a. That * leads to a sequence of balanced calls to k_mul. */ if (2 * asize <= bsize) @@ -3549,13 +3712,11 @@ k_mul(PyLongObject *a, PyLongObject *b) /* Split a & b into hi & lo pieces. */ shift = bsize >> 1; if (kmul_split(a, shift, &ah, &al) < 0) goto fail; - assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ + assert(_PyLong_IsPositive(ah)); /* the split isn't degenerate */ if (a == b) { - bh = ah; - bl = al; - Py_INCREF(bh); - Py_INCREF(bl); + bh = (PyLongObject*)Py_NewRef(ah); + bl = (PyLongObject*)Py_NewRef(al); } else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; @@ -3580,20 +3741,20 @@ k_mul(PyLongObject *a, PyLongObject *b) if (ret == NULL) goto fail; #ifdef Py_DEBUG /* Fill with trash, to catch reference to uninitialized digits. */ - memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0xDF, _PyLong_DigitCount(ret) * sizeof(digit)); #endif /* 2. t1 <- ah*bh, and copy into high digits of result. */ if ((t1 = k_mul(ah, bh)) == NULL) goto fail; - assert(Py_SIZE(t1) >= 0); - assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); - memcpy(ret->ob_digit + 2*shift, t1->ob_digit, - Py_SIZE(t1) * sizeof(digit)); + assert(!_PyLong_IsNegative(t1)); + assert(2*shift + _PyLong_DigitCount(t1) <= _PyLong_DigitCount(ret)); + memcpy(ret->long_value.ob_digit + 2*shift, t1->long_value.ob_digit, + _PyLong_DigitCount(t1) * sizeof(digit)); /* Zero-out the digits higher than the ah*bh copy. */ - i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); + i = _PyLong_DigitCount(ret) - 2*shift - _PyLong_DigitCount(t1); if (i) - memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, + memset(ret->long_value.ob_digit + 2*shift + _PyLong_DigitCount(t1), 0, i * sizeof(digit)); /* 3. t2 <- al*bl, and copy into the low digits. */ @@ -3601,23 +3762,23 @@ k_mul(PyLongObject *a, PyLongObject *b) Py_DECREF(t1); goto fail; } - assert(Py_SIZE(t2) >= 0); - assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ - memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); + assert(!_PyLong_IsNegative(t2)); + assert(_PyLong_DigitCount(t2) <= 2*shift); /* no overlap with high digits */ + memcpy(ret->long_value.ob_digit, t2->long_value.ob_digit, _PyLong_DigitCount(t2) * sizeof(digit)); /* Zero out remaining digits. */ - i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ + i = 2*shift - _PyLong_DigitCount(t2); /* number of uninitialized digits */ if (i) - memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); + memset(ret->long_value.ob_digit + _PyLong_DigitCount(t2), 0, i * sizeof(digit)); /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first * because it's fresher in cache. */ - i = Py_SIZE(ret) - shift; /* # digits after shift */ - (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); + i = _PyLong_DigitCount(ret) - shift; /* # digits after shift */ + (void)v_isub(ret->long_value.ob_digit + shift, i, t2->long_value.ob_digit, _PyLong_DigitCount(t2)); _Py_DECREF_INT(t2); - (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); + (void)v_isub(ret->long_value.ob_digit + shift, i, t1->long_value.ob_digit, _PyLong_DigitCount(t1)); _Py_DECREF_INT(t1); /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ @@ -3627,8 +3788,7 @@ k_mul(PyLongObject *a, PyLongObject *b) ah = al = NULL; if (a == b) { - t2 = t1; - Py_INCREF(t2); + t2 = (PyLongObject*)Py_NewRef(t1); } else if ((t2 = x_add(bh, bl)) == NULL) { Py_DECREF(t1); @@ -3642,12 +3802,12 @@ k_mul(PyLongObject *a, PyLongObject *b) _Py_DECREF_INT(t1); _Py_DECREF_INT(t2); if (t3 == NULL) goto fail; - assert(Py_SIZE(t3) >= 0); + assert(!_PyLong_IsNegative(t3)); /* Add t3. It's not obvious why we can't run out of room here. * See the (*) comment after this function. */ - (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); + (void)v_iadd(ret->long_value.ob_digit + shift, i, t3->long_value.ob_digit, _PyLong_DigitCount(t3)); _Py_DECREF_INT(t3); return long_normalize(ret); @@ -3708,17 +3868,17 @@ ah*bh and al*bl too. /* b has at least twice the digits of a, and a is big enough that Karatsuba * would pay off *if* the inputs had balanced sizes. View b as a sequence - * of slices, each with a->ob_size digits, and multiply the slices by a, - * one at a time. This gives k_mul balanced inputs to work with, and is - * also cache-friendly (we compute one double-width slice of the result + * of slices, each with the same number of digits as a, and multiply the + * slices by a, one at a time. This gives k_mul balanced inputs to work with, + * and is also cache-friendly (we compute one double-width slice of the result * at a time, then move on, never backtracking except for the helpful * single-width slice overlap between successive partial sums). */ static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = Py_ABS(Py_SIZE(a)); - Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + const Py_ssize_t asize = _PyLong_DigitCount(a); + Py_ssize_t bsize = _PyLong_DigitCount(b); Py_ssize_t nbdone; /* # of b digits already multiplied */ PyLongObject *ret; PyLongObject *bslice = NULL; @@ -3730,7 +3890,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) ret = _PyLong_New(asize + bsize); if (ret == NULL) return NULL; - memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0, _PyLong_DigitCount(ret) * sizeof(digit)); /* Successive slices of b are copied into bslice. */ bslice = _PyLong_New(asize); @@ -3743,16 +3903,17 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) const Py_ssize_t nbtouse = Py_MIN(bsize, asize); /* Multiply the next slice of b by a. */ - memcpy(bslice->ob_digit, b->ob_digit + nbdone, + memcpy(bslice->long_value.ob_digit, b->long_value.ob_digit + nbdone, nbtouse * sizeof(digit)); - Py_SET_SIZE(bslice, nbtouse); + assert(nbtouse >= 0); + _PyLong_SetSignAndDigitCount(bslice, 1, nbtouse); product = k_mul(a, bslice); if (product == NULL) goto fail; /* Add into result. */ - (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, - product->ob_digit, Py_SIZE(product)); + (void)v_iadd(ret->long_value.ob_digit + nbdone, _PyLong_DigitCount(ret) - nbdone, + product->long_value.ob_digit, _PyLong_DigitCount(product)); _Py_DECREF_INT(product); bsize -= nbtouse; @@ -3774,14 +3935,14 @@ _PyLong_Multiply(PyLongObject *a, PyLongObject *b) PyLongObject *z; /* fast path for single-digit multiplication */ - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { stwodigits v = medium_value(a) * medium_value(b); return _PyLong_FromSTwoDigits(v); } z = k_mul(a, b); /* Negate if exactly one of the inputs is negative. */ - if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) { + if (!_PyLong_SameSign(a, b) && z) { _PyLong_Negate(&z); if (z == NULL) return NULL; @@ -3800,15 +3961,14 @@ long_mul(PyLongObject *a, PyLongObject *b) static PyObject * fast_mod(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit mod; - assert(Py_ABS(Py_SIZE(a)) == 1); - assert(Py_ABS(Py_SIZE(b)) == 1); - - if (Py_SIZE(a) == Py_SIZE(b)) { - /* 'a' and 'b' have the same sign. */ + assert(_PyLong_DigitCount(a) == 1); + assert(_PyLong_DigitCount(b) == 1); + sdigit sign = _PyLong_CompactSign(b); + if (_PyLong_SameSign(a, b)) { mod = left % right; } else { @@ -3816,22 +3976,21 @@ fast_mod(PyLongObject *a, PyLongObject *b) mod = right - 1 - (left - 1) % right; } - return PyLong_FromLong(mod * (sdigit)Py_SIZE(b)); + return PyLong_FromLong(mod * sign); } /* Fast floor division for single-digit longs. */ static PyObject * fast_floor_div(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit div; - assert(Py_ABS(Py_SIZE(a)) == 1); - assert(Py_ABS(Py_SIZE(b)) == 1); + assert(_PyLong_DigitCount(a) == 1); + assert(_PyLong_DigitCount(b) == 1); - if (Py_SIZE(a) == Py_SIZE(b)) { - /* 'a' and 'b' have the same sign. */ + if (_PyLong_SameSign(a, b)) { div = left / right; } else { @@ -3842,6 +4001,46 @@ fast_floor_div(PyLongObject *a, PyLongObject *b) return PyLong_FromLong(div); } +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster divmod, using _pylong.py */ +static int +pylong_int_divmod(PyLongObject *v, PyLongObject *w, + PyLongObject **pdiv, PyLongObject **pmod) +{ + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + PyObject *result = PyObject_CallMethod(mod, "int_divmod", "OO", v, w); + Py_DECREF(mod); + if (result == NULL) { + return -1; + } + if (!PyTuple_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple is required from int_divmod()"); + return -1; + } + PyObject *q = PyTuple_GET_ITEM(result, 0); + PyObject *r = PyTuple_GET_ITEM(result, 1); + if (!PyLong_Check(q) || !PyLong_Check(r)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple of int is required from int_divmod()"); + return -1; + } + if (pdiv != NULL) { + *pdiv = (PyLongObject *)Py_NewRef(q); + } + if (pmod != NULL) { + *pmod = (PyLongObject *)Py_NewRef(r); + } + Py_DECREF(result); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* The / and % operators are now defined in terms of divmod(). The expression a mod b has the value a - b*floor(a/b). The long_divrem function gives the remainder after division of @@ -3869,7 +4068,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, { PyLongObject *div, *mod; - if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) { /* Fast path for single-digit longs */ div = NULL; if (pdiv != NULL) { @@ -3893,14 +4092,25 @@ l_divmod(PyLongObject *v, PyLongObject *w, } return 0; } +#if WITH_PYLONG_MODULE + Py_ssize_t size_v = _PyLong_DigitCount(v); /* digits in numerator */ + Py_ssize_t size_w = _PyLong_DigitCount(w); /* digits in denominator */ + if (size_w > 300 && (size_v - size_w) > 150) { + /* Switch to _pylong.int_divmod(). If the quotient is small then + "schoolbook" division is linear-time so don't use in that case. + These limits are empirically determined and should be slightly + conservative so that _pylong is used in cases it is likely + to be faster. See Tools/scripts/divmod_threshold.py. */ + return pylong_int_divmod(v, w, pdiv, pmod); + } +#endif if (long_divrem(v, w, &div, &mod) < 0) return -1; - if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || - (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) || + (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) { PyLongObject *temp; temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; + Py_SETREF(mod, temp); if (mod == NULL) { Py_DECREF(div); return -1; @@ -3911,8 +4121,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, Py_DECREF(div); return -1; } - Py_DECREF(div); - div = temp; + Py_SETREF(div, temp); } if (pdiv != NULL) *pdiv = div; @@ -3937,19 +4146,18 @@ l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod) PyLongObject *mod; assert(pmod); - if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) { /* Fast path for single-digit longs */ *pmod = (PyLongObject *)fast_mod(v, w); return -(*pmod == NULL); } if (long_rem(v, w, &mod) < 0) return -1; - if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || - (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) || + (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) { PyLongObject *temp; temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; + Py_SETREF(mod, temp); if (mod == NULL) return -1; } @@ -3965,7 +4173,7 @@ long_div(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + if (_PyLong_DigitCount((PyLongObject*)a) == 1 && _PyLong_DigitCount((PyLongObject*)b) == 1) { return fast_floor_div((PyLongObject*)a, (PyLongObject*)b); } @@ -4080,9 +4288,9 @@ long_true_divide(PyObject *v, PyObject *w) */ /* Reduce to case where a and b are both positive. */ - a_size = Py_ABS(Py_SIZE(a)); - b_size = Py_ABS(Py_SIZE(b)); - negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + a_size = _PyLong_DigitCount(a); + b_size = _PyLong_DigitCount(b); + negate = (_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b)); if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); @@ -4097,18 +4305,18 @@ long_true_divide(PyObject *v, PyObject *w) the x87 FPU set to 64-bit precision. */ a_is_small = a_size <= MANT_DIG_DIGITS || (a_size == MANT_DIG_DIGITS+1 && - a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + a->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); b_is_small = b_size <= MANT_DIG_DIGITS || (b_size == MANT_DIG_DIGITS+1 && - b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); if (a_is_small && b_is_small) { double da, db; - da = a->ob_digit[--a_size]; + da = a->long_value.ob_digit[--a_size]; while (a_size > 0) - da = da * PyLong_BASE + a->ob_digit[--a_size]; - db = b->ob_digit[--b_size]; + da = da * PyLong_BASE + a->long_value.ob_digit[--a_size]; + db = b->long_value.ob_digit[--b_size]; while (b_size > 0) - db = db * PyLong_BASE + b->ob_digit[--b_size]; + db = db * PyLong_BASE + b->long_value.ob_digit[--b_size]; result = da / db; goto success; } @@ -4122,8 +4330,8 @@ long_true_divide(PyObject *v, PyObject *w) /* Extreme underflow */ goto underflow_or_zero; /* Next line is now safe from overflowing a Py_ssize_t */ - diff = diff * PyLong_SHIFT + bit_length_digit(a->ob_digit[a_size - 1]) - - bit_length_digit(b->ob_digit[b_size - 1]); + diff = diff * PyLong_SHIFT + bit_length_digit(a->long_value.ob_digit[a_size - 1]) - + bit_length_digit(b->long_value.ob_digit[b_size - 1]); /* Now diff = a_bits - b_bits. */ if (diff > DBL_MAX_EXP) goto overflow; @@ -4152,10 +4360,10 @@ long_true_divide(PyObject *v, PyObject *w) if (x == NULL) goto error; for (i = 0; i < shift_digits; i++) - x->ob_digit[i] = 0; - rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + x->long_value.ob_digit[i] = 0; + rem = v_lshift(x->long_value.ob_digit + shift_digits, a->long_value.ob_digit, a_size, -shift % PyLong_SHIFT); - x->ob_digit[a_size + shift_digits] = rem; + x->long_value.ob_digit[a_size + shift_digits] = rem; } else { Py_ssize_t shift_digits = shift / PyLong_SHIFT; @@ -4165,23 +4373,23 @@ long_true_divide(PyObject *v, PyObject *w) x = _PyLong_New(a_size - shift_digits); if (x == NULL) goto error; - rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + rem = v_rshift(x->long_value.ob_digit, a->long_value.ob_digit + shift_digits, a_size - shift_digits, shift % PyLong_SHIFT); /* set inexact if any of the bits shifted out is nonzero */ if (rem) inexact = 1; while (!inexact && shift_digits > 0) - if (a->ob_digit[--shift_digits]) + if (a->long_value.ob_digit[--shift_digits]) inexact = 1; } long_normalize(x); - x_size = Py_SIZE(x); + x_size = _PyLong_SignedDigitCount(x); /* x //= b. If the remainder is nonzero, set inexact. We own the only reference to x, so it's safe to modify it in-place. */ if (b_size == 1) { - digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, - b->ob_digit[0]); + digit rem = inplace_divrem1(x->long_value.ob_digit, x->long_value.ob_digit, x_size, + b->long_value.ob_digit[0]); long_normalize(x); if (rem) inexact = 1; @@ -4189,17 +4397,16 @@ long_true_divide(PyObject *v, PyObject *w) else { PyLongObject *div, *rem; div = x_divrem(x, b, &rem); - Py_DECREF(x); - x = div; + Py_SETREF(x, div); if (x == NULL) goto error; - if (Py_SIZE(rem)) + if (!_PyLong_IsZero(rem)) inexact = 1; Py_DECREF(rem); } - x_size = Py_ABS(Py_SIZE(x)); + x_size = _PyLong_DigitCount(x); assert(x_size > 0); /* result of division is never zero */ - x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->ob_digit[x_size-1]); + x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->long_value.ob_digit[x_size-1]); /* The number of extra bits that have to be rounded away. */ extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; @@ -4207,15 +4414,15 @@ long_true_divide(PyObject *v, PyObject *w) /* Round by directly modifying the low digit of x. */ mask = (digit)1 << (extra_bits - 1); - low = x->ob_digit[0] | inexact; + low = x->long_value.ob_digit[0] | inexact; if ((low & mask) && (low & (3U*mask-1U))) low += mask; - x->ob_digit[0] = low & ~(2U*mask-1U); + x->long_value.ob_digit[0] = low & ~(2U*mask-1U); /* Convert x to a double dx; the conversion is exact. */ - dx = x->ob_digit[--x_size]; + dx = x->long_value.ob_digit[--x_size]; while (x_size > 0) - dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + dx = dx * PyLong_BASE + x->long_value.ob_digit[--x_size]; Py_DECREF(x); /* Check whether ldexp result will overflow a double. */ @@ -4299,7 +4506,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) PyLongObject *b, *c; /* Should only ever be called for positive n */ - assert(Py_SIZE(n) > 0); + assert(_PyLong_IsPositive(n)); b = (PyLongObject *)PyLong_FromLong(1L); if (b == NULL) { @@ -4314,14 +4521,13 @@ long_invmod(PyLongObject *a, PyLongObject *n) Py_INCREF(n); /* references now owned: a, b, c, n */ - while (Py_SIZE(n) != 0) { + while (!_PyLong_IsZero(n)) { PyLongObject *q, *r, *s, *t; if (l_divmod(a, n, &q, &r) == -1) { goto Error; } - Py_DECREF(a); - a = n; + Py_SETREF(a, n); n = r; t = (PyLongObject *)long_mul(q, c); Py_DECREF(q); @@ -4333,8 +4539,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) if (s == NULL) { goto Error; } - Py_DECREF(b); - b = c; + Py_SETREF(b, c); c = s; } /* references now owned: a, b, c, n */ @@ -4379,7 +4584,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* k-ary values. If the exponent is large enough, table is * precomputed so that table[i] == a**(2*i+1) % c for i in * range(EXP_TABLE_LEN). - * Note: this is uninitialzed stack trash: don't pay to set it to known + * Note: this is uninitialized stack trash: don't pay to set it to known * values unless it's needed. Instead ensure that num_table_entries is * set to the number of entries actually filled whenever a branch to the * Error or Done labels is possible. @@ -4389,11 +4594,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* a, b, c = v, w, x */ CHECK_BINOP(v, w); - a = (PyLongObject*)v; Py_INCREF(a); - b = (PyLongObject*)w; Py_INCREF(b); + a = (PyLongObject*)Py_NewRef(v); + b = (PyLongObject*)Py_NewRef(w); if (PyLong_Check(x)) { - c = (PyLongObject *)x; - Py_INCREF(x); + c = (PyLongObject *)Py_NewRef(x); } else if (x == Py_None) c = NULL; @@ -4403,7 +4607,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_RETURN_NOTIMPLEMENTED; } - if (Py_SIZE(b) < 0 && c == NULL) { + if (_PyLong_IsNegative(b) && c == NULL) { /* if exponent is negative and there's no modulus: return a float. This works because we know that this calls float_pow() which converts its @@ -4416,7 +4620,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (c) { /* if modulus == 0: raise ValueError() */ - if (Py_SIZE(c) == 0) { + if (_PyLong_IsZero(c)) { PyErr_SetString(PyExc_ValueError, "pow() 3rd argument cannot be 0"); goto Error; @@ -4425,13 +4629,12 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* if modulus < 0: negativeOutput = True modulus = -modulus */ - if (Py_SIZE(c) < 0) { + if (_PyLong_IsNegative(c)) { negativeOutput = 1; temp = (PyLongObject *)_PyLong_Copy(c); if (temp == NULL) goto Error; - Py_DECREF(c); - c = temp; + Py_SETREF(c, temp); temp = NULL; _PyLong_Negate(&c); if (c == NULL) @@ -4440,19 +4643,18 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* if modulus == 1: return 0 */ - if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { + if (_PyLong_IsNonNegativeCompact(c) && (c->long_value.ob_digit[0] == 1)) { z = (PyLongObject *)PyLong_FromLong(0L); goto Done; } /* if exponent is negative, negate the exponent and replace the base with a modular inverse */ - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(b)) { temp = (PyLongObject *)_PyLong_Copy(b); if (temp == NULL) goto Error; - Py_DECREF(b); - b = temp; + Py_SETREF(b, temp); temp = NULL; _PyLong_Negate(&b); if (b == NULL) @@ -4461,8 +4663,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) temp = long_invmod(a, c); if (temp == NULL) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } @@ -4475,11 +4676,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) base % modulus instead. We could _always_ do this reduction, but l_mod() isn't cheap, so we only do it when it buys something. */ - if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) { + if (_PyLong_IsNegative(a) || _PyLong_DigitCount(a) > _PyLong_DigitCount(c)) { if (l_mod(a, c, &temp) < 0) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } } @@ -4518,8 +4718,8 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) REDUCE(result); \ } while(0) - i = Py_SIZE(b); - digit bi = i ? b->ob_digit[i-1] : 0; + i = _PyLong_SignedDigitCount(b); + digit bi = i ? b->long_value.ob_digit[i-1] : 0; digit bit; if (i <= 1 && bi <= 3) { /* aim for minimal overhead */ @@ -4546,9 +4746,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) * because we're primarily trying to cut overhead for small powers. */ assert(bi); /* else there is no significant bit */ - Py_INCREF(a); - Py_DECREF(z); - z = a; + Py_SETREF(z, (PyLongObject*)Py_NewRef(a)); for (bit = 2; ; bit <<= 1) { if (bit > bi) { /* found the first bit */ assert((bi & bit) == 0); @@ -4567,7 +4765,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (--i < 0) { break; } - bi = b->ob_digit[i]; + bi = b->long_value.ob_digit[i]; bit = (digit)1 << (PyLong_SHIFT-1); } } @@ -4575,8 +4773,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* Left-to-right k-ary sliding window exponentiation * (Handbook of Applied Cryptography (HAC) Algorithm 14.85) */ - Py_INCREF(a); - table[0] = a; + table[0] = (PyLongObject*)Py_NewRef(a); num_table_entries = 1; MULT(a, a, a2); /* table[i] == a**(2*i + 1) % c */ @@ -4613,8 +4810,8 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) pending = 0; \ } while(0) - for (i = Py_SIZE(b) - 1; i >= 0; --i) { - const digit bi = b->ob_digit[i]; + for (i = _PyLong_SignedDigitCount(b) - 1; i >= 0; --i) { + const digit bi = b->long_value.ob_digit[i]; for (j = PyLong_SHIFT - 1; j >= 0; --j) { const int bit = (bi >> j) & 1; pending = (pending << 1) | bit; @@ -4631,12 +4828,11 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) ABSORB_PENDING; } - if (negativeOutput && (Py_SIZE(z) != 0)) { + if (negativeOutput && !_PyLong_IsZero(z)) { temp = (PyLongObject *)long_sub(z, c); if (temp == NULL) goto Error; - Py_DECREF(z); - z = temp; + Py_SETREF(z, temp); temp = NULL; } goto Done; @@ -4660,14 +4856,14 @@ long_invert(PyLongObject *v) { /* Implement ~x as -(x+1) */ PyLongObject *x; - if (IS_MEDIUM_VALUE(v)) + if (_PyLong_IsCompact(v)) return _PyLong_FromSTwoDigits(~medium_value(v)); x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne()); if (x == NULL) return NULL; _PyLong_Negate(&x); - /* No need for maybe_small_long here, since any small - longs will have been caught in the Py_SIZE <= 1 fast path. */ + /* No need for maybe_small_long here, since any small longs + will have been caught in the _PyLong_IsCompact() fast path. */ return (PyObject *)x; } @@ -4675,18 +4871,18 @@ static PyObject * long_neg(PyLongObject *v) { PyLongObject *z; - if (IS_MEDIUM_VALUE(v)) + if (_PyLong_IsCompact(v)) return _PyLong_FromSTwoDigits(-medium_value(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) - Py_SET_SIZE(z, -(Py_SIZE(v))); + _PyLong_FlipSign(z); return (PyObject *)z; } static PyObject * long_abs(PyLongObject *v) { - if (Py_SIZE(v) < 0) + if (_PyLong_IsNegative(v)) return long_neg(v); else return long_long((PyObject *)v); @@ -4695,7 +4891,7 @@ long_abs(PyLongObject *v) static int long_bool(PyLongObject *v) { - return Py_SIZE(v) != 0; + return !_PyLong_IsZero(v); } /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ @@ -4703,14 +4899,14 @@ static int divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift) { assert(PyLong_Check(shiftby)); - assert(Py_SIZE(shiftby) >= 0); + assert(!_PyLong_IsNegative((PyLongObject *)shiftby)); Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby); if (lshiftby >= 0) { *wordshift = lshiftby / PyLong_SHIFT; *remshift = lshiftby % PyLong_SHIFT; return 0; } - /* PyLong_Check(shiftby) is true and Py_SIZE(shiftby) >= 0, so it must + /* PyLong_Check(shiftby) is true and shiftby is not negative, so it must be that PyLong_AsSsize_t raised an OverflowError. */ assert(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); @@ -4748,7 +4944,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) assert(remshift < PyLong_SHIFT); /* Fast path for small a. */ - if (IS_MEDIUM_VALUE(a)) { + if (_PyLong_IsCompact(a)) { stwodigits m, x; digit shift; m = medium_value(a); @@ -4757,8 +4953,8 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) return _PyLong_FromSTwoDigits(x); } - a_negative = Py_SIZE(a) < 0; - size_a = Py_ABS(Py_SIZE(a)); + a_negative = _PyLong_IsNegative(a); + size_a = _PyLong_DigitCount(a); if (a_negative) { /* For negative 'a', adjust so that 0 < remshift <= PyLong_SHIFT, @@ -4786,7 +4982,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) } hishift = PyLong_SHIFT - remshift; - accum = a->ob_digit[wordshift]; + accum = a->long_value.ob_digit[wordshift]; if (a_negative) { /* For a positive integer a and nonnegative shift, we have: @@ -4799,23 +4995,23 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) significant `wordshift` digits of `a` is nonzero. Digit `wordshift` of `2**shift - 1` has value `PyLong_MASK >> hishift`. */ - Py_SET_SIZE(z, -newsize); + _PyLong_SetSignAndDigitCount(z, -1, newsize); digit sticky = 0; for (Py_ssize_t j = 0; j < wordshift; j++) { - sticky |= a->ob_digit[j]; + sticky |= a->long_value.ob_digit[j]; } accum += (PyLong_MASK >> hishift) + (digit)(sticky != 0); } accum >>= remshift; for (Py_ssize_t i = 0, j = wordshift + 1; j < size_a; i++, j++) { - accum += (twodigits)a->ob_digit[j] << hishift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum += (twodigits)a->long_value.ob_digit[j] << hishift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } assert(accum <= PyLong_MASK); - z->ob_digit[newsize - 1] = (digit)accum; + z->long_value.ob_digit[newsize - 1] = (digit)accum; z = maybe_small_long(long_normalize(z)); return (PyObject *)z; @@ -4829,11 +5025,11 @@ long_rshift(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative((PyLongObject *)b)) { PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } if (divmod_shift(b, &wordshift, &remshift) < 0) @@ -4849,7 +5045,7 @@ _PyLong_Rshift(PyObject *a, size_t shiftby) digit remshift; assert(PyLong_Check(a)); - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } wordshift = shiftby / PyLong_SHIFT; @@ -4864,34 +5060,34 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) Py_ssize_t oldsize, newsize, i, j; twodigits accum; - if (wordshift == 0 && IS_MEDIUM_VALUE(a)) { + if (wordshift == 0 && _PyLong_IsCompact(a)) { stwodigits m = medium_value(a); // bypass undefined shift operator behavior stwodigits x = m < 0 ? -(-m << remshift) : m << remshift; return _PyLong_FromSTwoDigits(x); } - oldsize = Py_ABS(Py_SIZE(a)); + oldsize = _PyLong_DigitCount(a); newsize = oldsize + wordshift; if (remshift) ++newsize; z = _PyLong_New(newsize); if (z == NULL) return NULL; - if (Py_SIZE(a) < 0) { + if (_PyLong_IsNegative(a)) { assert(Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -Py_SIZE(z)); + _PyLong_FlipSign(z); } for (i = 0; i < wordshift; i++) - z->ob_digit[i] = 0; + z->long_value.ob_digit[i] = 0; accum = 0; - for (i = wordshift, j = 0; j < oldsize; i++, j++) { - accum |= (twodigits)a->ob_digit[j] << remshift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + for (j = 0; j < oldsize; i++, j++) { + accum |= (twodigits)a->long_value.ob_digit[j] << remshift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } if (remshift) - z->ob_digit[newsize-1] = (digit)accum; + z->long_value.ob_digit[newsize-1] = (digit)accum; else assert(!accum); z = long_normalize(z); @@ -4906,11 +5102,11 @@ long_lshift(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative((PyLongObject *)b)) { PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } if (divmod_shift(b, &wordshift, &remshift) < 0) @@ -4926,7 +5122,7 @@ _PyLong_Lshift(PyObject *a, size_t shiftby) digit remshift; assert(PyLong_Check(a)); - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } wordshift = shiftby / PyLong_SHIFT; @@ -4968,13 +5164,13 @@ long_bitwise(PyLongObject *a, result back to sign-magnitude at the end. */ /* If a is negative, replace it by its two's complement. */ - size_a = Py_ABS(Py_SIZE(a)); - nega = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + nega = _PyLong_IsNegative(a); if (nega) { z = _PyLong_New(size_a); if (z == NULL) return NULL; - v_complement(z->ob_digit, a->ob_digit, size_a); + v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a); a = z; } else @@ -4982,15 +5178,15 @@ long_bitwise(PyLongObject *a, Py_INCREF(a); /* Same for b. */ - size_b = Py_ABS(Py_SIZE(b)); - negb = Py_SIZE(b) < 0; + size_b = _PyLong_DigitCount(b); + negb = _PyLong_IsNegative(b); if (negb) { z = _PyLong_New(size_b); if (z == NULL) { Py_DECREF(a); return NULL; } - v_complement(z->ob_digit, b->ob_digit, size_b); + v_complement(z->long_value.ob_digit, b->long_value.ob_digit, size_b); b = z; } else @@ -5040,15 +5236,15 @@ long_bitwise(PyLongObject *a, switch(op) { case '&': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] & b->long_value.ob_digit[i]; break; case '|': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] | b->long_value.ob_digit[i]; break; case '^': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ b->long_value.ob_digit[i]; break; default: Py_UNREACHABLE(); @@ -5057,16 +5253,16 @@ long_bitwise(PyLongObject *a, /* Copy any remaining digits of a, inverting if necessary. */ if (op == '^' && negb) for (; i < size_z; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ PyLong_MASK; else if (i < size_z) - memcpy(&z->ob_digit[i], &a->ob_digit[i], + memcpy(&z->long_value.ob_digit[i], &a->long_value.ob_digit[i], (size_z-i)*sizeof(digit)); /* Complement result if negative. */ if (negz) { - Py_SET_SIZE(z, -(Py_SIZE(z))); - z->ob_digit[size_z] = PyLong_MASK; - v_complement(z->ob_digit, z->ob_digit, size_z+1); + _PyLong_FlipSign(z); + z->long_value.ob_digit[size_z] = PyLong_MASK; + v_complement(z->long_value.ob_digit, z->long_value.ob_digit, size_z+1); } Py_DECREF(a); @@ -5080,7 +5276,7 @@ long_and(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) & medium_value(y)); } return long_bitwise(x, '&', y); @@ -5092,7 +5288,7 @@ long_xor(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y)); } return long_bitwise(x, '^', y); @@ -5104,7 +5300,7 @@ long_or(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) | medium_value(y)); } return long_bitwise(x, '|', y); @@ -5113,11 +5309,12 @@ long_or(PyObject *a, PyObject *b) static PyObject * long_long(PyObject *v) { - if (PyLong_CheckExact(v)) - Py_INCREF(v); - else - v = _PyLong_Copy((PyLongObject *)v); - return v; + if (PyLong_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return _PyLong_Copy((PyLongObject *)v); + } } PyObject * @@ -5127,14 +5324,11 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) stwodigits x, y, q, s, t, c_carry, d_carry; stwodigits A, B, C, D, T; int nbits, k; - Py_ssize_t size_a, size_b, alloc_a, alloc_b; digit *a_digit, *b_digit, *c_digit, *d_digit, *a_end, *b_end; a = (PyLongObject *)aarg; b = (PyLongObject *)barg; - size_a = Py_SIZE(a); - size_b = Py_SIZE(b); - if (-2 <= size_a && size_a <= 2 && -2 <= size_b && size_b <= 2) { + if (_PyLong_DigitCount(a) <= 2 && _PyLong_DigitCount(b) <= 2) { Py_INCREF(a); Py_INCREF(b); goto simple; @@ -5156,14 +5350,15 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) } /* We now own references to a and b */ - alloc_a = Py_SIZE(a); - alloc_b = Py_SIZE(b); + Py_ssize_t size_a, size_b, alloc_a, alloc_b; + alloc_a = _PyLong_DigitCount(a); + alloc_b = _PyLong_DigitCount(b); /* reduce until a fits into 2 digits */ - while ((size_a = Py_SIZE(a)) > 2) { - nbits = bit_length_digit(a->ob_digit[size_a-1]); + while ((size_a = _PyLong_DigitCount(a)) > 2) { + nbits = bit_length_digit(a->long_value.ob_digit[size_a-1]); /* extract top 2*PyLong_SHIFT bits of a into x, along with corresponding bits of b into y */ - size_b = Py_SIZE(b); + size_b = _PyLong_DigitCount(b); assert(size_b <= size_a); if (size_b == 0) { if (size_a < alloc_a) { @@ -5177,13 +5372,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) Py_XDECREF(d); return (PyObject *)r; } - x = (((twodigits)a->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | - ((twodigits)a->ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | - (a->ob_digit[size_a-3] >> nbits)); + x = (((twodigits)a->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | + ((twodigits)a->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | + (a->long_value.ob_digit[size_a-3] >> nbits)); - y = ((size_b >= size_a - 2 ? b->ob_digit[size_a-3] >> nbits : 0) | - (size_b >= size_a - 1 ? (twodigits)b->ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | - (size_b >= size_a ? (twodigits)b->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); + y = ((size_b >= size_a - 2 ? b->long_value.ob_digit[size_a-3] >> nbits : 0) | + (size_b >= size_a - 1 ? (twodigits)b->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | + (size_b >= size_a ? (twodigits)b->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); /* inner loop of Lehmer's algorithm; A, B, C, D never grow larger than PyLong_MASK during the algorithm. */ @@ -5204,11 +5399,10 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) /* no progress; do a Euclidean step */ if (l_mod(a, b, &r) < 0) goto error; - Py_DECREF(a); - a = b; + Py_SETREF(a, b); b = r; alloc_a = alloc_b; - alloc_b = Py_SIZE(b); + alloc_b = _PyLong_DigitCount(b); continue; } @@ -5221,11 +5415,11 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) T = -C; C = -D; D = T; } if (c != NULL) { - Py_SET_SIZE(c, size_a); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(c, 1, size_a); } else if (Py_REFCNT(a) == 1) { - Py_INCREF(a); - c = a; + c = (PyLongObject*)Py_NewRef(a); } else { alloc_a = size_a; @@ -5235,12 +5429,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) } if (d != NULL) { - Py_SET_SIZE(d, size_a); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(d, 1, size_a); } else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { - Py_INCREF(b); - d = b; - Py_SET_SIZE(d, size_a); + d = (PyLongObject*)Py_NewRef(b); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(d, 1, size_a); } else { alloc_b = size_a; @@ -5248,14 +5443,14 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) if (d == NULL) goto error; } - a_end = a->ob_digit + size_a; - b_end = b->ob_digit + size_b; + a_end = a->long_value.ob_digit + size_a; + b_end = b->long_value.ob_digit + size_b; /* compute new a and new b in parallel */ - a_digit = a->ob_digit; - b_digit = b->ob_digit; - c_digit = c->ob_digit; - d_digit = d->ob_digit; + a_digit = a->long_value.ob_digit; + b_digit = b->long_value.ob_digit; + c_digit = c->long_value.ob_digit; + d_digit = d->long_value.ob_digit; c_carry = 0; d_carry = 0; while (b_digit < b_end) { @@ -5412,9 +5607,7 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) if (tmp == NULL) return NULL; assert(PyLong_Check(tmp)); - n = Py_SIZE(tmp); - if (n < 0) - n = -n; + n = _PyLong_DigitCount(tmp); /* Fast operations for single digit integers (including zero) * assume that there is always at least one digit present. */ if (n == 0) { @@ -5426,9 +5619,9 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) return NULL; } assert(PyLong_Check(newobj)); - Py_SET_SIZE(newobj, Py_SIZE(tmp)); + newobj->long_value.lv_tag = tmp->long_value.lv_tag; for (i = 0; i < n; i++) { - newobj->ob_digit[i] = tmp->ob_digit[i]; + newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i]; } Py_DECREF(tmp); return (PyObject *)newobj; @@ -5462,11 +5655,13 @@ int.__format__ format_spec: unicode / + +Convert to a string according to format_spec. [clinic start generated code]*/ static PyObject * int___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=b4929dee9ae18689 input=e31944a9b3e428b7]*/ +/*[clinic end generated code: output=b4929dee9ae18689 input=d5e1254a47e8d1dc]*/ { _PyUnicodeWriter writer; int ret; @@ -5518,7 +5713,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) } /* Do a and b have different signs? If so, quotient is negative. */ - quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + quo_is_neg = (_PyLong_IsNegative((PyLongObject *)a)) != (_PyLong_IsNegative((PyLongObject *)b)); if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) goto error; @@ -5531,23 +5726,21 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) goto error; if (quo_is_neg) { temp = long_neg((PyLongObject*)twice_rem); - Py_DECREF(twice_rem); - twice_rem = temp; + Py_SETREF(twice_rem, temp); if (twice_rem == NULL) goto error; } cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); Py_DECREF(twice_rem); - quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); - if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + quo_is_odd = (quo->long_value.ob_digit[0] & 1) != 0; + if ((_PyLong_IsNegative((PyLongObject *)b) ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { /* fix up quotient */ if (quo_is_neg) temp = long_sub(quo, (PyLongObject *)one); else temp = long_add(quo, (PyLongObject *)one); - Py_DECREF(quo); - quo = (PyLongObject *)temp; + Py_SETREF(quo, (PyLongObject *)temp); if (quo == NULL) goto error; /* and remainder */ @@ -5555,8 +5748,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) temp = long_add(rem, (PyLongObject *)b); else temp = long_sub(rem, (PyLongObject *)b); - Py_DECREF(rem); - rem = (PyLongObject *)temp; + Py_SETREF(rem, (PyLongObject *)temp); if (rem == NULL) goto error; } @@ -5615,15 +5807,14 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return NULL; /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ - if (Py_SIZE(ndigits) >= 0) { + if (!_PyLong_IsNegative((PyLongObject *)ndigits)) { Py_DECREF(ndigits); return long_long(self); } /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ temp = long_neg((PyLongObject*)ndigits); - Py_DECREF(ndigits); - ndigits = temp; + Py_SETREF(ndigits, temp); if (ndigits == NULL) return NULL; @@ -5635,21 +5826,18 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) temp = long_pow(result, ndigits, Py_None); Py_DECREF(ndigits); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = _PyLong_DivmodNear(self, result); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = long_sub((PyLongObject *)self, (PyLongObject *)PyTuple_GET_ITEM(result, 1)); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); return result; } @@ -5664,13 +5852,10 @@ static Py_ssize_t int___sizeof___impl(PyObject *self) /*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/ { - Py_ssize_t res; - - res = offsetof(PyLongObject, ob_digit) - /* using Py_MAX(..., 1) because we always allocate space for at least - one digit, even though the integer zero has a Py_SIZE of 0 */ - + Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit); - return res; + /* using Py_MAX(..., 1) because we always allocate space for at least + one digit, even though the integer zero has a digit count of 0 */ + Py_ssize_t ndigits = Py_MAX(_PyLong_DigitCount((PyLongObject *)self), 1); + return Py_TYPE(self)->tp_basicsize + Py_TYPE(self)->tp_itemsize * ndigits; } /*[clinic input] @@ -5696,11 +5881,11 @@ int_bit_length_impl(PyObject *self) assert(self != NULL); assert(PyLong_Check(self)); - ndigits = Py_ABS(Py_SIZE(self)); + ndigits = _PyLong_DigitCount((PyLongObject *)self); if (ndigits == 0) return PyLong_FromLong(0); - msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; + msd = ((PyLongObject *)self)->long_value.ob_digit[ndigits-1]; msd_bits = bit_length_digit(msd); if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) @@ -5717,8 +5902,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); x = (PyLongObject *)PyLong_FromLong((long)msd_bits); if (x == NULL) @@ -5727,8 +5911,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); return (PyObject *)result; @@ -5767,7 +5950,7 @@ int_bit_count_impl(PyObject *self) assert(PyLong_Check(self)); PyLongObject *z = (PyLongObject *)self; - Py_ssize_t ndigits = Py_ABS(Py_SIZE(z)); + Py_ssize_t ndigits = _PyLong_DigitCount(z); Py_ssize_t bit_count = 0; /* Each digit has up to PyLong_SHIFT ones, so the accumulated bit count @@ -5775,7 +5958,7 @@ int_bit_count_impl(PyObject *self) Py_ssize_t. */ Py_ssize_t ndigits_fast = Py_MIN(ndigits, PY_SSIZE_T_MAX/PyLong_SHIFT); for (Py_ssize_t i = 0; i < ndigits_fast; i++) { - bit_count += popcount_digit(z->ob_digit[i]); + bit_count += popcount_digit(z->long_value.ob_digit[i]); } PyObject *result = PyLong_FromSsize_t(bit_count); @@ -5785,7 +5968,7 @@ int_bit_count_impl(PyObject *self) /* Use Python integers if bit_count would overflow. */ for (Py_ssize_t i = ndigits_fast; i < ndigits; i++) { - PyObject *x = PyLong_FromLong(popcount_digit(z->ob_digit[i])); + PyObject *x = PyLong_FromLong(popcount_digit(z->long_value.ob_digit[i])); if (x == NULL) { goto error; } @@ -5794,8 +5977,7 @@ int_bit_count_impl(PyObject *self) if (y == NULL) { goto error; } - Py_DECREF(result); - result = y; + Py_SETREF(result, y); } return result; @@ -5808,10 +5990,9 @@ int_bit_count_impl(PyObject *self) /*[clinic input] int.as_integer_ratio -Return integer ratio. +Return a pair of integers, whose ratio is equal to the original int. -Return a pair of integers, whose ratio is exactly equal to the original int -and with a positive denominator. +The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) @@ -5823,7 +6004,7 @@ and with a positive denominator. static PyObject * int_as_integer_ratio_impl(PyObject *self) -/*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/ +/*[clinic end generated code: output=e60803ae1cc8621a input=384ff1766634bec2]*/ { PyObject *ratio_tuple; PyObject *numerator = long_long(self); @@ -5961,6 +6142,19 @@ long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored)) return long_long(self); } +/*[clinic input] +int.is_integer + +Returns True. Exists for duck type compatibility with float.is_integer. +[clinic start generated code]*/ + +static PyObject * +int_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=90f8e794ce5430ef input=7e41c4d4416e05f2]*/ +{ + Py_RETURN_TRUE; +} + static PyMethodDef long_methods[] = { {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -5979,6 +6173,7 @@ static PyMethodDef long_methods[] = { INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF + INT_IS_INTEGER_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -6058,9 +6253,9 @@ static PyNumberMethods long_as_number = { PyTypeObject PyLong_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "int", /* tp_name */ - offsetof(PyLongObject, ob_digit), /* tp_basicsize */ + offsetof(PyLongObject, long_value.ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ - 0, /* tp_dealloc */ + long_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -6158,23 +6353,11 @@ PyLong_GetInfo(void) PyStatus _PyLong_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyLong_Type) < 0) { - return _PyStatus_ERR("Can't initialize int type"); - } - /* initialize int_info */ - if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { - return _PyStatus_ERR("can't init int info type"); - } - } - interp->int_max_str_digits = _Py_global_config_int_max_str_digits; - if (interp->int_max_str_digits == -1) { - interp->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; + if (_PyStructSequence_InitBuiltin(interp, &Int_InfoType, + &int_info_desc) < 0) + { + return _PyStatus_ERR("can't init int info type"); } return _PyStatus_OK(); @@ -6184,9 +6367,19 @@ _PyLong_InitTypes(PyInterpreterState *interp) void _PyLong_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } + _PyStructSequence_FiniBuiltin(interp, &Int_InfoType); +} + +#undef PyUnstable_Long_IsCompact - _PyStructSequence_FiniType(&Int_InfoType); +int +PyUnstable_Long_IsCompact(const PyLongObject* op) { + return _PyLong_IsCompact(op); +} + +#undef PyUnstable_Long_CompactValue + +Py_ssize_t +PyUnstable_Long_CompactValue(const PyLongObject* op) { + return _PyLong_CompactValue(op); } diff --git a/contrib/tools/python3/src/Objects/memoryobject.c b/contrib/tools/python3/src/Objects/memoryobject.c index e958ab45963..b0168044d9f 100644 --- a/contrib/tools/python3/src/Objects/memoryobject.c +++ b/contrib/tools/python3/src/Objects/memoryobject.c @@ -85,7 +85,7 @@ mbuf_alloc(void) } static PyObject * -_PyManagedBuffer_FromObject(PyObject *base) +_PyManagedBuffer_FromObject(PyObject *base, int flags) { _PyManagedBufferObject *mbuf; @@ -93,7 +93,7 @@ _PyManagedBuffer_FromObject(PyObject *base) if (mbuf == NULL) return NULL; - if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) { + if (PyObject_GetBuffer(base, &mbuf->master, flags) < 0) { mbuf->master.obj = NULL; Py_DECREF(mbuf); return NULL; @@ -193,6 +193,20 @@ PyTypeObject _PyManagedBuffer_Type = { return -1; \ } +#define CHECK_RESTRICTED(mv) \ + if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return NULL; \ + } + +#define CHECK_RESTRICTED_INT(mv) \ + if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return -1; \ + } + /* See gh-92888. These macros signal that we need to check the memoryview again due to possible read after frees. */ #define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv) @@ -682,8 +696,7 @@ mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) init_suboffsets(dest, src); init_flags(mv); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -713,8 +726,7 @@ mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src, dest = &mv->view; init_shared_values(dest, src); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -779,22 +791,24 @@ PyMemoryView_FromBuffer(const Py_buffer *info) return mv; } -/* Create a memoryview from an object that implements the buffer protocol. +/* Create a memoryview from an object that implements the buffer protocol, + using the given flags. If the object is a memoryview, the new memoryview must be registered with the same managed buffer. Otherwise, a new managed buffer is created. */ -PyObject * -PyMemoryView_FromObject(PyObject *v) +static PyObject * +PyMemoryView_FromObjectAndFlags(PyObject *v, int flags) { _PyManagedBufferObject *mbuf; if (PyMemoryView_Check(v)) { PyMemoryViewObject *mv = (PyMemoryViewObject *)v; CHECK_RELEASED(mv); + CHECK_RESTRICTED(mv); return mbuf_add_view(mv->mbuf, &mv->view); } else if (PyObject_CheckBuffer(v)) { PyObject *ret; - mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v); + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v, flags); if (mbuf == NULL) return NULL; ret = mbuf_add_view(mbuf, NULL); @@ -808,6 +822,38 @@ PyMemoryView_FromObject(PyObject *v) return NULL; } +/* Create a memoryview from an object that implements the buffer protocol, + using the given flags. + If the object is a memoryview, the new memoryview must be registered + with the same managed buffer. Otherwise, a new managed buffer is created. */ +PyObject * +_PyMemoryView_FromBufferProc(PyObject *v, int flags, getbufferproc bufferproc) +{ + _PyManagedBufferObject *mbuf = mbuf_alloc(); + if (mbuf == NULL) + return NULL; + + int res = bufferproc(v, &mbuf->master, flags); + if (res < 0) { + mbuf->master.obj = NULL; + Py_DECREF(mbuf); + return NULL; + } + + PyObject *ret = mbuf_add_view(mbuf, NULL); + Py_DECREF(mbuf); + return ret; +} + +/* Create a memoryview from an object that implements the buffer protocol. + If the object is a memoryview, the new memoryview must be registered + with the same managed buffer. Otherwise, a new managed buffer is created. */ +PyObject * +PyMemoryView_FromObject(PyObject *v) +{ + return PyMemoryView_FromObjectAndFlags(v, PyBUF_FULL_RO); +} + /* Copy the format string from a base object that might vanish. */ static int mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt) @@ -853,7 +899,7 @@ memory_from_contiguous_copy(const Py_buffer *src, char order) if (bytes == NULL) return NULL; - mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes); + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes, PyBUF_FULL_RO); Py_DECREF(bytes); if (mbuf == NULL) return NULL; @@ -970,6 +1016,24 @@ memoryview_impl(PyTypeObject *type, PyObject *object) } +/*[clinic input] +@classmethod +memoryview._from_flags + + object: object + flags: int + +Create a new memoryview object which references the given object. +[clinic start generated code]*/ + +static PyObject * +memoryview__from_flags_impl(PyTypeObject *type, PyObject *object, int flags) +/*[clinic end generated code: output=bf71f9906c266ee2 input=f5f82fd0e744356b]*/ +{ + return PyMemoryView_FromObjectAndFlags(object, flags); +} + + /****************************************************************************/ /* Previously in abstract.c */ /****************************************************************************/ @@ -1102,8 +1166,7 @@ static PyObject * memory_enter(PyObject *self, PyObject *args) { CHECK_RELEASED(self); - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -1135,6 +1198,7 @@ get_native_fmtchar(char *result, const char *fmt) case 'n': case 'N': size = sizeof(Py_ssize_t); break; case 'f': size = sizeof(float); break; case 'd': size = sizeof(double); break; + case 'e': size = sizeof(float) / 2; break; case '?': size = sizeof(_Bool); break; case 'P': size = sizeof(void *); break; } @@ -1178,6 +1242,7 @@ get_native_fmtstr(const char *fmt) case 'N': RETURN("N"); case 'f': RETURN("f"); case 'd': RETURN("d"); + case 'e': RETURN("e"); case '?': RETURN("?"); case 'P': RETURN("P"); } @@ -1371,6 +1436,7 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, Py_ssize_t ndim = 1; CHECK_RELEASED(self); + CHECK_RESTRICTED(self); if (!MV_C_CONTIGUOUS(self->flags)) { PyErr_SetString(PyExc_TypeError, @@ -1426,6 +1492,7 @@ memoryview_toreadonly_impl(PyMemoryViewObject *self) /*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/ { CHECK_RELEASED(self); + CHECK_RESTRICTED(self); /* Even if self is already readonly, we still need to create a new * object for .release() to work correctly. */ @@ -1448,6 +1515,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) int baseflags = self->flags; CHECK_RELEASED_INT(self); + CHECK_RESTRICTED_INT(self); /* start with complete information */ *view = *base; @@ -1513,8 +1581,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) } - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); self->exports++; return 0; @@ -1697,6 +1764,12 @@ unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt) CHECK_RELEASED_AGAIN(self); +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + switch (fmt[0]) { /* signed integers and fast path for 'B' */ @@ -1725,6 +1798,7 @@ unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt) /* floats */ case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double; case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double; + case 'e': d = PyFloat_Unpack2(ptr, endian); goto convert_double; /* bytes object */ case 'c': goto convert_bytes; @@ -1786,6 +1860,11 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt double d; void *p; +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif switch (fmt[0]) { /* signed integers */ case 'b': case 'h': case 'i': case 'l': @@ -1862,7 +1941,7 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt break; /* floats */ - case 'f': case 'd': + case 'f': case 'd': case 'e': d = PyFloat_AsDouble(item); if (d == -1.0 && PyErr_Occurred()) goto err_occurred; @@ -1870,9 +1949,14 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt if (fmt[0] == 'f') { PACK_SINGLE(ptr, d, float); } - else { + else if (fmt[0] == 'd') { PACK_SINGLE(ptr, d, double); } + else { + if (PyFloat_Pack2(d, ptr, endian) < 0) { + goto err_occurred; + } + } break; /* bool */ @@ -1882,7 +1966,7 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt return -1; /* preserve original error */ CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, ld, _Bool); - break; + break; /* bytes object */ case 'c': @@ -1967,18 +2051,12 @@ unpacker_free(struct unpacker *x) static struct unpacker * struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) { - PyObject *structmodule; /* XXX cache these two */ - PyObject *Struct = NULL; /* XXX in globals? */ + PyObject *Struct = NULL; /* XXX cache it in globals? */ PyObject *structobj = NULL; PyObject *format = NULL; struct unpacker *x = NULL; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) - return NULL; - - Struct = PyObject_GetAttrString(structmodule, "Struct"); - Py_DECREF(structmodule); + Struct = _PyImport_GetModuleAttrString("struct", "Struct"); if (Struct == NULL) return NULL; @@ -2034,10 +2112,9 @@ struct_unpack_single(const char *ptr, struct unpacker *x) return NULL; if (PyTuple_GET_SIZE(v) == 1) { - PyObject *tmp = PyTuple_GET_ITEM(v, 0); - Py_INCREF(tmp); + PyObject *res = Py_NewRef(PyTuple_GET_ITEM(v, 0)); Py_DECREF(v); - return tmp; + return res; } return v; @@ -2483,8 +2560,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) return unpack_single(self, view->buf, fmt); } else if (key == Py_Ellipsis) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyErr_SetString(PyExc_TypeError, @@ -2501,6 +2577,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) return memory_item(self, index); } else if (PySlice_Check(key)) { + CHECK_RESTRICTED(self); PyMemoryViewObject *sliced; sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view); @@ -2635,7 +2712,11 @@ static Py_ssize_t memory_length(PyMemoryViewObject *self) { CHECK_RELEASED_INT(self); - return self->view.ndim == 0 ? 1 : self->view.shape[0]; + if (self->view.ndim == 0) { + PyErr_SetString(PyExc_TypeError, "0-dim memory has no length"); + return -1; + } + return self->view.shape[0]; } /* As mapping */ @@ -2754,6 +2835,17 @@ unpack_cmp(const char *p, const char *q, char fmt, /* XXX DBL_EPSILON? */ case 'f': CMP_SINGLE(p, q, float); return equal; case 'd': CMP_SINGLE(p, q, double); return equal; + case 'e': { +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + /* Note: PyFloat_Unpack2 should never fail */ + double u = PyFloat_Unpack2(p, endian); + double v = PyFloat_Unpack2(q, endian); + return (u == v); + } /* bytes object */ case 'c': return *p == *q; @@ -2933,8 +3025,7 @@ result: unpacker_free(unpack_v); unpacker_free(unpack_w); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } /**************************************************************************/ @@ -3028,8 +3119,7 @@ memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) if (view->obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(view->obj); - return view->obj; + return Py_NewRef(view->obj); } static PyObject * @@ -3164,6 +3254,7 @@ static PyMethodDef memory_methods[] = { MEMORYVIEW_TOLIST_METHODDEF MEMORYVIEW_CAST_METHODDEF MEMORYVIEW_TOREADONLY_METHODDEF + MEMORYVIEW__FROM_FLAGS_METHODDEF {"__enter__", memory_enter, METH_NOARGS, NULL}, {"__exit__", memory_exit, METH_VARARGS, NULL}, {NULL, NULL} @@ -3257,8 +3348,7 @@ memory_iter(PyObject *seq) it->it_fmt = fmt; it->it_length = memory_length(obj); it->it_index = 0; - Py_INCREF(seq); - it->it_seq = obj; + it->it_seq = (PyMemoryViewObject*)Py_NewRef(obj); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/contrib/tools/python3/src/Objects/methodobject.c b/contrib/tools/python3/src/Objects/methodobject.c index faafc8ac329..44735045163 100644 --- a/contrib/tools/python3/src/Objects/methodobject.c +++ b/contrib/tools/python3/src/Objects/methodobject.c @@ -88,8 +88,7 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c if (om == NULL) { return NULL; } - Py_INCREF(cls); - om->mm_class = cls; + om->mm_class = (PyTypeObject*)Py_NewRef(cls); op = (PyCFunctionObject *)om; } else { if (cls) { @@ -106,10 +105,8 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c op->m_weakreflist = NULL; op->m_ml = ml; - Py_XINCREF(self); - op->m_self = self; - Py_XINCREF(module); - op->m_module = module; + op->m_self = Py_XNewRef(self); + op->m_module = Py_XNewRef(module); op->vectorcall = vectorcall; _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -260,8 +257,7 @@ meth_get__self__(PyCFunctionObject *m, void *closure) self = PyCFunction_GET_SELF(m); if (self == NULL) self = Py_None; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyGetSetDef meth_getsets [] = { @@ -314,8 +310,7 @@ meth_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t diff --git a/contrib/tools/python3/src/Objects/moduleobject.c b/contrib/tools/python3/src/Objects/moduleobject.c index d18f2060f2f..4daf1a929e0 100644 --- a/contrib/tools/python3/src/Objects/moduleobject.c +++ b/contrib/tools/python3/src/Objects/moduleobject.c @@ -9,7 +9,6 @@ #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "structmember.h" // PyMemberDef -static Py_ssize_t max_module_number; static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, @@ -43,10 +42,9 @@ PyModuleDef_Init(PyModuleDef* def) { assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY); if (def->m_base.m_index == 0) { - max_module_number++; Py_SET_REFCNT(def, 1); Py_SET_TYPE(def, &PyModuleDef_Type); - def->m_base.m_index = max_module_number; + def->m_base.m_index = _PyImport_GetNextModuleIndex(); } return (PyObject*)def; } @@ -70,8 +68,7 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict, if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0) return -1; if (PyUnicode_CheckExact(name)) { - Py_INCREF(name); - Py_XSETREF(mod->md_name, name); + Py_XSETREF(mod->md_name, Py_NewRef(name)); } return 0; @@ -211,22 +208,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) "module %s: PyModule_Create is incompatible with m_slots", name); return NULL; } - /* Make sure name is fully qualified. - - This is a bit of a hack: when the shared library is loaded, - the module name is "package.module", but the module calls - PyModule_Create*() with just "module" for the name. The shared - library loader squirrels away the true name of the module in - _Py_PackageContext, and PyModule_Create*() will substitute this - (if the name actually matches). - */ - if (_Py_PackageContext != NULL) { - const char *p = strrchr(_Py_PackageContext, '.'); - if (p != NULL && strcmp(module->m_name, p+1) == 0) { - name = _Py_PackageContext; - _Py_PackageContext = NULL; - } - } + name = _PyImport_ResolveNameWithPackageContext(name); if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; @@ -263,9 +245,12 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio PyObject *(*create)(PyObject *, PyModuleDef*) = NULL; PyObject *nameobj; PyObject *m = NULL; + int has_multiple_interpreters_slot = 0; + void *multiple_interpreters = (void *)0; int has_execution_slots = 0; const char *name; int ret; + PyInterpreterState *interp = _PyInterpreterState_GET(); PyModuleDef_Init(def); @@ -291,25 +276,60 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio } for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { - if (cur_slot->slot == Py_mod_create) { - if (create) { + switch (cur_slot->slot) { + case Py_mod_create: + if (create) { + PyErr_Format( + PyExc_SystemError, + "module %s has multiple create slots", + name); + goto error; + } + create = cur_slot->value; + break; + case Py_mod_exec: + has_execution_slots = 1; + break; + case Py_mod_multiple_interpreters: + if (has_multiple_interpreters_slot) { + PyErr_Format( + PyExc_SystemError, + "module %s has more than one 'multiple interpreters' slots", + name); + goto error; + } + multiple_interpreters = cur_slot->value; + has_multiple_interpreters_slot = 1; + break; + default: + assert(cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT); PyErr_Format( PyExc_SystemError, - "module %s has multiple create slots", - name); + "module %s uses unknown slot ID %i", + name, cur_slot->slot); goto error; - } - create = cur_slot->value; - } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) { - PyErr_Format( - PyExc_SystemError, - "module %s uses unknown slot ID %i", - name, cur_slot->slot); + } + } + + /* By default, multi-phase init modules are expected + to work under multiple interpreters. */ + if (!has_multiple_interpreters_slot) { + multiple_interpreters = Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED; + } + if (multiple_interpreters == Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED) { + if (!_Py_IsMainInterpreter(interp) + && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0) + { goto error; - } else { - has_execution_slots = 1; } } + else if (multiple_interpreters != Py_MOD_PER_INTERPRETER_GIL_SUPPORTED + && interp->ceval.own_gil + && !_Py_IsMainInterpreter(interp) + && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0) + { + goto error; + } if (create) { m = create(spec, def); @@ -323,9 +343,10 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio goto error; } else { if (PyErr_Occurred()) { - PyErr_Format(PyExc_SystemError, - "creation of module %s raised unreported exception", - name); + _PyErr_FormatFromCause( + PyExc_SystemError, + "creation of module %s raised unreported exception", + name); goto error; } } @@ -427,13 +448,16 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) return -1; } if (PyErr_Occurred()) { - PyErr_Format( + _PyErr_FormatFromCause( PyExc_SystemError, "execution of module %s raised unreported exception", name); return -1; } break; + case Py_mod_multiple_interpreters: + /* handled in PyModule_FromDefAndSpec2 */ + break; default: PyErr_Format( PyExc_SystemError, @@ -502,8 +526,7 @@ PyModule_GetNameObject(PyObject *m) } return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } const char * @@ -537,8 +560,7 @@ PyModule_GetFilenameObject(PyObject *m) } return NULL; } - Py_INCREF(fileobj); - return fileobj; + return Py_NewRef(fileobj); } const char * @@ -707,8 +729,7 @@ static PyObject * module_repr(PyModuleObject *m) { PyInterpreterState *interp = _PyInterpreterState_GET(); - - return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m); + return _PyImport_ImportlibModuleRepr(interp, (PyObject *)m); } /* Check if the "_initializing" attribute of the module spec is set to true. @@ -718,7 +739,11 @@ int _PyModuleSpec_IsInitializing(PyObject *spec) { if (spec != NULL) { - PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing)); + PyObject *value; + int ok = _PyObject_LookupAttr(spec, &_Py_ID(_initializing), &value); + if (ok == 0) { + return 0; + } if (value != NULL) { int initializing = PyObject_IsTrue(value); Py_DECREF(value); @@ -754,19 +779,37 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name) return is_uninitialized; } -static PyObject* -module_getattro(PyModuleObject *m, PyObject *name) +PyObject* +_Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) { + // When suppress=1, this function suppresses AttributeError. PyObject *attr, *mod_name, *getattr; - attr = PyObject_GenericGetAttr((PyObject *)m, name); - if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) { + attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress); + if (attr) { return attr; } - PyErr_Clear(); + if (suppress == 1) { + if (PyErr_Occurred()) { + // pass up non-AttributeError exception + return NULL; + } + } + else { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + // pass up non-AttributeError exception + return NULL; + } + PyErr_Clear(); + } assert(m->md_dict != NULL); getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__)); if (getattr) { - return PyObject_CallOneArg(getattr, name); + PyObject *result = PyObject_CallOneArg(getattr, name); + if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) { + // suppress AttributeError + PyErr_Clear(); + } + return result; } if (PyErr_Occurred()) { return NULL; @@ -779,37 +822,48 @@ module_getattro(PyModuleObject *m, PyObject *name) Py_DECREF(mod_name); return NULL; } - Py_XINCREF(spec); - if (_PyModuleSpec_IsInitializing(spec)) { - PyErr_Format(PyExc_AttributeError, - "partially initialized " - "module '%U' has no attribute '%U' " - "(most likely due to a circular import)", - mod_name, name); - } - else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) { - PyErr_Format(PyExc_AttributeError, - "cannot access submodule '%U' of module '%U' " - "(most likely due to a circular import)", - name, mod_name); - } - else { - PyErr_Format(PyExc_AttributeError, - "module '%U' has no attribute '%U'", - mod_name, name); + if (suppress != 1) { + Py_XINCREF(spec); + if (_PyModuleSpec_IsInitializing(spec)) { + PyErr_Format(PyExc_AttributeError, + "partially initialized " + "module '%U' has no attribute '%U' " + "(most likely due to a circular import)", + mod_name, name); + } + else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) { + PyErr_Format(PyExc_AttributeError, + "cannot access submodule '%U' of module '%U' " + "(most likely due to a circular import)", + name, mod_name); + } + else { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", + mod_name, name); + } + Py_XDECREF(spec); } - Py_XDECREF(spec); Py_DECREF(mod_name); return NULL; } else if (PyErr_Occurred()) { return NULL; } - PyErr_Format(PyExc_AttributeError, - "module has no attribute '%U'", name); + if (suppress != 1) { + PyErr_Format(PyExc_AttributeError, + "module has no attribute '%U'", name); + } return NULL; } + +PyObject* +_Py_module_getattro(PyModuleObject *m, PyObject *name) +{ + return _Py_module_getattro_impl(m, name, 0); +} + static int module_traverse(PyModuleObject *m, visitproc visit, void *arg) { @@ -961,7 +1015,7 @@ PyTypeObject PyModule_Type = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - (getattrofunc)module_getattro, /* tp_getattro */ + (getattrofunc)_Py_module_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | diff --git a/contrib/tools/python3/src/Objects/namespaceobject.c b/contrib/tools/python3/src/Objects/namespaceobject.c index 7875e7cafec..2cc4ddd3c91 100644 --- a/contrib/tools/python3/src/Objects/namespaceobject.c +++ b/contrib/tools/python3/src/Objects/namespaceobject.c @@ -85,9 +85,8 @@ namespace_repr(PyObject *ns) if (pairs == NULL) goto error; - d = ((_PyNamespaceObject *)ns)->ns_dict; - assert(d != NULL); - Py_INCREF(d); + assert(((_PyNamespaceObject *)ns)->ns_dict != NULL); + d = Py_NewRef(((_PyNamespaceObject *)ns)->ns_dict); keys = PyDict_Keys(d); if (keys == NULL) diff --git a/contrib/tools/python3/src/Objects/object.c b/contrib/tools/python3/src/Objects/object.c index c4f2786c50a..aac707d6a26 100644 --- a/contrib/tools/python3/src/Objects/object.c +++ b/contrib/tools/python3/src/Objects/object.c @@ -14,9 +14,10 @@ #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntry_Type -#include "pycore_typeobject.h" // _PyTypes_InitSlotDefs() +#include "pycore_typevarobject.h" // _PyTypeAlias_Type, _Py_initialize_generic +#include "pycore_typeobject.h" // _PyBufferWrapper_Type #include "pycore_unionobject.h" // _PyUnion_Type -#include "pycore_interpreteridobject.h" // _PyInterpreterID_Type +#include "interpreteridobject.h" // _PyInterpreterID_Type #ifdef Py_LIMITED_API // Prevent recursive call _Py_IncRef() <=> Py_INCREF() @@ -55,19 +56,100 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) #ifdef Py_REF_DEBUG +/* We keep the legacy symbol around for backward compatibility. */ Py_ssize_t _Py_RefTotal; -Py_ssize_t -_Py_GetRefTotal(void) +static inline Py_ssize_t +get_legacy_reftotal(void) { return _Py_RefTotal; } +#endif + +#ifdef Py_REF_DEBUG + +# define REFTOTAL(interp) \ + interp->object_state.reftotal + +static inline void +reftotal_increment(PyInterpreterState *interp) +{ + REFTOTAL(interp)++; +} + +static inline void +reftotal_decrement(PyInterpreterState *interp) +{ + REFTOTAL(interp)--; +} + +static inline void +reftotal_add(PyInterpreterState *interp, Py_ssize_t n) +{ + REFTOTAL(interp) += n; +} + +static inline Py_ssize_t get_global_reftotal(_PyRuntimeState *); + +/* We preserve the number of refs leaked during runtime finalization, + so they can be reported if the runtime is initialized again. */ +// XXX We don't lose any information by dropping this, +// so we should consider doing so. +static Py_ssize_t last_final_reftotal = 0; + +void +_Py_FinalizeRefTotal(_PyRuntimeState *runtime) +{ + last_final_reftotal = get_global_reftotal(runtime); + runtime->object_state.interpreter_leaks = 0; +} + +void +_PyInterpreterState_FinalizeRefTotal(PyInterpreterState *interp) +{ + interp->runtime->object_state.interpreter_leaks += REFTOTAL(interp); + REFTOTAL(interp) = 0; +} + +static inline Py_ssize_t +get_reftotal(PyInterpreterState *interp) +{ + /* For a single interpreter, we ignore the legacy _Py_RefTotal, + since we can't determine which interpreter updated it. */ + return REFTOTAL(interp); +} + +static inline Py_ssize_t +get_global_reftotal(_PyRuntimeState *runtime) +{ + Py_ssize_t total = 0; + + /* Add up the total from each interpreter. */ + HEAD_LOCK(&_PyRuntime); + PyInterpreterState *interp = PyInterpreterState_Head(); + for (; interp != NULL; interp = PyInterpreterState_Next(interp)) { + total += REFTOTAL(interp); + } + HEAD_UNLOCK(&_PyRuntime); + + /* Add in the updated value from the legacy _Py_RefTotal. */ + total += get_legacy_reftotal(); + total += last_final_reftotal; + total += runtime->object_state.interpreter_leaks; + + return total; +} + +#undef REFTOTAL void _PyDebug_PrintTotalRefs(void) { + _PyRuntimeState *runtime = &_PyRuntime; fprintf(stderr, "[%zd refs, %zd blocks]\n", - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); + get_global_reftotal(runtime), _Py_GetGlobalAllocatedBlocks()); + /* It may be helpful to also print the "legacy" reftotal separately. + Likewise for the total for each interpreter. */ } #endif /* Py_REF_DEBUG */ @@ -76,11 +158,16 @@ _PyDebug_PrintTotalRefs(void) { Do not call them otherwise, they do not initialize the object! */ #ifdef Py_TRACE_REFS -/* Head of circular doubly-linked list of all objects. These are linked - * together via the _ob_prev and _ob_next members of a PyObject, which - * exist only in a Py_TRACE_REFS build. - */ -static PyObject refchain = {&refchain, &refchain}; + +#define REFCHAIN(interp) &interp->object_state.refchain + +static inline void +init_refchain(PyInterpreterState *interp) +{ + PyObject *refchain = REFCHAIN(interp); + refchain->_ob_prev = refchain; + refchain->_ob_next = refchain; +} /* Insert op at the front of the list of all objects. If force is true, * op is added even if _ob_prev and _ob_next are non-NULL already. If @@ -105,10 +192,11 @@ _Py_AddToAllObjects(PyObject *op, int force) } #endif if (force || op->_ob_prev == NULL) { - op->_ob_next = refchain._ob_next; - op->_ob_prev = &refchain; - refchain._ob_next->_ob_prev = op; - refchain._ob_next = op; + PyObject *refchain = REFCHAIN(_PyInterpreterState_GET()); + op->_ob_next = refchain->_ob_next; + op->_ob_prev = refchain; + refchain->_ob_next->_ob_prev = op; + refchain->_ob_next = op; } } #endif /* Py_TRACE_REFS */ @@ -122,6 +210,58 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op) filename, lineno, __func__); } +/* This is used strictly by Py_INCREF(). */ +void +_Py_INCREF_IncRefTotal(void) +{ + reftotal_increment(_PyInterpreterState_GET()); +} + +/* This is used strictly by Py_DECREF(). */ +void +_Py_DECREF_DecRefTotal(void) +{ + reftotal_decrement(_PyInterpreterState_GET()); +} + +void +_Py_IncRefTotal(PyInterpreterState *interp) +{ + reftotal_increment(interp); +} + +void +_Py_DecRefTotal(PyInterpreterState *interp) +{ + reftotal_decrement(interp); +} + +void +_Py_AddRefTotal(PyInterpreterState *interp, Py_ssize_t n) +{ + reftotal_add(interp, n); +} + +/* This includes the legacy total + and any carried over from the last runtime init/fini cycle. */ +Py_ssize_t +_Py_GetGlobalRefTotal(void) +{ + return get_global_reftotal(&_PyRuntime); +} + +Py_ssize_t +_Py_GetLegacyRefTotal(void) +{ + return get_legacy_reftotal(); +} + +Py_ssize_t +_PyInterpreterState_GetRefTotal(PyInterpreterState *interp) +{ + return get_reftotal(interp); +} + #endif /* Py_REF_DEBUG */ void @@ -148,6 +288,9 @@ _Py_DecRef(PyObject *o) Py_DECREF(o); } + +/**************************************/ + PyObject * PyObject_Init(PyObject *op, PyTypeObject *tp) { @@ -239,17 +382,12 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) /* tp_finalize resurrected it! Make it look like the original Py_DECREF * never happened. */ Py_ssize_t refcnt = Py_REFCNT(self); - _Py_NewReference(self); + _Py_NewReferenceNoTotal(self); Py_SET_REFCNT(self, refcnt); _PyObject_ASSERT(self, (!_PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self))); - /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased - _Py_RefTotal, so we need to undo that. */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif return -1; } @@ -273,11 +411,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) } else { if (Py_REFCNT(op) <= 0) { - /* XXX(twouters) cast refcount to long until %zd is - universally available */ Py_BEGIN_ALLOW_THREADS - fprintf(fp, "<refcnt %ld at %p>", - (long)Py_REFCNT(op), (void *)op); + fprintf(fp, "<refcnt %zd at %p>", Py_REFCNT(op), (void *)op); Py_END_ALLOW_THREADS } else { @@ -286,31 +421,22 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) s = PyObject_Str(op); else s = PyObject_Repr(op); - if (s == NULL) + if (s == NULL) { ret = -1; - else if (PyBytes_Check(s)) { - fwrite(PyBytes_AS_STRING(s), 1, - PyBytes_GET_SIZE(s), fp); } - else if (PyUnicode_Check(s)) { - PyObject *t; - t = PyUnicode_AsEncodedString(s, "utf-8", "backslashreplace"); + else { + assert(PyUnicode_Check(s)); + const char *t; + Py_ssize_t len; + t = PyUnicode_AsUTF8AndSize(s, &len); if (t == NULL) { ret = -1; } else { - fwrite(PyBytes_AS_STRING(t), 1, - PyBytes_GET_SIZE(t), fp); - Py_DECREF(t); + fwrite(t, 1, len, fp); } + Py_DECREF(s); } - else { - PyErr_Format(PyExc_TypeError, - "str() or repr() returned '%.100s'", - Py_TYPE(s)->tp_name); - ret = -1; - } - Py_XDECREF(s); } } if (ret == 0) { @@ -370,9 +496,7 @@ _PyObject_Dump(PyObject* op) /* first, write fields which are the least likely to crash */ fprintf(stderr, "object address : %p\n", (void *)op); - /* XXX(twouters) cast refcount to long until %zd is - universally available */ - fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); + fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op)); fflush(stderr); PyTypeObject *type = Py_TYPE(op); @@ -385,13 +509,12 @@ _PyObject_Dump(PyObject* op) fflush(stderr); PyGILState_STATE gil = PyGILState_Ensure(); - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); (void)PyObject_Print(op, stderr, 0); fflush(stderr); - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); PyGILState_Release(gil); fprintf(stderr, "\n"); @@ -470,8 +593,7 @@ PyObject_Str(PyObject *v) if (PyUnicode_READY(v) < 0) return NULL; #endif - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (Py_TYPE(v)->tp_str == NULL) return PyObject_Repr(v); @@ -547,8 +669,7 @@ PyObject_Bytes(PyObject *v) return PyBytes_FromString("<NULL>"); if (PyBytes_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); @@ -704,8 +825,7 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) Py_TYPE(w)->tp_name); return NULL; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } /* Perform a rich comparison with object result. This wraps do_richcompare() @@ -778,7 +898,7 @@ PyObject_Hash(PyObject *v) * an explicit call to PyType_Ready, we implicitly call * PyType_Ready here and then check the tp_hash slot again */ - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return -1; if (tp->tp_hash != NULL) @@ -806,13 +926,24 @@ PyObject_GetAttrString(PyObject *v, const char *name) int PyObject_HasAttrString(PyObject *v, const char *name) { - PyObject *res = PyObject_GetAttrString(v, name); - if (res != NULL) { - Py_DECREF(res); - return 1; + if (Py_TYPE(v)->tp_getattr != NULL) { + PyObject *res = (*Py_TYPE(v)->tp_getattr)(v, (char*)name); + if (res != NULL) { + Py_DECREF(res); + return 1; + } + PyErr_Clear(); + return 0; } - PyErr_Clear(); - return 0; + + PyObject *attr_name = PyUnicode_FromString(name); + if (attr_name == NULL) { + PyErr_Clear(); + return 0; + } + int ok = PyObject_HasAttr(v, attr_name); + Py_DECREF(attr_name); + return ok; } int @@ -878,25 +1009,22 @@ set_attribute_error_context(PyObject* v, PyObject* name) return 0; } // Intercept AttributeError exceptions and augment them to offer suggestions later. - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - // Check if the normalized exception is indeed an AttributeError - if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) { + PyObject *exc = PyErr_GetRaisedException(); + if (!PyErr_GivenExceptionMatches(exc, PyExc_AttributeError)) { goto restore; } - PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) exc; // Check if this exception was already augmented if (the_exc->name || the_exc->obj) { goto restore; } // Augment the exception with the name and object - if (PyObject_SetAttr(value, &_Py_ID(name), name) || - PyObject_SetAttr(value, &_Py_ID(obj), v)) { + if (PyObject_SetAttr(exc, &_Py_ID(name), name) || + PyObject_SetAttr(exc, &_Py_ID(obj), v)) { return 1; } restore: - PyErr_Restore(type, value, traceback); + PyErr_SetRaisedException(exc); return 0; } @@ -924,7 +1052,7 @@ PyObject_GetAttr(PyObject *v, PyObject *name) } else { PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); } @@ -957,7 +1085,26 @@ _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) } return 0; } - if (tp->tp_getattro != NULL) { + if (tp->tp_getattro == (getattrofunc)_Py_type_getattro) { + int supress_missing_attribute_exception = 0; + *result = _Py_type_getattro_impl((PyTypeObject*)v, name, &supress_missing_attribute_exception); + if (supress_missing_attribute_exception) { + // return 0 without having to clear the exception + return 0; + } + } + else if (tp->tp_getattro == (getattrofunc)_Py_module_getattro) { + // optimization: suppress attribute error from module getattro method + *result = _Py_module_getattro_impl((PyModuleObject*)v, name, 1); + if (*result != NULL) { + return 1; + } + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + else if (tp->tp_getattro != NULL) { *result = (*tp->tp_getattro)(v, name); } else if (tp->tp_getattr != NULL) { @@ -1059,18 +1206,19 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) } PyObject ** -_PyObject_DictPointer(PyObject *obj) +_PyObject_ComputedDictPointer(PyObject *obj) { - Py_ssize_t dictoffset; PyTypeObject *tp = Py_TYPE(obj); + assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); - if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - return _PyObject_ManagedDictPointer(obj); - } - dictoffset = tp->tp_dictoffset; - if (dictoffset == 0) + Py_ssize_t dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) { return NULL; + } + if (dictoffset < 0) { + assert(dictoffset != -1); + Py_ssize_t tsize = Py_SIZE(obj); if (tsize < 0) { tsize = -tsize; @@ -1096,29 +1244,24 @@ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return _PyObject_DictPointer(obj); + return _PyObject_ComputedDictPointer(obj); } - PyObject **dict_ptr = _PyObject_ManagedDictPointer(obj); - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (*values_ptr == NULL) { - return dict_ptr; - } - assert(*dict_ptr == NULL); - PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - PyErr_Clear(); - return NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr)); + if (dict == NULL) { + PyErr_Clear(); + return NULL; + } + dorv_ptr->dict = dict; } - *values_ptr = NULL; - *dict_ptr = dict; - return dict_ptr; + return &dorv_ptr->dict; } PyObject * PyObject_SelfIter(PyObject *obj) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* Helper used when the __next__ method is removed from a type: @@ -1180,36 +1323,46 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } } - PyDictValues *values; - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - (values = *_PyObject_ValuesPointer(obj))) - { - assert(*_PyObject_DictPointer(obj) == NULL); - PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); - if (attr != NULL) { - *method = attr; - Py_XDECREF(descr); - return 0; - } - } - else { - PyObject **dictptr = _PyObject_DictPointer(obj); - PyObject *dict; - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - PyObject *attr = PyDict_GetItemWithError(dict, name); + PyObject *dict; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); if (attr != NULL) { - *method = Py_NewRef(attr); - Py_DECREF(dict); + *method = attr; Py_XDECREF(descr); return 0; } + dict = NULL; + } + else { + dict = dorv_ptr->dict; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr != NULL) { + dict = *dictptr; + } + else { + dict = NULL; + } + } + if (dict != NULL) { + Py_INCREF(dict); + PyObject *attr = PyDict_GetItemWithError(dict, name); + if (attr != NULL) { + *method = Py_NewRef(attr); Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + Py_DECREF(dict); - if (PyErr_Occurred()) { - Py_XDECREF(descr); - return 0; - } + if (PyErr_Occurred()) { + Py_XDECREF(descr); + return 0; } } @@ -1230,7 +1383,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); set_attribute_error_context(obj, name); @@ -1253,7 +1406,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *descr = NULL; PyObject *res = NULL; descrgetfunc f; - PyObject **dictptr; if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, @@ -1263,7 +1415,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } Py_INCREF(name); - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) goto done; } @@ -1284,30 +1436,31 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj)) - { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (PyUnicode_CheckExact(name)) { - assert(*_PyObject_DictPointer(obj) == NULL); - res = _PyObject_GetInstanceAttribute(obj, *values_ptr, name); - if (res != NULL) { - goto done; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + if (PyUnicode_CheckExact(name)) { + res = _PyObject_GetInstanceAttribute(obj, values, name); + if (res != NULL) { + goto done; + } + } + else { + dict = _PyObject_MakeDictFromInstanceAttributes(obj, values); + if (dict == NULL) { + res = NULL; + goto done; + } + dorv_ptr->dict = dict; } } else { - dictptr = _PyObject_DictPointer(obj); - assert(dictptr != NULL && *dictptr == NULL); - *dictptr = dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - res = NULL; - goto done; - } - *values_ptr = NULL; + dict = _PyDictOrValues_GetDict(*dorv_ptr); } } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr) { dict = *dictptr; } @@ -1351,7 +1504,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, if (!suppress) { PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); set_attribute_error_context(obj, name); @@ -1384,8 +1537,9 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, return -1; } - if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + if (!_PyType_IsReady(tp) && PyType_Ready(tp) < 0) { return -1; + } Py_INCREF(name); Py_INCREF(tp); @@ -1401,27 +1555,34 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && *_PyObject_ValuesPointer(obj)) { - res = _PyObject_StoreInstanceAttribute(obj, *_PyObject_ValuesPointer(obj), name, value); + PyObject **dictptr; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + res = _PyObject_StoreInstanceAttribute( + obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); + goto error_check; + } + dictptr = &dorv_ptr->dict; } else { - PyObject **dictptr = _PyObject_DictPointer(obj); - if (dictptr == NULL) { - if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); - } - else { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); - } - goto done; + dictptr = _PyObject_ComputedDictPointer(obj); + } + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); } else { - res = _PyObjectDict_SetItem(tp, dictptr, name, value); + PyErr_Format(PyExc_AttributeError, + "'%.100s' object attribute '%U' is read-only", + tp->tp_name, name); } + goto done; + } + else { + res = _PyObjectDict_SetItem(tp, dictptr, name, value); } } else { @@ -1432,6 +1593,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); } + error_check: if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { if (PyType_IsSubtype(tp, &PyType_Type)) { PyErr_Format(PyExc_AttributeError, @@ -1463,7 +1625,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj) != NULL) + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj))) { /* Was unable to convert to dict */ PyErr_NoMemory(); @@ -1484,8 +1646,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_INCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_NewRef(value)); return 0; } @@ -1549,13 +1710,15 @@ _dir_locals(void) PyObject *names; PyObject *locals; - locals = PyEval_GetLocals(); + locals = _PyEval_GetFrameLocals(); if (locals == NULL) return NULL; names = PyMapping_Keys(locals); - if (!names) + Py_DECREF(locals); + if (!names) { return NULL; + } if (!PyList_Check(names)) { PyErr_Format(PyExc_TypeError, "dir(): expected keys() of locals to be a list, " @@ -1567,7 +1730,6 @@ _dir_locals(void) Py_DECREF(names); return NULL; } - /* the locals don't need to be DECREF'd */ return names; } @@ -1624,10 +1786,14 @@ none_repr(PyObject *op) return PyUnicode_FromString("None"); } -static void _Py_NO_RETURN -none_dealloc(PyObject* Py_UNUSED(ignore)) +static void +none_dealloc(PyObject* none) { - _Py_FatalRefcountError("deallocating None"); + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref None out of existence. Instead, + * since None is an immortal object, re-set the reference count. + */ + _Py_SetImmortal(none); } static PyObject * @@ -1646,6 +1812,11 @@ none_bool(PyObject *v) return 0; } +static Py_hash_t none_hash(PyObject *v) +{ + return 0xFCA86420; +} + static PyNumberMethods none_as_number = { 0, /* nb_add */ 0, /* nb_subtract */ @@ -1688,7 +1859,7 @@ PyTypeObject _PyNone_Type = { "NoneType", 0, 0, - none_dealloc, /*tp_dealloc*/ /*never called*/ + none_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -1697,7 +1868,7 @@ PyTypeObject _PyNone_Type = { &none_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + (hashfunc)none_hash,/*tp_hash */ 0, /*tp_call */ 0, /*tp_str */ 0, /*tp_getattro */ @@ -1707,7 +1878,7 @@ PyTypeObject _PyNone_Type = { 0, /*tp_doc */ 0, /*tp_traverse */ 0, /*tp_clear */ - 0, /*tp_richcompare */ + _Py_BaseObject_RichCompare, /*tp_richcompare */ 0, /*tp_weaklistoffset */ 0, /*tp_iter */ 0, /*tp_iternext */ @@ -1725,8 +1896,9 @@ PyTypeObject _PyNone_Type = { }; PyObject _Py_NoneStruct = { - _PyObject_EXTRA_INIT - 1, &_PyNone_Type + _PyObject_EXTRA_INIT + { _Py_IMMORTAL_REFCNT }, + &_PyNone_Type }; /* NotImplemented is an object that can be used to signal that an @@ -1759,13 +1931,14 @@ notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) Py_RETURN_NOTIMPLEMENTED; } -static void _Py_NO_RETURN -notimplemented_dealloc(PyObject* ignore) +static void +notimplemented_dealloc(PyObject *notimplemented) { /* This should never get called, but we also don't want to SEGV if - * we accidentally decref NotImplemented out of existence. + * we accidentally decref NotImplemented out of existence. Instead, + * since Notimplemented is an immortal object, re-set the reference count. */ - Py_FatalError("deallocating NotImplemented"); + _Py_SetImmortal(notimplemented); } static int @@ -1827,31 +2000,27 @@ PyTypeObject _PyNotImplemented_Type = { PyObject _Py_NotImplementedStruct = { _PyObject_EXTRA_INIT - 1, &_PyNotImplemented_Type + { _Py_IMMORTAL_REFCNT }, + &_PyNotImplemented_Type }; -PyStatus -_PyTypes_InitState(PyInterpreterState *interp) + +void +_PyObject_InitState(PyInterpreterState *interp) { +#ifdef Py_TRACE_REFS if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - PyStatus status = _PyTypes_InitSlotDefs(); - if (_PyStatus_EXCEPTION(status)) { - return status; + init_refchain(interp); } - - return _PyStatus_OK(); +#endif } - -#ifdef MS_WINDOWS -extern PyTypeObject PyHKEY_Type; -#endif extern PyTypeObject _Py_GenericAliasIterType; extern PyTypeObject _PyMemoryIter_Type; +extern PyTypeObject _PyLineIterator; +extern PyTypeObject _PyPositionsIterator; +extern PyTypeObject _PyLegacyEventHandler_Type; static PyTypeObject* static_types[] = { // The two most important base types: must be initialized first and @@ -1897,9 +2066,6 @@ static PyTypeObject* static_types[] = { &PyFunction_Type, &PyGen_Type, &PyGetSetDescr_Type, -#ifdef MS_WINDOWS - &PyHKEY_Type, -#endif &PyInstanceMethod_Type, &PyListIter_Type, &PyListRevIter_Type, @@ -1939,6 +2105,7 @@ static PyTypeObject* static_types[] = { &_PyAsyncGenASend_Type, &_PyAsyncGenAThrow_Type, &_PyAsyncGenWrappedValue_Type, + &_PyBufferWrapper_Type, &_PyContextTokenMissing_Type, &_PyCoroWrapper_Type, &_Py_GenericAliasIterType, @@ -1949,18 +2116,22 @@ static PyTypeObject* static_types[] = { &_PyHamt_BitmapNode_Type, &_PyHamt_CollisionNode_Type, &_PyHamt_Type, + &_PyLegacyEventHandler_Type, &_PyInterpreterID_Type, + &_PyLineIterator, &_PyManagedBuffer_Type, &_PyMemoryIter_Type, &_PyMethodWrapper_Type, &_PyNamespace_Type, &_PyNone_Type, &_PyNotImplemented_Type, + &_PyPositionsIterator, &_PyUnicodeASCIIIter_Type, &_PyUnion_Type, &_PyWeakref_CallableProxyType, &_PyWeakref_ProxyType, &_PyWeakref_RefType, + &_PyTypeAlias_Type, // subclasses: _PyTypes_FiniTypes() deallocates them before their base // class @@ -1976,15 +2147,11 @@ static PyTypeObject* static_types[] = { PyStatus _PyTypes_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; - if (PyType_Ready(type) < 0) { - return _PyStatus_ERR("Can't initialize types"); + if (_PyStaticType_InitBuiltin(interp, type) < 0) { + return _PyStatus_ERR("Can't initialize builtin type"); } if (type == &PyType_Type) { // Sanitify checks of the two most important types @@ -1993,6 +2160,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp) } } + // Must be after static types are initialized + if (_Py_initialize_generic(interp) < 0) { + return _PyStatus_ERR("Can't initialize generic types"); + } + return _PyStatus_OK(); } @@ -2006,34 +2178,43 @@ _PyTypes_InitTypes(PyInterpreterState *interp) void _PyTypes_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - // Deallocate types in the reverse order to deallocate subclasses before // their base classes. for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { PyTypeObject *type = static_types[i]; - _PyStaticType_Dealloc(type); + _PyStaticType_Dealloc(interp, type); } } -void -_Py_NewReference(PyObject *op) +static inline void +new_reference(PyObject *op) { - if (_Py_tracemalloc_config.tracing) { + if (_PyRuntime.tracemalloc.config.tracing) { _PyTraceMalloc_NewReference(op); } -#ifdef Py_REF_DEBUG - _Py_RefTotal++; -#endif - Py_SET_REFCNT(op, 1); + // Skip the immortal object check in Py_SET_REFCNT; always set refcnt to 1 + op->ob_refcnt = 1; #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op, 1); #endif } +void +_Py_NewReference(PyObject *op) +{ +#ifdef Py_REF_DEBUG + reftotal_increment(_PyInterpreterState_GET()); +#endif + new_reference(op); +} + +void +_Py_NewReferenceNoTotal(PyObject *op) +{ + new_reference(op); +} + #ifdef Py_TRACE_REFS void @@ -2043,7 +2224,8 @@ _Py_ForgetReference(PyObject *op) _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); } - if (op == &refchain || + PyObject *refchain = REFCHAIN(_PyInterpreterState_GET()); + if (op == refchain || op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) { _PyObject_ASSERT_FAILED_MSG(op, "invalid object chain"); @@ -2051,12 +2233,12 @@ _Py_ForgetReference(PyObject *op) #ifdef SLOW_UNREF_CHECK PyObject *p; - for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { + for (p = refchain->_ob_next; p != refchain; p = p->_ob_next) { if (p == op) { break; } } - if (p == &refchain) { + if (p == refchain) { /* Not found */ _PyObject_ASSERT_FAILED_MSG(op, "object not found in the objects list"); @@ -2072,11 +2254,15 @@ _Py_ForgetReference(PyObject *op) * interpreter must be in a healthy state. */ void -_Py_PrintReferences(FILE *fp) +_Py_PrintReferences(PyInterpreterState *interp, FILE *fp) { PyObject *op; + if (interp == NULL) { + interp = _PyInterpreterState_Main(); + } fprintf(fp, "Remaining objects:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { + PyObject *refchain = REFCHAIN(interp); + for (op = refchain->_ob_next; op != refchain; op = op->_ob_next) { fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op)); if (PyObject_Print(op, fp, 0) != 0) { PyErr_Clear(); @@ -2088,34 +2274,42 @@ _Py_PrintReferences(FILE *fp) /* Print the addresses of all live objects. Unlike _Py_PrintReferences, this * doesn't make any calls to the Python C API, so is always safe to call. */ +// XXX This function is not safe to use if the interpreter has been +// freed or is in an unhealthy state (e.g. late in finalization). +// The call in Py_FinalizeEx() is okay since the main interpreter +// is statically allocated. void -_Py_PrintReferenceAddresses(FILE *fp) +_Py_PrintReferenceAddresses(PyInterpreterState *interp, FILE *fp) { PyObject *op; + PyObject *refchain = REFCHAIN(interp); fprintf(fp, "Remaining object addresses:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) + for (op = refchain->_ob_next; op != refchain; op = op->_ob_next) fprintf(fp, "%p [%zd] %s\n", (void *)op, Py_REFCNT(op), Py_TYPE(op)->tp_name); } +/* The implementation of sys.getobjects(). */ PyObject * _Py_GetObjects(PyObject *self, PyObject *args) { int i, n; PyObject *t = NULL; PyObject *res, *op; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (!PyArg_ParseTuple(args, "i|O", &n, &t)) return NULL; - op = refchain._ob_next; + PyObject *refchain = REFCHAIN(interp); + op = refchain->_ob_next; res = PyList_New(0); if (res == NULL) return NULL; - for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { + for (i = 0; (n == 0 || i < n) && op != refchain; i++) { while (op == self || op == args || op == res || op == t || (t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) { op = op->_ob_next; - if (op == &refchain) + if (op == refchain) return res; } if (PyList_Append(res, op) < 0) { @@ -2127,7 +2321,9 @@ _Py_GetObjects(PyObject *self, PyObject *args) return res; } -#endif +#undef REFCHAIN + +#endif /* Py_TRACE_REFS */ /* Hack to force loading of abstract.o */ @@ -2195,9 +2391,8 @@ Py_ReprLeave(PyObject *obj) PyObject *dict; PyObject *list; Py_ssize_t i; - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); dict = PyThreadState_GetDict(); if (dict == NULL) @@ -2218,7 +2413,7 @@ Py_ReprLeave(PyObject *obj) finally: /* ignore exceptions because there is no way to report them. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } /* Trashcan support. */ @@ -2230,22 +2425,20 @@ finally: * object, with refcount 0. Py_DECREF must already have been called on it. */ static void -_PyTrash_thread_deposit_object(PyObject *op) +_PyTrash_thread_deposit_object(struct _py_trashcan *trash, PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); _PyObject_ASSERT(op, _PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); _PyObject_ASSERT(op, Py_REFCNT(op) == 0); - _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); - tstate->trash_delete_later = op; + _PyGCHead_SET_PREV(_Py_AS_GC(op), (PyGC_Head*)trash->delete_later); + trash->delete_later = op; } /* Deallocate all the objects in the gcstate->trash_delete_later list. * Called when the call-stack unwinds again. */ static void -_PyTrash_thread_destroy_chain(void) +_PyTrash_thread_destroy_chain(struct _py_trashcan *trash) { - PyThreadState *tstate = _PyThreadState_GET(); /* We need to increase trash_delete_nesting here, otherwise, _PyTrash_thread_destroy_chain will be called recursively and then possibly crash. An example that may crash without @@ -2257,13 +2450,13 @@ _PyTrash_thread_destroy_chain(void) tups = [(tup,) for tup in tups] del tups */ - assert(tstate->trash_delete_nesting == 0); - ++tstate->trash_delete_nesting; - while (tstate->trash_delete_later) { - PyObject *op = tstate->trash_delete_later; + assert(trash->delete_nesting == 0); + ++trash->delete_nesting; + while (trash->delete_later) { + PyObject *op = trash->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; - tstate->trash_delete_later = + trash->delete_later = (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); /* Call the deallocator directly. This used to try to @@ -2274,22 +2467,64 @@ _PyTrash_thread_destroy_chain(void) */ _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); - assert(tstate->trash_delete_nesting == 1); + assert(trash->delete_nesting == 1); + } + --trash->delete_nesting; +} + + +static struct _py_trashcan * +_PyTrash_get_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + return &tstate->trash; + } + // The current thread must be finalizing. + // Fall back to using thread-local state. + // XXX Use thread-local variable syntax? + assert(PyThread_tss_is_created(&_PyRuntime.trashTSSkey)); + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash == NULL) { + trash = PyMem_RawMalloc(sizeof(struct _py_trashcan)); + if (trash == NULL) { + Py_FatalError("Out of memory"); + } + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)trash); + } + return trash; +} + +static void +_PyTrash_clear_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + assert(tstate->trash.delete_later == NULL); + return; + } + if (PyThread_tss_is_created(&_PyRuntime.trashTSSkey)) { + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash != NULL) { + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)NULL); + PyMem_RawFree(trash); + } } - --tstate->trash_delete_nesting; } int _PyTrash_begin(PyThreadState *tstate, PyObject *op) { - if (tstate->trash_delete_nesting >= _PyTrash_UNWIND_LEVEL) { + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + if (trash->delete_nesting >= _PyTrash_UNWIND_LEVEL) { /* Store the object (to be deallocated later) and jump past * Py_TRASHCAN_END, skipping the body of the deallocator */ - _PyTrash_thread_deposit_object(op); + _PyTrash_thread_deposit_object(trash, op); return 1; } - ++tstate->trash_delete_nesting; + ++trash->delete_nesting; return 0; } @@ -2297,9 +2532,14 @@ _PyTrash_begin(PyThreadState *tstate, PyObject *op) void _PyTrash_end(PyThreadState *tstate) { - --tstate->trash_delete_nesting; - if (tstate->trash_delete_later && tstate->trash_delete_nesting <= 0) { - _PyTrash_thread_destroy_chain(); + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + --trash->delete_nesting; + if (trash->delete_nesting <= 0) { + if (trash->delete_later != NULL) { + _PyTrash_thread_destroy_chain(trash); + } + _PyTrash_clear_state(tstate); } } @@ -2347,14 +2587,9 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, /* Display the traceback where the object has been allocated. Do it before dumping repr(obj), since repr() is more likely to crash than dumping the traceback. */ - void *ptr; PyTypeObject *type = Py_TYPE(obj); - if (_PyType_IS_GC(type)) { - ptr = (void *)((char *)obj - sizeof(PyGC_Head)); - } - else { - ptr = (void *)obj; - } + const size_t presize = _PyType_PreHeaderSize(type); + void *ptr = (void *)((char *)obj - presize); _PyMem_DumpTraceback(fileno(stderr), ptr); /* This might succeed or fail, but we're about to abort, so at least @@ -2376,10 +2611,10 @@ _Py_Dealloc(PyObject *op) destructor dealloc = type->tp_dealloc; #ifdef Py_DEBUG PyThreadState *tstate = _PyThreadState_GET(); - PyObject *old_exc_type = tstate->curexc_type; + PyObject *old_exc = tstate != NULL ? tstate->current_exception : NULL; // Keep the old exception type alive to prevent undefined behavior // on (tstate->curexc_type != old_exc_type) below - Py_XINCREF(old_exc_type); + Py_XINCREF(old_exc); // Make sure that type->tp_name remains valid Py_INCREF(type); #endif @@ -2392,12 +2627,12 @@ _Py_Dealloc(PyObject *op) #ifdef Py_DEBUG // gh-89373: The tp_dealloc function must leave the current exception // unchanged. - if (tstate->curexc_type != old_exc_type) { + if (tstate != NULL && tstate->current_exception != old_exc) { const char *err; - if (old_exc_type == NULL) { + if (old_exc == NULL) { err = "Deallocator of type '%s' raised an exception"; } - else if (tstate->curexc_type == NULL) { + else if (tstate->current_exception == NULL) { err = "Deallocator of type '%s' cleared the current exception"; } else { @@ -2408,7 +2643,7 @@ _Py_Dealloc(PyObject *op) } _Py_FatalErrorFormat(__func__, err, type->tp_name); } - Py_XDECREF(old_exc_type); + Py_XDECREF(old_exc); Py_DECREF(type); #endif } diff --git a/contrib/tools/python3/src/Objects/obmalloc.c b/contrib/tools/python3/src/Objects/obmalloc.c index b9529e418d4..9620a8fbb44 100644 --- a/contrib/tools/python3/src/Objects/obmalloc.c +++ b/contrib/tools/python3/src/Objects/obmalloc.c @@ -1,96 +1,40 @@ -#include "Python.h" -#include "pycore_pymem.h" // _PyTraceMalloc_Config -#include "pycore_code.h" // stats - -#include <stdbool.h> -#include <stdlib.h> // malloc() - +/* Python's malloc wrappers (see pymem.h) */ -/* Defined in tracemalloc.c */ -extern void _PyMem_DumpTraceback(int fd, const void *ptr); +#include "Python.h" +#include "pycore_code.h" // stats +#include "pycore_pystate.h" // _PyInterpreterState_GET +#include "pycore_obmalloc.h" +#include "pycore_pymem.h" -/* Python's malloc wrappers (see pymem.h) */ +#include <stdlib.h> // malloc() +#include <stdbool.h> #undef uint -#define uint unsigned int /* assuming >= 16 bits */ +#define uint pymem_uint -/* Forward declaration */ -static void* _PyMem_DebugRawMalloc(void *ctx, size_t size); -static void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugRawFree(void *ctx, void *ptr); -static void* _PyMem_DebugMalloc(void *ctx, size_t size); -static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugFree(void *ctx, void *p); +/* Defined in tracemalloc.c */ +extern void _PyMem_DumpTraceback(int fd, const void *ptr); static void _PyObject_DebugDumpAddress(const void *p); static void _PyMem_DebugCheckAddress(const char *func, char api_id, const void *p); -static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); -#if defined(__has_feature) /* Clang */ -# if __has_feature(address_sanitizer) /* is ASAN enabled? */ -# define _Py_NO_SANITIZE_ADDRESS \ - __attribute__((no_sanitize("address"))) -# endif -# if __has_feature(thread_sanitizer) /* is TSAN enabled? */ -# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -# endif -# if __has_feature(memory_sanitizer) /* is MSAN enabled? */ -# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */ -# define _Py_NO_SANITIZE_ADDRESS \ - __attribute__((no_sanitize_address)) -# endif - // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro - // is provided only since GCC 7. -# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) -# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -# endif -#endif +static void set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain); +static void set_up_debug_hooks_unlocked(void); +static void get_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *); +static void set_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *); -#ifndef _Py_NO_SANITIZE_ADDRESS -# define _Py_NO_SANITIZE_ADDRESS -#endif -#ifndef _Py_NO_SANITIZE_THREAD -# define _Py_NO_SANITIZE_THREAD -#endif -#ifndef _Py_NO_SANITIZE_MEMORY -# define _Py_NO_SANITIZE_MEMORY -#endif -#ifdef WITH_PYMALLOC - -#ifdef MS_WINDOWS -# include <windows.h> -#elif defined(HAVE_MMAP) -# include <sys/mman.h> -# ifdef MAP_ANONYMOUS -# define ARENAS_USE_MMAP -# endif -#endif - -/* Forward declaration */ -static void* _PyObject_Malloc(void *ctx, size_t size); -static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); -static void _PyObject_Free(void *ctx, void *p); -static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); -#endif +/***************************************/ +/* low-level allocator implementations */ +/***************************************/ +/* the default raw allocator (wraps malloc) */ -/* bpo-35053: Declare tracemalloc configuration here rather than - Modules/_tracemalloc.c because _tracemalloc can be compiled as dynamic - library, whereas _Py_NewReference() requires it. */ -struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT; - - -static void * -_PyMem_RawMalloc(void *ctx, size_t size) +void * +_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size) { /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL for malloc(0), which would be treated as an error. Some platforms would @@ -101,8 +45,8 @@ _PyMem_RawMalloc(void *ctx, size_t size) return malloc(size); } -static void * -_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) +void * +_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize) { /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL for calloc(0, 0), which would be treated as an error. Some platforms @@ -115,39 +59,81 @@ _PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) return calloc(nelem, elsize); } -static void * -_PyMem_RawRealloc(void *ctx, void *ptr, size_t size) +void * +_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size) { if (size == 0) size = 1; return realloc(ptr, size); } -static void -_PyMem_RawFree(void *ctx, void *ptr) +void +_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr) { free(ptr); } +#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} +#define PYRAW_ALLOC MALLOC_ALLOC -#ifdef MS_WINDOWS -static void * -_PyObject_ArenaVirtualAlloc(void *ctx, size_t size) +/* the default object allocator */ + +// The actual implementation is further down. + +#ifdef WITH_PYMALLOC +void* _PyObject_Malloc(void *ctx, size_t size); +void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); +void _PyObject_Free(void *ctx, void *p); +void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); +# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +# define PYOBJ_ALLOC PYMALLOC_ALLOC +#else +# define PYOBJ_ALLOC MALLOC_ALLOC +#endif // WITH_PYMALLOC + +#define PYMEM_ALLOC PYOBJ_ALLOC + +/* the default debug allocators */ + +// The actual implementation is further down. + +void* _PyMem_DebugRawMalloc(void *ctx, size_t size); +void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugRawFree(void *ctx, void *ptr); + +void* _PyMem_DebugMalloc(void *ctx, size_t size); +void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugFree(void *ctx, void *p); + +#define PYDBGRAW_ALLOC \ + {&_PyRuntime.allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC \ + {&_PyRuntime.allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC \ + {&_PyRuntime.allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +/* the low-level virtual memory allocator */ + +#ifdef WITH_PYMALLOC +# ifdef MS_WINDOWS +# include <windows.h> +# elif defined(HAVE_MMAP) +# include <sys/mman.h> +# ifdef MAP_ANONYMOUS +# define ARENAS_USE_MMAP +# endif +# endif +#endif + +void * +_PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size) { +#ifdef MS_WINDOWS return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -} - -static void -_PyObject_ArenaVirtualFree(void *ctx, void *ptr, size_t size) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - #elif defined(ARENAS_USE_MMAP) -static void * -_PyObject_ArenaMmap(void *ctx, size_t size) -{ void *ptr; ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); @@ -155,80 +141,86 @@ _PyObject_ArenaMmap(void *ctx, size_t size) return NULL; assert(ptr != NULL); return ptr; -} - -static void -_PyObject_ArenaMunmap(void *ctx, void *ptr, size_t size) -{ - munmap(ptr, size); -} - #else -static void * -_PyObject_ArenaMalloc(void *ctx, size_t size) -{ return malloc(size); +#endif } -static void -_PyObject_ArenaFree(void *ctx, void *ptr, size_t size) +void +_PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr, +#if defined(ARENAS_USE_MMAP) + size_t size +#else + size_t Py_UNUSED(size) +#endif +) { +#ifdef MS_WINDOWS + VirtualFree(ptr, 0, MEM_RELEASE); +#elif defined(ARENAS_USE_MMAP) + munmap(ptr, size); +#else free(ptr); -} #endif +} -#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} -#ifdef WITH_PYMALLOC -# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +/*******************************************/ +/* end low-level allocator implementations */ +/*******************************************/ + + +#if defined(__has_feature) /* Clang */ +# if __has_feature(address_sanitizer) /* is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize("address"))) +# endif +# if __has_feature(thread_sanitizer) /* is TSAN enabled? */ +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif +# if __has_feature(memory_sanitizer) /* is MSAN enabled? */ +# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +# endif +#elif defined(__GNUC__) +# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize_address)) +# endif + // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro + // is provided only since GCC 7. +# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif #endif -#define PYRAW_ALLOC MALLOC_ALLOC -#ifdef WITH_PYMALLOC -# define PYOBJ_ALLOC PYMALLOC_ALLOC -#else -# define PYOBJ_ALLOC MALLOC_ALLOC +#ifndef _Py_NO_SANITIZE_ADDRESS +# define _Py_NO_SANITIZE_ADDRESS +#endif +#ifndef _Py_NO_SANITIZE_THREAD +# define _Py_NO_SANITIZE_THREAD +#endif +#ifndef _Py_NO_SANITIZE_MEMORY +# define _Py_NO_SANITIZE_MEMORY #endif -#define PYMEM_ALLOC PYOBJ_ALLOC -typedef struct { - /* We tag each block with an API ID in order to tag API violations */ - char api_id; - PyMemAllocatorEx alloc; -} debug_alloc_api_t; -static struct { - debug_alloc_api_t raw; - debug_alloc_api_t mem; - debug_alloc_api_t obj; -} _PyMem_Debug = { - {'r', PYRAW_ALLOC}, - {'m', PYMEM_ALLOC}, - {'o', PYOBJ_ALLOC} - }; -#define PYDBGRAW_ALLOC \ - {&_PyMem_Debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} -#define PYDBGMEM_ALLOC \ - {&_PyMem_Debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} -#define PYDBGOBJ_ALLOC \ - {&_PyMem_Debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define ALLOCATORS_MUTEX (_PyRuntime.allocators.mutex) +#define _PyMem_Raw (_PyRuntime.allocators.standard.raw) +#define _PyMem (_PyRuntime.allocators.standard.mem) +#define _PyObject (_PyRuntime.allocators.standard.obj) +#define _PyMem_Debug (_PyRuntime.allocators.debug) +#define _PyObject_Arena (_PyRuntime.allocators.obj_arena) -#ifdef Py_DEBUG -static PyMemAllocatorEx _PyMem_Raw = PYDBGRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYDBGMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYDBGOBJ_ALLOC; -#else -static PyMemAllocatorEx _PyMem_Raw = PYRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYOBJ_ALLOC; -#endif +/***************************/ +/* managing the allocators */ +/***************************/ static int -pymem_set_default_allocator(PyMemAllocatorDomain domain, int debug, - PyMemAllocatorEx *old_alloc) +set_default_allocator_unlocked(PyMemAllocatorDomain domain, int debug, + PyMemAllocatorEx *old_alloc) { if (old_alloc != NULL) { - PyMem_GetAllocator(domain, old_alloc); + get_allocator_unlocked(domain, old_alloc); } @@ -248,24 +240,32 @@ pymem_set_default_allocator(PyMemAllocatorDomain domain, int debug, /* unknown domain */ return -1; } - PyMem_SetAllocator(domain, &new_alloc); + set_allocator_unlocked(domain, &new_alloc); if (debug) { - _PyMem_SetupDebugHooksDomain(domain); + set_up_debug_hooks_domain_unlocked(domain); } return 0; } +#ifdef Py_DEBUG +static const int pydebug = 1; +#else +static const int pydebug = 0; +#endif + int _PyMem_SetDefaultAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc) { -#ifdef Py_DEBUG - const int debug = 1; -#else - const int debug = 0; -#endif - return pymem_set_default_allocator(domain, debug, old_alloc); + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must be initializing. */ + return set_default_allocator_unlocked(domain, pydebug, old_alloc); + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + int res = set_default_allocator_unlocked(domain, pydebug, old_alloc); + PyThread_release_lock(ALLOCATORS_MUTEX); + return res; } @@ -305,8 +305,8 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator) } -int -_PyMem_SetupAllocators(PyMemAllocatorName allocator) +static int +set_up_allocators_unlocked(PyMemAllocatorName allocator) { switch (allocator) { case PYMEM_ALLOCATOR_NOT_SET: @@ -314,15 +314,15 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) break; case PYMEM_ALLOCATOR_DEFAULT: - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, NULL); - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_MEM, NULL); - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_OBJ, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, pydebug, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, pydebug, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, pydebug, NULL); break; case PYMEM_ALLOCATOR_DEBUG: - (void)pymem_set_default_allocator(PYMEM_DOMAIN_RAW, 1, NULL); - (void)pymem_set_default_allocator(PYMEM_DOMAIN_MEM, 1, NULL); - (void)pymem_set_default_allocator(PYMEM_DOMAIN_OBJ, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, 1, NULL); break; #ifdef WITH_PYMALLOC @@ -330,14 +330,14 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) case PYMEM_ALLOCATOR_PYMALLOC_DEBUG: { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &pymalloc); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &pymalloc); + set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc); + set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &pymalloc); if (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG) { - PyMem_SetupDebugHooks(); + set_up_debug_hooks_unlocked(); } break; } @@ -347,12 +347,12 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) case PYMEM_ALLOCATOR_MALLOC_DEBUG: { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &malloc_alloc); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_MEM, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &malloc_alloc); if (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG) { - PyMem_SetupDebugHooks(); + set_up_debug_hooks_unlocked(); } break; } @@ -361,9 +361,19 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) /* unknown allocator */ return -1; } + return 0; } +int +_PyMem_SetupAllocators(PyMemAllocatorName allocator) +{ + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + int res = set_up_allocators_unlocked(allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); + return res; +} + static int pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b) @@ -372,8 +382,8 @@ pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b) } -const char* -_PyMem_GetCurrentAllocatorName(void) +static const char* +get_current_allocator_name_unlocked(void) { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; #ifdef WITH_PYMALLOC @@ -422,26 +432,15 @@ _PyMem_GetCurrentAllocatorName(void) return NULL; } +const char* +_PyMem_GetCurrentAllocatorName(void) +{ + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + const char *name = get_current_allocator_name_unlocked(); + PyThread_release_lock(ALLOCATORS_MUTEX); + return name; +} -#undef MALLOC_ALLOC -#undef PYMALLOC_ALLOC -#undef PYRAW_ALLOC -#undef PYMEM_ALLOC -#undef PYOBJ_ALLOC -#undef PYDBGRAW_ALLOC -#undef PYDBGMEM_ALLOC -#undef PYDBGOBJ_ALLOC - - -static PyObjectArenaAllocator _PyObject_Arena = {NULL, -#ifdef MS_WINDOWS - _PyObject_ArenaVirtualAlloc, _PyObject_ArenaVirtualFree -#elif defined(ARENAS_USE_MMAP) - _PyObject_ArenaMmap, _PyObject_ArenaMunmap -#else - _PyObject_ArenaMalloc, _PyObject_ArenaFree -#endif - }; #ifdef WITH_PYMALLOC static int @@ -464,7 +463,7 @@ _PyMem_PymallocEnabled(void) static void -_PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain) +set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain) { PyMemAllocatorEx alloc; @@ -473,53 +472,66 @@ _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain) return; } - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &_PyMem_Debug.raw.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.raw.alloc); alloc.ctx = &_PyMem_Debug.raw; alloc.malloc = _PyMem_DebugRawMalloc; alloc.calloc = _PyMem_DebugRawCalloc; alloc.realloc = _PyMem_DebugRawRealloc; alloc.free = _PyMem_DebugRawFree; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); + set_allocator_unlocked(domain, &alloc); } else if (domain == PYMEM_DOMAIN_MEM) { if (_PyMem.malloc == _PyMem_DebugMalloc) { return; } - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &_PyMem_Debug.mem.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.mem.alloc); alloc.ctx = &_PyMem_Debug.mem; alloc.malloc = _PyMem_DebugMalloc; alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + set_allocator_unlocked(domain, &alloc); } else if (domain == PYMEM_DOMAIN_OBJ) { if (_PyObject.malloc == _PyMem_DebugMalloc) { return; } - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &_PyMem_Debug.obj.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.obj.alloc); alloc.ctx = &_PyMem_Debug.obj; alloc.malloc = _PyMem_DebugMalloc; alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); + set_allocator_unlocked(domain, &alloc); } } +static void +set_up_debug_hooks_unlocked(void) +{ + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_RAW); + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_MEM); + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_OBJ); +} + void PyMem_SetupDebugHooks(void) { - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_RAW); - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_MEM); - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_OBJ); + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + set_up_debug_hooks_unlocked(); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + set_up_debug_hooks_unlocked(); + PyThread_release_lock(ALLOCATORS_MUTEX); } -void -PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +static void +get_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -536,8 +548,8 @@ PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) } } -void -PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +static void +set_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -549,11 +561,76 @@ PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) } void +PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + get_allocator_unlocked(domain, allocator); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + get_allocator_unlocked(domain, allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); +} + +void +PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + set_allocator_unlocked(domain, allocator); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + set_allocator_unlocked(domain, allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); +} + +void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) { + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + *allocator = _PyObject_Arena; + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); *allocator = _PyObject_Arena; + PyThread_release_lock(ALLOCATORS_MUTEX); +} + +void +PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + _PyObject_Arena = *allocator; + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + _PyObject_Arena = *allocator; + PyThread_release_lock(ALLOCATORS_MUTEX); } + +/* Note that there is a possible, but very unlikely, race in any place + * below where we call one of the allocator functions. We access two + * fields in each case: "malloc", etc. and "ctx". + * + * It is unlikely that the allocator will be changed while one of those + * calls is happening, much less in that very narrow window. + * Furthermore, the likelihood of a race is drastically reduced by the + * fact that the allocator may not be changed after runtime init + * (except with a wrapper). + * + * With the above in mind, we currently don't worry about locking + * around these uses of the runtime-global allocators state. */ + + +/*************************/ +/* the "arena" allocator */ +/*************************/ + void * _PyObject_VirtualAlloc(size_t size) { @@ -566,11 +643,10 @@ _PyObject_VirtualFree(void *obj, size_t size) _PyObject_Arena.free(_PyObject_Arena.ctx, obj, size); } -void -PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) -{ - _PyObject_Arena = *allocator; -} + +/***********************/ +/* the "raw" allocator */ +/***********************/ void * PyMem_RawMalloc(size_t size) @@ -610,6 +686,10 @@ void PyMem_RawFree(void *ptr) } +/***********************/ +/* the "mem" allocator */ +/***********************/ + void * PyMem_Malloc(size_t size) { @@ -653,6 +733,10 @@ PyMem_Free(void *ptr) } +/***************************/ +/* pymem utility functions */ +/***************************/ + wchar_t* _PyMem_RawWcsdup(const wchar_t *str) { @@ -699,6 +783,11 @@ _PyMem_Strdup(const char *str) return copy; } + +/**************************/ +/* the "object" allocator */ +/**************************/ + void * PyObject_Malloc(size_t size) { @@ -761,534 +850,64 @@ PyObject_Free(void *ptr) static int running_on_valgrind = -1; #endif +typedef struct _obmalloc_state OMState; -/* An object allocator for Python. - - Here is an introduction to the layers of the Python memory architecture, - showing where the object allocator is actually used (layer +2), It is - called for every object allocation and deallocation (PyObject_New/Del), - unless the object-specific allocators implement a proprietary allocation - scheme (ex.: ints use a simple free list). This is also the place where - the cyclic garbage collector operates selectively on container objects. - - - Object-specific allocators - _____ ______ ______ ________ - [ int ] [ dict ] [ list ] ... [ string ] Python core | -+3 | <----- Object-specific memory -----> | <-- Non-object memory --> | - _______________________________ | | - [ Python's object allocator ] | | -+2 | ####### Object memory ####### | <------ Internal buffers ------> | - ______________________________________________________________ | - [ Python's raw memory allocator (PyMem_ API) ] | -+1 | <----- Python memory (under PyMem manager's control) ------> | | - __________________________________________________________________ - [ Underlying general-purpose allocator (ex: C library malloc) ] - 0 | <------ Virtual memory allocated for the python process -------> | - - ========================================================================= - _______________________________________________________________________ - [ OS-specific Virtual Memory Manager (VMM) ] --1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | - __________________________________ __________________________________ - [ ] [ ] --2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | - -*/ -/*==========================================================================*/ - -/* A fast, special-purpose memory allocator for small blocks, to be used - on top of a general-purpose malloc -- heavily based on previous art. */ - -/* Vladimir Marangozov -- August 2000 */ - -/* - * "Memory management is where the rubber meets the road -- if we do the wrong - * thing at any level, the results will not be good. And if we don't make the - * levels work well together, we are in serious trouble." (1) - * - * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, - * "Dynamic Storage Allocation: A Survey and Critical Review", - * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. - */ - -/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ - -/*==========================================================================*/ - -/* - * Allocation strategy abstract: - * - * For small requests, the allocator sub-allocates <Big> blocks of memory. - * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the - * system's allocator. - * - * Small requests are grouped in size classes spaced 8 bytes apart, due - * to the required valid alignment of the returned address. Requests of - * a particular size are serviced from memory pools of 4K (one VMM page). - * Pools are fragmented on demand and contain free lists of blocks of one - * particular size class. In other words, there is a fixed-size allocator - * for each size class. Free pools are shared by the different allocators - * thus minimizing the space reserved for a particular size class. - * - * This allocation strategy is a variant of what is known as "simple - * segregated storage based on array of free lists". The main drawback of - * simple segregated storage is that we might end up with lot of reserved - * memory for the different free lists, which degenerate in time. To avoid - * this, we partition each free list in pools and we share dynamically the - * reserved space between all free lists. This technique is quite efficient - * for memory intensive programs which allocate mainly small-sized blocks. - * - * For small requests we have the following table: - * - * Request in bytes Size of allocated block Size class idx - * ---------------------------------------------------------------- - * 1-8 8 0 - * 9-16 16 1 - * 17-24 24 2 - * 25-32 32 3 - * 33-40 40 4 - * 41-48 48 5 - * 49-56 56 6 - * 57-64 64 7 - * 65-72 72 8 - * ... ... ... - * 497-504 504 62 - * 505-512 512 63 - * - * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying - * allocator. - */ - -/*==========================================================================*/ - -/* - * -- Main tunable settings section -- - */ - -/* - * Alignment of addresses returned to the user. 8-bytes alignment works - * on most current architectures (with 32-bit or 64-bit address buses). - * The alignment value is also used for grouping small requests in size - * classes spaced ALIGNMENT bytes apart. - * - * You shouldn't change this unless you know what you are doing. - */ - -#if SIZEOF_VOID_P > 4 -#define ALIGNMENT 16 /* must be 2^N */ -#define ALIGNMENT_SHIFT 4 -#else -#define ALIGNMENT 8 /* must be 2^N */ -#define ALIGNMENT_SHIFT 3 -#endif - -/* Return the number of bytes in size class I, as a uint. */ -#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) - -/* - * Max size threshold below which malloc requests are considered to be - * small enough in order to use preallocated memory pools. You can tune - * this value according to your application behaviour and memory needs. - * - * Note: a size threshold of 512 guarantees that newly created dictionaries - * will be allocated from preallocated memory pools on 64-bit. - * - * The following invariants must hold: - * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 - * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT - * - * Although not required, for better performance and space efficiency, - * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. - */ -#define SMALL_REQUEST_THRESHOLD 512 -#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) - -/* - * The system's VMM page size can be obtained on most unices with a - * getpagesize() call or deduced from various header files. To make - * things simpler, we assume that it is 4K, which is OK for most systems. - * It is probably better if this is the native page size, but it doesn't - * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page - * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation - * violation fault. 4K is apparently OK for all the platforms that python - * currently targets. - */ -#define SYSTEM_PAGE_SIZE (4 * 1024) - -/* - * Maximum amount of memory managed by the allocator for small requests. - */ -#ifdef WITH_MEMORY_LIMITS -#ifndef SMALL_MEMORY_LIMIT -#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ -#endif -#endif - -#if !defined(WITH_PYMALLOC_RADIX_TREE) -/* Use radix-tree to track arena memory regions, for address_in_range(). - * Enable by default since it allows larger pool sizes. Can be disabled - * using -DWITH_PYMALLOC_RADIX_TREE=0 */ -#define WITH_PYMALLOC_RADIX_TREE 1 -#endif - -#if SIZEOF_VOID_P > 4 -/* on 64-bit platforms use larger pools and arenas if we can */ -#define USE_LARGE_ARENAS -#if WITH_PYMALLOC_RADIX_TREE -/* large pools only supported if radix-tree is enabled */ -#define USE_LARGE_POOLS -#endif -#endif +static inline int +has_own_state(PyInterpreterState *interp) +{ + return (_Py_IsMainInterpreter(interp) || + !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC) || + _Py_IsMainInterpreterFinalizing(interp)); +} -/* - * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned - * on a page boundary. This is a reserved virtual address space for the - * current process (obtained through a malloc()/mmap() call). In no way this - * means that the memory arenas will be used entirely. A malloc(<Big>) is - * usually an address range reservation for <Big> bytes, unless all pages within - * this space are referenced subsequently. So malloc'ing big blocks and not - * using them does not mean "wasting memory". It's an addressable range - * wastage... - * - * Arenas are allocated with mmap() on systems supporting anonymous memory - * mappings to reduce heap fragmentation. - */ -#ifdef USE_LARGE_ARENAS -#define ARENA_BITS 20 /* 1 MiB */ -#else -#define ARENA_BITS 18 /* 256 KiB */ -#endif -#define ARENA_SIZE (1 << ARENA_BITS) -#define ARENA_SIZE_MASK (ARENA_SIZE - 1) +static inline OMState * +get_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!has_own_state(interp)) { + interp = _PyInterpreterState_Main(); + } + return &interp->obmalloc; +} -#ifdef WITH_MEMORY_LIMITS -#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) -#endif +// These macros all rely on a local "state" variable. +#define usedpools (state->pools.used) +#define allarenas (state->mgmt.arenas) +#define maxarenas (state->mgmt.maxarenas) +#define unused_arena_objects (state->mgmt.unused_arena_objects) +#define usable_arenas (state->mgmt.usable_arenas) +#define nfp2lasta (state->mgmt.nfp2lasta) +#define narenas_currently_allocated (state->mgmt.narenas_currently_allocated) +#define ntimes_arena_allocated (state->mgmt.ntimes_arena_allocated) +#define narenas_highwater (state->mgmt.narenas_highwater) +#define raw_allocated_blocks (state->mgmt.raw_allocated_blocks) -/* - * Size of the pools used for small blocks. Must be a power of 2. - */ -#ifdef USE_LARGE_POOLS -#define POOL_BITS 14 /* 16 KiB */ +Py_ssize_t +_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp) +{ +#ifdef Py_DEBUG + assert(has_own_state(interp)); #else -#define POOL_BITS 12 /* 4 KiB */ -#endif -#define POOL_SIZE (1 << POOL_BITS) -#define POOL_SIZE_MASK (POOL_SIZE - 1) - -#if !WITH_PYMALLOC_RADIX_TREE -#if POOL_SIZE != SYSTEM_PAGE_SIZE -# error "pool size must be equal to system page size" -#endif -#endif - -#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) -#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE -# error "arena size not an exact multiple of pool size" + if (!has_own_state(interp)) { + _Py_FatalErrorFunc(__func__, + "the interpreter doesn't have its own allocator"); + } #endif + OMState *state = &interp->obmalloc; -/* - * -- End of tunable settings section -- - */ - -/*==========================================================================*/ - -/* When you say memory, my mind reasons in terms of (pointers to) blocks */ -typedef uint8_t block; - -/* Pool for small blocks. */ -struct pool_header { - union { block *_padding; - uint count; } ref; /* number of allocated blocks */ - block *freeblock; /* pool's free list head */ - struct pool_header *nextpool; /* next pool of this size class */ - struct pool_header *prevpool; /* previous pool "" */ - uint arenaindex; /* index into arenas of base adr */ - uint szidx; /* block size class index */ - uint nextoffset; /* bytes to virgin block */ - uint maxnextoffset; /* largest valid nextoffset */ -}; - -typedef struct pool_header *poolp; - -/* Record keeping for arenas. */ -struct arena_object { - /* The address of the arena, as returned by malloc. Note that 0 - * will never be returned by a successful malloc, and is used - * here to mark an arena_object that doesn't correspond to an - * allocated arena. - */ - uintptr_t address; - - /* Pool-aligned pointer to the next pool to be carved off. */ - block* pool_address; - - /* The number of available pools in the arena: free pools + never- - * allocated pools. - */ - uint nfreepools; - - /* The total number of pools in the arena, whether or not available. */ - uint ntotalpools; - - /* Singly-linked list of available pools. */ - struct pool_header* freepools; - - /* Whenever this arena_object is not associated with an allocated - * arena, the nextarena member is used to link all unassociated - * arena_objects in the singly-linked `unused_arena_objects` list. - * The prevarena member is unused in this case. - * - * When this arena_object is associated with an allocated arena - * with at least one available pool, both members are used in the - * doubly-linked `usable_arenas` list, which is maintained in - * increasing order of `nfreepools` values. - * - * Else this arena_object is associated with an allocated arena - * all of whose pools are in use. `nextarena` and `prevarena` - * are both meaningless in this case. - */ - struct arena_object* nextarena; - struct arena_object* prevarena; -}; - -#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) - -#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ - -/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ -#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) - -/* Return total number of blocks in pool of size index I, as a uint. */ -#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) - -/*==========================================================================*/ - -/* - * Pool table -- headed, circular, doubly-linked lists of partially used pools. - -This is involved. For an index i, usedpools[i+i] is the header for a list of -all partially used pools holding small blocks with "size class idx" i. So -usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size -16, and so on: index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT. - -Pools are carved off an arena's highwater mark (an arena_object's pool_address -member) as needed. Once carved off, a pool is in one of three states forever -after: - -used == partially used, neither empty nor full - At least one block in the pool is currently allocated, and at least one - block in the pool is not currently allocated (note this implies a pool - has room for at least two blocks). - This is a pool's initial state, as a pool is created only when malloc - needs space. - The pool holds blocks of a fixed size, and is in the circular list headed - at usedpools[i] (see above). It's linked to the other used pools of the - same size class via the pool_header's nextpool and prevpool members. - If all but one block is currently allocated, a malloc can cause a - transition to the full state. If all but one block is not currently - allocated, a free can cause a transition to the empty state. - -full == all the pool's blocks are currently allocated - On transition to full, a pool is unlinked from its usedpools[] list. - It's not linked to from anything then anymore, and its nextpool and - prevpool members are meaningless until it transitions back to used. - A free of a block in a full pool puts the pool back in the used state. - Then it's linked in at the front of the appropriate usedpools[] list, so - that the next allocation for its size class will reuse the freed block. - -empty == all the pool's blocks are currently available for allocation - On transition to empty, a pool is unlinked from its usedpools[] list, - and linked to the front of its arena_object's singly-linked freepools list, - via its nextpool member. The prevpool member has no meaning in this case. - Empty pools have no inherent size class: the next time a malloc finds - an empty list in usedpools[], it takes the first pool off of freepools. - If the size class needed happens to be the same as the size class the pool - last had, some pool initialization can be skipped. - - -Block Management - -Blocks within pools are again carved out as needed. pool->freeblock points to -the start of a singly-linked list of free blocks within the pool. When a -block is freed, it's inserted at the front of its pool's freeblock list. Note -that the available blocks in a pool are *not* linked all together when a pool -is initialized. Instead only "the first two" (lowest addresses) blocks are -set up, returning the first such block, and setting pool->freeblock to a -one-block list holding the second such block. This is consistent with that -pymalloc strives at all levels (arena, pool, and block) never to touch a piece -of memory until it's actually needed. - -So long as a pool is in the used state, we're certain there *is* a block -available for allocating, and pool->freeblock is not NULL. If pool->freeblock -points to the end of the free list before we've carved the entire pool into -blocks, that means we simply haven't yet gotten to one of the higher-address -blocks. The offset from the pool_header to the start of "the next" virgin -block is stored in the pool_header nextoffset member, and the largest value -of nextoffset that makes sense is stored in the maxnextoffset member when a -pool is initialized. All the blocks in a pool have been passed out at least -once when and only when nextoffset > maxnextoffset. - - -Major obscurity: While the usedpools vector is declared to have poolp -entries, it doesn't really. It really contains two pointers per (conceptual) -poolp entry, the nextpool and prevpool members of a pool_header. The -excruciating initialization code below fools C so that - - usedpool[i+i] - -"acts like" a genuine poolp, but only so long as you only reference its -nextpool and prevpool members. The "- 2*sizeof(block *)" gibberish is -compensating for that a pool_header's nextpool and prevpool members -immediately follow a pool_header's first two members: - - union { block *_padding; - uint count; } ref; - block *freeblock; - -each of which consume sizeof(block *) bytes. So what usedpools[i+i] really -contains is a fudged-up pointer p such that *if* C believes it's a poolp -pointer, then p->nextpool and p->prevpool are both p (meaning that the headed -circular list is empty). - -It's unclear why the usedpools setup is so convoluted. It could be to -minimize the amount of cache required to hold this heavily-referenced table -(which only *needs* the two interpool pointer members of a pool_header). OTOH, -referencing code has to remember to "double the index" and doing so isn't -free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying -on that C doesn't insert any padding anywhere in a pool_header at or before -the prevpool member. -**************************************************************************** */ - -#define PTA(x) ((poolp )((uint8_t *)&(usedpools[2*(x)]) - 2*sizeof(block *))) -#define PT(x) PTA(x), PTA(x) - -static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = { - PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7) -#if NB_SMALL_SIZE_CLASSES > 8 - , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15) -#if NB_SMALL_SIZE_CLASSES > 16 - , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23) -#if NB_SMALL_SIZE_CLASSES > 24 - , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31) -#if NB_SMALL_SIZE_CLASSES > 32 - , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39) -#if NB_SMALL_SIZE_CLASSES > 40 - , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47) -#if NB_SMALL_SIZE_CLASSES > 48 - , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55) -#if NB_SMALL_SIZE_CLASSES > 56 - , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63) -#if NB_SMALL_SIZE_CLASSES > 64 -#error "NB_SMALL_SIZE_CLASSES should be less than 64" -#endif /* NB_SMALL_SIZE_CLASSES > 64 */ -#endif /* NB_SMALL_SIZE_CLASSES > 56 */ -#endif /* NB_SMALL_SIZE_CLASSES > 48 */ -#endif /* NB_SMALL_SIZE_CLASSES > 40 */ -#endif /* NB_SMALL_SIZE_CLASSES > 32 */ -#endif /* NB_SMALL_SIZE_CLASSES > 24 */ -#endif /* NB_SMALL_SIZE_CLASSES > 16 */ -#endif /* NB_SMALL_SIZE_CLASSES > 8 */ -}; - -/*========================================================================== -Arena management. - -`arenas` is a vector of arena_objects. It contains maxarenas entries, some of -which may not be currently used (== they're arena_objects that aren't -currently associated with an allocated arena). Note that arenas proper are -separately malloc'ed. - -Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, -we do try to free() arenas, and use some mild heuristic strategies to increase -the likelihood that arenas eventually can be freed. - -unused_arena_objects - - This is a singly-linked list of the arena_objects that are currently not - being used (no arena is associated with them). Objects are taken off the - head of the list in new_arena(), and are pushed on the head of the list in - PyObject_Free() when the arena is empty. Key invariant: an arena_object - is on this list if and only if its .address member is 0. - -usable_arenas - - This is a doubly-linked list of the arena_objects associated with arenas - that have pools available. These pools are either waiting to be reused, - or have not been used before. The list is sorted to have the most- - allocated arenas first (ascending order based on the nfreepools member). - This means that the next allocation will come from a heavily used arena, - which gives the nearly empty arenas a chance to be returned to the system. - In my unscientific tests this dramatically improved the number of arenas - that could be freed. - -Note that an arena_object associated with an arena all of whose pools are -currently in use isn't on either list. - -Changed in Python 3.8: keeping usable_arenas sorted by number of free pools -used to be done by one-at-a-time linear search when an arena's number of -free pools changed. That could, overall, consume time quadratic in the -number of arenas. That didn't really matter when there were only a few -hundred arenas (typical!), but could be a timing disaster when there were -hundreds of thousands. See bpo-37029. - -Now we have a vector of "search fingers" to eliminate the need to search: -nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas -with nfp free pools. This is NULL if and only if there is no arena with -nfp free pools in usable_arenas. -*/ - -/* Array of objects used to track chunks of memory (arenas). */ -static struct arena_object* arenas = NULL; -/* Number of slots currently allocated in the `arenas` vector. */ -static uint maxarenas = 0; - -/* The head of the singly-linked, NULL-terminated list of available - * arena_objects. - */ -static struct arena_object* unused_arena_objects = NULL; - -/* The head of the doubly-linked, NULL-terminated at each end, list of - * arena_objects associated with arenas that have pools available. - */ -static struct arena_object* usable_arenas = NULL; - -/* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ -static struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1] = { NULL }; - -/* How many arena_objects do we initially allocate? - * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the - * `arenas` vector. - */ -#define INITIAL_ARENA_OBJECTS 16 - -/* Number of arenas allocated that haven't been free()'d. */ -static size_t narenas_currently_allocated = 0; - -/* Total number of times malloc() called to allocate an arena. */ -static size_t ntimes_arena_allocated = 0; -/* High water mark (max value ever seen) for narenas_currently_allocated. */ -static size_t narenas_highwater = 0; - -static Py_ssize_t raw_allocated_blocks; - -Py_ssize_t -_Py_GetAllocatedBlocks(void) -{ Py_ssize_t n = raw_allocated_blocks; /* add up allocated blocks for used pools */ for (uint i = 0; i < maxarenas; ++i) { /* Skip arenas which are not allocated. */ - if (arenas[i].address == 0) { + if (allarenas[i].address == 0) { continue; } - uintptr_t base = (uintptr_t)_Py_ALIGN_UP(arenas[i].address, POOL_SIZE); + uintptr_t base = (uintptr_t)_Py_ALIGN_UP(allarenas[i].address, POOL_SIZE); /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; n += p->ref.count; } @@ -1296,157 +915,100 @@ _Py_GetAllocatedBlocks(void) return n; } -#if WITH_PYMALLOC_RADIX_TREE -/*==========================================================================*/ -/* radix tree for tracking arena usage. If enabled, used to implement - address_in_range(). - - memory address bit allocation for keys - - 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size: - 15 -> MAP_TOP_BITS - 15 -> MAP_MID_BITS - 14 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 64-bit pointers, IGNORE_BITS=16, and 2^20 arena size: - 16 -> IGNORE_BITS - 10 -> MAP_TOP_BITS - 10 -> MAP_MID_BITS - 8 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 32-bit pointers and 2^18 arena size: - 14 -> MAP_BOT_BITS - 18 -> ideal aligned arena - ---- - 32 - -*/ - -#if SIZEOF_VOID_P == 8 - -/* number of bits in a pointer */ -#define POINTER_BITS 64 - -/* High bits of memory addresses that will be ignored when indexing into the - * radix tree. Setting this to zero is the safe default. For most 64-bit - * machines, setting this to 16 would be safe. The kernel would not give - * user-space virtual memory addresses that have significant information in - * those high bits. The main advantage to setting IGNORE_BITS > 0 is that less - * virtual memory will be used for the top and middle radix tree arrays. Those - * arrays are allocated in the BSS segment and so will typically consume real - * memory only if actually accessed. - */ -#define IGNORE_BITS 0 - -/* use the top and mid layers of the radix tree */ -#define USE_INTERIOR_NODES - -#elif SIZEOF_VOID_P == 4 - -#define POINTER_BITS 32 -#define IGNORE_BITS 0 +void +_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *interp) +{ + if (has_own_state(interp)) { + Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp); + assert(has_own_state(interp) || leaked == 0); + interp->runtime->obmalloc.interpreter_leaks += leaked; + } +} -#else +static Py_ssize_t get_num_global_allocated_blocks(_PyRuntimeState *); - /* Currently this code works for 64-bit or 32-bit pointers only. */ -#error "obmalloc radix tree requires 64-bit or 32-bit pointers." +/* We preserve the number of blockss leaked during runtime finalization, + so they can be reported if the runtime is initialized again. */ +// XXX We don't lose any information by dropping this, +// so we should consider doing so. +static Py_ssize_t last_final_leaks = 0; -#endif /* SIZEOF_VOID_P */ +void +_Py_FinalizeAllocatedBlocks(_PyRuntimeState *runtime) +{ + last_final_leaks = get_num_global_allocated_blocks(runtime); + runtime->obmalloc.interpreter_leaks = 0; +} -/* arena_coverage_t members require this to be true */ -#if ARENA_BITS >= 32 -# error "arena size must be < 2^32" +static Py_ssize_t +get_num_global_allocated_blocks(_PyRuntimeState *runtime) +{ + Py_ssize_t total = 0; + if (_PyRuntimeState_GetFinalizing(runtime) != NULL) { + PyInterpreterState *interp = _PyInterpreterState_Main(); + if (interp == NULL) { + /* We are at the very end of runtime finalization. + We can't rely on finalizing->interp since that thread + state is probably already freed, so we don't worry + about it. */ + assert(PyInterpreterState_Head() == NULL); + } + else { + assert(interp != NULL); + /* It is probably the last interpreter but not necessarily. */ + assert(PyInterpreterState_Next(interp) == NULL); + total += _PyInterpreterState_GetAllocatedBlocks(interp); + } + } + else { + HEAD_LOCK(runtime); + PyInterpreterState *interp = PyInterpreterState_Head(); + assert(interp != NULL); +#ifdef Py_DEBUG + int got_main = 0; #endif - -/* the lower bits of the address that are not ignored */ -#define ADDRESS_BITS (POINTER_BITS - IGNORE_BITS) - -#ifdef USE_INTERIOR_NODES -/* number of bits used for MAP_TOP and MAP_MID nodes */ -#define INTERIOR_BITS ((ADDRESS_BITS - ARENA_BITS + 2) / 3) -#else -#define INTERIOR_BITS 0 + for (; interp != NULL; interp = PyInterpreterState_Next(interp)) { +#ifdef Py_DEBUG + if (_Py_IsMainInterpreter(interp)) { + assert(!got_main); + got_main = 1; + assert(has_own_state(interp)); + } #endif - -#define MAP_TOP_BITS INTERIOR_BITS -#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS) -#define MAP_TOP_MASK (MAP_TOP_LENGTH - 1) - -#define MAP_MID_BITS INTERIOR_BITS -#define MAP_MID_LENGTH (1 << MAP_MID_BITS) -#define MAP_MID_MASK (MAP_MID_LENGTH - 1) - -#define MAP_BOT_BITS (ADDRESS_BITS - ARENA_BITS - 2*INTERIOR_BITS) -#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS) -#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1) - -#define MAP_BOT_SHIFT ARENA_BITS -#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT) -#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT) - -#define AS_UINT(p) ((uintptr_t)(p)) -#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK) -#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK) -#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK) - -#if IGNORE_BITS > 0 -/* Return the ignored part of the pointer address. Those bits should be same - * for all valid pointers if IGNORE_BITS is set correctly. - */ -#define HIGH_BITS(p) (AS_UINT(p) >> ADDRESS_BITS) -#else -#define HIGH_BITS(p) 0 + if (has_own_state(interp)) { + total += _PyInterpreterState_GetAllocatedBlocks(interp); + } + } + HEAD_UNLOCK(runtime); +#ifdef Py_DEBUG + assert(got_main); #endif + } + total += runtime->obmalloc.interpreter_leaks; + total += last_final_leaks; + return total; +} +Py_ssize_t +_Py_GetGlobalAllocatedBlocks(void) +{ + return get_num_global_allocated_blocks(&_PyRuntime); +} -/* This is the leaf of the radix tree. See arena_map_mark_used() for the - * meaning of these members. */ -typedef struct { - int32_t tail_hi; - int32_t tail_lo; -} arena_coverage_t; - -typedef struct arena_map_bot { - /* The members tail_hi and tail_lo are accessed together. So, it - * better to have them as an array of structs, rather than two - * arrays. - */ - arena_coverage_t arenas[MAP_BOT_LENGTH]; -} arena_map_bot_t; - -#ifdef USE_INTERIOR_NODES -typedef struct arena_map_mid { - struct arena_map_bot *ptrs[MAP_MID_LENGTH]; -} arena_map_mid_t; - -typedef struct arena_map_top { - struct arena_map_mid *ptrs[MAP_TOP_LENGTH]; -} arena_map_top_t; -#endif +#if WITH_PYMALLOC_RADIX_TREE +/*==========================================================================*/ +/* radix tree for tracking arena usage. */ -/* The root of radix tree. Note that by initializing like this, the memory - * should be in the BSS. The OS will only memory map pages as the MAP_MID - * nodes get used (OS pages are demand loaded as needed). - */ +#define arena_map_root (state->usage.arena_map_root) #ifdef USE_INTERIOR_NODES -static arena_map_top_t arena_map_root; -/* accounting for number of used interior nodes */ -static int arena_map_mid_count; -static int arena_map_bot_count; -#else -static arena_map_bot_t arena_map_root; +#define arena_map_mid_count (state->usage.arena_map_mid_count) +#define arena_map_bot_count (state->usage.arena_map_bot_count) #endif /* Return a pointer to a bottom tree node, return NULL if it doesn't exist or * it cannot be created */ static inline Py_ALWAYS_INLINE arena_map_bot_t * -arena_map_get(block *p, int create) +arena_map_get(OMState *state, pymem_block *p, int create) { #ifdef USE_INTERIOR_NODES /* sanity check that IGNORE_BITS is correct */ @@ -1507,16 +1069,17 @@ arena_map_get(block *p, int create) /* mark or unmark addresses covered by arena */ static int -arena_map_mark_used(uintptr_t arena_base, int is_used) +arena_map_mark_used(OMState *state, uintptr_t arena_base, int is_used) { /* sanity check that IGNORE_BITS is correct */ assert(HIGH_BITS(arena_base) == HIGH_BITS(&arena_map_root)); - arena_map_bot_t *n_hi = arena_map_get((block *)arena_base, is_used); + arena_map_bot_t *n_hi = arena_map_get( + state, (pymem_block *)arena_base, is_used); if (n_hi == NULL) { assert(is_used); /* otherwise node should already exist */ return 0; /* failed to allocate space for node */ } - int i3 = MAP_BOT_INDEX((block *)arena_base); + int i3 = MAP_BOT_INDEX((pymem_block *)arena_base); int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK); if (tail == 0) { /* is ideal arena address */ @@ -1536,7 +1099,8 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) * must overflow to 0. However, that would mean arena_base was * "ideal" and we should not be in this case. */ assert(arena_base < arena_base_next); - arena_map_bot_t *n_lo = arena_map_get((block *)arena_base_next, is_used); + arena_map_bot_t *n_lo = arena_map_get( + state, (pymem_block *)arena_base_next, is_used); if (n_lo == NULL) { assert(is_used); /* otherwise should already exist */ n_hi->arenas[i3].tail_hi = 0; @@ -1551,9 +1115,9 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) /* Return true if 'p' is a pointer inside an obmalloc arena. * _PyObject_Free() calls this so it needs to be very fast. */ static int -arena_map_is_used(block *p) +arena_map_is_used(OMState *state, pymem_block *p) { - arena_map_bot_t *n = arena_map_get(p, 0); + arena_map_bot_t *n = arena_map_get(state, p, 0); if (n == NULL) { return 0; } @@ -1576,16 +1140,17 @@ arena_map_is_used(block *p) * `usable_arenas` to the return value. */ static struct arena_object* -new_arena(void) +new_arena(OMState *state) { struct arena_object* arenaobj; uint excess; /* number of bytes above pool alignment */ void *address; - static int debug_stats = -1; + int debug_stats = _PyRuntime.obmalloc.dump_debug_stats; if (debug_stats == -1) { const char *opt = Py_GETENV("PYTHONMALLOCSTATS"); debug_stats = (opt != NULL && *opt != '\0'); + _PyRuntime.obmalloc.dump_debug_stats = debug_stats; } if (debug_stats) { _PyObject_DebugMallocStats(stderr); @@ -1603,14 +1168,14 @@ new_arena(void) if (numarenas <= maxarenas) return NULL; /* overflow */ #if SIZEOF_SIZE_T <= SIZEOF_INT - if (numarenas > SIZE_MAX / sizeof(*arenas)) + if (numarenas > SIZE_MAX / sizeof(*allarenas)) return NULL; /* overflow */ #endif - nbytes = numarenas * sizeof(*arenas); - arenaobj = (struct arena_object *)PyMem_RawRealloc(arenas, nbytes); + nbytes = numarenas * sizeof(*allarenas); + arenaobj = (struct arena_object *)PyMem_RawRealloc(allarenas, nbytes); if (arenaobj == NULL) return NULL; - arenas = arenaobj; + allarenas = arenaobj; /* We might need to fix pointers that were copied. However, * new_arena only gets called when all the pages in the @@ -1623,13 +1188,13 @@ new_arena(void) /* Put the new arenas on the unused_arena_objects list. */ for (i = maxarenas; i < numarenas; ++i) { - arenas[i].address = 0; /* mark as unassociated */ - arenas[i].nextarena = i < numarenas - 1 ? - &arenas[i+1] : NULL; + allarenas[i].address = 0; /* mark as unassociated */ + allarenas[i].nextarena = i < numarenas - 1 ? + &allarenas[i+1] : NULL; } /* Update globals. */ - unused_arena_objects = &arenas[maxarenas]; + unused_arena_objects = &allarenas[maxarenas]; maxarenas = numarenas; } @@ -1641,7 +1206,7 @@ new_arena(void) address = _PyObject_Arena.alloc(_PyObject_Arena.ctx, ARENA_SIZE); #if WITH_PYMALLOC_RADIX_TREE if (address != NULL) { - if (!arena_map_mark_used((uintptr_t)address, 1)) { + if (!arena_map_mark_used(state, (uintptr_t)address, 1)) { /* marking arena in radix tree failed, abort */ _PyObject_Arena.free(_PyObject_Arena.ctx, address, ARENA_SIZE); address = NULL; @@ -1665,7 +1230,7 @@ new_arena(void) arenaobj->freepools = NULL; /* pool_address <- first pool-aligned address in the arena nfreepools <- number of whole pools that fit after alignment */ - arenaobj->pool_address = (block*)arenaobj->address; + arenaobj->pool_address = (pymem_block*)arenaobj->address; arenaobj->nfreepools = MAX_POOLS_IN_ARENA; excess = (uint)(arenaobj->address & POOL_SIZE_MASK); if (excess != 0) { @@ -1684,9 +1249,9 @@ new_arena(void) pymalloc. When the radix tree is used, 'poolp' is unused. */ static bool -address_in_range(void *p, poolp pool) +address_in_range(OMState *state, void *p, poolp Py_UNUSED(pool)) { - return arena_map_is_used(p); + return arena_map_is_used(state, p); } #else /* @@ -1767,7 +1332,7 @@ extremely desirable that it be this fast. static bool _Py_NO_SANITIZE_ADDRESS _Py_NO_SANITIZE_THREAD _Py_NO_SANITIZE_MEMORY -address_in_range(void *p, poolp pool) +address_in_range(OMState *state, void *p, poolp pool) { // Since address_in_range may be reading from memory which was not allocated // by Python, it is important that pool->arenaindex is read only once, as @@ -1776,8 +1341,8 @@ address_in_range(void *p, poolp pool) // only once. uint arenaindex = *((volatile uint *)&pool->arenaindex); return arenaindex < maxarenas && - (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE && - arenas[arenaindex].address != 0; + (uintptr_t)p - allarenas[arenaindex].address < ARENA_SIZE && + allarenas[arenaindex].address != 0; } #endif /* !WITH_PYMALLOC_RADIX_TREE */ @@ -1791,9 +1356,9 @@ pymalloc_pool_extend(poolp pool, uint size) { if (UNLIKELY(pool->nextoffset <= pool->maxnextoffset)) { /* There is room for another block. */ - pool->freeblock = (block*)pool + pool->nextoffset; + pool->freeblock = (pymem_block*)pool + pool->nextoffset; pool->nextoffset += INDEX2SIZE(size); - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return; } @@ -1809,7 +1374,7 @@ pymalloc_pool_extend(poolp pool, uint size) * This function takes new pool and allocate a block from it. */ static void* -allocate_from_new_pool(uint size) +allocate_from_new_pool(OMState *state, uint size) { /* There isn't a pool of the right size class immediately * available: use a free pool. @@ -1821,7 +1386,7 @@ allocate_from_new_pool(uint size) return NULL; } #endif - usable_arenas = new_arena(); + usable_arenas = new_arena(state); if (usable_arenas == NULL) { return NULL; } @@ -1873,7 +1438,7 @@ allocate_from_new_pool(uint size) */ assert(usable_arenas->freepools != NULL || usable_arenas->pool_address <= - (block*)usable_arenas->address + + (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); } } @@ -1882,10 +1447,10 @@ allocate_from_new_pool(uint size) assert(usable_arenas->nfreepools > 0); assert(usable_arenas->freepools == NULL); pool = (poolp)usable_arenas->pool_address; - assert((block*)pool <= (block*)usable_arenas->address + + assert((pymem_block*)pool <= (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); - pool->arenaindex = (uint)(usable_arenas - arenas); - assert(&arenas[pool->arenaindex] == usable_arenas); + pool->arenaindex = (uint)(usable_arenas - allarenas); + assert(&allarenas[pool->arenaindex] == usable_arenas); pool->szidx = DUMMY_SIZE_IDX; usable_arenas->pool_address += POOL_SIZE; --usable_arenas->nfreepools; @@ -1904,7 +1469,7 @@ allocate_from_new_pool(uint size) } /* Frontlink to used pools. */ - block *bp; + pymem_block *bp; poolp next = usedpools[size + size]; /* == prev */ pool->nextpool = next; pool->prevpool = next; @@ -1918,7 +1483,7 @@ allocate_from_new_pool(uint size) */ bp = pool->freeblock; assert(bp != NULL); - pool->freeblock = *(block **)bp; + pool->freeblock = *(pymem_block **)bp; return bp; } /* @@ -1928,11 +1493,11 @@ allocate_from_new_pool(uint size) */ pool->szidx = size; size = INDEX2SIZE(size); - bp = (block *)pool + POOL_OVERHEAD; + bp = (pymem_block *)pool + POOL_OVERHEAD; pool->nextoffset = POOL_OVERHEAD + (size << 1); pool->maxnextoffset = POOL_SIZE - size; pool->freeblock = bp + size; - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return bp; } @@ -1945,7 +1510,7 @@ allocate_from_new_pool(uint size) or when the max memory limit has been reached. */ static inline void* -pymalloc_alloc(void *ctx, size_t nbytes) +pymalloc_alloc(OMState *state, void *Py_UNUSED(ctx), size_t nbytes) { #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) { @@ -1965,7 +1530,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) uint size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; poolp pool = usedpools[size + size]; - block *bp; + pymem_block *bp; if (LIKELY(pool != pool->nextpool)) { /* @@ -1976,7 +1541,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) bp = pool->freeblock; assert(bp != NULL); - if (UNLIKELY((pool->freeblock = *(block **)bp) == NULL)) { + if (UNLIKELY((pool->freeblock = *(pymem_block **)bp) == NULL)) { // Reached the end of the free list, try to extend it. pymalloc_pool_extend(pool, size); } @@ -1985,17 +1550,18 @@ pymalloc_alloc(void *ctx, size_t nbytes) /* There isn't a pool of the right size class immediately * available: use a free pool. */ - bp = allocate_from_new_pool(size); + bp = allocate_from_new_pool(state, size); } return (void *)bp; } -static void * +void * _PyObject_Malloc(void *ctx, size_t nbytes) { - void* ptr = pymalloc_alloc(ctx, nbytes); + OMState *state = get_state(); + void* ptr = pymalloc_alloc(state, ctx, nbytes); if (LIKELY(ptr != NULL)) { return ptr; } @@ -2008,13 +1574,14 @@ _PyObject_Malloc(void *ctx, size_t nbytes) } -static void * +void * _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) { assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); size_t nbytes = nelem * elsize; - void* ptr = pymalloc_alloc(ctx, nbytes); + OMState *state = get_state(); + void* ptr = pymalloc_alloc(state, ctx, nbytes); if (LIKELY(ptr != NULL)) { memset(ptr, 0, nbytes); return ptr; @@ -2029,7 +1596,7 @@ _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) static void -insert_to_usedpool(poolp pool) +insert_to_usedpool(OMState *state, poolp pool) { assert(pool->ref.count > 0); /* else the pool is empty */ @@ -2045,7 +1612,7 @@ insert_to_usedpool(poolp pool) } static void -insert_to_freepool(poolp pool) +insert_to_freepool(OMState *state, poolp pool) { poolp next = pool->nextpool; poolp prev = pool->prevpool; @@ -2055,7 +1622,7 @@ insert_to_freepool(poolp pool) /* Link the pool to freepools. This is a singly-linked * list, and pool->prevpool isn't used there. */ - struct arena_object *ao = &arenas[pool->arenaindex]; + struct arena_object *ao = &allarenas[pool->arenaindex]; pool->nextpool = ao->freepools; ao->freepools = pool; uint nf = ao->nfreepools; @@ -2128,7 +1695,7 @@ insert_to_freepool(poolp pool) #if WITH_PYMALLOC_RADIX_TREE /* mark arena region as not under control of obmalloc */ - arena_map_mark_used(ao->address, 0); + arena_map_mark_used(state, ao->address, 0); #endif /* Free the entire arena. */ @@ -2215,7 +1782,7 @@ insert_to_freepool(poolp pool) Return 1 if it was freed. Return 0 if the block was not allocated by pymalloc_alloc(). */ static inline int -pymalloc_free(void *ctx, void *p) +pymalloc_free(OMState *state, void *Py_UNUSED(ctx), void *p) { assert(p != NULL); @@ -2226,7 +1793,7 @@ pymalloc_free(void *ctx, void *p) #endif poolp pool = POOL_ADDR(p); - if (UNLIKELY(!address_in_range(p, pool))) { + if (UNLIKELY(!address_in_range(state, p, pool))) { return 0; } /* We allocated this address. */ @@ -2238,9 +1805,9 @@ pymalloc_free(void *ctx, void *p) * list in any case). */ assert(pool->ref.count > 0); /* else it was empty */ - block *lastfree = pool->freeblock; - *(block **)p = lastfree; - pool->freeblock = (block *)p; + pymem_block *lastfree = pool->freeblock; + *(pymem_block **)p = lastfree; + pool->freeblock = (pymem_block *)p; pool->ref.count--; if (UNLIKELY(lastfree == NULL)) { @@ -2250,7 +1817,7 @@ pymalloc_free(void *ctx, void *p) * targets optimal filling when several pools contain * blocks of the same size class. */ - insert_to_usedpool(pool); + insert_to_usedpool(state, pool); return 1; } @@ -2267,12 +1834,12 @@ pymalloc_free(void *ctx, void *p) * previously freed pools will be allocated later * (being not referenced, they are perhaps paged out). */ - insert_to_freepool(pool); + insert_to_freepool(state, pool); return 1; } -static void +void _PyObject_Free(void *ctx, void *p) { /* PyObject_Free(NULL) has no effect */ @@ -2280,7 +1847,8 @@ _PyObject_Free(void *ctx, void *p) return; } - if (UNLIKELY(!pymalloc_free(ctx, p))) { + OMState *state = get_state(); + if (UNLIKELY(!pymalloc_free(state, ctx, p))) { /* pymalloc didn't allocate this address */ PyMem_RawFree(p); raw_allocated_blocks--; @@ -2298,7 +1866,8 @@ _PyObject_Free(void *ctx, void *p) Return 0 if pymalloc didn't allocated p. */ static int -pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) +pymalloc_realloc(OMState *state, void *ctx, + void **newptr_p, void *p, size_t nbytes) { void *bp; poolp pool; @@ -2314,7 +1883,7 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) #endif pool = POOL_ADDR(p); - if (!address_in_range(p, pool)) { + if (!address_in_range(state, p, pool)) { /* pymalloc is not managing this block. If nbytes <= SMALL_REQUEST_THRESHOLD, it's tempting to try to take @@ -2358,7 +1927,7 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) } -static void * +void * _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) { void *ptr2; @@ -2367,7 +1936,8 @@ _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) return _PyObject_Malloc(ctx, nbytes); } - if (pymalloc_realloc(ctx, &ptr2, ptr, nbytes)) { + OMState *state = get_state(); + if (pymalloc_realloc(state, ctx, &ptr2, ptr, nbytes)) { return ptr2; } @@ -2381,11 +1951,29 @@ _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) * only be used by extensions that are compiled with pymalloc enabled. */ Py_ssize_t -_Py_GetAllocatedBlocks(void) +_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp)) +{ + return 0; +} + +Py_ssize_t +_Py_GetGlobalAllocatedBlocks(void) { return 0; } +void +_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp)) +{ + return; +} + +void +_Py_FinalizeAllocatedBlocks(_PyRuntimeState *Py_UNUSED(runtime)) +{ + return; +} + #endif /* WITH_PYMALLOC */ @@ -2535,13 +2123,13 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) return data; } -static void * +void * _PyMem_DebugRawMalloc(void *ctx, size_t nbytes) { return _PyMem_DebugRawAlloc(0, ctx, nbytes); } -static void * +void * _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) { size_t nbytes; @@ -2556,7 +2144,7 @@ _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) Then fills the original bytes with PYMEM_DEADBYTE. Then calls the underlying free. */ -static void +void _PyMem_DebugRawFree(void *ctx, void *p) { /* PyMem_Free(NULL) has no effect */ @@ -2576,7 +2164,7 @@ _PyMem_DebugRawFree(void *ctx, void *p) } -static void * +void * _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) { if (p == NULL) { @@ -2686,14 +2274,14 @@ _PyMem_DebugCheckGIL(const char *func) } } -static void * +void * _PyMem_DebugMalloc(void *ctx, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); return _PyMem_DebugRawMalloc(ctx, nbytes); } -static void * +void * _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) { _PyMem_DebugCheckGIL(__func__); @@ -2701,7 +2289,7 @@ _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) } -static void +void _PyMem_DebugFree(void *ctx, void *ptr) { _PyMem_DebugCheckGIL(__func__); @@ -2709,7 +2297,7 @@ _PyMem_DebugFree(void *ctx, void *ptr) } -static void * +void * _PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); @@ -2960,6 +2548,7 @@ _PyObject_DebugMallocStats(FILE *out) if (!_PyMem_PymallocEnabled()) { return 0; } + OMState *state = get_state(); uint i; const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT; @@ -2999,14 +2588,14 @@ _PyObject_DebugMallocStats(FILE *out) * will be living in full pools -- would be a shame to miss them. */ for (i = 0; i < maxarenas; ++i) { - uintptr_t base = arenas[i].address; + uintptr_t base = allarenas[i].address; /* Skip arenas which are not allocated. */ - if (arenas[i].address == (uintptr_t)NULL) + if (allarenas[i].address == (uintptr_t)NULL) continue; narenas += 1; - numfreepools += arenas[i].nfreepools; + numfreepools += allarenas[i].nfreepools; /* round up to pool alignment */ if (base & (uintptr_t)POOL_SIZE_MASK) { @@ -3016,8 +2605,8 @@ _PyObject_DebugMallocStats(FILE *out) } /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; const uint sz = p->szidx; uint freeblocks; @@ -3025,7 +2614,7 @@ _PyObject_DebugMallocStats(FILE *out) if (p->ref.count == 0) { /* currently unused */ #ifdef Py_DEBUG - assert(pool_is_in_list(p, arenas[i].freepools)); + assert(pool_is_in_list(p, allarenas[i].freepools)); #endif continue; } diff --git a/contrib/tools/python3/src/Objects/odictobject.c b/contrib/tools/python3/src/Objects/odictobject.c index bd2a7677fe1..39b0f684510 100644 --- a/contrib/tools/python3/src/Objects/odictobject.c +++ b/contrib/tools/python3/src/Objects/odictobject.c @@ -889,8 +889,7 @@ odict_inplace_or(PyObject *self, PyObject *other) if (mutablemapping_update_arg(self, other) < 0) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* tp_as_number */ @@ -1007,8 +1006,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, return NULL; assert(_odict_find_node(self, key) == NULL); if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } else { @@ -1024,8 +1022,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, result = PyObject_GetItem((PyObject *)self, key); } else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } @@ -1055,8 +1052,7 @@ _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, else if (value == NULL && !PyErr_Occurred()) { /* Apply the fallback value, if necessary. */ if (failobj) { - value = failobj; - Py_INCREF(failobj); + value = Py_NewRef(failobj); } else { PyErr_SetObject(PyExc_KeyError, key); @@ -1118,8 +1114,7 @@ OrderedDict_popitem_impl(PyODictObject *self, int last) } node = last ? _odict_LAST(self) : _odict_FIRST(self); - key = _odictnode_KEY(node); - Py_INCREF(key); + key = Py_NewRef(_odictnode_KEY(node)); value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; @@ -1372,7 +1367,7 @@ static PyObject * odict_repr(PyODictObject *self) { int i; - PyObject *pieces = NULL, *result = NULL; + PyObject *result = NULL, *dcopy = NULL; if (PyODict_SIZE(self) == 0) return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self))); @@ -1382,57 +1377,17 @@ odict_repr(PyODictObject *self) return i > 0 ? PyUnicode_FromString("...") : NULL; } - if (PyODict_CheckExact(self)) { - Py_ssize_t count = 0; - _ODictNode *node; - pieces = PyList_New(PyODict_SIZE(self)); - if (pieces == NULL) - goto Done; - - _odict_FOREACH(self, node) { - PyObject *pair; - PyObject *key = _odictnode_KEY(node); - PyObject *value = _odictnode_VALUE(node, self); - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); - goto Done; - } - pair = PyTuple_Pack(2, key, value); - if (pair == NULL) - goto Done; - - if (count < PyList_GET_SIZE(pieces)) - PyList_SET_ITEM(pieces, count, pair); /* steals reference */ - else { - if (PyList_Append(pieces, pair) < 0) { - Py_DECREF(pair); - goto Done; - } - Py_DECREF(pair); - } - count++; - } - if (count < PyList_GET_SIZE(pieces)) { - Py_SET_SIZE(pieces, count); - } - } - else { - PyObject *items = PyObject_CallMethodNoArgs( - (PyObject *)self, &_Py_ID(items)); - if (items == NULL) - goto Done; - pieces = PySequence_List(items); - Py_DECREF(items); - if (pieces == NULL) - goto Done; + dcopy = PyDict_Copy((PyObject *)self); + if (dcopy == NULL) { + goto Done; } result = PyUnicode_FromFormat("%s(%R)", - _PyType_Name(Py_TYPE(self)), pieces); + _PyType_Name(Py_TYPE(self)), + dcopy); + Py_DECREF(dcopy); Done: - Py_XDECREF(pieces); Py_ReprLeave((PyObject *)self); return result; } @@ -1497,8 +1452,7 @@ odict_richcompare(PyObject *v, PyObject *w, int op) return NULL; res = (eq == (op == Py_EQ)) ? Py_True : Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } else { Py_RETURN_NOTIMPLEMENTED; } @@ -1602,10 +1556,9 @@ _PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value, res = _odict_add_new_node((PyODictObject *)od, key, hash); if (res < 0) { /* Revert setting the value on the dict */ - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); (void) _PyDict_DelItem_KnownHash(od, key, hash); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); } } return res; @@ -1714,8 +1667,7 @@ odictiter_nextkey(odictiterobject *di) di->di_current = NULL; } else { - di->di_current = _odictnode_KEY(node); - Py_INCREF(di->di_current); + di->di_current = Py_NewRef(_odictnode_KEY(node)); } return key; @@ -1872,12 +1824,10 @@ odictiter_new(PyODictObject *od, int kind) di->kind = kind; node = reversed ? _odict_LAST(od) : _odict_FIRST(od); - di->di_current = node ? _odictnode_KEY(node) : NULL; - Py_XINCREF(di->di_current); + di->di_current = node ? Py_NewRef(_odictnode_KEY(node)) : NULL; di->di_size = PyODict_SIZE(od); di->di_state = od->od_state; - di->di_odict = od; - Py_INCREF(od); + di->di_odict = (PyODictObject*)Py_NewRef(od); _PyObject_GC_TRACK(di); return (PyObject *)di; diff --git a/contrib/tools/python3/src/Objects/rangeobject.c b/contrib/tools/python3/src/Objects/rangeobject.c index 5d583b2edf0..beb86b9623b 100644 --- a/contrib/tools/python3/src/Objects/rangeobject.c +++ b/contrib/tools/python3/src/Objects/rangeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_range.h" #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef @@ -32,7 +33,7 @@ validate_step(PyObject *step) return PyLong_FromLong(1); step = PyNumber_Index(step); - if (step && _PyLong_Sign(step) == 0) { + if (step && _PyLong_IsZero((PyLongObject *)step)) { PyErr_SetString(PyExc_ValueError, "range() arg 3 must not be zero"); Py_CLEAR(step); @@ -104,10 +105,8 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) if (!stop) { return NULL; } - start = _PyLong_GetZero(); - Py_INCREF(start); - step = _PyLong_GetOne(); - Py_INCREF(step); + start = Py_NewRef(_PyLong_GetZero()); + step = Py_NewRef(_PyLong_GetOne()); break; case 0: PyErr_SetString(PyExc_TypeError, @@ -172,6 +171,49 @@ range_dealloc(rangeobject *r) PyObject_Free(r); } +static unsigned long +get_len_of_range(long lo, long hi, long step); + +/* Return the length as a long, -2 for an overflow and -1 for any other type of error + * + * In case of an overflow no error is set + */ +static long compute_range_length_long(PyObject *start, + PyObject *stop, PyObject *step) { + int overflow = 0; + + long long_start = PyLong_AsLongAndOverflow(start, &overflow); + if (overflow) { + return -2; + } + if (long_start == -1 && PyErr_Occurred()) { + return -1; + } + long long_stop = PyLong_AsLongAndOverflow(stop, &overflow); + if (overflow) { + return -2; + } + if (long_stop == -1 && PyErr_Occurred()) { + return -1; + } + long long_step = PyLong_AsLongAndOverflow(step, &overflow); + if (overflow) { + return -2; + } + if (long_step == -1 && PyErr_Occurred()) { + return -1; + } + + unsigned long ulen = get_len_of_range(long_start, long_stop, long_step); + if (ulen > (unsigned long)LONG_MAX) { + /* length too large for a long */ + return -2; + } + else { + return (long)ulen; + } +} + /* Return number of items in range (lo, hi, step) as a PyLong object, * when arguments are PyLong objects. Arguments MUST return 1 with * PyLong_Check(). Return NULL when there is an error. @@ -192,6 +234,21 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) PyObject *zero = _PyLong_GetZero(); // borrowed reference PyObject *one = _PyLong_GetOne(); // borrowed reference + assert(PyLong_Check(start)); + assert(PyLong_Check(stop)); + assert(PyLong_Check(step)); + + /* fast path when all arguments fit into a long integer */ + long len = compute_range_length_long(start, stop, step); + if (len >= 0) { + return PyLong_FromLong(len); + } + else if (len == -1) { + /* unexpected error from compute_range_length_long, we propagate to the caller */ + return NULL; + } + assert(len == -2); + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); if (cmp_result == -1) return NULL; @@ -215,8 +272,7 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) if (cmp_result < 0) return NULL; result = zero; - Py_INCREF(result); - return result; + return Py_NewRef(result); } if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) @@ -296,8 +352,7 @@ compute_range_item(rangeobject *r, PyObject *arg) return NULL; } } else { - i = arg; - Py_INCREF(i); + i = Py_NewRef(arg); } /* PyLong equivalent to: @@ -521,30 +576,24 @@ range_hash(rangeobject *r) t = PyTuple_New(3); if (!t) return -1; - Py_INCREF(r->length); - PyTuple_SET_ITEM(t, 0, r->length); + PyTuple_SET_ITEM(t, 0, Py_NewRef(r->length)); cmp_result = PyObject_Not(r->length); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 1, Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 1, Py_NewRef(Py_None)); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->start); - PyTuple_SET_ITEM(t, 1, r->start); + PyTuple_SET_ITEM(t, 1, Py_NewRef(r->start)); cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->step); - PyTuple_SET_ITEM(t, 2, r->step); + PyTuple_SET_ITEM(t, 2, Py_NewRef(r->step)); } } result = PyObject_Hash(t); @@ -762,36 +811,29 @@ PyTypeObject PyRange_Type = { in the normal case, but possible for any numeric value. */ -typedef struct { - PyObject_HEAD - long index; - long start; - long step; - long len; -} rangeiterobject; - static PyObject * -rangeiter_next(rangeiterobject *r) +rangeiter_next(_PyRangeIterObject *r) { - if (r->index < r->len) - /* cast to unsigned to avoid possible signed overflow - in intermediate calculations. */ - return PyLong_FromLong((long)(r->start + - (unsigned long)(r->index++) * r->step)); + if (r->len > 0) { + long result = r->start; + r->start = result + r->step; + r->len--; + return PyLong_FromLong(result); + } return NULL; } static PyObject * -rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_len(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { - return PyLong_FromLong(r->len - r->index); + return PyLong_FromLong(r->len); } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_reduce(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { PyObject *start=NULL, *stop=NULL, *step=NULL; PyObject *range; @@ -811,8 +853,8 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) if (range == NULL) goto err; /* return the result */ - return Py_BuildValue( - "N(N)l", _PyEval_GetBuiltin(&_Py_ID(iter)), range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); err: Py_XDECREF(start); Py_XDECREF(stop); @@ -821,7 +863,7 @@ err: } static PyObject * -rangeiter_setstate(rangeiterobject *r, PyObject *state) +rangeiter_setstate(_PyRangeIterObject *r, PyObject *state) { long index = PyLong_AsLong(state); if (index == -1 && PyErr_Occurred()) @@ -831,7 +873,8 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) index = 0; else if (index > r->len) index = r->len; /* exhausted iterator */ - r->index = index; + r->start += index * r->step; + r->len -= index; Py_RETURN_NONE; } @@ -850,8 +893,8 @@ static PyMethodDef rangeiter_methods[] = { PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "range_iterator", /* tp_name */ - sizeof(rangeiterobject), /* tp_basicsize */ + "range_iterator", /* tp_name */ + sizeof(_PyRangeIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ @@ -915,19 +958,17 @@ get_len_of_range(long lo, long hi, long step) static PyObject * fast_range_iter(long start, long stop, long step, long len) { - rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + _PyRangeIterObject *it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type); if (it == NULL) return NULL; it->start = start; it->step = step; it->len = len; - it->index = 0; return (PyObject *)it; } typedef struct { PyObject_HEAD - PyObject *index; PyObject *start; PyObject *step; PyObject *len; @@ -936,7 +977,8 @@ typedef struct { static PyObject * longrangeiter_len(longrangeiterobject *r, PyObject *no_args) { - return PyNumber_Subtract(r->len, r->index); + Py_INCREF(r->len); + return r->len; } static PyObject * @@ -953,10 +995,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) Py_DECREF(product); if (stop == NULL) return NULL; - Py_INCREF(r->start); - Py_INCREF(r->step); range = (PyObject*)make_range_object(&PyRange_Type, - r->start, stop, r->step); + Py_NewRef(r->start), stop, Py_NewRef(r->step)); if (range == NULL) { Py_DECREF(r->start); Py_DECREF(stop); @@ -965,8 +1005,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) } /* return the result */ - return Py_BuildValue( - "N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); } static PyObject * @@ -989,8 +1029,22 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state) if (cmp > 0) state = r->len; } - Py_INCREF(state); - Py_XSETREF(r->index, state); + PyObject *product = PyNumber_Multiply(state, r->step); + if (product == NULL) + return NULL; + PyObject *new_start = PyNumber_Add(r->start, product); + Py_DECREF(product); + if (new_start == NULL) + return NULL; + PyObject *new_len = PyNumber_Subtract(r->len, state); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; + } + PyObject *tmp = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); + Py_DECREF(tmp); Py_RETURN_NONE; } @@ -1007,7 +1061,6 @@ static PyMethodDef longrangeiter_methods[] = { static void longrangeiter_dealloc(longrangeiterobject *r) { - Py_XDECREF(r->index); Py_XDECREF(r->start); Py_XDECREF(r->step); Py_XDECREF(r->len); @@ -1017,29 +1070,21 @@ longrangeiter_dealloc(longrangeiterobject *r) static PyObject * longrangeiter_next(longrangeiterobject *r) { - PyObject *product, *new_index, *result; - if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) + if (PyObject_RichCompareBool(r->len, _PyLong_GetZero(), Py_GT) != 1) return NULL; - new_index = PyNumber_Add(r->index, _PyLong_GetOne()); - if (!new_index) - return NULL; - - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(new_index); + PyObject *new_start = PyNumber_Add(r->start, r->step); + if (new_start == NULL) { return NULL; } - - result = PyNumber_Add(r->start, product); - Py_DECREF(product); - if (result) { - Py_SETREF(r->index, new_index); - } - else { - Py_DECREF(new_index); + PyObject *new_len = PyNumber_Subtract(r->len, _PyLong_GetOne()); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; } - + PyObject *result = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); return result; } @@ -1125,14 +1170,9 @@ range_iter(PyObject *seq) if (it == NULL) return NULL; - it->start = r->start; - it->step = r->step; - it->len = r->length; - it->index = _PyLong_GetZero(); - Py_INCREF(it->start); - Py_INCREF(it->step); - Py_INCREF(it->len); - Py_INCREF(it->index); + it->start = Py_NewRef(r->start); + it->step = Py_NewRef(r->step); + it->len = Py_NewRef(r->length); return (PyObject *)it; } @@ -1210,11 +1250,10 @@ long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; - it->index = it->start = it->step = NULL; + it->start = it->step = NULL; /* start + (len - 1) * step */ - it->len = range->length; - Py_INCREF(it->len); + it->len = Py_NewRef(range->length); diff = PyNumber_Subtract(it->len, _PyLong_GetOne()); if (!diff) @@ -1235,8 +1274,6 @@ long_range: if (!it->step) goto create_failure; - it->index = _PyLong_GetZero(); - Py_INCREF(it->index); return (PyObject *)it; create_failure: diff --git a/contrib/tools/python3/src/Objects/setobject.c b/contrib/tools/python3/src/Objects/setobject.c index 5fcc957f49c..763f9a3d204 100644 --- a/contrib/tools/python3/src/Objects/setobject.c +++ b/contrib/tools/python3/src/Objects/setobject.c @@ -588,8 +588,7 @@ set_merge(PySetObject *so, PyObject *otherset) key = other_entry->key; if (key != NULL) { assert(so_entry->key == NULL); - Py_INCREF(key); - so_entry->key = key; + so_entry->key = Py_NewRef(key); so_entry->hash = other_entry->hash; } } @@ -607,8 +606,8 @@ set_merge(PySetObject *so, PyObject *otherset) for (i = other->mask + 1; i > 0 ; i--, other_entry++) { key = other_entry->key; if (key != NULL && key != dummy) { - Py_INCREF(key); - set_insert_clean(newtable, newmask, key, other_entry->hash); + set_insert_clean(newtable, newmask, Py_NewRef(key), + other_entry->hash); } } return 0; @@ -820,8 +819,7 @@ static PyObject *setiter_iternext(setiterobject *si) goto fail; si->len--; key = entry[i].key; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: si->si_set = NULL; @@ -868,8 +866,7 @@ set_iter(PySetObject *so) setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type); if (si == NULL) return NULL; - Py_INCREF(so); - si->si_set = so; + si->si_set = (PySetObject*)Py_NewRef(so); si->si_used = so->used; si->si_pos = 0; si->len = so->used; @@ -997,8 +994,7 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) { /* frozenset(f) is idempotent */ - Py_INCREF(iterable); - return iterable; + return Py_NewRef(iterable); } return make_new_set(type, iterable); } @@ -1100,8 +1096,7 @@ static PyObject * frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) { if (PyFrozenSet_CheckExact(so)) { - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } return set_copy(so, NULL); } @@ -1173,8 +1168,7 @@ set_ior(PySetObject *so, PyObject *other) if (set_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1264,12 +1258,11 @@ static PyObject * set_intersection_multi(PySetObject *so, PyObject *args) { Py_ssize_t i; - PyObject *result = (PyObject *)so; if (PyTuple_GET_SIZE(args) == 0) return set_copy(so, NULL); - Py_INCREF(so); + PyObject *result = Py_NewRef(so); for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { PyObject *other = PyTuple_GET_ITEM(args, i); PyObject *newresult = set_intersection((PySetObject *)result, other); @@ -1277,8 +1270,7 @@ set_intersection_multi(PySetObject *so, PyObject *args) Py_DECREF(result); return NULL; } - Py_DECREF(result); - result = newresult; + Py_SETREF(result, newresult); } return result; } @@ -1336,8 +1328,7 @@ set_iand(PySetObject *so, PyObject *other) if (result == NULL) return NULL; Py_DECREF(result); - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1609,8 +1600,7 @@ set_isub(PySetObject *so, PyObject *other) Py_RETURN_NOTIMPLEMENTED; if (set_difference_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1647,8 +1637,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) } if (PyAnySet_Check(other)) { - Py_INCREF(other); - otherset = (PySetObject *)other; + otherset = (PySetObject *)Py_NewRef(other); } else { otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other); if (otherset == NULL) @@ -1723,8 +1712,7 @@ set_ixor(PySetObject *so, PyObject *other) if (result == NULL) return NULL; Py_DECREF(result); - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1735,13 +1723,13 @@ set_issubset(PySetObject *so, PyObject *other) int rv; if (!PyAnySet_Check(other)) { - PyObject *tmp, *result; - tmp = make_new_set(&PySet_Type, other); - if (tmp == NULL) + PyObject *tmp = set_intersection(so, other); + if (tmp == NULL) { return NULL; - result = set_issubset(so, tmp); + } + int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so)); Py_DECREF(tmp); - return result; + return PyBool_FromLong(result); } if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other)) Py_RETURN_FALSE; @@ -1977,12 +1965,11 @@ done: static PyObject * set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored)) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(so)); - if (so->table != so->smalltable) - res = res + (so->mask + 1) * sizeof(setentry); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(so)); + if (so->table != so->smalltable) { + res += ((size_t)so->mask + 1) * sizeof(setentry); + } + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes"); @@ -2564,6 +2551,7 @@ static PyTypeObject _PySetDummy_Type = { }; static PyObject _dummy_struct = { - _PyObject_EXTRA_INIT - 2, &_PySetDummy_Type + _PyObject_EXTRA_INIT + { _Py_IMMORTAL_REFCNT }, + &_PySetDummy_Type }; diff --git a/contrib/tools/python3/src/Objects/sliceobject.c b/contrib/tools/python3/src/Objects/sliceobject.c index 713829da574..e6776ac92b6 100644 --- a/contrib/tools/python3/src/Objects/sliceobject.c +++ b/contrib/tools/python3/src/Objects/sliceobject.c @@ -26,8 +26,17 @@ ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments"); return NULL; } - Py_INCREF(Py_Ellipsis); - return Py_Ellipsis; + return Py_NewRef(Py_Ellipsis); +} + +static void +ellipsis_dealloc(PyObject *ellipsis) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref Ellipsis out of existence. Instead, + * since Ellipsis is an immortal object, re-set the reference count. + */ + _Py_SetImmortal(ellipsis); } static PyObject * @@ -52,7 +61,7 @@ PyTypeObject PyEllipsis_Type = { "ellipsis", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ - 0, /*never called*/ /* tp_dealloc */ + ellipsis_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -90,7 +99,8 @@ PyTypeObject PyEllipsis_Type = { PyObject _Py_EllipsisObject = { _PyObject_EXTRA_INIT - 1, &PyEllipsis_Type + { _Py_IMMORTAL_REFCNT }, + &PyEllipsis_Type }; @@ -110,18 +120,10 @@ void _PySlice_Fini(PyInterpreterState *interp) index is present. */ -PyObject * -PySlice_New(PyObject *start, PyObject *stop, PyObject *step) +static PySliceObject * +_PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step) { - if (step == NULL) { - step = Py_None; - } - if (start == NULL) { - start = Py_None; - } - if (stop == NULL) { - stop = Py_None; - } + assert(start != NULL && stop != NULL && step != NULL); PyInterpreterState *interp = _PyInterpreterState_GET(); PySliceObject *obj; @@ -133,19 +135,43 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step) else { obj = PyObject_GC_New(PySliceObject, &PySlice_Type); if (obj == NULL) { - return NULL; + goto error; } } - Py_INCREF(step); - obj->step = step; - Py_INCREF(start); obj->start = start; - Py_INCREF(stop); obj->stop = stop; + obj->step = Py_NewRef(step); _PyObject_GC_TRACK(obj); - return (PyObject *) obj; + return obj; +error: + Py_DECREF(start); + Py_DECREF(stop); + return NULL; +} + +PyObject * +PySlice_New(PyObject *start, PyObject *stop, PyObject *step) +{ + if (step == NULL) { + step = Py_None; + } + if (start == NULL) { + start = Py_None; + } + if (stop == NULL) { + stop = Py_None; + } + return (PyObject *)_PyBuildSlice_Consume2(Py_NewRef(start), + Py_NewRef(stop), step); +} + +PyObject * +_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop) +{ + assert(start != NULL && stop != NULL); + return (PyObject *)_PyBuildSlice_Consume2(start, stop, Py_None); } PyObject * @@ -389,8 +415,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, /* Convert step to an integer; raise for zero step. */ if (self->step == Py_None) { - step = _PyLong_GetOne(); - Py_INCREF(step); + step = Py_NewRef(_PyLong_GetOne()); step_is_negative = 0; } else { @@ -418,27 +443,23 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, goto error; } else { - lower = _PyLong_GetZero(); - Py_INCREF(lower); - upper = length; - Py_INCREF(upper); + lower = Py_NewRef(_PyLong_GetZero()); + upper = Py_NewRef(length); } /* Compute start. */ if (self->start == Py_None) { - start = step_is_negative ? upper : lower; - Py_INCREF(start); + start = Py_NewRef(step_is_negative ? upper : lower); } else { start = evaluate_slice_index(self->start); if (start == NULL) goto error; - if (_PyLong_Sign(start) < 0) { + if (_PyLong_IsNegative((PyLongObject *)start)) { /* start += length */ PyObject *tmp = PyNumber_Add(start, length); - Py_DECREF(start); - start = tmp; + Py_SETREF(start, tmp); if (start == NULL) goto error; @@ -446,9 +467,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(start); - start = lower; + Py_SETREF(start, Py_NewRef(lower)); } } else { @@ -456,28 +475,24 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(start); - start = upper; + Py_SETREF(start, Py_NewRef(upper)); } } } /* Compute stop. */ if (self->stop == Py_None) { - stop = step_is_negative ? lower : upper; - Py_INCREF(stop); + stop = Py_NewRef(step_is_negative ? lower : upper); } else { stop = evaluate_slice_index(self->stop); if (stop == NULL) goto error; - if (_PyLong_Sign(stop) < 0) { + if (_PyLong_IsNegative((PyLongObject *)stop)) { /* stop += length */ PyObject *tmp = PyNumber_Add(stop, length); - Py_DECREF(stop); - stop = tmp; + Py_SETREF(stop, tmp); if (stop == NULL) goto error; @@ -485,9 +500,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(stop); - stop = lower; + Py_SETREF(stop, Py_NewRef(lower)); } } else { @@ -495,9 +508,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(stop); - stop = upper; + Py_SETREF(stop, Py_NewRef(upper)); } } } @@ -533,7 +544,7 @@ slice_indices(PySliceObject* self, PyObject* len) if (length == NULL) return NULL; - if (_PyLong_Sign(length) < 0) { + if (_PyLong_IsNegative((PyLongObject *)length)) { PyErr_SetString(PyExc_ValueError, "length should not be negative"); Py_DECREF(length); @@ -592,8 +603,7 @@ slice_richcompare(PyObject *v, PyObject *w, int op) res = Py_False; break; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } @@ -629,6 +639,42 @@ slice_traverse(PySliceObject *v, visitproc visit, void *arg) return 0; } +/* code based on tuplehash() of Objects/tupleobject.c */ +#if SIZEOF_PY_UHASH_T > 4 +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) +#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ +#else +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL) +#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ +#endif + +static Py_hash_t +slicehash(PySliceObject *v) +{ + Py_uhash_t acc = _PyHASH_XXPRIME_5; +#define _PyHASH_SLICE_PART(com) { \ + Py_uhash_t lane = PyObject_Hash(v->com); \ + if(lane == (Py_uhash_t)-1) { \ + return -1; \ + } \ + acc += lane * _PyHASH_XXPRIME_2; \ + acc = _PyHASH_XXROTATE(acc); \ + acc *= _PyHASH_XXPRIME_1; \ +} + _PyHASH_SLICE_PART(start); + _PyHASH_SLICE_PART(stop); + _PyHASH_SLICE_PART(step); +#undef _PyHASH_SLICE_PART + if(acc == (Py_uhash_t)-1) { + return 1546275796; + } + return acc; +} + PyTypeObject PySlice_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "slice", /* Name of this type */ @@ -643,7 +689,7 @@ PyTypeObject PySlice_Type = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ + (hashfunc)slicehash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/contrib/tools/python3/src/Objects/stringlib/asciilib.h b/contrib/tools/python3/src/Objects/stringlib/asciilib.h index eebe888e411..b3016bfbbb0 100644 --- a/contrib/tools/python3/src/Objects/stringlib/asciilib.h +++ b/contrib/tools/python3/src/Objects/stringlib/asciilib.h @@ -21,6 +21,7 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h b/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h index b88517bd364..49388cf043c 100644 --- a/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h +++ b/contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" "--\n" @@ -20,8 +26,31 @@ static PyObject * stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -249,4 +278,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=46d058103bffedf7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d44a269805f6739e input=a9049054013a1b77]*/ diff --git a/contrib/tools/python3/src/Objects/stringlib/count.h b/contrib/tools/python3/src/Objects/stringlib/count.h index f48500bf561..e20edcd104b 100644 --- a/contrib/tools/python3/src/Objects/stringlib/count.h +++ b/contrib/tools/python3/src/Objects/stringlib/count.h @@ -4,6 +4,11 @@ #error must include "stringlib/fastsearch.h" before including this module #endif +// gh-97982: Implementing asciilib_count() is not worth it, FASTSEARCH() does +// not specialize the code for ASCII strings. Use ucs1lib_count() for ASCII and +// UCS1 strings: it's the same than asciilib_count(). +#if !STRINGLIB_IS_UNICODE || STRINGLIB_MAX_CHAR > 0x7Fu + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, @@ -24,4 +29,4 @@ STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, return count; } - +#endif diff --git a/contrib/tools/python3/src/Objects/stringlib/eq.h b/contrib/tools/python3/src/Objects/stringlib/eq.h index 9c1058b86cb..2eac4baf5ca 100644 --- a/contrib/tools/python3/src/Objects/stringlib/eq.h +++ b/contrib/tools/python3/src/Objects/stringlib/eq.h @@ -4,16 +4,8 @@ * unicode_eq() is called when the hash of two unicode objects is equal. */ Py_LOCAL_INLINE(int) -unicode_eq(PyObject *aa, PyObject *bb) +unicode_eq(PyObject *a, PyObject *b) { - assert(PyUnicode_Check(aa)); - assert(PyUnicode_Check(bb)); - assert(PyUnicode_IS_READY(aa)); - assert(PyUnicode_IS_READY(bb)); - - PyUnicodeObject *a = (PyUnicodeObject *)aa; - PyUnicodeObject *b = (PyUnicodeObject *)bb; - if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b)) return 0; if (PyUnicode_GET_LENGTH(a) == 0) diff --git a/contrib/tools/python3/src/Objects/stringlib/fastsearch.h b/contrib/tools/python3/src/Objects/stringlib/fastsearch.h index 7403d8a3f70..257b7bd6788 100644 --- a/contrib/tools/python3/src/Objects/stringlib/fastsearch.h +++ b/contrib/tools/python3/src/Objects/stringlib/fastsearch.h @@ -18,7 +18,8 @@ algorithm, which has worst-case O(n) runtime and best-case O(n/k). Also compute a table of shifts to achieve O(n/k) in more cases, and often (data dependent) deduce larger shifts than pure C&P can - deduce. */ + deduce. See stringlib_find_two_way_notes.txt in this folder for a + detailed explanation. */ #define FAST_COUNT 0 #define FAST_SEARCH 1 @@ -39,7 +40,7 @@ #define STRINGLIB_BLOOM(mask, ch) \ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR # define MEMCHR_CUT_OFF 15 #else # define MEMCHR_CUT_OFF 40 @@ -53,8 +54,8 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) p = s; e = s + n; if (n > MEMCHR_CUT_OFF) { -#if STRINGLIB_SIZEOF_CHAR == 1 - p = memchr(s, ch, n); +#ifdef STRINGLIB_FAST_MEMCHR + p = STRINGLIB_FAST_MEMCHR(s, ch, n); if (p != NULL) return (p - s); return -1; @@ -102,16 +103,26 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } +#undef MEMCHR_CUT_OFF + +#if STRINGLIB_SIZEOF_CHAR == 1 +# define MEMRCHR_CUT_OFF 15 +#else +# define MEMRCHR_CUT_OFF 40 +#endif + + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) { const STRINGLIB_CHAR *p; #ifdef HAVE_MEMRCHR - /* memrchr() is a GNU extension, available since glibc 2.1.91. - it doesn't seem as optimized as memchr(), but is still quite - faster than our hand-written loop below */ + /* memrchr() is a GNU extension, available since glibc 2.1.91. it + doesn't seem as optimized as memchr(), but is still quite + faster than our hand-written loop below. There is no wmemrchr + for 4-byte chars. */ - if (n > MEMCHR_CUT_OFF) { + if (n > MEMRCHR_CUT_OFF) { #if STRINGLIB_SIZEOF_CHAR == 1 p = memrchr(s, ch, n); if (p != NULL) @@ -139,11 +150,11 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) if (*p == ch) return n; /* False positive */ - if (n1 - n > MEMCHR_CUT_OFF) + if (n1 - n > MEMRCHR_CUT_OFF) continue; - if (n <= MEMCHR_CUT_OFF) + if (n <= MEMRCHR_CUT_OFF) break; - s1 = p - MEMCHR_CUT_OFF; + s1 = p - MEMRCHR_CUT_OFF; while (p > s1) { p--; if (*p == ch) @@ -151,7 +162,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) } n = p - s; } - while (n > MEMCHR_CUT_OFF); + while (n > MEMRCHR_CUT_OFF); } #endif } @@ -165,7 +176,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } -#undef MEMCHR_CUT_OFF +#undef MEMRCHR_CUT_OFF /* Change to a 1 to see logging comments walk through the algorithm. */ #if 0 && STRINGLIB_SIZEOF_CHAR == 1 @@ -388,7 +399,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } no_shift: window = window_last - len_needle + 1; @@ -447,7 +458,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } window = window_last - len_needle + 1; assert((window[len_needle - 1] & TABLE_MASK) == diff --git a/contrib/tools/python3/src/Objects/stringlib/join.h b/contrib/tools/python3/src/Objects/stringlib/join.h index bb011f7db79..de6bd83ffe4 100644 --- a/contrib/tools/python3/src/Objects/stringlib/join.h +++ b/contrib/tools/python3/src/Objects/stringlib/join.h @@ -63,8 +63,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) item = PySequence_Fast_GET_ITEM(seq, i); if (PyBytes_CheckExact(item)) { /* Fast path. */ - Py_INCREF(item); - buffers[i].obj = item; + buffers[i].obj = Py_NewRef(item); buffers[i].buf = PyBytes_AS_STRING(item); buffers[i].len = PyBytes_GET_SIZE(item); } diff --git a/contrib/tools/python3/src/Objects/stringlib/localeutil.h b/contrib/tools/python3/src/Objects/stringlib/localeutil.h index bd16e0a1728..d77715ec0de 100644 --- a/contrib/tools/python3/src/Objects/stringlib/localeutil.h +++ b/contrib/tools/python3/src/Objects/stringlib/localeutil.h @@ -75,7 +75,7 @@ InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, if (n_zeros) { *buffer_pos -= n_zeros; - enum PyUnicode_Kind kind = PyUnicode_KIND(writer->buffer); + int kind = PyUnicode_KIND(writer->buffer); void *data = PyUnicode_DATA(writer->buffer); unicode_fill(kind, data, '0', *buffer_pos, n_zeros); } diff --git a/contrib/tools/python3/src/Objects/stringlib/replace.h b/contrib/tools/python3/src/Objects/stringlib/replace.h index ef318ed6dd5..123c9f850f5 100644 --- a/contrib/tools/python3/src/Objects/stringlib/replace.h +++ b/contrib/tools/python3/src/Objects/stringlib/replace.h @@ -29,9 +29,9 @@ STRINGLIB(replace_1char_inplace)(STRINGLIB_CHAR* s, STRINGLIB_CHAR* end, if (!--attempts) { /* if u1 was not found for attempts iterations, use FASTSEARCH() or memchr() */ -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR s++; - s = memchr(s, u1, end - s); + s = STRINGLIB_FAST_MEMCHR(s, u1, end - s); if (s == NULL) return; #else diff --git a/contrib/tools/python3/src/Objects/stringlib/stringdefs.h b/contrib/tools/python3/src/Objects/stringlib/stringdefs.h index 88641b25d47..484b98b7291 100644 --- a/contrib/tools/python3/src/Objects/stringlib/stringdefs.h +++ b/contrib/tools/python3/src/Objects/stringlib/stringdefs.h @@ -24,4 +24,5 @@ #define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_Repr +#define STRINGLIB_FAST_MEMCHR memchr #endif /* !STRINGLIB_STRINGDEFS_H */ diff --git a/contrib/tools/python3/src/Objects/stringlib/transmogrify.h b/contrib/tools/python3/src/Objects/stringlib/transmogrify.h index e1165ea38e8..71099bb586e 100644 --- a/contrib/tools/python3/src/Objects/stringlib/transmogrify.h +++ b/contrib/tools/python3/src/Objects/stringlib/transmogrify.h @@ -17,8 +17,7 @@ return_self(PyObject *self) { #if !STRINGLIB_MUTABLE if (STRINGLIB_CHECK_EXACT(self)) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } #endif return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h index 026ab11f1f7..1b9b65ecbaa 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs1lib.h @@ -20,6 +20,7 @@ #define STRINGLIB_NEW _PyUnicode_FromUCS1 #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_MUTABLE 0 #define STRINGLIB_TOSTR PyObject_Str diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h index 75f11bc2905..4b49bbb31d7 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs2lib.h @@ -21,6 +21,10 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 2 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS2 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h b/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h index 57344f235b6..def4ca5d17d 100644 --- a/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h +++ b/contrib/tools/python3/src/Objects/stringlib/ucs4lib.h @@ -21,6 +21,10 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 4 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS4 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/contrib/tools/python3/src/Objects/stringlib/undef.h b/contrib/tools/python3/src/Objects/stringlib/undef.h index bf32298505e..cc873a2ec4e 100644 --- a/contrib/tools/python3/src/Objects/stringlib/undef.h +++ b/contrib/tools/python3/src/Objects/stringlib/undef.h @@ -8,3 +8,4 @@ #undef STRINGLIB_NEW #undef STRINGLIB_IS_UNICODE #undef STRINGLIB_MUTABLE +#undef STRINGLIB_FAST_MEMCHR diff --git a/contrib/tools/python3/src/Objects/stringlib/unicode_format.h b/contrib/tools/python3/src/Objects/stringlib/unicode_format.h index a4eea7b9198..ccd7c77c0a0 100644 --- a/contrib/tools/python3/src/Objects/stringlib/unicode_format.h +++ b/contrib/tools/python3/src/Objects/stringlib/unicode_format.h @@ -473,8 +473,7 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, goto error; /* assign to obj */ - Py_DECREF(obj); - obj = tmp; + Py_SETREF(obj, tmp); } /* end of iterator, this is the non-error case */ if (ok == 1) @@ -825,8 +824,7 @@ output_markup(SubString *field_name, SubString *format_spec, goto done; /* do the assignment, transferring ownership: fieldobj = tmp */ - Py_DECREF(fieldobj); - fieldobj = tmp; + Py_SETREF(fieldobj, tmp); tmp = NULL; } @@ -1042,8 +1040,7 @@ formatteriter_next(formatteriterobject *it) otherwise create a one length string with the conversion character */ if (conversion == '\0') { - conversion_str = Py_None; - Py_INCREF(conversion_str); + conversion_str = Py_NewRef(Py_None); } else conversion_str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, @@ -1121,8 +1118,7 @@ formatter_parser(PyObject *ignored, PyObject *self) return NULL; /* take ownership, give the object to the iterator */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* initialize the contained MarkupIterator */ MarkupIterator_init(&it->it_markup, (PyObject*)self, 0, PyUnicode_GET_LENGTH(self)); @@ -1265,8 +1261,7 @@ formatter_field_name_split(PyObject *ignored, PyObject *self) /* take ownership, give the object to the iterator. this is just to keep the field_name alive */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* Pass in auto_number = NULL. We'll return an empty string for first_obj in that case. */ diff --git a/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h b/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h deleted file mode 100644 index ba2ce0aeea1..00000000000 --- a/contrib/tools/python3/src/Objects/stringlib/unicodedefs.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef STRINGLIB_UNICODEDEFS_H -#define STRINGLIB_UNICODEDEFS_H - -/* this is sort of a hack. there's at least one place (formatting - floats) where some stringlib code takes a different path if it's - compiled as unicode. */ -#define STRINGLIB_IS_UNICODE 1 - -#define FASTSEARCH fastsearch -#define STRINGLIB(F) stringlib_##F -#define STRINGLIB_OBJECT PyUnicodeObject -#define STRINGLIB_SIZEOF_CHAR Py_UNICODE_SIZE -#define STRINGLIB_CHAR Py_UNICODE -#define STRINGLIB_TYPE_NAME "unicode" -#define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE -#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK -#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL -#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL -#define STRINGLIB_STR PyUnicode_AS_UNICODE -#define STRINGLIB_LEN PyUnicode_GET_SIZE -#define STRINGLIB_NEW PyUnicode_FromUnicode -#define STRINGLIB_CHECK PyUnicode_Check -#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_MUTABLE 0 - -#define STRINGLIB_TOSTR PyObject_Str -#define STRINGLIB_TOASCII PyObject_ASCII - -#define STRINGLIB_WANT_CONTAINS_OBJ 1 - -#endif /* !STRINGLIB_UNICODEDEFS_H */ diff --git a/contrib/tools/python3/src/Objects/structseq.c b/contrib/tools/python3/src/Objects/structseq.c index 229e3d893ff..8b189595710 100644 --- a/contrib/tools/python3/src/Objects/structseq.c +++ b/contrib/tools/python3/src/Objects/structseq.c @@ -26,11 +26,12 @@ const char * const PyStructSequence_UnnamedField = "unnamed field"; static Py_ssize_t get_type_attr_as_size(PyTypeObject *tp, PyObject *name) { - PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name); + PyObject *v = PyDict_GetItemWithError(_PyType_GetDict(tp), name); if (v == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "Missed attribute '%U' of type %s", name, tp->tp_name); + return -1; } return PyLong_AsSsize_t(v); } @@ -200,8 +201,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } for (i = 0; i < len; ++i) { PyObject *v = PySequence_Fast_GET_ITEM(arg, i); - Py_INCREF(v); - res->ob_item[i] = v; + res->ob_item[i] = Py_NewRef(v); } Py_DECREF(arg); for (; i < max_len; ++i) { @@ -219,8 +219,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) ob = Py_None; } } - Py_INCREF(ob); - res->ob_item[i] = ob; + res->ob_item[i] = Py_NewRef(ob); } _PyObject_GC_TRACK(res); @@ -432,11 +431,19 @@ error: return -1; } -static void -initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, - Py_ssize_t n_members) { - Py_ssize_t i, k; +static PyMemberDef * +initialize_members(PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) +{ + PyMemberDef *members; + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return NULL; + } + + Py_ssize_t i, k; for (i = k = 0; i < n_members; ++i) { if (desc->fields[i].name == PyStructSequence_UnnamedField) { continue; @@ -453,30 +460,15 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, k++; } members[k].name = NULL; + + return members; } -int -_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, - unsigned long tp_flags) +static void +initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc, + PyMemberDef *tp_members, unsigned long tp_flags) { - PyMemberDef *members; - Py_ssize_t n_members, n_unnamed_members; - -#ifdef Py_TRACE_REFS - /* if the type object was chained, unchain it first - before overwriting its storage */ - if (type->ob_base.ob_base._ob_next) { - _Py_ForgetReference((PyObject *)type); - } -#endif - - /* PyTypeObject has already been initialized */ - if (Py_REFCNT(type) != 0) { - PyErr_BadInternalCall(); - return -1; - } - type->tp_name = desc->name; type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); type->tp_itemsize = sizeof(PyObject *); @@ -488,25 +480,20 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, type->tp_new = structseq_new; type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = (traverseproc) structseq_traverse; + type->tp_members = tp_members; +} - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); - if (members == NULL) { - PyErr_NoMemory(); - return -1; - } - initialize_members(desc, members, n_members); - type->tp_members = members; - +static int +initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { + /* initialize_static_fields() should have been called already. */ if (PyType_Ready(type) < 0) { - PyMem_Free(members); return -1; } Py_INCREF(type); if (initialize_structseq_dict( - desc, type->tp_dict, n_members, n_unnamed_members) < 0) { - PyMem_Free(members); + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) { Py_DECREF(type); return -1; } @@ -515,9 +502,92 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, } int +_PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, + PyTypeObject *type, + PyStructSequence_Desc *desc, + unsigned long tp_flags) +{ + Py_ssize_t n_unnamed_members; + Py_ssize_t n_members = count_members(desc, &n_unnamed_members); + PyMemberDef *members = NULL; + + if ((type->tp_flags & Py_TPFLAGS_READY) == 0) { + assert(type->tp_name == NULL); + assert(type->tp_members == NULL); + assert(type->tp_base == NULL); + + members = initialize_members(desc, n_members, n_unnamed_members); + if (members == NULL) { + goto error; + } + initialize_static_fields(type, desc, members, tp_flags); + + _Py_SetImmortal(type); + } +#ifndef NDEBUG + else { + // Ensure that the type was initialized. + assert(type->tp_name != NULL); + assert(type->tp_members != NULL); + assert(type->tp_base == &PyTuple_Type); + assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_Py_IsImmortal(type)); + } +#endif + + if (_PyStaticType_InitBuiltin(interp, type) < 0) { + PyErr_Format(PyExc_RuntimeError, + "Can't initialize builtin type %s", + desc->name); + goto error; + } + + if (initialize_structseq_dict( + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) + { + goto error; + } + + return 0; + +error: + if (members != NULL) { + PyMem_Free(members); + } + return -1; +} + +int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { - return _PyStructSequence_InitType(type, desc, 0); + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + +#ifdef Py_TRACE_REFS + /* if the type object was chained, unchain it first + before overwriting its storage */ + if (type->ob_base.ob_base._ob_next) { + _Py_ForgetReference((PyObject *)type); + } +#endif + + /* PyTypeObject has already been initialized */ + if (Py_REFCNT(type) != 0) { + PyErr_BadInternalCall(); + return -1; + } + + n_members = count_members(desc, &n_unnamed_members); + members = initialize_members(desc, n_members, n_unnamed_members); + if (members == NULL) { + return -1; + } + initialize_static_fields(type, desc, members, 0); + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + PyMem_Free(members); + return -1; + } + return 0; } void @@ -527,35 +597,34 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) } +/* This is exposed in the internal API, not the public API. + It is only called on builtin static types, which are all + initialized via _PyStructSequence_InitBuiltinWithFlags(). */ + void -_PyStructSequence_FiniType(PyTypeObject *type) +_PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type) { // Ensure that the type is initialized assert(type->tp_name != NULL); assert(type->tp_base == &PyTuple_Type); + assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_Py_IsImmortal(type)); // Cannot delete a type if it still has subclasses - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { + // XXX Shouldn't this be an error? return; } - // Undo PyStructSequence_NewType() - type->tp_name = NULL; - PyMem_Free(type->tp_members); - - _PyStaticType_Dealloc(type); - assert(Py_REFCNT(type) == 1); - // Undo Py_INCREF(type) of _PyStructSequence_InitType(). - // Don't use Py_DECREF(): static type must not be deallocated - Py_SET_REFCNT(type, 0); -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif + _PyStaticType_Dealloc(interp, type); - // Make sure that _PyStructSequence_InitType() will initialize - // the type again - assert(Py_REFCNT(type) == 0); - assert(type->tp_name == NULL); + if (_Py_IsMainInterpreter(interp)) { + // Undo _PyStructSequence_InitBuiltinWithFlags(). + type->tp_name = NULL; + PyMem_Free(type->tp_members); + type->tp_members = NULL; + type->tp_base = NULL; + } } @@ -570,12 +639,10 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) /* Initialize MemberDefs */ n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + members = initialize_members(desc, n_members, n_unnamed_members); if (members == NULL) { - PyErr_NoMemory(); return NULL; } - initialize_members(desc, members, n_members); /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; @@ -603,7 +670,7 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) } if (initialize_structseq_dict( - desc, type->tp_dict, n_members, n_unnamed_members) < 0) { + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) { Py_DECREF(type); return NULL; } diff --git a/contrib/tools/python3/src/Objects/tupleobject.c b/contrib/tools/python3/src/Objects/tupleobject.c index 1e82a5b674e..991edcc8667 100644 --- a/contrib/tools/python3/src/Objects/tupleobject.c +++ b/contrib/tools/python3/src/Objects/tupleobject.c @@ -61,8 +61,7 @@ tuple_alloc(Py_ssize_t size) static inline PyObject * tuple_get_empty(void) { - Py_INCREF(&_Py_SINGLETON(tuple_empty)); - return (PyObject *)&_Py_SINGLETON(tuple_empty); + return Py_NewRef(&_Py_SINGLETON(tuple_empty)); } PyObject * @@ -171,8 +170,7 @@ PyTuple_Pack(Py_ssize_t n, ...) items = result->ob_item; for (i = 0; i < n; i++) { o = va_arg(vargs, PyObject *); - Py_INCREF(o); - items[i] = o; + items[i] = Py_NewRef(o); } va_end(vargs); _PyObject_GC_TRACK(result); @@ -290,7 +288,7 @@ error: /* Hash for tuples. This is a slightly simplified version of the xxHash non-cryptographic hash: - - we do not use any parallellism, there is only 1 accumulator. + - we do not use any parallelism, there is only 1 accumulator. - we drop the final mixing since this is just a permutation of the output space: it does not help against collisions. - at the end, we mangle the length with a single constant. @@ -367,8 +365,7 @@ tupleitem(PyTupleObject *a, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "tuple index out of range"); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } PyObject * @@ -385,8 +382,7 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) PyObject **dst = tuple->ob_item; for (Py_ssize_t i = 0; i < n; i++) { PyObject *item = src[i]; - Py_INCREF(item); - dst[i] = item; + dst[i] = Py_NewRef(item); } _PyObject_GC_TRACK(tuple); return (PyObject *)tuple; @@ -425,8 +421,7 @@ tupleslice(PyTupleObject *a, Py_ssize_t ilow, if (ihigh < ilow) ihigh = ilow; if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } return _PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow); } @@ -449,8 +444,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyObject **src, **dest; PyTupleObject *np; if (Py_SIZE(a) == 0 && PyTuple_CheckExact(bb)) { - Py_INCREF(bb); - return bb; + return Py_NewRef(bb); } if (!PyTuple_Check(bb)) { PyErr_Format(PyExc_TypeError, @@ -461,8 +455,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyTupleObject *b = (PyTupleObject *)bb; if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); @@ -478,15 +471,13 @@ tupleconcat(PyTupleObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } _PyObject_GC_TRACK(np); return (PyObject *)np; @@ -495,52 +486,46 @@ tupleconcat(PyTupleObject *a, PyObject *bb) static PyObject * tuplerepeat(PyTupleObject *a, Py_ssize_t n) { - Py_ssize_t size; - PyTupleObject *np; - if (Py_SIZE(a) == 0 || n == 1) { + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n == 1) { if (PyTuple_CheckExact(a)) { /* Since tuples are immutable, we can return a shared copy in this case */ - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } } - if (Py_SIZE(a) == 0 || n <= 0) { + if (input_size == 0 || n <= 0) { return tuple_get_empty(); } - if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) + assert(n>0); + + if (input_size > PY_SSIZE_T_MAX / n) return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - np = tuple_alloc(size); + Py_ssize_t output_size = input_size * n; + + PyTupleObject *np = tuple_alloc(output_size); if (np == NULL) return NULL; + PyObject **dest = np->ob_item; - PyObject **dest_end = dest + size; - if (Py_SIZE(a) == 1) { + if (input_size == 1) { PyObject *elem = a->ob_item[0]; - Py_SET_REFCNT(elem, Py_REFCNT(elem) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; while (dest < dest_end) { *dest++ = elem; } } else { PyObject **src = a->ob_item; - PyObject **src_end = src + Py_SIZE(a); + PyObject **src_end = src + input_size; while (src < src_end) { - Py_SET_REFCNT(*src, Py_REFCNT(*src) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif - *dest++ = *src++; - } - // Now src chases after dest in the same buffer - src = np->ob_item; - while (dest < dest_end) { + _Py_RefcntAdd(*src, n); *dest++ = *src++; } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); } _PyObject_GC_TRACK(np); return (PyObject *) np; @@ -752,8 +737,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable) } for (i = 0; i < n; i++) { item = PyTuple_GET_ITEM(tmp, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newobj, i, item); + PyTuple_SET_ITEM(newobj, i, Py_NewRef(item)); } Py_DECREF(tmp); @@ -804,8 +788,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyTuple_GET_SIZE(self) && PyTuple_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyTupleObject* result = tuple_alloc(slicelength); @@ -815,8 +798,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) dest = result->ob_item; for (cur = start, i = 0; i < slicelength; cur += step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } @@ -948,10 +930,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) return *pv == NULL ? -1 : 0; } - /* XXX UNREF/NEWREF interface should be more symmetrical */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif if (_PyObject_GC_IS_TRACKED(v)) { _PyObject_GC_UNTRACK(v); } @@ -965,10 +943,13 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { *pv = NULL; +#ifdef Py_REF_DEBUG + _Py_DecRefTotal(_PyInterpreterState_GET()); +#endif PyObject_GC_Del(v); return -1; } - _Py_NewReference((PyObject *) sv); + _Py_NewReferenceNoTotal((PyObject *) sv); /* Zero out items added by growing */ if (newsize > oldsize) memset(&sv->ob_item[oldsize], 0, @@ -979,24 +960,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } -PyStatus -_PyTuple_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyTuple_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple type"); - } - - if (PyType_Ready(&PyTupleIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple iterator type"); - } - - return _PyStatus_OK(); -} - static void maybe_freelist_clear(PyInterpreterState *, int); void @@ -1013,14 +976,9 @@ _PyTuple_ClearFreeList(PyInterpreterState *interp) /*********************** Tuple Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ -} tupleiterobject; static void -tupleiter_dealloc(tupleiterobject *it) +tupleiter_dealloc(_PyTupleIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -1028,14 +986,14 @@ tupleiter_dealloc(tupleiterobject *it) } static int -tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg) +tupleiter_traverse(_PyTupleIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -tupleiter_next(tupleiterobject *it) +tupleiter_next(_PyTupleIterObject *it) { PyTupleObject *seq; PyObject *item; @@ -1049,8 +1007,7 @@ tupleiter_next(tupleiterobject *it) if (it->it_index < PyTuple_GET_SIZE(seq)) { item = PyTuple_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -1059,7 +1016,7 @@ tupleiter_next(tupleiterobject *it) } static PyObject * -tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_len(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -1070,7 +1027,7 @@ tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_reduce(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); @@ -1085,7 +1042,7 @@ tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) } static PyObject * -tupleiter_setstate(tupleiterobject *it, PyObject *state) +tupleiter_setstate(_PyTupleIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -1113,7 +1070,7 @@ static PyMethodDef tupleiter_methods[] = { PyTypeObject PyTupleIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "tuple_iterator", /* tp_name */ - sizeof(tupleiterobject), /* tp_basicsize */ + sizeof(_PyTupleIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)tupleiter_dealloc, /* tp_dealloc */ @@ -1146,18 +1103,17 @@ PyTypeObject PyTupleIter_Type = { static PyObject * tuple_iter(PyObject *seq) { - tupleiterobject *it; + _PyTupleIterObject *it; if (!PyTuple_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); + it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyTupleObject *)seq; + it->it_seq = (PyTupleObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/contrib/tools/python3/src/Objects/typeobject.c b/contrib/tools/python3/src/Objects/typeobject.c index 983adee8731..8aa07d85281 100644 --- a/contrib/tools/python3/src/Objects/typeobject.c +++ b/contrib/tools/python3/src/Objects/typeobject.c @@ -3,10 +3,13 @@ #include "Python.h" #include "pycore_call.h" #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_initconfig.h" // _PyStatus_OK() +#include "pycore_memoryobject.h" // _PyMemoryView_FromBufferProc() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_object.h" // _PyType_HasFeature() +#include "pycore_long.h" // _PyLong_IsNegative() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_typeobject.h" // struct type_cache @@ -16,6 +19,7 @@ #include "structmember.h" // PyMemberDef #include <ctype.h> +#include <stddef.h> // ptrdiff_t /*[clinic input] class type "PyTypeObject *" "&PyType_Type" @@ -43,28 +47,432 @@ class object "PyObject *" "&PyBaseObject_Type" PyUnicode_IS_READY(name) && \ (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) -// bpo-42745: next_version_tag remains shared by all interpreters because of static types -// Used to set PyTypeObject.tp_version_tag -static unsigned int next_version_tag = 1; +#define NEXT_GLOBAL_VERSION_TAG _PyRuntime.types.next_version_tag +#define NEXT_VERSION_TAG(interp) \ + (interp)->types.next_version_tag typedef struct PySlot_Offset { short subslot_offset; short slot_offset; } PySlot_Offset; +static void +slot_bf_releasebuffer(PyObject *self, Py_buffer *buffer); + +static void +releasebuffer_call_python(PyObject *self, Py_buffer *buffer); static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static void -clear_slotdefs(void); - static PyObject * lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound); static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value); + +static inline PyTypeObject * +type_from_ref(PyObject *ref) +{ + assert(PyWeakref_CheckRef(ref)); + PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref + assert(obj != NULL); + if (obj == Py_None) { + return NULL; + } + assert(PyType_Check(obj)); + return _PyType_CAST(obj); +} + + +/* helpers for for static builtin types */ + +static inline int +static_builtin_index_is_set(PyTypeObject *self) +{ + return self->tp_subclasses != NULL; +} + +static inline size_t +static_builtin_index_get(PyTypeObject *self) +{ + assert(static_builtin_index_is_set(self)); + /* We store a 1-based index so 0 can mean "not initialized". */ + return (size_t)self->tp_subclasses - 1; +} + +static inline void +static_builtin_index_set(PyTypeObject *self, size_t index) +{ + assert(index < _Py_MAX_STATIC_BUILTIN_TYPES); + /* We store a 1-based index so 0 can mean "not initialized". */ + self->tp_subclasses = (PyObject *)(index + 1); +} + +static inline void +static_builtin_index_clear(PyTypeObject *self) +{ + self->tp_subclasses = NULL; +} + +static inline static_builtin_state * +static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self) +{ + return &(interp->types.builtins[static_builtin_index_get(self)]); +} + +/* For static types we store some state in an array on each interpreter. */ +static_builtin_state * +_PyStaticType_GetState(PyInterpreterState *interp, PyTypeObject *self) +{ + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + return static_builtin_state_get(interp, self); +} + +/* Set the type's per-interpreter state. */ +static void +static_builtin_state_init(PyInterpreterState *interp, PyTypeObject *self) +{ + if (!static_builtin_index_is_set(self)) { + static_builtin_index_set(self, interp->types.num_builtins_initialized); + } + static_builtin_state *state = static_builtin_state_get(interp, self); + + /* It should only be called once for each builtin type. */ + assert(state->type == NULL); + state->type = self; + + /* state->tp_subclasses is left NULL until init_subclasses() sets it. */ + /* state->tp_weaklist is left NULL until insert_head() or insert_after() + (in weakrefobject.c) sets it. */ + + interp->types.num_builtins_initialized++; +} + +/* Reset the type's per-interpreter state. + This basically undoes what static_builtin_state_init() did. */ +static void +static_builtin_state_clear(PyInterpreterState *interp, PyTypeObject *self) +{ + static_builtin_state *state = static_builtin_state_get(interp, self); + + assert(state->type != NULL); + state->type = NULL; + assert(state->tp_weaklist == NULL); // It was already cleared out. + + if (_Py_IsMainInterpreter(interp)) { + static_builtin_index_clear(self); + } + + assert(interp->types.num_builtins_initialized > 0); + interp->types.num_builtins_initialized--; +} + +// Also see _PyStaticType_InitBuiltin() and _PyStaticType_Dealloc(). + +/* end static builtin helpers */ + + +static inline void +start_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + assert(!state->readying); + state->readying = 1; + return; + } + assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); + type->tp_flags |= Py_TPFLAGS_READYING; +} + +static inline void +stop_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + assert(state->readying); + state->readying = 0; + return; + } + assert(type->tp_flags & Py_TPFLAGS_READYING); + type->tp_flags &= ~Py_TPFLAGS_READYING; +} + +static inline int +is_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + return state->readying; + } + return (type->tp_flags & Py_TPFLAGS_READYING) != 0; +} + + +/* accessors for objects stored on PyTypeObject */ + +static inline PyObject * +lookup_tp_dict(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + return state->tp_dict; + } + return self->tp_dict; +} + +PyObject * +_PyType_GetDict(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_dict(self); +} + +PyObject * +PyType_GetDict(PyTypeObject *self) +{ + PyObject *dict = lookup_tp_dict(self); + return _Py_XNewRef(dict); +} + +static inline void +set_tp_dict(PyTypeObject *self, PyObject *dict) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + state->tp_dict = dict; + return; + } + self->tp_dict = dict; +} + +static inline void +clear_tp_dict(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + Py_CLEAR(state->tp_dict); + return; + } + Py_CLEAR(self->tp_dict); +} + + +static inline PyObject * +lookup_tp_bases(PyTypeObject *self) +{ + return self->tp_bases; +} + +PyObject * +_PyType_GetBases(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_bases(self); +} + +static inline void +set_tp_bases(PyTypeObject *self, PyObject *bases) +{ + assert(PyTuple_CheckExact(bases)); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + // XXX tp_bases can probably be statically allocated for each + // static builtin type. + assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + assert(self->tp_bases == NULL); + if (PyTuple_GET_SIZE(bases) == 0) { + assert(self->tp_base == NULL); + } + else { + assert(PyTuple_GET_SIZE(bases) == 1); + assert(PyTuple_GET_ITEM(bases, 0) == (PyObject *)self->tp_base); + assert(self->tp_base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_Py_IsImmortal(self->tp_base)); + } + _Py_SetImmortal(bases); + } + self->tp_bases = bases; +} + +static inline void +clear_tp_bases(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + if (self->tp_bases != NULL) { + if (PyTuple_GET_SIZE(self->tp_bases) == 0) { + Py_CLEAR(self->tp_bases); + } + else { + assert(_Py_IsImmortal(self->tp_bases)); + _Py_ClearImmortal(self->tp_bases); + } + } + } + return; + } + Py_CLEAR(self->tp_bases); +} + + +static inline PyObject * +lookup_tp_mro(PyTypeObject *self) +{ + return self->tp_mro; +} + +PyObject * +_PyType_GetMRO(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_mro(self); +} + +static inline void +set_tp_mro(PyTypeObject *self, PyObject *mro) +{ + assert(PyTuple_CheckExact(mro)); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + // XXX tp_mro can probably be statically allocated for each + // static builtin type. + assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + assert(self->tp_mro == NULL); + /* Other checks are done via set_tp_bases. */ + _Py_SetImmortal(mro); + } + self->tp_mro = mro; +} + +static inline void +clear_tp_mro(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + if (self->tp_mro != NULL) { + if (PyTuple_GET_SIZE(self->tp_mro) == 0) { + Py_CLEAR(self->tp_mro); + } + else { + assert(_Py_IsImmortal(self->tp_mro)); + _Py_ClearImmortal(self->tp_mro); + } + } + } + return; + } + Py_CLEAR(self->tp_mro); +} + + +static PyObject * +init_tp_subclasses(PyTypeObject *self) +{ + PyObject *subclasses = PyDict_New(); + if (subclasses == NULL) { + return NULL; + } + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + state->tp_subclasses = subclasses; + return subclasses; + } + self->tp_subclasses = (void *)subclasses; + return subclasses; +} + +static void +clear_tp_subclasses(PyTypeObject *self) +{ + /* Delete the dictionary to save memory. _PyStaticType_Dealloc() + callers also test if tp_subclasses is NULL to check if a static type + has no subclass. */ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + Py_CLEAR(state->tp_subclasses); + return; + } + Py_CLEAR(self->tp_subclasses); +} + +static inline PyObject * +lookup_tp_subclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + return state->tp_subclasses; + } + return (PyObject *)self->tp_subclasses; +} + +int +_PyType_HasSubclasses(PyTypeObject *self) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN + // XXX _PyStaticType_GetState() should never return NULL. + && _PyStaticType_GetState(interp, self) == NULL) + { + return 0; + } + if (lookup_tp_subclasses(self) == NULL) { + return 0; + } + return 1; +} + +PyObject* +_PyType_GetSubclasses(PyTypeObject *self) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + PyObject *subclasses = lookup_tp_subclasses(self); // borrowed ref + if (subclasses == NULL) { + return list; + } + assert(PyDict_CheckExact(subclasses)); + // The loop cannot modify tp_subclasses, there is no need + // to hold a strong reference (use a borrowed reference). + + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, NULL, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + + if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) { + Py_DECREF(list); + return NULL; + } + } + return list; +} + +/* end accessors for objects stored on PyTypeObject */ + + /* * finds the beginning of the docstring's introspection signature. * if present, returns a pointer pointing to the first '('. @@ -134,8 +542,8 @@ _PyType_CheckConsistency(PyTypeObject *type) CHECK(Py_REFCNT(type) >= 1); CHECK(PyType_Check(type)); - CHECK(!(type->tp_flags & Py_TPFLAGS_READYING)); - CHECK(type->tp_dict != NULL); + CHECK(!is_readying(type)); + CHECK(lookup_tp_dict(type) != NULL); if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { // bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set. @@ -145,7 +553,7 @@ _PyType_CheckConsistency(PyTypeObject *type) if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) { CHECK(type->tp_new == NULL); - CHECK(PyDict_Contains(type->tp_dict, &_Py_ID(__new__)) == 0); + CHECK(PyDict_Contains(lookup_tp_dict(type), &_Py_ID(__new__)) == 0); } return 1; @@ -204,7 +612,7 @@ static struct type_cache* get_type_cache(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->type_cache; + return &interp->types.type_cache; } @@ -223,7 +631,7 @@ type_cache_clear(struct type_cache *cache, PyObject *value) void _PyType_InitCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; for (Py_ssize_t i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { struct type_cache_entry *entry = &cache->hashtable[i]; assert(entry->name == NULL); @@ -231,7 +639,7 @@ _PyType_InitCache(PyInterpreterState *interp) entry->version = 0; // Set to None so _PyType_Lookup() can use Py_SETREF(), // rather than using slower Py_XSETREF(). - entry->name = Py_NewRef(Py_None); + entry->name = Py_None; entry->value = NULL; } } @@ -240,24 +648,12 @@ _PyType_InitCache(PyInterpreterState *interp) static unsigned int _PyType_ClearCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; -#if MCACHE_STATS - size_t total = cache->hits + cache->collisions + cache->misses; - fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", - cache->hits, (int) (100.0 * cache->hits / total)); - fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", - cache->misses, (int) (100.0 * cache->misses / total)); - fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", - cache->collisions, (int) (100.0 * cache->collisions / total)); - fprintf(stderr, "-- Method cache size = %zd KiB\n", - sizeof(cache->hashtable) / 1024); -#endif - + struct type_cache *cache = &interp->types.type_cache; // Set to None, rather than NULL, so _PyType_Lookup() can // use Py_SETREF() rather than using slower Py_XSETREF(). type_cache_clear(cache, Py_None); - return next_version_tag - 1; + return NEXT_VERSION_TAG(interp) - 1; } @@ -272,13 +668,93 @@ PyType_ClearCache(void) void _PyTypes_Fini(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; type_cache_clear(cache, NULL); - if (_Py_IsMainInterpreter(interp)) { - clear_slotdefs(); + + assert(interp->types.num_builtins_initialized == 0); + // All the static builtin types should have been finalized already. + for (size_t i = 0; i < _Py_MAX_STATIC_BUILTIN_TYPES; i++) { + assert(interp->types.builtins[i].type == NULL); + } +} + + +int +PyType_AddWatcher(PyType_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < TYPE_MAX_WATCHERS; i++) { + if (!interp->type_watchers[i]) { + interp->type_watchers[i] = callback; + return i; + } } + + PyErr_SetString(PyExc_RuntimeError, "no more type watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= TYPE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid type watcher ID %d", watcher_id); + return -1; + } + if (!interp->type_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No type watcher set for ID %d", watcher_id); + return -1; + } + return 0; } +int +PyType_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->type_watchers[watcher_id] = NULL; + return 0; +} + +static int assign_version_tag(PyInterpreterState *interp, PyTypeObject *type); + +int +PyType_Watch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + // ensure we will get a callback on the next modification + assign_version_tag(interp, type); + type->tp_watched |= (1 << watcher_id); + return 0; +} + +int +PyType_Unwatch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + type->tp_watched &= ~(1 << watcher_id); + return 0; +} void PyType_Modified(PyTypeObject *type) @@ -302,24 +778,46 @@ PyType_Modified(PyTypeObject *type) return; } - PyObject *subclasses = type->tp_subclasses; + PyObject *subclasses = lookup_tp_subclasses(type); if (subclasses != NULL) { assert(PyDict_CheckExact(subclasses)); Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); - if (obj == Py_None) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { continue; } - PyType_Modified(_PyType_CAST(obj)); + PyType_Modified(subclass); + } + } + + // Notify registered type watchers, if any + if (type->tp_watched) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int bits = type->tp_watched; + int i = 0; + while (bits) { + assert(i < TYPE_MAX_WATCHERS); + if (bits & 1) { + PyType_WatchCallback cb = interp->type_watchers[i]; + if (cb && (cb(type) < 0)) { + PyErr_WriteUnraisable((PyObject *)type); + } + } + i++; + bits >>= 1; } } type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ + if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { + // This field *must* be invalidated if the type is modified (see the + // comment on struct _specialization_cache): + ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + } } static void @@ -370,13 +868,20 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } } return; + clear: + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ + if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { + // This field *must* be invalidated if the type is modified (see the + // comment on struct _specialization_cache): + ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + } } static int -assign_version_tag(struct type_cache *cache, PyTypeObject *type) +assign_version_tag(PyInterpreterState *interp, PyTypeObject *type) { /* Ensure that the tp_version_tag is valid and set Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this @@ -390,35 +895,54 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type) return 0; } - if (next_version_tag == 0) { - /* We have run out of version numbers */ - return 0; + if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + /* static types */ + if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) { + /* We have run out of version numbers */ + return 0; + } + type->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++; + assert (type->tp_version_tag <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); + } + else { + /* heap types */ + if (NEXT_VERSION_TAG(interp) == 0) { + /* We have run out of version numbers */ + return 0; + } + type->tp_version_tag = NEXT_VERSION_TAG(interp)++; + assert (type->tp_version_tag != 0); } - type->tp_version_tag = next_version_tag++; - assert (type->tp_version_tag != 0); - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t n = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); - if (!assign_version_tag(cache, _PyType_CAST(b))) + if (!assign_version_tag(interp, _PyType_CAST(b))) return 0; } type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; return 1; } +int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return assign_version_tag(interp, type); +} + static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + /* Note that this value is misleading for static builtin types, + since the memory at this offset will always be NULL. */ {"__weakrefoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, {"__dictoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_dictoffset), READONLY}, - {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY}, {0} }; @@ -466,8 +990,7 @@ type_name(PyTypeObject *type, void *context) if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_name); - return et->ht_name; + return Py_NewRef(et->ht_name); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -479,8 +1002,7 @@ type_qualname(PyTypeObject *type, void *context) { if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_qualname); - return et->ht_qualname; + return Py_NewRef(et->ht_qualname); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -512,8 +1034,7 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) } type->tp_name = tp_name; - Py_INCREF(value); - Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value); + Py_SETREF(((PyHeapTypeObject*)type)->ht_name, Py_NewRef(value)); return 0; } @@ -533,8 +1054,7 @@ type_set_qualname(PyTypeObject *type, PyObject *value, void *context) } et = (PyHeapTypeObject*)type; - Py_INCREF(value); - Py_SETREF(et->ht_qualname, value); + Py_SETREF(et->ht_qualname, Py_NewRef(value)); return 0; } @@ -544,7 +1064,8 @@ type_module(PyTypeObject *type, void *context) PyObject *mod; if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { - mod = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__module__)); + PyObject *dict = lookup_tp_dict(type); + mod = PyDict_GetItemWithError(dict, &_Py_ID(__module__)); if (mod == NULL) { if (!PyErr_Occurred()) { PyErr_Format(PyExc_AttributeError, "__module__"); @@ -562,8 +1083,7 @@ type_module(PyTypeObject *type, void *context) PyUnicode_InternInPlace(&mod); } else { - mod = &_Py_ID(builtins); - Py_INCREF(mod); + mod = Py_NewRef(&_Py_ID(builtins)); } } return mod; @@ -577,7 +1097,8 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context) PyType_Modified(type); - return PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), value); + PyObject *dict = lookup_tp_dict(type); + return PyDict_SetItem(dict, &_Py_ID(__module__), value); } static PyObject * @@ -586,17 +1107,17 @@ type_abstractmethods(PyTypeObject *type, void *context) PyObject *mod = NULL; /* type itself has an __abstractmethods__ descriptor (this). Don't return that. */ - if (type != &PyType_Type) - mod = PyDict_GetItemWithError(type->tp_dict, - &_Py_ID(__abstractmethods__)); + if (type != &PyType_Type) { + PyObject *dict = lookup_tp_dict(type); + mod = PyDict_GetItemWithError(dict, &_Py_ID(__abstractmethods__)); + } if (!mod) { if (!PyErr_Occurred()) { PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); } return NULL; } - Py_INCREF(mod); - return mod; + return Py_NewRef(mod); } static int @@ -607,15 +1128,16 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) special to update subclasses. */ int abstract, res; + PyObject *dict = lookup_tp_dict(type); if (value != NULL) { abstract = PyObject_IsTrue(value); if (abstract < 0) return -1; - res = PyDict_SetItem(type->tp_dict, &_Py_ID(__abstractmethods__), value); + res = PyDict_SetItem(dict, &_Py_ID(__abstractmethods__), value); } else { abstract = 0; - res = PyDict_DelItem(type->tp_dict, &_Py_ID(__abstractmethods__)); + res = PyDict_DelItem(dict, &_Py_ID(__abstractmethods__)); if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); return -1; @@ -634,8 +1156,21 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) static PyObject * type_get_bases(PyTypeObject *type, void *context) { - Py_INCREF(type->tp_bases); - return type->tp_bases; + PyObject *bases = lookup_tp_bases(type); + if (bases == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(bases); +} + +static PyObject * +type_get_mro(PyTypeObject *type, void *context) +{ + PyObject *mro = lookup_tp_mro(type); + if (mro == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(mro); } static PyTypeObject *best_base(PyObject *); @@ -663,7 +1198,7 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) /* error / reentrance */ return res; } - PyObject *new_mro = type->tp_mro; + PyObject *new_mro = lookup_tp_mro(type); PyObject *tuple; if (old_mro != NULL) { @@ -682,14 +1217,14 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) Py_XDECREF(tuple); if (res < 0) { - type->tp_mro = old_mro; + set_tp_mro(type, old_mro); Py_DECREF(new_mro); return -1; } Py_XDECREF(old_mro); // Avoid creating an empty list if there is no subclass - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { /* Obtain a copy of subclasses list to iterate over. Otherwise type->tp_subclasses might be altered @@ -761,7 +1296,8 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) below), which in turn may cause an inheritance cycle through tp_base chain. And this is definitely not what you want to ever happen. */ - (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) + (lookup_tp_mro(base) != NULL + && type_is_subtype_base_chain(base, type))) { PyErr_SetString(PyExc_TypeError, "a __bases__ item causes an inheritance cycle"); @@ -778,11 +1314,11 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) return -1; } - PyObject *old_bases = type->tp_bases; + PyObject *old_bases = lookup_tp_bases(type); assert(old_bases != NULL); PyTypeObject *old_base = type->tp_base; - type->tp_bases = Py_NewRef(new_bases); + set_tp_bases(type, Py_NewRef(new_bases)); type->tp_base = (PyTypeObject *)Py_NewRef(new_base); PyObject *temp = PyList_New(0); @@ -797,7 +1333,7 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) /* Take no action in case if type->tp_bases has been replaced through reentrance. */ int res; - if (type->tp_bases == new_bases) { + if (lookup_tp_bases(type) == new_bases) { /* any base that was in __bases__ but now isn't, we need to remove |type| from its tp_subclasses. conversely, any class now in __bases__ that wasn't @@ -828,19 +1364,18 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), "", 2, 3, &cls, &new_mro, &old_mro); /* Do not rollback if cls has a newer version of MRO. */ - if (cls->tp_mro == new_mro) { - Py_XINCREF(old_mro); - cls->tp_mro = old_mro; + if (lookup_tp_mro(cls) == new_mro) { + set_tp_mro(cls, Py_XNewRef(old_mro)); Py_DECREF(new_mro); } } Py_DECREF(temp); bail: - if (type->tp_bases == new_bases) { + if (lookup_tp_bases(type) == new_bases) { assert(type->tp_base == new_base); - type->tp_bases = old_bases; + set_tp_bases(type, old_bases); type->tp_base = old_base; Py_DECREF(new_bases); @@ -858,10 +1393,11 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) static PyObject * type_dict(PyTypeObject *type, void *context) { - if (type->tp_dict == NULL) { + PyObject *dict = lookup_tp_dict(type); + if (dict == NULL) { Py_RETURN_NONE; } - return PyDictProxy_New(type->tp_dict); + return PyDictProxy_New(dict); } static PyObject * @@ -871,11 +1407,11 @@ type_get_doc(PyTypeObject *type, void *context) if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); } - result = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + result = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); if (result == NULL) { if (!PyErr_Occurred()) { - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); } } else if (Py_TYPE(result)->tp_descr_get) { @@ -900,7 +1436,8 @@ type_set_doc(PyTypeObject *type, PyObject *value, void *context) if (!check_set_special_type_attr(type, value, "__doc__")) return -1; PyType_Modified(type); - return PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), value); + PyObject *dict = lookup_tp_dict(type); + return PyDict_SetItem(dict, &_Py_ID(__doc__), value); } static PyObject * @@ -912,7 +1449,8 @@ type_get_annotations(PyTypeObject *type, void *context) } PyObject *annotations; - annotations = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__annotations__)); + PyObject *dict = lookup_tp_dict(type); + annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); if (annotations) { if (Py_TYPE(annotations)->tp_descr_get) { annotations = Py_TYPE(annotations)->tp_descr_get( @@ -925,7 +1463,7 @@ type_get_annotations(PyTypeObject *type, void *context) annotations = PyDict_New(); if (annotations) { int result = PyDict_SetItem( - type->tp_dict, &_Py_ID(__annotations__), annotations); + dict, &_Py_ID(__annotations__), annotations); if (result) { Py_CLEAR(annotations); } else { @@ -947,12 +1485,13 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) } int result; + PyObject *dict = lookup_tp_dict(type); if (value != NULL) { /* set */ - result = PyDict_SetItem(type->tp_dict, &_Py_ID(__annotations__), value); + result = PyDict_SetItem(dict, &_Py_ID(__annotations__), value); } else { /* delete */ - result = PyDict_DelItem(type->tp_dict, &_Py_ID(__annotations__)); + result = PyDict_DelItem(dict, &_Py_ID(__annotations__)); if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_SetString(PyExc_AttributeError, "__annotations__"); } @@ -964,6 +1503,37 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) return result; } +static PyObject * +type_get_type_params(PyTypeObject *type, void *context) +{ + PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__)); + + if (params) { + return Py_NewRef(params); + } + if (PyErr_Occurred()) { + return NULL; + } + + return PyTuple_New(0); +} + +static int +type_set_type_params(PyTypeObject *type, PyObject *value, void *context) +{ + if (!check_set_special_type_attr(type, value, "__type_params__")) { + return -1; + } + + PyObject *dict = lookup_tp_dict(type); + int result = PyDict_SetItem(dict, &_Py_ID(__type_params__), value); + + if (result == 0) { + PyType_Modified(type); + } + return result; +} + /*[clinic input] type.__instancecheck__ -> bool @@ -1002,6 +1572,7 @@ static PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, (setter)type_set_name, NULL}, {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL}, {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL}, + {"__mro__", (getter)type_get_mro, NULL, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__abstractmethods__", (getter)type_abstractmethods, (setter)type_set_abstractmethods, NULL}, @@ -1009,6 +1580,7 @@ static PyGetSetDef type_getsets[] = { {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, {"__text_signature__", (getter)type_get_text_signature, NULL, NULL}, {"__annotations__", (getter)type_get_annotations, (setter)type_set_annotations, NULL}, + {"__type_params__", (getter)type_get_type_params, (setter)type_set_type_params, NULL}, {0} }; @@ -1027,8 +1599,7 @@ type_repr(PyTypeObject *type) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { @@ -1068,8 +1639,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) if (nargs == 1 && (kwds == NULL || !PyDict_GET_SIZE(kwds))) { obj = (PyObject *) Py_TYPE(PyTuple_GET_ITEM(args, 0)); - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* SF bug 475327 -- if that didn't trigger, we need 3 @@ -1103,8 +1673,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) int res = type->tp_init(obj, args, kwds); if (res < 0) { assert(_PyErr_Occurred(tstate)); - Py_DECREF(obj); - obj = NULL; + Py_SETREF(obj, NULL); } else { assert(!_PyErr_Occurred(tstate)); @@ -1117,8 +1686,13 @@ PyObject * _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) { PyObject *obj; + /* The +1 on nitems is needed for most types but not all. We could save a + * bit of space by allocating one less item in certain cases, depending on + * the type. However, given the extra complexity (e.g. an additional type + * flag to indicate when that is safe) it does not seem worth the memory + * savings. An example type that doesn't need the +1 is a subclass of + * tuple. See GH-100659 and GH-81381. */ const size_t size = _PyObject_VAR_SIZE(type, nitems+1); - /* note that we need to add one, for the sentinel */ const size_t presize = _PyType_PreHeaderSize(type); char *alloc = PyObject_Malloc(size + presize); @@ -1164,6 +1738,12 @@ PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) /* Helpers for subtyping */ +static inline PyMemberDef * +_PyHeapType_GET_MEMBERS(PyHeapTypeObject* type) +{ + return PyObject_GetItemData((PyObject *)type); +} + static int traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) { @@ -1206,18 +1786,21 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) assert(base); } - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - assert(type->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); - if (err) { - return err; - } - } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); - if (dictptr && *dictptr) - Py_VISIT(*dictptr); + assert(base->tp_dictoffset == 0); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + assert(type->tp_dictoffset == -1); + int err = _PyObject_VisitManagedDict(self, visit, arg); + if (err) { + return err; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); + if (dictptr && *dictptr) { + Py_VISIT(*dictptr); + } + } } if (type->tp_flags & Py_TPFLAGS_HEAPTYPE @@ -1276,10 +1859,12 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - _PyObject_ClearInstanceAttributes(self); + if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + _PyObject_ClearManagedDict(self); + } } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr && *dictptr) Py_CLEAR(*dictptr); } @@ -1404,11 +1989,15 @@ subtype_dealloc(PyObject *self) finalizers since they might rely on part of the object being finalized that has already been destroyed. */ if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { - /* Modeled after GET_WEAKREFS_LISTPTR() */ - PyWeakReference **list = (PyWeakReference **) \ - _PyObject_GET_WEAKREFS_LISTPTR(self); - while (*list) + /* Modeled after GET_WEAKREFS_LISTPTR(). + + This is never triggered for static types so we can avoid the + (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). */ + PyWeakReference **list = \ + _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(self); + while (*list) { _PyWeakref_ClearRef(*list); + } } } @@ -1423,18 +2012,17 @@ subtype_dealloc(PyObject *self) /* If we added a dict, DECREF it, or free inline values. */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyObject **dictptr = _PyObject_ManagedDictPointer(self); - if (*dictptr != NULL) { - assert(*_PyObject_ValuesPointer(self) == NULL); - Py_DECREF(*dictptr); - *dictptr = NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + _PyObject_FreeInstanceAttributes(self); } else { - _PyObject_FreeInstanceAttributes(self); + Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr)); } + dorv_ptr->values = NULL; } else if (type->tp_dictoffset && !base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict != NULL) { @@ -1532,7 +2120,7 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) { PyObject *mro; - mro = a->tp_mro; + mro = lookup_tp_mro(a); if (mro != NULL) { /* Deal with multiple inheritance without recursion by walking the MRO tuple */ @@ -1638,6 +2226,7 @@ vectorcall_unbound(PyThreadState *tstate, int unbound, PyObject *func, args++; nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_SLOT, func); return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } @@ -1915,17 +2504,17 @@ mro_implementation(PyTypeObject *type) return NULL; } - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t n = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); - if (base->tp_mro == NULL) { + if (lookup_tp_mro(base) == NULL) { PyErr_Format(PyExc_TypeError, "Cannot extend an incomplete type '%.100s'", base->tp_name); return NULL; } - assert(PyTuple_Check(base->tp_mro)); + assert(PyTuple_Check(lookup_tp_mro(base))); } if (n == 1) { @@ -1933,18 +2522,18 @@ mro_implementation(PyTypeObject *type) * is trivial. */ PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, 0)); - Py_ssize_t k = PyTuple_GET_SIZE(base->tp_mro); + PyObject *base_mro = lookup_tp_mro(base); + Py_ssize_t k = PyTuple_GET_SIZE(base_mro); PyObject *result = PyTuple_New(k + 1); if (result == NULL) { return NULL; } - Py_INCREF(type); - PyTuple_SET_ITEM(result, 0, (PyObject *) type); + ; + PyTuple_SET_ITEM(result, 0, Py_NewRef(type)); for (Py_ssize_t i = 0; i < k; i++) { - PyObject *cls = PyTuple_GET_ITEM(base->tp_mro, i); - Py_INCREF(cls); - PyTuple_SET_ITEM(result, i + 1, cls); + PyObject *cls = PyTuple_GET_ITEM(base_mro, i); + PyTuple_SET_ITEM(result, i + 1, Py_NewRef(cls)); } return result; } @@ -1970,7 +2559,7 @@ mro_implementation(PyTypeObject *type) for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); - to_merge[i] = base->tp_mro; + to_merge[i] = lookup_tp_mro(base); } to_merge[n] = bases; @@ -1980,8 +2569,7 @@ mro_implementation(PyTypeObject *type) return NULL; } - Py_INCREF(type); - PyList_SET_ITEM(result, 0, (PyObject *)type); + PyList_SET_ITEM(result, 0, Py_NewRef(type)); if (pmerge(result, to_merge, n + 1) < 0) { Py_CLEAR(result); } @@ -2126,10 +2714,9 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) /* Keep a reference to be able to do a reentrancy check below. Don't let old_mro be GC'ed and its address be reused for another object, like (suddenly!) a new tp_mro. */ - old_mro = type->tp_mro; - Py_XINCREF(old_mro); + old_mro = Py_XNewRef(lookup_tp_mro(type)); new_mro = mro_invoke(type); /* might cause reentrance */ - reent = (type->tp_mro != old_mro); + reent = (lookup_tp_mro(type) != old_mro); Py_XDECREF(old_mro); if (new_mro == NULL) { return -1; @@ -2140,14 +2727,22 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) return 0; } - type->tp_mro = new_mro; + set_tp_mro(type, new_mro); - type_mro_modified(type, type->tp_mro); + type_mro_modified(type, new_mro); /* corner case: the super class might have been hidden from the custom MRO */ - type_mro_modified(type, type->tp_bases); + type_mro_modified(type, lookup_tp_bases(type)); - PyType_Modified(type); + // XXX Expand this to Py_TPFLAGS_IMMUTABLETYPE? + if (!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)) { + PyType_Modified(type); + } + else { + /* For static builtin types, this is only called during init + before the method cache has been populated. */ + assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + } if (p_old_mro != NULL) *p_old_mro = old_mro; /* transfer the ownership */ @@ -2215,36 +2810,13 @@ best_base(PyObject *bases) return base; } -#define ADDED_FIELD_AT_OFFSET(name, offset) \ - (type->tp_ ## name && (base->tp_ ##name == 0) && \ - type->tp_ ## name + sizeof(PyObject *) == (offset) && \ - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - static int -extra_ivars(PyTypeObject *type, PyTypeObject *base) +shape_differs(PyTypeObject *t1, PyTypeObject *t2) { - size_t t_size = type->tp_basicsize; - size_t b_size = base->tp_basicsize; - - assert(t_size >= b_size); /* Else type smaller than base! */ - if (type->tp_itemsize || base->tp_itemsize) { - /* If itemsize is involved, stricter rules */ - return t_size != b_size || - type->tp_itemsize != base->tp_itemsize; - } - /* Check for __dict__ and __weakrefs__ slots in either order */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 && - ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - /* Check __weakrefs__ again, in case it precedes __dict__ */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - return t_size != b_size; + return ( + t1->tp_basicsize != t2->tp_basicsize || + t1->tp_itemsize != t2->tp_itemsize + ); } static PyTypeObject * @@ -2252,14 +2824,18 @@ solid_base(PyTypeObject *type) { PyTypeObject *base; - if (type->tp_base) + if (type->tp_base) { base = solid_base(type->tp_base); - else + } + else { base = &PyBaseObject_Type; - if (extra_ivars(type, base)) + } + if (shape_differs(type, base)) { return type; - else + } + else { return base; + } } static void object_dealloc(PyObject *); @@ -2364,8 +2940,7 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_XINCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_XNewRef(value)); return 0; } @@ -2382,17 +2957,17 @@ subtype_getweakref(PyObject *obj, void *context) return NULL; } _PyObject_ASSERT((PyObject *)type, - type->tp_weaklistoffset > 0); + type->tp_weaklistoffset > 0 || + type->tp_weaklistoffset == MANAGED_WEAKREF_OFFSET); _PyObject_ASSERT((PyObject *)type, - ((type->tp_weaklistoffset + sizeof(PyObject *)) - <= (size_t)(type->tp_basicsize))); + ((type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject *)) + <= type->tp_basicsize)); weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset); if (*weaklistptr == NULL) result = Py_None; else result = *weaklistptr; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* Three variants on the subtype_getsets list. */ @@ -2554,8 +3129,7 @@ type_new_visit_slots(type_new_ctx *ctx) if (!ctx->may_add_weak || ctx->add_weak != 0) { PyErr_SetString(PyExc_TypeError, "__weakref__ slot disallowed: " - "either we already got one, " - "or __itemsize__ != 0"); + "we already got one"); return -1; } ctx->add_weak++; @@ -2601,11 +3175,12 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict) goto error; } if (r > 0) { - /* CPython inserts __qualname__ and __classcell__ (when needed) + /* CPython inserts these names (when needed) into the namespace when creating a class. They will be deleted below so won't act as class variables. */ if (!_PyUnicode_Equal(slot, &_Py_ID(__qualname__)) && - !_PyUnicode_Equal(slot, &_Py_ID(__classcell__))) + !_PyUnicode_Equal(slot, &_Py_ID(__classcell__)) && + !_PyUnicode_Equal(slot, &_Py_ID(__classdictcell__))) { PyErr_Format(PyExc_ValueError, "%R in __slots__ conflicts with class variable", @@ -2760,7 +3335,7 @@ type_new_alloc(type_new_ctx *ctx) type->tp_as_mapping = &et->as_mapping; type->tp_as_buffer = &et->as_buffer; - type->tp_bases = Py_NewRef(ctx->bases); + set_tp_bases(type, Py_NewRef(ctx->bases)); type->tp_base = (PyTypeObject *)Py_NewRef(ctx->base); type->tp_dealloc = subtype_dealloc; @@ -2800,7 +3375,8 @@ type_new_set_name(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_module(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__module__)); if (r < 0) { return -1; } @@ -2821,7 +3397,7 @@ type_new_set_module(PyTypeObject *type) return 0; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), module) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__module__), module) < 0) { return -1; } return 0; @@ -2834,8 +3410,8 @@ static int type_new_set_ht_name(PyTypeObject *type) { PyHeapTypeObject *et = (PyHeapTypeObject *)type; - PyObject *qualname = PyDict_GetItemWithError( - type->tp_dict, &_Py_ID(__qualname__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *qualname = PyDict_GetItemWithError(dict, &_Py_ID(__qualname__)); if (qualname != NULL) { if (!PyUnicode_Check(qualname)) { PyErr_Format(PyExc_TypeError, @@ -2844,7 +3420,7 @@ type_new_set_ht_name(PyTypeObject *type) return -1; } et->ht_qualname = Py_NewRef(qualname); - if (PyDict_DelItem(type->tp_dict, &_Py_ID(__qualname__)) < 0) { + if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) { return -1; } } @@ -2864,7 +3440,8 @@ type_new_set_ht_name(PyTypeObject *type) static int type_new_set_doc(PyTypeObject *type) { - PyObject *doc = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *doc = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); if (doc == NULL) { if (PyErr_Occurred()) { return -1; @@ -2899,7 +3476,8 @@ type_new_set_doc(PyTypeObject *type) static int type_new_staticmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); + PyObject *dict = lookup_tp_dict(type); + PyObject *func = PyDict_GetItemWithError(dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2914,7 +3492,7 @@ type_new_staticmethod(PyTypeObject *type, PyObject *attr) if (static_func == NULL) { return -1; } - if (PyDict_SetItem(type->tp_dict, attr, static_func) < 0) { + if (PyDict_SetItem(dict, attr, static_func) < 0) { Py_DECREF(static_func); return -1; } @@ -2926,7 +3504,8 @@ type_new_staticmethod(PyTypeObject *type, PyObject *attr) static int type_new_classmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); + PyObject *dict = lookup_tp_dict(type); + PyObject *func = PyDict_GetItemWithError(dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2942,7 +3521,7 @@ type_new_classmethod(PyTypeObject *type, PyObject *attr) return -1; } - if (PyDict_SetItem(type->tp_dict, attr, method) < 0) { + if (PyDict_SetItem(dict, attr, method) < 0) { Py_DECREF(method); return -1; } @@ -2977,20 +3556,15 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } } - if (ctx->add_dict && ctx->base->tp_itemsize) { - type->tp_dictoffset = -(long)sizeof(PyObject *); - slotoffset += sizeof(PyObject *); - } - if (ctx->add_weak) { - assert(!ctx->base->tp_itemsize); - type->tp_weaklistoffset = slotoffset; - slotoffset += sizeof(PyObject *); + assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0); + type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF; + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; } - if (ctx->add_dict && ctx->base->tp_itemsize == 0) { + if (ctx->add_dict) { assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); type->tp_flags |= Py_TPFLAGS_MANAGED_DICT; - type->tp_dictoffset = -slotoffset - sizeof(PyObject *)*3; + type->tp_dictoffset = -1; } type->tp_basicsize = slotoffset; @@ -3033,8 +3607,8 @@ type_new_set_slots(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_classcell(PyTypeObject *type) { - PyObject *cell = PyDict_GetItemWithError( - type->tp_dict, &_Py_ID(__classcell__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classcell__)); if (cell == NULL) { if (PyErr_Occurred()) { return -1; @@ -3051,12 +3625,38 @@ type_new_set_classcell(PyTypeObject *type) } (void)PyCell_Set(cell, (PyObject *) type); - if (PyDict_DelItem(type->tp_dict, &_Py_ID(__classcell__)) < 0) { + if (PyDict_DelItem(dict, &_Py_ID(__classcell__)) < 0) { return -1; } return 0; } +static int +type_new_set_classdictcell(PyTypeObject *type) +{ + PyObject *dict = lookup_tp_dict(type); + PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classdictcell__)); + if (cell == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + + /* At least one method requires a reference to the dict of its defining class */ + if (!PyCell_Check(cell)) { + PyErr_Format(PyExc_TypeError, + "__classdictcell__ must be a nonlocal cell, not %.200R", + Py_TYPE(cell)); + return -1; + } + + (void)PyCell_Set(cell, (PyObject *)dict); + if (PyDict_DelItem(dict, &_Py_ID(__classdictcell__)) < 0) { + return -1; + } + return 0; +} static int type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) @@ -3101,6 +3701,9 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) if (type_new_set_classcell(type) < 0) { return -1; } + if (type_new_set_classdictcell(type) < 0) { + return -1; + } return 0; } @@ -3158,7 +3761,7 @@ type_new_init(type_new_ctx *ctx) goto error; } - type->tp_dict = dict; + set_tp_dict(type, dict); PyHeapTypeObject *et = (PyHeapTypeObject*)type; et->ht_slots = ctx->slots; @@ -3358,29 +3961,135 @@ static const PySlot_Offset pyslot_offsets[] = { #include "typeslots.inc" }; -PyObject * -PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +/* Align up to the nearest multiple of alignof(max_align_t) + * (like _Py_ALIGN_UP, but for a size rather than pointer) + */ +static Py_ssize_t +_align_up(Py_ssize_t size) { - return PyType_FromModuleAndSpec(NULL, spec, bases); + return (size + ALIGNOF_MAX_ALIGN_T - 1) & ~(ALIGNOF_MAX_ALIGN_T - 1); } -PyObject * -PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +/* Given a PyType_FromMetaclass `bases` argument (NULL, type, or tuple of + * types), return a tuple of types. + */ +inline static PyObject * +get_bases_tuple(PyObject *bases_in, PyType_Spec *spec) { - PyHeapTypeObject *res; - PyObject *modname; - PyTypeObject *type, *base; + if (!bases_in) { + /* Default: look in the spec, fall back to (type,). */ + PyTypeObject *base = &PyBaseObject_Type; // borrowed ref + PyObject *bases = NULL; // borrowed ref + const PyType_Slot *slot; + for (slot = spec->slots; slot->slot; slot++) { + switch (slot->slot) { + case Py_tp_base: + base = slot->pfunc; + break; + case Py_tp_bases: + bases = slot->pfunc; + break; + } + } + if (!bases) { + return PyTuple_Pack(1, base); + } + if (PyTuple_Check(bases)) { + return Py_NewRef(bases); + } + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); + return NULL; + } + if (PyTuple_Check(bases_in)) { + return Py_NewRef(bases_in); + } + // Not a tuple, should be a single type + return PyTuple_Pack(1, bases_in); +} + +static inline int +check_basicsize_includes_size_and_offsets(PyTypeObject* type) +{ + if (type->tp_alloc != PyType_GenericAlloc) { + // Custom allocators can ignore tp_basicsize + return 1; + } + Py_ssize_t max = (Py_ssize_t)type->tp_basicsize; + + if (type->tp_base && type->tp_base->tp_basicsize > type->tp_basicsize) { + PyErr_Format(PyExc_TypeError, + "tp_basicsize for type '%s' (%d) is too small for base '%s' (%d)", + type->tp_name, type->tp_basicsize, + type->tp_base->tp_name, type->tp_base->tp_basicsize); + return 0; + } + if (type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "weaklist offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_weaklistoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_dictoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "dict offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_dictoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_vectorcall_offset + (Py_ssize_t)sizeof(vectorcallfunc*) > max) { + PyErr_Format(PyExc_TypeError, + "vectorcall offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_vectorcall_offset, + type->tp_name, type->tp_basicsize); + return 0; + } + return 1; +} + +static PyObject * +_PyType_FromMetaclass_impl( + PyTypeObject *metaclass, PyObject *module, + PyType_Spec *spec, PyObject *bases_in, int _allow_tp_new) +{ + /* Invariant: A non-NULL value in one of these means this function holds + * a strong reference or owns allocated memory. + * These get decrefed/freed/returned at the end, on both success and error. + */ + PyHeapTypeObject *res = NULL; + PyTypeObject *type; + PyObject *bases = NULL; + char *tp_doc = NULL; + PyObject *ht_name = NULL; + char *_ht_tpname = NULL; + int r; + /* Prepare slots that need special handling. + * Keep in mind that a slot can be given multiple times: + * if that would cause trouble (leaks, UB, ...), raise an exception. + */ + const PyType_Slot *slot; - Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset; + Py_ssize_t nmembers = 0; + Py_ssize_t weaklistoffset, dictoffset, vectorcalloffset; char *res_start; - short slot_offset, subslot_offset; nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0; for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_members) { - nmembers = 0; + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto finally; + } + switch (slot->slot) { + case Py_tp_members: + if (nmembers != 0) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_members slots are not supported."); + goto finally; + } for (const PyMemberDef *memb = slot->pfunc; memb->name != NULL; memb++) { nmembers++; if (strcmp(memb->name, "__weaklistoffset__") == 0) { @@ -3401,26 +4110,62 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) assert(memb->flags == READONLY); vectorcalloffset = memb->offset; } + if (memb->flags & Py_RELATIVE_OFFSET) { + if (spec->basicsize > 0) { + PyErr_SetString( + PyExc_SystemError, + "With Py_RELATIVE_OFFSET, basicsize must be negative."); + goto finally; + } + if (memb->offset < 0 || memb->offset >= -spec->basicsize) { + PyErr_SetString( + PyExc_SystemError, + "Member offset out of range (0..-basicsize)"); + goto finally; + } + } + } + break; + case Py_tp_doc: + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ + if (tp_doc != NULL) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_doc slots are not supported."); + goto finally; + } + if (slot->pfunc == NULL) { + PyObject_Free(tp_doc); + tp_doc = NULL; } + else { +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __msan_unpoison_string(slot->pfunc); +# endif +#endif + size_t len = strlen(slot->pfunc)+1; + tp_doc = PyObject_Malloc(len); + if (tp_doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(tp_doc, slot->pfunc, len); + } + break; } } - res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers); - if (res == NULL) - return NULL; - res_start = (char*)res; + /* Prepare the type name and qualname */ if (spec->name == NULL) { PyErr_SetString(PyExc_SystemError, "Type spec does not define the name field."); - goto fail; + goto finally; } - type = &res->ht_type; - /* The flags must be initialized early, before the GC traverses us */ - type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; - /* Set the type name and qualname */ #if defined(__has_feature) # if __has_feature(memory_sanitizer) __msan_unpoison_string(spec->name); @@ -3434,11 +4179,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) s++; } - res->ht_name = PyUnicode_FromString(s); - if (!res->ht_name) { - goto fail; + ht_name = PyUnicode_FromString(s); + if (!ht_name) { + goto finally; } - res->ht_qualname = Py_NewRef(res->ht_name); /* Copy spec->name to a buffer we own. * @@ -3450,124 +4194,207 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) * deallocated with the type (if it's non-NULL). */ Py_ssize_t name_buf_len = strlen(spec->name) + 1; - res->_ht_tpname = PyMem_Malloc(name_buf_len); - if (res->_ht_tpname == NULL) { - goto fail; + _ht_tpname = PyMem_Malloc(name_buf_len); + if (_ht_tpname == NULL) { + goto finally; } - type->tp_name = memcpy(res->_ht_tpname, spec->name, name_buf_len); + memcpy(_ht_tpname, spec->name, name_buf_len); - res->ht_module = Py_XNewRef(module); - - /* Adjust for empty tuple bases */ + /* Get a tuple of bases. + * bases is a strong reference (unlike bases_in). + */ + bases = get_bases_tuple(bases_in, spec); if (!bases) { - base = &PyBaseObject_Type; - /* See whether Py_tp_base(s) was specified */ - for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_base) - base = slot->pfunc; - else if (slot->slot == Py_tp_bases) { - bases = slot->pfunc; + goto finally; + } + + /* If this is an immutable type, check if all bases are also immutable, + * and (for now) fire a deprecation warning if not. + * (This isn't necessary for static types: those can't have heap bases, + * and only heap types can be mutable.) + */ + if (spec->flags & Py_TPFLAGS_IMMUTABLETYPE) { + for (int i=0; i<PyTuple_GET_SIZE(bases); i++) { + PyTypeObject *b = (PyTypeObject*)PyTuple_GET_ITEM(bases, i); + if (!b) { + goto finally; + } + if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) { + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, + 0, + "Creating immutable type %s from mutable base %s is " + "deprecated, and slated to be disallowed in Python 3.14.", + spec->name, + b->tp_name)) + { + goto finally; + } } } - if (!bases) { - bases = PyTuple_Pack(1, base); - if (!bases) - goto fail; - } - else if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); - goto fail; + } + + /* Calculate the metaclass */ + + if (!metaclass) { + metaclass = &PyType_Type; + } + metaclass = _PyType_CalculateMetaclass(metaclass, bases); + if (metaclass == NULL) { + goto finally; + } + if (!PyType_Check(metaclass)) { + PyErr_Format(PyExc_TypeError, + "Metaclass '%R' is not a subclass of 'type'.", + metaclass); + goto finally; + } + if (metaclass->tp_new && metaclass->tp_new != PyType_Type.tp_new) { + if (_allow_tp_new) { + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, 1, + "Type %s uses PyType_Spec with a metaclass that has custom " + "tp_new. This is deprecated and will no longer be allowed in " + "Python 3.14.", spec->name) < 0) { + goto finally; + } } else { - Py_INCREF(bases); + PyErr_SetString( + PyExc_TypeError, + "Metaclasses with custom tp_new are not supported."); + goto finally; } } - else if (!PyTuple_Check(bases)) { - bases = PyTuple_Pack(1, bases); - if (!bases) - goto fail; - } - else { - Py_INCREF(bases); - } /* Calculate best base, and check that all bases are type objects */ - base = best_base(bases); + PyTypeObject *base = best_base(bases); // borrowed ref if (base == NULL) { - Py_DECREF(bases); - goto fail; + goto finally; } - if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { - PyErr_Format(PyExc_TypeError, - "type '%.100s' is not an acceptable base type", - base->tp_name); - Py_DECREF(bases); - goto fail; + // best_base should check Py_TPFLAGS_BASETYPE & raise a proper exception, + // here we just check its work + assert(_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)); + + /* Calculate sizes */ + + Py_ssize_t basicsize = spec->basicsize; + Py_ssize_t type_data_offset = spec->basicsize; + if (basicsize == 0) { + /* Inherit */ + basicsize = base->tp_basicsize; + } + else if (basicsize < 0) { + /* Extend */ + type_data_offset = _align_up(base->tp_basicsize); + basicsize = type_data_offset + _align_up(-spec->basicsize); + + /* Inheriting variable-sized types is limited */ + if (base->tp_itemsize + && !((base->tp_flags | spec->flags) & Py_TPFLAGS_ITEMS_AT_END)) + { + PyErr_SetString( + PyExc_SystemError, + "Cannot extend variable-size class without Py_TPFLAGS_ITEMS_AT_END."); + goto finally; + } + } + + Py_ssize_t itemsize = spec->itemsize; + + /* Allocate the new type + * + * Between here and PyType_Ready, we should limit: + * - calls to Python code + * - raising exceptions + * - memory allocations + */ + + res = (PyHeapTypeObject*)metaclass->tp_alloc(metaclass, nmembers); + if (res == NULL) { + goto finally; } + res_start = (char*)res; + + type = &res->ht_type; + /* The flags must be initialized early, before the GC traverses us */ + type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + + res->ht_module = Py_XNewRef(module); /* Initialize essential fields */ + type->tp_as_async = &res->as_async; type->tp_as_number = &res->as_number; type->tp_as_sequence = &res->as_sequence; type->tp_as_mapping = &res->as_mapping; type->tp_as_buffer = &res->as_buffer; - /* Set tp_base and tp_bases */ - type->tp_bases = bases; - Py_INCREF(base); - type->tp_base = base; - type->tp_basicsize = spec->basicsize; - type->tp_itemsize = spec->itemsize; + /* Set slots we have prepared */ + + type->tp_base = (PyTypeObject *)Py_NewRef(base); + set_tp_bases(type, bases); + bases = NULL; // We give our reference to bases to the type + + type->tp_doc = tp_doc; + tp_doc = NULL; // Give ownership of the allocated memory to the type + + res->ht_qualname = Py_NewRef(ht_name); + res->ht_name = ht_name; + ht_name = NULL; // Give our reference to the type + + type->tp_name = _ht_tpname; + res->_ht_tpname = _ht_tpname; + _ht_tpname = NULL; // Give ownership to the type + + /* Copy the sizes */ + + type->tp_basicsize = basicsize; + type->tp_itemsize = itemsize; + + /* Copy all the ordinary slots */ for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot < 0 - || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); - goto fail; - } - else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { + switch (slot->slot) { + case Py_tp_base: + case Py_tp_bases: + case Py_tp_doc: /* Processed above */ - continue; - } - else if (slot->slot == Py_tp_doc) { - /* For the docstring slot, which usually points to a static string - literal, we need to make a copy */ - if (slot->pfunc == NULL) { - type->tp_doc = NULL; - continue; - } -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) - __msan_unpoison_string(slot->pfunc); -# endif -#endif - size_t len = strlen(slot->pfunc)+1; - char *tp_doc = PyObject_Malloc(len); - if (tp_doc == NULL) { - type->tp_doc = NULL; - PyErr_NoMemory(); - goto fail; + break; + case Py_tp_members: + { + /* Move the slots to the heap type itself */ + size_t len = Py_TYPE(type)->tp_itemsize * nmembers; + memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); + type->tp_members = _PyHeapType_GET_MEMBERS(res); + PyMemberDef *memb; + Py_ssize_t i; + for (memb = _PyHeapType_GET_MEMBERS(res), i = nmembers; + i > 0; ++memb, --i) + { + if (memb->flags & Py_RELATIVE_OFFSET) { + memb->flags &= ~Py_RELATIVE_OFFSET; + memb->offset += type_data_offset; + } + } } - memcpy(tp_doc, slot->pfunc, len); - type->tp_doc = tp_doc; - } - else if (slot->slot == Py_tp_members) { - /* Move the slots to the heap type itself */ - size_t len = Py_TYPE(type)->tp_itemsize * nmembers; - memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); - type->tp_members = _PyHeapType_GET_MEMBERS(res); - } - else { - /* Copy other slots directly */ - PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; - slot_offset = slotoffsets.slot_offset; - if (slotoffsets.subslot_offset == -1) { - *(void**)((char*)res_start + slot_offset) = slot->pfunc; - } else { - void *parent_slot = *(void**)((char*)res_start + slot_offset); - subslot_offset = slotoffsets.subslot_offset; - *(void**)((char*)parent_slot + subslot_offset) = slot->pfunc; + break; + default: + { + /* Copy other slots directly */ + PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; + short slot_offset = slotoffsets.slot_offset; + if (slotoffsets.subslot_offset == -1) { + /* Set a slot in the main PyTypeObject */ + *(void**)((char*)res_start + slot_offset) = slot->pfunc; + } + else { + void *procs = *(void**)((char*)res_start + slot_offset); + short subslot_offset = slotoffsets.subslot_offset; + *(void**)((char*)procs + subslot_offset) = slot->pfunc; + } } + break; } } if (type->tp_dealloc == NULL) { @@ -3577,71 +4404,113 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) type->tp_dealloc = subtype_dealloc; } - if (vectorcalloffset) { - type->tp_vectorcall_offset = vectorcalloffset; + /* Set up offsets */ + + type->tp_vectorcall_offset = vectorcalloffset; + type->tp_weaklistoffset = weaklistoffset; + type->tp_dictoffset = dictoffset; + + /* Ready the type (which includes inheritance). + * + * After this call we should generally only touch up what's + * accessible to Python code, like __dict__. + */ + + if (PyType_Ready(type) < 0) { + goto finally; } - if (PyType_Ready(type) < 0) - goto fail; + if (!check_basicsize_includes_size_and_offsets(type)) { + goto finally; + } + PyObject *dict = lookup_tp_dict(type); if (type->tp_doc) { PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); - if (!__doc__) - goto fail; - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), __doc__); + if (!__doc__) { + goto finally; + } + r = PyDict_SetItem(dict, &_Py_ID(__doc__), __doc__); Py_DECREF(__doc__); - if (r < 0) - goto fail; + if (r < 0) { + goto finally; + } } if (weaklistoffset) { - type->tp_weaklistoffset = weaklistoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) - goto fail; + if (PyDict_DelItem(dict, &_Py_ID(__weaklistoffset__)) < 0) { + goto finally; + } } if (dictoffset) { - type->tp_dictoffset = dictoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__dictoffset__") < 0) - goto fail; + if (PyDict_DelItem(dict, &_Py_ID(__dictoffset__)) < 0) { + goto finally; + } } /* Set type.__module__ */ - r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); + r = PyDict_Contains(dict, &_Py_ID(__module__)); if (r < 0) { - goto fail; + goto finally; } if (r == 0) { s = strrchr(spec->name, '.'); if (s != NULL) { - modname = PyUnicode_FromStringAndSize( + PyObject *modname = PyUnicode_FromStringAndSize( spec->name, (Py_ssize_t)(s - spec->name)); if (modname == NULL) { - goto fail; + goto finally; } - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), modname); + r = PyDict_SetItem(dict, &_Py_ID(__module__), modname); Py_DECREF(modname); - if (r != 0) - goto fail; - } else { + if (r != 0) { + goto finally; + } + } + else { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "builtin type %.200s has no __module__ attribute", spec->name)) - goto fail; + goto finally; } } assert(_PyType_CheckConsistency(type)); + + finally: + if (PyErr_Occurred()) { + Py_CLEAR(res); + } + Py_XDECREF(bases); + PyObject_Free(tp_doc); + Py_XDECREF(ht_name); + PyMem_Free(_ht_tpname); return (PyObject*)res; +} - fail: - Py_DECREF(res); - return NULL; +PyObject * +PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, + PyType_Spec *spec, PyObject *bases_in) +{ + return _PyType_FromMetaclass_impl(metaclass, module, spec, bases_in, 0); +} + +PyObject * +PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +{ + return _PyType_FromMetaclass_impl(NULL, module, spec, bases, 1); +} + +PyObject * +PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +{ + return _PyType_FromMetaclass_impl(NULL, NULL, spec, bases, 1); } PyObject * PyType_FromSpec(PyType_Spec *spec) { - return PyType_FromSpecWithBases(spec, NULL); + return _PyType_FromMetaclass_impl(NULL, NULL, spec, NULL, 1); } PyObject * @@ -3721,7 +4590,7 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) { assert(PyType_Check(type)); - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); // The type must be ready assert(mro != NULL); assert(PyTuple_Check(mro)); @@ -3751,6 +4620,34 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) return NULL; } +void * +PyObject_GetTypeData(PyObject *obj, PyTypeObject *cls) +{ + assert(PyObject_TypeCheck(obj, cls)); + return (char *)obj + _align_up(cls->tp_base->tp_basicsize); +} + +Py_ssize_t +PyType_GetTypeDataSize(PyTypeObject *cls) +{ + ptrdiff_t result = cls->tp_basicsize - _align_up(cls->tp_base->tp_basicsize); + if (result < 0) { + return 0; + } + return result; +} + +void * +PyObject_GetItemData(PyObject *obj) +{ + if (!PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_ITEMS_AT_END)) { + PyErr_Format(PyExc_TypeError, + "type '%s' does not have Py_TPFLAGS_ITEMS_AT_END", + Py_TYPE(obj)->tp_name); + return NULL; + } + return (char *)obj + Py_TYPE(obj)->tp_basicsize; +} /* Internal API to look for a name through the MRO, bypassing the method cache. This returns a borrowed reference, and might set an exception. @@ -3770,14 +4667,14 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) } /* Look in tp_dict of types in MRO */ - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); if (mro == NULL) { - if ((type->tp_flags & Py_TPFLAGS_READYING) == 0) { + if (!is_readying(type)) { if (PyType_Ready(type) < 0) { *error = -1; return NULL; } - mro = type->tp_mro; + mro = lookup_tp_mro(type); } if (mro == NULL) { *error = 1; @@ -3792,7 +4689,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyObject *base = PyTuple_GET_ITEM(mro, i); - PyObject *dict = _PyType_CAST(base)->tp_dict; + PyObject *dict = lookup_tp_dict(_PyType_CAST(base)); assert(dict && PyDict_Check(dict)); res = _PyDict_GetItem_KnownHash(dict, name, hash); if (res != NULL) { @@ -3809,6 +4706,24 @@ done: return res; } +/* Check if the "readied" PyUnicode name + is a double-underscore special name. */ +static int +is_dunder_name(PyObject *name) +{ + Py_ssize_t length = PyUnicode_GET_LENGTH(name); + int kind = PyUnicode_KIND(name); + /* Special names contain at least "__x__" and are always ASCII. */ + if (length > 4 && kind == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); + return ( + ((characters[length-2] == '_') && (characters[length-1] == '_')) && + ((characters[0] == '_') && (characters[1] == '_')) + ); + } + return 0; +} + /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ PyObject * @@ -3816,18 +4731,20 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) { PyObject *res; int error; + PyInterpreterState *interp = _PyInterpreterState_GET(); unsigned int h = MCACHE_HASH_METHOD(type, name); struct type_cache *cache = get_type_cache(); struct type_cache_entry *entry = &cache->hashtable[h]; if (entry->version == type->tp_version_tag && entry->name == name) { -#if MCACHE_STATS - cache->hits++; -#endif assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + OBJECT_STAT_INC_COND(type_cache_hits, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_hits, is_dunder_name(name)); return entry->value; } + OBJECT_STAT_INC_COND(type_cache_misses, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_misses, is_dunder_name(name)); /* We may end up clearing live exceptions below, so make sure it's ours. */ assert(!PyErr_Occurred()); @@ -3849,20 +4766,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) return NULL; } - if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(cache, type)) { + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(interp, type)) { h = MCACHE_HASH_METHOD(type, name); struct type_cache_entry *entry = &cache->hashtable[h]; entry->version = type->tp_version_tag; entry->value = res; /* borrowed */ assert(_PyASCIIObject_CAST(name)->hash != -1); -#if MCACHE_STATS - if (entry->name != Py_None && entry->name != name) { - cache->collisions++; - } - else { - cache->misses++; - } -#endif + OBJECT_STAT_INC_COND(type_cache_collisions, entry->name != Py_None && entry->name != name); assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); Py_SETREF(entry->name, Py_NewRef(name)); } @@ -3879,28 +4789,20 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name) return _PyType_Lookup(type, oname); } -/* Check if the "readied" PyUnicode name - is a double-underscore special name. */ -static int -is_dunder_name(PyObject *name) -{ - Py_ssize_t length = PyUnicode_GET_LENGTH(name); - int kind = PyUnicode_KIND(name); - /* Special names contain at least "__x__" and are always ASCII. */ - if (length > 4 && kind == PyUnicode_1BYTE_KIND) { - const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); - return ( - ((characters[length-2] == '_') && (characters[length-1] == '_')) && - ((characters[0] == '_') && (characters[1] == '_')) - ); - } - return 0; -} - /* This is similar to PyObject_GenericGetAttr(), - but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ -static PyObject * -type_getattro(PyTypeObject *type, PyObject *name) + but uses _PyType_Lookup() instead of just looking in type->tp_dict. + + The argument suppress_missing_attribute is used to provide a + fast path for hasattr. The possible values are: + + * NULL: do not suppress the exception + * Non-zero pointer: suppress the PyExc_AttributeError and + set *suppress_missing_attribute to 1 to signal we are returning NULL while + having suppressed the exception (other exceptions are not suppressed) + + */ +PyObject * +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int * suppress_missing_attribute) { PyTypeObject *metatype = Py_TYPE(type); PyObject *meta_attribute, *attribute; @@ -3980,12 +4882,25 @@ type_getattro(PyTypeObject *type, PyObject *name) } /* Give up */ - PyErr_Format(PyExc_AttributeError, - "type object '%.50s' has no attribute '%U'", - type->tp_name, name); + if (suppress_missing_attribute == NULL) { + PyErr_Format(PyExc_AttributeError, + "type object '%.100s' has no attribute '%U'", + type->tp_name, name); + } else { + // signal the caller we have not set an PyExc_AttributeError and gave up + *suppress_missing_attribute = 1; + } return NULL; } +/* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ +PyObject * +_Py_type_getattro(PyTypeObject *type, PyObject *name) +{ + return _Py_type_getattro_impl(type, name, NULL); +} + static int type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { @@ -4048,41 +4963,89 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys); static void type_dealloc_common(PyTypeObject *type) { - if (type->tp_bases != NULL) { - PyObject *tp, *val, *tb; - PyErr_Fetch(&tp, &val, &tb); - remove_all_subclasses(type, type->tp_bases); - PyErr_Restore(tp, val, tb); + PyObject *bases = lookup_tp_bases(type); + if (bases != NULL) { + PyObject *exc = PyErr_GetRaisedException(); + remove_all_subclasses(type, bases); + PyErr_SetRaisedException(exc); } } -void -_PyStaticType_Dealloc(PyTypeObject *type) +static void +clear_static_tp_subclasses(PyTypeObject *type) { - // If a type still has subtypes, it cannot be deallocated. - // A subtype can inherit attributes and methods of its parent type, - // and a type must no longer be used once it's deallocated. - if (type->tp_subclasses != NULL) { + PyObject *subclasses = lookup_tp_subclasses(type); + if (subclasses == NULL) { return; } + /* Normally it would be a problem to finalize the type if its + tp_subclasses wasn't cleared first. However, this is only + ever called at the end of runtime finalization, so we can be + more liberal in cleaning up. If the given type still has + subtypes at this point then some extension module did not + correctly finalize its objects. + + We can safely obliterate such subtypes since the extension + module and its objects won't be used again, except maybe if + the runtime were re-initialized. In that case the sticky + situation would only happen if the module were re-imported + then and only if the subtype were stored in a global and only + if that global were not overwritten during import. We'd be + fine since the extension is otherwise unsafe and unsupported + in that situation, and likely problematic already. + + In any case, this situation means at least some memory is + going to leak. This mostly only affects embedding scenarios. + */ + + // For now we just do a sanity check and then clear tp_subclasses. + Py_ssize_t i = 0; + PyObject *key, *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + // All static builtin subtypes should have been finalized already. + assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + } + + clear_tp_subclasses(type); +} + +static void +clear_static_type_objects(PyInterpreterState *interp, PyTypeObject *type) +{ + if (_Py_IsMainInterpreter(interp)) { + Py_CLEAR(type->tp_cache); + } + clear_tp_dict(type); + clear_tp_bases(type); + clear_tp_mro(type); + clear_static_tp_subclasses(type); +} + +void +_PyStaticType_Dealloc(PyInterpreterState *interp, PyTypeObject *type) +{ + assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_Py_IsImmortal((PyObject *)type)); + type_dealloc_common(type); - Py_CLEAR(type->tp_dict); - Py_CLEAR(type->tp_bases); - Py_CLEAR(type->tp_mro); - Py_CLEAR(type->tp_cache); - // type->tp_subclasses is NULL + clear_static_type_objects(interp, type); - // PyObject_ClearWeakRefs() raises an exception if Py_REFCNT() != 0 - if (Py_REFCNT(type) == 0) { - PyObject_ClearWeakRefs((PyObject *)type); + if (_Py_IsMainInterpreter(interp)) { + type->tp_flags &= ~Py_TPFLAGS_READY; + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; + type->tp_version_tag = 0; } - type->tp_flags &= ~Py_TPFLAGS_READY; - type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; - type->tp_version_tag = 0; + _PyStaticType_ClearWeakRefs(interp, type); + static_builtin_state_clear(interp, type); + /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */ } @@ -4105,7 +5068,7 @@ type_dealloc(PyTypeObject *type) Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_cache); - Py_XDECREF(type->tp_subclasses); + clear_tp_subclasses(type); /* A type's tp_doc is heap allocated, unlike the tp_doc slots * of most other objects. It's okay to cast it to char *. @@ -4125,41 +5088,6 @@ type_dealloc(PyTypeObject *type) } -PyObject* -_PyType_GetSubclasses(PyTypeObject *self) -{ - PyObject *list = PyList_New(0); - if (list == NULL) { - return NULL; - } - - PyObject *subclasses = self->tp_subclasses; // borrowed ref - if (subclasses == NULL) { - return list; - } - assert(PyDict_CheckExact(subclasses)); - // The loop cannot modify tp_subclasses, there is no need - // to hold a strong reference (use a borrowed reference). - - Py_ssize_t i = 0; - PyObject *ref; // borrowed ref - while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref - if (obj == Py_None) { - continue; - } - assert(PyType_Check(obj)); - - if (PyList_Append(list, obj) < 0) { - Py_DECREF(list); - return NULL; - } - } - return list; -} - - /*[clinic input] type.__subclasses__ @@ -4276,16 +5204,17 @@ static PyObject * type___sizeof___impl(PyTypeObject *self) /*[clinic end generated code: output=766f4f16cd3b1854 input=99398f24b9cf45d6]*/ { - Py_ssize_t size; + size_t size; if (self->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)self; size = sizeof(PyHeapTypeObject); if (et->ht_cached_keys) size += _PyDict_KeysSize(et->ht_cached_keys); } - else + else { size = sizeof(PyTypeObject); - return PyLong_FromSsize_t(size); + } + return PyLong_FromSize_t(size); } static PyMethodDef type_methods[] = { @@ -4372,8 +5301,9 @@ type_clear(PyTypeObject *type) */ PyType_Modified(type); - if (type->tp_dict) { - PyDict_Clear(type->tp_dict); + PyObject *dict = lookup_tp_dict(type); + if (dict) { + PyDict_Clear(dict); } Py_CLEAR(((PyHeapTypeObject *)type)->ht_module); @@ -4410,12 +5340,13 @@ PyTypeObject PyType_Type = { 0, /* tp_hash */ (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ - (getattrofunc)type_getattro, /* tp_getattro */ + (getattrofunc)_Py_type_getattro, /* tp_getattro */ (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS | - Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_ITEMS_AT_END, /* tp_flags */ type_doc, /* tp_doc */ (traverseproc)type_traverse, /* tp_traverse */ (inquiry)type_clear, /* tp_clear */ @@ -4533,9 +5464,10 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *abstract_methods; PyObject *sorted_methods; PyObject *joined; + PyObject* comma_w_quotes_sep; Py_ssize_t method_count; - /* Compute ", ".join(sorted(type.__abstractmethods__)) + /* Compute "', '".join(sorted(type.__abstractmethods__)) into joined. */ abstract_methods = type_abstractmethods(type, NULL); if (abstract_methods == NULL) @@ -4548,22 +5480,28 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(sorted_methods); return NULL; } - _Py_DECLARE_STR(comma_sep, ", "); - joined = PyUnicode_Join(&_Py_STR(comma_sep), sorted_methods); + comma_w_quotes_sep = PyUnicode_FromString("', '"); + joined = PyUnicode_Join(comma_w_quotes_sep, sorted_methods); method_count = PyObject_Length(sorted_methods); Py_DECREF(sorted_methods); - if (joined == NULL) + if (joined == NULL) { + Py_DECREF(comma_w_quotes_sep); return NULL; - if (method_count == -1) + } + if (method_count == -1) { + Py_DECREF(comma_w_quotes_sep); + Py_DECREF(joined); return NULL; + } PyErr_Format(PyExc_TypeError, "Can't instantiate abstract class %s " - "with abstract method%s %U", + "without an implementation for abstract method%s '%U'", type->tp_name, method_count > 1 ? "s" : "", joined); Py_DECREF(joined); + Py_DECREF(comma_w_quotes_sep); return NULL; } PyObject *obj = type->tp_alloc(type, 0); @@ -4594,8 +5532,7 @@ object_repr(PyObject *self) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { @@ -4634,16 +5571,14 @@ object_richcompare(PyObject *self, PyObject *other, int op) /* Return NotImplemented instead of False, so if two objects are compared, both get a chance at the comparison. See issue #1393. */ - res = (self == other) ? Py_True : Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef((self == other) ? Py_True : Py_NotImplemented); break; case Py_NE: /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ if (Py_TYPE(self)->tp_richcompare == NULL) { - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } res = (*Py_TYPE(self)->tp_richcompare)(self, other, Py_EQ); @@ -4654,28 +5589,31 @@ object_richcompare(PyObject *self, PyObject *other, int op) res = NULL; else { if (ok) - res = Py_False; + res = Py_NewRef(Py_False); else - res = Py_True; - Py_INCREF(res); + res = Py_NewRef(Py_True); } } break; default: - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } return res; } +PyObject* +_Py_BaseObject_RichCompare(PyObject* self, PyObject* other, int op) +{ + return object_richcompare(self, other, op); +} + static PyObject * object_get_class(PyObject *self, void *closure) { - Py_INCREF(Py_TYPE(self)); - return (PyObject *)(Py_TYPE(self)); + return Py_NewRef(Py_TYPE(self)); } static int @@ -4757,9 +5695,9 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* !same_slots_added(newbase, oldbase))) { goto differs; } - /* The above does not check for managed __dicts__ */ - if ((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == - ((newto->tp_flags & Py_TPFLAGS_MANAGED_DICT))) + /* The above does not check for the preheader */ + if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == + ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) { return 1; } @@ -4858,9 +5796,11 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT)); + assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER)); _PyObject_GetDictPtr(self); - if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && *_PyObject_ValuesPointer(self)) { + if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) + { /* Was unable to convert to dict */ PyErr_NoMemory(); return -1; @@ -4919,7 +5859,8 @@ _PyType_GetSlotNames(PyTypeObject *cls) assert(PyType_Check(cls)); /* Get the slot names from the cache in the class if possible. */ - slotnames = PyDict_GetItemWithError(cls->tp_dict, &_Py_ID(__slotnames__)); + PyObject *dict = lookup_tp_dict(cls); + slotnames = PyDict_GetItemWithError(dict, &_Py_ID(__slotnames__)); if (slotnames != NULL) { if (slotnames != Py_None && !PyList_Check(slotnames)) { PyErr_Format(PyExc_TypeError, @@ -4928,8 +5869,7 @@ _PyType_GetSlotNames(PyTypeObject *cls) cls->tp_name, Py_TYPE(slotnames)->tp_name); return NULL; } - Py_INCREF(slotnames); - return slotnames; + return Py_NewRef(slotnames); } else { if (PyErr_Occurred()) { @@ -4975,8 +5915,7 @@ object_getstate_default(PyObject *obj, int required) } if (_PyObject_IsInstanceDictEmpty(obj)) { - state = Py_None; - Py_INCREF(state); + state = Py_NewRef(Py_None); } else { state = PyObject_GenericGetDict(obj, NULL); @@ -4999,7 +5938,7 @@ object_getstate_default(PyObject *obj, int required) { basicsize += sizeof(PyObject *); } - if (Py_TYPE(obj)->tp_weaklistoffset) { + if (Py_TYPE(obj)->tp_weaklistoffset > 0) { basicsize += sizeof(PyObject *); } if (slotnames != Py_None) { @@ -5030,8 +5969,7 @@ object_getstate_default(PyObject *obj, int required) for (i = 0; i < slotnames_size; i++) { PyObject *name, *value; - name = PyList_GET_ITEM(slotnames, i); - Py_INCREF(name); + name = Py_NewRef(PyList_GET_ITEM(slotnames, i)); if (_PyObject_LookupAttr(obj, name, &value) < 0) { Py_DECREF(name); goto error; @@ -5101,7 +6039,7 @@ object_getstate(PyObject *obj, int required) PyCFunction_GET_SELF(getstate) == obj && PyCFunction_GET_FUNCTION(getstate) == object___getstate__) { - /* If __getstate__ is not overriden pass the required argument. */ + /* If __getstate__ is not overridden pass the required argument. */ state = object_getstate_default(obj, required); } else { @@ -5163,10 +6101,8 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) Py_DECREF(newargs); return -1; } - *args = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(*args); - *kwargs = PyTuple_GET_ITEM(newargs, 1); - Py_INCREF(*kwargs); + *args = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); + *kwargs = Py_NewRef(PyTuple_GET_ITEM(newargs, 1)); Py_DECREF(newargs); /* XXX We should perhaps allow None to be passed here. */ @@ -5234,8 +6170,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyList_Check(obj)) { - *listitems = Py_None; - Py_INCREF(*listitems); + *listitems = Py_NewRef(Py_None); } else { *listitems = PyObject_GetIter(obj); @@ -5244,8 +6179,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyDict_Check(obj)) { - *dictitems = Py_None; - Py_INCREF(*dictitems); + *dictitems = Py_NewRef(Py_None); } else { PyObject *items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items)); @@ -5310,12 +6244,10 @@ reduce_newobj(PyObject *obj) return NULL; } cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 0, cls); + PyTuple_SET_ITEM(newargs, 0, Py_NewRef(cls)); for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); - Py_INCREF(v); - PyTuple_SET_ITEM(newargs, i+1, v); + PyTuple_SET_ITEM(newargs, i+1, Py_NewRef(v)); } Py_XDECREF(args); } @@ -5423,12 +6355,13 @@ static PyObject * object___reduce_ex___impl(PyObject *self, int protocol) /*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/ { - static PyObject *objreduce; +#define objreduce \ + (_Py_INTERP_CACHED_OBJECT(_PyInterpreterState_Get(), objreduce)) PyObject *reduce, *res; if (objreduce == NULL) { - objreduce = PyDict_GetItemWithError( - PyBaseObject_Type.tp_dict, &_Py_ID(__reduce__)); + PyObject *dict = lookup_tp_dict(&PyBaseObject_Type); + objreduce = PyDict_GetItemWithError(dict, &_Py_ID(__reduce__)); if (objreduce == NULL && PyErr_Occurred()) { return NULL; } @@ -5459,6 +6392,7 @@ object___reduce_ex___impl(PyObject *self, int protocol) } return _common_reduce(self, protocol); +#undef objreduce } static PyObject * @@ -5494,11 +6428,13 @@ object.__format__ / Default object formatter. + +Return str(self) if format_spec is empty. Raise TypeError otherwise. [clinic start generated code]*/ static PyObject * object___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=34897efb543a974b input=7c3b3bc53a6fb7fa]*/ +/*[clinic end generated code: output=34897efb543a974b input=b94d8feb006689ea]*/ { /* Issue 7994: If we're converting to a string, we should reject format specifications */ @@ -5563,8 +6499,7 @@ object___dir___impl(PyObject *self) else { /* Copy __dict__ to avoid mutating it. */ PyObject *temp = PyDict_Copy(dict); - Py_DECREF(dict); - dict = temp; + Py_SETREF(dict, temp); } if (dict == NULL) @@ -5692,11 +6627,12 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) } int err; + PyObject *dict = lookup_tp_dict(type); if (!(meth->ml_flags & METH_COEXIST)) { - err = PyDict_SetDefault(type->tp_dict, name, descr) == NULL; + err = PyDict_SetDefault(dict, name, descr) == NULL; } else { - err = PyDict_SetItem(type->tp_dict, name, descr) < 0; + err = PyDict_SetItem(dict, name, descr) < 0; } if (!isdescr) { Py_DECREF(name); @@ -5735,7 +6671,7 @@ type_add_members(PyTypeObject *type) return 0; } - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); for (; memb->name != NULL; memb++) { PyObject *descr = PyDescr_NewMember(type, memb); if (descr == NULL) @@ -5759,7 +6695,7 @@ type_add_getset(PyTypeObject *type) return 0; } - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); for (; gsp->name != NULL; gsp++) { PyObject *descr = PyDescr_NewGetSet(type, gsp); if (descr == NULL) { @@ -5789,7 +6725,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } - type->tp_flags |= (base->tp_flags & Py_TPFLAGS_MANAGED_DICT); + type->tp_flags |= (base->tp_flags & Py_TPFLAGS_PREHEADER); if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; @@ -5802,6 +6738,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset); + #undef COPYVAL /* Setup fast subclass flags */ @@ -5829,15 +6766,20 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) else if (PyType_IsSubtype(base, &PyDict_Type)) { type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; } + + /* Setup some inheritable flags */ if (PyType_HasFeature(base, _Py_TPFLAGS_MATCH_SELF)) { type->tp_flags |= _Py_TPFLAGS_MATCH_SELF; } + if (PyType_HasFeature(base, Py_TPFLAGS_ITEMS_AT_END)) { + type->tp_flags |= Py_TPFLAGS_ITEMS_AT_END; + } } static int overrides_hash(PyTypeObject *type) { - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); assert(dict != NULL); int r = PyDict_Contains(dict, &_Py_ID(__eq__)); @@ -5975,11 +6917,9 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) * won't be used automatically. */ COPYSLOT(tp_vectorcall_offset); - /* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types - * if tp_call is not overridden */ + /* Inherit Py_TPFLAGS_HAVE_VECTORCALL if tp_call is not overridden */ if (!type->tp_call && - _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) && - _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL)) { type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL; } @@ -6081,7 +7021,7 @@ type_ready_pre_checks(PyTypeObject *type) static int -type_ready_set_bases(PyTypeObject *type) +type_ready_set_base(PyTypeObject *type) { /* Initialize tp_base (defaults to BaseObject unless that's us) */ PyTypeObject *base = type->tp_base; @@ -6106,6 +7046,12 @@ type_ready_set_bases(PyTypeObject *type) } } + return 0; +} + +static int +type_ready_set_type(PyTypeObject *type) +{ /* Initialize ob_type if NULL. This means extensions that want to be compilable separately on Windows can call PyType_Ready() instead of initializing the ob_type field of their type objects. */ @@ -6113,12 +7059,26 @@ type_ready_set_bases(PyTypeObject *type) NULL when type is &PyBaseObject_Type, and we know its ob_type is not NULL (it's initialized to &PyType_Type). But coverity doesn't know that. */ + PyTypeObject *base = type->tp_base; if (Py_IS_TYPE(type, NULL) && base != NULL) { Py_SET_TYPE(type, Py_TYPE(base)); } - /* Initialize tp_bases */ - PyObject *bases = type->tp_bases; + return 0; +} + +static int +type_ready_set_bases(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + assert(lookup_tp_bases(type) != NULL); + return 0; + } + assert(lookup_tp_bases(type) == NULL); + } + + PyObject *bases = lookup_tp_bases(type); if (bases == NULL) { PyTypeObject *base = type->tp_base; if (base == NULL) { @@ -6130,7 +7090,7 @@ type_ready_set_bases(PyTypeObject *type) if (bases == NULL) { return -1; } - type->tp_bases = bases; + set_tp_bases(type, bases); } return 0; } @@ -6139,7 +7099,7 @@ type_ready_set_bases(PyTypeObject *type) static int type_ready_set_dict(PyTypeObject *type) { - if (type->tp_dict != NULL) { + if (lookup_tp_dict(type) != NULL) { return 0; } @@ -6147,7 +7107,7 @@ type_ready_set_dict(PyTypeObject *type) if (dict == NULL) { return -1; } - type->tp_dict = dict; + set_tp_dict(type, dict); return 0; } @@ -6157,7 +7117,8 @@ type_ready_set_dict(PyTypeObject *type) static int type_dict_set_doc(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__doc__)); if (r < 0) { return -1; } @@ -6173,14 +7134,14 @@ type_dict_set_doc(PyTypeObject *type) return -1; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), doc) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__doc__), doc) < 0) { Py_DECREF(doc); return -1; } Py_DECREF(doc); } else { - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), Py_None) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__doc__), Py_None) < 0) { return -1; } } @@ -6210,20 +7171,57 @@ type_ready_fill_dict(PyTypeObject *type) return 0; } +static int +type_ready_preheader(PyTypeObject *type) +{ + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set", + type->tp_name); + return -1; + } + type->tp_dictoffset = -1; + } + if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) { + if (type->tp_weaklistoffset != 0 && + type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET) + { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag " + "but tp_weaklistoffset is set", + type->tp_name); + return -1; + } + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; + } + return 0; +} static int type_ready_mro(PyTypeObject *type) { + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + assert(lookup_tp_mro(type) != NULL); + return 0; + } + assert(lookup_tp_mro(type) == NULL); + } + /* Calculate method resolution order */ if (mro_internal(type, NULL) < 0) { return -1; } - assert(type->tp_mro != NULL); - assert(PyTuple_Check(type->tp_mro)); + PyObject *mro = lookup_tp_mro(type); + assert(mro != NULL); + assert(PyTuple_Check(mro)); - /* All bases of statically allocated type should be statically allocated */ + /* All bases of statically allocated type should be statically allocated, + and static builtin types must have static builtin bases. */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - PyObject *mro = type->tp_mro; + assert(type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE); Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); @@ -6234,6 +7232,8 @@ type_ready_mro(PyTypeObject *type) type->tp_name, base->tp_name); return -1; } + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) || + (base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); } } return 0; @@ -6282,8 +7282,8 @@ type_ready_inherit(PyTypeObject *type) } // Inherit slots - PyObject *mro = type->tp_mro; - Py_ssize_t n = PyTuple_GET_SIZE(type->tp_mro); + PyObject *mro = lookup_tp_mro(type); + Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 1; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(mro, i); if (PyType_Check(b)) { @@ -6328,7 +7328,8 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__hash__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__hash__)); if (r < 0) { return -1; } @@ -6336,7 +7337,7 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__hash__), Py_None) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__hash__), Py_None) < 0) { return -1; } type->tp_hash = PyObject_HashNotImplemented; @@ -6348,7 +7349,7 @@ type_ready_set_hash(PyTypeObject *type) static int type_ready_add_subclasses(PyTypeObject *type) { - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t nbase = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < nbase; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); @@ -6363,7 +7364,7 @@ type_ready_add_subclasses(PyTypeObject *type) // Set tp_new and the "__new__" key in the type dictionary. // Use the Py_TPFLAGS_DISALLOW_INSTANTIATION flag. static int -type_ready_set_new(PyTypeObject *type) +type_ready_set_new(PyTypeObject *type, int rerunbuiltin) { PyTypeObject *base = type->tp_base; /* The condition below could use some explanation. @@ -6385,10 +7386,12 @@ type_ready_set_new(PyTypeObject *type) if (!(type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)) { if (type->tp_new != NULL) { - // If "__new__" key does not exists in the type dictionary, - // set it to tp_new_wrapper(). - if (add_tp_new_wrapper(type) < 0) { - return -1; + if (!rerunbuiltin || base == NULL || type->tp_new != base->tp_new) { + // If "__new__" key does not exists in the type dictionary, + // set it to tp_new_wrapper(). + if (add_tp_new_wrapper(type) < 0) { + return -1; + } } } else { @@ -6441,15 +7444,34 @@ type_ready_post_checks(PyTypeObject *type) type->tp_name); return -1; } + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset != -1) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set to incompatible value", + type->tp_name); + return -1; + } + } + else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) { + if (type->tp_dictoffset + type->tp_basicsize <= 0) { + PyErr_Format(PyExc_SystemError, + "type %s has a tp_dictoffset that is too small", + type->tp_name); + } + } return 0; } static int -type_ready(PyTypeObject *type) +type_ready(PyTypeObject *type, int rerunbuiltin) { + _PyObject_ASSERT((PyObject *)type, !is_readying(type)); + start_readying(type); + if (type_ready_pre_checks(type) < 0) { - return -1; + goto error; } #ifdef Py_TRACE_REFS @@ -6463,38 +7485,60 @@ type_ready(PyTypeObject *type) /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ if (type_ready_set_dict(type) < 0) { - return -1; + goto error; + } + if (type_ready_set_base(type) < 0) { + goto error; + } + if (type_ready_set_type(type) < 0) { + goto error; } if (type_ready_set_bases(type) < 0) { - return -1; + goto error; } if (type_ready_mro(type) < 0) { - return -1; + goto error; } - if (type_ready_set_new(type) < 0) { - return -1; + if (type_ready_set_new(type, rerunbuiltin) < 0) { + goto error; } if (type_ready_fill_dict(type) < 0) { - return -1; + goto error; } - if (type_ready_inherit(type) < 0) { - return -1; + if (!rerunbuiltin) { + if (type_ready_inherit(type) < 0) { + goto error; + } + if (type_ready_preheader(type) < 0) { + goto error; + } } if (type_ready_set_hash(type) < 0) { - return -1; + goto error; } if (type_ready_add_subclasses(type) < 0) { - return -1; - } - if (type_ready_managed_dict(type) < 0) { - return -1; + goto error; } - if (type_ready_post_checks(type) < 0) { - return -1; + if (!rerunbuiltin) { + if (type_ready_managed_dict(type) < 0) { + goto error; + } + if (type_ready_post_checks(type) < 0) { + goto error; + } } + + /* All done -- set the ready flag */ + type->tp_flags = type->tp_flags | Py_TPFLAGS_READY; + stop_readying(type); + + assert(_PyType_CheckConsistency(type)); return 0; -} +error: + stop_readying(type); + return -1; +} int PyType_Ready(PyTypeObject *type) @@ -6503,25 +7547,48 @@ PyType_Ready(PyTypeObject *type) assert(_PyType_CheckConsistency(type)); return 0; } - _PyObject_ASSERT((PyObject *)type, - (type->tp_flags & Py_TPFLAGS_READYING) == 0); - - type->tp_flags |= Py_TPFLAGS_READYING; + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); /* Historically, all static types were immutable. See bpo-43908 */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; } - if (type_ready(type) < 0) { - type->tp_flags &= ~Py_TPFLAGS_READYING; - return -1; + return type_ready(type, 0); +} + +int +_PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self) +{ + assert(_Py_IsImmortal((PyObject *)self)); + assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE)); + assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_DICT)); + assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF)); + + int ismain = _Py_IsMainInterpreter(interp); + if ((self->tp_flags & Py_TPFLAGS_READY) == 0) { + assert(ismain); + + self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN; + self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; + + assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); + self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++; + self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; + } + else { + assert(!ismain); + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(self->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG); } - /* All done -- set the ready flag */ - type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; - assert(_PyType_CheckConsistency(type)); - return 0; + static_builtin_state_init(interp, self); + + int res = type_ready(self, !ismain); + if (res < 0) { + static_builtin_state_clear(interp, self); + } + return res; } @@ -6541,9 +7608,9 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) // Only get tp_subclasses after creating the key and value. // PyWeakref_NewRef() can trigger a garbage collection which can execute // arbitrary Python code and so modify base->tp_subclasses. - PyObject *subclasses = base->tp_subclasses; + PyObject *subclasses = lookup_tp_subclasses(base); if (subclasses == NULL) { - base->tp_subclasses = subclasses = PyDict_New(); + subclasses = init_tp_subclasses(base); if (subclasses == NULL) { Py_DECREF(key); Py_DECREF(ref); @@ -6574,17 +7641,43 @@ add_all_subclasses(PyTypeObject *type, PyObject *bases) return res; } +static PyObject * +get_subclasses_key(PyTypeObject *type, PyTypeObject *base) +{ + PyObject *key = PyLong_FromVoidPtr((void *) type); + if (key != NULL) { + return key; + } + PyErr_Clear(); + + /* This basically means we're out of memory. + We fall back to manually traversing the values. */ + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(base); + if (subclasses != NULL) { + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == type) { + return Py_NewRef(key); + } + } + } + /* It wasn't found. */ + return NULL; +} + static void remove_subclass(PyTypeObject *base, PyTypeObject *type) { - PyObject *subclasses = base->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(base); // borrowed ref if (subclasses == NULL) { return; } assert(PyDict_CheckExact(subclasses)); - PyObject *key = PyLong_FromVoidPtr((void *) type); - if (key == NULL || PyDict_DelItem(subclasses, key)) { + PyObject *key = get_subclasses_key(type, base); + if (key != NULL && PyDict_DelItem(subclasses, key)) { /* This can happen if the type initialization errored out before the base subclasses were updated (e.g. a non-str __qualname__ was passed in the type dict). */ @@ -6593,10 +7686,7 @@ remove_subclass(PyTypeObject *base, PyTypeObject *type) Py_XDECREF(key); if (PyDict_Size(subclasses) == 0) { - // Delete the dictionary to save memory. _PyStaticType_Dealloc() - // callers also test if tp_subclasses is NULL to check if a static type - // has no subclass. - Py_CLEAR(base->tp_subclasses); + clear_tp_subclasses(base); } } @@ -6894,7 +7984,7 @@ static int hackcheck(PyObject *self, setattrofunc func, const char *what) { PyTypeObject *type = Py_TYPE(self); - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); if (!mro) { /* Probably ok not to check the call in this case. */ return 1; @@ -7098,6 +8188,63 @@ wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) } static PyObject * +wrap_buffer(PyObject *self, PyObject *args, void *wrapped) +{ + PyObject *arg = NULL; + + if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) { + return NULL; + } + Py_ssize_t flags = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (flags == -1 && PyErr_Occurred()) { + return NULL; + } + if (flags > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "buffer flags too large"); + return NULL; + } + + return _PyMemoryView_FromBufferProc(self, Py_SAFE_DOWNCAST(flags, Py_ssize_t, int), + (getbufferproc)wrapped); +} + +static PyObject * +wrap_releasebuffer(PyObject *self, PyObject *args, void *wrapped) +{ + PyObject *arg = NULL; + if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) { + return NULL; + } + if (!PyMemoryView_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "expected a memoryview object"); + return NULL; + } + PyMemoryViewObject *mview = (PyMemoryViewObject *)arg; + if (mview->view.obj == NULL) { + // Already released, ignore + Py_RETURN_NONE; + } + if (mview->view.obj != self) { + PyErr_SetString(PyExc_ValueError, + "memoryview's buffer is not this object"); + return NULL; + } + if (mview->flags & _Py_MEMORYVIEW_RELEASED) { + PyErr_SetString(PyExc_ValueError, + "memoryview's buffer has already been released"); + return NULL; + } + PyObject *res = PyObject_CallMethodNoArgs((PyObject *)mview, &_Py_ID(release)); + if (res == NULL) { + return NULL; + } + Py_DECREF(res); + Py_RETURN_NONE; +} + +static PyObject * wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) { initproc func = (initproc)wrapped; @@ -7182,7 +8329,8 @@ static struct PyMethodDef tp_new_methoddef[] = { static int add_tp_new_wrapper(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__new__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__new__)); if (r > 0) { return 0; } @@ -7194,7 +8342,7 @@ add_tp_new_wrapper(PyTypeObject *type) if (func == NULL) { return -1; } - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__new__), func); + r = PyDict_SetItem(dict, &_Py_ID(__new__), func); Py_DECREF(func); return r; } @@ -7312,7 +8460,7 @@ slot_sq_length(PyObject *self) return -1; assert(PyLong_Check(res)); - if (Py_SIZE(res) < 0) { + if (_PyLong_IsNegative((PyLongObject *)res)) { Py_DECREF(res); PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); @@ -7579,8 +8727,7 @@ slot_tp_hash(PyObject *self) func = lookup_maybe_method(self, &_Py_ID(__hash__), &unbound); if (func == Py_None) { - Py_DECREF(func); - func = NULL; + Py_SETREF(func, NULL); } if (func == NULL) { @@ -7642,26 +8789,33 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) /* There are two slot dispatch functions for tp_getattro. - - slot_tp_getattro() is used when __getattribute__ is overridden + - _Py_slot_tp_getattro() is used when __getattribute__ is overridden but no __getattr__ hook is present; - - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + - _Py_slot_tp_getattr_hook() is used when a __getattr__ hook is present. - The code in update_one_slot() always installs slot_tp_getattr_hook(); this - detects the absence of __getattr__ and then installs the simpler slot if - necessary. */ + The code in update_one_slot() always installs _Py_slot_tp_getattr_hook(); + this detects the absence of __getattr__ and then installs the simpler + slot if necessary. */ -static PyObject * -slot_tp_getattro(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattro(PyObject *self, PyObject *name) { PyObject *stack[2] = {self, name}; return vectorcall_method(&_Py_ID(__getattribute__), stack, 2); } -static PyObject * +static inline PyObject * call_attribute(PyObject *self, PyObject *attr, PyObject *name) { PyObject *res, *descr = NULL; + + if (_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + PyObject *args[] = { self, name }; + res = PyObject_Vectorcall(attr, args, 2, NULL); + return res; + } + descrgetfunc f = Py_TYPE(attr)->tp_descr_get; if (f != NULL) { @@ -7676,8 +8830,8 @@ call_attribute(PyObject *self, PyObject *attr, PyObject *name) return res; } -static PyObject * -slot_tp_getattr_hook(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name) { PyTypeObject *tp = Py_TYPE(self); PyObject *getattr, *getattribute, *res; @@ -7690,8 +8844,8 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) getattr = _PyType_Lookup(tp, &_Py_ID(__getattr__)); if (getattr == NULL) { /* No __getattr__ hook: use a simpler dispatcher */ - tp->tp_getattro = slot_tp_getattro; - return slot_tp_getattro(self, name); + tp->tp_getattro = _Py_slot_tp_getattro; + return _Py_slot_tp_getattro(self, name); } Py_INCREF(getattr); /* speed hack: we could use lookup_maybe, but that would resolve the @@ -7703,17 +8857,23 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) if (getattribute == NULL || (Py_IS_TYPE(getattribute, &PyWrapperDescr_Type) && ((PyWrapperDescrObject *)getattribute)->d_wrapped == - (void *)PyObject_GenericGetAttr)) - res = PyObject_GenericGetAttr(self, name); - else { + (void *)PyObject_GenericGetAttr)) { + res = _PyObject_GenericGetAttrWithDict(self, name, NULL, 1); + /* if res == NULL with no exception set, then it must be an + AttributeError suppressed by us. */ + if (res == NULL && !PyErr_Occurred()) { + res = call_attribute(self, getattr, name); + } + } else { Py_INCREF(getattribute); res = call_attribute(self, getattribute, name); Py_DECREF(getattribute); + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + res = call_attribute(self, getattr, name); + } } - if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - res = call_attribute(self, getattr, name); - } + Py_DECREF(getattr); return res; } @@ -7817,14 +8977,14 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) /* Avoid further slowdowns */ if (tp->tp_descr_get == slot_tp_descr_get) tp->tp_descr_get = NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (obj == NULL) obj = Py_None; if (type == NULL) type = Py_None; - return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL); + PyObject *stack[3] = {self, obj, type}; + return PyObject_Vectorcall(get, stack, 3, NULL); } static int @@ -7901,10 +9061,9 @@ slot_tp_finalize(PyObject *self) { int unbound; PyObject *del, *res; - PyObject *error_type, *error_value, *error_traceback; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); /* Execute __del__ method, if any. */ del = lookup_maybe_method(self, &_Py_ID(__del__), &unbound); @@ -7918,7 +9077,244 @@ slot_tp_finalize(PyObject *self) } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); +} + +typedef struct _PyBufferWrapper { + PyObject_HEAD + PyObject *mv; + PyObject *obj; +} PyBufferWrapper; + +static int +bufferwrapper_traverse(PyBufferWrapper *self, visitproc visit, void *arg) +{ + Py_VISIT(self->mv); + Py_VISIT(self->obj); + return 0; +} + +static void +bufferwrapper_dealloc(PyObject *self) +{ + PyBufferWrapper *bw = (PyBufferWrapper *)self; + + _PyObject_GC_UNTRACK(self); + Py_XDECREF(bw->mv); + Py_XDECREF(bw->obj); + Py_TYPE(self)->tp_free(self); +} + +static void +bufferwrapper_releasebuf(PyObject *self, Py_buffer *view) +{ + PyBufferWrapper *bw = (PyBufferWrapper *)self; + + if (bw->mv == NULL || bw->obj == NULL) { + // Already released + return; + } + + PyObject *mv = bw->mv; + PyObject *obj = bw->obj; + + assert(PyMemoryView_Check(mv)); + Py_TYPE(mv)->tp_as_buffer->bf_releasebuffer(mv, view); + // We only need to call bf_releasebuffer if it's a Python function. If it's a C + // bf_releasebuf, it will be called when the memoryview is released. + if (((PyMemoryViewObject *)mv)->view.obj != obj + && Py_TYPE(obj)->tp_as_buffer != NULL + && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer == slot_bf_releasebuffer) { + releasebuffer_call_python(obj, view); + } + + Py_CLEAR(bw->mv); + Py_CLEAR(bw->obj); +} + +static PyBufferProcs bufferwrapper_as_buffer = { + .bf_releasebuffer = bufferwrapper_releasebuf, +}; + + +PyTypeObject _PyBufferWrapper_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "_buffer_wrapper", + .tp_basicsize = sizeof(PyBufferWrapper), + .tp_alloc = PyType_GenericAlloc, + .tp_free = PyObject_GC_Del, + .tp_traverse = (traverseproc)bufferwrapper_traverse, + .tp_dealloc = bufferwrapper_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_as_buffer = &bufferwrapper_as_buffer, +}; + +static int +slot_bf_getbuffer(PyObject *self, Py_buffer *buffer, int flags) +{ + PyObject *flags_obj = PyLong_FromLong(flags); + if (flags_obj == NULL) { + return -1; + } + PyBufferWrapper *wrapper = NULL; + PyObject *stack[2] = {self, flags_obj}; + PyObject *ret = vectorcall_method(&_Py_ID(__buffer__), stack, 2); + if (ret == NULL) { + goto fail; + } + if (!PyMemoryView_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "__buffer__ returned non-memoryview object"); + goto fail; + } + + if (PyObject_GetBuffer(ret, buffer, flags) < 0) { + goto fail; + } + assert(buffer->obj == ret); + + wrapper = PyObject_GC_New(PyBufferWrapper, &_PyBufferWrapper_Type); + if (wrapper == NULL) { + goto fail; + } + wrapper->mv = ret; + wrapper->obj = Py_NewRef(self); + _PyObject_GC_TRACK(wrapper); + + buffer->obj = (PyObject *)wrapper; + Py_DECREF(ret); + Py_DECREF(flags_obj); + return 0; + +fail: + Py_XDECREF(wrapper); + Py_XDECREF(ret); + Py_DECREF(flags_obj); + return -1; +} + +static int +releasebuffer_maybe_call_super(PyObject *self, Py_buffer *buffer) +{ + PyTypeObject *self_type = Py_TYPE(self); + PyObject *mro = lookup_tp_mro(self_type); + if (mro == NULL) { + return -1; + } + + assert(PyTuple_Check(mro)); + Py_ssize_t n = PyTuple_GET_SIZE(mro); + Py_ssize_t i; + + /* No need to check the last one: it's gonna be skipped anyway. */ + for (i = 0; i < n -1; i++) { + if ((PyObject *)(self_type) == PyTuple_GET_ITEM(mro, i)) + break; + } + i++; /* skip self_type */ + if (i >= n) + return -1; + + releasebufferproc base_releasebuffer = NULL; + for (; i < n; i++) { + PyObject *obj = PyTuple_GET_ITEM(mro, i); + if (!PyType_Check(obj)) { + continue; + } + PyTypeObject *base_type = (PyTypeObject *)obj; + if (base_type->tp_as_buffer != NULL + && base_type->tp_as_buffer->bf_releasebuffer != NULL + && base_type->tp_as_buffer->bf_releasebuffer != slot_bf_releasebuffer) { + base_releasebuffer = base_type->tp_as_buffer->bf_releasebuffer; + break; + } + } + + if (base_releasebuffer != NULL) { + base_releasebuffer(self, buffer); + } + return 0; +} + +static void +releasebuffer_call_python(PyObject *self, Py_buffer *buffer) +{ + // bf_releasebuffer may be called while an exception is already active. + // We have no way to report additional errors up the stack, because + // this slot returns void, so we simply stash away the active exception + // and restore it after the call to Python returns. + PyObject *exc = PyErr_GetRaisedException(); + + PyObject *mv; + bool is_buffer_wrapper = Py_TYPE(buffer->obj) == &_PyBufferWrapper_Type; + if (is_buffer_wrapper) { + // Make sure we pass the same memoryview to + // __release_buffer__() that __buffer__() returned. + PyBufferWrapper *bw = (PyBufferWrapper *)buffer->obj; + if (bw->mv == NULL) { + goto end; + } + mv = Py_NewRef(bw->mv); + } + else { + // This means we are not dealing with a memoryview returned + // from a Python __buffer__ function. + mv = PyMemoryView_FromBuffer(buffer); + if (mv == NULL) { + PyErr_WriteUnraisable(self); + goto end; + } + // Set the memoryview to restricted mode, which forbids + // users from saving any reference to the underlying buffer + // (e.g., by doing .cast()). This is necessary to ensure + // no Python code retains a reference to the to-be-released + // buffer. + ((PyMemoryViewObject *)mv)->flags |= _Py_MEMORYVIEW_RESTRICTED; + } + PyObject *stack[2] = {self, mv}; + PyObject *ret = vectorcall_method(&_Py_ID(__release_buffer__), stack, 2); + if (ret == NULL) { + PyErr_WriteUnraisable(self); + } + else { + Py_DECREF(ret); + } + if (!is_buffer_wrapper) { + PyObject *res = PyObject_CallMethodNoArgs(mv, &_Py_ID(release)); + if (res == NULL) { + PyErr_WriteUnraisable(self); + } + else { + Py_DECREF(res); + } + } + Py_DECREF(mv); +end: + assert(!PyErr_Occurred()); + + PyErr_SetRaisedException(exc); +} + +/* + * bf_releasebuffer is very delicate, because we need to ensure that + * C bf_releasebuffer slots are called correctly (or we'll leak memory), + * but we cannot trust any __release_buffer__ implemented in Python to + * do so correctly. Therefore, if a base class has a C bf_releasebuffer + * slot, we call it directly here. That is safe because this function + * only gets called from C callers of the bf_releasebuffer slot. Python + * code that calls __release_buffer__ directly instead goes through + * wrap_releasebuffer(), which doesn't call the bf_releasebuffer slot + * directly but instead simply releases the associated memoryview. + */ +static void +slot_bf_releasebuffer(PyObject *self, Py_buffer *buffer) +{ + releasebuffer_call_python(self, buffer); + if (releasebuffer_maybe_call_super(self, buffer) < 0) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(self); + } + } } static PyObject * @@ -7983,14 +9379,12 @@ which incorporates the additional structures used for numbers, sequences and mappings. Note that multiple names may map to the same slot (e.g. __eq__, __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots (e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with -an all-zero entry. (This table is further initialized in -_PyTypes_InitSlotDefs().) +an all-zero entry. */ -typedef struct wrapperbase slotdef; - #undef TPSLOT #undef FLSLOT +#undef BUFSLOT #undef AMSLOT #undef ETSLOT #undef SQSLOT @@ -8002,14 +9396,16 @@ typedef struct wrapperbase slotdef; #undef RBINSLOT #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME)} #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC), FLAGS} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), FLAGS, .name_strobj = &_Py_ID(NAME) } #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME) } +#define BUFSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_buffer.SLOT, FUNCTION, WRAPPER, DOC) #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ @@ -8020,204 +9416,211 @@ typedef struct wrapperbase slotdef; ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, /)\n--\n\n" DOC) + #NAME "($self, /)\n--\n\n" DOC) #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") + #NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\n" DOC) + #NAME "($self, value, /)\n--\n\n" DOC) #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\n" DOC) + #NAME "($self, value, /)\n--\n\n" DOC) -static slotdef slotdefs[] = { - TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), - TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), - TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, +static pytype_slotdef slotdefs[] = { + TPSLOT(__getattribute__, tp_getattr, NULL, NULL, ""), + TPSLOT(__getattr__, tp_getattr, NULL, NULL, ""), + TPSLOT(__setattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__delattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__repr__, tp_repr, slot_tp_repr, wrap_unaryfunc, "__repr__($self, /)\n--\n\nReturn repr(self)."), - TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, + TPSLOT(__hash__, tp_hash, slot_tp_hash, wrap_hashfunc, "__hash__($self, /)\n--\n\nReturn hash(self)."), - FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, + FLSLOT(__call__, tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", PyWrapperFlag_KEYWORDS), - TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + TPSLOT(__str__, tp_str, slot_tp_str, wrap_unaryfunc, "__str__($self, /)\n--\n\nReturn str(self)."), - TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + TPSLOT(__getattribute__, tp_getattro, _Py_slot_tp_getattr_hook, wrap_binaryfunc, "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), - TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), - TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + TPSLOT(__getattr__, tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), + TPSLOT(__setattr__, tp_setattro, slot_tp_setattro, wrap_setattr, "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), - TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + TPSLOT(__delattr__, tp_setattro, slot_tp_setattro, wrap_delattr, "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), - TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + TPSLOT(__lt__, tp_richcompare, slot_tp_richcompare, richcmp_lt, "__lt__($self, value, /)\n--\n\nReturn self<value."), - TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le, + TPSLOT(__le__, tp_richcompare, slot_tp_richcompare, richcmp_le, "__le__($self, value, /)\n--\n\nReturn self<=value."), - TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, + TPSLOT(__eq__, tp_richcompare, slot_tp_richcompare, richcmp_eq, "__eq__($self, value, /)\n--\n\nReturn self==value."), - TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, + TPSLOT(__ne__, tp_richcompare, slot_tp_richcompare, richcmp_ne, "__ne__($self, value, /)\n--\n\nReturn self!=value."), - TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, + TPSLOT(__gt__, tp_richcompare, slot_tp_richcompare, richcmp_gt, "__gt__($self, value, /)\n--\n\nReturn self>value."), - TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, + TPSLOT(__ge__, tp_richcompare, slot_tp_richcompare, richcmp_ge, "__ge__($self, value, /)\n--\n\nReturn self>=value."), - TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, + TPSLOT(__iter__, tp_iter, slot_tp_iter, wrap_unaryfunc, "__iter__($self, /)\n--\n\nImplement iter(self)."), - TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, + TPSLOT(__next__, tp_iternext, slot_tp_iternext, wrap_next, "__next__($self, /)\n--\n\nImplement next(self)."), - TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, + TPSLOT(__get__, tp_descr_get, slot_tp_descr_get, wrap_descr_get, "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), - TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, + TPSLOT(__set__, tp_descr_set, slot_tp_descr_set, wrap_descr_set, "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), - TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + TPSLOT(__delete__, tp_descr_set, slot_tp_descr_set, wrap_descr_delete, "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), - FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, + FLSLOT(__init__, tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, "__init__($self, /, *args, **kwargs)\n--\n\n" "Initialize self. See help(type(self)) for accurate signature.", PyWrapperFlag_KEYWORDS), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, + TPSLOT(__new__, tp_new, slot_tp_new, NULL, "__new__(type, /, *args, **kwargs)\n--\n\n" "Create and return new object. See help(type) for accurate signature."), - TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), + TPSLOT(__del__, tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), - AMSLOT("__await__", am_await, slot_am_await, wrap_unaryfunc, + BUFSLOT(__buffer__, bf_getbuffer, slot_bf_getbuffer, wrap_buffer, + "__buffer__($self, flags, /)\n--\n\n" + "Return a buffer object that exposes the underlying memory of the object."), + BUFSLOT(__release_buffer__, bf_releasebuffer, slot_bf_releasebuffer, wrap_releasebuffer, + "__release_buffer__($self, buffer, /)\n--\n\n" + "Release the buffer object that exposes the underlying memory of the object."), + + AMSLOT(__await__, am_await, slot_am_await, wrap_unaryfunc, "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), - AMSLOT("__aiter__", am_aiter, slot_am_aiter, wrap_unaryfunc, + AMSLOT(__aiter__, am_aiter, slot_am_aiter, wrap_unaryfunc, "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), - AMSLOT("__anext__", am_anext, slot_am_anext, wrap_unaryfunc, + AMSLOT(__anext__, am_anext, slot_am_anext, wrap_unaryfunc, "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), - BINSLOT("__add__", nb_add, slot_nb_add, + BINSLOT(__add__, nb_add, slot_nb_add, "+"), - RBINSLOT("__radd__", nb_add, slot_nb_add, + RBINSLOT(__radd__, nb_add, slot_nb_add, "+"), - BINSLOT("__sub__", nb_subtract, slot_nb_subtract, + BINSLOT(__sub__, nb_subtract, slot_nb_subtract, "-"), - RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, + RBINSLOT(__rsub__, nb_subtract, slot_nb_subtract, "-"), - BINSLOT("__mul__", nb_multiply, slot_nb_multiply, + BINSLOT(__mul__, nb_multiply, slot_nb_multiply, "*"), - RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, + RBINSLOT(__rmul__, nb_multiply, slot_nb_multiply, "*"), - BINSLOT("__mod__", nb_remainder, slot_nb_remainder, + BINSLOT(__mod__, nb_remainder, slot_nb_remainder, "%"), - RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, + RBINSLOT(__rmod__, nb_remainder, slot_nb_remainder, "%"), - BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, + BINSLOTNOTINFIX(__divmod__, nb_divmod, slot_nb_divmod, "Return divmod(self, value)."), - RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, + RBINSLOTNOTINFIX(__rdivmod__, nb_divmod, slot_nb_divmod, "Return divmod(value, self)."), - NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, + NBSLOT(__pow__, nb_power, slot_nb_power, wrap_ternaryfunc, "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), - NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, + NBSLOT(__rpow__, nb_power, slot_nb_power, wrap_ternaryfunc_r, "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), - UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), - UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), - UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, + UNSLOT(__neg__, nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), + UNSLOT(__pos__, nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), + UNSLOT(__abs__, nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(self)"), - UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, + UNSLOT(__bool__, nb_bool, slot_nb_bool, wrap_inquirypred, "True if self else False"), - UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), - BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), - RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), - BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), - RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), - BINSLOT("__and__", nb_and, slot_nb_and, "&"), - RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), - BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), - RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), - BINSLOT("__or__", nb_or, slot_nb_or, "|"), - RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), - UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + UNSLOT(__invert__, nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), + BINSLOT(__lshift__, nb_lshift, slot_nb_lshift, "<<"), + RBINSLOT(__rlshift__, nb_lshift, slot_nb_lshift, "<<"), + BINSLOT(__rshift__, nb_rshift, slot_nb_rshift, ">>"), + RBINSLOT(__rrshift__, nb_rshift, slot_nb_rshift, ">>"), + BINSLOT(__and__, nb_and, slot_nb_and, "&"), + RBINSLOT(__rand__, nb_and, slot_nb_and, "&"), + BINSLOT(__xor__, nb_xor, slot_nb_xor, "^"), + RBINSLOT(__rxor__, nb_xor, slot_nb_xor, "^"), + BINSLOT(__or__, nb_or, slot_nb_or, "|"), + RBINSLOT(__ror__, nb_or, slot_nb_or, "|"), + UNSLOT(__int__, nb_int, slot_nb_int, wrap_unaryfunc, "int(self)"), - UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + UNSLOT(__float__, nb_float, slot_nb_float, wrap_unaryfunc, "float(self)"), - IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, + IBSLOT(__iadd__, nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), - IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, + IBSLOT(__isub__, nb_inplace_subtract, slot_nb_inplace_subtract, wrap_binaryfunc, "-="), - IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, + IBSLOT(__imul__, nb_inplace_multiply, slot_nb_inplace_multiply, wrap_binaryfunc, "*="), - IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, + IBSLOT(__imod__, nb_inplace_remainder, slot_nb_inplace_remainder, wrap_binaryfunc, "%="), - IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, + IBSLOT(__ipow__, nb_inplace_power, slot_nb_inplace_power, wrap_ternaryfunc, "**="), - IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, + IBSLOT(__ilshift__, nb_inplace_lshift, slot_nb_inplace_lshift, wrap_binaryfunc, "<<="), - IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, + IBSLOT(__irshift__, nb_inplace_rshift, slot_nb_inplace_rshift, wrap_binaryfunc, ">>="), - IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, + IBSLOT(__iand__, nb_inplace_and, slot_nb_inplace_and, wrap_binaryfunc, "&="), - IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, + IBSLOT(__ixor__, nb_inplace_xor, slot_nb_inplace_xor, wrap_binaryfunc, "^="), - IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, + IBSLOT(__ior__, nb_inplace_or, slot_nb_inplace_or, wrap_binaryfunc, "|="), - BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), - RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), - IBSLOT("__ifloordiv__", nb_inplace_floor_divide, + BINSLOT(__floordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + RBINSLOT(__rfloordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + BINSLOT(__truediv__, nb_true_divide, slot_nb_true_divide, "/"), + RBINSLOT(__rtruediv__, nb_true_divide, slot_nb_true_divide, "/"), + IBSLOT(__ifloordiv__, nb_inplace_floor_divide, slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), - IBSLOT("__itruediv__", nb_inplace_true_divide, + IBSLOT(__itruediv__, nb_inplace_true_divide, slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + NBSLOT(__index__, nb_index, slot_nb_index, wrap_unaryfunc, "__index__($self, /)\n--\n\n" "Return self converted to an integer, if self is suitable " "for use as an index into a list."), - BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + BINSLOT(__matmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + RBINSLOT(__rmatmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, + IBSLOT(__imatmul__, nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, wrap_binaryfunc, "@="), - MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, + MPSLOT(__len__, mp_length, slot_mp_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), - MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, + MPSLOT(__getitem__, mp_subscript, slot_mp_subscript, wrap_binaryfunc, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__setitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__delitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, + SQSLOT(__len__, sq_length, slot_sq_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. The logic in abstract.c always falls back to nb_add/nb_multiply in this case. Defining both the nb_* and the sq_* slots to call the user-defined methods has unexpected side-effects, as shown by test_descr.notimplemented() */ - SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + SQSLOT(__add__, sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), - SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__mul__, sq_repeat, NULL, wrap_indexargfunc, "__mul__($self, value, /)\n--\n\nReturn self*value."), - SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__rmul__, sq_repeat, NULL, wrap_indexargfunc, "__rmul__($self, value, /)\n--\n\nReturn value*self."), - SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, + SQSLOT(__getitem__, sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, + SQSLOT(__setitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, + SQSLOT(__delitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, - "__contains__($self, key, /)\n--\n\nReturn key in self."), - SQSLOT("__iadd__", sq_inplace_concat, NULL, + SQSLOT(__contains__, sq_contains, slot_sq_contains, wrap_objobjproc, + "__contains__($self, key, /)\n--\n\nReturn bool(key in self)."), + SQSLOT(__iadd__, sq_inplace_concat, NULL, wrap_binaryfunc, "__iadd__($self, value, /)\n--\n\nImplement self+=value."), - SQSLOT("__imul__", sq_inplace_repeat, NULL, + SQSLOT(__imul__, sq_inplace_repeat, NULL, wrap_indexargfunc, "__imul__($self, value, /)\n--\n\nImplement self*=value."), @@ -8237,8 +9640,12 @@ slotptr(PyTypeObject *type, int ioffset) /* Note: this depends on the order of the members of PyHeapTypeObject! */ assert(offset >= 0); - assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer)); - if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) { + assert((size_t)offset < offsetof(PyHeapTypeObject, ht_name)); + if ((size_t)offset >= offsetof(PyHeapTypeObject, as_buffer)) { + ptr = (char *)type->tp_as_buffer; + offset -= offsetof(PyHeapTypeObject, as_buffer); + } + else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) { ptr = (char *)type->tp_as_sequence; offset -= offsetof(PyHeapTypeObject, as_sequence); } @@ -8262,12 +9669,6 @@ slotptr(PyTypeObject *type, int ioffset) return (void **)ptr; } -/* Length of array of slotdef pointers used to store slots with the - same __name__. There should be at most MAX_EQUIV-1 slotdef entries with - the same __name__, for any __name__. Since that's a static property, it is - appropriate to declare fixed-size arrays for this. */ -#define MAX_EQUIV 10 - /* Return a slot pointer for a given name, but ONLY if the attribute has exactly one slot function. The name must be an interned string. */ static void ** @@ -8276,9 +9677,10 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) /* XXX Maybe this could be optimized more -- but is it worth it? */ /* pname and ptrs act as a little cache */ - static PyObject *pname; - static slotdef *ptrs[MAX_EQUIV]; - slotdef *p, **pp; + PyInterpreterState *interp = _PyInterpreterState_Get(); +#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname) +#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs) + pytype_slotdef *p, **pp; void **res, **ptr; if (pname != name) { @@ -8305,6 +9707,8 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) res = ptr; } return res; +#undef pname +#undef ptrs } @@ -8362,13 +9766,22 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) * When done, return a pointer to the next slotdef with a different offset, * because that's convenient for fixup_slot_dispatchers(). This function never * sets an exception: if an internal error happens (unlikely), it's ignored. */ -static slotdef * -update_one_slot(PyTypeObject *type, slotdef *p) +static pytype_slotdef * +update_one_slot(PyTypeObject *type, pytype_slotdef *p) { PyObject *descr; PyWrapperDescrObject *d; - void *generic = NULL, *specific = NULL; + + // The correct specialized C function, like "tp_repr of str" in the + // example above + void *specific = NULL; + + // A generic wrapper that uses method lookup (safe but slow) + void *generic = NULL; + + // Set to 1 if the generic wrapper is necessary int use_generic = 0; + int offset = p->offset; int error; void **ptr = slotptr(type, offset); @@ -8451,6 +9864,10 @@ update_one_slot(PyTypeObject *type, slotdef *p) else { use_generic = 1; generic = p->function; + if (p->function == slot_tp_call) { + /* A generic __call__ is incompatible with vectorcall */ + type->tp_flags &= ~Py_TPFLAGS_HAVE_VECTORCALL; + } } } while ((++p)->offset == offset); if (specific && !use_generic) @@ -8465,61 +9882,29 @@ update_one_slot(PyTypeObject *type, slotdef *p) static int update_slots_callback(PyTypeObject *type, void *data) { - slotdef **pp = (slotdef **)data; + pytype_slotdef **pp = (pytype_slotdef **)data; for (; *pp; pp++) { update_one_slot(type, *pp); } return 0; } -static int slotdefs_initialized = 0; -/* Initialize the slotdefs table by adding interned string objects for the - names. */ -PyStatus -_PyTypes_InitSlotDefs(void) -{ - if (slotdefs_initialized) { - return _PyStatus_OK(); - } - - for (slotdef *p = slotdefs; p->name; p++) { - /* Slots must be ordered by their offset in the PyHeapTypeObject. */ - assert(!p[1].name || p->offset <= p[1].offset); - /* bpo-40521: Interned strings are shared by all subinterpreters */ - p->name_strobj = PyUnicode_InternFromString(p->name); - if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) { - return _PyStatus_NO_MEMORY(); - } - } - slotdefs_initialized = 1; - return _PyStatus_OK(); -} - -/* Undo _PyTypes_InitSlotDefs(), releasing the interned strings. */ -static void clear_slotdefs(void) -{ - for (slotdef *p = slotdefs; p->name; p++) { - Py_CLEAR(p->name_strobj); - } - slotdefs_initialized = 0; -} - /* Update the slots after assignment to a class (type) attribute. */ static int update_slot(PyTypeObject *type, PyObject *name) { - slotdef *ptrs[MAX_EQUIV]; - slotdef *p; - slotdef **pp; + pytype_slotdef *ptrs[MAX_EQUIV]; + pytype_slotdef *p; + pytype_slotdef **pp; int offset; assert(PyUnicode_CheckExact(name)); assert(PyUnicode_CHECK_INTERNED(name)); - assert(slotdefs_initialized); pp = ptrs; for (p = slotdefs; p->name; p++) { assert(PyUnicode_CheckExact(p->name_strobj)); + assert(PyUnicode_CHECK_INTERNED(p->name_strobj)); assert(PyUnicode_CheckExact(name)); /* bpo-40521: Using interned strings. */ if (p->name_strobj == name) { @@ -8547,8 +9932,7 @@ static void fixup_slot_dispatchers(PyTypeObject *type) { assert(!PyErr_Occurred()); - assert(slotdefs_initialized); - for (slotdef *p = slotdefs; p->name; ) { + for (pytype_slotdef *p = slotdefs; p->name; ) { p = update_one_slot(type, p); } } @@ -8556,12 +9940,11 @@ fixup_slot_dispatchers(PyTypeObject *type) static void update_all_slots(PyTypeObject* type) { - slotdef *p; + pytype_slotdef *p; /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ PyType_Modified(type); - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { /* update_slot returns int but can't actually fail */ update_slot(type, p->name_strobj); @@ -8574,7 +9957,8 @@ update_all_slots(PyTypeObject* type) static int type_new_set_names(PyTypeObject *type) { - PyObject *names_to_set = PyDict_Copy(type->tp_dict); + PyObject *dict = lookup_tp_dict(type); + PyObject *names_to_set = PyDict_Copy(dict); if (names_to_set == NULL) { return -1; } @@ -8595,13 +9979,15 @@ type_new_set_names(PyTypeObject *type) Py_DECREF(set_name); if (res == NULL) { - _PyErr_FormatFromCause(PyExc_RuntimeError, + _PyErr_FormatNote( "Error calling __set_name__ on '%.100s' instance %R " "in '%.100s'", Py_TYPE(value)->tp_name, key, type->tp_name); goto error; } - Py_DECREF(res); + else { + Py_DECREF(res); + } } Py_DECREF(names_to_set); @@ -8661,7 +10047,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, // It is safe to use a borrowed reference because update_subclasses() is // only used with update_slots_callback() which doesn't modify // tp_subclasses. - PyObject *subclasses = type->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(type); // borrowed ref if (subclasses == NULL) { return 0; } @@ -8670,16 +10056,13 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); - assert(obj != NULL); - if (obj == Py_None) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { continue; } - PyTypeObject *subclass = _PyType_CAST(obj); /* Avoid recursing down into unaffected classes */ - PyObject *dict = subclass->tp_dict; + PyObject *dict = lookup_tp_dict(subclass); if (dict != NULL && PyDict_Check(dict)) { int r = PyDict_Contains(dict, attr_name); if (r < 0) { @@ -8730,12 +10113,11 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, static int add_operators(PyTypeObject *type) { - PyObject *dict = type->tp_dict; - slotdef *p; + PyObject *dict = lookup_tp_dict(type); + pytype_slotdef *p; PyObject *descr; void **ptr; - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { if (p->wrapper == NULL) continue; @@ -8817,65 +10199,43 @@ super_repr(PyObject *self) su->type ? su->type->tp_name : "NULL"); } +/* Do a super lookup without executing descriptors or falling back to getattr +on the super object itself. + +May return NULL with or without an exception set, like PyDict_GetItemWithError. */ static PyObject * -super_getattro(PyObject *self, PyObject *name) +_super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *name) { - superobject *su = (superobject *)self; - PyTypeObject *starttype; - PyObject *mro; + PyObject *mro, *res; Py_ssize_t i, n; - starttype = su->obj_type; - if (starttype == NULL) - goto skip; - - /* We want __class__ to return the class of the super object - (i.e. super, or a subclass), not the class of su->obj. */ - if (PyUnicode_Check(name) && - PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_Equal(name, &_Py_ID(__class__))) - goto skip; - - mro = starttype->tp_mro; + mro = lookup_tp_mro(su_obj_type); if (mro == NULL) - goto skip; + return NULL; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); /* No need to check the last one: it's gonna be skipped anyway. */ for (i = 0; i+1 < n; i++) { - if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) + if ((PyObject *)(su_type) == PyTuple_GET_ITEM(mro, i)) break; } i++; /* skip su->type (if any) */ if (i >= n) - goto skip; + return NULL; - /* keep a strong reference to mro because starttype->tp_mro can be + /* keep a strong reference to mro because su_obj_type->tp_mro can be replaced during PyDict_GetItemWithError(dict, name) */ Py_INCREF(mro); do { PyObject *obj = PyTuple_GET_ITEM(mro, i); - PyObject *dict = _PyType_CAST(obj)->tp_dict; + PyObject *dict = lookup_tp_dict(_PyType_CAST(obj)); assert(dict != NULL && PyDict_Check(dict)); - PyObject *res = PyDict_GetItemWithError(dict, name); + res = PyDict_GetItemWithError(dict, name); if (res != NULL) { Py_INCREF(res); - - descrgetfunc f = Py_TYPE(res)->tp_descr_get; - if (f != NULL) { - PyObject *res2; - res2 = f(res, - /* Only pass 'obj' param if this is instance-mode super - (See SF ID #743627) */ - (su->obj == (PyObject *)starttype) ? NULL : su->obj, - (PyObject *)starttype); - Py_DECREF(res); - res = res2; - } - Py_DECREF(mro); return res; } @@ -8887,9 +10247,75 @@ super_getattro(PyObject *self, PyObject *name) i++; } while (i < n); Py_DECREF(mro); + return NULL; +} + +// if `method` is non-NULL, we are looking for a method descriptor, +// and setting `*method = 1` means we found one. +static PyObject * +do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj, + PyTypeObject *su_obj_type, PyObject *name, int *method) +{ + PyObject *res; + int temp_su = 0; + + if (su_obj_type == NULL) { + goto skip; + } + + res = _super_lookup_descr(su_type, su_obj_type, name); + if (res != NULL) { + if (method && _PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + *method = 1; + } + else { + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (f != NULL) { + PyObject *res2; + res2 = f(res, + /* Only pass 'obj' param if this is instance-mode super + (See SF ID #743627) */ + (su_obj == (PyObject *)su_obj_type) ? NULL : su_obj, + (PyObject *)su_obj_type); + Py_SETREF(res, res2); + } + } + + return res; + } + else if (PyErr_Occurred()) { + return NULL; + } skip: - return PyObject_GenericGetAttr(self, name); + if (su == NULL) { + PyObject *args[] = {(PyObject *)su_type, su_obj}; + su = (superobject *)PyObject_Vectorcall((PyObject *)&PySuper_Type, args, 2, NULL); + if (su == NULL) { + return NULL; + } + temp_su = 1; + } + res = PyObject_GenericGetAttr((PyObject *)su, name); + if (temp_su) { + Py_DECREF(su); + } + return res; +} + +static PyObject * +super_getattro(PyObject *self, PyObject *name) +{ + superobject *su = (superobject *)self; + + /* We want __class__ to return the class of the super object + (i.e. super, or a subclass), not the class of su->obj. */ + if (PyUnicode_Check(name) && + PyUnicode_GET_LENGTH(name) == 9 && + _PyUnicode_Equal(name, &_Py_ID(__class__))) + return PyObject_GenericGetAttr(self, name); + + return do_super_lookup(su, su->type, su->obj, su->obj_type, name, NULL); } static PyTypeObject * @@ -8912,14 +10338,12 @@ supercheck(PyTypeObject *type, PyObject *obj) /* Check for first bullet above (special case) */ if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) { - Py_INCREF(obj); - return (PyTypeObject *)obj; + return (PyTypeObject *)Py_NewRef(obj); } /* Normal case */ if (PyType_IsSubtype(Py_TYPE(obj), type)) { - Py_INCREF(Py_TYPE(obj)); - return Py_TYPE(obj); + return (PyTypeObject*)Py_NewRef(Py_TYPE(obj)); } else { /* Try the slow way */ @@ -8947,6 +10371,18 @@ supercheck(PyTypeObject *type, PyObject *obj) return NULL; } +PyObject * +_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *method) +{ + PyTypeObject *su_obj_type = supercheck(su_type, su_obj); + if (su_obj_type == NULL) { + return NULL; + } + PyObject *res = do_super_lookup(NULL, su_type, su_obj, su_obj_type, name, method); + Py_DECREF(su_obj_type); + return res; +} + static PyObject * super_descr_get(PyObject *self, PyObject *obj, PyObject *type) { @@ -8955,8 +10391,7 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) if (obj == NULL || obj == Py_None || su->obj != NULL) { /* Not binding to an object, or already bound */ - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (!Py_IS_TYPE(su, &PySuper_Type)) /* If su is an instance of a (strict) subclass of super, @@ -8974,10 +10409,8 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) Py_DECREF(obj_type); return NULL; } - Py_INCREF(su->type); - Py_INCREF(obj); - newobj->type = su->type; - newobj->obj = obj; + newobj->type = (PyTypeObject*)Py_NewRef(su->type); + newobj->obj = Py_NewRef(obj); newobj->obj_type = obj_type; return (PyObject *)newobj; } @@ -9002,8 +10435,8 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, if (_PyInterpreterFrame_LASTI(cframe) >= 0) { // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // to use _PyOpcode_Deopt here: - assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || - _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); + assert(_PyCode_CODE(co)[0].op.code == MAKE_CELL || + _PyCode_CODE(co)[0].op.code == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); } @@ -9016,7 +10449,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, // Look for __class__ in the free vars. PyTypeObject *type = NULL; - int i = co->co_nlocals + co->co_nplaincellvars; + int i = PyCode_GetFirstFree(co); for (; i < co->co_nlocalsplus; i++) { assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); @@ -9080,13 +10513,13 @@ super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *cframe = tstate->cframe->current_frame; - if (cframe == NULL) { + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); + if (frame == NULL) { PyErr_SetString(PyExc_RuntimeError, "super(): no current frame"); return -1; } - int res = super_init_without_args(cframe, cframe->f_code, &type, &obj); + int res = super_init_without_args(frame, frame->f_code, &type, &obj); if (res < 0) { return -1; @@ -9101,8 +10534,7 @@ super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { return -1; Py_INCREF(obj); } - Py_INCREF(type); - Py_XSETREF(su->type, type); + Py_XSETREF(su->type, (PyTypeObject*)Py_NewRef(type)); Py_XSETREF(su->obj, obj); Py_XSETREF(su->obj_type, obj_type); return 0; diff --git a/contrib/tools/python3/src/Objects/typevarobject.c b/contrib/tools/python3/src/Objects/typevarobject.c new file mode 100644 index 00000000000..db9c2191d60 --- /dev/null +++ b/contrib/tools/python3/src/Objects/typevarobject.c @@ -0,0 +1,1691 @@ +// TypeVar, TypeVarTuple, and ParamSpec +#include "Python.h" +#include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK +#include "pycore_typevarobject.h" +#include "pycore_unionobject.h" // _Py_union_type_or +#include "structmember.h" + +/*[clinic input] +class typevar "typevarobject *" "&_PyTypeVar_Type" +class paramspec "paramspecobject *" "&_PyParamSpec_Type" +class paramspecargs "paramspecattrobject *" "&_PyParamSpecArgs_Type" +class paramspeckwargs "paramspecattrobject *" "&_PyParamSpecKwargs_Type" +class typevartuple "typevartupleobject *" "&_PyTypeVarTuple_Type" +class typealias "typealiasobject *" "&_PyTypeAlias_Type" +class Generic "PyObject *" "&PyGeneric_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa86741931a0f55c]*/ + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *bound; + PyObject *evaluate_bound; + PyObject *constraints; + PyObject *evaluate_constraints; + bool covariant; + bool contravariant; + bool infer_variance; +} typevarobject; + +typedef struct { + PyObject_HEAD + PyObject *name; +} typevartupleobject; + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *bound; + bool covariant; + bool contravariant; + bool infer_variance; +} paramspecobject; + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *type_params; + PyObject *compute_value; + PyObject *value; + PyObject *module; +} typealiasobject; + +#include "clinic/typevarobject.c.h" + +static PyObject * +call_typing_func_object(const char *name, PyObject **args, size_t nargs) +{ + PyObject *typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + return NULL; + } + PyObject *func = PyObject_GetAttrString(typing, name); + if (func == NULL) { + Py_DECREF(typing); + return NULL; + } + PyObject *result = PyObject_Vectorcall(func, args, nargs, NULL); + Py_DECREF(func); + Py_DECREF(typing); + return result; +} + +static PyObject * +type_check(PyObject *arg, const char *msg) +{ + // Calling typing.py here leads to bootstrapping problems + if (Py_IsNone(arg)) { + return Py_NewRef(Py_TYPE(arg)); + } + PyObject *message_str = PyUnicode_FromString(msg); + if (message_str == NULL) { + return NULL; + } + PyObject *args[2] = {arg, message_str}; + PyObject *result = call_typing_func_object("_type_check", args, 2); + Py_DECREF(message_str); + return result; +} + +/* + * Return a typing.Union. This is used as the nb_or (|) operator for + * TypeVar and ParamSpec. We use this rather than _Py_union_type_or + * (which would produce a types.Union) because historically TypeVar + * supported unions with string forward references, and we want to + * preserve that behavior. _Py_union_type_or only allows a small set + * of types. + */ +static PyObject * +make_union(PyObject *self, PyObject *other) +{ + PyObject *args[2] = {self, other}; + PyObject *result = call_typing_func_object("_make_union", args, 2); + return result; +} + +static PyObject * +caller(void) +{ + _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + if (f == NULL) { + Py_RETURN_NONE; + } + if (f == NULL || f->f_funcobj == NULL) { + Py_RETURN_NONE; + } + PyObject *r = PyFunction_GetModule(f->f_funcobj); + if (!r) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return Py_NewRef(r); +} + +static PyObject * +typevartuple_unpack(PyObject *tvt) +{ + PyObject *typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + return NULL; + } + PyObject *unpack = PyObject_GetAttrString(typing, "Unpack"); + if (unpack == NULL) { + Py_DECREF(typing); + return NULL; + } + PyObject *unpacked = PyObject_GetItem(unpack, tvt); + Py_DECREF(typing); + Py_DECREF(unpack); + return unpacked; +} + +static int +contains_typevartuple(PyTupleObject *params) +{ + Py_ssize_t n = PyTuple_GET_SIZE(params); + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *param = PyTuple_GET_ITEM(params, i); + if (Py_IS_TYPE(param, tp)) { + return 1; + } + } + return 0; +} + +static PyObject * +unpack_typevartuples(PyObject *params) +{ + assert(PyTuple_Check(params)); + // TypeVarTuple must be unpacked when passed to Generic, so we do that here. + if (contains_typevartuple((PyTupleObject *)params)) { + Py_ssize_t n = PyTuple_GET_SIZE(params); + PyObject *new_params = PyTuple_New(n); + if (new_params == NULL) { + return NULL; + } + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *param = PyTuple_GET_ITEM(params, i); + if (Py_IS_TYPE(param, tp)) { + PyObject *unpacked = typevartuple_unpack(param); + if (unpacked == NULL) { + Py_DECREF(new_params); + return NULL; + } + PyTuple_SET_ITEM(new_params, i, unpacked); + } + else { + PyTuple_SET_ITEM(new_params, i, Py_NewRef(param)); + } + } + return new_params; + } + else { + return Py_NewRef(params); + } +} + +static void +typevar_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + typevarobject *tv = (typevarobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_DECREF(tv->name); + Py_XDECREF(tv->bound); + Py_XDECREF(tv->evaluate_bound); + Py_XDECREF(tv->constraints); + Py_XDECREF(tv->evaluate_constraints); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +typevar_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + typevarobject *tv = (typevarobject *)self; + Py_VISIT(tv->bound); + Py_VISIT(tv->evaluate_bound); + Py_VISIT(tv->constraints); + Py_VISIT(tv->evaluate_constraints); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +typevar_clear(typevarobject *self) +{ + Py_CLEAR(self->bound); + Py_CLEAR(self->evaluate_bound); + Py_CLEAR(self->constraints); + Py_CLEAR(self->evaluate_constraints); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static PyObject * +typevar_repr(PyObject *self) +{ + typevarobject *tv = (typevarobject *)self; + + if (tv->infer_variance) { + return Py_NewRef(tv->name); + } + + char variance = tv->covariant ? '+' : tv->contravariant ? '-' : '~'; + return PyUnicode_FromFormat("%c%U", variance, tv->name); +} + +static PyMemberDef typevar_members[] = { + {"__name__", T_OBJECT, offsetof(typevarobject, name), READONLY}, + {"__covariant__", T_BOOL, offsetof(typevarobject, covariant), READONLY}, + {"__contravariant__", T_BOOL, offsetof(typevarobject, contravariant), READONLY}, + {"__infer_variance__", T_BOOL, offsetof(typevarobject, infer_variance), READONLY}, + {0} +}; + +static PyObject * +typevar_bound(typevarobject *self, void *Py_UNUSED(ignored)) +{ + if (self->bound != NULL) { + return Py_NewRef(self->bound); + } + if (self->evaluate_bound == NULL) { + Py_RETURN_NONE; + } + PyObject *bound = PyObject_CallNoArgs(self->evaluate_bound); + self->bound = Py_XNewRef(bound); + return bound; +} + +static PyObject * +typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored)) +{ + if (self->constraints != NULL) { + return Py_NewRef(self->constraints); + } + if (self->evaluate_constraints == NULL) { + return PyTuple_New(0); + } + PyObject *constraints = PyObject_CallNoArgs(self->evaluate_constraints); + self->constraints = Py_XNewRef(constraints); + return constraints; +} + +static PyGetSetDef typevar_getset[] = { + {"__bound__", (getter)typevar_bound, NULL, NULL, NULL}, + {"__constraints__", (getter)typevar_constraints, NULL, NULL, NULL}, + {0} +}; + +static typevarobject * +typevar_alloc(PyObject *name, PyObject *bound, PyObject *evaluate_bound, + PyObject *constraints, PyObject *evaluate_constraints, + bool covariant, bool contravariant, bool infer_variance, + PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevar_type; + assert(tp != NULL); + typevarobject *tv = PyObject_GC_New(typevarobject, tp); + if (tv == NULL) { + return NULL; + } + + tv->name = Py_NewRef(name); + + tv->bound = Py_XNewRef(bound); + tv->evaluate_bound = Py_XNewRef(evaluate_bound); + tv->constraints = Py_XNewRef(constraints); + tv->evaluate_constraints = Py_XNewRef(evaluate_constraints); + + tv->covariant = covariant; + tv->contravariant = contravariant; + tv->infer_variance = infer_variance; + _PyObject_GC_TRACK(tv); + + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)tv, "__module__", module) < 0) { + Py_DECREF(tv); + return NULL; + } + } + + return tv; +} + +/*[clinic input] +@classmethod +typevar.__new__ as typevar_new + + name: object(subclass_of="&PyUnicode_Type") + *constraints: object + * + bound: object = None + covariant: bool = False + contravariant: bool = False + infer_variance: bool = False + +Create a TypeVar. +[clinic start generated code]*/ + +static PyObject * +typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, + PyObject *bound, int covariant, int contravariant, + int infer_variance) +/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/ +{ + if (covariant && contravariant) { + PyErr_SetString(PyExc_ValueError, + "Bivariant types are not supported."); + return NULL; + } + + if (infer_variance && (covariant || contravariant)) { + PyErr_SetString(PyExc_ValueError, + "Variance cannot be specified with infer_variance."); + return NULL; + } + + if (Py_IsNone(bound)) { + bound = NULL; + } + if (bound != NULL) { + bound = type_check(bound, "Bound must be a type."); + if (bound == NULL) { + return NULL; + } + } + + if (constraints != NULL) { + if (!PyTuple_CheckExact(constraints)) { + PyErr_SetString(PyExc_TypeError, + "constraints must be a tuple"); + return NULL; + } + Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints); + if (n_constraints == 1) { + PyErr_SetString(PyExc_TypeError, + "A single constraint is not allowed"); + Py_XDECREF(bound); + return NULL; + } else if (n_constraints == 0) { + constraints = NULL; + } else if (bound != NULL) { + PyErr_SetString(PyExc_TypeError, + "Constraints cannot be combined with bound=..."); + Py_XDECREF(bound); + return NULL; + } + } + PyObject *module = caller(); + if (module == NULL) { + Py_XDECREF(bound); + return NULL; + } + + PyObject *tv = (PyObject *)typevar_alloc(name, bound, NULL, + constraints, NULL, + covariant, contravariant, + infer_variance, module); + Py_XDECREF(bound); + Py_XDECREF(module); + return tv; +} + +/*[clinic input] +typevar.__typing_subst__ as typevar_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +typevar_typing_subst_impl(typevarobject *self, PyObject *arg) +/*[clinic end generated code: output=c76ced134ed8f4e1 input=6b70a4bb2da838de]*/ +{ + PyObject *args[2] = {(PyObject *)self, arg}; + PyObject *result = call_typing_func_object("_typevar_subst", args, 2); + return result; +} + +/*[clinic input] +typevar.__reduce__ as typevar_reduce + +[clinic start generated code]*/ + +static PyObject * +typevar_reduce_impl(typevarobject *self) +/*[clinic end generated code: output=02e5c55d7cf8a08f input=de76bc95f04fb9ff]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typevar_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of TypeVar"); + return NULL; +} + +static PyMethodDef typevar_methods[] = { + TYPEVAR_TYPING_SUBST_METHODDEF + TYPEVAR_REDUCE_METHODDEF + {"__mro_entries__", typevar_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(typevar_doc, +"Type variable.\n\ +\n\ +The preferred way to construct a type variable is via the dedicated\n\ +syntax for generic functions, classes, and type aliases::\n\ +\n\ + class Sequence[T]: # T is a TypeVar\n\ + ...\n\ +\n\ +This syntax can also be used to create bound and constrained type\n\ +variables::\n\ +\n\ + # S is a TypeVar bound to str\n\ + class StrSequence[S: str]:\n\ + ...\n\ +\n\ + # A is a TypeVar constrained to str or bytes\n\ + class StrOrBytesSequence[A: (str, bytes)]:\n\ + ...\n\ +\n\ +However, if desired, reusable type variables can also be constructed\n\ +manually, like so::\n\ +\n\ + T = TypeVar('T') # Can be anything\n\ + S = TypeVar('S', bound=str) # Can be any subtype of str\n\ + A = TypeVar('A', str, bytes) # Must be exactly str or bytes\n\ +\n\ +Type variables exist primarily for the benefit of static type\n\ +checkers. They serve as the parameters for generic types as well\n\ +as for generic function and type alias definitions.\n\ +\n\ +The variance of type variables is inferred by type checkers when they\n\ +are created through the type parameter syntax and when\n\ +``infer_variance=True`` is passed. Manually created type variables may\n\ +be explicitly marked covariant or contravariant by passing\n\ +``covariant=True`` or ``contravariant=True``. By default, manually\n\ +created type variables are invariant. See PEP 484 and PEP 695 for more\n\ +details.\n\ +"); + +static PyType_Slot typevar_slots[] = { + {Py_tp_doc, (void *)typevar_doc}, + {Py_tp_methods, typevar_methods}, + {Py_nb_or, make_union}, + {Py_tp_new, typevar_new}, + {Py_tp_dealloc, typevar_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, typevar_traverse}, + {Py_tp_clear, typevar_clear}, + {Py_tp_repr, typevar_repr}, + {Py_tp_members, typevar_members}, + {Py_tp_getset, typevar_getset}, + {0, NULL}, +}; + +PyType_Spec typevar_spec = { + .name = "typing.TypeVar", + .basicsize = sizeof(typevarobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = typevar_slots, +}; + +typedef struct { + PyObject_HEAD + PyObject *__origin__; +} paramspecattrobject; + +static void +paramspecattr_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + paramspecattrobject *psa = (paramspecattrobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_XDECREF(psa->__origin__); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +paramspecattr_traverse(PyObject *self, visitproc visit, void *arg) +{ + paramspecattrobject *psa = (paramspecattrobject *)self; + Py_VISIT(psa->__origin__); + return 0; +} + +static int +paramspecattr_clear(paramspecattrobject *self) +{ + Py_CLEAR(self->__origin__); + return 0; +} + +static PyObject * +paramspecattr_richcompare(PyObject *a, PyObject *b, int op) +{ + if (!Py_IS_TYPE(a, Py_TYPE(b))) { + Py_RETURN_NOTIMPLEMENTED; + } + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + return PyObject_RichCompare( + ((paramspecattrobject *)a)->__origin__, + ((paramspecattrobject *)b)->__origin__, + op + ); +} + +static PyMemberDef paramspecattr_members[] = { + {"__origin__", T_OBJECT, offsetof(paramspecattrobject, __origin__), READONLY}, + {0} +}; + +static paramspecattrobject * +paramspecattr_new(PyTypeObject *tp, PyObject *origin) +{ + paramspecattrobject *psa = PyObject_GC_New(paramspecattrobject, tp); + if (psa == NULL) { + return NULL; + } + psa->__origin__ = Py_NewRef(origin); + _PyObject_GC_TRACK(psa); + return psa; +} + +static PyObject * +paramspecargs_repr(PyObject *self) +{ + paramspecattrobject *psa = (paramspecattrobject *)self; + + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + if (Py_IS_TYPE(psa->__origin__, tp)) { + return PyUnicode_FromFormat("%U.args", + ((paramspecobject *)psa->__origin__)->name); + } + return PyUnicode_FromFormat("%R.args", psa->__origin__); +} + + +/*[clinic input] +@classmethod +paramspecargs.__new__ as paramspecargs_new + + origin: object + +Create a ParamSpecArgs object. +[clinic start generated code]*/ + +static PyObject * +paramspecargs_new_impl(PyTypeObject *type, PyObject *origin) +/*[clinic end generated code: output=9a1463dc8942fe4e input=3596a0bb6183c208]*/ +{ + return (PyObject *)paramspecattr_new(type, origin); +} + +static PyObject * +paramspecargs_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpecArgs"); + return NULL; +} + +static PyMethodDef paramspecargs_methods[] = { + {"__mro_entries__", paramspecargs_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspecargs_doc, +"The args for a ParamSpec object.\n\ +\n\ +Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\ +\n\ +ParamSpecArgs objects have a reference back to their ParamSpec::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.args.__origin__ is P\n\ + True\n\ +\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ +"); + +static PyType_Slot paramspecargs_slots[] = { + {Py_tp_doc, (void *)paramspecargs_doc}, + {Py_tp_methods, paramspecargs_methods}, + {Py_tp_new, paramspecargs_new}, + {Py_tp_dealloc, paramspecattr_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspecattr_traverse}, + {Py_tp_clear, (inquiry)paramspecattr_clear}, + {Py_tp_repr, paramspecargs_repr}, + {Py_tp_members, paramspecattr_members}, + {Py_tp_richcompare, paramspecattr_richcompare}, + {0, NULL}, +}; + +PyType_Spec paramspecargs_spec = { + .name = "typing.ParamSpecArgs", + .basicsize = sizeof(paramspecattrobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspecargs_slots, +}; + +static PyObject * +paramspeckwargs_repr(PyObject *self) +{ + paramspecattrobject *psk = (paramspecattrobject *)self; + + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + if (Py_IS_TYPE(psk->__origin__, tp)) { + return PyUnicode_FromFormat("%U.kwargs", + ((paramspecobject *)psk->__origin__)->name); + } + return PyUnicode_FromFormat("%R.kwargs", psk->__origin__); +} + +/*[clinic input] +@classmethod +paramspeckwargs.__new__ as paramspeckwargs_new + + origin: object + +Create a ParamSpecKwargs object. +[clinic start generated code]*/ + +static PyObject * +paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin) +/*[clinic end generated code: output=277b11967ebaf4ab input=981bca9b0cf9e40a]*/ +{ + return (PyObject *)paramspecattr_new(type, origin); +} + +static PyObject * +paramspeckwargs_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpecKwargs"); + return NULL; +} + +static PyMethodDef paramspeckwargs_methods[] = { + {"__mro_entries__", paramspeckwargs_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspeckwargs_doc, +"The kwargs for a ParamSpec object.\n\ +\n\ +Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\ +\n\ +ParamSpecKwargs objects have a reference back to their ParamSpec::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.kwargs.__origin__ is P\n\ + True\n\ +\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ +"); + +static PyType_Slot paramspeckwargs_slots[] = { + {Py_tp_doc, (void *)paramspeckwargs_doc}, + {Py_tp_methods, paramspeckwargs_methods}, + {Py_tp_new, paramspeckwargs_new}, + {Py_tp_dealloc, paramspecattr_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspecattr_traverse}, + {Py_tp_clear, (inquiry)paramspecattr_clear}, + {Py_tp_repr, paramspeckwargs_repr}, + {Py_tp_members, paramspecattr_members}, + {Py_tp_richcompare, paramspecattr_richcompare}, + {0, NULL}, +}; + +PyType_Spec paramspeckwargs_spec = { + .name = "typing.ParamSpecKwargs", + .basicsize = sizeof(paramspecattrobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspeckwargs_slots, +}; + +static void +paramspec_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + paramspecobject *ps = (paramspecobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_DECREF(ps->name); + Py_XDECREF(ps->bound); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +paramspec_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + paramspecobject *ps = (paramspecobject *)self; + Py_VISIT(ps->bound); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +paramspec_clear(paramspecobject *self) +{ + Py_CLEAR(self->bound); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static PyObject * +paramspec_repr(PyObject *self) +{ + paramspecobject *ps = (paramspecobject *)self; + + if (ps->infer_variance) { + return Py_NewRef(ps->name); + } + + char variance = ps->covariant ? '+' : ps->contravariant ? '-' : '~'; + return PyUnicode_FromFormat("%c%U", variance, ps->name); +} + +static PyMemberDef paramspec_members[] = { + {"__name__", T_OBJECT, offsetof(paramspecobject, name), READONLY}, + {"__bound__", T_OBJECT, offsetof(paramspecobject, bound), READONLY}, + {"__covariant__", T_BOOL, offsetof(paramspecobject, covariant), READONLY}, + {"__contravariant__", T_BOOL, offsetof(paramspecobject, contravariant), READONLY}, + {"__infer_variance__", T_BOOL, offsetof(paramspecobject, infer_variance), READONLY}, + {0} +}; + +static PyObject * +paramspec_args(PyObject *self, void *unused) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspecargs_type; + return (PyObject *)paramspecattr_new(tp, self); +} + +static PyObject * +paramspec_kwargs(PyObject *self, void *unused) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspeckwargs_type; + return (PyObject *)paramspecattr_new(tp, self); +} + +static PyGetSetDef paramspec_getset[] = { + {"args", (getter)paramspec_args, NULL, "Represents positional arguments.", NULL}, + {"kwargs", (getter)paramspec_kwargs, NULL, "Represents keyword arguments.", NULL}, + {0}, +}; + +static paramspecobject * +paramspec_alloc(PyObject *name, PyObject *bound, bool covariant, + bool contravariant, bool infer_variance, PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + paramspecobject *ps = PyObject_GC_New(paramspecobject, tp); + if (ps == NULL) { + return NULL; + } + ps->name = Py_NewRef(name); + ps->bound = Py_XNewRef(bound); + ps->covariant = covariant; + ps->contravariant = contravariant; + ps->infer_variance = infer_variance; + _PyObject_GC_TRACK(ps); + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)ps, "__module__", module) < 0) { + Py_DECREF(ps); + return NULL; + } + } + return ps; +} + +/*[clinic input] +@classmethod +paramspec.__new__ as paramspec_new + + name: object(subclass_of="&PyUnicode_Type") + * + bound: object = None + covariant: bool = False + contravariant: bool = False + infer_variance: bool = False + +Create a ParamSpec object. +[clinic start generated code]*/ + +static PyObject * +paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound, + int covariant, int contravariant, int infer_variance) +/*[clinic end generated code: output=fd2daab79cba62da input=57c49c581979b952]*/ +{ + if (covariant && contravariant) { + PyErr_SetString(PyExc_ValueError, "Bivariant types are not supported."); + return NULL; + } + if (infer_variance && (covariant || contravariant)) { + PyErr_SetString(PyExc_ValueError, "Variance cannot be specified with infer_variance."); + return NULL; + } + if (bound != NULL) { + bound = type_check(bound, "Bound must be a type."); + if (bound == NULL) { + return NULL; + } + } + PyObject *module = caller(); + if (module == NULL) { + Py_XDECREF(bound); + return NULL; + } + PyObject *ps = (PyObject *)paramspec_alloc( + name, bound, covariant, contravariant, infer_variance, module); + Py_XDECREF(bound); + Py_DECREF(module); + return ps; +} + + +/*[clinic input] +paramspec.__typing_subst__ as paramspec_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg) +/*[clinic end generated code: output=803e1ade3f13b57d input=4e0005d24023e896]*/ +{ + PyObject *args[2] = {(PyObject *)self, arg}; + PyObject *result = call_typing_func_object("_paramspec_subst", args, 2); + return result; +} + +/*[clinic input] +paramspec.__typing_prepare_subst__ as paramspec_typing_prepare_subst + + alias: object + args: object + +[clinic start generated code]*/ + +static PyObject * +paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, + PyObject *args) +/*[clinic end generated code: output=95449d630a2adb9a input=4375e2ffcb2ad635]*/ +{ + PyObject *args_array[3] = {(PyObject *)self, alias, args}; + PyObject *result = call_typing_func_object( + "_paramspec_prepare_subst", args_array, 3); + return result; +} + +/*[clinic input] +paramspec.__reduce__ as paramspec_reduce + +[clinic start generated code]*/ + +static PyObject * +paramspec_reduce_impl(paramspecobject *self) +/*[clinic end generated code: output=b83398674416db27 input=5bf349f0d5dd426c]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +paramspec_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpec"); + return NULL; +} + +static PyMethodDef paramspec_methods[] = { + PARAMSPEC_TYPING_SUBST_METHODDEF + PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF + PARAMSPEC_REDUCE_METHODDEF + {"__mro_entries__", paramspec_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspec_doc, +"Parameter specification variable.\n\ +\n\ +The preferred way to construct a parameter specification is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where the use of '**' creates a parameter specification::\n\ +\n\ + type IntFunc[**P] = Callable[P, int]\n\ +\n\ +For compatibility with Python 3.11 and earlier, ParamSpec objects\n\ +can also be created as follows::\n\ +\n\ + P = ParamSpec('P')\n\ +\n\ +Parameter specification variables exist primarily for the benefit of\n\ +static type checkers. They are used to forward the parameter types of\n\ +one callable to another callable, a pattern commonly found in\n\ +higher-order functions and decorators. They are only valid when used\n\ +in ``Concatenate``, or as the first argument to ``Callable``, or as\n\ +parameters for user-defined Generics. See class Generic for more\n\ +information on generic types.\n\ +\n\ +An example for annotating a decorator::\n\ +\n\ + def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:\n\ + '''A type-safe decorator to add logging to a function.'''\n\ + def inner(*args: P.args, **kwargs: P.kwargs) -> T:\n\ + logging.info(f'{f.__name__} was called')\n\ + return f(*args, **kwargs)\n\ + return inner\n\ +\n\ + @add_logging\n\ + def add_two(x: float, y: float) -> float:\n\ + '''Add two numbers together.'''\n\ + return x + y\n\ +\n\ +Parameter specification variables can be introspected. e.g.::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.__name__\n\ + 'P'\n\ +\n\ +Note that only parameter specification variables defined in the global\n\ +scope can be pickled.\n\ +"); + +static PyType_Slot paramspec_slots[] = { + {Py_tp_doc, (void *)paramspec_doc}, + {Py_tp_members, paramspec_members}, + {Py_tp_methods, paramspec_methods}, + {Py_tp_getset, paramspec_getset}, + // Unions of ParamSpecs have no defined meaning, but they were allowed + // by the Python implementation, so we allow them here too. + {Py_nb_or, make_union}, + {Py_tp_new, paramspec_new}, + {Py_tp_dealloc, paramspec_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspec_traverse}, + {Py_tp_clear, paramspec_clear}, + {Py_tp_repr, paramspec_repr}, + {0, 0}, +}; + +PyType_Spec paramspec_spec = { + .name = "typing.ParamSpec", + .basicsize = sizeof(paramspecobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspec_slots, +}; + +static void +typevartuple_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + typevartupleobject *tvt = (typevartupleobject *)self; + + Py_DECREF(tvt->name); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +typevartuple_iter(PyObject *self) +{ + PyObject *unpacked = typevartuple_unpack(self); + if (unpacked == NULL) { + return NULL; + } + PyObject *tuple = PyTuple_Pack(1, unpacked); + if (tuple == NULL) { + Py_DECREF(unpacked); + return NULL; + } + PyObject *result = PyObject_GetIter(tuple); + Py_DECREF(unpacked); + Py_DECREF(tuple); + return result; +} + +static PyObject * +typevartuple_repr(PyObject *self) +{ + typevartupleobject *tvt = (typevartupleobject *)self; + + return Py_NewRef(tvt->name); +} + +static PyMemberDef typevartuple_members[] = { + {"__name__", T_OBJECT, offsetof(typevartupleobject, name), READONLY}, + {0} +}; + +static typevartupleobject * +typevartuple_alloc(PyObject *name, PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + typevartupleobject *tvt = PyObject_GC_New(typevartupleobject, tp); + if (tvt == NULL) { + return NULL; + } + tvt->name = Py_NewRef(name); + _PyObject_GC_TRACK(tvt); + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)tvt, "__module__", module) < 0) { + Py_DECREF(tvt); + return NULL; + } + } + return tvt; +} + +/*[clinic input] +@classmethod +typevartuple.__new__ + + name: object(subclass_of="&PyUnicode_Type") + +Create a new TypeVarTuple with the given name. +[clinic start generated code]*/ + +static PyObject * +typevartuple_impl(PyTypeObject *type, PyObject *name) +/*[clinic end generated code: output=09d417a28f976202 input=00d28abcf1fc96bb]*/ +{ + PyObject *module = caller(); + if (module == NULL) { + return NULL; + } + PyObject *result = (PyObject *)typevartuple_alloc(name, module); + Py_DECREF(module); + return result; +} + +/*[clinic input] +typevartuple.__typing_subst__ as typevartuple_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg) +/*[clinic end generated code: output=814316519441cd76 input=670c4e0a36e5d8c0]*/ +{ + PyErr_SetString(PyExc_TypeError, "Substitution of bare TypeVarTuple is not supported"); + return NULL; +} + +/*[clinic input] +typevartuple.__typing_prepare_subst__ as typevartuple_typing_prepare_subst + + alias: object + args: object + +[clinic start generated code]*/ + +static PyObject * +typevartuple_typing_prepare_subst_impl(typevartupleobject *self, + PyObject *alias, PyObject *args) +/*[clinic end generated code: output=ff999bc5b02036c1 input=a211b05f2eeb4306]*/ +{ + PyObject *args_array[3] = {(PyObject *)self, alias, args}; + PyObject *result = call_typing_func_object( + "_typevartuple_prepare_subst", args_array, 3); + return result; +} + +/*[clinic input] +typevartuple.__reduce__ as typevartuple_reduce + +[clinic start generated code]*/ + +static PyObject * +typevartuple_reduce_impl(typevartupleobject *self) +/*[clinic end generated code: output=3215bc0477913d20 input=3018a4d66147e807]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typevartuple_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of TypeVarTuple"); + return NULL; +} + +static int +typevartuple_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +typevartuple_clear(PyObject *self) +{ + _PyObject_ClearManagedDict(self); + return 0; +} + +static PyMethodDef typevartuple_methods[] = { + TYPEVARTUPLE_TYPING_SUBST_METHODDEF + TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF + TYPEVARTUPLE_REDUCE_METHODDEF + {"__mro_entries__", typevartuple_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(typevartuple_doc, +"Type variable tuple. A specialized form of type variable that enables\n\ +variadic generics.\n\ +\n\ +The preferred way to construct a type variable tuple is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where a single '*' indicates a type variable tuple::\n\ +\n\ + def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\ + return (*tup[1:], tup[0])\n\ +\n\ +For compatibility with Python 3.11 and earlier, TypeVarTuple objects\n\ +can also be created as follows::\n\ +\n\ + Ts = TypeVarTuple('Ts') # Can be given any name\n\ +\n\ +Just as a TypeVar (type variable) is a placeholder for a single type,\n\ +a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\ +example, if we define a generic class using a TypeVarTuple::\n\ +\n\ + class C[*Ts]: ...\n\ +\n\ +Then we can parameterize that class with an arbitrary number of type\n\ +arguments::\n\ +\n\ + C[int] # Fine\n\ + C[int, str] # Also fine\n\ + C[()] # Even this is fine\n\ +\n\ +For more details, see PEP 646.\n\ +\n\ +Note that only TypeVarTuples defined in the global scope can be\n\ +pickled.\n\ +"); + +PyType_Slot typevartuple_slots[] = { + {Py_tp_doc, (void *)typevartuple_doc}, + {Py_tp_members, typevartuple_members}, + {Py_tp_methods, typevartuple_methods}, + {Py_tp_new, typevartuple}, + {Py_tp_iter, typevartuple_iter}, + {Py_tp_repr, typevartuple_repr}, + {Py_tp_dealloc, typevartuple_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, typevartuple_traverse}, + {Py_tp_clear, typevartuple_clear}, + {0, 0}, +}; + +PyType_Spec typevartuple_spec = { + .name = "typing.TypeVarTuple", + .basicsize = sizeof(typevartupleobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT + | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = typevartuple_slots, +}; + +PyObject * +_Py_make_typevar(PyObject *name, PyObject *evaluate_bound, PyObject *evaluate_constraints) +{ + return (PyObject *)typevar_alloc(name, NULL, evaluate_bound, NULL, evaluate_constraints, + false, false, true, NULL); +} + +PyObject * +_Py_make_paramspec(PyThreadState *Py_UNUSED(ignored), PyObject *v) +{ + assert(PyUnicode_Check(v)); + return (PyObject *)paramspec_alloc(v, NULL, false, false, true, NULL); +} + +PyObject * +_Py_make_typevartuple(PyThreadState *Py_UNUSED(ignored), PyObject *v) +{ + assert(PyUnicode_Check(v)); + return (PyObject *)typevartuple_alloc(v, NULL); +} + +static void +typealias_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + typealiasobject *ta = (typealiasobject *)self; + Py_DECREF(ta->name); + Py_XDECREF(ta->type_params); + Py_XDECREF(ta->compute_value); + Py_XDECREF(ta->value); + Py_XDECREF(ta->module); + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +typealias_get_value(typealiasobject *ta) +{ + if (ta->value != NULL) { + return Py_NewRef(ta->value); + } + PyObject *result = PyObject_CallNoArgs(ta->compute_value); + if (result == NULL) { + return NULL; + } + ta->value = Py_NewRef(result); + return result; +} + +static PyObject * +typealias_repr(PyObject *self) +{ + typealiasobject *ta = (typealiasobject *)self; + return Py_NewRef(ta->name); +} + +static PyMemberDef typealias_members[] = { + {"__name__", T_OBJECT, offsetof(typealiasobject, name), READONLY}, + {0} +}; + +static PyObject * +typealias_value(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + return typealias_get_value(ta); +} + +static PyObject * +typealias_parameters(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->type_params == NULL) { + return PyTuple_New(0); + } + return unpack_typevartuples(ta->type_params); +} + +static PyObject * +typealias_type_params(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->type_params == NULL) { + return PyTuple_New(0); + } + return Py_NewRef(ta->type_params); +} + +static PyObject * +typealias_module(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->module != NULL) { + return Py_NewRef(ta->module); + } + if (ta->compute_value != NULL) { + PyObject* mod = PyFunction_GetModule(ta->compute_value); + if (mod != NULL) { + // PyFunction_GetModule() returns a borrowed reference, + // and it may return NULL (e.g., for functions defined + // in an exec()'ed block). + return Py_NewRef(mod); + } + } + Py_RETURN_NONE; +} + +static PyGetSetDef typealias_getset[] = { + {"__parameters__", typealias_parameters, (setter)NULL, NULL, NULL}, + {"__type_params__", typealias_type_params, (setter)NULL, NULL, NULL}, + {"__value__", typealias_value, (setter)NULL, NULL, NULL}, + {"__module__", typealias_module, (setter)NULL, NULL, NULL}, + {0} +}; + +static typealiasobject * +typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value, + PyObject *value, PyObject *module) +{ + typealiasobject *ta = PyObject_GC_New(typealiasobject, &_PyTypeAlias_Type); + if (ta == NULL) { + return NULL; + } + ta->name = Py_NewRef(name); + ta->type_params = Py_IsNone(type_params) ? NULL : Py_XNewRef(type_params); + ta->compute_value = Py_XNewRef(compute_value); + ta->value = Py_XNewRef(value); + ta->module = Py_XNewRef(module); + _PyObject_GC_TRACK(ta); + return ta; +} + +static int +typealias_traverse(typealiasobject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->type_params); + Py_VISIT(self->compute_value); + Py_VISIT(self->value); + Py_VISIT(self->module); + return 0; +} + +static int +typealias_clear(typealiasobject *self) +{ + Py_CLEAR(self->type_params); + Py_CLEAR(self->compute_value); + Py_CLEAR(self->value); + Py_CLEAR(self->module); + return 0; +} + +/*[clinic input] +typealias.__reduce__ as typealias_reduce + +[clinic start generated code]*/ + +static PyObject * +typealias_reduce_impl(typealiasobject *self) +/*[clinic end generated code: output=913724f92ad3b39b input=4f06fbd9472ec0f1]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typealias_subscript(PyObject *self, PyObject *args) +{ + if (((typealiasobject *)self)->type_params == NULL) { + PyErr_SetString(PyExc_TypeError, + "Only generic type aliases are subscriptable"); + return NULL; + } + return Py_GenericAlias(self, args); +} + +static PyMethodDef typealias_methods[] = { + TYPEALIAS_REDUCE_METHODDEF + {0} +}; + + +/*[clinic input] +@classmethod +typealias.__new__ as typealias_new + + name: object(subclass_of="&PyUnicode_Type") + value: object + * + type_params: object = NULL + +Create a TypeAliasType. +[clinic start generated code]*/ + +static PyObject * +typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, + PyObject *type_params) +/*[clinic end generated code: output=8920ce6bdff86f00 input=df163c34e17e1a35]*/ +{ + if (type_params != NULL && !PyTuple_Check(type_params)) { + PyErr_SetString(PyExc_TypeError, "type_params must be a tuple"); + return NULL; + } + PyObject *module = caller(); + if (module == NULL) { + return NULL; + } + PyObject *ta = (PyObject *)typealias_alloc(name, type_params, NULL, value, + module); + Py_DECREF(module); + return ta; +} + +PyDoc_STRVAR(typealias_doc, +"Type alias.\n\ +\n\ +Type aliases are created through the type statement::\n\ +\n\ + type Alias = int\n\ +\n\ +In this example, Alias and int will be treated equivalently by static\n\ +type checkers.\n\ +\n\ +At runtime, Alias is an instance of TypeAliasType. The __name__\n\ +attribute holds the name of the type alias. The value of the type alias\n\ +is stored in the __value__ attribute. It is evaluated lazily, so the\n\ +value is computed only if the attribute is accessed.\n\ +\n\ +Type aliases can also be generic::\n\ +\n\ + type ListOrSet[T] = list[T] | set[T]\n\ +\n\ +In this case, the type parameters of the alias are stored in the\n\ +__type_params__ attribute.\n\ +\n\ +See PEP 695 for more information.\n\ +"); + +static PyNumberMethods typealias_as_number = { + .nb_or = _Py_union_type_or, +}; + +static PyMappingMethods typealias_as_mapping = { + .mp_subscript = typealias_subscript, +}; + +PyTypeObject _PyTypeAlias_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "typing.TypeAliasType", + .tp_basicsize = sizeof(typealiasobject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC, + .tp_doc = typealias_doc, + .tp_members = typealias_members, + .tp_methods = typealias_methods, + .tp_getset = typealias_getset, + .tp_alloc = PyType_GenericAlloc, + .tp_dealloc = typealias_dealloc, + .tp_new = typealias_new, + .tp_free = PyObject_GC_Del, + .tp_traverse = (traverseproc)typealias_traverse, + .tp_clear = (inquiry)typealias_clear, + .tp_repr = typealias_repr, + .tp_as_number = &typealias_as_number, + .tp_as_mapping = &typealias_as_mapping, +}; + +PyObject * +_Py_make_typealias(PyThreadState* unused, PyObject *args) +{ + assert(PyTuple_Check(args)); + assert(PyTuple_GET_SIZE(args) == 3); + PyObject *name = PyTuple_GET_ITEM(args, 0); + assert(PyUnicode_Check(name)); + PyObject *type_params = PyTuple_GET_ITEM(args, 1); + PyObject *compute_value = PyTuple_GET_ITEM(args, 2); + assert(PyFunction_Check(compute_value)); + return (PyObject *)typealias_alloc(name, type_params, compute_value, NULL, NULL); +} + +PyDoc_STRVAR(generic_doc, +"Abstract base class for generic types.\n\ +\n\ +On Python 3.12 and newer, generic classes implicitly inherit from\n\ +Generic when they declare a parameter list after the class's name::\n\ +\n\ + class Mapping[KT, VT]:\n\ + def __getitem__(self, key: KT) -> VT:\n\ + ...\n\ + # Etc.\n\ +\n\ +On older versions of Python, however, generic classes have to\n\ +explicitly inherit from Generic.\n\ +\n\ +After a class has been declared to be generic, it can then be used as\n\ +follows::\n\ +\n\ + def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\ + try:\n\ + return mapping[key]\n\ + except KeyError:\n\ + return default\n\ +"); + +PyDoc_STRVAR(generic_class_getitem_doc, +"Parameterizes a generic class.\n\ +\n\ +At least, parameterizing a generic class is the *main* thing this\n\ +method does. For example, for some generic class `Foo`, this is called\n\ +when we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\ +\n\ +However, note that this method is also called when defining generic\n\ +classes in the first place with `class Foo[T]: ...`.\n\ +"); + +static PyObject * +call_typing_args_kwargs(const char *name, PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + PyObject *typing = NULL, *func = NULL, *new_args = NULL; + typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + goto error; + } + func = PyObject_GetAttrString(typing, name); + if (func == NULL) { + goto error; + } + assert(PyTuple_Check(args)); + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + new_args = PyTuple_New(nargs + 1); + if (new_args == NULL) { + goto error; + } + PyTuple_SET_ITEM(new_args, 0, Py_NewRef((PyObject *)cls)); + for (Py_ssize_t i = 0; i < nargs; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + PyTuple_SET_ITEM(new_args, i + 1, Py_NewRef(arg)); + } + PyObject *result = PyObject_Call(func, new_args, kwargs); + Py_DECREF(typing); + Py_DECREF(func); + Py_DECREF(new_args); + return result; +error: + Py_XDECREF(typing); + Py_XDECREF(func); + Py_XDECREF(new_args); + return NULL; +} + +static PyObject * +generic_init_subclass(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + return call_typing_args_kwargs("_generic_init_subclass", cls, args, kwargs); +} + +static PyObject * +generic_class_getitem(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + return call_typing_args_kwargs("_generic_class_getitem", cls, args, kwargs); +} + +PyObject * +_Py_subscript_generic(PyThreadState* unused, PyObject *params) +{ + params = unpack_typevartuples(params); + + PyInterpreterState *interp = PyInterpreterState_Get(); + if (interp->cached_objects.generic_type == NULL) { + PyErr_SetString(PyExc_SystemError, "Cannot find Generic type"); + return NULL; + } + PyObject *args[2] = {(PyObject *)interp->cached_objects.generic_type, params}; + PyObject *result = call_typing_func_object("_GenericAlias", args, 2); + Py_DECREF(params); + return result; +} + +static PyMethodDef generic_methods[] = { + {"__class_getitem__", (PyCFunction)(void (*)(void))generic_class_getitem, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + generic_class_getitem_doc}, + {"__init_subclass__", (PyCFunction)(void (*)(void))generic_init_subclass, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("Function to initialize subclasses.")}, + {NULL} /* Sentinel */ +}; + +static void +generic_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +generic_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static PyType_Slot generic_slots[] = { + {Py_tp_doc, (void *)generic_doc}, + {Py_tp_methods, generic_methods}, + {Py_tp_dealloc, generic_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, generic_traverse}, + {0, NULL}, +}; + +PyType_Spec generic_spec = { + .name = "typing.Generic", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = generic_slots, +}; + +int _Py_initialize_generic(PyInterpreterState *interp) +{ +#define MAKE_TYPE(name) \ + do { \ + PyTypeObject *name ## _type = (PyTypeObject *)PyType_FromSpec(&name ## _spec); \ + if (name ## _type == NULL) { \ + return -1; \ + } \ + interp->cached_objects.name ## _type = name ## _type; \ + } while(0) + + MAKE_TYPE(generic); + MAKE_TYPE(typevar); + MAKE_TYPE(typevartuple); + MAKE_TYPE(paramspec); + MAKE_TYPE(paramspecargs); + MAKE_TYPE(paramspeckwargs); +#undef MAKE_TYPE + return 0; +} + +void _Py_clear_generic_types(PyInterpreterState *interp) +{ + Py_CLEAR(interp->cached_objects.generic_type); + Py_CLEAR(interp->cached_objects.typevar_type); + Py_CLEAR(interp->cached_objects.typevartuple_type); + Py_CLEAR(interp->cached_objects.paramspec_type); + Py_CLEAR(interp->cached_objects.paramspecargs_type); + Py_CLEAR(interp->cached_objects.paramspeckwargs_type); +} diff --git a/contrib/tools/python3/src/Objects/unicodeobject.c b/contrib/tools/python3/src/Objects/unicodeobject.c index b5510fc1c85..f6787c8f8aa 100644 --- a/contrib/tools/python3/src/Objects/unicodeobject.c +++ b/contrib/tools/python3/src/Objects/unicodeobject.c @@ -54,7 +54,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "pycore_unicodeobject.h" // struct _Py_unicode_state +#include "pycore_unicodeobject_generated.h" // _PyUnicode_InitStaticStrings() #include "stringlib/eq.h" // unicode_eq() +#include <stddef.h> // ptrdiff_t #ifdef MS_WINDOWS #include <windows.h> @@ -115,7 +117,6 @@ extern "C" { (_PyCompactUnicodeObject_CAST(op)->utf8) #define PyUnicode_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ ((char*)(_PyASCIIObject_CAST(op) + 1)) : \ _PyUnicode_UTF8(op)) @@ -123,21 +124,10 @@ extern "C" { (_PyCompactUnicodeObject_CAST(op)->utf8_length) #define PyUnicode_UTF8_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ _PyASCIIObject_CAST(op)->length : \ _PyUnicode_UTF8_LENGTH(op)) -#define _PyUnicode_WSTR(op) \ - (_PyASCIIObject_CAST(op)->wstr) -/* Don't use deprecated macro of unicodeobject.h */ -#undef PyUnicode_WSTR_LENGTH -#define PyUnicode_WSTR_LENGTH(op) \ - (PyUnicode_IS_COMPACT_ASCII(op) ? \ - _PyASCIIObject_CAST(op)->length : \ - _PyCompactUnicodeObject_CAST(op)->wstr_length) -#define _PyUnicode_WSTR_LENGTH(op) \ - (_PyCompactUnicodeObject_CAST(op)->wstr_length) #define _PyUnicode_LENGTH(op) \ (_PyASCIIObject_CAST(op)->length) #define _PyUnicode_STATE(op) \ @@ -153,20 +143,10 @@ extern "C" { #define _PyUnicode_DATA_ANY(op) \ (_PyUnicodeObject_CAST(op)->data.any) -#undef PyUnicode_READY -#define PyUnicode_READY(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (PyUnicode_IS_READY(op) ? \ - 0 : \ - _PyUnicode_Ready(op))) - #define _PyUnicode_SHARE_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ assert(!PyUnicode_IS_COMPACT_ASCII(op)), \ (_PyUnicode_UTF8(op) == PyUnicode_DATA(op))) -#define _PyUnicode_SHARE_WSTR(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (_PyUnicode_WSTR(unicode) == PyUnicode_DATA(op))) /* true if the Unicode object has an allocated UTF-8 memory block (not shared with other data) */ @@ -175,13 +155,6 @@ extern "C" { && _PyUnicode_UTF8(op) \ && _PyUnicode_UTF8(op) != PyUnicode_DATA(op))) -/* true if the Unicode object has an allocated wstr memory block - (not shared with other data) */ -#define _PyUnicode_HAS_WSTR_MEMORY(op) \ - ((_PyUnicode_WSTR(op) && \ - (!PyUnicode_IS_READY(op) || \ - _PyUnicode_WSTR(op) != PyUnicode_DATA(op)))) - /* Generic helper macro to convert characters of different types. from_type and to_type have to be valid type names, begin and end are pointers to the source characters which should be of type @@ -219,16 +192,6 @@ extern "C" { # define OVERALLOCATE_FACTOR 4 #endif -/* This dictionary holds all interned unicode strings. Note that references - to strings in this dictionary are *not* counted in the string's ob_refcnt. - When the interned string reaches a refcnt of 0 the string deallocation - function will delete the reference from this dictionary. - - Another way to look at this is that to say that the actual reference - count of a string is: s->ob_refcnt + (s->state ? 2 : 0) -*/ -static PyObject *interned = NULL; - /* Forward declaration */ static inline int _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); @@ -259,8 +222,89 @@ static inline PyObject* unicode_get_empty(void) static inline PyObject* unicode_new_empty(void) { PyObject *empty = unicode_get_empty(); - Py_INCREF(empty); - return empty; + return Py_NewRef(empty); +} + +/* This dictionary holds all interned unicode strings. Note that references + to strings in this dictionary are *not* counted in the string's ob_refcnt. + When the interned string reaches a refcnt of 0 the string deallocation + function will delete the reference from this dictionary. +*/ +static inline PyObject *get_interned_dict(PyInterpreterState *interp) +{ + return _Py_INTERP_CACHED_OBJECT(interp, interned_strings); +} + +#define INTERNED_STRINGS _PyRuntime.cached_objects.interned_strings + +Py_ssize_t +_PyUnicode_InternedSize(void) +{ + PyObject *dict = get_interned_dict(_PyInterpreterState_GET()); + return _Py_hashtable_len(INTERNED_STRINGS) + PyDict_GET_SIZE(dict); +} + +static Py_hash_t unicode_hash(PyObject *); +static int unicode_compare_eq(PyObject *, PyObject *); + +static Py_uhash_t +hashtable_unicode_hash(const void *key) +{ + return unicode_hash((PyObject *)key); +} + +static int +hashtable_unicode_compare(const void *key1, const void *key2) +{ + PyObject *obj1 = (PyObject *)key1; + PyObject *obj2 = (PyObject *)key2; + if (obj1 != NULL && obj2 != NULL) { + return unicode_compare_eq(obj1, obj2); + } + else { + return obj1 == obj2; + } +} + +static int +init_interned_dict(PyInterpreterState *interp) +{ + if (_Py_IsMainInterpreter(interp)) { + assert(INTERNED_STRINGS == NULL); + _Py_hashtable_allocator_t hashtable_alloc = {PyMem_RawMalloc, PyMem_RawFree}; + INTERNED_STRINGS = _Py_hashtable_new_full( + hashtable_unicode_hash, + hashtable_unicode_compare, + NULL, + NULL, + &hashtable_alloc + ); + if (INTERNED_STRINGS == NULL) { + return -1; + } + } + assert(get_interned_dict(interp) == NULL); + PyObject *interned = interned = PyDict_New(); + if (interned == NULL) { + return -1; + } + _Py_INTERP_CACHED_OBJECT(interp, interned_strings) = interned; + return 0; +} + +static void +clear_interned_dict(PyInterpreterState *interp) +{ + PyObject *interned = get_interned_dict(interp); + if (interned != NULL) { + PyDict_Clear(interned); + Py_DECREF(interned); + _Py_INTERP_CACHED_OBJECT(interp, interned_strings) = NULL; + } + if (_Py_IsMainInterpreter(interp) && INTERNED_STRINGS != NULL) { + _Py_hashtable_destroy(INTERNED_STRINGS); + INTERNED_STRINGS = NULL; + } } #define _Py_RETURN_UNICODE_EMPTY() \ @@ -269,11 +313,10 @@ static inline PyObject* unicode_new_empty(void) } while (0) static inline void -unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value, +unicode_fill(int kind, void *data, Py_UCS4 value, Py_ssize_t start, Py_ssize_t length) { assert(0 <= start); - assert(kind != PyUnicode_WCHAR_KIND); switch (kind) { case PyUnicode_1BYTE_KIND: { assert(value <= 0xff); @@ -335,7 +378,6 @@ const unsigned char _Py_ascii_whitespace[] = { }; /* forward */ -static PyUnicodeObject *_PyUnicode_New(Py_ssize_t length); static PyObject* get_latin1_char(unsigned char ch); static int unicode_modifiable(PyObject *unicode); @@ -478,7 +520,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) return 0; } - if (encoding != NULL) { + if (encoding != NULL + // Fast path for the most common built-in encodings. Even if the codec + // is cached, _PyCodec_Lookup() decodes the bytes string from UTF-8 to + // create a temporary Unicode string (the key in the cache). + && strcmp(encoding, "utf-8") != 0 + && strcmp(encoding, "utf8") != 0 + && strcmp(encoding, "ascii") != 0) + { PyObject *handler = _PyCodec_Lookup(encoding); if (handler == NULL) { return -1; @@ -486,7 +535,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) Py_DECREF(handler); } - if (errors != NULL) { + if (errors != NULL + // Fast path for the most common built-in error handlers. + && strcmp(errors, "strict") != 0 + && strcmp(errors, "ignore") != 0 + && strcmp(errors, "replace") != 0 + && strcmp(errors, "surrogateescape") != 0 + && strcmp(errors, "surrogatepass") != 0) + { PyObject *handler = PyCodec_LookupError(errors); if (handler == NULL) { return -1; @@ -507,11 +563,10 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) CHECK(PyUnicode_Check(op)); PyASCIIObject *ascii = _PyASCIIObject_CAST(op); - unsigned int kind = ascii->state.kind; + int kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { CHECK(kind == PyUnicode_1BYTE_KIND); - CHECK(ascii->state.ready == 1); } else { PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); @@ -523,62 +578,32 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) || kind == PyUnicode_2BYTE_KIND || kind == PyUnicode_4BYTE_KIND); CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 1); CHECK(compact->utf8 != data); } else { PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); data = unicode->data.any; - if (kind == PyUnicode_WCHAR_KIND) { - CHECK(ascii->length == 0); - CHECK(ascii->hash == -1); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 0); - CHECK(ascii->state.interned == SSTATE_NOT_INTERNED); - CHECK(ascii->wstr != NULL); - CHECK(data == NULL); - CHECK(compact->utf8 == NULL); + CHECK(kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + CHECK(ascii->state.compact == 0); + CHECK(data != NULL); + if (ascii->state.ascii) { + CHECK(compact->utf8 == data); + CHECK(compact->utf8_length == ascii->length); } else { - CHECK(kind == PyUnicode_1BYTE_KIND - || kind == PyUnicode_2BYTE_KIND - || kind == PyUnicode_4BYTE_KIND); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ready == 1); - CHECK(data != NULL); - if (ascii->state.ascii) { - CHECK(compact->utf8 == data); - CHECK(compact->utf8_length == ascii->length); - } - else - CHECK(compact->utf8 != data); + CHECK(compact->utf8 != data); } } - if (kind != PyUnicode_WCHAR_KIND) { - if ( -#if SIZEOF_WCHAR_T == 2 - kind == PyUnicode_2BYTE_KIND -#else - kind == PyUnicode_4BYTE_KIND -#endif - ) - { - CHECK(ascii->wstr == data); - CHECK(compact->wstr_length == ascii->length); - } else - CHECK(ascii->wstr != data); - } if (compact->utf8 == NULL) CHECK(compact->utf8_length == 0); - if (ascii->wstr == NULL) - CHECK(compact->wstr_length == 0); } /* check that the best kind is used: O(n) operation */ - if (check_content && kind != PyUnicode_WCHAR_KIND) { + if (check_content) { Py_ssize_t i; Py_UCS4 maxchar = 0; const void *data; @@ -614,47 +639,12 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #undef CHECK } - static PyObject* -unicode_result_wchar(PyObject *unicode) -{ -#ifndef Py_DEBUG - Py_ssize_t len; - - len = _PyUnicode_WSTR_LENGTH(unicode); - if (len == 0) { - Py_DECREF(unicode); - _Py_RETURN_UNICODE_EMPTY(); - } - - if (len == 1) { - wchar_t ch = _PyUnicode_WSTR(unicode)[0]; - if ((Py_UCS4)ch < 256) { - Py_DECREF(unicode); - return get_latin1_char((unsigned char)ch); - } - } - - if (_PyUnicode_Ready(unicode) < 0) { - Py_DECREF(unicode); - return NULL; - } -#else - assert(Py_REFCNT(unicode) == 1); - - /* don't make the result ready in debug mode to ensure that the caller - makes the string ready before using it */ - assert(_PyUnicode_CheckConsistency(unicode, 1)); -#endif - return unicode; -} - -static PyObject* -unicode_result_ready(PyObject *unicode) +unicode_result(PyObject *unicode) { - Py_ssize_t length; + assert(_PyUnicode_CHECK(unicode)); - length = PyUnicode_GET_LENGTH(unicode); + Py_ssize_t length = PyUnicode_GET_LENGTH(unicode); if (length == 0) { PyObject *empty = unicode_get_empty(); if (unicode != empty) { @@ -683,23 +673,10 @@ unicode_result_ready(PyObject *unicode) } static PyObject* -unicode_result(PyObject *unicode) -{ - assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_IS_READY(unicode)) - return unicode_result_ready(unicode); - else - return unicode_result_wchar(unicode); -} - -static PyObject* unicode_result_unchanged(PyObject *unicode) { if (PyUnicode_CheckExact(unicode)) { - if (PyUnicode_READY(unicode) == -1) - return NULL; - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } else /* Subtype -- return genuine unicode string with the same value. */ @@ -714,10 +691,9 @@ backslashreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -781,10 +757,9 @@ xmlcharrefreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -908,7 +883,7 @@ ensure_unicode(PyObject *obj) Py_TYPE(obj)->tp_name); return -1; } - return PyUnicode_READY(obj); + return 0; } /* Compilation of templated routines */ @@ -954,15 +929,6 @@ ensure_unicode(PyObject *obj) #include "stringlib/find_max_char.h" #include "stringlib/undef.h" -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS -#include "stringlib/unicodedefs.h" -#include "stringlib/fastsearch.h" -#include "stringlib/count.h" -#include "stringlib/find.h" -#include "stringlib/undef.h" -_Py_COMP_DIAG_POP - #undef STRINGLIB_GET_EMPTY /* --- Unicode Object ----------------------------------------------------- */ @@ -1022,14 +988,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length) Py_ssize_t char_size; Py_ssize_t struct_size; Py_ssize_t new_size; - int share_wstr; PyObject *new_unicode; #ifdef Py_DEBUG Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif assert(unicode_modifiable(unicode)); - assert(PyUnicode_IS_READY(unicode)); assert(PyUnicode_IS_COMPACT(unicode)); char_size = PyUnicode_KIND(unicode); @@ -1037,7 +1001,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length) struct_size = sizeof(PyASCIIObject); else struct_size = sizeof(PyCompactUnicodeObject); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) { PyErr_NoMemory(); @@ -1050,34 +1013,20 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif #ifdef Py_TRACE_REFS _Py_ForgetReference(unicode); #endif new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size); if (new_unicode == NULL) { - _Py_NewReference(unicode); + _Py_NewReferenceNoTotal(unicode); PyErr_NoMemory(); return NULL; } unicode = new_unicode; - _Py_NewReference(unicode); + _Py_NewReferenceNoTotal(unicode); _PyUnicode_LENGTH(unicode) = length; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = PyUnicode_DATA(unicode); - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } #ifdef Py_DEBUG unicode_fill_invalid(unicode, old_length); #endif @@ -1090,78 +1039,55 @@ resize_compact(PyObject *unicode, Py_ssize_t length) static int resize_inplace(PyObject *unicode, Py_ssize_t length) { - wchar_t *wstr; - Py_ssize_t new_size; assert(!PyUnicode_IS_COMPACT(unicode)); assert(Py_REFCNT(unicode) == 1); - if (PyUnicode_IS_READY(unicode)) { - Py_ssize_t char_size; - int share_wstr, share_utf8; - void *data; + Py_ssize_t new_size; + Py_ssize_t char_size; + int share_utf8; + void *data; #ifdef Py_DEBUG - Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); + Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif - data = _PyUnicode_DATA_ANY(unicode); - char_size = PyUnicode_KIND(unicode); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); - share_utf8 = _PyUnicode_SHARE_UTF8(unicode); + data = _PyUnicode_DATA_ANY(unicode); + char_size = PyUnicode_KIND(unicode); + share_utf8 = _PyUnicode_SHARE_UTF8(unicode); - if (length > (PY_SSIZE_T_MAX / char_size - 1)) { - PyErr_NoMemory(); - return -1; - } - new_size = (length + 1) * char_size; + if (length > (PY_SSIZE_T_MAX / char_size - 1)) { + PyErr_NoMemory(); + return -1; + } + new_size = (length + 1) * char_size; - if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) - { - PyObject_Free(_PyUnicode_UTF8(unicode)); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } + if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) + { + PyObject_Free(_PyUnicode_UTF8(unicode)); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } - data = (PyObject *)PyObject_Realloc(data, new_size); - if (data == NULL) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = data; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = data; - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - if (share_utf8) { - _PyUnicode_UTF8(unicode) = data; - _PyUnicode_UTF8_LENGTH(unicode) = length; - } - _PyUnicode_LENGTH(unicode) = length; - PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); + data = (PyObject *)PyObject_Realloc(data, new_size); + if (data == NULL) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_DATA_ANY(unicode) = data; + if (share_utf8) { + _PyUnicode_UTF8(unicode) = data; + _PyUnicode_UTF8_LENGTH(unicode) = length; + } + _PyUnicode_LENGTH(unicode) = length; + PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); #ifdef Py_DEBUG - unicode_fill_invalid(unicode, old_length); + unicode_fill_invalid(unicode, old_length); #endif - if (share_wstr || _PyUnicode_WSTR(unicode) == NULL) { - assert(_PyUnicode_CheckConsistency(unicode, 0)); - return 0; - } - } - assert(_PyUnicode_WSTR(unicode) != NULL); /* check for integer overflow */ if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { PyErr_NoMemory(); return -1; } - new_size = sizeof(wchar_t) * (length + 1); - wstr = _PyUnicode_WSTR(unicode); - wstr = PyObject_Realloc(wstr, new_size); - if (!wstr) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_WSTR(unicode) = wstr; - _PyUnicode_WSTR(unicode)[length] = 0; - _PyUnicode_WSTR_LENGTH(unicode) = length; assert(_PyUnicode_CheckConsistency(unicode, 0)); return 0; } @@ -1170,99 +1096,15 @@ static PyObject* resize_copy(PyObject *unicode, Py_ssize_t length) { Py_ssize_t copy_length; - if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) { - PyObject *copy; - - assert(PyUnicode_IS_READY(unicode)); - - copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); - if (copy == NULL) - return NULL; - - copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); - _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); - return copy; - } - else { - PyObject *w; - - w = (PyObject*)_PyUnicode_New(length); - if (w == NULL) - return NULL; - copy_length = _PyUnicode_WSTR_LENGTH(unicode); - copy_length = Py_MIN(copy_length, length); - memcpy(_PyUnicode_WSTR(w), _PyUnicode_WSTR(unicode), - copy_length * sizeof(wchar_t)); - return w; - } -} - -/* We allocate one more byte to make sure the string is - Ux0000 terminated; some code (e.g. new_identifier) - relies on that. - - XXX This allocator could further be enhanced by assuring that the - free list never reduces its size below 1. - -*/ - -static PyUnicodeObject * -_PyUnicode_New(Py_ssize_t length) -{ - PyUnicodeObject *unicode; - size_t new_size; - - /* Optimization for empty strings */ - if (length == 0) { - return (PyUnicodeObject *)unicode_new_empty(); - } - - /* Ensure we won't overflow the size. */ - if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { - return (PyUnicodeObject *)PyErr_NoMemory(); - } - if (length < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to _PyUnicode_New"); - return NULL; - } - - unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type); - if (unicode == NULL) - return NULL; - new_size = sizeof(Py_UNICODE) * ((size_t)length + 1); - - _PyUnicode_WSTR_LENGTH(unicode) = length; - _PyUnicode_HASH(unicode) = -1; - _PyUnicode_STATE(unicode).interned = 0; - _PyUnicode_STATE(unicode).kind = 0; - _PyUnicode_STATE(unicode).compact = 0; - _PyUnicode_STATE(unicode).ready = 0; - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_DATA_ANY(unicode) = NULL; - _PyUnicode_LENGTH(unicode) = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; + PyObject *copy; - _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_Malloc(new_size); - if (!_PyUnicode_WSTR(unicode)) { - Py_DECREF(unicode); - PyErr_NoMemory(); + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (copy == NULL) return NULL; - } - - /* Initialize the first element to guard against cases where - * the caller fails before initializing str -- unicode_resize() - * reads str[0], and the Keep-Alive optimization can keep memory - * allocated for str alive across a call to unicode_dealloc(unicode). - * We don't want unicode_resize to read uninitialized memory in - * that case. - */ - _PyUnicode_WSTR(unicode)[0] = 0; - _PyUnicode_WSTR(unicode)[length] = 0; - assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0)); - return unicode; + copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); + return copy; } static const char* @@ -1272,8 +1114,6 @@ unicode_kind_name(PyObject *unicode) _PyUnicode_Dump() */ if (!PyUnicode_IS_COMPACT(unicode)) { - if (!PyUnicode_IS_READY(unicode)) - return "wstr"; switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: @@ -1289,7 +1129,6 @@ unicode_kind_name(PyObject *unicode) return "<legacy invalid kind>"; } } - assert(PyUnicode_IS_READY(unicode)); switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(unicode)) @@ -1346,15 +1185,7 @@ _PyUnicode_Dump(PyObject *op) data = unicode->data.any; printf("%s: len=%zu, ", unicode_kind_name(op), ascii->length); - if (ascii->wstr == data) - printf("shared "); - printf("wstr=%p", (void *)ascii->wstr); - - if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { - printf(" (%zu), ", compact->wstr_length); - if (!ascii->state.compact && compact->utf8 == unicode->data.any) { - printf("shared "); - } + if (!ascii->state.ascii) { printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); @@ -1373,13 +1204,12 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) PyObject *obj; PyCompactUnicodeObject *unicode; void *data; - enum PyUnicode_Kind kind; - int is_sharing, is_ascii; + int kind; + int is_ascii; Py_ssize_t char_size; Py_ssize_t struct_size; is_ascii = 0; - is_sharing = 0; struct_size = sizeof(PyCompactUnicodeObject); if (maxchar < 128) { kind = PyUnicode_1BYTE_KIND; @@ -1394,8 +1224,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) else if (maxchar < 65536) { kind = PyUnicode_2BYTE_KIND; char_size = 2; - if (sizeof(wchar_t) == 2) - is_sharing = 1; } else { if (maxchar > MAX_UNICODE) { @@ -1405,8 +1233,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) } kind = PyUnicode_4BYTE_KIND; char_size = 4; - if (sizeof(wchar_t) == 4) - is_sharing = 1; } /* Ensure we won't overflow the size. */ @@ -1438,16 +1264,13 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) _PyUnicode_STATE(unicode).interned = 0; _PyUnicode_STATE(unicode).kind = kind; _PyUnicode_STATE(unicode).compact = 1; - _PyUnicode_STATE(unicode).ready = 1; _PyUnicode_STATE(unicode).ascii = is_ascii; + _PyUnicode_STATE(unicode).statically_allocated = 0; if (is_ascii) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; } else if (kind == PyUnicode_1BYTE_KIND) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; unicode->utf8 = NULL; unicode->utf8_length = 0; } @@ -1458,14 +1281,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) ((Py_UCS2*)data)[size] = 0; else /* kind == PyUnicode_4BYTE_KIND */ ((Py_UCS4*)data)[size] = 0; - if (is_sharing) { - _PyUnicode_WSTR_LENGTH(unicode) = size; - _PyUnicode_WSTR(unicode) = (wchar_t *)data; - } - else { - _PyUnicode_WSTR_LENGTH(unicode) = 0; - _PyUnicode_WSTR(unicode) = NULL; - } } #ifdef Py_DEBUG unicode_fill_invalid((PyObject*)unicode, 0); @@ -1530,7 +1345,7 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many, int check_maxchar) { - unsigned int from_kind, to_kind; + int from_kind, to_kind; const void *from_data; void *to_data; @@ -1538,11 +1353,9 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, assert(0 <= from_start); assert(0 <= to_start); assert(PyUnicode_Check(from)); - assert(PyUnicode_IS_READY(from)); assert(from_start + how_many <= PyUnicode_GET_LENGTH(from)); assert(PyUnicode_Check(to)); - assert(PyUnicode_IS_READY(to)); assert(to_start + how_many <= PyUnicode_GET_LENGTH(to)); if (how_many == 0) @@ -1687,11 +1500,6 @@ PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start, return -1; } - if (PyUnicode_READY(from) == -1) - return -1; - if (PyUnicode_READY(to) == -1) - return -1; - if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -1776,135 +1584,6 @@ find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end, return 0; } -int -_PyUnicode_Ready(PyObject *unicode) -{ - wchar_t *end; - Py_UCS4 maxchar = 0; - Py_ssize_t num_surrogates; -#if SIZEOF_WCHAR_T == 2 - Py_ssize_t length_wo_surrogates; -#endif - - /* _PyUnicode_Ready() is only intended for old-style API usage where - strings were created using _PyObject_New() and where no canonical - representation (the str field) has been set yet aka strings - which are not yet ready. */ - assert(_PyUnicode_CHECK(unicode)); - assert(_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND); - assert(_PyUnicode_WSTR(unicode) != NULL); - assert(_PyUnicode_DATA_ANY(unicode) == NULL); - assert(_PyUnicode_UTF8(unicode) == NULL); - /* Actually, it should neither be interned nor be anything else: */ - assert(_PyUnicode_STATE(unicode).interned == SSTATE_NOT_INTERNED); - - end = _PyUnicode_WSTR(unicode) + _PyUnicode_WSTR_LENGTH(unicode); - if (find_maxchar_surrogates(_PyUnicode_WSTR(unicode), end, - &maxchar, &num_surrogates) == -1) - return -1; - - if (maxchar < 256) { - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(_PyUnicode_WSTR_LENGTH(unicode) + 1); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, unsigned char, - _PyUnicode_WSTR(unicode), end, - PyUnicode_1BYTE_DATA(unicode)); - PyUnicode_1BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_1BYTE_KIND; - if (maxchar < 128) { - _PyUnicode_STATE(unicode).ascii = 1; - _PyUnicode_UTF8(unicode) = _PyUnicode_DATA_ANY(unicode); - _PyUnicode_UTF8_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - } - else { - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } - /* In this case we might have to convert down from 4-byte native - wchar_t to 2-byte unicode. */ - else if (maxchar < 65536) { - assert(num_surrogates == 0 && - "FindMaxCharAndNumSurrogatePairs() messed up"); - -#if SIZEOF_WCHAR_T == 2 - /* We can share representations and are done. */ - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; -#else - /* sizeof(wchar_t) == 4 */ - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc( - 2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, Py_UCS2, - _PyUnicode_WSTR(unicode), end, - PyUnicode_2BYTE_DATA(unicode)); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#endif - } - /* maxchar exceeds 16 bit, wee need 4 bytes for unicode characters */ - else { -#if SIZEOF_WCHAR_T == 2 - /* in case the native representation is 2-bytes, we need to allocate a - new normalized 4-byte version. */ - length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates; - if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(4 * (length_wo_surrogates + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_LENGTH(unicode) = length_wo_surrogates; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - /* unicode_convert_wchar_to_ucs4() requires a ready string */ - _PyUnicode_STATE(unicode).ready = 1; - unicode_convert_wchar_to_ucs4(_PyUnicode_WSTR(unicode), end, unicode); - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#else - assert(num_surrogates == 0); - - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; -#endif - PyUnicode_4BYTE_DATA(unicode)[_PyUnicode_LENGTH(unicode)] = '\0'; - } - _PyUnicode_STATE(unicode).ready = 1; - assert(_PyUnicode_CheckConsistency(unicode, 1)); - return 0; -} - static void unicode_dealloc(PyObject *unicode) { @@ -1913,38 +1592,15 @@ unicode_dealloc(PyObject *unicode) _Py_FatalRefcountError("deallocating an Unicode singleton"); } #endif - - switch (PyUnicode_CHECK_INTERNED(unicode)) { - case SSTATE_NOT_INTERNED: - break; - case SSTATE_INTERNED_MORTAL: + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref an immortal string out of existence. Since + * the string is an immortal object, just re-set the reference count. + */ + if (PyUnicode_CHECK_INTERNED(unicode) + || _PyUnicode_STATE(unicode).statically_allocated) { - /* Revive the dead object temporarily. PyDict_DelItem() removes two - references (key and value) which were ignored by - PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2 - to prevent calling unicode_dealloc() again. Adjust refcnt after - PyDict_DelItem(). */ - assert(Py_REFCNT(unicode) == 0); - Py_SET_REFCNT(unicode, 3); - if (PyDict_DelItem(interned, unicode) != 0) { - _PyErr_WriteUnraisableMsg("deletion of interned string failed", - NULL); - } - assert(Py_REFCNT(unicode) == 1); - Py_SET_REFCNT(unicode, 0); - break; - } - - case SSTATE_INTERNED_IMMORTAL: - _PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died"); - break; - - default: - Py_UNREACHABLE(); - } - - if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); + _Py_SetImmortal(unicode); + return; } if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { PyObject_Free(_PyUnicode_UTF8(unicode)); @@ -1965,7 +1621,7 @@ unicode_is_singleton(PyObject *unicode) } PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode); - if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { + if (ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); if (ch < 256 && LATIN1(ch) == unicode) { return 1; @@ -2007,10 +1663,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length) assert(PyUnicode_Check(unicode)); assert(0 <= length); - if (_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND) - old_length = PyUnicode_WSTR_LENGTH(unicode); - else - old_length = PyUnicode_GET_LENGTH(unicode); + old_length = PyUnicode_GET_LENGTH(unicode); if (old_length == length) return 0; @@ -2064,7 +1717,7 @@ static void unicode_write_cstr(PyObject *unicode, Py_ssize_t index, const char *str, Py_ssize_t len) { - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); const char *end = str + len; @@ -2140,28 +1793,6 @@ unicode_char(Py_UCS4 ch) } PyObject * -PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) -{ - if (u == NULL) { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromUnicode(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject*)_PyUnicode_New(size); - } - - if (size < 0) { - PyErr_BadInternalCall(); - return NULL; - } - - return PyUnicode_FromWideChar(u, size); -} - -PyObject * PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) { PyObject *unicode; @@ -2254,16 +1885,12 @@ PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) if (u != NULL) { return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL); } - else { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromStringAndSize(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject *)_PyUnicode_New(size); + if (size > 0) { + PyErr_SetString(PyExc_SystemError, + "NULL string with positive size with NULL passed to PyUnicode_FromStringAndSize"); + return NULL; } + return unicode_new_empty(); } PyObject * @@ -2291,7 +1918,7 @@ _PyUnicode_FromId(_Py_Identifier *id) Py_ssize_t index = _Py_atomic_size_get(&id->index); if (index < 0) { - struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; + struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); // Check again to detect concurrent access. Another thread can have @@ -2382,7 +2009,7 @@ _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size) } static Py_UCS4 -kind_maxchar_limit(unsigned int kind) +kind_maxchar_limit(int kind) { switch (kind) { case PyUnicode_1BYTE_KIND: @@ -2496,10 +2123,9 @@ PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size) Py_UCS4 _PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end) { - enum PyUnicode_Kind kind; + int kind; const void *startptr, *endptr; - assert(PyUnicode_IS_READY(unicode)); assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(unicode)); assert(start <= end); @@ -2538,11 +2164,10 @@ unicode_adjust_maxchar(PyObject **p_unicode) PyObject *unicode, *copy; Py_UCS4 max_char; Py_ssize_t len; - unsigned int kind; + int kind; assert(p_unicode != NULL); unicode = *p_unicode; - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_IS_ASCII(unicode)) return; @@ -2586,8 +2211,6 @@ _PyUnicode_Copy(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; length = PyUnicode_GET_LENGTH(unicode); copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); @@ -2606,7 +2229,7 @@ _PyUnicode_Copy(PyObject *unicode) character. Return NULL on error. */ static void* -unicode_askind(unsigned int skind, void const *data, Py_ssize_t len, unsigned int kind) +unicode_askind(int skind, void const *data, Py_ssize_t len, int kind) { void *result; @@ -2656,8 +2279,6 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, int kind; const void *data; Py_ssize_t len, targetlen; - if (PyUnicode_READY(string) == -1) - return NULL; kind = PyUnicode_KIND(string); data = PyUnicode_DATA(string); len = PyUnicode_GET_LENGTH(string); @@ -2716,21 +2337,19 @@ PyUnicode_AsUCS4Copy(PyObject *string) return as_ucs4(string, NULL, 0, 1); } -/* maximum number of characters required for output of %lld or %p. - We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, - plus 1 for the sign. 53/22 is an upper bound for log10(256). */ -#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) +/* maximum number of characters required for output of %jo or %jd or %p. + We need at most ceil(log8(256)*sizeof(intmax_t)) digits, + plus 1 for the sign, plus 2 for the 0x prefix (for %p), + plus 1 for the terminal NUL. */ +#define MAX_INTMAX_CHARS (5 + (sizeof(intmax_t)*8-1) / 3) static int unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, - Py_ssize_t width, Py_ssize_t precision) + Py_ssize_t width, Py_ssize_t precision, int flags) { Py_ssize_t length, fill, arglen; Py_UCS4 maxchar; - if (PyUnicode_READY(str) == -1) - return -1; - length = PyUnicode_GET_LENGTH(str); if ((precision == -1 || precision >= length) && width <= length) @@ -2748,8 +2367,8 @@ unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, if (_PyUnicodeWriter_Prepare(writer, arglen, maxchar) == -1) return -1; - if (width > length) { - fill = width - length; + fill = Py_MAX(width - length, 0); + if (fill && !(flags & F_LJUST)) { if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1) return -1; writer->pos += fill; @@ -2758,12 +2377,19 @@ unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, str, 0, length); writer->pos += length; + + if (fill && (flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1) + return -1; + writer->pos += fill; + } + return 0; } static int unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str, - Py_ssize_t width, Py_ssize_t precision) + Py_ssize_t width, Py_ssize_t precision, int flags) { /* UTF-8 */ Py_ssize_t length; @@ -2783,36 +2409,93 @@ unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str, if (unicode == NULL) return -1; - res = unicode_fromformat_write_str(writer, unicode, width, -1); + res = unicode_fromformat_write_str(writer, unicode, width, -1, flags); Py_DECREF(unicode); return res; } +static int +unicode_fromformat_write_wcstr(_PyUnicodeWriter *writer, const wchar_t *str, + Py_ssize_t width, Py_ssize_t precision, int flags) +{ + /* UTF-8 */ + Py_ssize_t length; + PyObject *unicode; + int res; + + if (precision == -1) { + length = wcslen(str); + } + else { + length = 0; + while (length < precision && str[length]) { + length++; + } + } + unicode = PyUnicode_FromWideChar(str, length); + if (unicode == NULL) + return -1; + + res = unicode_fromformat_write_str(writer, unicode, width, -1, flags); + Py_DECREF(unicode); + return res; +} + +#define F_LONG 1 +#define F_LONGLONG 2 +#define F_SIZE 3 +#define F_PTRDIFF 4 +#define F_INTMAX 5 +static const char * const formats[] = {"%d", "%ld", "%lld", "%zd", "%td", "%jd"}; +static const char * const formats_o[] = {"%o", "%lo", "%llo", "%zo", "%to", "%jo"}; +static const char * const formats_u[] = {"%u", "%lu", "%llu", "%zu", "%tu", "%ju"}; +static const char * const formats_x[] = {"%x", "%lx", "%llx", "%zx", "%tx", "%jx"}; +static const char * const formats_X[] = {"%X", "%lX", "%llX", "%zX", "%tX", "%jX"}; + static const char* unicode_fromformat_arg(_PyUnicodeWriter *writer, const char *f, va_list *vargs) { const char *p; Py_ssize_t len; - int zeropad; + int flags = 0; Py_ssize_t width; Py_ssize_t precision; - int longflag; - int longlongflag; - int size_tflag; - Py_ssize_t fill; p = f; f++; - zeropad = 0; - if (*f == '0') { - zeropad = 1; + if (*f == '%') { + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; f++; + return f; + } + + /* Parse flags. Example: "%-i" => flags=F_LJUST. */ + /* Flags '+', ' ' and '#' are not particularly useful. + * They are not worth the implementation and maintenance costs. + * In addition, '#' should add "0" for "o" conversions for compatibility + * with printf, but it would confuse Python users. */ + while (1) { + switch (*f++) { + case '-': flags |= F_LJUST; continue; + case '0': flags |= F_ZERO; continue; + } + f--; + break; } /* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */ width = -1; - if (Py_ISDIGIT((unsigned)*f)) { + if (*f == '*') { + width = va_arg(*vargs, int); + if (width < 0) { + flags |= F_LJUST; + width = -width; + } + f++; + } + else if (Py_ISDIGIT((unsigned)*f)) { width = *f - '0'; f++; while (Py_ISDIGIT((unsigned)*f)) { @@ -2828,7 +2511,14 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, precision = -1; if (*f == '.') { f++; - if (Py_ISDIGIT((unsigned)*f)) { + if (*f == '*') { + precision = va_arg(*vargs, int); + if (precision < 0) { + precision = -2; + } + f++; + } + else if (Py_ISDIGIT((unsigned)*f)) { precision = (*f - '0'); f++; while (Py_ISDIGIT((unsigned)*f)) { @@ -2841,41 +2531,50 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, f++; } } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; } - /* Handle %ld, %lu, %lld and %llu. */ - longflag = 0; - longlongflag = 0; - size_tflag = 0; + int sizemod = 0; if (*f == 'l') { - if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') { - longflag = 1; - ++f; - } - else if (f[1] == 'l' && - (f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) { - longlongflag = 1; + if (f[1] == 'l') { + sizemod = F_LONGLONG; f += 2; } + else { + sizemod = F_LONG; + ++f; + } } - /* handle the size_t flag. */ - else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) { - size_tflag = 1; + else if (*f == 'z') { + sizemod = F_SIZE; ++f; } - - if (f[1] == '\0') + else if (*f == 't') { + sizemod = F_PTRDIFF; + ++f; + } + else if (*f == 'j') { + sizemod = F_INTMAX; + ++f; + } + if (f[0] != '\0' && f[1] == '\0') writer->overallocate = 0; switch (*f) { + case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': + break; + case 'c': case 'p': + if (sizemod || width >= 0 || precision >= 0) goto invalid_format; + break; + case 's': + case 'V': + if (sizemod && sizemod != F_LONG) goto invalid_format; + break; + default: + if (sizemod) goto invalid_format; + break; + } + + switch (*f) { case 'c': { int ordinal = va_arg(*vargs, int); @@ -2889,78 +2588,98 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case 'i': - case 'd': - case 'u': - case 'x': + case 'd': case 'i': + case 'o': case 'u': case 'x': case 'X': { /* used by sprintf */ - char buffer[MAX_LONG_LONG_CHARS]; - Py_ssize_t arglen; - - if (*f == 'u') { - if (longflag) { - len = sprintf(buffer, "%lu", va_arg(*vargs, unsigned long)); - } - else if (longlongflag) { - len = sprintf(buffer, "%llu", va_arg(*vargs, unsigned long long)); - } - else if (size_tflag) { - len = sprintf(buffer, "%zu", va_arg(*vargs, size_t)); - } - else { - len = sprintf(buffer, "%u", va_arg(*vargs, unsigned int)); - } + char buffer[MAX_INTMAX_CHARS]; + const char *fmt = NULL; + switch (*f) { + case 'o': fmt = formats_o[sizemod]; break; + case 'u': fmt = formats_u[sizemod]; break; + case 'x': fmt = formats_x[sizemod]; break; + case 'X': fmt = formats_X[sizemod]; break; + default: fmt = formats[sizemod]; break; } - else if (*f == 'x') { - len = sprintf(buffer, "%x", va_arg(*vargs, int)); - } - else { - if (longflag) { - len = sprintf(buffer, "%li", va_arg(*vargs, long)); - } - else if (longlongflag) { - len = sprintf(buffer, "%lli", va_arg(*vargs, long long)); - } - else if (size_tflag) { - len = sprintf(buffer, "%zi", va_arg(*vargs, Py_ssize_t)); - } - else { - len = sprintf(buffer, "%i", va_arg(*vargs, int)); - } + int issigned = (*f == 'd' || *f == 'i'); + switch (sizemod) { + case F_LONG: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, long)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned long)); + break; + case F_LONGLONG: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, long long)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned long long)); + break; + case F_SIZE: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, Py_ssize_t)) : + sprintf(buffer, fmt, va_arg(*vargs, size_t)); + break; + case F_PTRDIFF: + len = sprintf(buffer, fmt, va_arg(*vargs, ptrdiff_t)); + break; + case F_INTMAX: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, intmax_t)) : + sprintf(buffer, fmt, va_arg(*vargs, uintmax_t)); + break; + default: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, int)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned int)); + break; } assert(len >= 0); - if (precision < len) - precision = len; + int sign = (buffer[0] == '-'); + len -= sign; + + precision = Py_MAX(precision, len); + width = Py_MAX(width, precision + sign); + if ((flags & F_ZERO) && !(flags & F_LJUST)) { + precision = width - sign; + } + + Py_ssize_t spacepad = Py_MAX(width - precision - sign, 0); + Py_ssize_t zeropad = Py_MAX(precision - len, 0); - arglen = Py_MAX(precision, width); - if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1) + if (_PyUnicodeWriter_Prepare(writer, width, 127) == -1) return NULL; - if (width > precision) { - Py_UCS4 fillchar; - fill = width - precision; - fillchar = zeropad?'0':' '; - if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1) + if (spacepad && !(flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, spacepad, ' ') == -1) return NULL; - writer->pos += fill; + writer->pos += spacepad; } - if (precision > len) { - fill = precision - len; - if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1) + + if (sign) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } + + if (zeropad) { + if (PyUnicode_Fill(writer->buffer, writer->pos, zeropad, '0') == -1) return NULL; - writer->pos += fill; + writer->pos += zeropad; } - if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0) + if (_PyUnicodeWriter_WriteASCIIString(writer, &buffer[sign], len) < 0) return NULL; + + if (spacepad && (flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, spacepad, ' ') == -1) + return NULL; + writer->pos += spacepad; + } break; } case 'p': { - char number[MAX_LONG_LONG_CHARS]; + char number[MAX_INTMAX_CHARS]; len = sprintf(number, "%p", va_arg(*vargs, void*)); assert(len >= 0); @@ -2983,10 +2702,17 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 's': { - /* UTF-8 */ - const char *s = va_arg(*vargs, const char*); - if (unicode_fromformat_write_cstr(writer, s, width, precision) < 0) - return NULL; + if (sizemod) { + const wchar_t *s = va_arg(*vargs, const wchar_t*); + if (unicode_fromformat_write_wcstr(writer, s, width, precision, flags) < 0) + return NULL; + } + else { + /* UTF-8 */ + const char *s = va_arg(*vargs, const char*); + if (unicode_fromformat_write_cstr(writer, s, width, precision, flags) < 0) + return NULL; + } break; } @@ -2995,7 +2721,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, PyObject *obj = va_arg(*vargs, PyObject *); assert(obj && _PyUnicode_CHECK(obj)); - if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + if (unicode_fromformat_write_str(writer, obj, width, precision, flags) == -1) return NULL; break; } @@ -3003,15 +2729,27 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'V': { PyObject *obj = va_arg(*vargs, PyObject *); - const char *str = va_arg(*vargs, const char *); + const char *str; + const wchar_t *wstr; + if (sizemod) { + wstr = va_arg(*vargs, const wchar_t*); + } + else { + str = va_arg(*vargs, const char *); + } if (obj) { assert(_PyUnicode_CHECK(obj)); - if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + if (unicode_fromformat_write_str(writer, obj, width, precision, flags) == -1) + return NULL; + } + else if (sizemod) { + assert(wstr != NULL); + if (unicode_fromformat_write_wcstr(writer, wstr, width, precision, flags) < 0) return NULL; } else { assert(str != NULL); - if (unicode_fromformat_write_cstr(writer, str, width, precision) < 0) + if (unicode_fromformat_write_cstr(writer, str, width, precision, flags) < 0) return NULL; } break; @@ -3025,7 +2763,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, str = PyObject_Str(obj); if (!str) return NULL; - if (unicode_fromformat_write_str(writer, str, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, str, width, precision, flags) == -1) { Py_DECREF(str); return NULL; } @@ -3041,7 +2779,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, repr = PyObject_Repr(obj); if (!repr) return NULL; - if (unicode_fromformat_write_str(writer, repr, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, repr, width, precision, flags) == -1) { Py_DECREF(repr); return NULL; } @@ -3057,7 +2795,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, ascii = PyObject_ASCII(obj); if (!ascii) return NULL; - if (unicode_fromformat_write_str(writer, ascii, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, ascii, width, precision, flags) == -1) { Py_DECREF(ascii); return NULL; } @@ -3065,21 +2803,10 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case '%': - if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) - return NULL; - break; - default: - /* if we stumble upon an unknown formatting code, copy the rest - of the format string to the output string. (we cannot just - skip the code, since there's no way to know what's in the - argument list) */ - len = strlen(p); - if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) - return NULL; - f = p+len; - return f; + invalid_format: + PyErr_Format(PyExc_SystemError, "invalid format string: %s", p); + return NULL; } f++; @@ -3149,11 +2876,7 @@ PyUnicode_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyUnicode_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -3167,13 +2890,6 @@ unicode_get_widechar_size(PyObject *unicode) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - if (_PyUnicode_WSTR(unicode) != NULL) { - return PyUnicode_WSTR_LENGTH(unicode); - } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); - res = _PyUnicode_LENGTH(unicode); #if SIZEOF_WCHAR_T == 2 if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) { @@ -3195,19 +2911,10 @@ unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wstr = _PyUnicode_WSTR(unicode); - if (wstr != NULL) { - memcpy(w, wstr, size * sizeof(wchar_t)); - return; - } -#else /* USE_UNICODE_WCHAR_CACHE */ if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) { memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t)); return; } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) { const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode); @@ -3312,7 +3019,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, } buflen = unicode_get_widechar_size(unicode); - buffer = (wchar_t *) PyMem_NEW(wchar_t, (buflen + 1)); + buffer = (wchar_t *) PyMem_New(wchar_t, (buflen + 1)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; @@ -3348,26 +3055,16 @@ _PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str, not %.50s", @@ -3380,9 +3077,7 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } @@ -3391,19 +3086,11 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str or None, not %.50s", @@ -3429,10 +3116,7 @@ PyUnicode_FromObject(PyObject *obj) /* XXX Perhaps we should make this API an alias of PyObject_Str() instead ?! */ if (PyUnicode_CheckExact(obj)) { - if (PyUnicode_READY(obj) == -1) - return NULL; - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyUnicode_Check(obj)) { /* For a Unicode subtype that's not a Unicode object, @@ -4103,48 +3787,25 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) int PyUnicode_FSDecoder(PyObject* arg, void* addr) { - int is_buffer = 0; - PyObject *path = NULL; - PyObject *output = NULL; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); *(PyObject**)addr = NULL; return 1; } - is_buffer = PyObject_CheckBuffer(arg); - if (!is_buffer) { - path = PyOS_FSPath(arg); - if (path == NULL) { - return 0; - } - } - else { - path = arg; - Py_INCREF(arg); + PyObject *path = PyOS_FSPath(arg); + if (path == NULL) { + return 0; } + PyObject *output = NULL; if (PyUnicode_Check(path)) { output = path; } - else if (PyBytes_Check(path) || is_buffer) { - PyObject *path_bytes = NULL; - - if (!PyBytes_Check(path) && - PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "path should be string, bytes, or os.PathLike, not %.200s", - Py_TYPE(arg)->tp_name)) { - Py_DECREF(path); - return 0; - } - path_bytes = PyBytes_FromObject(path); + else if (PyBytes_Check(path)) { + output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path), + PyBytes_GET_SIZE(path)); Py_DECREF(path); - if (!path_bytes) { - return 0; - } - output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path_bytes), - PyBytes_GET_SIZE(path_bytes)); - Py_DECREF(path_bytes); if (!output) { return 0; } @@ -4156,10 +3817,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) Py_DECREF(path); return 0; } - if (PyUnicode_READY(output) == -1) { - Py_DECREF(output); - return 0; - } + if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { PyErr_SetString(PyExc_ValueError, "embedded null character"); @@ -4180,8 +3838,6 @@ PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_UTF8(unicode) == NULL) { if (unicode_fill_utf8(unicode) == -1) { @@ -4200,85 +3856,22 @@ PyUnicode_AsUTF8(PyObject *unicode) return PyUnicode_AsUTF8AndSize(unicode, NULL); } -Py_UNICODE * -PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) -{ - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } - Py_UNICODE *w = _PyUnicode_WSTR(unicode); - if (w == NULL) { - /* Non-ASCII compact unicode object */ - assert(_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND); - assert(PyUnicode_IS_READY(unicode)); - - Py_ssize_t wlen = unicode_get_widechar_size(unicode); - if ((size_t)wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { - PyErr_NoMemory(); - return NULL; - } - w = (wchar_t *) PyObject_Malloc(sizeof(wchar_t) * (wlen + 1)); - if (w == NULL) { - PyErr_NoMemory(); - return NULL; - } - unicode_copy_as_widechar(unicode, w, wlen + 1); - _PyUnicode_WSTR(unicode) = w; - if (!PyUnicode_IS_COMPACT_ASCII(unicode)) { - _PyUnicode_WSTR_LENGTH(unicode) = wlen; - } - } - if (size != NULL) - *size = PyUnicode_WSTR_LENGTH(unicode); - return w; -} - -/* Deprecated APIs */ - -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - -Py_UNICODE * -PyUnicode_AsUnicode(PyObject *unicode) -{ - return PyUnicode_AsUnicodeAndSize(unicode, NULL); -} - -const Py_UNICODE * -_PyUnicode_AsUnicode(PyObject *unicode) -{ - Py_ssize_t size; - const Py_UNICODE *wstr; - - wstr = PyUnicode_AsUnicodeAndSize(unicode, &size); - if (wstr && wcslen(wstr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return NULL; - } - return wstr; -} - +/* +PyUnicode_GetSize() has been deprecated since Python 3.3 +because it returned length of Py_UNICODE. -Py_ssize_t +But this function is part of stable abi, because it don't +include Py_UNICODE in signature and it was not excluded from +stable abi in PEP 384. +*/ +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize(PyObject *unicode) { - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - goto onError; - } - if (_PyUnicode_WSTR(unicode) == NULL) { - if (PyUnicode_AsUnicode(unicode) == NULL) - goto onError; - } - return PyUnicode_WSTR_LENGTH(unicode); - - onError: + PyErr_SetString(PyExc_RuntimeError, + "PyUnicode_GetSize has been removed."); return -1; } -_Py_COMP_DIAG_POP - Py_ssize_t PyUnicode_GetLength(PyObject *unicode) { @@ -4286,8 +3879,6 @@ PyUnicode_GetLength(PyObject *unicode) PyErr_BadArgument(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; return PyUnicode_GET_LENGTH(unicode); } @@ -4301,9 +3892,6 @@ PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index) PyErr_BadArgument(); return (Py_UCS4)-1; } - if (PyUnicode_READY(unicode) == -1) { - return (Py_UCS4)-1; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return (Py_UCS4)-1; @@ -4320,7 +3908,6 @@ PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, Py_UCS4 ch) PyErr_BadArgument(); return -1; } - assert(PyUnicode_IS_READY(unicode)); if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -4453,19 +4040,10 @@ unicode_decode_call_errorhandler_wchar( goto onError; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - repwlen = PyUnicode_GetSize(repunicode); - if (repwlen < 0) - goto onError; -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ repwlen = PyUnicode_AsWideChar(repunicode, NULL, 0); if (repwlen < 0) goto onError; repwlen--; -#endif /* USE_UNICODE_WCHAR_CACHE */ /* need more space? (at least enough for what we have+the replacement+the rest of the string (starting at the new input position), so we won't have to check space @@ -4915,8 +4493,6 @@ _PyUnicode_EncodeUTF7(PyObject *str, char * out; const char * start; - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5548,14 +5124,11 @@ unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; - if (PyUnicode_UTF8(unicode)) return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode), PyUnicode_UTF8_LENGTH(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5591,7 +5164,7 @@ unicode_fill_utf8(PyObject *unicode) /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5726,7 +5299,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, Py_UCS4 maxch = PyUnicode_MAX_CHAR_VALUE(writer.buffer); if (e - q >= 4) { - enum PyUnicode_Kind kind = writer.kind; + int kind = writer.kind; void *data = writer.data; const unsigned char *last = e - 4; Py_ssize_t pos = writer.pos; @@ -5811,7 +5384,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -5831,8 +5404,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5899,8 +5470,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, @@ -6132,7 +5701,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -6153,8 +5722,6 @@ _PyUnicode_EncodeUTF16(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -6238,8 +5805,6 @@ _PyUnicode_EncodeUTF16(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, @@ -6303,8 +5868,6 @@ PyUnicode_AsUTF16String(PyObject *unicode) /* --- Unicode Escape Codec ----------------------------------------------- */ -static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; - PyObject * _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, Py_ssize_t size, @@ -6317,6 +5880,8 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, const char *end; PyObject *errorHandler = NULL; PyObject *exc = NULL; + _PyUnicode_Name_CAPI *ucnhash_capi; + PyInterpreterState *interp = _PyInterpreterState_Get(); // so we can remember if we've seen an invalid escape char or not *first_invalid_escape = NULL; @@ -6464,6 +6029,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, /* \N{name} */ case 'N': + ucnhash_capi = interp->unicode.ucnhash_capi; if (ucnhash_capi == NULL) { /* load the unicode data module */ ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( @@ -6475,6 +6041,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ); goto onError; } + interp->unicode.ucnhash_capi = ucnhash_capi; } message = "malformed \\N character escape"; @@ -6601,7 +6168,7 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) Py_ssize_t i, len; PyObject *repr; char *p; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t expandsize; @@ -6617,9 +6184,6 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } len = PyUnicode_GET_LENGTH(unicode); if (len == 0) { @@ -6874,9 +6438,6 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); len = PyUnicode_GET_LENGTH(unicode); @@ -7013,8 +6574,6 @@ unicode_encode_call_errorhandler(const char *errors, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); make_encode_exception(exceptionObject, @@ -7072,8 +6631,6 @@ unicode_encode_ucs1(PyObject *unicode, /* output object */ _PyBytesWriter writer; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -7192,9 +6749,6 @@ unicode_encode_ucs1(PyObject *unicode, else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto onError; - if (limit == 256 ? PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND : !PyUnicode_IS_ASCII(rep)) @@ -7241,8 +6795,6 @@ _PyUnicode_AsLatin1String(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is a one-byte string, construct bytes object directly. */ if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) @@ -7367,8 +6919,6 @@ _PyUnicode_AsASCIIString(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is an ASCII-only string, construct bytes object directly. Else defer to above function to raise the exception. */ if (PyUnicode_IS_ASCII(unicode)) @@ -7756,22 +7306,11 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, substring = PyUnicode_Substring(unicode, offset, offset+len); if (substring == NULL) return -1; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - p = PyUnicode_AsUnicodeAndSize(substring, &size); - if (p == NULL) { - Py_DECREF(substring); - return -1; - } -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ p = PyUnicode_AsWideCharString(substring, &size); Py_CLEAR(substring); if (p == NULL) { return -1; } -#endif /* USE_UNICODE_WCHAR_CACHE */ assert(size <= INT_MAX); /* First get the size of the result */ @@ -7822,11 +7361,7 @@ _Py_COMP_DIAG_POP ret = 0; done: -#if USE_UNICODE_WCHAR_CACHE - Py_DECREF(substring); -#else /* USE_UNICODE_WCHAR_CACHE */ PyMem_Free(p); -#endif /* USE_UNICODE_WCHAR_CACHE */ return ret; error: @@ -7976,14 +7511,9 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, } else { Py_ssize_t i; - enum PyUnicode_Kind kind; + int kind; const void *data; - if (PyUnicode_READY(rep) == -1) { - Py_DECREF(rep); - goto error; - } - outsize = PyUnicode_GET_LENGTH(rep); morebytes += outsize; if (morebytes > 0) { @@ -8044,8 +7574,6 @@ encode_code_page(int code_page, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); if (code_page < 0) { @@ -8122,14 +7650,11 @@ charmap_decode_string(const char *s, Py_ssize_t startinpos, endinpos; PyObject *errorHandler = NULL, *exc = NULL; Py_ssize_t maplen; - enum PyUnicode_Kind mapkind; + int mapkind; const void *mapdata; Py_UCS4 x; unsigned char ch; - if (PyUnicode_READY(mapping) == -1) - return -1; - maplen = PyUnicode_GET_LENGTH(mapping); mapdata = PyUnicode_DATA(mapping); mapkind = PyUnicode_KIND(mapping); @@ -8163,7 +7688,7 @@ charmap_decode_string(const char *s, while (s < e) { if (mapkind == PyUnicode_2BYTE_KIND && maplen >= 256) { - enum PyUnicode_Kind outkind = writer->kind; + int outkind = writer->kind; const Py_UCS2 *mapdata_ucs2 = (const Py_UCS2 *)mapdata; if (outkind == PyUnicode_1BYTE_KIND) { Py_UCS1 *outdata = (Py_UCS1 *)writer->data; @@ -8282,8 +7807,6 @@ charmap_decode_mapping(const char *s, goto onError; } else if (PyUnicode_Check(item)) { - if (PyUnicode_READY(item) == -1) - goto onError; if (PyUnicode_GET_LENGTH(item) == 1) { Py_UCS4 value = PyUnicode_READ_CHAR(item, 0); if (value == 0xFFFE) @@ -8689,7 +8212,7 @@ charmap_encoding_error( PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ Py_ssize_t size, repsize; Py_ssize_t newpos; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t index; /* startpos for collecting unencodable chars */ @@ -8702,8 +8225,6 @@ charmap_encoding_error( Py_UCS4 ch; int val; - if (PyUnicode_READY(unicode) == -1) - return -1; size = PyUnicode_GET_LENGTH(unicode); /* find all unencodable characters */ while (collendpos < size) { @@ -8799,10 +8320,6 @@ charmap_encoding_error( break; } /* generate replacement */ - if (PyUnicode_READY(repunicode) == -1) { - Py_DECREF(repunicode); - return -1; - } repsize = PyUnicode_GET_LENGTH(repunicode); data = PyUnicode_DATA(repunicode); kind = PyUnicode_KIND(repunicode); @@ -8843,8 +8360,6 @@ _PyUnicode_EncodeCharmap(PyObject *unicode, const void *data; int kind; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); data = PyUnicode_DATA(unicode); kind = PyUnicode_KIND(unicode); @@ -9123,10 +8638,6 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, else if (PyUnicode_Check(item)) { Py_UCS4 replace; - if (PyUnicode_READY(item) == -1) { - Py_DECREF(item); - return -1; - } if (PyUnicode_GET_LENGTH(item) != 1) goto exit; @@ -9223,8 +8734,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, return NULL; } - if (PyUnicode_READY(input) == -1) - return NULL; data = PyUnicode_DATA(input); kind = PyUnicode_KIND(input); size = PyUnicode_GET_LENGTH(input); @@ -9240,8 +8749,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, ignore = (errors != NULL && strcmp(errors, "ignore") == 0); - if (PyUnicode_READY(input) == -1) - return NULL; if (PyUnicode_IS_ASCII(input)) { res = unicode_fast_translate(input, mapping, &writer, ignore, &i); if (res < 0) { @@ -9337,12 +8844,9 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_IS_ASCII(unicode)) { /* If the string is already ASCII, just return the same string */ - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); @@ -9530,15 +9034,6 @@ _PyUnicode_InsertThousandsGrouping( assert(0 <= n_digits); assert(grouping != NULL); - if (digits != NULL) { - if (PyUnicode_READY(digits) == -1) { - return -1; - } - } - if (PyUnicode_READY(thousands_sep) == -1) { - return -1; - } - Py_ssize_t count = 0; Py_ssize_t n_zeros; int loop_broken = 0; @@ -9624,21 +9119,20 @@ _PyUnicode_InsertThousandsGrouping( return count; } - -Py_ssize_t -PyUnicode_Count(PyObject *str, - PyObject *substr, - Py_ssize_t start, - Py_ssize_t end) +static Py_ssize_t +unicode_count_impl(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) { + assert(PyUnicode_Check(str)); + assert(PyUnicode_Check(substr)); + Py_ssize_t result; int kind1, kind2; const void *buf1 = NULL, *buf2 = NULL; Py_ssize_t len1, len2; - if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) - return -1; - kind1 = PyUnicode_KIND(str); kind2 = PyUnicode_KIND(substr); if (kind1 < kind2) @@ -9658,18 +9152,13 @@ PyUnicode_Count(PyObject *str, goto onError; } + // We don't reuse `anylib_count` here because of the explicit casts. switch (kind1) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(str) && PyUnicode_IS_ASCII(substr)) - result = asciilib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - else - result = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); + result = ucs1lib_count( + ((const Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); break; case PyUnicode_2BYTE_KIND: result = ucs2lib_count( @@ -9700,6 +9189,18 @@ PyUnicode_Count(PyObject *str, } Py_ssize_t +PyUnicode_Count(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -1; + + return unicode_count_impl(str, substr, start, end); +} + +Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, @@ -9719,8 +9220,6 @@ PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, { int kind; Py_ssize_t len, result; - if (PyUnicode_READY(str) == -1) - return -2; len = PyUnicode_GET_LENGTH(str); ADJUST_INDICES(start, end, len); if (end - start < 1) @@ -9749,10 +9248,6 @@ tailmatch(PyObject *self, Py_ssize_t i; Py_ssize_t end_sub; - if (PyUnicode_READY(self) == -1 || - PyUnicode_READY(substring) == -1) - return -1; - ADJUST_INDICES(start, end, PyUnicode_GET_LENGTH(self)); end -= PyUnicode_GET_LENGTH(substring); if (end < start) @@ -10011,8 +9506,6 @@ case_operation(PyObject *self, void *outdata; Py_UCS4 maxchar = 0, *tmp, *tmpend; - assert(PyUnicode_IS_READY(self)); - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); length = PyUnicode_GET_LENGTH(self); @@ -10085,7 +9578,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq int use_memcpy; unsigned char *res_data = NULL, *sep_data = NULL; PyObject *last_obj; - unsigned int kind = 0; + int kind = 0; /* If empty sequence, return u"". */ if (seqlen == 0) { @@ -10097,8 +9590,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq if (seqlen == 1) { if (PyUnicode_CheckExact(items[0])) { res = items[0]; - Py_INCREF(res); - return res; + return Py_NewRef(res); } seplen = 0; maxchar = 0; @@ -10121,8 +9613,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq Py_TYPE(separator)->tp_name); goto onError; } - if (PyUnicode_READY(separator)) - goto onError; sep = separator; seplen = PyUnicode_GET_LENGTH(separator); maxchar = PyUnicode_MAX_CHAR_VALUE(separator); @@ -10154,8 +9644,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq i, Py_TYPE(item)->tp_name); goto onError; } - if (PyUnicode_READY(item) == -1) - goto onError; add_sz = PyUnicode_GET_LENGTH(item); item_maxchar = PyUnicode_MAX_CHAR_VALUE(item); maxchar = Py_MAX(maxchar, item_maxchar); @@ -10248,9 +9736,8 @@ void _PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, Py_UCS4 fill_char) { - const enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + const int kind = PyUnicode_KIND(unicode); void *data = PyUnicode_DATA(unicode); - assert(PyUnicode_IS_READY(unicode)); assert(unicode_modifiable(unicode)); assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode)); assert(start >= 0); @@ -10268,8 +9755,6 @@ PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, PyErr_BadInternalCall(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; if (unicode_check_modifiable(unicode)) return -1; @@ -10378,53 +9863,53 @@ split(PyObject *self, const void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; - - if (PyUnicode_READY(self) == -1) - return NULL; - - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_split_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_split_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } + } - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10471,52 +9956,52 @@ rsplit(PyObject *self, Py_ssize_t len1, len2; PyObject* out; - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; - - if (PyUnicode_READY(self) == -1) - return NULL; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_rsplit_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_rsplit_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } - - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); + } kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10577,10 +10062,7 @@ anylib_count(int kind, PyObject *sstr, const void* sbuf, Py_ssize_t slen, { switch (kind) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(sstr) && PyUnicode_IS_ASCII(str1)) - return asciilib_count(sbuf, slen, buf1, len1, maxcount); - else - return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); + return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_2BYTE_KIND: return ucs2lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_4BYTE_KIND: @@ -10908,8 +10390,6 @@ static PyObject * unicode_title_impl(PyObject *self) /*[clinic end generated code: output=c75ae03809574902 input=fa945d669b26e683]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_title); } @@ -10926,8 +10406,6 @@ static PyObject * unicode_capitalize_impl(PyObject *self) /*[clinic end generated code: output=e49a4c333cdb7667 input=f4cbf1016938da6d]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_GET_LENGTH(self) == 0) return unicode_result_unchanged(self); return case_operation(self, do_capitalize); @@ -10943,8 +10421,6 @@ static PyObject * unicode_casefold_impl(PyObject *self) /*[clinic end generated code: output=0120daf657ca40af input=384d66cc2ae30daf]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_casefold); @@ -10964,8 +10440,6 @@ convert_uc(PyObject *obj, void *addr) "not %.100s", Py_TYPE(obj)->tp_name); return 0; } - if (PyUnicode_READY(obj) < 0) - return 0; if (PyUnicode_GET_LENGTH(obj) != 1) { PyErr_SetString(PyExc_TypeError, "The fill character must be exactly one character long"); @@ -10993,9 +10467,6 @@ unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) { Py_ssize_t marg, left; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -11152,9 +10623,6 @@ _PyUnicode_Equal(PyObject *str1, PyObject *str2) if (str1 == str2) { return 1; } - if (PyUnicode_READY(str1) || PyUnicode_READY(str2)) { - return -1; - } return unicode_compare_eq(str1, str2); } @@ -11163,10 +10631,6 @@ int PyUnicode_Compare(PyObject *left, PyObject *right) { if (PyUnicode_Check(left) && PyUnicode_Check(right)) { - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return -1; - /* a string is equal to itself */ if (left == right) return 0; @@ -11186,24 +10650,8 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) Py_ssize_t i; int kind; Py_UCS4 chr; - const unsigned char *ustr = (const unsigned char *)str; assert(_PyUnicode_CHECK(uni)); - if (!PyUnicode_IS_READY(uni)) { - const wchar_t *ws = _PyUnicode_WSTR(uni); - /* Compare Unicode string and source character set string */ - for (i = 0; (chr = ws[i]) && ustr[i]; i++) { - if (chr != ustr[i]) - return (chr < ustr[i]) ? -1 : 1; - } - /* This check keeps Python strings that end in '\0' from comparing equal - to C strings identical up to that point. */ - if (_PyUnicode_WSTR_LENGTH(uni) != i || chr) - return 1; /* uni is longer */ - if (ustr[i]) - return -1; /* str is longer */ - return 0; - } kind = PyUnicode_KIND(uni); if (kind == PyUnicode_1BYTE_KIND) { const void *data = PyUnicode_1BYTE_DATA(uni); @@ -11241,24 +10689,6 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) } } -static int -non_ready_unicode_equal_to_ascii_string(PyObject *unicode, const char *str) -{ - size_t i, len; - const wchar_t *p; - len = (size_t)_PyUnicode_WSTR_LENGTH(unicode); - if (strlen(str) != len) - return 0; - p = _PyUnicode_WSTR(unicode); - assert(p); - for (i = 0; i < len; i++) { - unsigned char c = (unsigned char)str[i]; - if (c >= 128 || p[i] != (wchar_t)c) - return 0; - } - return 1; -} - int _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) { @@ -11270,11 +10700,6 @@ _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) assert((unsigned char)*p < 128); } #endif - if (PyUnicode_READY(unicode) == -1) { - /* Memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(unicode, str); - } if (!PyUnicode_IS_ASCII(unicode)) return 0; len = (size_t)PyUnicode_GET_LENGTH(unicode); @@ -11295,12 +10720,6 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) } #endif - if (PyUnicode_READY(left) == -1) { - /* memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(left, right->string); - } - if (!PyUnicode_IS_ASCII(left)) return 0; @@ -11334,10 +10753,6 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) Py_RETURN_NOTIMPLEMENTED; - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return NULL; - if (left == right) { switch (op) { case Py_EQ: @@ -11385,8 +10800,6 @@ PyUnicode_Contains(PyObject *str, PyObject *substr) Py_TYPE(substr)->tp_name); return -1; } - if (PyUnicode_READY(substr) == -1) - return -1; if (ensure_unicode(str) < 0) return -1; @@ -11450,8 +10863,6 @@ PyUnicode_Concat(PyObject *left, PyObject *right) Py_TYPE(right)->tp_name); return NULL; } - if (PyUnicode_READY(right) < 0) - return NULL; /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference @@ -11505,17 +10916,11 @@ PyUnicode_Append(PyObject **p_left, PyObject *right) goto error; } - if (PyUnicode_READY(left) == -1) - goto error; - if (PyUnicode_READY(right) == -1) - goto error; - /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference if (left == empty) { Py_DECREF(left); - Py_INCREF(right); - *p_left = right; + *p_left = Py_NewRef(right); return; } if (right == empty) { @@ -11576,7 +10981,7 @@ PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right) } /* -Wraps stringlib_parse_args_finds() and additionally ensures that the +Wraps asciilib_parse_args_finds() and additionally ensures that the first argument is a unicode object. */ @@ -11585,8 +10990,7 @@ parse_args_finds_unicode(const char * function_name, PyObject *args, PyObject **substring, Py_ssize_t *start, Py_ssize_t *end) { - if(stringlib_parse_args_finds(function_name, args, substring, - start, end)) { + if (asciilib_parse_args_finds(function_name, args, substring, start, end)) { if (ensure_unicode(*substring) < 0) return 0; return 1; @@ -11607,62 +11011,16 @@ unicode_count(PyObject *self, PyObject *args) PyObject *substring = NULL; /* initialize to fix a compiler warning */ Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *result; - int kind1, kind2; - const void *buf1, *buf2; - Py_ssize_t len1, len2, iresult; + Py_ssize_t result; if (!parse_args_finds_unicode("count", args, &substring, &start, &end)) return NULL; - kind1 = PyUnicode_KIND(self); - kind2 = PyUnicode_KIND(substring); - if (kind1 < kind2) - return PyLong_FromLong(0); - - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - ADJUST_INDICES(start, end, len1); - if (end - start < len2) - return PyLong_FromLong(0); - - buf1 = PyUnicode_DATA(self); - buf2 = PyUnicode_DATA(substring); - if (kind2 != kind1) { - buf2 = unicode_askind(kind2, buf2, len2, kind1); - if (!buf2) - return NULL; - } - switch (kind1) { - case PyUnicode_1BYTE_KIND: - iresult = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_2BYTE_KIND: - iresult = ucs2lib_count( - ((const Py_UCS2*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_4BYTE_KIND: - iresult = ucs4lib_count( - ((const Py_UCS4*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - default: - Py_UNREACHABLE(); - } - - result = PyLong_FromSsize_t(iresult); - - assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(substring))); - if (kind2 != kind1) - PyMem_Free((void *)buf2); + result = unicode_count_impl(self, substring, start, end); + if (result == -1) + return NULL; - return result; + return PyLong_FromSsize_t(result); } /*[clinic input] @@ -11709,9 +11067,6 @@ unicode_expandtabs_impl(PyObject *self, int tabsize) int kind; int found; - if (PyUnicode_READY(self) == -1) - return NULL; - /* First pass: determine size of output string */ src_len = PyUnicode_GET_LENGTH(self); i = j = line_pos = 0; @@ -11797,9 +11152,6 @@ unicode_find(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("find", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11812,16 +11164,13 @@ static PyObject * unicode_getitem(PyObject *self, Py_ssize_t index) { const void *data; - enum PyUnicode_Kind kind; + int kind; Py_UCS4 ch; if (!PyUnicode_Check(self)) { PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(self) == -1) { - return NULL; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; @@ -11844,8 +11193,6 @@ unicode_hash(PyObject *self) #endif if (_PyUnicode_HASH(self) != -1) return _PyUnicode_HASH(self); - if (PyUnicode_READY(self) == -1) - return -1; x = _Py_HashBytes(PyUnicode_DATA(self), PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self)); @@ -11874,9 +11221,6 @@ unicode_index(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("index", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11903,9 +11247,6 @@ static PyObject * unicode_isascii_impl(PyObject *self) /*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/ { - if (PyUnicode_READY(self) == -1) { - return NULL; - } return PyBool_FromLong(PyUnicode_IS_ASCII(self)); } @@ -11927,8 +11268,6 @@ unicode_islower_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -11972,8 +11311,6 @@ unicode_isupper_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12017,8 +11354,6 @@ unicode_istitle_impl(PyObject *self) const void *data; int cased, previous_is_cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12074,8 +11409,6 @@ unicode_isspace_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12114,8 +11447,6 @@ unicode_isalpha_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12153,9 +11484,6 @@ unicode_isalnum_impl(PyObject *self) const void *data; Py_ssize_t len, i; - if (PyUnicode_READY(self) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12195,8 +11523,6 @@ unicode_isdecimal_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12234,8 +11560,6 @@ unicode_isdigit_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12274,8 +11598,6 @@ unicode_isnumeric_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12300,9 +11622,6 @@ Py_ssize_t _PyUnicode_ScanIdentifier(PyObject *self) { Py_ssize_t i; - if (PyUnicode_READY(self) == -1) - return -1; - Py_ssize_t len = PyUnicode_GET_LENGTH(self); if (len == 0) { /* an empty string is not a valid identifier */ @@ -12336,54 +11655,10 @@ _PyUnicode_ScanIdentifier(PyObject *self) int PyUnicode_IsIdentifier(PyObject *self) { - if (PyUnicode_IS_READY(self)) { - Py_ssize_t i = _PyUnicode_ScanIdentifier(self); - Py_ssize_t len = PyUnicode_GET_LENGTH(self); - /* an empty string is not a valid identifier */ - return len && i == len; - } - else { -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_ssize_t i = 0, len = PyUnicode_GET_SIZE(self); - if (len == 0) { - /* an empty string is not a valid identifier */ - return 0; - } - - const wchar_t *wstr = _PyUnicode_WSTR(self); - Py_UCS4 ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidStart(ch) && ch != 0x5F /* LOW LINE */) { - return 0; - } - - while (i < len) { - ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidContinue(ch)) { - return 0; - } - } - return 1; -_Py_COMP_DIAG_POP - } + Py_ssize_t i = _PyUnicode_ScanIdentifier(self); + Py_ssize_t len = PyUnicode_GET_LENGTH(self); + /* an empty string is not a valid identifier */ + return len && i == len; } /*[clinic input] @@ -12419,8 +11694,6 @@ unicode_isprintable_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12462,8 +11735,6 @@ unicode_join(PyObject *self, PyObject *iterable) static Py_ssize_t unicode_length(PyObject *self) { - if (PyUnicode_READY(self) == -1) - return -1; return PyUnicode_GET_LENGTH(self); } @@ -12483,9 +11754,6 @@ static PyObject * unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -12502,8 +11770,6 @@ static PyObject * unicode_lower_impl(PyObject *self) /*[clinic end generated code: output=84ef9ed42efad663 input=60a2984b8beff23a]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_lower); @@ -12528,9 +11794,6 @@ _PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj) BLOOM_MASK sepmask; Py_ssize_t seplen; - if (PyUnicode_READY(self) == -1 || PyUnicode_READY(sepobj) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12576,9 +11839,6 @@ PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end) int kind; Py_ssize_t length; - if (PyUnicode_READY(self) == -1) - return NULL; - length = PyUnicode_GET_LENGTH(self); end = Py_MIN(end, length); @@ -12611,9 +11871,6 @@ do_strip(PyObject *self, int striptype) { Py_ssize_t len, i, j; - if (PyUnicode_READY(self) == -1) - return NULL; - len = PyUnicode_GET_LENGTH(self); if (PyUnicode_IS_ASCII(self)) { @@ -12760,9 +12017,6 @@ unicode_repeat(PyObject *str, Py_ssize_t len) if (len == 1) return unicode_result_unchanged(str); - if (PyUnicode_READY(str) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(str) > PY_SSIZE_T_MAX / len) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); @@ -12837,8 +12091,6 @@ unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count) /*[clinic end generated code: output=b63f1a8b5eebf448 input=147d12206276ebeb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return replace(self, old, new, count); } @@ -12908,9 +12160,6 @@ unicode_repr(PyObject *unicode) const void *idata; void *odata; - if (PyUnicode_READY(unicode) == -1) - return NULL; - isize = PyUnicode_GET_LENGTH(unicode); idata = PyUnicode_DATA(unicode); @@ -13083,9 +12332,6 @@ unicode_rfind(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rfind", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13115,9 +12361,6 @@ unicode_rindex(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rindex", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13147,9 +12390,6 @@ static PyObject * unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13384,7 +12624,7 @@ unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) /*[clinic input] str.splitlines as unicode_splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the string, breaking at line boundaries. @@ -13394,7 +12634,7 @@ true. static PyObject * unicode_splitlines_impl(PyObject *self, int keepends) -/*[clinic end generated code: output=f664dcdad153ec40 input=b508e180459bdd8b]*/ +/*[clinic end generated code: output=f664dcdad153ec40 input=ba6ad05ee85d2b55]*/ { return PyUnicode_Splitlines(self, keepends); } @@ -13415,8 +12655,6 @@ static PyObject * unicode_swapcase_impl(PyObject *self) /*[clinic end generated code: output=5d28966bf6d7b2af input=3f3ef96d5798a7bb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_swapcase); } @@ -13582,8 +12820,6 @@ static PyObject * unicode_upper_impl(PyObject *self) /*[clinic end generated code: output=1b7ddd16bbcdc092 input=db3d55682dfe2e6c]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 0); return case_operation(self, do_upper); @@ -13610,9 +12846,6 @@ unicode_zfill_impl(PyObject *self, Py_ssize_t width) const void *data; Py_UCS4 chr; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13655,7 +12888,7 @@ unicode_startswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("startswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13709,7 +12942,7 @@ unicode_endswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("endswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13756,7 +12989,7 @@ _PyUnicodeWriter_Update(_PyUnicodeWriter *writer) else { /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); /* Copy-on-write mode: set buffer size to 0 so @@ -13776,7 +13009,7 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer) /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); } @@ -13869,7 +13102,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, int _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind) + int kind) { Py_UCS4 maxchar; @@ -13911,8 +13144,6 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; len = PyUnicode_GET_LENGTH(str); if (len == 0) return 0; @@ -13921,8 +13152,7 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) if (writer->buffer == NULL && !writer->overallocate) { assert(_PyUnicode_CheckConsistency(str, 1)); writer->readonly = 1; - Py_INCREF(str); - writer->buffer = str; + writer->buffer = Py_NewRef(str); _PyUnicodeWriter_Update(writer); writer->pos += len; return 0; @@ -13943,9 +13173,6 @@ _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str, Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; - assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(str)); assert(start <= end); @@ -14074,7 +13301,7 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) } assert(_PyUnicode_CheckConsistency(str, 1)); - return unicode_result_ready(str); + return unicode_result(str); } void @@ -14113,8 +13340,6 @@ unicode___format___impl(PyObject *self, PyObject *format_spec) _PyUnicodeWriter writer; int ret; - if (PyUnicode_READY(self) == -1) - return NULL; _PyUnicodeWriter_Init(&writer); ret = _PyUnicode_FormatAdvancedWriter(&writer, self, format_spec, 0, @@ -14140,11 +13365,13 @@ unicode_sizeof_impl(PyObject *self) /* If it's a compact object, account for base structure + character data. */ - if (PyUnicode_IS_COMPACT_ASCII(self)) + if (PyUnicode_IS_COMPACT_ASCII(self)) { size = sizeof(PyASCIIObject) + PyUnicode_GET_LENGTH(self) + 1; - else if (PyUnicode_IS_COMPACT(self)) + } + else if (PyUnicode_IS_COMPACT(self)) { size = sizeof(PyCompactUnicodeObject) + (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); + } else { /* If it is a two-block object, account for base object, and for character block if present. */ @@ -14153,10 +13380,6 @@ unicode_sizeof_impl(PyObject *self) size += (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); } - /* If the wstr pointer is present, account for it unless it is shared - with the data pointer. Check if the data is not shared. */ - if (_PyUnicode_HAS_WSTR_MEMORY(self)) - size += (PyUnicode_WSTR_LENGTH(self) + 1) * sizeof(wchar_t); if (_PyUnicode_HAS_UTF8_MEMORY(self)) size += PyUnicode_UTF8_LENGTH(self) + 1; @@ -14255,9 +13478,6 @@ static PySequenceMethods unicode_as_sequence = { static PyObject* unicode_subscript(PyObject* self, PyObject* item) { - if (PyUnicode_READY(self) == -1) - return NULL; - if (_PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) @@ -14340,7 +13560,7 @@ struct unicode_formatter_t { Py_ssize_t arglen, argidx; PyObject *dict; - enum PyUnicode_Kind fmtkind; + int fmtkind; Py_ssize_t fmtcnt, fmtpos; const void *fmtdata; PyObject *fmtstr; @@ -14479,7 +13699,6 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) return NULL; assert(unicode_modifiable(result)); - assert(PyUnicode_IS_READY(result)); assert(PyUnicode_IS_ASCII(result)); /* To modify the string in-place, there can only be one reference. */ @@ -14534,8 +13753,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) for (i = 0; i < numdigits; i++) *b1++ = *buf++; *b1 = '\0'; - Py_DECREF(result); - result = r1; + Py_SETREF(result, r1); buf = PyBytes_AS_STRING(result); len = numnondigits + prec; } @@ -14552,8 +13770,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) || buf != PyUnicode_DATA(result)) { PyObject *unicode; unicode = _PyUnicode_FromASCII(buf, len); - Py_DECREF(result); - result = unicode; + Py_SETREF(result, unicode); } else if (len != PyUnicode_GET_LENGTH(result)) { if (PyUnicode_Resize(&result, len) < 0) @@ -14594,8 +13811,7 @@ mainformatlong(PyObject *v, assert(PyLong_Check(iobj)); } else { - iobj = v; - Py_INCREF(iobj); + iobj = Py_NewRef(v); } if (PyLong_CheckExact(v) @@ -14918,8 +14134,7 @@ unicode_format_arg_format(struct unicode_formatter_t *ctx, } if (PyUnicode_CheckExact(v) && arg->ch == 's') { - *p_str = v; - Py_INCREF(*p_str); + *p_str = Py_NewRef(v); } else { if (arg->ch == 's') @@ -15001,7 +14216,7 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, PyObject *str) { Py_ssize_t len; - enum PyUnicode_Kind kind; + int kind; const void *pbuf; Py_ssize_t pindex; Py_UCS4 signchar; @@ -15015,9 +14230,6 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, if (arg->sign && arg->flags & F_ZERO) fill = '0'; - if (PyUnicode_READY(str) == -1) - return -1; - len = PyUnicode_GET_LENGTH(str); if ((arg->width == -1 || arg->width <= len) && (arg->prec == -1 || arg->prec >= len) @@ -15319,15 +14531,12 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) { PyObject *self; Py_ssize_t length, char_size; - int share_wstr, share_utf8; - unsigned int kind; + int share_utf8; + int kind; void *data; assert(PyType_IsSubtype(type, &PyUnicode_Type)); assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } self = type->tp_alloc(type, 0); if (self == NULL) { @@ -15346,15 +14555,12 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_STATE(self).kind = kind; _PyUnicode_STATE(self).compact = 0; _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii; - _PyUnicode_STATE(self).ready = 1; - _PyUnicode_WSTR(self) = NULL; + _PyUnicode_STATE(self).statically_allocated = 0; _PyUnicode_UTF8_LENGTH(self) = 0; _PyUnicode_UTF8(self) = NULL; - _PyUnicode_WSTR_LENGTH(self) = 0; _PyUnicode_DATA_ANY(self) = NULL; share_utf8 = 0; - share_wstr = 0; if (kind == PyUnicode_1BYTE_KIND) { char_size = 1; if (PyUnicode_MAX_CHAR_VALUE(unicode) < 128) @@ -15362,14 +14568,10 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) } else if (kind == PyUnicode_2BYTE_KIND) { char_size = 2; - if (sizeof(wchar_t) == 2) - share_wstr = 1; } else { assert(kind == PyUnicode_4BYTE_KIND); char_size = 4; - if (sizeof(wchar_t) == 4) - share_wstr = 1; } /* Ensure we won't overflow the length. */ @@ -15388,13 +14590,8 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_UTF8_LENGTH(self) = length; _PyUnicode_UTF8(self) = data; } - if (share_wstr) { - _PyUnicode_WSTR_LENGTH(self) = length; - _PyUnicode_WSTR(self) = (wchar_t *)data; - } - memcpy(data, PyUnicode_DATA(unicode), - kind * (length + 1)); + memcpy(data, PyUnicode_DATA(unicode), kind * (length + 1)); assert(_PyUnicode_CheckConsistency(self, 1)); #ifdef Py_DEBUG _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); @@ -15474,12 +14671,14 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -void -_PyUnicode_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { + static int initialized = 0; + if (initialized) { return; } + initialized = 1; /* initialize the linebreak bloom filter */ const Py_UCS2 linebreak[] = { @@ -15497,21 +14696,42 @@ _PyUnicode_InitState(PyInterpreterState *interp) Py_ARRAY_LENGTH(linebreak)); } +void +_PyUnicode_InitState(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); + // Initialize the global interned dict + if (init_interned_dict(interp)) { + PyErr_Clear(); + return _PyStatus_ERR("failed to create interned dict"); } + if (_Py_IsMainInterpreter(interp)) { + /* Intern statically allocated string identifiers and deepfreeze strings. + * This must be done before any module initialization so that statically + * allocated string identifiers are used instead of heap allocated strings. + * Deepfreeze uses the interned identifiers if present to save space + * else generates them and they are interned to speed up dict lookups. + */ + _PyUnicode_InitStaticStrings(interp); + #ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); + assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); - for (int i = 0; i < 256; i++) { - assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); - } + for (int i = 0; i < 256; i++) { + assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); + } #endif + } return _PyStatus_OK(); } @@ -15520,17 +14740,13 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) PyStatus _PyUnicode_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&EncodingMapType) < 0) { + if (_PyStaticType_InitBuiltin(interp, &EncodingMapType) < 0) { goto error; } - if (PyType_Ready(&PyFieldNameIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(interp, &PyFieldNameIter_Type) < 0) { goto error; } - if (PyType_Ready(&PyFormatterIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(interp, &PyFormatterIter_Type) < 0) { goto error; } return _PyStatus_OK(); @@ -15541,7 +14757,7 @@ error: void -PyUnicode_InternInPlace(PyObject **p) +_PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p) { PyObject *s = *p; #ifdef Py_DEBUG @@ -15563,19 +14779,26 @@ PyUnicode_InternInPlace(PyObject **p) return; } - if (PyUnicode_READY(s) == -1) { - PyErr_Clear(); + /* Look in the global cache first. */ + PyObject *r = (PyObject *)_Py_hashtable_get(INTERNED_STRINGS, s); + if (r != NULL && r != s) { + Py_SETREF(*p, Py_NewRef(r)); return; } - if (interned == NULL) { - interned = PyDict_New(); - if (interned == NULL) { - PyErr_Clear(); /* Don't leave an exception */ - return; + /* Handle statically allocated strings. */ + if (_PyUnicode_STATE(s).statically_allocated) { + assert(_Py_IsImmortal(s)); + if (_Py_hashtable_set(INTERNED_STRINGS, s, s) == 0) { + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL_STATIC; } + return; } + /* Look in the per-interpreter cache. */ + PyObject *interned = get_interned_dict(interp); + assert(interned != NULL); + PyObject *t = PyDict_SetDefault(interned, s, s); if (t == NULL) { PyErr_Clear(); @@ -15583,35 +14806,44 @@ PyUnicode_InternInPlace(PyObject **p) } if (t != s) { - Py_INCREF(t); - Py_SETREF(*p, t); + Py_SETREF(*p, Py_NewRef(t)); + return; + } + + if (_Py_IsImmortal(s)) { + // XXX Restrict this to the main interpreter? + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL_STATIC; return; } - /* The two references in interned dict (key and value) are not counted by - refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of - this. */ - Py_SET_REFCNT(s, Py_REFCNT(s) - 2); - _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; +#ifdef Py_REF_DEBUG + /* The reference count value excluding the 2 references from the + interned dictionary should be excluded from the RefTotal. The + decrements to these objects will not be registered so they + need to be accounted for in here. */ + for (Py_ssize_t i = 0; i < Py_REFCNT(s) - 2; i++) { + _Py_DecRefTotal(_PyInterpreterState_GET()); + } +#endif + _Py_SetImmortal(s); + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; +} + +void +PyUnicode_InternInPlace(PyObject **p) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyUnicode_InternInPlace(interp, p); } +// Function kept for the stable ABI. +PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); void PyUnicode_InternImmortal(PyObject **p) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_InternImmortal() is deprecated; " - "use PyUnicode_InternInPlace() instead", 1) < 0) - { - // The function has no return value, the exception cannot - // be reported to the caller, so just log it. - PyErr_WriteUnraisable(NULL); - } - PyUnicode_InternInPlace(p); - if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { - _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; - Py_INCREF(*p); - } + // Leak a reference on purpose + Py_INCREF(*p); } PyObject * @@ -15628,61 +14860,81 @@ PyUnicode_InternFromString(const char *cp) void _PyUnicode_ClearInterned(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - // interned dict is shared by all interpreters - return; - } - + PyObject *interned = get_interned_dict(interp); if (interned == NULL) { return; } assert(PyDict_CheckExact(interned)); - /* Interned unicode strings are not forcibly deallocated; rather, we give - them their stolen references back, and then clear and DECREF the - interned dict. */ - + /* TODO: + * Currently, the runtime is not able to guarantee that it can exit without + * allocations that carry over to a future initialization of Python within + * the same process. i.e: + * ./python -X showrefcount -c 'import itertools' + * [237 refs, 237 blocks] + * + * Therefore, this should remain disabled for until there is a strict guarantee + * that no memory will be left after `Py_Finalize`. + */ +#ifdef Py_DEBUG + /* For all non-singleton interned strings, restore the two valid references + to that instance from within the intern string dictionary and let the + normal reference counting process clean up these instances. */ #ifdef INTERNED_STATS fprintf(stderr, "releasing %zd interned strings\n", PyDict_GET_SIZE(interned)); - Py_ssize_t immortal_size = 0, mortal_size = 0; + Py_ssize_t total_length = 0; #endif Py_ssize_t pos = 0; PyObject *s, *ignored_value; while (PyDict_Next(interned, &pos, &s, &ignored_value)) { assert(PyUnicode_IS_READY(s)); - + int shared = 0; switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: - Py_SET_REFCNT(s, Py_REFCNT(s) + 1); -#ifdef INTERNED_STATS - immortal_size += PyUnicode_GET_LENGTH(s); -#endif - break; - case SSTATE_INTERNED_MORTAL: - // Restore the two references (key and value) ignored + // Skip the Immortal Instance check and restore + // the two references (key and value) ignored // by PyUnicode_InternInPlace(). - Py_SET_REFCNT(s, Py_REFCNT(s) + 2); + s->ob_refcnt = 2; #ifdef INTERNED_STATS - mortal_size += PyUnicode_GET_LENGTH(s); + total_length += PyUnicode_GET_LENGTH(s); #endif break; + case SSTATE_INTERNED_IMMORTAL_STATIC: + /* It is shared between interpreters, so we should unmark it + only when this is the last interpreter in which it's + interned. We immortalize all the statically initialized + strings during startup, so we can rely on the + main interpreter to be the last one. */ + if (!_Py_IsMainInterpreter(interp)) { + shared = 1; + } + break; + case SSTATE_INTERNED_MORTAL: + /* fall through */ case SSTATE_NOT_INTERNED: /* fall through */ default: Py_UNREACHABLE(); } - _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + if (!shared) { + _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + } } #ifdef INTERNED_STATS fprintf(stderr, - "total size of all interned strings: %zd/%zd mortal/immortal\n", - mortal_size, immortal_size); + "total length of all interned strings: %zd characters\n", + total_length); #endif - PyDict_Clear(interned); - Py_CLEAR(interned); + struct _Py_unicode_state *state = &interp->unicode; + struct _Py_unicode_ids *ids = &state->ids; + for (Py_ssize_t i=0; i < ids->size; i++) { + Py_XINCREF(ids->array[i]); + } +#endif /* Py_DEBUG */ + clear_interned_dict(interp); } @@ -15779,7 +15031,7 @@ unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) if (it->it_seq != NULL) { return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } else { - PyObject *u = (PyObject *)_PyUnicode_New(0); + PyObject *u = unicode_new_empty(); if (u == NULL) { Py_XDECREF(iter); return NULL; @@ -15873,8 +15125,6 @@ unicode_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(seq) == -1) - return NULL; if (PyUnicode_IS_COMPACT_ASCII(seq)) { it = PyObject_GC_New(unicodeiterobject, &_PyUnicodeASCIIIter_Type); } @@ -15884,8 +15134,7 @@ unicode_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -16012,10 +15261,13 @@ init_fs_codec(PyInterpreterState *interp) /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors global configuration variables. */ - if (_Py_SetFileSystemEncoding(fs_codec->encoding, - fs_codec->errors) < 0) { - PyErr_NoMemory(); - return -1; + if (_Py_IsMainInterpreter(interp)) { + + if (_Py_SetFileSystemEncoding(fs_codec->encoding, + fs_codec->errors) < 0) { + PyErr_NoMemory(); + return -1; + } } return 0; } @@ -16098,7 +15350,7 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) static inline int unicode_is_finalizing(void) { - return (interned == NULL); + return (get_interned_dict(_PyInterpreterState_Main()) == NULL); } #endif @@ -16106,42 +15358,9 @@ unicode_is_finalizing(void) void _PyUnicode_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - - _PyStaticType_Dealloc(&EncodingMapType); - _PyStaticType_Dealloc(&PyFieldNameIter_Type); - _PyStaticType_Dealloc(&PyFormatterIter_Type); -} - - -static void unicode_static_dealloc(PyObject *op) -{ - PyASCIIObject *ascii = _PyASCIIObject_CAST(op); - - assert(ascii->state.compact); - - if (ascii->state.ascii) { - if (ascii->wstr) { - PyObject_Free(ascii->wstr); - ascii->wstr = NULL; - } - } - else { - PyCompactUnicodeObject* compact = (PyCompactUnicodeObject*)op; - void* data = (void*)(compact + 1); - if (ascii->wstr && ascii->wstr != data) { - PyObject_Free(ascii->wstr); - ascii->wstr = NULL; - compact->wstr_length = 0; - } - if (compact->utf8) { - PyObject_Free(compact->utf8); - compact->utf8 = NULL; - compact->utf8_length = 0; - } - } + _PyStaticType_Dealloc(interp, &EncodingMapType); + _PyStaticType_Dealloc(interp, &PyFieldNameIter_Type); + _PyStaticType_Dealloc(interp, &PyFormatterIter_Type); } @@ -16150,35 +15369,18 @@ _PyUnicode_Fini(PyInterpreterState *interp) { struct _Py_unicode_state *state = &interp->unicode; - if (_Py_IsMainInterpreter(interp)) { - // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() - assert(interned == NULL); - // bpo-47182: force a unicodedata CAPI capsule re-import on - // subsequent initialization of main interpreter. - ucnhash_capi = NULL; - } + // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() + assert(get_interned_dict(interp) == NULL); _PyUnicode_FiniEncodings(&state->fs_codec); - unicode_clear_identifiers(state); - - // Clear the single character singletons - for (int i = 0; i < 128; i++) { - unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).ascii[i]); - } - for (int i = 0; i < 128; i++) { - unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).latin1[i]); - } -} - + // bpo-47182: force a unicodedata CAPI capsule re-import on + // subsequent initialization of interpreter. + interp->unicode.ucnhash_capi = NULL; -void -_PyStaticUnicode_Dealloc(PyObject *op) -{ - unicode_static_dealloc(op); + unicode_clear_identifiers(state); } - /* A _string module, to export formatter_parser and formatter_field_name_split to the string.Formatter class implemented in Python. */ @@ -16190,12 +15392,18 @@ static PyMethodDef _string_methods[] = { {NULL, NULL} }; +static PyModuleDef_Slot module_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + static struct PyModuleDef _string_module = { PyModuleDef_HEAD_INIT, .m_name = "_string", .m_doc = PyDoc_STR("string helper module"), .m_size = 0, .m_methods = _string_methods, + .m_slots = module_slots, }; PyMODINIT_FUNC diff --git a/contrib/tools/python3/src/Objects/unicodetype_db.h b/contrib/tools/python3/src/Objects/unicodetype_db.h index fb8bb9fc7ed..22f8243eaec 100644 --- a/contrib/tools/python3/src/Objects/unicodetype_db.h +++ b/contrib/tools/python3/src/Objects/unicodetype_db.h @@ -3,7 +3,6 @@ /* a list of unique character type descriptors */ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 32}, {0, 0, 0, 0, 0, 48}, {0, 0, 0, 0, 0, 1056}, @@ -1783,508 +1782,315 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 34, 34, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 143, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 143, 175, 176, 143, 177, 178, 179, 180, - 143, 181, 182, 183, 184, 185, 186, 143, 143, 187, 188, 189, 190, 143, - 191, 143, 192, 34, 34, 34, 34, 34, 34, 34, 193, 194, 34, 195, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 196, 34, 34, 34, 34, 34, 34, 34, 34, 197, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 34, 34, 34, 34, 198, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 34, 34, 34, 34, 199, 200, 201, 202, 143, 143, 143, 143, 203, - 204, 205, 206, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 125, 143, 144, 145, 146, 147, 148, 149, 34, 34, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 125, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 125, 174, 175, 125, 176, 177, 178, 179, + 125, 180, 181, 182, 183, 184, 185, 186, 125, 187, 188, 189, 190, 125, + 191, 192, 193, 34, 34, 34, 34, 34, 34, 34, 194, 195, 34, 196, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 197, 34, 34, 34, 34, 34, 34, 34, 34, 198, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 34, 34, 34, 34, 199, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 34, 34, 34, 34, 200, 201, 202, 203, 125, 125, 125, 125, 204, + 205, 206, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 208, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 209, 210, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 211, 34, 34, 212, 34, 34, 213, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 214, 215, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 216, 217, 64, 218, + 219, 220, 221, 222, 223, 125, 224, 225, 226, 227, 228, 229, 230, 231, 64, + 64, 64, 64, 232, 233, 125, 125, 125, 125, 125, 125, 125, 125, 234, 125, + 235, 236, 237, 125, 125, 238, 125, 125, 125, 239, 125, 125, 125, 125, + 125, 240, 34, 241, 242, 125, 125, 125, 125, 125, 243, 244, 245, 125, 246, + 247, 125, 125, 248, 249, 250, 251, 252, 125, 64, 253, 64, 64, 64, 64, 64, + 254, 255, 256, 257, 258, 64, 64, 259, 260, 64, 261, 125, 125, 125, 125, + 125, 125, 125, 125, 262, 263, 264, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 86, 265, 34, 266, 267, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 207, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 208, 209, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 210, 34, 34, 211, 34, 34, 212, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 213, 214, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 215, 216, 64, 217, - 218, 219, 220, 221, 222, 143, 223, 224, 225, 226, 227, 228, 229, 230, 64, - 64, 64, 64, 231, 232, 143, 143, 143, 143, 143, 143, 143, 143, 233, 143, - 234, 143, 235, 143, 143, 236, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 237, 34, 238, 239, 143, 143, 143, 143, 143, 240, 241, 242, 143, 243, - 244, 143, 143, 245, 246, 247, 248, 249, 143, 64, 250, 64, 64, 64, 64, 64, - 251, 252, 253, 254, 255, 64, 64, 256, 257, 64, 258, 143, 143, 143, 143, - 143, 143, 143, 143, 259, 260, 261, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 86, 262, 34, 263, 264, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 269, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 265, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 266, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 267, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 271, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 269, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 34, 274, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 271, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 275, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 276, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 34, 268, 34, 34, 277, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 34, 265, 34, 34, 274, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 278, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 275, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 276, 143, 277, 278, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 125, 125, 125, 125, 125, + 34, 34, 34, 34, 34, 34, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2321,7 +2127,6 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2357,1864 +2162,2079 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 279, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 280, 125, 281, 282, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, }; static const unsigned short index2[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 5, - 5, 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 6, 5, 20, 5, 5, - 21, 5, 6, 5, 5, 22, 23, 6, 24, 5, 25, 6, 26, 20, 5, 27, 27, 27, 5, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 28, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 19, 29, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 32, 33, 30, 31, 30, 31, 30, 31, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 35, 30, 31, 30, 31, 30, 31, 36, 37, 38, 30, 31, 30, 31, 39, - 30, 31, 40, 40, 30, 31, 20, 41, 42, 43, 30, 31, 40, 44, 45, 46, 47, 30, - 31, 48, 20, 46, 49, 50, 51, 30, 31, 30, 31, 30, 31, 52, 30, 31, 52, 20, - 20, 30, 31, 52, 30, 31, 53, 53, 30, 31, 30, 31, 54, 30, 31, 20, 55, 30, - 31, 20, 56, 55, 55, 55, 55, 57, 58, 59, 57, 58, 59, 57, 58, 59, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 60, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 61, 57, 58, - 59, 30, 31, 62, 63, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 20, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 20, 20, 20, 20, 65, - 30, 31, 66, 67, 68, 68, 30, 31, 69, 70, 71, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 80, 20, 20, - 20, 77, 81, 20, 82, 20, 83, 84, 20, 85, 86, 84, 87, 88, 20, 20, 86, 20, - 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 94, - 93, 20, 20, 20, 95, 93, 96, 97, 97, 98, 20, 20, 20, 20, 20, 99, 20, 55, - 20, 20, 20, 20, 20, 20, 20, 20, 100, 101, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 103, 103, 103, 103, 103, 103, 103, 102, 102, 6, 6, 6, 6, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 102, 102, 102, 102, 102, 6, 6, 6, 6, 6, 6, 6, - 103, 6, 103, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 104, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 30, 31, 30, 31, 103, 6, 30, 31, 0, 0, 105, 50, 50, 50, 5, 106, 0, - 0, 0, 0, 6, 6, 107, 25, 108, 108, 108, 0, 109, 0, 110, 110, 111, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 112, 113, 113, 113, 114, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 115, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 116, 117, 117, 118, 119, 120, 121, 121, 121, 122, 123, - 124, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 125, 126, 127, 128, 129, 130, 5, 30, 31, 131, - 30, 31, 20, 64, 64, 64, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 133, - 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 133, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 5, - 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 134, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 135, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 136, 136, 136, 136, 136, 136, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 2, 1, 3, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 4, 4, 4, 4, 5, 4, 19, 4, 4, + 20, 4, 5, 4, 4, 21, 22, 5, 23, 4, 24, 5, 25, 19, 4, 26, 26, 26, 4, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 16, 16, 16, 16, 16, 16, 16, 27, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 4, 18, 18, 18, 18, 18, 18, 18, 28, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 31, 32, 29, 30, 29, 30, 29, 30, 19, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 33, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 34, 29, 30, 29, 30, 29, 30, 35, 36, 37, 29, 30, 29, 30, 38, + 29, 30, 39, 39, 29, 30, 19, 40, 41, 42, 29, 30, 39, 43, 44, 45, 46, 29, + 30, 47, 19, 45, 48, 49, 50, 29, 30, 29, 30, 29, 30, 51, 29, 30, 51, 19, + 19, 29, 30, 51, 29, 30, 52, 52, 29, 30, 29, 30, 53, 29, 30, 19, 54, 29, + 30, 19, 55, 54, 54, 54, 54, 56, 57, 58, 56, 57, 58, 56, 57, 58, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 59, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 60, 56, 57, + 58, 29, 30, 61, 62, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 63, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 19, 19, 19, 19, 64, + 29, 30, 65, 66, 67, 67, 29, 30, 68, 69, 70, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 71, 72, 73, 74, 75, 19, 76, 76, 19, 77, 19, 78, 79, 19, 19, + 19, 76, 80, 19, 81, 19, 82, 83, 19, 84, 85, 83, 86, 87, 19, 19, 85, 19, + 88, 89, 19, 19, 90, 19, 19, 19, 19, 19, 19, 19, 91, 19, 19, 92, 19, 93, + 92, 19, 19, 19, 94, 92, 95, 96, 96, 97, 19, 19, 19, 19, 19, 98, 19, 54, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 100, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 102, 102, 102, 102, 102, 102, 102, 101, 101, 5, 5, 5, 5, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 5, + 102, 5, 102, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 103, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 29, 30, 29, 30, 102, 5, 29, 30, 0, 0, 104, 49, 49, 49, 4, 105, 0, + 0, 0, 0, 5, 5, 106, 24, 107, 107, 107, 0, 108, 0, 109, 109, 110, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 111, 112, 112, 112, 113, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 114, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 115, 116, 116, 117, 118, 119, 120, 120, 120, 121, 122, + 123, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 124, 125, 126, 127, 128, 129, 4, 29, 30, 130, + 29, 30, 19, 63, 63, 63, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 4, + 24, 24, 24, 24, 24, 5, 5, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 133, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 134, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 0, 0, 102, 4, 4, 4, 4, 4, 5, 19, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 0, 0, 103, 5, 5, 5, 5, 5, 6, 20, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 138, 20, 5, 5, 0, 0, 5, 5, 5, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, 5, 25, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, - 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 21, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, - 103, 103, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 103, 103, 5, 5, 5, 5, 103, 0, 0, 25, - 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 25, 25, 25, 103, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 103, 25, 25, 25, 103, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 0, 0, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 6, 55, 55, 55, 55, 55, 55, 0, 21, 21, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 18, 25, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 18, - 18, 25, 18, 18, 55, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, - 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 55, 0, 0, - 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 0, 0, 18, 18, 25, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 55, 55, 0, 55, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 5, 5, 27, 27, 27, 27, 27, - 27, 5, 5, 55, 5, 25, 0, 0, 25, 25, 18, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 0, 55, 55, 0, 0, 25, 0, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 25, 25, 0, 0, 25, 25, 25, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 0, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, - 25, 55, 55, 55, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, - 18, 18, 18, 25, 25, 25, 25, 25, 0, 25, 25, 18, 0, 18, 18, 25, 0, 0, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 25, 25, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, - 25, 25, 25, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, - 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 25, 25, 25, 25, 0, 0, 18, 18, - 0, 0, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 0, 0, 0, 55, 55, 0, - 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 55, 27, - 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 0, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 0, 55, 55, 0, - 55, 0, 55, 55, 0, 0, 0, 55, 55, 0, 0, 0, 55, 55, 55, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 18, 18, 25, 18, 18, 0, 0, - 0, 18, 18, 18, 0, 18, 18, 18, 25, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 25, 18, 18, 18, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, 0, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 5, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 25, 18, 18, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 18, 18, 18, 18, - 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, - 0, 0, 0, 55, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, 18, 18, 18, 25, - 55, 5, 0, 0, 0, 0, 55, 55, 55, 18, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 55, 55, 55, 55, 55, 0, 25, 18, 18, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 0, 0, 0, 0, 18, 18, 18, 25, - 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 18, 18, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 139, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 103, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 55, 139, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, 0, - 0, 55, 55, 55, 55, 55, 0, 103, 0, 25, 25, 25, 25, 25, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 136, 136, 136, 136, 136, 137, 19, 4, 4, 0, 0, 4, 4, 4, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 24, 4, 24, 24, 4, 24, 24, 4, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, + 54, 54, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 20, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 4, 4, 4, 4, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 4, 54, 24, 24, 24, 24, 24, 24, 24, 20, 4, 24, 24, 24, 24, 24, 24, + 102, 102, 24, 24, 4, 24, 24, 24, 24, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 4, 4, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 0, 20, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 102, 102, 4, 4, 4, 4, 102, 0, 0, 24, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 102, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 102, 24, 24, 24, 102, 24, 24, 24, 24, 24, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 0, 0, + 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 5, 54, 54, 54, 54, 54, 54, 0, 20, 20, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 24, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 24, 17, 17, 54, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, 0, 54, 54, 54, 54, 0, 0, 24, + 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, 17, 24, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 4, 4, 26, 26, 26, 26, 26, 26, 4, + 4, 54, 4, 24, 0, 0, 24, 24, 17, 0, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, + 54, 54, 0, 54, 54, 0, 0, 24, 0, 17, 17, 17, 24, 24, 0, 0, 0, 0, 24, 24, + 0, 0, 24, 24, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 54, + 54, 54, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 0, 24, 24, 17, 0, 17, 17, 24, 0, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 4, 4, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, + 24, 0, 24, 17, 17, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 0, 0, 24, 54, 17, 24, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, + 17, 24, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 54, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 0, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 0, 54, 54, 0, 54, 0, + 54, 54, 0, 0, 0, 54, 54, 0, 0, 0, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 17, 17, 24, 17, 17, 0, 0, 0, + 17, 17, 17, 0, 17, 17, 17, 24, 0, 0, 54, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, + 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 24, 17, 17, 17, 24, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 54, + 24, 24, 24, 17, 17, 17, 17, 0, 24, 24, 24, 0, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 24, 24, 0, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 4, 26, 26, 26, 26, + 26, 26, 26, 4, 54, 24, 17, 17, 4, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 24, 17, 17, 17, 17, 17, 0, + 24, 17, 17, 0, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, + 0, 0, 54, 54, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 0, 54, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 54, 17, 17, 17, 24, 24, 24, 24, 0, 17, 17, 17, 0, 17, 17, 17, 24, + 54, 4, 0, 0, 0, 0, 54, 54, 54, 17, 26, 26, 26, 26, 26, 26, 26, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 54, 54, 54, 54, 54, 54, 0, 24, 17, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 0, 0, 0, 0, 17, 17, 17, 24, 24, + 24, 0, 24, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 17, 17, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 54, 138, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 102, 24, 24, + 24, 24, 24, 24, 24, 24, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 25, 25, 5, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 25, 5, 25, 5, 25, 5, 5, 5, 5, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 5, 25, 25, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, - 18, 25, 25, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, - 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 55, 55, 55, 55, 25, 25, 25, 55, - 18, 18, 18, 55, 55, 18, 18, 18, 18, 18, 18, 18, 55, 55, 55, 25, 25, 25, - 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, - 25, 18, 18, 18, 18, 18, 18, 25, 55, 18, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 18, 18, 25, 5, 5, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 138, 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 0, 0, 54, 54, + 54, 54, 54, 0, 102, 0, 24, 24, 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 4, 4, + 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 24, 4, 24, 4, 24, 4, 4, 4, 4, 17, 17, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 17, 24, 24, 24, 24, 24, 4, 24, 24, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 24, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, + 24, 24, 24, 17, 24, 24, 24, 24, 24, 24, 17, 24, 24, 17, 17, 24, 24, 54, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 17, 17, 24, 24, 54, 54, 54, 54, 24, 24, 24, 54, 17, 17, 17, 54, 54, + 17, 17, 17, 17, 17, 17, 17, 54, 54, 54, 24, 24, 24, 24, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, 24, 17, 17, 17, 17, + 17, 17, 24, 54, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 24, + 4, 4, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 139, 0, 0, 0, + 0, 0, 139, 0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 0, 140, 0, 0, 0, 0, 0, 140, 0, 0, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 5, 103, 141, 141, 141, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 0, 237, 238, 239, 240, 241, - 242, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 5, 5, 243, 243, 243, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 5, 5, 5, 103, 5, 5, 5, 5, 55, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, - 25, 21, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 244, 244, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, - 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, 18, - 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 142, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 18, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 103, - 5, 5, 5, 5, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 140, 140, 140, 140, 4, 101, 140, 140, 140, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 24, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 141, 142, 143, 144, 145, 146, 147, 148, 149, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 0, 0, 236, 237, 238, 239, 240, 241, 0, 0, 4, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 1, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 242, 242, 242, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 24, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 17, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 102, 4, 4, 4, 4, 54, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 20, 24, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 243, 243, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 24, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 17, 17, 17, 17, 24, 24, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 24, 17, 17, 17, 17, 17, 17, 24, 24, 24, + 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 141, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 17, 17, 24, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 24, 17, 24, 24, 24, 24, 24, 24, 24, 0, + 24, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 4, 4, 4, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, - 18, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 25, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, - 18, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 18, 25, 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 103, 103, 103, 103, 103, 103, 5, 5, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 0, 0, 254, 254, 254, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 5, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, - 25, 55, 55, 55, 55, 55, 55, 25, 55, 55, 18, 25, 25, 55, 0, 0, 0, 0, 0, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 255, 20, 20, 20, 256, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 257, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 258, 259, 260, 261, 262, 263, 20, 20, 264, 20, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, - 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, 266, 266, 266, 266, - 266, 266, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, - 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 265, 265, 266, - 266, 266, 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, - 266, 266, 266, 266, 266, 266, 0, 0, 267, 265, 268, 265, 269, 265, 270, - 265, 0, 266, 0, 266, 0, 266, 0, 266, 265, 265, 265, 265, 265, 265, 265, - 265, 266, 266, 266, 266, 266, 266, 266, 266, 271, 271, 272, 272, 272, - 272, 273, 273, 274, 274, 275, 275, 276, 276, 0, 0, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 265, 265, 325, 326, 327, 0, 328, 329, 266, 266, 330, 330, 331, - 6, 332, 6, 6, 6, 333, 334, 335, 0, 336, 337, 338, 338, 338, 338, 339, 6, - 6, 6, 265, 265, 340, 341, 0, 0, 342, 343, 266, 266, 344, 344, 0, 6, 6, 6, - 265, 265, 345, 346, 347, 127, 348, 349, 266, 266, 350, 350, 131, 6, 6, 6, - 0, 0, 351, 352, 353, 0, 354, 355, 356, 356, 357, 357, 358, 6, 6, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, - 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 359, 102, - 0, 0, 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 102, 359, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 0, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 121, 5, 5, 5, 5, 121, 5, 5, 20, 121, 121, 121, 20, 20, 121, 121, - 121, 20, 5, 121, 5, 5, 366, 121, 121, 121, 121, 121, 5, 5, 5, 5, 5, 5, - 121, 5, 367, 5, 121, 5, 368, 369, 121, 121, 366, 20, 121, 121, 370, 121, - 20, 55, 55, 55, 55, 20, 5, 5, 20, 20, 121, 121, 5, 5, 5, 5, 5, 121, 20, - 20, 20, 20, 5, 5, 5, 5, 371, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 243, 243, 243, 30, 31, 243, 243, - 243, 243, 27, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, - 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 359, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, - 359, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, - 22, 23, 360, 361, 362, 363, 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, - 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 17, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, 24, 24, 24, 24, 17, 24, + 17, 17, 17, 17, 17, 24, 17, 17, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 17, 17, 24, 24, 17, 24, 24, 24, 54, 54, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, + 24, 17, 17, 17, 24, 17, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 17, 17, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 17, 24, 24, 0, 0, 0, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 102, 102, 102, 102, 102, 102, 4, 4, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 0, 0, 0, 0, 0, 0, 0, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 0, 0, + 253, 253, 253, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, + 24, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, + 24, 24, 24, 24, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 24, 54, + 54, 17, 24, 24, 54, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 254, 19, 19, 19, 255, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 256, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 257, 258, 259, 260, 261, 262, 19, + 19, 263, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 264, 264, 264, 264, 264, 264, 264, + 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, 264, 264, + 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 264, 264, 264, 264, 264, + 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, + 264, 264, 264, 264, 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 266, + 264, 267, 264, 268, 264, 269, 264, 0, 265, 0, 265, 0, 265, 0, 265, 264, + 264, 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, + 265, 270, 270, 271, 271, 271, 271, 272, 272, 273, 273, 274, 274, 275, + 275, 0, 0, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 264, 264, 324, 325, 326, 0, 327, + 328, 265, 265, 329, 329, 330, 5, 331, 5, 5, 5, 332, 333, 334, 0, 335, + 336, 337, 337, 337, 337, 338, 5, 5, 5, 264, 264, 339, 340, 0, 0, 341, + 342, 265, 265, 343, 343, 0, 5, 5, 5, 264, 264, 344, 345, 346, 126, 347, + 348, 265, 265, 349, 349, 130, 5, 5, 5, 0, 0, 350, 351, 352, 0, 353, 354, + 355, 355, 356, 356, 357, 5, 5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, + 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 5, 4, 4, 5, 2, 2, 20, 20, 20, 20, 20, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 20, 20, 20, 20, 20, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 358, 101, 0, 0, 359, 360, 361, 362, 363, + 364, 4, 4, 4, 4, 4, 101, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, + 4, 4, 4, 4, 4, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 5, 5, 5, 24, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 120, 4, 4, 4, 4, 120, 4, + 4, 19, 120, 120, 120, 19, 19, 120, 120, 120, 19, 4, 120, 4, 4, 365, 120, + 120, 120, 120, 120, 4, 4, 4, 4, 4, 4, 120, 4, 366, 4, 120, 4, 367, 368, + 120, 120, 365, 19, 120, 120, 369, 120, 19, 54, 54, 54, 54, 19, 4, 4, 19, + 19, 120, 120, 4, 4, 4, 4, 4, 120, 19, 19, 19, 19, 4, 4, 4, 4, 370, 4, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 242, 242, 242, 29, 30, 242, 242, 242, 242, 26, 4, 4, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 358, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, + 21, 22, 359, 360, 361, 362, 363, 364, 26, 358, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 25, 21, 22, 359, 360, 361, 362, + 363, 364, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 25, 21, 22, + 359, 360, 361, 362, 363, 364, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 30, 31, 376, - 377, 378, 379, 380, 30, 31, 30, 31, 30, 31, 381, 382, 383, 384, 20, 30, - 31, 20, 30, 31, 20, 20, 20, 20, 20, 102, 102, 385, 385, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 20, 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, 25, 25, 25, - 30, 31, 0, 0, 0, 0, 0, 5, 5, 5, 5, 27, 5, 5, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 0, 386, 0, 0, 0, 0, 0, 386, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 103, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 387, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 103, - 55, 243, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, 25, 25, - 18, 18, 5, 103, 103, 103, 103, 103, 5, 5, 243, 243, 243, 103, 55, 5, 5, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, - 6, 6, 103, 103, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 103, 103, 103, 55, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 5, 27, 27, 27, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 388, 55, 55, 388, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 388, 388, 388, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 388, 388, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 388, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 103, 103, 103, 103, 103, 103, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 5, 5, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 55, 25, 6, 6, 6, 5, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 103, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 102, 102, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 20, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 102, 20, 20, 20, 20, 20, 20, 20, - 20, 30, 31, 30, 31, 389, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 103, 6, - 6, 30, 31, 390, 20, 55, 30, 31, 30, 31, 391, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 392, 393, 394, - 395, 392, 20, 396, 397, 398, 399, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 400, 401, 402, 30, 31, 30, 31, 0, 0, 0, 0, 0, 30, - 31, 0, 20, 0, 20, 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 103, 30, 31, 55, 102, 102, 20, - 55, 55, 55, 55, 55, 55, 55, 25, 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 25, 18, 5, 5, 5, 5, 25, 0, 0, 0, 27, 27, 27, - 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 5, 55, 55, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, - 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 103, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, - 25, 25, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 25, 18, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, - 55, 55, 25, 25, 55, 55, 55, 55, 55, 25, 25, 55, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 103, 5, 5, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, - 103, 103, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 403, 20, 20, 20, 20, 20, 20, 20, 6, 102, 102, 102, 102, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 103, 6, 6, 0, 0, 0, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 18, 18, 25, 18, 18, 5, 18, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 136, 136, 136, 136, 136, 136, 136, 29, 30, 375, 376, 377, 378, 379, 29, + 30, 29, 30, 29, 30, 380, 381, 382, 383, 19, 29, 30, 19, 29, 30, 19, 19, + 19, 19, 19, 101, 101, 384, 384, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 19, 4, 4, 4, 4, 4, 4, 29, 30, 29, 30, 24, 24, 24, 29, 30, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 26, 4, 4, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 0, + 385, 0, 0, 0, 0, 0, 385, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 102, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 386, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 1, 4, 4, 4, 4, 102, 54, 242, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 24, 24, 17, 17, 4, 102, 102, 102, + 102, 102, 4, 4, 242, 242, 242, 102, 54, 4, 4, 4, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 5, 5, 102, 102, 54, 4, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 102, 102, 102, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 4, 4, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, + 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 387, 54, 54, 387, 54, 54, 54, 387, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 387, 387, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, + 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 387, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 102, 102, 102, 102, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 102, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 54, 24, 5, 5, 5, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 102, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 101, 101, 24, 24, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 101, 19, 19, 19, 19, 19, 19, 19, 19, 29, 30, 29, 30, 388, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 102, 5, 5, 29, 30, 389, 19, 54, 29, 30, 29, + 30, 390, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 391, 392, 393, 394, 391, 19, 395, 396, 397, 398, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 399, 400, + 401, 29, 30, 29, 30, 0, 0, 0, 0, 0, 29, 30, 0, 19, 0, 19, 29, 30, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, 485, 486, 487, 488, 489, - 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 492, 493, 494, 495, 0, 0, - 0, 0, 0, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 496, 496, 496, 496, 496, 496, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 496, 496, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 18, 5, 5, 6, 0, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 496, 55, 496, 55, 496, 0, - 496, 55, 496, 55, 496, 55, 496, 55, 496, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, - 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, - 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, + 101, 101, 101, 29, 30, 54, 101, 101, 19, 54, 54, 54, 54, 54, 54, 54, 24, + 54, 54, 54, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 24, + 17, 4, 4, 4, 4, 24, 0, 0, 0, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 4, 4, 4, 54, + 4, 54, 54, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, + 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, + 24, 24, 24, 17, 17, 24, 24, 17, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 102, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 54, + 54, 54, 54, 54, 24, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 17, 17, 24, 24, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 4, + 4, 4, 54, 17, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 24, 24, 24, 54, 54, 24, 24, 54, 54, 54, 54, 54, 24, 24, 54, + 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, + 24, 24, 17, 17, 4, 4, 54, 102, 102, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 497, 497, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 0, 0, 0, 5, 5, 5, 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, + 19, 19, 19, 19, 19, 19, 402, 19, 19, 19, 19, 19, 19, 19, 5, 101, 101, + 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 5, 5, 0, 0, 0, 0, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 17, 17, 24, 17, 17, + 4, 17, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 27, 27, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 243, 55, 55, 55, - 55, 55, 55, 55, 55, 243, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 243, 243, 243, 243, 243, 0, 0, 0, 0, + 0, 0, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 490, 491, 492, 493, 494, 0, 0, 0, 0, 0, 54, 24, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, + 495, 495, 495, 495, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, 495, + 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 17, 17, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 17, + 4, 4, 5, 0, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 4, 4, 4, 4, 0, 0, 0, 0, 495, 54, 495, 54, 495, 0, 495, 54, 495, 54, 495, + 54, 495, 54, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 20, 0, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 0, 0, 0, + 4, 4, 4, 5, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 20, 20, 4, 4, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 4, + 4, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 26, + 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 242, 54, 54, 54, 54, 54, 54, 54, 54, 242, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 242, 242, 242, + 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, - 0, 0, 0, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 500, 500, 500, 500, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, + 499, 499, 499, 499, 499, 499, 0, 499, 499, 0, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, - 500, 0, 500, 500, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 501, 0, 501, 501, 501, 501, 501, 501, 501, 0, 501, 501, 0, 0, 0, 0, + 0, 500, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 102, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 102, 103, 103, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, 0, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, + 26, 26, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 26, 26, 26, 26, + 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, + 0, 0, 0, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 26, 26, 54, 54, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 54, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, 0, 24, + 24, 24, 24, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 0, 0, 0, 0, 24, 25, 21, 22, 359, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 27, 27, 55, 55, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 25, 25, 25, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, - 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 0, 0, 0, 0, 25, 26, 22, 23, 360, 27, 27, 27, 27, 27, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 0, 0, 0, 0, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 27, 27, - 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 25, 25, 5, 0, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 4, 0, 0, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, 55, 55, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 5, 5, 21, 5, 5, - 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 55, 18, 18, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 18, 18, 55, 55, 55, 55, 5, 5, 5, 5, 25, 25, 25, 25, 5, - 18, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 5, 55, 5, 5, 5, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 55, 55, 55, 0, 25, 25, 55, 18, 18, 25, 18, 18, 18, 18, 0, - 0, 18, 18, 0, 0, 18, 18, 18, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 18, 18, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, - 25, 25, 25, 25, 25, 18, 18, 25, 25, 25, 18, 25, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 5, 25, 55, 55, 55, 0, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 26, 26, 26, 26, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 24, + 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 24, 54, 54, 24, 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 17, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 17, 17, 24, + 24, 4, 4, 20, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, + 54, 17, 17, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 4, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 54, 54, 54, 54, 4, 4, 4, + 4, 24, 24, 24, 24, 4, 17, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 4, + 54, 4, 4, 4, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, + 4, 4, 4, 24, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 25, 25, 18, 25, 25, - 55, 55, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 18, 18, 25, 25, - 18, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 18, 18, 25, 25, - 25, 25, 25, 25, 18, 25, 55, 5, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 4, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 24, 24, 54, 17, + 17, 24, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 54, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 17, 17, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 24, 24, 17, + 24, 54, 54, 54, 54, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, + 4, 0, 4, 24, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 17, 17, 17, + 17, 24, 24, 17, 24, 24, 54, 54, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, + 17, 17, 17, 17, 24, 24, 17, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 25, 25, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 54, 4, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 17, 17, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 4, 4, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 0, 18, - 18, 0, 0, 25, 25, 18, 25, 55, 18, 55, 18, 25, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, + 17, 17, 17, 0, 17, 17, 0, 0, 24, 24, 17, 24, 54, 17, 54, 17, 24, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 25, 25, 18, 18, 18, 18, - 25, 55, 5, 55, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, - 18, 18, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 5, 5, 55, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 25, 25, 25, - 0, 25, 25, 25, 25, 25, 25, 18, 25, 55, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 18, - 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 24, 24, + 17, 17, 17, 17, 24, 54, 4, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 17, 54, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, + 24, 24, 24, 17, 17, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, 4, 4, 4, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 0, 0, 0, 25, 0, 25, - 25, 0, 25, 25, 25, 25, 25, 25, 25, 55, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 18, 18, 0, 25, 25, 0, 18, 18, 25, 18, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 17, 24, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 17, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 0, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 0, 24, 24, 0, + 17, 17, 24, 17, 24, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 25, 18, 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 17, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 24, 24, 54, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 17, 17, 24, 24, 24, 24, 24, 0, 0, 0, 17, 17, 24, 17, 24, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 0, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 103, 103, - 103, 103, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 27, 27, 27, 27, 27, 27, 27, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 24, + 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, + 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 24, 24, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 102, 102, 102, 102, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 26, 26, 26, 26, 26, 26, 26, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 55, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 103, 103, 5, 103, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 24, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 4, 102, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 103, 103, 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, - 0, 103, 103, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 5, 25, 25, 5, - 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 0, 102, + 102, 102, 102, 102, 102, 102, 0, 102, 102, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 4, 24, 24, 4, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 25, 25, 25, 5, 5, 5, 18, 18, 18, 18, 18, 18, 21, 21, - 21, 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 24, 24, 24, 4, 4, 4, 17, 17, + 17, 17, 17, 17, 20, 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, + 24, 24, 4, 4, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, - 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 0, 121, 121, 0, 0, 121, 0, - 0, 121, 121, 0, 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 0, 20, 0, 20, 20, 20, 20, 20, 20, 20, 0, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 0, - 121, 121, 121, 121, 0, 0, 121, 121, 121, 121, 121, 121, 121, 121, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 0, 121, 0, 0, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, - 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 5, 20, 20, 20, 20, 20, 20, 121, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 120, 0, 120, 120, 0, 0, 120, 0, 0, 120, 120, 0, 0, 120, 120, 120, + 120, 0, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 0, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 0, 120, 120, 120, + 120, 120, 120, 120, 120, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 120, 120, + 120, 120, 120, 0, 120, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, + 19, 19, 120, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 4, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 55, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 54, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 0, 25, 25, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, + 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 103, 103, 103, 103, 103, 103, 103, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 0, 0, 55, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 54, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 25, 25, - 25, 25, 25, 25, 25, 103, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 5, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 24, 24, 24, 24, 24, 24, 24, 102, + 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 26, 26, 26, 4, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 359, 26, 22, 23, 360, 361, - 362, 363, 364, 365, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 0, + 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, + 54, 0, 54, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 54, 0, 54, 0, 54, 0, 54, 54, + 54, 0, 54, 54, 0, 54, 0, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 54, 0, + 54, 0, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 358, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, - 0, 0, 0, 0, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -4291,10 +4311,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C50: case 0x11D50: case 0x11DA0: + case 0x11F50: case 0x16A60: case 0x16AC0: case 0x16B50: case 0x16E80: + case 0x1D2C0: case 0x1D2E0: case 0x1D7CE: case 0x1D7D8: @@ -4303,6 +4325,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F6: case 0x1E140: case 0x1E2F0: + case 0x1E4F0: case 0x1E950: case 0x1F100: case 0x1F101: @@ -4420,6 +4443,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5A: case 0x11D51: case 0x11DA1: + case 0x11F51: case 0x12415: case 0x1241E: case 0x1242C: @@ -4431,6 +4455,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B51: case 0x16E81: case 0x16E94: + case 0x1D2C1: case 0x1D2E1: case 0x1D360: case 0x1D372: @@ -4442,6 +4467,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F7: case 0x1E141: case 0x1E2F1: + case 0x1E4F1: case 0x1E8C7: case 0x1E951: case 0x1EC71: @@ -4599,6 +4625,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C63: case 0x16B5B: case 0x16E8A: + case 0x1D2CA: case 0x1D2EA: case 0x1D369: case 0x1EC7A: @@ -4706,6 +4733,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2492: case 0x24EB: case 0x16E8B: + case 0x1D2CB: case 0x1D2EB: return (double) 11.0; case 0x109BC: @@ -4719,6 +4747,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2493: case 0x24EC: case 0x16E8C: + case 0x1D2CC: case 0x1D2EC: return (double) 12.0; case 0x246C: @@ -4726,6 +4755,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2494: case 0x24ED: case 0x16E8D: + case 0x1D2CD: case 0x1D2ED: return (double) 13.0; case 0x0F30: @@ -4735,6 +4765,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2495: case 0x24EE: case 0x16E8E: + case 0x1D2CE: case 0x1D2EE: return (double) 14.0; case 0x246E: @@ -4742,6 +4773,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2496: case 0x24EF: case 0x16E8F: + case 0x1D2CF: case 0x1D2EF: return (double) 15.0; case 0x0F31: @@ -4752,6 +4784,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2497: case 0x24F0: case 0x16E90: + case 0x1D2D0: case 0x1D2F0: return (double) 16.0; case 0x16EE: @@ -4760,6 +4793,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2498: case 0x24F1: case 0x16E91: + case 0x1D2D1: case 0x1D2F1: return (double) 17.0; case 0x0F32: @@ -4770,6 +4804,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2499: case 0x24F2: case 0x16E92: + case 0x1D2D2: case 0x1D2F2: return (double) 18.0; case 0x16F0: @@ -4778,6 +4813,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x249A: case 0x24F3: case 0x16E93: + case 0x1D2D3: case 0x1D2F3: return (double) 19.0; case 0x0032: @@ -4885,6 +4921,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5B: case 0x11D52: case 0x11DA2: + case 0x11F52: case 0x12400: case 0x12416: case 0x1241F: @@ -4900,6 +4937,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B52: case 0x16E82: case 0x16E95: + case 0x1D2C2: case 0x1D2E2: case 0x1D361: case 0x1D373: @@ -4910,6 +4948,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F8: case 0x1E142: case 0x1E2F2: + case 0x1E4F2: case 0x1E8C8: case 0x1E952: case 0x1EC72: @@ -5111,6 +5150,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5C: case 0x11D53: case 0x11DA3: + case 0x11F53: case 0x12401: case 0x12408: case 0x12417: @@ -5131,6 +5171,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B53: case 0x16E83: case 0x16E96: + case 0x1D2C3: case 0x1D2E3: case 0x1D362: case 0x1D374: @@ -5141,6 +5182,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F9: case 0x1E143: case 0x1E2F3: + case 0x1E4F3: case 0x1E8C9: case 0x1E953: case 0x1EC73: @@ -5334,6 +5376,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5D: case 0x11D54: case 0x11DA4: + case 0x11F54: case 0x12402: case 0x12409: case 0x1240F: @@ -5354,6 +5397,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC4: case 0x16B54: case 0x16E84: + case 0x1D2C4: case 0x1D2E4: case 0x1D363: case 0x1D375: @@ -5364,6 +5408,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FA: case 0x1E144: case 0x1E2F4: + case 0x1E4F4: case 0x1E8CA: case 0x1E954: case 0x1EC74: @@ -5533,6 +5578,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5E: case 0x11D55: case 0x11DA5: + case 0x11F55: case 0x12403: case 0x1240A: case 0x12410: @@ -5549,6 +5595,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC5: case 0x16B55: case 0x16E85: + case 0x1D2C5: case 0x1D2E5: case 0x1D364: case 0x1D376: @@ -5560,6 +5607,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FB: case 0x1E145: case 0x1E2F5: + case 0x1E4F5: case 0x1E8CB: case 0x1E955: case 0x1EC75: @@ -5729,6 +5777,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5F: case 0x11D56: case 0x11DA6: + case 0x11F56: case 0x12404: case 0x1240B: case 0x12411: @@ -5741,6 +5790,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC6: case 0x16B56: case 0x16E86: + case 0x1D2C6: case 0x1D2E6: case 0x1D365: case 0x1D7D4: @@ -5750,6 +5800,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FC: case 0x1E146: case 0x1E2F6: + case 0x1E4F6: case 0x1E8CC: case 0x1E956: case 0x1EC76: @@ -5878,6 +5929,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C60: case 0x11D57: case 0x11DA7: + case 0x11F57: case 0x12405: case 0x1240C: case 0x12412: @@ -5891,6 +5943,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC7: case 0x16B57: case 0x16E87: + case 0x1D2C7: case 0x1D2E7: case 0x1D366: case 0x1D7D5: @@ -5900,6 +5953,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FD: case 0x1E147: case 0x1E2F7: + case 0x1E4F7: case 0x1E8CD: case 0x1E957: case 0x1EC77: @@ -6029,6 +6083,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C61: case 0x11D58: case 0x11DA8: + case 0x11F58: case 0x12406: case 0x1240D: case 0x12413: @@ -6041,6 +6096,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC8: case 0x16B58: case 0x16E88: + case 0x1D2C8: case 0x1D2E8: case 0x1D367: case 0x1D7D6: @@ -6050,6 +6106,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FE: case 0x1E148: case 0x1E2F8: + case 0x1E4F8: case 0x1E8CE: case 0x1E958: case 0x1EC78: @@ -6174,6 +6231,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C62: case 0x11D59: case 0x11DA9: + case 0x11F59: case 0x12407: case 0x1240E: case 0x12414: @@ -6188,6 +6246,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC9: case 0x16B59: case 0x16E89: + case 0x1D2C9: case 0x1D2E9: case 0x1D368: case 0x1D7D7: @@ -6197,6 +6256,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FF: case 0x1E149: case 0x1E2F9: + case 0x1E4F9: case 0x1E8CF: case 0x1E959: case 0x1EC79: diff --git a/contrib/tools/python3/src/Objects/unionobject.c b/contrib/tools/python3/src/Objects/unionobject.c index 5eee27c08fa..f509a161bb9 100644 --- a/contrib/tools/python3/src/Objects/unionobject.c +++ b/contrib/tools/python3/src/Objects/unionobject.c @@ -1,6 +1,7 @@ // types.UnionType -- used to represent e.g. Union[int, str], int | str #include "Python.h" #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK +#include "pycore_typevarobject.h" // _PyTypeAlias_Type #include "pycore_unionobject.h" #include "structmember.h" @@ -114,12 +115,10 @@ merge(PyObject **items1, Py_ssize_t size1, } for (; pos < size1; pos++) { PyObject *a = items1[pos]; - Py_INCREF(a); - PyTuple_SET_ITEM(tuple, pos, a); + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(a)); } } - Py_INCREF(arg); - PyTuple_SET_ITEM(tuple, pos, arg); + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(arg)); pos++; } @@ -149,10 +148,14 @@ get_types(PyObject **obj, Py_ssize_t *size) static int is_unionable(PyObject *obj) { - return (obj == Py_None || + if (obj == Py_None || PyType_Check(obj) || _PyGenericAlias_Check(obj) || - _PyUnion_Check(obj)); + _PyUnion_Check(obj) || + Py_IS_TYPE(obj, &_PyTypeAlias_Type)) { + return 1; + } + return 0; } PyObject * @@ -170,8 +173,7 @@ _Py_union_type_or(PyObject* self, PyObject* other) if (PyErr_Occurred()) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyObject *new_union = make_union(tuple); @@ -298,8 +300,7 @@ union_getitem(PyObject *self, PyObject *item) res = make_union(newargs); } else { - res = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(res); + res = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); for (Py_ssize_t iarg = 1; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(newargs, iarg); Py_SETREF(res, PyNumber_Or(res, arg)); @@ -326,8 +327,7 @@ union_parameters(PyObject *self, void *Py_UNUSED(unused)) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); } static PyGetSetDef union_properties[] = { @@ -400,9 +400,8 @@ make_union(PyObject *args) return NULL; } - Py_INCREF(args); result->parameters = NULL; - result->args = args; + result->args = Py_NewRef(args); _PyObject_GC_TRACK(result); return (PyObject*)result; } diff --git a/contrib/tools/python3/src/Objects/weakrefobject.c b/contrib/tools/python3/src/Objects/weakrefobject.c index c76c92843cb..aee79fc1410 100644 --- a/contrib/tools/python3/src/Objects/weakrefobject.c +++ b/contrib/tools/python3/src/Objects/weakrefobject.c @@ -308,8 +308,7 @@ weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (callback == NULL && type == &_PyWeakref_RefType) { if (ref != NULL) { /* We can re-use an existing reference. */ - Py_INCREF(ref); - return (PyObject *)ref; + return Py_NewRef(ref); } } /* We have to create a new reference. */ @@ -822,9 +821,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - Py_INCREF(ref); - result = ref; + Py_SETREF(result, (PyWeakReference*)Py_NewRef(ref)); } } else { @@ -887,9 +884,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - result = proxy; - Py_INCREF(result); + Py_SETREF(result, (PyWeakReference*)Py_NewRef(proxy)); goto skip_insert; } prev = ref; @@ -961,9 +956,8 @@ PyObject_ClearWeakRefs(PyObject *object) if (*list != NULL) { PyWeakReference *current = *list; Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); - PyObject *err_type, *err_value, *err_tb; + PyObject *exc = PyErr_GetRaisedException(); - PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; @@ -982,7 +976,7 @@ PyObject_ClearWeakRefs(PyObject *object) tuple = PyTuple_New(count * 2); if (tuple == NULL) { - _PyErr_ChainExceptions(err_type, err_value, err_tb); + _PyErr_ChainExceptions1(exc); return; } @@ -990,8 +984,7 @@ PyObject_ClearWeakRefs(PyObject *object) PyWeakReference *next = current->wr_next; if (Py_REFCNT((PyObject *)current) > 0) { - Py_INCREF(current); - PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); + PyTuple_SET_ITEM(tuple, i * 2, Py_NewRef(current)); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); } else { @@ -1013,6 +1006,25 @@ PyObject_ClearWeakRefs(PyObject *object) Py_DECREF(tuple); } assert(!PyErr_Occurred()); - PyErr_Restore(err_type, err_value, err_tb); + PyErr_SetRaisedException(exc); + } +} + +/* This function is called by _PyStaticType_Dealloc() to clear weak references. + * + * This is called at the end of runtime finalization, so we can just + * wipe out the type's weaklist. We don't bother with callbacks + * or anything else. + */ +void +_PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type) +{ + static_builtin_state *state = _PyStaticType_GetState(interp, type); + PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state); + while (*list != NULL) { + /* Note that clear_weakref() pops the first ref off the type's + weaklist before clearing its wr_object and wr_callback. + That is how we're able to loop over the list. */ + clear_weakref((PyWeakReference *)*list); } } |
