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

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 3 years 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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 {"__doc__", (getter)method_get_doc}, 403 {"__doc__", (getter)method_get_doc},
404 {"__qualname__", (getter)descr_get_qualname}, 404 {"__qualname__", (getter)descr_get_qualname},
405 {"__text_signature__", (getter)method_get_text_signature}, 405 {"__text_signature__", (getter)method_get_text_signature},
406 {0} 406 {0}
407 }; 407 };
408 408
409 static PyObject * 409 static PyObject *
410 member_get_doc(PyMemberDescrObject *descr, void *closure) 410 member_get_doc(PyMemberDescrObject *descr, void *closure)
411 { 411 {
412 if (descr->d_member->doc == NULL) { 412 if (descr->d_member->doc == NULL) {
413 Py_INCREF(Py_None); 413 Py_RETURN_NONE;
414 return Py_None;
415 } 414 }
416 return PyUnicode_FromString(descr->d_member->doc); 415 return PyUnicode_FromString(descr->d_member->doc);
417 } 416 }
418 417
419 static PyGetSetDef member_getset[] = { 418 static PyGetSetDef member_getset[] = {
420 {"__doc__", (getter)member_get_doc}, 419 {"__doc__", (getter)member_get_doc},
421 {"__qualname__", (getter)descr_get_qualname}, 420 {"__qualname__", (getter)descr_get_qualname},
422 {0} 421 {0}
423 }; 422 };
424 423
425 static PyObject * 424 static PyObject *
426 getset_get_doc(PyGetSetDescrObject *descr, void *closure) 425 getset_get_doc(PyGetSetDescrObject *descr, void *closure)
427 { 426 {
428 if (descr->d_getset->doc == NULL) { 427 if (descr->d_getset->doc == NULL) {
429 Py_INCREF(Py_None); 428 Py_RETURN_NONE;
430 return Py_None;
431 } 429 }
432 return PyUnicode_FromString(descr->d_getset->doc); 430 return PyUnicode_FromString(descr->d_getset->doc);
433 } 431 }
434 432
435 static PyGetSetDef getset_getset[] = { 433 static PyGetSetDef getset_getset[] = {
436 {"__doc__", (getter)getset_get_doc}, 434 {"__doc__", (getter)getset_get_doc},
437 {"__qualname__", (getter)descr_get_qualname}, 435 {"__qualname__", (getter)descr_get_qualname},
438 {0} 436 {0}
439 }; 437 };
440 438
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 (reprfunc)method_repr, /* tp_repr */ 515 (reprfunc)method_repr, /* tp_repr */
518 0, /* tp_as_number */ 516 0, /* tp_as_number */
519 0, /* tp_as_sequence */ 517 0, /* tp_as_sequence */
520 0, /* tp_as_mapping */ 518 0, /* tp_as_mapping */
521 0, /* tp_hash */ 519 0, /* tp_hash */
522 0, /* tp_call */ 520 0, /* tp_call */
523 0, /* tp_str */ 521 0, /* tp_str */
524 PyObject_GenericGetAttr, /* tp_getattro */ 522 PyObject_GenericGetAttr, /* tp_getattro */
525 0, /* tp_setattro */ 523 0, /* tp_setattro */
526 0, /* tp_as_buffer */ 524 0, /* tp_as_buffer */
527 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC 525 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
528 | Py_TPFLAGS_HAVE_FASTCALL, /* tp_flags */
inada.naoki 2017/01/20 05:23:39 PyMethodDescr_Type didn't change tp_flags. Consist
haypo 2017/01/20 09:08:40 Oh, I forgot to revert this change after I added F
529 0, /* tp_doc */ 526 0, /* tp_doc */
530 descr_traverse, /* tp_traverse */ 527 descr_traverse, /* tp_traverse */
531 0, /* tp_clear */ 528 0, /* tp_clear */
532 0, /* tp_richcompare */ 529 0, /* tp_richcompare */
533 0, /* tp_weaklistoffset */ 530 0, /* tp_weaklistoffset */
534 0, /* tp_iter */ 531 0, /* tp_iter */
535 0, /* tp_iternext */ 532 0, /* tp_iternext */
536 descr_methods, /* tp_methods */ 533 descr_methods, /* tp_methods */
537 descr_members, /* tp_members */ 534 descr_members, /* tp_members */
538 method_getset, /* tp_getset */ 535 method_getset, /* tp_getset */
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 651
655 .tp_fastcall = (fastternaryfunc)wrapperdescr_call, 652 .tp_fastcall = (fastternaryfunc)wrapperdescr_call,
656 }; 653 };
657 654
658 static PyDescrObject * 655 static PyDescrObject *
659 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) 656 descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name)
660 { 657 {
661 PyDescrObject *descr; 658 PyDescrObject *descr;
662 659
663 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); 660 descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0);
664 if (descr != NULL) { 661 if (descr == NULL) {
665 Py_XINCREF(type); 662 return NULL;
666 descr->d_type = type; 663 }
667 descr->d_name = PyUnicode_InternFromString(name); 664
668 if (descr->d_name == NULL) { 665 Py_XINCREF(type);
669 Py_DECREF(descr); 666 descr->d_type = type;
670 descr = NULL; 667 descr->d_name = PyUnicode_InternFromString(name);
671 } 668 if (descr->d_name == NULL) {
672 else { 669 Py_DECREF(descr);
673 descr->d_qualname = NULL; 670 descr = NULL;
674 } 671 }
672 else {
673 descr->d_qualname = NULL;
675 } 674 }
676 return descr; 675 return descr;
677 } 676 }
678 677
679 PyObject * 678 PyObject *
680 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method) 679 PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
681 { 680 {
682 PyMethodDescrObject *descr; 681 PyMethodDescrObject *descr;
683 682
684 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
718 PyGetSetDescrObject *descr; 717 PyGetSetDescrObject *descr;
719 718
720 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type, 719 descr = (PyGetSetDescrObject *)descr_new(&PyGetSetDescr_Type,
721 type, getset->name); 720 type, getset->name);
722 if (descr != NULL) 721 if (descr != NULL)
723 descr->d_getset = getset; 722 descr->d_getset = getset;
724 return (PyObject *)descr; 723 return (PyObject *)descr;
725 } 724 }
726 725
727 PyObject * 726 PyObject *
728 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
729 { 728 {
730 PyWrapperDescrObject *descr; 729 PyWrapperDescrObject *descr;
731 730
732 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type, 731 descr = (PyWrapperDescrObject *)descr_new(&PyWrapperDescr_Type,
733 type, base->name); 732 type, base->name);
734 if (descr != NULL) { 733 if (descr == NULL) {
735 descr->d_base = base; 734 return NULL;
736 descr->d_wrapped = wrapped; 735 }
737 } 736
737 descr->d_base = base;
738 descr->d_wrapped = wrapped;
739 descr->d_use_fastwrapper = use_fastwrapper;
738 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);
739 } 747 }
740 748
741 749
742 /* --- mappingproxy: read-only proxy for mappings --- */ 750 /* --- mappingproxy: read-only proxy for mappings --- */
743 751
744 /* 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
745 bit of a pain */ 753 bit of a pain */
746 754
747 typedef struct { 755 typedef struct {
748 PyObject_HEAD 756 PyObject_HEAD
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 static PyGetSetDef wrapper_getsets[] = { 1157 static PyGetSetDef wrapper_getsets[] = {
1150 {"__objclass__", (getter)wrapper_objclass}, 1158 {"__objclass__", (getter)wrapper_objclass},
1151 {"__name__", (getter)wrapper_name}, 1159 {"__name__", (getter)wrapper_name},
1152 {"__qualname__", (getter)wrapper_qualname}, 1160 {"__qualname__", (getter)wrapper_qualname},
1153 {"__doc__", (getter)wrapper_doc}, 1161 {"__doc__", (getter)wrapper_doc},
1154 {"__text_signature__", (getter)wrapper_text_signature}, 1162 {"__text_signature__", (getter)wrapper_text_signature},
1155 {0} 1163 {0}
1156 }; 1164 };
1157 1165
1158 static PyObject * 1166 static PyObject *
1159 wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) 1167 wrapper_call(wrapperobject *wp, PyObject **stack, Py_ssize_t nargs, PyObject *kw names)
1160 { 1168 {
1161 wrapperfunc wrapper = wp->descr->d_base->wrapper; 1169 wrapperfunc wrapper;
1162 PyObject *self = wp->self; 1170 PyObject *self = wp->self;
1163 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;
1164 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) { 1180 if (wp->descr->d_base->flags & PyWrapperFlag_KEYWORDS) {
1165 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; 1181 wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
1166 return (*wk)(self, args, wp->descr->d_wrapped, kwds); 1182
1167 } 1183 if (_PyStack_AsTupleAndDict(stack, nargs, kwnames, &args, &kwargs) < 0) {
1168 1184 return NULL;
1169 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) {
1170 PyErr_Format(PyExc_TypeError, 1195 PyErr_Format(PyExc_TypeError,
1171 "wrapper %s doesn't take keyword arguments", 1196 "wrapper %s doesn't take keyword arguments",
1172 wp->descr->d_base->name); 1197 wp->descr->d_base->name);
1173 return NULL; 1198 return NULL;
1174 } 1199 }
1175 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;
1176 } 1209 }
1177 1210
1178 static int 1211 static int
1179 wrapper_traverse(PyObject *self, visitproc visit, void *arg) 1212 wrapper_traverse(PyObject *self, visitproc visit, void *arg)
1180 { 1213 {
1181 wrapperobject *wp = (wrapperobject *)self; 1214 wrapperobject *wp = (wrapperobject *)self;
1182 Py_VISIT(wp->descr); 1215 Py_VISIT(wp->descr);
1183 Py_VISIT(wp->self); 1216 Py_VISIT(wp->self);
1184 return 0; 1217 return 0;
1185 } 1218 }
1186 1219
1187 PyTypeObject _PyMethodWrapper_Type = { 1220 PyTypeObject _PyMethodWrapper_Type = {
1188 PyVarObject_HEAD_INIT(&PyType_Type, 0) 1221 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1189 "method-wrapper", /* tp_name */ 1222 "method-wrapper", /* tp_name */
1190 sizeof(wrapperobject), /* tp_basicsize */ 1223 sizeof(wrapperobject), /* tp_basicsize */
1191 0, /* tp_itemsize */ 1224 0, /* tp_itemsize */
1192 /* methods */ 1225 /* methods */
1193 (destructor)wrapper_dealloc, /* tp_dealloc */ 1226 (destructor)wrapper_dealloc, /* tp_dealloc */
1194 0, /* tp_print */ 1227 0, /* tp_print */
1195 0, /* tp_getattr */ 1228 0, /* tp_getattr */
1196 0, /* tp_setattr */ 1229 0, /* tp_setattr */
1197 0, /* tp_reserved */ 1230 0, /* tp_reserved */
1198 (reprfunc)wrapper_repr, /* tp_repr */ 1231 (reprfunc)wrapper_repr, /* tp_repr */
1199 0, /* tp_as_number */ 1232 0, /* tp_as_number */
1200 0, /* tp_as_sequence */ 1233 0, /* tp_as_sequence */
1201 0, /* tp_as_mapping */ 1234 0, /* tp_as_mapping */
1202 (hashfunc)wrapper_hash, /* tp_hash */ 1235 (hashfunc)wrapper_hash, /* tp_hash */
1203 (ternaryfunc)wrapper_call, /* tp_call */ 1236 0, /* tp_call */
1204 0, /* tp_str */ 1237 0, /* tp_str */
1205 PyObject_GenericGetAttr, /* tp_getattro */ 1238 PyObject_GenericGetAttr, /* tp_getattro */
1206 0, /* tp_setattro */ 1239 0, /* tp_setattro */
1207 0, /* tp_as_buffer */ 1240 0, /* tp_as_buffer */
1208 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1209 0, /* tp_doc */ 1242 0, /* tp_doc */
1210 wrapper_traverse, /* tp_traverse */ 1243 wrapper_traverse, /* tp_traverse */
1211 0, /* tp_clear */ 1244 0, /* tp_clear */
1212 wrapper_richcompare, /* tp_richcompare */ 1245 wrapper_richcompare, /* tp_richcompare */
1213 0, /* tp_weaklistoffset */ 1246 0, /* tp_weaklistoffset */
1214 0, /* tp_iter */ 1247 0, /* tp_iter */
1215 0, /* tp_iternext */ 1248 0, /* tp_iternext */
1216 wrapper_methods, /* tp_methods */ 1249 wrapper_methods, /* tp_methods */
1217 wrapper_members, /* tp_members */ 1250 wrapper_members, /* tp_members */
1218 wrapper_getsets, /* tp_getset */ 1251 wrapper_getsets, /* tp_getset */
1219 0, /* tp_base */ 1252
1220 0, /* tp_dict */ 1253 .tp_fastcall = (fastternaryfunc)wrapper_call,
1221 0, /* tp_descr_get */
1222 0, /* tp_descr_set */
1223 }; 1254 };
1224 1255
1225 PyObject * 1256 PyObject *
1226 PyWrapper_New(PyObject *d, PyObject *self) 1257 PyWrapper_New(PyObject *d, PyObject *self)
1227 { 1258 {
1228 wrapperobject *wp; 1259 wrapperobject *wp;
1229 PyWrapperDescrObject *descr; 1260 PyWrapperDescrObject *descr;
1230 1261
1231 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type)); 1262 assert(PyObject_TypeCheck(d, &PyWrapperDescr_Type));
1232 descr = (PyWrapperDescrObject *)d; 1263 descr = (PyWrapperDescrObject *)d;
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 0, /* tp_base */ 1641 0, /* tp_base */
1611 0, /* tp_dict */ 1642 0, /* tp_dict */
1612 property_descr_get, /* tp_descr_get */ 1643 property_descr_get, /* tp_descr_get */
1613 property_descr_set, /* tp_descr_set */ 1644 property_descr_set, /* tp_descr_set */
1614 0, /* tp_dictoffset */ 1645 0, /* tp_dictoffset */
1615 property_init, /* tp_init */ 1646 property_init, /* tp_init */
1616 PyType_GenericAlloc, /* tp_alloc */ 1647 PyType_GenericAlloc, /* tp_alloc */
1617 PyType_GenericNew, /* tp_new */ 1648 PyType_GenericNew, /* tp_new */
1618 PyObject_GC_Del, /* tp_free */ 1649 PyObject_GC_Del, /* tp_free */
1619 }; 1650 };
LEFTRIGHT

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