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

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, 12 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 PyObject *kwds) 249 Py_ssize_t nargs, PyObject *kwnames)
251 { 250 {
252 Py_ssize_t argc; 251 PyObject *self, *func, *result;
253 PyObject *self, *func, *result, **stack;
254 252
255 /* Make sure that the first argument is acceptable as 'self' */ 253 /* Make sure that the first argument is acceptable as 'self' */
256 assert(PyTuple_Check(args)); 254 if (nargs < 1) {
257 argc = PyTuple_GET_SIZE(args);
258 if (argc < 1) {
259 PyErr_Format(PyExc_TypeError, 255 PyErr_Format(PyExc_TypeError,
260 "descriptor '%V' of '%.100s' " 256 "descriptor '%V' of '%.100s' "
261 "object needs an argument", 257 "object needs an argument",
262 descr_name((PyDescrObject *)descr), "?", 258 descr_name((PyDescrObject *)descr), "?",
263 PyDescr_TYPE(descr)->tp_name); 259 PyDescr_TYPE(descr)->tp_name);
264 return NULL; 260 return NULL;
265 } 261 }
266 self = PyTuple_GET_ITEM(args, 0); 262 self = args[0];
267 if (!PyType_Check(self)) { 263 if (!PyType_Check(self)) {
268 PyErr_Format(PyExc_TypeError, 264 PyErr_Format(PyExc_TypeError,
269 "descriptor '%V' requires a type " 265 "descriptor '%V' requires a type "
270 "but received a '%.100s'", 266 "but received a '%.100s'",
271 descr_name((PyDescrObject *)descr), "?", 267 descr_name((PyDescrObject *)descr), "?",
272 PyDescr_TYPE(descr)->tp_name, 268 PyDescr_TYPE(descr)->tp_name,
273 self->ob_type->tp_name); 269 self->ob_type->tp_name);
274 return NULL; 270 return NULL;
275 } 271 }
276 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) { 272 if (!PyType_IsSubtype((PyTypeObject *)self, PyDescr_TYPE(descr))) {
277 PyErr_Format(PyExc_TypeError, 273 PyErr_Format(PyExc_TypeError,
278 "descriptor '%V' " 274 "descriptor '%V' "
279 "requires a subtype of '%.100s' " 275 "requires a subtype of '%.100s' "
280 "but received '%.100s", 276 "but received '%.100s",
281 descr_name((PyDescrObject *)descr), "?", 277 descr_name((PyDescrObject *)descr), "?",
282 PyDescr_TYPE(descr)->tp_name, 278 PyDescr_TYPE(descr)->tp_name,
283 self->ob_type->tp_name); 279 self->ob_type->tp_name);
284 return NULL; 280 return NULL;
285 } 281 }
286 282
287 func = PyCFunction_NewEx(descr->d_method, self, NULL); 283 func = PyCFunction_NewEx(descr->d_method, self, NULL);
288 if (func == NULL) 284 if (func == NULL)
289 return NULL; 285 return NULL;
290 stack = &PyTuple_GET_ITEM(args, 1); 286 result = _PyObject_FastCallKeywords(func, args + 1, nargs - 1, kwnames);
291 result = _PyObject_FastCallDict(func, stack, argc - 1, kwds);
292 Py_DECREF(func); 287 Py_DECREF(func);
293 return result; 288 return result;
294 } 289 }
295 290
296 static PyObject * 291 static PyObject *
297 wrapperdescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs, 292 wrapperdescr_call(PyMethodDescrObject *descr, PyObject **args, Py_ssize_t nargs,
298 PyObject *kwnames) 293 PyObject *kwnames)
299 { 294 {
300 PyObject *self, *func, *result; 295 PyObject *self, *func, *result;
301 296
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 {"__doc__", (getter)method_get_doc}, 403 {"__doc__", (getter)method_get_doc},
409 {"__qualname__", (getter)descr_get_qualname}, 404 {"__qualname__", (getter)descr_get_qualname},
410 {"__text_signature__", (getter)method_get_text_signature}, 405 {"__text_signature__", (getter)method_get_text_signature},
411 {0} 406 {0}
412 }; 407 };
413 408
414 static PyObject * 409 static PyObject *
415 member_get_doc(PyMemberDescrObject *descr, void *closure) 410 member_get_doc(PyMemberDescrObject *descr, void *closure)
416 { 411 {
417 if (descr->d_member->doc == NULL) { 412 if (descr->d_member->doc == NULL) {
418 Py_INCREF(Py_None); 413 Py_RETURN_NONE;
419 return Py_None;
420 } 414 }
421 return PyUnicode_FromString(descr->d_member->doc); 415 return PyUnicode_FromString(descr->d_member->doc);
422 } 416 }
423 417
424 static PyGetSetDef member_getset[] = { 418 static PyGetSetDef member_getset[] = {
425 {"__doc__", (getter)member_get_doc}, 419 {"__doc__", (getter)member_get_doc},
426 {"__qualname__", (getter)descr_get_qualname}, 420 {"__qualname__", (getter)descr_get_qualname},
427 {0} 421 {0}
428 }; 422 };
429 423
430 static PyObject * 424 static PyObject *
431 getset_get_doc(PyGetSetDescrObject *descr, void *closure) 425 getset_get_doc(PyGetSetDescrObject *descr, void *closure)
432 { 426 {
433 if (descr->d_getset->doc == NULL) { 427 if (descr->d_getset->doc == NULL) {
434 Py_INCREF(Py_None); 428 Py_RETURN_NONE;
435 return Py_None;
436 } 429 }
437 return PyUnicode_FromString(descr->d_getset->doc); 430 return PyUnicode_FromString(descr->d_getset->doc);
438 } 431 }
439 432
440 static PyGetSetDef getset_getset[] = { 433 static PyGetSetDef getset_getset[] = {
441 {"__doc__", (getter)getset_get_doc}, 434 {"__doc__", (getter)getset_get_doc},
442 {"__qualname__", (getter)descr_get_qualname}, 435 {"__qualname__", (getter)descr_get_qualname},
443 {0} 436 {0}
444 }; 437 };
445 438
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 0, /* tp_richcompare */ 490 0, /* tp_richcompare */
498 0, /* tp_weaklistoffset */ 491 0, /* tp_weaklistoffset */
499 0, /* tp_iter */ 492 0, /* tp_iter */
500 0, /* tp_iternext */ 493 0, /* tp_iternext */
501 descr_methods, /* tp_methods */ 494 descr_methods, /* tp_methods */
502 descr_members, /* tp_members */ 495 descr_members, /* tp_members */
503 method_getset, /* tp_getset */ 496 method_getset, /* tp_getset */
504 0, /* tp_base */ 497 0, /* tp_base */
505 0, /* tp_dict */ 498 0, /* tp_dict */
506 (descrgetfunc)method_get, /* tp_descr_get */ 499 (descrgetfunc)method_get, /* tp_descr_get */
507 0, /* tp_descr_set */ 500
508 0, /* tp_dictoffset */ 501 .tp_fastcall = (fastternaryfunc)methoddescr_call,
509 0, /* tp_init */
510 0, /* tp_alloc */
511 0, /* tp_new */
512 0, /* tp_free */
513 0, /* tp_is_gc */
514 0, /* tp_bases */
515 0, /* tp_mro */
516 0, /* tp_cache */
517 0, /* tp_subclasses */
518 0, /* tp_weaklist */
519 0, /* tp_del */
520 0, /* tp_version_tag */
521 0, /* tp_finalize */
522 (fastternaryfunc)methoddescr_call, /* tp_fastcall */
523 }; 502 };
524 503
525 /* 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! */
526 PyTypeObject PyClassMethodDescr_Type = { 505 PyTypeObject PyClassMethodDescr_Type = {
527 PyVarObject_HEAD_INIT(&PyType_Type, 0) 506 PyVarObject_HEAD_INIT(&PyType_Type, 0)
528 "classmethod_descriptor", 507 "classmethod_descriptor",
529 sizeof(PyMethodDescrObject), 508 sizeof(PyMethodDescrObject),
530 0, 509 0,
531 (destructor)descr_dealloc, /* tp_dealloc */ 510 (destructor)descr_dealloc, /* tp_dealloc */
532 0, /* tp_print */ 511 0, /* tp_print */
533 0, /* tp_getattr */ 512 0, /* tp_getattr */
534 0, /* tp_setattr */ 513 0, /* tp_setattr */
535 0, /* tp_reserved */ 514 0, /* tp_reserved */
536 (reprfunc)method_repr, /* tp_repr */ 515 (reprfunc)method_repr, /* tp_repr */
537 0, /* tp_as_number */ 516 0, /* tp_as_number */
538 0, /* tp_as_sequence */ 517 0, /* tp_as_sequence */
539 0, /* tp_as_mapping */ 518 0, /* tp_as_mapping */
540 0, /* tp_hash */ 519 0, /* tp_hash */
541 (ternaryfunc)classmethoddescr_call, /* tp_call */ 520 0, /* tp_call */
542 0, /* tp_str */ 521 0, /* tp_str */
543 PyObject_GenericGetAttr, /* tp_getattro */ 522 PyObject_GenericGetAttr, /* tp_getattro */
544 0, /* tp_setattro */ 523 0, /* tp_setattro */
545 0, /* tp_as_buffer */ 524 0, /* tp_as_buffer */
546 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
547 0, /* tp_doc */ 526 0, /* tp_doc */
548 descr_traverse, /* tp_traverse */ 527 descr_traverse, /* tp_traverse */
549 0, /* tp_clear */ 528 0, /* tp_clear */
550 0, /* tp_richcompare */ 529 0, /* tp_richcompare */
551 0, /* tp_weaklistoffset */ 530 0, /* tp_weaklistoffset */
552 0, /* tp_iter */ 531 0, /* tp_iter */
553 0, /* tp_iternext */ 532 0, /* tp_iternext */
554 descr_methods, /* tp_methods */ 533 descr_methods, /* tp_methods */
555 descr_members, /* tp_members */ 534 descr_members, /* tp_members */
556 method_getset, /* tp_getset */ 535 method_getset, /* tp_getset */
557 0, /* tp_base */ 536 0, /* tp_base */
558 0, /* tp_dict */ 537 0, /* tp_dict */
559 (descrgetfunc)classmethod_get, /* tp_descr_get */ 538 (descrgetfunc)classmethod_get, /* tp_descr_get */
560 0, /* tp_descr_set */ 539
540 .tp_fastcall = (fastternaryfunc)classmethoddescr_call,
561 }; 541 };
562 542
563 PyTypeObject PyMemberDescr_Type = { 543 PyTypeObject PyMemberDescr_Type = {
564 PyVarObject_HEAD_INIT(&PyType_Type, 0) 544 PyVarObject_HEAD_INIT(&PyType_Type, 0)
565 "member_descriptor", 545 "member_descriptor",
566 sizeof(PyMemberDescrObject), 546 sizeof(PyMemberDescrObject),
567 0, 547 0,
568 (destructor)descr_dealloc, /* tp_dealloc */ 548 (destructor)descr_dealloc, /* tp_dealloc */
569 0, /* tp_print */ 549 0, /* tp_print */
570 0, /* tp_getattr */ 550 0, /* tp_getattr */
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 0, /* tp_richcompare */ 641 0, /* tp_richcompare */
662 0, /* tp_weaklistoffset */ 642 0, /* tp_weaklistoffset */
663 0, /* tp_iter */ 643 0, /* tp_iter */
664 0, /* tp_iternext */ 644 0, /* tp_iternext */
665 descr_methods, /* tp_methods */ 645 descr_methods, /* tp_methods */
666 descr_members, /* tp_members */ 646 descr_members, /* tp_members */
667 wrapperdescr_getset, /* tp_getset */ 647 wrapperdescr_getset, /* tp_getset */
668 0, /* tp_base */ 648 0, /* tp_base */
669 0, /* tp_dict */ 649 0, /* tp_dict */
670 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */ 650 (descrgetfunc)wrapperdescr_get, /* tp_descr_get */
671 0, /* tp_descr_set */ 651
672 0, /* tp_dictoffset */ 652 .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
673 0, /* tp_init */
674 0, /* tp_alloc */
675 0, /* tp_new */
676 0, /* tp_free */
677 0, /* tp_is_gc */
678 0, /* tp_bases */
679 0, /* tp_mro */
680 0, /* tp_cache */
681 0, /* tp_subclasses */
682 0, /* tp_weaklist */
683 0, /* tp_del */
684 0, /* tp_version_tag */
685 0, /* tp_finalize */
686 (fastternaryfunc)wrapperdescr_call, /* tp_fastcall */
687 }; 653 };
688 654
689 static PyDescrObject * 655 static PyDescrObject *
690 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 656 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
691 { 657 {
692 PyDescrObject *descr; 658 PyDescrObject *descr;
693 659
694 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 660 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
695 if (descr != NULL) { 661 if (descr == NULL) {
696 Py_XINCREF(type); 662 return NULL;
697 descr->d_type = type; 663 }
698 descr->d_name = PyUnicode_InternFromString(name); 664
699 if (descr->d_name == NULL) { 665 Py_XINCREF(type);
700 Py_DECREF(descr); 666 descr->d_type = type;
701 descr = NULL; 667 descr->d_name = PyUnicode_InternFromString(name);
702 } 668 if (descr->d_name == NULL) {
703 else { 669 Py_DECREF(descr);
704 descr->d_qualname = NULL; 670 descr = NULL;
705 } 671 }
672 else {
673 descr->d_qualname = NULL;
706 } 674 }
707 return descr; 675 return descr;
708 } 676 }
709 677
710 PyObject * 678 PyObject *
711 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 679 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
712 { 680 {
713 PyMethodDescrObject *descr; 681 PyMethodDescrObject *descr;
714 682
715 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
749 PyGetSetDescrObject *descr; 717 PyGetSetDescrObject *descr;
750 718
751 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 719 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
752 type, getset->name); 720 type, getset->name);
753 if (descr != NULL) 721 if (descr != NULL)
754 descr->d_getset = getset; 722 descr->d_getset = getset;
755 return (PyObject *)descr; 723 return (PyObject *)descr;
756 } 724 }
757 725
758 PyObject * 726 PyObject *
759 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
760 { 728 {
761 PyWrapperDescrObject *descr; 729 PyWrapperDescrObject *descr;
762 730
763 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, 731 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
764 type, base->name); 732 type, base->name);
765 if (descr != NULL) { 733 if (descr == NULL) {
766 descr->d_base = base; 734 return NULL;
767 descr->d_wrapped = wrapped; 735 }
768 } 736
737 descr->d_base = base;
738 descr->d_wrapped = wrapped;
739 descr->d_use_fastwrapper = use_fastwrapper;
769 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);
770 } 747 }
771 748
772 749
773 /* --- mappingproxy: read-only proxy for mappings --- */ 750 /* --- mappingproxy: read-only proxy for mappings --- */
774 751
775 /* 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
776 bit of a pain */ 753 bit of a pain */
777 754
778 typedef struct { 755 typedef struct {
779 PyObject_HEAD 756 PyObject_HEAD
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 static PyGetSetDef wrapper_getsets[] = { 1157 static PyGetSetDef wrapper_getsets[] = {
1181 {"__objclass__", (getter)wrapper_objclass}, 1158 {"__objclass__", (getter)wrapper_objclass},
1182 {"__name__", (getter)wrapper_name}, 1159 {"__name__", (getter)wrapper_name},
1183 {"__qualname__", (getter)wrapper_qualname}, 1160 {"__qualname__", (getter)wrapper_qualname},
1184 {"__doc__", (getter)wrapper_doc}, 1161 {"__doc__", (getter)wrapper_doc},
1185 {"__text_signature__", (getter)wrapper_text_signature}, 1162 {"__text_signature__", (getter)wrapper_text_signature},
1186 {0} 1163 {0}
1187 }; 1164 };
1188 1165
1189 static PyObject * 1166 static PyObject *
1190 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 1167 wrapper_call(wrapperobject *wp, PyObject **stack, Py_ssize_t nargs, PyObject *kw names)
1191 { 1168 {
1192 wrapperfunc wrapper = wp->descr->d_base->wrapper; 1169 wrapperfunc wrapper;
1193 PyObject *self = wp->self; 1170 PyObject *self = wp->self;
1194 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;
1195 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 1180 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
1196 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; 1181 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
1197 return (*wk)(self, args, wp->descr->d_wrapped, kwds); 1182
1198 } 1183 if (_PyStack_AsTupleAndDict(stack, nargs, kwnames, &args, &kwargs) < 0) {
1199 1184 return NULL;
1200 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) {
1201 PyErr_Format(PyExc_TypeError, 1195 PyErr_Format(PyExc_TypeError,
1202 "wrapper %s doesn't take keyword arguments", 1196 "wrapper %s doesn't take keyword arguments",
1203 wp->descr->d_base->name); 1197 wp->descr->d_base->name);
1204 return NULL; 1198 return NULL;
1205 } 1199 }
1206 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;
1207 } 1209 }
1208 1210
1209 static int 1211 static int
1210 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 1212 wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1211 { 1213 {
1212 wrapperobject *wp = (wrapperobject *)self; 1214 wrapperobject *wp = (wrapperobject *)self;
1213 Py_VISIT(wp->descr); 1215 Py_VISIT(wp->descr);
1214 Py_VISIT(wp->self); 1216 Py_VISIT(wp->self);
1215 return 0; 1217 return 0;
1216 } 1218 }
1217 1219
1218 PyTypeObject _PyMethodWrapper_Type = { 1220 PyTypeObject _PyMethodWrapper_Type = {
1219 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1220 "method-wrapper", /* tp_name */ 1222 "method-wrapper", /* tp_name */
1221 sizeof(wrapperobject), /* tp_basicsize */ 1223 sizeof(wrapperobject), /* tp_basicsize */
1222 0, /* tp_itemsize */ 1224 0, /* tp_itemsize */
1223 /* methods */ 1225 /* methods */
1224 (destructor)wrapper_dealloc, /* tp_dealloc */ 1226 (destructor)wrapper_dealloc, /* tp_dealloc */
1225 0, /* tp_print */ 1227 0, /* tp_print */
1226 0, /* tp_getattr */ 1228 0, /* tp_getattr */
1227 0, /* tp_setattr */ 1229 0, /* tp_setattr */
1228 0, /* tp_reserved */ 1230 0, /* tp_reserved */
1229 (reprfunc)wrapper_repr, /* tp_repr */ 1231 (reprfunc)wrapper_repr, /* tp_repr */
1230 0, /* tp_as_number */ 1232 0, /* tp_as_number */
1231 0, /* tp_as_sequence */ 1233 0, /* tp_as_sequence */
1232 0, /* tp_as_mapping */ 1234 0, /* tp_as_mapping */
1233 (hashfunc)wrapper_hash, /* tp_hash */ 1235 (hashfunc)wrapper_hash, /* tp_hash */
1234 (ternaryfunc)wrapper_call, /* tp_call */ 1236 0, /* tp_call */
1235 0, /* tp_str */ 1237 0, /* tp_str */
1236 PyObject_GenericGetAttr, /* tp_getattro */ 1238 PyObject_GenericGetAttr, /* tp_getattro */
1237 0, /* tp_setattro */ 1239 0, /* tp_setattro */
1238 0, /* tp_as_buffer */ 1240 0, /* tp_as_buffer */
1239 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1240 0, /* tp_doc */ 1242 0, /* tp_doc */
1241 wrapper_traverse, /* tp_traverse */ 1243 wrapper_traverse, /* tp_traverse */
1242 0, /* tp_clear */ 1244 0, /* tp_clear */
1243 wrapper_richcompare, /* tp_richcompare */ 1245 wrapper_richcompare, /* tp_richcompare */
1244 0, /* tp_weaklistoffset */ 1246 0, /* tp_weaklistoffset */
1245 0, /* tp_iter */ 1247 0, /* tp_iter */
1246 0, /* tp_iternext */ 1248 0, /* tp_iternext */
1247 wrapper_methods, /* tp_methods */ 1249 wrapper_methods, /* tp_methods */
1248 wrapper_members, /* tp_members */ 1250 wrapper_members, /* tp_members */
1249 wrapper_getsets, /* tp_getset */ 1251 wrapper_getsets, /* tp_getset */
1250 0, /* tp_base */ 1252
1251 0, /* tp_dict */ 1253 .tp_fastcall = (fastternaryfunc)wrapper_call,
1252 0, /* tp_descr_get */
1253 0, /* tp_descr_set */
1254 }; 1254 };
1255 1255
1256 PyObject * 1256 PyObject *
1257 PyWrapper_New(PyObject *d, PyObject *self) 1257 PyWrapper_New(PyObject *d, PyObject *self)
1258 { 1258 {
1259 wrapperobject *wp; 1259 wrapperobject *wp;
1260 PyWrapperDescrObject *descr; 1260 PyWrapperDescrObject *descr;
1261 1261
1262 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1262 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1263 descr = (PyWrapperDescrObject *)d; 1263 descr = (PyWrapperDescrObject *)d;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 Py_XDECREF(gs->prop_get); 1376 Py_XDECREF(gs->prop_get);
1377 Py_XDECREF(gs->prop_set); 1377 Py_XDECREF(gs->prop_set);
1378 Py_XDECREF(gs->prop_del); 1378 Py_XDECREF(gs->prop_del);
1379 Py_XDECREF(gs->prop_doc); 1379 Py_XDECREF(gs->prop_doc);
1380 self->ob_type->tp_free(self); 1380 self->ob_type->tp_free(self);
1381 } 1381 }
1382 1382
1383 static PyObject * 1383 static PyObject *
1384 property_descr_get(PyObject *self, PyObject *obj, PyObject *type) 1384 property_descr_get(PyObject *self, PyObject *obj, PyObject *type)
1385 { 1385 {
1386 static PyObject * volatile cached_args = NULL;
1387 PyObject *ret;
1388 propertyobject *gs = (propertyobject *)self; 1386 propertyobject *gs = (propertyobject *)self;
1387 PyObject *args[1];
1389 1388
1390 if (obj == NULL || obj == Py_None) { 1389 if (obj == NULL || obj == Py_None) {
1391 Py_INCREF(self); 1390 Py_INCREF(self);
1392 return self; 1391 return self;
1393 } 1392 }
1394 if (gs->prop_get == NULL) { 1393 if (gs->prop_get == NULL) {
1395 PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); 1394 PyErr_SetString(PyExc_AttributeError, "unreadable attribute");
1396 return NULL; 1395 return NULL;
1397 } 1396 }
1398 1397
1399 if (Py_TYPE(gs->prop_get)->tp_fastcall) { 1398 args[0] = obj;
1400 PyObject *args[1] = {obj}; 1399 return _PyObject_FastCall(gs->prop_get, args, 1);
1401
1402 ret = _PyObject_FastCall(gs->prop_get, args, 1);
1403 }
1404 else {
1405 PyObject *args;
1406
1407 args = cached_args;
1408 cached_args = NULL;
1409 if (!args) {
1410 args = PyTuple_New(1);
1411 if (!args)
1412 return NULL;
1413 _PyObject_GC_UNTRACK(args);
1414 }
1415 Py_INCREF(obj);
1416 PyTuple_SET_ITEM(args, 0, obj);
1417 ret = PyObject_Call(gs->prop_get, args, NULL);
1418 if (cached_args == NULL && Py_REFCNT(args) == 1) {
1419 assert(Py_SIZE(args) == 1);
1420 assert(PyTuple_GET_ITEM(args, 0) == obj);
1421 cached_args = args;
1422 Py_DECREF(obj);
1423 }
1424 else {
1425 assert(Py_REFCNT(args) >= 1);
1426 _PyObject_GC_TRACK(args);
1427 Py_DECREF(args);
1428 }
1429 }
1430 return ret;
1431 } 1400 }
1432 1401
1433 static int 1402 static int
1434 property_descr_set(PyObject *self, PyObject *obj, PyObject *value) 1403 property_descr_set(PyObject *self, PyObject *obj, PyObject *value)
1435 { 1404 {
1436 propertyobject *gs = (propertyobject *)self; 1405 propertyobject *gs = (propertyobject *)self;
1437 PyObject *func, *res; 1406 PyObject *func, *res;
1438 1407
1439 if (value == NULL) 1408 if (value == NULL)
1440 func = gs->prop_del; 1409 func = gs->prop_del;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 0, /* tp_base */ 1641 0, /* tp_base */
1673 0, /* tp_dict */ 1642 0, /* tp_dict */
1674 property_descr_get, /* tp_descr_get */ 1643 property_descr_get, /* tp_descr_get */
1675 property_descr_set, /* tp_descr_set */ 1644 property_descr_set, /* tp_descr_set */
1676 0, /* tp_dictoffset */ 1645 0, /* tp_dictoffset */
1677 property_init, /* tp_init */ 1646 property_init, /* tp_init */
1678 PyType_GenericAlloc, /* tp_alloc */ 1647 PyType_GenericAlloc, /* tp_alloc */
1679 PyType_GenericNew, /* tp_new */ 1648 PyType_GenericNew, /* tp_new */
1680 PyObject_GC_Del, /* tp_free */ 1649 PyObject_GC_Del, /* tp_free */
1681 }; 1650 };
LEFTRIGHT

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