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

Delta Between Two Patch Sets: Objects/descrobject.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Left Patch Set: Created 3 years ago
Right 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, Py_ssize_t nargs, 213 methoddescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
214 PyObject *kwnames) 214 PyObject *kwnames)
215 { 215 {
216 PyObject *self, *func, *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 if (nargs < 1) { 219 if (nargs < 1) {
220 PyErr_Format(PyExc_TypeError, 220 PyErr_Format(PyExc_TypeError,
221 "descriptor '%V' of '%.100s' " 221 "descriptor '%V' of '%.100s' "
222 "object needs an argument", 222 "object needs an argument",
223 descr_name((PyDescrObject *)descr), "?", 223 descr_name((PyDescrObject *)descr), "?",
224 PyDescr_TYPE(descr)->tp_name); 224 PyDescr_TYPE(descr)->tp_name);
225 return NULL; 225 return NULL;
226 } 226 }
227 self = args[0]; 227 self = args[0];
228 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self), 228 if (!_PyObject_RealIsSubclass((PyObject *)Py_TYPE(self),
229 (PyObject *)PyDescr_TYPE(descr))) { 229 (PyObject *)PyDescr_TYPE(descr))) {
230 PyErr_Format(PyExc_TypeError, 230 PyErr_Format(PyExc_TypeError,
231 "descriptor '%V' " 231 "descriptor '%V' "
232 "requires a '%.100s' object " 232 "requires a '%.100s' object "
233 "but received a '%.100s'", 233 "but received a '%.100s'",
234 descr_name((PyDescrObject *)descr), "?", 234 descr_name((PyDescrObject *)descr), "?",
235 PyDescr_TYPE(descr)->tp_name, 235 PyDescr_TYPE(descr)->tp_name,
236 self->ob_type->tp_name); 236 self->ob_type->tp_name);
237 return NULL; 237 return NULL;
238 } 238 }
239 239
240 func = PyCFunction_NewEx(descr->d_method, self, NULL); 240 result = _PyMethodDef_RawFastCallKeywords(descr->d_method, self,
241 if (func == NULL) 241 args + 1, nargs - 1,
242 return NULL; 242 kwnames);
243 result = _PyCFunction_FastCallKeywords(func, args + 1, nargs - 1, kwnames); 243 result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL);
244 Py_DECREF(func);
245 return result; 244 return result;
246 } 245 }
247 246
248 static PyObject * 247 static PyObject *
249 classmethoddescr_call(PyMethodDescrObject *descr, PyObject **args, 248 classmethoddescr_call(PyMethodDescrObject *descr, PyObject **args,
250 Py_ssize_t nargs, PyObject *kwnames) 249 Py_ssize_t nargs, PyObject *kwnames)
251 { 250 {
252 PyObject *self, *func, *result; 251 PyObject *self, *func, *result;
253 252
254 /* Make sure that the first argument is acceptable as 'self' */ 253 /* Make sure that the first argument is acceptable as 'self' */
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 {"__doc__", (getter)method_get_doc}, 403 {"__doc__", (getter)method_get_doc},
405 {"__qualname__", (getter)descr_get_qualname}, 404 {"__qualname__", (getter)descr_get_qualname},
406 {"__text_signature__", (getter)method_get_text_signature}, 405 {"__text_signature__", (getter)method_get_text_signature},
407 {0} 406 {0}
408 }; 407 };
409 408
410 static PyObject * 409 static PyObject *
411 member_get_doc(PyMemberDescrObject *descr, void *closure) 410 member_get_doc(PyMemberDescrObject *descr, void *closure)
412 { 411 {
413 if (descr->d_member->doc == NULL) { 412 if (descr->d_member->doc == NULL) {
414 Py_INCREF(Py_None); 413 Py_RETURN_NONE;
415 return Py_None;
416 } 414 }
417 return PyUnicode_FromString(descr->d_member->doc); 415 return PyUnicode_FromString(descr->d_member->doc);
418 } 416 }
419 417
420 static PyGetSetDef member_getset[] = { 418 static PyGetSetDef member_getset[] = {
421 {"__doc__", (getter)member_get_doc}, 419 {"__doc__", (getter)member_get_doc},
422 {"__qualname__", (getter)descr_get_qualname}, 420 {"__qualname__", (getter)descr_get_qualname},
423 {0} 421 {0}
424 }; 422 };
425 423
426 static PyObject * 424 static PyObject *
427 getset_get_doc(PyGetSetDescrObject *descr, void *closure) 425 getset_get_doc(PyGetSetDescrObject *descr, void *closure)
428 { 426 {
429 if (descr->d_getset->doc == NULL) { 427 if (descr->d_getset->doc == NULL) {
430 Py_INCREF(Py_None); 428 Py_RETURN_NONE;
431 return Py_None;
432 } 429 }
433 return PyUnicode_FromString(descr->d_getset->doc); 430 return PyUnicode_FromString(descr->d_getset->doc);
434 } 431 }
435 432
436 static PyGetSetDef getset_getset[] = { 433 static PyGetSetDef getset_getset[] = {
437 {"__doc__", (getter)getset_get_doc}, 434 {"__doc__", (getter)getset_get_doc},
438 {"__qualname__", (getter)descr_get_qualname}, 435 {"__qualname__", (getter)descr_get_qualname},
439 {0} 436 {0}
440 }; 437 };
441 438
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 (reprfunc)method_repr, /* tp_repr */ 476 (reprfunc)method_repr, /* tp_repr */
480 0, /* tp_as_number */ 477 0, /* tp_as_number */
481 0, /* tp_as_sequence */ 478 0, /* tp_as_sequence */
482 0, /* tp_as_mapping */ 479 0, /* tp_as_mapping */
483 0, /* tp_hash */ 480 0, /* tp_hash */
484 0, /* tp_call */ 481 0, /* tp_call */
485 0, /* tp_str */ 482 0, /* tp_str */
486 PyObject_GenericGetAttr, /* tp_getattro */ 483 PyObject_GenericGetAttr, /* tp_getattro */
487 0, /* tp_setattro */ 484 0, /* tp_setattro */
488 0, /* tp_as_buffer */ 485 0, /* tp_as_buffer */
489 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 486 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
490 | Py_TPFLAGS_HAVE_FASTCALL, /* tp_flags */
491 0, /* tp_doc */ 487 0, /* tp_doc */
492 descr_traverse, /* tp_traverse */ 488 descr_traverse, /* tp_traverse */
493 0, /* tp_clear */ 489 0, /* tp_clear */
494 0, /* tp_richcompare */ 490 0, /* tp_richcompare */
495 0, /* tp_weaklistoffset */ 491 0, /* tp_weaklistoffset */
496 0, /* tp_iter */ 492 0, /* tp_iter */
497 0, /* tp_iternext */ 493 0, /* tp_iternext */
498 descr_methods, /* tp_methods */ 494 descr_methods, /* tp_methods */
499 descr_members, /* tp_members */ 495 descr_members, /* tp_members */
500 method_getset, /* tp_getset */ 496 method_getset, /* tp_getset */
501 0, /* tp_base */ 497 0, /* tp_base */
502 0, /* tp_dict */ 498 0, /* tp_dict */
503 (descrgetfunc)method_get, /* tp_descr_get */ 499 (descrgetfunc)method_get, /* tp_descr_get */
504 0, /* tp_descr_set */ 500
505 0, /* tp_dictoffset */ 501 .tp_fastcall = (fastternaryfunc)methoddescr_call,
506 0, /* tp_init */
507 0, /* tp_alloc */
508 0, /* tp_new */
509 0, /* tp_free */
510 0, /* tp_is_gc */
511 0, /* tp_bases */
512 0, /* tp_mro */
513 0, /* tp_cache */
514 0, /* tp_subclasses */
515 0, /* tp_weaklist */
516 0, /* tp_del */
517 0, /* tp_version_tag */
518 0, /* tp_finalize */
519 (fastternaryfunc)methoddescr_call, /* tp_fastcall */
520 }; 502 };
521 503
522 /* 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! */
523 PyTypeObject PyClassMethodDescr_Type = { 505 PyTypeObject PyClassMethodDescr_Type = {
524 PyVarObject_HEAD_INIT(&PyType_Type, 0) 506 PyVarObject_HEAD_INIT(&PyType_Type, 0)
525 "classmethod_descriptor", 507 "classmethod_descriptor",
526 sizeof(PyMethodDescrObject), 508 sizeof(PyMethodDescrObject),
527 0, 509 0,
528 (destructor)descr_dealloc, /* tp_dealloc */ 510 (destructor)descr_dealloc, /* tp_dealloc */
529 0, /* tp_print */ 511 0, /* tp_print */
530 0, /* tp_getattr */ 512 0, /* tp_getattr */
531 0, /* tp_setattr */ 513 0, /* tp_setattr */
532 0, /* tp_reserved */ 514 0, /* tp_reserved */
533 (reprfunc)method_repr, /* tp_repr */ 515 (reprfunc)method_repr, /* tp_repr */
534 0, /* tp_as_number */ 516 0, /* tp_as_number */
535 0, /* tp_as_sequence */ 517 0, /* tp_as_sequence */
536 0, /* tp_as_mapping */ 518 0, /* tp_as_mapping */
537 0, /* tp_hash */ 519 0, /* tp_hash */
538 0, /* tp_call */ 520 0, /* tp_call */
539 0, /* tp_str */ 521 0, /* tp_str */
540 PyObject_GenericGetAttr, /* tp_getattro */ 522 PyObject_GenericGetAttr, /* tp_getattro */
541 0, /* tp_setattro */ 523 0, /* tp_setattro */
542 0, /* tp_as_buffer */ 524 0, /* tp_as_buffer */
543 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
544 | Py_TPFLAGS_HAVE_FASTCALL, /* tp_flags */
545 0, /* tp_doc */ 526 0, /* tp_doc */
546 descr_traverse, /* tp_traverse */ 527 descr_traverse, /* tp_traverse */
547 0, /* tp_clear */ 528 0, /* tp_clear */
548 0, /* tp_richcompare */ 529 0, /* tp_richcompare */
549 0, /* tp_weaklistoffset */ 530 0, /* tp_weaklistoffset */
550 0, /* tp_iter */ 531 0, /* tp_iter */
551 0, /* tp_iternext */ 532 0, /* tp_iternext */
552 descr_methods, /* tp_methods */ 533 descr_methods, /* tp_methods */
553 descr_members, /* tp_members */ 534 descr_members, /* tp_members */
554 method_getset, /* tp_getset */ 535 method_getset, /* tp_getset */
555 0, /* tp_base */ 536 0, /* tp_base */
556 0, /* tp_dict */ 537 0, /* tp_dict */
557 (descrgetfunc)classmethod_get, /* tp_descr_get */ 538 (descrgetfunc)classmethod_get, /* tp_descr_get */
558 0, /* tp_descr_set */ 539
559 0, /* tp_dictoffset */ 540 .tp_fastcall = (fastternaryfunc)classmethoddescr_call,
560 0, /* tp_init */
561 0, /* tp_alloc */
562 0, /* tp_new */
563 0, /* tp_free */
564 0, /* tp_is_gc */
565 0, /* tp_bases */
566 0, /* tp_mro */
567 0, /* tp_cache */
568 0, /* tp_subclasses */
569 0, /* tp_weaklist */
570 0, /* tp_del */
571 0, /* tp_version_tag */
572 0, /* tp_finalize */
573 (fastternaryfunc)classmethoddescr_call, /* tp_fastcall */
574 }; 541 };
575 542
576 PyTypeObject PyMemberDescr_Type = { 543 PyTypeObject PyMemberDescr_Type = {
577 PyVarObject_HEAD_INIT(&PyType_Type, 0) 544 PyVarObject_HEAD_INIT(&PyType_Type, 0)
578 "member_descriptor", 545 "member_descriptor",
579 sizeof(PyMemberDescrObject), 546 sizeof(PyMemberDescrObject),
580 0, 547 0,
581 (destructor)descr_dealloc, /* tp_dealloc */ 548 (destructor)descr_dealloc, /* tp_dealloc */
582 0, /* tp_print */ 549 0, /* tp_print */
583 0, /* tp_getattr */ 550 0, /* tp_getattr */
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 (reprfunc)wrapperdescr_repr, /* tp_repr */ 627 (reprfunc)wrapperdescr_repr, /* tp_repr */
661 0, /* tp_as_number */ 628 0, /* tp_as_number */
662 0, /* tp_as_sequence */ 629 0, /* tp_as_sequence */
663 0, /* tp_as_mapping */ 630 0, /* tp_as_mapping */
664 0, /* tp_hash */ 631 0, /* tp_hash */
665 0, /* tp_call */ 632 0, /* tp_call */
666 0, /* tp_str */ 633 0, /* tp_str */
667 PyObject_GenericGetAttr, /* tp_getattro */ 634 PyObject_GenericGetAttr, /* tp_getattro */
668 0, /* tp_setattro */ 635 0, /* tp_setattro */
669 0, /* tp_as_buffer */ 636 0, /* tp_as_buffer */
670 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 637 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
671 | Py_TPFLAGS_HAVE_FASTCALL, /* tp_flags */
672 0, /* tp_doc */ 638 0, /* tp_doc */
673 descr_traverse, /* tp_traverse */ 639 descr_traverse, /* tp_traverse */
674 0, /* tp_clear */ 640 0, /* tp_clear */
675 0, /* tp_richcompare */ 641 0, /* tp_richcompare */
676 0, /* tp_weaklistoffset */ 642 0, /* tp_weaklistoffset */
677 0, /* tp_iter */ 643 0, /* tp_iter */
678 0, /* tp_iternext */ 644 0, /* tp_iternext */
679 descr_methods, /* tp_methods */ 645 descr_methods, /* tp_methods */
680 descr_members, /* tp_members */ 646 descr_members, /* tp_members */
681 wrapperdescr_getset, /* tp_getset */ 647 wrapperdescr_getset, /* tp_getset */
682 0, /* tp_base */ 648 0, /* tp_base */
683 0, /* tp_dict */ 649 0, /* tp_dict */
684 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 650 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
685 0, /* tp_descr_set */ 651
686 0, /* tp_dictoffset */ 652 .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
687 0, /* tp_init */
688 0, /* tp_alloc */
689 0, /* tp_new */
690 0, /* tp_free */
691 0, /* tp_is_gc */
692 0, /* tp_bases */
693 0, /* tp_mro */
694 0, /* tp_cache */
695 0, /* tp_subclasses */
696 0, /* tp_weaklist */
697 0, /* tp_del */
698 0, /* tp_version_tag */
699 0, /* tp_finalize */
700 (fastternaryfunc)wrapperdescr_call, /* tp_fastcall */
701 }; 653 };
702 654
703 static PyDescrObject * 655 static PyDescrObject *
704 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 656 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
705 { 657 {
706 PyDescrObject *descr; 658 PyDescrObject *descr;
707 659
708 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 660 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
709 if (descr != NULL) { 661 if (descr == NULL) {
710 Py_XINCREF(type); 662 return NULL;
711 descr->d_type = type; 663 }
712 descr->d_name = PyUnicode_InternFromString(name); 664
713 if (descr->d_name == NULL) { 665 Py_XINCREF(type);
714 Py_DECREF(descr); 666 descr->d_type = type;
715 descr = NULL; 667 descr->d_name = PyUnicode_InternFromString(name);
716 } 668 if (descr->d_name == NULL) {
717 else { 669 Py_DECREF(descr);
718 descr->d_qualname = NULL; 670 descr = NULL;
719 } 671 }
672 else {
673 descr->d_qualname = NULL;
720 } 674 }
721 return descr; 675 return descr;
722 } 676 }
723 677
724 PyObject * 678 PyObject *
725 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 679 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
726 { 680 {
727 PyMethodDescrObject *descr; 681 PyMethodDescrObject *descr;
728 682
729 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type, 683 descr = (PyMethodDescrObject *)descr_new(&PyMethodDescr_Type,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 PyGetSetDescrObject *descr; 717 PyGetSetDescrObject *descr;
764 718
765 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 719 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
766 type, getset->name); 720 type, getset->name);
767 if (descr != NULL) 721 if (descr != NULL)
768 descr->d_getset = getset; 722 descr->d_getset = getset;
769 return (PyObject *)descr; 723 return (PyObject *)descr;
770 } 724 }
771 725
772 PyObject * 726 PyObject *
773 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped) 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
774 { 728 {
775 PyWrapperDescrObject *descr; 729 PyWrapperDescrObject *descr;
776 730
777 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, 731 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
778 type, base->name); 732 type, base->name);
779 if (descr != NULL) { 733 if (descr == NULL) {
780 descr->d_base = base; 734 return NULL;
781 descr->d_wrapped = wrapped; 735 }
782 } 736
737 descr->d_base = base;
738 descr->d_wrapped = wrapped;
739 descr->d_use_fastwrapper = use_fastwrapper;
783 return (PyObject *)descr; 740 return (PyObject *)descr;
741 }
742
743 PyObject *
744 PyDescr_NewWrapper(PyTypeObject *type, struct wrapperbase *base, void *wrapped)
745 {
746 return _PyDescr_NewWrapperEx(type, base, wrapped, 0);
784 } 747 }
785 748
786 749
787 /* --- mappingproxy: read-only proxy for mappings --- */ 750 /* --- mappingproxy: read-only proxy for mappings --- */
788 751
789 /* 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
790 bit of a pain */ 753 bit of a pain */
791 754
792 typedef struct { 755 typedef struct {
793 PyObject_HEAD 756 PyObject_HEAD
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 static PyGetSetDef wrapper_getsets[] = { 1157 static PyGetSetDef wrapper_getsets[] = {
1195 {"__objclass__", (getter)wrapper_objclass}, 1158 {"__objclass__", (getter)wrapper_objclass},
1196 {"__name__", (getter)wrapper_name}, 1159 {"__name__", (getter)wrapper_name},
1197 {"__qualname__", (getter)wrapper_qualname}, 1160 {"__qualname__", (getter)wrapper_qualname},
1198 {"__doc__", (getter)wrapper_doc}, 1161 {"__doc__", (getter)wrapper_doc},
1199 {"__text_signature__", (getter)wrapper_text_signature}, 1162 {"__text_signature__", (getter)wrapper_text_signature},
1200 {0} 1163 {0}
1201 }; 1164 };
1202 1165
1203 static PyObject * 1166 static PyObject *
1204 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 1167 wrapper_call(wrapperobject *wp, PyObject **stack, Py_ssize_t nargs, PyObject *kw names)
1205 { 1168 {
1206 wrapperfunc wrapper = wp->descr->d_base->wrapper; 1169 wrapperfunc wrapper;
1207 PyObject *self = wp->self; 1170 PyObject *self = wp->self;
1208 1171 PyObject *args, *kwargs, *result;
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;
1209 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 1180 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
1210 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; 1181 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
1211 return (*wk)(self, args, wp->descr->d_wrapped, kwds); 1182
1212 } 1183 if (_PyStack_AsTupleAndDict(stack, nargs, kwnames, &args, &kwargs) < 0) {
1213 1184 return NULL;
1214 if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { 1185 }
1186
1187 result = (*wk)(self, args, wp->descr->d_wrapped, kwargs);
1188 Py_DECREF(args);
1189 Py_XDECREF(kwargs);
1190
1191 return result;
1192 }
1193
1194 if (kwnames != NULL && PyTuple_GET_SIZE(kwnames) != 0) {
1215 PyErr_Format(PyExc_TypeError, 1195 PyErr_Format(PyExc_TypeError,
1216 "wrapper %s doesn't take keyword arguments", 1196 "wrapper %s doesn't take keyword arguments",
1217 wp->descr->d_base->name); 1197 wp->descr->d_base->name);
1218 return NULL; 1198 return NULL;
1219 } 1199 }
1220 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;
1221 } 1209 }
1222 1210
1223 static int 1211 static int
1224 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 1212 wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1225 { 1213 {
1226 wrapperobject *wp = (wrapperobject *)self; 1214 wrapperobject *wp = (wrapperobject *)self;
1227 Py_VISIT(wp->descr); 1215 Py_VISIT(wp->descr);
1228 Py_VISIT(wp->self); 1216 Py_VISIT(wp->self);
1229 return 0; 1217 return 0;
1230 } 1218 }
1231 1219
1232 PyTypeObject _PyMethodWrapper_Type = { 1220 PyTypeObject _PyMethodWrapper_Type = {
1233 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1234 "method-wrapper", /* tp_name */ 1222 "method-wrapper", /* tp_name */
1235 sizeof(wrapperobject), /* tp_basicsize */ 1223 sizeof(wrapperobject), /* tp_basicsize */
1236 0, /* tp_itemsize */ 1224 0, /* tp_itemsize */
1237 /* methods */ 1225 /* methods */
1238 (destructor)wrapper_dealloc, /* tp_dealloc */ 1226 (destructor)wrapper_dealloc, /* tp_dealloc */
1239 0, /* tp_print */ 1227 0, /* tp_print */
1240 0, /* tp_getattr */ 1228 0, /* tp_getattr */
1241 0, /* tp_setattr */ 1229 0, /* tp_setattr */
1242 0, /* tp_reserved */ 1230 0, /* tp_reserved */
1243 (reprfunc)wrapper_repr, /* tp_repr */ 1231 (reprfunc)wrapper_repr, /* tp_repr */
1244 0, /* tp_as_number */ 1232 0, /* tp_as_number */
1245 0, /* tp_as_sequence */ 1233 0, /* tp_as_sequence */
1246 0, /* tp_as_mapping */ 1234 0, /* tp_as_mapping */
1247 (hashfunc)wrapper_hash, /* tp_hash */ 1235 (hashfunc)wrapper_hash, /* tp_hash */
1248 (ternaryfunc)wrapper_call, /* tp_call */ 1236 0, /* tp_call */
1249 0, /* tp_str */ 1237 0, /* tp_str */
1250 PyObject_GenericGetAttr, /* tp_getattro */ 1238 PyObject_GenericGetAttr, /* tp_getattro */
1251 0, /* tp_setattro */ 1239 0, /* tp_setattro */
1252 0, /* tp_as_buffer */ 1240 0, /* tp_as_buffer */
1253 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1254 0, /* tp_doc */ 1242 0, /* tp_doc */
1255 wrapper_traverse, /* tp_traverse */ 1243 wrapper_traverse, /* tp_traverse */
1256 0, /* tp_clear */ 1244 0, /* tp_clear */
1257 wrapper_richcompare, /* tp_richcompare */ 1245 wrapper_richcompare, /* tp_richcompare */
1258 0, /* tp_weaklistoffset */ 1246 0, /* tp_weaklistoffset */
1259 0, /* tp_iter */ 1247 0, /* tp_iter */
1260 0, /* tp_iternext */ 1248 0, /* tp_iternext */
1261 wrapper_methods, /* tp_methods */ 1249 wrapper_methods, /* tp_methods */
1262 wrapper_members, /* tp_members */ 1250 wrapper_members, /* tp_members */
1263 wrapper_getsets, /* tp_getset */ 1251 wrapper_getsets, /* tp_getset */
1264 0, /* tp_base */ 1252
1265 0, /* tp_dict */ 1253 .tp_fastcall = (fastternaryfunc)wrapper_call,
1266 0, /* tp_descr_get */
1267 0, /* tp_descr_set */
1268 }; 1254 };
1269 1255
1270 PyObject * 1256 PyObject *
1271 PyWrapper_New(PyObject *d, PyObject *self) 1257 PyWrapper_New(PyObject *d, PyObject *self)
1272 { 1258 {
1273 wrapperobject *wp; 1259 wrapperobject *wp;
1274 PyWrapperDescrObject *descr; 1260 PyWrapperDescrObject *descr;
1275 1261
1276 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1262 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1277 descr = (PyWrapperDescrObject *)d; 1263 descr = (PyWrapperDescrObject *)d;
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1655 0, /* tp_base */ 1641 0, /* tp_base */
1656 0, /* tp_dict */ 1642 0, /* tp_dict */
1657 property_descr_get, /* tp_descr_get */ 1643 property_descr_get, /* tp_descr_get */
1658 property_descr_set, /* tp_descr_set */ 1644 property_descr_set, /* tp_descr_set */
1659 0, /* tp_dictoffset */ 1645 0, /* tp_dictoffset */
1660 property_init, /* tp_init */ 1646 property_init, /* tp_init */
1661 PyType_GenericAlloc, /* tp_alloc */ 1647 PyType_GenericAlloc, /* tp_alloc */
1662 PyType_GenericNew, /* tp_new */ 1648 PyType_GenericNew, /* tp_new */
1663 PyObject_GC_Del, /* tp_free */ 1649 PyObject_GC_Del, /* tp_free */
1664 }; 1650 };
LEFTRIGHT

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