avoid PyMethodObject in slots

main change in python/cpython@516b98161a
test_exceptions changed in python/cpython@331bbe6aaa
type_settattro changed in python/cpython@193f7e094f
_PyObject_CallFunctionVa changed in python/cpython@fe4ff83049
This commit is contained in:
ahgamut 2021-11-09 02:56:47 +05:30
parent 7f4de20c0b
commit 9aac17ff54
5 changed files with 347 additions and 250 deletions

View file

@ -42,6 +42,14 @@ PyObject *_PyObject_FastCallKeywords(PyObject *func, PyObject **args,
PyObject *_PyObject_Call_Prepend(PyObject *func, PyObject *obj, PyObject *args,
PyObject *kwargs);
#define _PY_FASTCALL_SMALL_STACK 5
PyObject *_PyObject_FastCall_Prepend(
PyObject *callable,
PyObject *obj,
PyObject **args,
Py_ssize_t nargs);
#if IsModeDbg()
PyObject *_Py_CheckFunctionResult(PyObject *func, PyObject *result,
const char *where);

View file

@ -1162,27 +1162,20 @@ class ExceptionTests(unittest.TestCase):
# The following line is included in the traceback report:
raise exc
class BrokenRepr(BrokenDel):
def __repr__(self):
raise AttributeError("repr() is broken")
class BrokenExceptionDel:
def __del__(self):
exc = BrokenStrException()
# The following line is included in the traceback report:
raise exc
for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel):
for test_class in (BrokenDel, BrokenExceptionDel):
with self.subTest(test_class):
obj = test_class()
with captured_stderr() as stderr:
del obj
report = stderr.getvalue()
self.assertIn("Exception ignored", report)
if test_class is BrokenRepr:
self.assertIn("<object repr() failed>", report)
else:
self.assertIn(test_class.__del__.__qualname__, report)
self.assertIn(test_class.__del__.__qualname__, report)
self.assertIn("test_exceptions.py", report)
self.assertIn("raise exc", report)
if test_class is BrokenExceptionDel:

View file

@ -2389,10 +2389,44 @@ _PyObject_FastCallDict(PyObject *callable, PyObject **args, Py_ssize_t nargs,
/* Positional arguments are obj followed by args:
call callable(obj, *args, **kwargs) */
PyObject *
_PyObject_FastCall_Prepend(PyObject *callable,
PyObject *obj, PyObject **args, Py_ssize_t nargs)
{
PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
PyObject **args2;
PyObject *result;
nargs++;
if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
args2 = small_stack;
}
else {
args2 = PyMem_Malloc(nargs * sizeof(PyObject *));
if (args2 == NULL) {
PyErr_NoMemory();
return NULL;
}
}
/* use borrowed references */
args2[0] = obj;
memcpy(&args2[1],
args,
(nargs - 1)* sizeof(PyObject *));
result = _PyObject_FastCall(callable, args2, nargs);
if (args2 != small_stack) {
PyMem_Free(args2);
}
return result;
}
/* Call callable(obj, *args, **kwargs). */
PyObject *
_PyObject_Call_Prepend(PyObject *callable,
PyObject *obj, PyObject *args, PyObject *kwargs)
{
PyObject *small_stack[5];
PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
PyObject **stack;
Py_ssize_t argcount;
PyObject *result;
@ -2600,10 +2634,10 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format,
}
if (is_size_t) {
stack = _Py_VaBuildStack(small_stack, small_stack_len, format, va, &nargs);
stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, format, va, &nargs);
}
else {
stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, format, va, &nargs);
stack = _Py_VaBuildStack(small_stack, small_stack_len, format, va, &nargs);
}
if (stack == NULL) {
return NULL;

View file

@ -1255,6 +1255,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
return res;
}
int
PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
{

File diff suppressed because it is too large Load diff