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

Side by Side Diff: Modules/_operator.c

Issue 29259: Add tp_fastcall to PyTypeObject: support FASTCALL calling convention for all callable objects
Patch Set: Created 3 years, 4 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
« no previous file with comments | « Lib/test/test_sys.py ('k') | Objects/abstract.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 #include "Python.h" 2 #include "Python.h"
3 3
4 PyDoc_STRVAR(operator_doc, 4 PyDoc_STRVAR(operator_doc,
5 "Operator interface.\n\ 5 "Operator interface.\n\
6 \n\ 6 \n\
7 This module exports a set of functions implemented in C corresponding\n\ 7 This module exports a set of functions implemented in C corresponding\n\
8 to the intrinsic operators of Python. For example, operator.add(x, y)\n\ 8 to the intrinsic operators of Python. For example, operator.add(x, y)\n\
9 is equivalent to the expression x+y. The function names are those\n\ 9 is equivalent to the expression x+y. The function names are those\n\
10 used for special methods; variants without leading and trailing\n\ 10 used for special methods; variants without leading and trailing\n\
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 448 }
449 449
450 static int 450 static int
451 itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) 451 itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
452 { 452 {
453 Py_VISIT(ig->item); 453 Py_VISIT(ig->item);
454 return 0; 454 return 0;
455 } 455 }
456 456
457 static PyObject * 457 static PyObject *
458 itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) 458 itemgetter_call(itemgetterobject *ig, PyObject **args, Py_ssize_t nargs,
459 PyObject *kwnames)
459 { 460 {
460 PyObject *obj, *result; 461 PyObject *obj, *result;
461 Py_ssize_t i, nitems=ig->nitems; 462 Py_ssize_t i, nitems=ig->nitems;
462 463
463 if (kw != NULL && !_PyArg_NoKeywords("itemgetter", kw)) 464 if (kwnames != NULL && !_PyArg_NoStackKeywords("itemgetter", kwnames)) {
464 return NULL; 465 return NULL;
465 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj)) 466 }
467 if (!_PyArg_UnpackStack(args, nargs, "itemgetter", 1, 1, &obj)) {
466 return NULL; 468 return NULL;
467 if (nitems == 1) 469 }
470 if (nitems == 1) {
468 return PyObject_GetItem(obj, ig->item); 471 return PyObject_GetItem(obj, ig->item);
472 }
469 473
470 assert(PyTuple_Check(ig->item)); 474 assert(PyTuple_Check(ig->item));
471 assert(PyTuple_GET_SIZE(ig->item) == nitems); 475 assert(PyTuple_GET_SIZE(ig->item) == nitems);
472 476
473 result = PyTuple_New(nitems); 477 result = PyTuple_New(nitems);
474 if (result == NULL) 478 if (result == NULL) {
475 return NULL; 479 return NULL;
480 }
476 481
477 for (i=0 ; i < nitems ; i++) { 482 for (i=0 ; i < nitems ; i++) {
478 PyObject *item, *val; 483 PyObject *item, *val;
479 item = PyTuple_GET_ITEM(ig->item, i); 484 item = PyTuple_GET_ITEM(ig->item, i);
480 val = PyObject_GetItem(obj, item); 485 val = PyObject_GetItem(obj, item);
481 if (val == NULL) { 486 if (val == NULL) {
482 Py_DECREF(result); 487 Py_DECREF(result);
483 return NULL; 488 return NULL;
484 } 489 }
485 PyTuple_SET_ITEM(result, i, val); 490 PyTuple_SET_ITEM(result, i, val);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 (destructor)itemgetter_dealloc, /* tp_dealloc */ 543 (destructor)itemgetter_dealloc, /* tp_dealloc */
539 0, /* tp_print */ 544 0, /* tp_print */
540 0, /* tp_getattr */ 545 0, /* tp_getattr */
541 0, /* tp_setattr */ 546 0, /* tp_setattr */
542 0, /* tp_reserved */ 547 0, /* tp_reserved */
543 (reprfunc)itemgetter_repr, /* tp_repr */ 548 (reprfunc)itemgetter_repr, /* tp_repr */
544 0, /* tp_as_number */ 549 0, /* tp_as_number */
545 0, /* tp_as_sequence */ 550 0, /* tp_as_sequence */
546 0, /* tp_as_mapping */ 551 0, /* tp_as_mapping */
547 0, /* tp_hash */ 552 0, /* tp_hash */
548 (ternaryfunc)itemgetter_call, /* tp_call */ 553 0, /* tp_call */
549 0, /* tp_str */ 554 0, /* tp_str */
550 PyObject_GenericGetAttr, /* tp_getattro */ 555 PyObject_GenericGetAttr, /* tp_getattro */
551 0, /* tp_setattro */ 556 0, /* tp_setattro */
552 0, /* tp_as_buffer */ 557 0, /* tp_as_buffer */
553 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 558 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
554 itemgetter_doc, /* tp_doc */ 559 itemgetter_doc, /* tp_doc */
555 (traverseproc)itemgetter_traverse, /* tp_traverse */ 560 (traverseproc)itemgetter_traverse, /* tp_traverse */
556 0, /* tp_clear */ 561 0, /* tp_clear */
557 0, /* tp_richcompare */ 562 0, /* tp_richcompare */
558 0, /* tp_weaklistoffset */ 563 0, /* tp_weaklistoffset */
559 0, /* tp_iter */ 564 0, /* tp_iter */
560 0, /* tp_iternext */ 565 0, /* tp_iternext */
561 itemgetter_methods, /* tp_methods */ 566 itemgetter_methods, /* tp_methods */
562 0, /* tp_members */ 567 0, /* tp_members */
563 0, /* tp_getset */ 568 0, /* tp_getset */
564 0, /* tp_base */ 569 0, /* tp_base */
565 0, /* tp_dict */ 570 0, /* tp_dict */
566 0, /* tp_descr_get */ 571 0, /* tp_descr_get */
567 0, /* tp_descr_set */ 572 0, /* tp_descr_set */
568 0, /* tp_dictoffset */ 573 0, /* tp_dictoffset */
569 0, /* tp_init */ 574 0, /* tp_init */
570 0, /* tp_alloc */ 575 0, /* tp_alloc */
571 itemgetter_new, /* tp_new */ 576 itemgetter_new, /* tp_new */
572 0, /* tp_free */ 577
578 .tp_fastcall = (fastternaryfunc)itemgetter_call,
573 }; 579 };
574 580
575 581
576 /* attrgetter object **********************************************************/ 582 /* attrgetter object **********************************************************/
577 583
578 typedef struct { 584 typedef struct {
579 PyObject_HEAD 585 PyObject_HEAD
580 Py_ssize_t nattrs; 586 Py_ssize_t nattrs;
581 PyObject *attr; 587 PyObject *attr;
582 } attrgetterobject; 588 } attrgetterobject;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 newobj = PyObject_GetAttr(obj, attr); 743 newobj = PyObject_GetAttr(obj, attr);
738 if (newobj == NULL) 744 if (newobj == NULL)
739 return NULL; 745 return NULL;
740 obj = newobj; 746 obj = newobj;
741 } 747 }
742 748
743 return obj; 749 return obj;
744 } 750 }
745 751
746 static PyObject * 752 static PyObject *
747 attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) 753 attrgetter_call(attrgetterobject *ag, PyObject **args, Py_ssize_t nargs,
754 PyObject *kwnames)
748 { 755 {
749 PyObject *obj, *result; 756 PyObject *obj, *result;
750 Py_ssize_t i, nattrs=ag->nattrs; 757 Py_ssize_t i, nattrs=ag->nattrs;
751 758
752 if (kw != NULL && !_PyArg_NoKeywords("attrgetter", kw)) 759 if (kwnames != NULL && !_PyArg_NoStackKeywords("attrgetter", kwnames)) {
753 return NULL; 760 return NULL;
754 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj)) 761 }
762 if (!_PyArg_UnpackStack(args, nargs, "attrgetter", 1, 1, &obj)) {
755 return NULL; 763 return NULL;
756 if (ag->nattrs == 1) /* ag->attr is always a tuple */ 764 }
765 /* ag->attr is always a tuple */
766 if (ag->nattrs == 1) {
757 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0)); 767 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
768 }
758 769
759 assert(PyTuple_Check(ag->attr)); 770 assert(PyTuple_Check(ag->attr));
760 assert(PyTuple_GET_SIZE(ag->attr) == nattrs); 771 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
761 772
762 result = PyTuple_New(nattrs); 773 result = PyTuple_New(nattrs);
763 if (result == NULL) 774 if (result == NULL) {
764 return NULL; 775 return NULL;
776 }
765 777
766 for (i=0 ; i < nattrs ; i++) { 778 for (i=0 ; i < nattrs ; i++) {
767 PyObject *attr, *val; 779 PyObject *attr, *val;
768 attr = PyTuple_GET_ITEM(ag->attr, i); 780 attr = PyTuple_GET_ITEM(ag->attr, i);
769 val = dotted_getattr(obj, attr); 781 val = dotted_getattr(obj, attr);
770 if (val == NULL) { 782 if (val == NULL) {
771 Py_DECREF(result); 783 Py_DECREF(result);
772 return NULL; 784 return NULL;
773 } 785 }
774 PyTuple_SET_ITEM(result, i, val); 786 PyTuple_SET_ITEM(result, i, val);
775 } 787 }
776 return result; 788 return result;
777 } 789 }
790
778 791
779 static PyObject * 792 static PyObject *
780 dotjoinattr(PyObject *attr, PyObject **attrsep) 793 dotjoinattr(PyObject *attr, PyObject **attrsep)
781 { 794 {
782 if (PyTuple_CheckExact(attr)) { 795 if (PyTuple_CheckExact(attr)) {
783 if (*attrsep == NULL) { 796 if (*attrsep == NULL) {
784 *attrsep = PyUnicode_FromString("."); 797 *attrsep = PyUnicode_FromString(".");
785 if (*attrsep == NULL) 798 if (*attrsep == NULL)
786 return NULL; 799 return NULL;
787 } 800 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 (destructor)attrgetter_dealloc, /* tp_dealloc */ 894 (destructor)attrgetter_dealloc, /* tp_dealloc */
882 0, /* tp_print */ 895 0, /* tp_print */
883 0, /* tp_getattr */ 896 0, /* tp_getattr */
884 0, /* tp_setattr */ 897 0, /* tp_setattr */
885 0, /* tp_reserved */ 898 0, /* tp_reserved */
886 (reprfunc)attrgetter_repr, /* tp_repr */ 899 (reprfunc)attrgetter_repr, /* tp_repr */
887 0, /* tp_as_number */ 900 0, /* tp_as_number */
888 0, /* tp_as_sequence */ 901 0, /* tp_as_sequence */
889 0, /* tp_as_mapping */ 902 0, /* tp_as_mapping */
890 0, /* tp_hash */ 903 0, /* tp_hash */
891 (ternaryfunc)attrgetter_call, /* tp_call */ 904 0, /* tp_call */
892 0, /* tp_str */ 905 0, /* tp_str */
893 PyObject_GenericGetAttr, /* tp_getattro */ 906 PyObject_GenericGetAttr, /* tp_getattro */
894 0, /* tp_setattro */ 907 0, /* tp_setattro */
895 0, /* tp_as_buffer */ 908 0, /* tp_as_buffer */
896 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 909 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
897 attrgetter_doc, /* tp_doc */ 910 attrgetter_doc, /* tp_doc */
898 (traverseproc)attrgetter_traverse, /* tp_traverse */ 911 (traverseproc)attrgetter_traverse, /* tp_traverse */
899 0, /* tp_clear */ 912 0, /* tp_clear */
900 0, /* tp_richcompare */ 913 0, /* tp_richcompare */
901 0, /* tp_weaklistoffset */ 914 0, /* tp_weaklistoffset */
902 0, /* tp_iter */ 915 0, /* tp_iter */
903 0, /* tp_iternext */ 916 0, /* tp_iternext */
904 attrgetter_methods, /* tp_methods */ 917 attrgetter_methods, /* tp_methods */
905 0, /* tp_members */ 918 0, /* tp_members */
906 0, /* tp_getset */ 919 0, /* tp_getset */
907 0, /* tp_base */ 920 0, /* tp_base */
908 0, /* tp_dict */ 921 0, /* tp_dict */
909 0, /* tp_descr_get */ 922 0, /* tp_descr_get */
910 0, /* tp_descr_set */ 923 0, /* tp_descr_set */
911 0, /* tp_dictoffset */ 924 0, /* tp_dictoffset */
912 0, /* tp_init */ 925 0, /* tp_init */
913 0, /* tp_alloc */ 926 0, /* tp_alloc */
914 attrgetter_new, /* tp_new */ 927 attrgetter_new, /* tp_new */
915 0, /* tp_free */ 928
929 .tp_fastcall = (fastternaryfunc)attrgetter_call,
916 }; 930 };
917 931
918 932
919 /* methodcaller object ********************************************************* */ 933 /* methodcaller object ********************************************************* */
920 934
921 typedef struct { 935 typedef struct {
922 PyObject_HEAD 936 PyObject_HEAD
923 PyObject *name; 937 PyObject *name;
924 PyObject *args; 938 PyObject *args;
925 PyObject *kwds; 939 PyObject *kwds;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 995
982 static int 996 static int
983 methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) 997 methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
984 { 998 {
985 Py_VISIT(mc->args); 999 Py_VISIT(mc->args);
986 Py_VISIT(mc->kwds); 1000 Py_VISIT(mc->kwds);
987 return 0; 1001 return 0;
988 } 1002 }
989 1003
990 static PyObject * 1004 static PyObject *
991 methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) 1005 methodcaller_call(methodcallerobject *mc, PyObject **args,
1006 Py_ssize_t nargs, PyObject *kwnames)
992 { 1007 {
993 PyObject *method, *obj, *result; 1008 PyObject *method, *obj, *result;
994 1009
995 if (kw != NULL && !_PyArg_NoKeywords("methodcaller", kw)) 1010 if (kwnames != NULL && !_PyArg_NoStackKeywords("methodcaller", kwnames))
996 return NULL; 1011 return NULL;
997 if (!PyArg_UnpackTuple(args, "methodcaller", 1, 1, &obj)) 1012 if (!_PyArg_UnpackStack(args, nargs, "methodcaller", 1, 1, &obj))
998 return NULL; 1013 return NULL;
999 method = PyObject_GetAttr(obj, mc->name); 1014 method = PyObject_GetAttr(obj, mc->name);
1000 if (method == NULL) 1015 if (method == NULL)
1001 return NULL; 1016 return NULL;
1002 result = PyObject_Call(method, mc->args, mc->kwds); 1017 result = PyObject_Call(method, mc->args, mc->kwds);
1003 Py_DECREF(method); 1018 Py_DECREF(method);
1004 return result; 1019 return result;
1005 } 1020 }
1006 1021
1007 static PyObject * 1022 static PyObject *
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 (destructor)methodcaller_dealloc, /* tp_dealloc */ 1159 (destructor)methodcaller_dealloc, /* tp_dealloc */
1145 0, /* tp_print */ 1160 0, /* tp_print */
1146 0, /* tp_getattr */ 1161 0, /* tp_getattr */
1147 0, /* tp_setattr */ 1162 0, /* tp_setattr */
1148 0, /* tp_reserved */ 1163 0, /* tp_reserved */
1149 (reprfunc)methodcaller_repr, /* tp_repr */ 1164 (reprfunc)methodcaller_repr, /* tp_repr */
1150 0, /* tp_as_number */ 1165 0, /* tp_as_number */
1151 0, /* tp_as_sequence */ 1166 0, /* tp_as_sequence */
1152 0, /* tp_as_mapping */ 1167 0, /* tp_as_mapping */
1153 0, /* tp_hash */ 1168 0, /* tp_hash */
1154 (ternaryfunc)methodcaller_call, /* tp_call */ 1169 0, /* tp_call */
1155 0, /* tp_str */ 1170 0, /* tp_str */
1156 PyObject_GenericGetAttr, /* tp_getattro */ 1171 PyObject_GenericGetAttr, /* tp_getattro */
1157 0, /* tp_setattro */ 1172 0, /* tp_setattro */
1158 0, /* tp_as_buffer */ 1173 0, /* tp_as_buffer */
1159 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 1174 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1160 methodcaller_doc, /* tp_doc */ 1175 methodcaller_doc, /* tp_doc */
1161 (traverseproc)methodcaller_traverse, /* tp_traverse */ 1176 (traverseproc)methodcaller_traverse, /* tp_traverse */
1162 0, /* tp_clear */ 1177 0, /* tp_clear */
1163 0, /* tp_richcompare */ 1178 0, /* tp_richcompare */
1164 0, /* tp_weaklistoffset */ 1179 0, /* tp_weaklistoffset */
1165 0, /* tp_iter */ 1180 0, /* tp_iter */
1166 0, /* tp_iternext */ 1181 0, /* tp_iternext */
1167 methodcaller_methods, /* tp_methods */ 1182 methodcaller_methods, /* tp_methods */
1168 0, /* tp_members */ 1183 0, /* tp_members */
1169 0, /* tp_getset */ 1184 0, /* tp_getset */
1170 0, /* tp_base */ 1185 0, /* tp_base */
1171 0, /* tp_dict */ 1186 0, /* tp_dict */
1172 0, /* tp_descr_get */ 1187 0, /* tp_descr_get */
1173 0, /* tp_descr_set */ 1188 0, /* tp_descr_set */
1174 0, /* tp_dictoffset */ 1189 0, /* tp_dictoffset */
1175 0, /* tp_init */ 1190 0, /* tp_init */
1176 0, /* tp_alloc */ 1191 0, /* tp_alloc */
1177 methodcaller_new, /* tp_new */ 1192 methodcaller_new, /* tp_new */
1178 0, /* tp_free */ 1193
1194 .tp_fastcall = (fastternaryfunc)methodcaller_call,
1179 }; 1195 };
1180 1196
1181 1197
1182 /* Initialization function for the module (*must* be called PyInit__operator) */ 1198 /* Initialization function for the module (*must* be called PyInit__operator) */
1183 1199
1184 1200
1185 static struct PyModuleDef operatormodule = { 1201 static struct PyModuleDef operatormodule = {
1186 PyModuleDef_HEAD_INIT, 1202 PyModuleDef_HEAD_INIT,
1187 "_operator", 1203 "_operator",
1188 operator_doc, 1204 operator_doc,
(...skipping 24 matching lines...) Expand all
1213 return NULL; 1229 return NULL;
1214 Py_INCREF(&attrgetter_type); 1230 Py_INCREF(&attrgetter_type);
1215 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type); 1231 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
1216 1232
1217 if (PyType_Ready(&methodcaller_type) < 0) 1233 if (PyType_Ready(&methodcaller_type) < 0)
1218 return NULL; 1234 return NULL;
1219 Py_INCREF(&methodcaller_type); 1235 Py_INCREF(&methodcaller_type);
1220 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type); 1236 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
1221 return m; 1237 return m;
1222 } 1238 }
OLDNEW
« no previous file with comments | « Lib/test/test_sys.py ('k') | Objects/abstract.c » ('j') | no next file with comments »

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