Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(119)

Side by Side Diff: Objects/descrobject.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Patch Set: Created 2 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Descriptors -- a new, flexible way to describe attributes */ 1 /* Descriptors -- a new, flexible way to describe attributes */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "structmember.h" /* Why is this not included in Python.h? */ 4 #include "structmember.h" /* Why is this not included in Python.h? */
5 5
6 static void 6 static void
7 descr_dealloc(PyDescrObject *descr) 7 descr_dealloc(PyDescrObject *descr)
8 { 8 {
9 _PyObject_GC_UNTRACK(descr); 9 _PyObject_GC_UNTRACK(descr);
10 Py_XDECREF(descr->d_type); 10 Py_XDECREF(descr->d_type);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 return descr->d_getset->set(obj, value, 203 return descr->d_getset->set(obj, value,
204 descr->d_getset->closure); 204 descr->d_getset->closure);
205 PyErr_Format(PyExc_AttributeError, 205 PyErr_Format(PyExc_AttributeError,
206 "attribute '%V' of '%.100s' objects is not writable", 206 "attribute '%V' of '%.100s' objects is not writable",
207 descr_name((PyDescrObject *)descr), "?", 207 descr_name((PyDescrObject *)descr), "?",
208 PyDescr_TYPE(descr)->tp_name); 208 PyDescr_TYPE(descr)->tp_name);
209 return -1; 209 return -1;
210 } 210 }
211 211
212 static PyObject * 212 static PyObject *
213 methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) 213 methoddescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
214 PyObject *kwnames)
214 { 215 {
215 Py_ssize_t nargs;
216 PyObject *self, *result; 216 PyObject *self, *result;
217 217
218 /* Make sure that the first argument is acceptable as 'self' */ 218 /* Make sure that the first argument is acceptable as 'self' */
219 assert(PyTuple_Check(args));
220 nargs = PyTuple_GET_SIZE(args);
221 if (nargs < 1) { 219 if (nargs < 1) {
222 PyErr_Format(PyExc_TypeError, 220 PyErr_Format(PyExc_TypeError,
223 "descriptor '%V' of '%.100s' " 221 "descriptor '%V' of '%.100s' "
224 "object needs an argument", 222 "object needs an argument",
225 descr_name((PyDescrObject *)descr), "?", 223 descr_name((PyDescrObject *)descr), "?",
226 PyDescr_TYPE(descr)->tp_name); 224 PyDescr_TYPE(descr)->tp_name);
227 return NULL; 225 return NULL;
228 } 226 }
229 self = PyTuple_GET_ITEM(args, 0); 227 self = args[0];
230 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 228 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
231 (PyObject *)PyDescr_TYPE(descr))) { 229 (PyObject *)PyDescr_TYPE(descr))) {
232 PyErr_Format(PyExc_TypeError, 230 PyErr_Format(PyExc_TypeError,
233 "descriptor '%V' " 231 "descriptor '%V' "
234 "requires a '%.100s' object " 232 "requires a '%.100s' object "
235 "but received a '%.100s'", 233 "but received a '%.100s'",
236 descr_name((PyDescrObject *)descr), "?", 234 descr_name((PyDescrObject *)descr), "?",
237 PyDescr_TYPE(descr)->tp_name, 235 PyDescr_TYPE(descr)->tp_name,
238 self->ob_type->tp_name); 236 self->ob_type->tp_name);
239 return NULL; 237 return NULL;
240 } 238 }
241 239
242 result = _PyMethodDef_RawFastCallDict(descr->d_method, self, 240 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self,
243 &PyTuple_GET_ITEM(args, 1), nargs - 1, 241 args + 1, nargs - 1,
244 kwargs); 242 kwnames);
245 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); 243 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
246 return result; 244 return result;
247 } 245 }
248 246
249 static PyObject * 247 static PyObject *
250 classmethoddescr_call(PyMethodDescrObject *descr, PyObject *args, 248 classmethoddescr_call(PyMethodDescrObject *descr, PyObject **args,
251 PyObject *kwds) 249 Py_ssize_t nargs, PyObject *kwnames)
252 { 250 {
253 Py_ssize_t argc; 251 PyObject *self, *func, *result;
254 PyObject *self, *func, *result, **stack;
255 252
256 /* Make sure that the first argument is acceptable as 'self' */ 253 /* Make sure that the first argument is acceptable as 'self' */
257 assert(PyTuple_Check(args)); 254 if (nargs < 1) {
258 argc = PyTuple_GET_SIZE(args);
259 if (argc < 1) {
260 PyErr_Format(PyExc_TypeError, 255 PyErr_Format(PyExc_TypeError,
261 "descriptor '%V' of '%.100s' " 256 "descriptor '%V' of '%.100s' "
262 "object needs an argument", 257 "object needs an argument",
263 descr_name((PyDescrObject *)descr), "?", 258 descr_name((PyDescrObject *)descr), "?",
264 PyDescr_TYPE(descr)->tp_name); 259 PyDescr_TYPE(descr)->tp_name);
265 return NULL; 260 return NULL;
266 } 261 }
267 self = PyTuple_GET_ITEM(args, 0); 262 self = args[0];
268 if (!PyType_Check(self)) { 263 if (!PyType_Check(self)) {
269 PyErr_Format(PyExc_TypeError, 264 PyErr_Format(PyExc_TypeError,
270 "descriptor '%V' requires a type " 265 "descriptor '%V' requires a type "
271 "but received a '%.100s'", 266 "but received a '%.100s'",
272 descr_name((PyDescrObject *)descr), "?", 267 descr_name((PyDescrObject *)descr), "?",
273 PyDescr_TYPE(descr)->tp_name, 268 PyDescr_TYPE(descr)->tp_name,
274 self->ob_type->tp_name); 269 self->ob_type->tp_name);
275 return NULL; 270 return NULL;
276 } 271 }
277 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { 272 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
278 PyErr_Format(PyExc_TypeError, 273 PyErr_Format(PyExc_TypeError,
279 "descriptor '%V' " 274 "descriptor '%V' "
280 "requires a subtype of '%.100s' " 275 "requires a subtype of '%.100s' "
281 "but received '%.100s", 276 "but received '%.100s",
282 descr_name((PyDescrObject *)descr), "?", 277 descr_name((PyDescrObject *)descr), "?",
283 PyDescr_TYPE(descr)->tp_name, 278 PyDescr_TYPE(descr)->tp_name,
284 self->ob_type->tp_name); 279 self->ob_type->tp_name);
285 return NULL; 280 return NULL;
286 } 281 }
287 282
288 func = PyCFunction_NewEx(descr->d_method, self, NULL); 283 func = PyCFunction_NewEx(descr->d_method, self, NULL);
289 if (func == NULL) 284 if (func == NULL)
290 return NULL; 285 return NULL;
291 stack = &PyTuple_GET_ITEM(args, 1); 286 result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
292 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
293 Py_DECREF(func); 287 Py_DECREF(func);
294 return result; 288 return result;
295 } 289 }
296 290
297 static PyObject * 291 static PyObject *
298 wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) 292 wrapperdescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
293 PyObject *kwnames)
299 { 294 {
300 Py_ssize_t argc; 295 PyObject *self, *func, *result;
301 PyObject *self, *func, *result, **stack;
302 296
303 /* Make sure that the first argument is acceptable as 'self' */ 297 /* Make sure that the first argument is acceptable as 'self' */
304 assert(PyTuple_Check(args)); 298 if (nargs < 1) {
305 argc = PyTuple_GET_SIZE(args);
306 if (argc < 1) {
307 PyErr_Format(PyExc_TypeError, 299 PyErr_Format(PyExc_TypeError,
308 "descriptor '%V' of '%.100s' " 300 "descriptor '%V' of '%.100s' "
309 "object needs an argument", 301 "object needs an argument",
310 descr_name((PyDescrObject *)descr), "?", 302 descr_name((PyDescrObject *)descr), "?",
311 PyDescr_TYPE(descr)->tp_name); 303 PyDescr_TYPE(descr)->tp_name);
312 return NULL; 304 return NULL;
313 } 305 }
314 self = PyTuple_GET_ITEM(args, 0); 306 self = args[0];
315 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 307 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
316 (PyObject *)PyDescr_TYPE(descr))) { 308 (PyObject *)PyDescr_TYPE(descr))) {
317 PyErr_Format(PyExc_TypeError, 309 PyErr_Format(PyExc_TypeError,
318 "descriptor '%V' " 310 "descriptor '%V' "
319 "requires a '%.100s' object " 311 "requires a '%.100s' object "
320 "but received a '%.100s'", 312 "but received a '%.100s'",
321 descr_name((PyDescrObject *)descr), "?", 313 descr_name((PyDescrObject *)descr), "?",
322 PyDescr_TYPE(descr)->tp_name, 314 PyDescr_TYPE(descr)->tp_name,
323 self->ob_type->tp_name); 315 self->ob_type->tp_name);
324 return NULL; 316 return NULL;
325 } 317 }
326 318
327 func = PyWrapper_New((PyObject *)descr, self); 319 func = PyWrapper_New((PyObject *)descr, self);
328 if (func == NULL) 320 if (func == NULL)
329 return NULL; 321 return NULL;
330 322
331 stack = &PyTuple_GET_ITEM(args, 1); 323 result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
332 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
333 Py_DECREF(func); 324 Py_DECREF(func);
334 return result; 325 return result;
335 } 326 }
336 327
337 static PyObject * 328 static PyObject *
338 method_get_doc(PyMethodDescrObject *descr, void *closure) 329 method_get_doc(PyMethodDescrObject *descr, void *closure)
339 { 330 {
340 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_meth od->ml_doc); 331 return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_meth od->ml_doc);
341 } 332 }
342 333
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 (destructor)descr_dealloc, /* tp_dealloc */ 471 (destructor)descr_dealloc, /* tp_dealloc */
481 0, /* tp_print */ 472 0, /* tp_print */
482 0, /* tp_getattr */ 473 0, /* tp_getattr */
483 0, /* tp_setattr */ 474 0, /* tp_setattr */
484 0, /* tp_reserved */ 475 0, /* tp_reserved */
485 (reprfunc)method_repr, /* tp_repr */ 476 (reprfunc)method_repr, /* tp_repr */
486 0, /* tp_as_number */ 477 0, /* tp_as_number */
487 0, /* tp_as_sequence */ 478 0, /* tp_as_sequence */
488 0, /* tp_as_mapping */ 479 0, /* tp_as_mapping */
489 0, /* tp_hash */ 480 0, /* tp_hash */
490 (ternaryfunc)methoddescr_call, /* tp_call */ 481 0, /* tp_call */
491 0, /* tp_str */ 482 0, /* tp_str */
492 PyObject_GenericGetAttr, /* tp_getattro */ 483 PyObject_GenericGetAttr, /* tp_getattro */
493 0, /* tp_setattro */ 484 0, /* tp_setattro */
494 0, /* tp_as_buffer */ 485 0, /* tp_as_buffer */
495 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 486 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
496 0, /* tp_doc */ 487 0, /* tp_doc */
497 descr_traverse, /* tp_traverse */ 488 descr_traverse, /* tp_traverse */
498 0, /* tp_clear */ 489 0, /* tp_clear */
499 0, /* tp_richcompare */ 490 0, /* tp_richcompare */
500 0, /* tp_weaklistoffset */ 491 0, /* tp_weaklistoffset */
501 0, /* tp_iter */ 492 0, /* tp_iter */
502 0, /* tp_iternext */ 493 0, /* tp_iternext */
503 descr_methods, /* tp_methods */ 494 descr_methods, /* tp_methods */
504 descr_members, /* tp_members */ 495 descr_members, /* tp_members */
505 method_getset, /* tp_getset */ 496 method_getset, /* tp_getset */
506 0, /* tp_base */ 497 0, /* tp_base */
507 0, /* tp_dict */ 498 0, /* tp_dict */
508 (descrgetfunc)method_get, /* tp_descr_get */ 499 (descrgetfunc)method_get, /* tp_descr_get */
509 0, /* tp_descr_set */ 500
501 .tp_fastcall = (fastternaryfunc)methoddescr_call,
510 }; 502 };
511 503
512 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */ 504 /* This is for METH_CLASS in C, not for "f = classmethod(f)" in Python! */
513 PyTypeObject PyClassMethodDescr_Type = { 505 PyTypeObject PyClassMethodDescr_Type = {
514 PyVarObject_HEAD_INIT(&PyType_Type, 0) 506 PyVarObject_HEAD_INIT(&PyType_Type, 0)
515 "classmethod_descriptor", 507 "classmethod_descriptor",
516 sizeof(PyMethodDescrObject), 508 sizeof(PyMethodDescrObject),
517 0, 509 0,
518 (destructor)descr_dealloc, /* tp_dealloc */ 510 (destructor)descr_dealloc, /* tp_dealloc */
519 0, /* tp_print */ 511 0, /* tp_print */
520 0, /* tp_getattr */ 512 0, /* tp_getattr */
521 0, /* tp_setattr */ 513 0, /* tp_setattr */
522 0, /* tp_reserved */ 514 0, /* tp_reserved */
523 (reprfunc)method_repr, /* tp_repr */ 515 (reprfunc)method_repr, /* tp_repr */
524 0, /* tp_as_number */ 516 0, /* tp_as_number */
525 0, /* tp_as_sequence */ 517 0, /* tp_as_sequence */
526 0, /* tp_as_mapping */ 518 0, /* tp_as_mapping */
527 0, /* tp_hash */ 519 0, /* tp_hash */
528 (ternaryfunc)classmethoddescr_call, /* tp_call */ 520 0, /* tp_call */
529 0, /* tp_str */ 521 0, /* tp_str */
530 PyObject_GenericGetAttr, /* tp_getattro */ 522 PyObject_GenericGetAttr, /* tp_getattro */
531 0, /* tp_setattro */ 523 0, /* tp_setattro */
532 0, /* tp_as_buffer */ 524 0, /* tp_as_buffer */
533 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
534 0, /* tp_doc */ 526 0, /* tp_doc */
535 descr_traverse, /* tp_traverse */ 527 descr_traverse, /* tp_traverse */
536 0, /* tp_clear */ 528 0, /* tp_clear */
537 0, /* tp_richcompare */ 529 0, /* tp_richcompare */
538 0, /* tp_weaklistoffset */ 530 0, /* tp_weaklistoffset */
539 0, /* tp_iter */ 531 0, /* tp_iter */
540 0, /* tp_iternext */ 532 0, /* tp_iternext */
541 descr_methods, /* tp_methods */ 533 descr_methods, /* tp_methods */
542 descr_members, /* tp_members */ 534 descr_members, /* tp_members */
543 method_getset, /* tp_getset */ 535 method_getset, /* tp_getset */
544 0, /* tp_base */ 536 0, /* tp_base */
545 0, /* tp_dict */ 537 0, /* tp_dict */
546 (descrgetfunc)classmethod_get, /* tp_descr_get */ 538 (descrgetfunc)classmethod_get, /* tp_descr_get */
547 0, /* tp_descr_set */ 539
540 .tp_fastcall = (fastternaryfunc)classmethoddescr_call,
548 }; 541 };
549 542
550 PyTypeObject PyMemberDescr_Type = { 543 PyTypeObject PyMemberDescr_Type = {
551 PyVarObject_HEAD_INIT(&PyType_Type, 0) 544 PyVarObject_HEAD_INIT(&PyType_Type, 0)
552 "member_descriptor", 545 "member_descriptor",
553 sizeof(PyMemberDescrObject), 546 sizeof(PyMemberDescrObject),
554 0, 547 0,
555 (destructor)descr_dealloc, /* tp_dealloc */ 548 (destructor)descr_dealloc, /* tp_dealloc */
556 0, /* tp_print */ 549 0, /* tp_print */
557 0, /* tp_getattr */ 550 0, /* tp_getattr */
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 (destructor)descr_dealloc, /* tp_dealloc */ 622 (destructor)descr_dealloc, /* tp_dealloc */
630 0, /* tp_print */ 623 0, /* tp_print */
631 0, /* tp_getattr */ 624 0, /* tp_getattr */
632 0, /* tp_setattr */ 625 0, /* tp_setattr */
633 0, /* tp_reserved */ 626 0, /* tp_reserved */
634 (reprfunc)wrapperdescr_repr, /* tp_repr */ 627 (reprfunc)wrapperdescr_repr, /* tp_repr */
635 0, /* tp_as_number */ 628 0, /* tp_as_number */
636 0, /* tp_as_sequence */ 629 0, /* tp_as_sequence */
637 0, /* tp_as_mapping */ 630 0, /* tp_as_mapping */
638 0, /* tp_hash */ 631 0, /* tp_hash */
639 (ternaryfunc)wrapperdescr_call, /* tp_call */ 632 0, /* tp_call */
640 0, /* tp_str */ 633 0, /* tp_str */
641 PyObject_GenericGetAttr, /* tp_getattro */ 634 PyObject_GenericGetAttr, /* tp_getattro */
642 0, /* tp_setattro */ 635 0, /* tp_setattro */
643 0, /* tp_as_buffer */ 636 0, /* tp_as_buffer */
644 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 637 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
645 0, /* tp_doc */ 638 0, /* tp_doc */
646 descr_traverse, /* tp_traverse */ 639 descr_traverse, /* tp_traverse */
647 0, /* tp_clear */ 640 0, /* tp_clear */
648 0, /* tp_richcompare */ 641 0, /* tp_richcompare */
649 0, /* tp_weaklistoffset */ 642 0, /* tp_weaklistoffset */
650 0, /* tp_iter */ 643 0, /* tp_iter */
651 0, /* tp_iternext */ 644 0, /* tp_iternext */
652 descr_methods, /* tp_methods */ 645 descr_methods, /* tp_methods */
653 descr_members, /* tp_members */ 646 descr_members, /* tp_members */
654 wrapperdescr_getset, /* tp_getset */ 647 wrapperdescr_getset, /* tp_getset */
655 0, /* tp_base */ 648 0, /* tp_base */
656 0, /* tp_dict */ 649 0, /* tp_dict */
657 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 650 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
658 0, /* tp_descr_set */ 651
652 .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
659 }; 653 };
660 654
661 static PyDescrObject * 655 static PyDescrObject *
662 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 656 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
663 { 657 {
664 PyDescrObject *descr; 658 PyDescrObject *descr;
665 659
666 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 660 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
667 if (descr != NULL) { 661 if (descr == NULL) {
668 Py_XINCREF(type); 662 return NULL;
669 descr->d_type = type; 663 }
670 descr->d_name = PyUnicode_InternFromString(name); 664
671 if (descr->d_name == NULL) { 665 Py_XINCREF(type);
672 Py_DECREF(descr); 666 descr->d_type = type;
673 descr = NULL; 667 descr->d_name = PyUnicode_InternFromString(name);
674 } 668 if (descr->d_name == NULL) {
675 else { 669 Py_DECREF(descr);
676 descr->d_qualname = NULL; 670 descr = NULL;
677 } 671 }
672 else {
673 descr->d_qualname = NULL;
678 } 674 }
679 return descr; 675 return descr;
680 } 676 }
681 677
682 PyObject * 678 PyObject *
683 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 679 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
684 { 680 {
685 PyMethodDescrObject *descr; 681 PyMethodDescrObject *descr;
686 682
687 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, 683 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
(...skipping 30 matching lines...) Expand all
718 PyObject * 714 PyObject *
719 PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) 715 PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset)
720 { 716 {
721 PyGetSetDescrObject *descr; 717 PyGetSetDescrObject *descr;
722 718
723 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 719 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
724 type, getset->name); 720 type, getset->name);
725 if (descr != NULL) 721 if (descr != NULL)
726 descr->d_getset = getset; 722 descr->d_getset = getset;
727 return (PyObject *)descr; 723 return (PyObject *)descr;
724 }
725
726 PyObject *
727 _PyDescr_NewWrapperEx(PyTypeObject *type, struct wrapperbase *base, void *wrappe d, int use_fastwrapper)
haypo 2017/01/26 03:35:21 Maybe a new funtion is not worth it, the d_user_fa
728 {
729 PyWrapperDescrObject *descr;
730
731 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
732 type, base->name);
733 if (descr == NULL) {
734 return NULL;
735 }
736
737 descr->d_base = base;
738 descr->d_wrapped = wrapped;
739 descr->d_use_fastwrapper = use_fastwrapper;
740 return (PyObject *)descr;
728 } 741 }
729 742
730 PyObject * 743 PyObject *
731 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) 744 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
732 { 745 {
733 PyWrapperDescrObject *descr; 746 return _PyDescr_NewWrapperEx(type, base, wrapped, 0);
734
735 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
736 type, base->name);
737 if (descr != NULL) {
738 descr->d_base = base;
739 descr->d_wrapped = wrapped;
740 }
741 return (PyObject *)descr;
742 } 747 }
743 748
744 749
745 /* --- mappingproxy: read-only proxy for mappings --- */ 750 /* --- mappingproxy: read-only proxy for mappings --- */
746 751
747 /* This has no reason to be in this file except that adding new files is a 752 /* This has no reason to be in this file except that adding new files is a
748 bit of a pain */ 753 bit of a pain */
749 754
750 typedef struct { 755 typedef struct {
751 PyObject_HEAD 756 PyObject_HEAD
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 static PyGetSetDef wrapper_getsets[] = { 1157 static PyGetSetDef wrapper_getsets[] = {
1153 {"__objclass__", (getter)wrapper_objclass}, 1158 {"__objclass__", (getter)wrapper_objclass},
1154 {"__name__", (getter)wrapper_name}, 1159 {"__name__", (getter)wrapper_name},
1155 {"__qualname__", (getter)wrapper_qualname}, 1160 {"__qualname__", (getter)wrapper_qualname},
1156 {"__doc__", (getter)wrapper_doc}, 1161 {"__doc__", (getter)wrapper_doc},
1157 {"__text_signature__", (getter)wrapper_text_signature}, 1162 {"__text_signature__", (getter)wrapper_text_signature},
1158 {0} 1163 {0}
1159 }; 1164 };
1160 1165
1161 static PyObject * 1166 static PyObject *
1162 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 1167 wrapper_call(wrapperobject *wp, PyObject **stack, Py_ssize_t nargs, PyObject *kw names)
1163 { 1168 {
1164 wrapperfunc wrapper = wp->descr->d_base->wrapper; 1169 wrapperfunc wrapper;
1165 PyObject *self = wp->self; 1170 PyObject *self = wp->self;
1171 PyObject *args, *kwargs, *result;
1166 1172
1173 if (wp->descr->d_use_fastwrapper) {
1174 wrapperfunc_fast wf = wp->descr->d_base->fastwrapper;
1175
1176 return (*wf)(self, wp->descr->d_wrapped, stack, nargs, kwnames);
1177 }
1178
1179 wrapper = wp->descr->d_base->wrapper;
1167 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 1180 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
1168 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; 1181 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
1169 return (*wk)(self, args, wp->descr->d_wrapped, kwds); 1182
1183 if (_PyStack_AsTupleAndDict(stack, nargs, kwnames, &args, &kwargs) < 0) {
1184 return NULL;
1185 }
1186
1187 result = (*wk)(self, args, wp->descr->d_wrapped, kwargs);
1188 Py_DECREF(args);
1189 Py_XDECREF(kwargs);
1190
1191 return result;
1170 } 1192 }
1171 1193
1172 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { 1194 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) != 0) {
1173 PyErr_Format(PyExc_TypeError, 1195 PyErr_Format(PyExc_TypeError,
1174 "wrapper %s doesn't take keyword arguments", 1196 "wrapper %s doesn't take keyword arguments",
1175 wp->descr->d_base->name); 1197 wp->descr->d_base->name);
1176 return NULL; 1198 return NULL;
1177 } 1199 }
1178 return (*wrapper)(self, args, wp->descr->d_wrapped); 1200
1201 args = _PyStack_AsTuple(stack, nargs);
1202 if (args == NULL) {
1203 return NULL;
1204 }
1205
1206 result = (*wrapper)(self, args, wp->descr->d_wrapped);
1207 Py_DECREF(args);
1208 return result;
1179 } 1209 }
1180 1210
1181 static int 1211 static int
1182 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 1212 wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1183 { 1213 {
1184 wrapperobject *wp = (wrapperobject *)self; 1214 wrapperobject *wp = (wrapperobject *)self;
1185 Py_VISIT(wp->descr); 1215 Py_VISIT(wp->descr);
1186 Py_VISIT(wp->self); 1216 Py_VISIT(wp->self);
1187 return 0; 1217 return 0;
1188 } 1218 }
1189 1219
1190 PyTypeObject _PyMethodWrapper_Type = { 1220 PyTypeObject _PyMethodWrapper_Type = {
1191 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1192 "method-wrapper", /* tp_name */ 1222 "method-wrapper", /* tp_name */
1193 sizeof(wrapperobject), /* tp_basicsize */ 1223 sizeof(wrapperobject), /* tp_basicsize */
1194 0, /* tp_itemsize */ 1224 0, /* tp_itemsize */
1195 /* methods */ 1225 /* methods */
1196 (destructor)wrapper_dealloc, /* tp_dealloc */ 1226 (destructor)wrapper_dealloc, /* tp_dealloc */
1197 0, /* tp_print */ 1227 0, /* tp_print */
1198 0, /* tp_getattr */ 1228 0, /* tp_getattr */
1199 0, /* tp_setattr */ 1229 0, /* tp_setattr */
1200 0, /* tp_reserved */ 1230 0, /* tp_reserved */
1201 (reprfunc)wrapper_repr, /* tp_repr */ 1231 (reprfunc)wrapper_repr, /* tp_repr */
1202 0, /* tp_as_number */ 1232 0, /* tp_as_number */
1203 0, /* tp_as_sequence */ 1233 0, /* tp_as_sequence */
1204 0, /* tp_as_mapping */ 1234 0, /* tp_as_mapping */
1205 (hashfunc)wrapper_hash, /* tp_hash */ 1235 (hashfunc)wrapper_hash, /* tp_hash */
1206 (ternaryfunc)wrapper_call, /* tp_call */ 1236 0, /* tp_call */
1207 0, /* tp_str */ 1237 0, /* tp_str */
1208 PyObject_GenericGetAttr, /* tp_getattro */ 1238 PyObject_GenericGetAttr, /* tp_getattro */
1209 0, /* tp_setattro */ 1239 0, /* tp_setattro */
1210 0, /* tp_as_buffer */ 1240 0, /* tp_as_buffer */
1211 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1212 0, /* tp_doc */ 1242 0, /* tp_doc */
1213 wrapper_traverse, /* tp_traverse */ 1243 wrapper_traverse, /* tp_traverse */
1214 0, /* tp_clear */ 1244 0, /* tp_clear */
1215 wrapper_richcompare, /* tp_richcompare */ 1245 wrapper_richcompare, /* tp_richcompare */
1216 0, /* tp_weaklistoffset */ 1246 0, /* tp_weaklistoffset */
1217 0, /* tp_iter */ 1247 0, /* tp_iter */
1218 0, /* tp_iternext */ 1248 0, /* tp_iternext */
1219 wrapper_methods, /* tp_methods */ 1249 wrapper_methods, /* tp_methods */
1220 wrapper_members, /* tp_members */ 1250 wrapper_members, /* tp_members */
1221 wrapper_getsets, /* tp_getset */ 1251 wrapper_getsets, /* tp_getset */
1222 0, /* tp_base */ 1252
1223 0, /* tp_dict */ 1253 .tp_fastcall = (fastternaryfunc)wrapper_call,
1224 0, /* tp_descr_get */
1225 0, /* tp_descr_set */
1226 }; 1254 };
1227 1255
1228 PyObject * 1256 PyObject *
1229 PyWrapper_New(PyObject *d, PyObject *self) 1257 PyWrapper_New(PyObject *d, PyObject *self)
1230 { 1258 {
1231 wrapperobject *wp; 1259 wrapperobject *wp;
1232 PyWrapperDescrObject *descr; 1260 PyWrapperDescrObject *descr;
1233 1261
1234 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1262 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1235 descr = (PyWrapperDescrObject *)d; 1263 descr = (PyWrapperDescrObject *)d;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 Py_XDECREF(gs->prop_get); 1376 Py_XDECREF(gs->prop_get);
1349 Py_XDECREF(gs->prop_set); 1377 Py_XDECREF(gs->prop_set);
1350 Py_XDECREF(gs->prop_del); 1378 Py_XDECREF(gs->prop_del);
1351 Py_XDECREF(gs->prop_doc); 1379 Py_XDECREF(gs->prop_doc);
1352 self->ob_type->tp_free(self); 1380 self->ob_type->tp_free(self);
1353 } 1381 }
1354 1382
1355 static PyObject * 1383 static PyObject *
1356 property_descr_get(PyObject *self, PyObject *obj, PyObject *type) 1384 property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1357 { 1385 {
1358 static PyObject * volatile cached_args = NULL;
1359 PyObject *args;
1360 PyObject *ret;
1361 propertyobject *gs = (propertyobject *)self; 1386 propertyobject *gs = (propertyobject *)self;
1387 PyObject *args[1];
1362 1388
1363 if (obj == NULL || obj == Py_None) { 1389 if (obj == NULL || obj == Py_None) {
1364 Py_INCREF(self); 1390 Py_INCREF(self);
1365 return self; 1391 return self;
1366 } 1392 }
1367 if (gs->prop_get == NULL) { 1393 if (gs->prop_get == NULL) {
1368 PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); 1394 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1369 return NULL; 1395 return NULL;
1370 } 1396 }
1371 args = cached_args; 1397
1372 cached_args = NULL; 1398 args[0] = obj;
1373 if (!args) { 1399 return _PyObject_FastCall(gs->prop_get, args, 1);
1374 args = PyTuple_New(1);
1375 if (!args)
1376 return NULL;
1377 _PyObject_GC_UNTRACK(args);
1378 }
1379 Py_INCREF(obj);
1380 PyTuple_SET_ITEM(args, 0, obj);
1381 ret = PyObject_Call(gs->prop_get, args, NULL);
1382 if (cached_args == NULL && Py_REFCNT(args) == 1) {
1383 assert(Py_SIZE(args) == 1);
1384 assert(PyTuple_GET_ITEM(args, 0) == obj);
1385 cached_args = args;
1386 Py_DECREF(obj);
1387 }
1388 else {
1389 assert(Py_REFCNT(args) >= 1);
1390 _PyObject_GC_TRACK(args);
1391 Py_DECREF(args);
1392 }
1393 return ret;
1394 } 1400 }
1395 1401
1396 static int 1402 static int
1397 property_descr_set(PyObject *self, PyObject *obj, PyObject *value) 1403 property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1398 { 1404 {
1399 propertyobject *gs = (propertyobject *)self; 1405 propertyobject *gs = (propertyobject *)self;
1400 PyObject *func, *res; 1406 PyObject *func, *res;
1401 1407
1402 if (value == NULL) 1408 if (value == NULL)
1403 func = gs->prop_del; 1409 func = gs->prop_del;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 0, /* tp_base */ 1641 0, /* tp_base */
1636 0, /* tp_dict */ 1642 0, /* tp_dict */
1637 property_descr_get, /* tp_descr_get */ 1643 property_descr_get, /* tp_descr_get */
1638 property_descr_set, /* tp_descr_set */ 1644 property_descr_set, /* tp_descr_set */
1639 0, /* tp_dictoffset */ 1645 0, /* tp_dictoffset */
1640 property_init, /* tp_init */ 1646 property_init, /* tp_init */
1641 PyType_GenericAlloc, /* tp_alloc */ 1647 PyType_GenericAlloc, /* tp_alloc */
1642 PyType_GenericNew, /* tp_new */ 1648 PyType_GenericNew, /* tp_new */
1643 PyObject_GC_Del, /* tp_free */ 1649 PyObject_GC_Del, /* tp_free */
1644 }; 1650 };
OLDNEW

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+