summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects
diff options
context:
space:
mode:
authorAlexSm <[email protected]>2024-02-16 11:51:30 +0100
committerGitHub <[email protected]>2024-02-16 11:51:30 +0100
commit506ecaee93b52cc12c2e2f97c3d42e3ca2a7f59e (patch)
treed096fb9eb988fbb0ca1ba970041773207ce3aa70 /contrib/tools/python3/src/Objects
parent4749b9e5d260714490997e6f5ee1ee8c1c8fc46c (diff)
parentf200f72c9d7a89c1018e3dc6b46c49fe2ecf84fb (diff)
Merge pull request #1940 from dcherednik/importlib
Library import 14
Diffstat (limited to 'contrib/tools/python3/src/Objects')
-rw-r--r--contrib/tools/python3/src/Objects/abstract.c43
-rw-r--r--contrib/tools/python3/src/Objects/accu.c115
-rw-r--r--contrib/tools/python3/src/Objects/boolobject.c56
-rw-r--r--contrib/tools/python3/src/Objects/bytearrayobject.c25
-rw-r--r--contrib/tools/python3/src/Objects/bytes_methods.c12
-rw-r--r--contrib/tools/python3/src/Objects/bytesobject.c93
-rw-r--r--contrib/tools/python3/src/Objects/call.c103
-rw-r--r--contrib/tools/python3/src/Objects/capsule.c3
-rw-r--r--contrib/tools/python3/src/Objects/cellobject.c23
-rw-r--r--contrib/tools/python3/src/Objects/classobject.c36
-rw-r--r--contrib/tools/python3/src/Objects/clinic/bytearrayobject.c.h187
-rw-r--r--contrib/tools/python3/src/Objects/clinic/bytesobject.c.h187
-rw-r--r--contrib/tools/python3/src/Objects/clinic/classobject.c.h16
-rw-r--r--contrib/tools/python3/src/Objects/clinic/codeobject.c.h62
-rw-r--r--contrib/tools/python3/src/Objects/clinic/complexobject.c.h33
-rw-r--r--contrib/tools/python3/src/Objects/clinic/descrobject.c.h58
-rw-r--r--contrib/tools/python3/src/Objects/clinic/dictobject.c.h8
-rw-r--r--contrib/tools/python3/src/Objects/clinic/enumobject.c.h37
-rw-r--r--contrib/tools/python3/src/Objects/clinic/floatobject.c.h20
-rw-r--r--contrib/tools/python3/src/Objects/clinic/funcobject.c.h33
-rw-r--r--contrib/tools/python3/src/Objects/clinic/listobject.c.h42
-rw-r--r--contrib/tools/python3/src/Objects/clinic/longobject.c.h109
-rw-r--r--contrib/tools/python3/src/Objects/clinic/memoryobject.c.h168
-rw-r--r--contrib/tools/python3/src/Objects/clinic/moduleobject.c.h33
-rw-r--r--contrib/tools/python3/src/Objects/clinic/odictobject.c.h133
-rw-r--r--contrib/tools/python3/src/Objects/clinic/structseq.c.h33
-rw-r--r--contrib/tools/python3/src/Objects/clinic/tupleobject.c.h12
-rw-r--r--contrib/tools/python3/src/Objects/clinic/typeobject.c.h12
-rw-r--r--contrib/tools/python3/src/Objects/clinic/typevarobject.c.h786
-rw-r--r--contrib/tools/python3/src/Objects/clinic/unicodeobject.c.h162
-rw-r--r--contrib/tools/python3/src/Objects/codeobject.c651
-rw-r--r--contrib/tools/python3/src/Objects/complexobject.c15
-rw-r--r--contrib/tools/python3/src/Objects/descrobject.c150
-rw-r--r--contrib/tools/python3/src/Objects/dictobject.c820
-rw-r--r--contrib/tools/python3/src/Objects/enumobject.c3
-rw-r--r--contrib/tools/python3/src/Objects/exceptions.c456
-rw-r--r--contrib/tools/python3/src/Objects/fileobject.c35
-rw-r--r--contrib/tools/python3/src/Objects/floatobject.c96
-rw-r--r--contrib/tools/python3/src/Objects/frameobject.c615
-rw-r--r--contrib/tools/python3/src/Objects/funcobject.c278
-rw-r--r--contrib/tools/python3/src/Objects/genericaliasobject.c62
-rw-r--r--contrib/tools/python3/src/Objects/genobject.c377
-rw-r--r--contrib/tools/python3/src/Objects/interpreteridobject.c2
-rw-r--r--contrib/tools/python3/src/Objects/iterobject.c24
-rw-r--r--contrib/tools/python3/src/Objects/listobject.c260
-rw-r--r--contrib/tools/python3/src/Objects/longobject.c1867
-rw-r--r--contrib/tools/python3/src/Objects/memoryobject.c166
-rw-r--r--contrib/tools/python3/src/Objects/methodobject.c15
-rw-r--r--contrib/tools/python3/src/Objects/moduleobject.c200
-rw-r--r--contrib/tools/python3/src/Objects/namespaceobject.c5
-rw-r--r--contrib/tools/python3/src/Objects/object.c749
-rw-r--r--contrib/tools/python3/src/Objects/obmalloc.c1465
-rw-r--r--contrib/tools/python3/src/Objects/odictobject.c86
-rw-r--r--contrib/tools/python3/src/Objects/rangeobject.c211
-rw-r--r--contrib/tools/python3/src/Objects/setobject.c66
-rw-r--r--contrib/tools/python3/src/Objects/sliceobject.c152
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/asciilib.h1
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/clinic/transmogrify.h.h33
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/count.h7
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/eq.h10
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/fastsearch.h41
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/join.h3
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/localeutil.h2
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/replace.h4
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/stringdefs.h1
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/transmogrify.h3
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/ucs1lib.h1
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/ucs2lib.h4
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/ucs4lib.h4
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/undef.h1
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/unicode_format.h15
-rw-r--r--contrib/tools/python3/src/Objects/stringlib/unicodedefs.h32
-rw-r--r--contrib/tools/python3/src/Objects/structseq.c195
-rw-r--r--contrib/tools/python3/src/Objects/tupleobject.c138
-rw-r--r--contrib/tools/python3/src/Objects/typeobject.c3116
-rw-r--r--contrib/tools/python3/src/Objects/typevarobject.c1691
-rw-r--r--contrib/tools/python3/src/Objects/unicodeobject.c2196
-rw-r--r--contrib/tools/python3/src/Objects/unicodetype_db.h4468
-rw-r--r--contrib/tools/python3/src/Objects/unionobject.c27
-rw-r--r--contrib/tools/python3/src/Objects/weakrefobject.c40
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);
}
}