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 *_PyObject_Call_Prepend(PyObject *func, PyObject *obj, PyObject *args,
PyObject *kwargs); PyObject *kwargs);
#define _PY_FASTCALL_SMALL_STACK 5
PyObject *_PyObject_FastCall_Prepend(
PyObject *callable,
PyObject *obj,
PyObject **args,
Py_ssize_t nargs);
#if IsModeDbg() #if IsModeDbg()
PyObject *_Py_CheckFunctionResult(PyObject *func, PyObject *result, PyObject *_Py_CheckFunctionResult(PyObject *func, PyObject *result,
const char *where); const char *where);

View file

@ -1162,27 +1162,20 @@ class ExceptionTests(unittest.TestCase):
# The following line is included in the traceback report: # The following line is included in the traceback report:
raise exc raise exc
class BrokenRepr(BrokenDel):
def __repr__(self):
raise AttributeError("repr() is broken")
class BrokenExceptionDel: class BrokenExceptionDel:
def __del__(self): def __del__(self):
exc = BrokenStrException() exc = BrokenStrException()
# The following line is included in the traceback report: # The following line is included in the traceback report:
raise exc raise exc
for test_class in (BrokenDel, BrokenRepr, BrokenExceptionDel): for test_class in (BrokenDel, BrokenExceptionDel):
with self.subTest(test_class): with self.subTest(test_class):
obj = test_class() obj = test_class()
with captured_stderr() as stderr: with captured_stderr() as stderr:
del obj del obj
report = stderr.getvalue() report = stderr.getvalue()
self.assertIn("Exception ignored", report) self.assertIn("Exception ignored", report)
if test_class is BrokenRepr: self.assertIn(test_class.__del__.__qualname__, report)
self.assertIn("<object repr() failed>", report)
else:
self.assertIn(test_class.__del__.__qualname__, report)
self.assertIn("test_exceptions.py", report) self.assertIn("test_exceptions.py", report)
self.assertIn("raise exc", report) self.assertIn("raise exc", report)
if test_class is BrokenExceptionDel: 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: /* Positional arguments are obj followed by args:
call callable(obj, *args, **kwargs) */ call callable(obj, *args, **kwargs) */
PyObject * 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_Call_Prepend(PyObject *callable,
PyObject *obj, PyObject *args, PyObject *kwargs) PyObject *obj, PyObject *args, PyObject *kwargs)
{ {
PyObject *small_stack[5]; PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
PyObject **stack; PyObject **stack;
Py_ssize_t argcount; Py_ssize_t argcount;
PyObject *result; PyObject *result;
@ -2600,10 +2634,10 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format,
} }
if (is_size_t) { 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 { 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) { if (stack == NULL) {
return NULL; return NULL;

View file

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

File diff suppressed because it is too large Load diff