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

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 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:
View unified diff | Download patch
OLDNEW
1 1
2 #include "Python.h" 2 #include "Python.h"
3 3
4 #include "clinic/_operator.c.h" 4 #include "clinic/_operator.c.h"
5 5
6 /*[clinic input] 6 /*[clinic input]
7 module _operator 7 module _operator
8 [clinic start generated code]*/ 8 [clinic start generated code]*/
9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/ 9 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=672ecf48487521e7]*/
10 10
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 } 981 }
982 982
983 static int 983 static int
984 itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg) 984 itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
985 { 985 {
986 Py_VISIT(ig->item); 986 Py_VISIT(ig->item);
987 return 0; 987 return 0;
988 } 988 }
989 989
990 static PyObject * 990 static PyObject *
991 itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) 991 itemgetter_call(itemgetterobject *ig, PyObject **args, Py_ssize_t nargs,
992 PyObject *kwnames)
992 { 993 {
993 PyObject *obj, *result; 994 PyObject *obj, *result;
994 Py_ssize_t i, nitems=ig->nitems; 995 Py_ssize_t i, nitems=ig->nitems;
995 996
996 if (kw != NULL && !_PyArg_NoKeywords("itemgetter", kw)) 997 if (kwnames != NULL && !_PyArg_NoStackKeywords("itemgetter", kwnames)) {
997 return NULL; 998 return NULL;
998 if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj)) 999 }
1000 if (!_PyArg_UnpackStack(args, nargs, "itemgetter", 1, 1, &obj)) {
999 return NULL; 1001 return NULL;
1000 if (nitems == 1) 1002 }
1003 if (nitems == 1) {
1001 return PyObject_GetItem(obj, ig->item); 1004 return PyObject_GetItem(obj, ig->item);
1005 }
1002 1006
1003 assert(PyTuple_Check(ig->item)); 1007 assert(PyTuple_Check(ig->item));
1004 assert(PyTuple_GET_SIZE(ig->item) == nitems); 1008 assert(PyTuple_GET_SIZE(ig->item) == nitems);
1005 1009
1006 result = PyTuple_New(nitems); 1010 result = PyTuple_New(nitems);
1007 if (result == NULL) 1011 if (result == NULL) {
1008 return NULL; 1012 return NULL;
1013 }
1009 1014
1010 for (i=0 ; i < nitems ; i++) { 1015 for (i=0 ; i < nitems ; i++) {
1011 PyObject *item, *val; 1016 PyObject *item, *val;
1012 item = PyTuple_GET_ITEM(ig->item, i); 1017 item = PyTuple_GET_ITEM(ig->item, i);
1013 val = PyObject_GetItem(obj, item); 1018 val = PyObject_GetItem(obj, item);
1014 if (val == NULL) { 1019 if (val == NULL) {
1015 Py_DECREF(result); 1020 Py_DECREF(result);
1016 return NULL; 1021 return NULL;
1017 } 1022 }
1018 PyTuple_SET_ITEM(result, i, val); 1023 PyTuple_SET_ITEM(result, i, val);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 (destructor)itemgetter_dealloc, /* tp_dealloc */ 1076 (destructor)itemgetter_dealloc, /* tp_dealloc */
1072 0, /* tp_print */ 1077 0, /* tp_print */
1073 0, /* tp_getattr */ 1078 0, /* tp_getattr */
1074 0, /* tp_setattr */ 1079 0, /* tp_setattr */
1075 0, /* tp_reserved */ 1080 0, /* tp_reserved */
1076 (reprfunc)itemgetter_repr, /* tp_repr */ 1081 (reprfunc)itemgetter_repr, /* tp_repr */
1077 0, /* tp_as_number */ 1082 0, /* tp_as_number */
1078 0, /* tp_as_sequence */ 1083 0, /* tp_as_sequence */
1079 0, /* tp_as_mapping */ 1084 0, /* tp_as_mapping */
1080 0, /* tp_hash */ 1085 0, /* tp_hash */
1081 (ternaryfunc)itemgetter_call, /* tp_call */ 1086 0, /* tp_call */
1082 0, /* tp_str */ 1087 0, /* tp_str */
1083 PyObject_GenericGetAttr, /* tp_getattro */ 1088 PyObject_GenericGetAttr, /* tp_getattro */
1084 0, /* tp_setattro */ 1089 0, /* tp_setattro */
1085 0, /* tp_as_buffer */ 1090 0, /* tp_as_buffer */
1086 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1091 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1087 itemgetter_doc, /* tp_doc */ 1092 itemgetter_doc, /* tp_doc */
1088 (traverseproc)itemgetter_traverse, /* tp_traverse */ 1093 (traverseproc)itemgetter_traverse, /* tp_traverse */
1089 0, /* tp_clear */ 1094 0, /* tp_clear */
1090 0, /* tp_richcompare */ 1095 0, /* tp_richcompare */
1091 0, /* tp_weaklistoffset */ 1096 0, /* tp_weaklistoffset */
1092 0, /* tp_iter */ 1097 0, /* tp_iter */
1093 0, /* tp_iternext */ 1098 0, /* tp_iternext */
1094 itemgetter_methods, /* tp_methods */ 1099 itemgetter_methods, /* tp_methods */
1095 0, /* tp_members */ 1100 0, /* tp_members */
1096 0, /* tp_getset */ 1101 0, /* tp_getset */
1097 0, /* tp_base */ 1102 0, /* tp_base */
1098 0, /* tp_dict */ 1103 0, /* tp_dict */
1099 0, /* tp_descr_get */ 1104 0, /* tp_descr_get */
1100 0, /* tp_descr_set */ 1105 0, /* tp_descr_set */
1101 0, /* tp_dictoffset */ 1106 0, /* tp_dictoffset */
1102 0, /* tp_init */ 1107 0, /* tp_init */
1103 0, /* tp_alloc */ 1108 0, /* tp_alloc */
1104 itemgetter_new, /* tp_new */ 1109 itemgetter_new, /* tp_new */
1105 0, /* tp_free */ 1110
1111 .tp_fastcall = (fastternaryfunc)itemgetter_call,
1106 }; 1112 };
1107 1113
1108 1114
1109 /* attrgetter object **********************************************************/ 1115 /* attrgetter object **********************************************************/
1110 1116
1111 typedef struct { 1117 typedef struct {
1112 PyObject_HEAD 1118 PyObject_HEAD
1113 Py_ssize_t nattrs; 1119 Py_ssize_t nattrs;
1114 PyObject *attr; 1120 PyObject *attr;
1115 } attrgetterobject; 1121 } attrgetterobject;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 newobj = PyObject_GetAttr(obj, attr); 1277 newobj = PyObject_GetAttr(obj, attr);
1272 if (newobj == NULL) 1278 if (newobj == NULL)
1273 return NULL; 1279 return NULL;
1274 obj = newobj; 1280 obj = newobj;
1275 } 1281 }
1276 1282
1277 return obj; 1283 return obj;
1278 } 1284 }
1279 1285
1280 static PyObject * 1286 static PyObject *
1281 attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) 1287 attrgetter_call(attrgetterobject *ag, PyObject **args, Py_ssize_t nargs,
1288 PyObject *kwnames)
1282 { 1289 {
1283 PyObject *obj, *result; 1290 PyObject *obj, *result;
1284 Py_ssize_t i, nattrs=ag->nattrs; 1291 Py_ssize_t i, nattrs=ag->nattrs;
1285 1292
1286 if (kw != NULL && !_PyArg_NoKeywords("attrgetter", kw)) 1293 if (kwnames != NULL && !_PyArg_NoStackKeywords("attrgetter", kwnames)) {
1287 return NULL; 1294 return NULL;
1288 if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj)) 1295 }
1296 if (!_PyArg_UnpackStack(args, nargs, "attrgetter", 1, 1, &obj)) {
1289 return NULL; 1297 return NULL;
1290 if (ag->nattrs == 1) /* ag->attr is always a tuple */ 1298 }
1299 /* ag->attr is always a tuple */
1300 if (ag->nattrs == 1) {
1291 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0)); 1301 return dotted_getattr(obj, PyTuple_GET_ITEM(ag->attr, 0));
1302 }
1292 1303
1293 assert(PyTuple_Check(ag->attr)); 1304 assert(PyTuple_Check(ag->attr));
1294 assert(PyTuple_GET_SIZE(ag->attr) == nattrs); 1305 assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
1295 1306
1296 result = PyTuple_New(nattrs); 1307 result = PyTuple_New(nattrs);
1297 if (result == NULL) 1308 if (result == NULL) {
1298 return NULL; 1309 return NULL;
1310 }
1299 1311
1300 for (i=0 ; i < nattrs ; i++) { 1312 for (i=0 ; i < nattrs ; i++) {
1301 PyObject *attr, *val; 1313 PyObject *attr, *val;
1302 attr = PyTuple_GET_ITEM(ag->attr, i); 1314 attr = PyTuple_GET_ITEM(ag->attr, i);
1303 val = dotted_getattr(obj, attr); 1315 val = dotted_getattr(obj, attr);
1304 if (val == NULL) { 1316 if (val == NULL) {
1305 Py_DECREF(result); 1317 Py_DECREF(result);
1306 return NULL; 1318 return NULL;
1307 } 1319 }
1308 PyTuple_SET_ITEM(result, i, val); 1320 PyTuple_SET_ITEM(result, i, val);
1309 } 1321 }
1310 return result; 1322 return result;
1311 } 1323 }
1324
1312 1325
1313 static PyObject * 1326 static PyObject *
1314 dotjoinattr(PyObject *attr, PyObject **attrsep) 1327 dotjoinattr(PyObject *attr, PyObject **attrsep)
1315 { 1328 {
1316 if (PyTuple_CheckExact(attr)) { 1329 if (PyTuple_CheckExact(attr)) {
1317 if (*attrsep == NULL) { 1330 if (*attrsep == NULL) {
1318 *attrsep = PyUnicode_FromString("."); 1331 *attrsep = PyUnicode_FromString(".");
1319 if (*attrsep == NULL) 1332 if (*attrsep == NULL)
1320 return NULL; 1333 return NULL;
1321 } 1334 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 (destructor)attrgetter_dealloc, /* tp_dealloc */ 1428 (destructor)attrgetter_dealloc, /* tp_dealloc */
1416 0, /* tp_print */ 1429 0, /* tp_print */
1417 0, /* tp_getattr */ 1430 0, /* tp_getattr */
1418 0, /* tp_setattr */ 1431 0, /* tp_setattr */
1419 0, /* tp_reserved */ 1432 0, /* tp_reserved */
1420 (reprfunc)attrgetter_repr, /* tp_repr */ 1433 (reprfunc)attrgetter_repr, /* tp_repr */
1421 0, /* tp_as_number */ 1434 0, /* tp_as_number */
1422 0, /* tp_as_sequence */ 1435 0, /* tp_as_sequence */
1423 0, /* tp_as_mapping */ 1436 0, /* tp_as_mapping */
1424 0, /* tp_hash */ 1437 0, /* tp_hash */
1425 (ternaryfunc)attrgetter_call, /* tp_call */ 1438 0, /* tp_call */
1426 0, /* tp_str */ 1439 0, /* tp_str */
1427 PyObject_GenericGetAttr, /* tp_getattro */ 1440 PyObject_GenericGetAttr, /* tp_getattro */
1428 0, /* tp_setattro */ 1441 0, /* tp_setattro */
1429 0, /* tp_as_buffer */ 1442 0, /* tp_as_buffer */
1430 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 1443 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1431 attrgetter_doc, /* tp_doc */ 1444 attrgetter_doc, /* tp_doc */
1432 (traverseproc)attrgetter_traverse, /* tp_traverse */ 1445 (traverseproc)attrgetter_traverse, /* tp_traverse */
1433 0, /* tp_clear */ 1446 0, /* tp_clear */
1434 0, /* tp_richcompare */ 1447 0, /* tp_richcompare */
1435 0, /* tp_weaklistoffset */ 1448 0, /* tp_weaklistoffset */
1436 0, /* tp_iter */ 1449 0, /* tp_iter */
1437 0, /* tp_iternext */ 1450 0, /* tp_iternext */
1438 attrgetter_methods, /* tp_methods */ 1451 attrgetter_methods, /* tp_methods */
1439 0, /* tp_members */ 1452 0, /* tp_members */
1440 0, /* tp_getset */ 1453 0, /* tp_getset */
1441 0, /* tp_base */ 1454 0, /* tp_base */
1442 0, /* tp_dict */ 1455 0, /* tp_dict */
1443 0, /* tp_descr_get */ 1456 0, /* tp_descr_get */
1444 0, /* tp_descr_set */ 1457 0, /* tp_descr_set */
1445 0, /* tp_dictoffset */ 1458 0, /* tp_dictoffset */
1446 0, /* tp_init */ 1459 0, /* tp_init */
1447 0, /* tp_alloc */ 1460 0, /* tp_alloc */
1448 attrgetter_new, /* tp_new */ 1461 attrgetter_new, /* tp_new */
1449 0, /* tp_free */ 1462
1463 .tp_fastcall = (fastternaryfunc)attrgetter_call,
1450 }; 1464 };
1451 1465
1452 1466
1453 /* methodcaller object ********************************************************* */ 1467 /* methodcaller object ********************************************************* */
1454 1468
1455 typedef struct { 1469 typedef struct {
1456 PyObject_HEAD 1470 PyObject_HEAD
1457 PyObject *name; 1471 PyObject *name;
1458 PyObject *args; 1472 PyObject *args;
1459 PyObject *kwds; 1473 PyObject *kwds;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 1530
1517 static int 1531 static int
1518 methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg) 1532 methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
1519 { 1533 {
1520 Py_VISIT(mc->args); 1534 Py_VISIT(mc->args);
1521 Py_VISIT(mc->kwds); 1535 Py_VISIT(mc->kwds);
1522 return 0; 1536 return 0;
1523 } 1537 }
1524 1538
1525 static PyObject * 1539 static PyObject *
1526 methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) 1540 methodcaller_call(methodcallerobject *mc, PyObject **args,
1541 Py_ssize_t nargs, PyObject *kwnames)
1527 { 1542 {
1528 PyObject *method, *obj, *result; 1543 PyObject *method, *obj, *result;
1529 1544
1530 if (kw != NULL && !_PyArg_NoKeywords("methodcaller", kw)) 1545 if (kwnames != NULL && !_PyArg_NoStackKeywords("methodcaller", kwnames))
1531 return NULL; 1546 return NULL;
1532 if (!PyArg_UnpackTuple(args, "methodcaller", 1, 1, &obj)) 1547 if (!_PyArg_UnpackStack(args, nargs, "methodcaller", 1, 1, &obj))
1533 return NULL; 1548 return NULL;
1534 method = PyObject_GetAttr(obj, mc->name); 1549 method = PyObject_GetAttr(obj, mc->name);
1535 if (method == NULL) 1550 if (method == NULL)
1536 return NULL; 1551 return NULL;
1537 result = PyObject_Call(method, mc->args, mc->kwds); 1552 result = PyObject_Call(method, mc->args, mc->kwds);
1538 Py_DECREF(method); 1553 Py_DECREF(method);
1539 return result; 1554 return result;
1540 } 1555 }
1541 1556
1542 static PyObject * 1557 static PyObject *
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 (destructor)methodcaller_dealloc, /* tp_dealloc */ 1694 (destructor)methodcaller_dealloc, /* tp_dealloc */
1680 0, /* tp_print */ 1695 0, /* tp_print */
1681 0, /* tp_getattr */ 1696 0, /* tp_getattr */
1682 0, /* tp_setattr */ 1697 0, /* tp_setattr */
1683 0, /* tp_reserved */ 1698 0, /* tp_reserved */
1684 (reprfunc)methodcaller_repr, /* tp_repr */ 1699 (reprfunc)methodcaller_repr, /* tp_repr */
1685 0, /* tp_as_number */ 1700 0, /* tp_as_number */
1686 0, /* tp_as_sequence */ 1701 0, /* tp_as_sequence */
1687 0, /* tp_as_mapping */ 1702 0, /* tp_as_mapping */
1688 0, /* tp_hash */ 1703 0, /* tp_hash */
1689 (ternaryfunc)methodcaller_call, /* tp_call */ 1704 0, /* tp_call */
1690 0, /* tp_str */ 1705 0, /* tp_str */
1691 PyObject_GenericGetAttr, /* tp_getattro */ 1706 PyObject_GenericGetAttr, /* tp_getattro */
1692 0, /* tp_setattro */ 1707 0, /* tp_setattro */
1693 0, /* tp_as_buffer */ 1708 0, /* tp_as_buffer */
1694 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 1709 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
1695 methodcaller_doc, /* tp_doc */ 1710 methodcaller_doc, /* tp_doc */
1696 (traverseproc)methodcaller_traverse, /* tp_traverse */ 1711 (traverseproc)methodcaller_traverse, /* tp_traverse */
1697 0, /* tp_clear */ 1712 0, /* tp_clear */
1698 0, /* tp_richcompare */ 1713 0, /* tp_richcompare */
1699 0, /* tp_weaklistoffset */ 1714 0, /* tp_weaklistoffset */
1700 0, /* tp_iter */ 1715 0, /* tp_iter */
1701 0, /* tp_iternext */ 1716 0, /* tp_iternext */
1702 methodcaller_methods, /* tp_methods */ 1717 methodcaller_methods, /* tp_methods */
1703 0, /* tp_members */ 1718 0, /* tp_members */
1704 0, /* tp_getset */ 1719 0, /* tp_getset */
1705 0, /* tp_base */ 1720 0, /* tp_base */
1706 0, /* tp_dict */ 1721 0, /* tp_dict */
1707 0, /* tp_descr_get */ 1722 0, /* tp_descr_get */
1708 0, /* tp_descr_set */ 1723 0, /* tp_descr_set */
1709 0, /* tp_dictoffset */ 1724 0, /* tp_dictoffset */
1710 0, /* tp_init */ 1725 0, /* tp_init */
1711 0, /* tp_alloc */ 1726 0, /* tp_alloc */
1712 methodcaller_new, /* tp_new */ 1727 methodcaller_new, /* tp_new */
1713 0, /* tp_free */ 1728
1729 .tp_fastcall = (fastternaryfunc)methodcaller_call,
1714 }; 1730 };
1715 1731
1716 1732
1717 /* Initialization function for the module (*must* be called PyInit__operator) */ 1733 /* Initialization function for the module (*must* be called PyInit__operator) */
1718 1734
1719 1735
1720 static struct PyModuleDef operatormodule = { 1736 static struct PyModuleDef operatormodule = {
1721 PyModuleDef_HEAD_INIT, 1737 PyModuleDef_HEAD_INIT,
1722 "_operator", 1738 "_operator",
1723 operator_doc, 1739 operator_doc,
(...skipping 24 matching lines...) Expand all
1748 return NULL; 1764 return NULL;
1749 Py_INCREF(&attrgetter_type); 1765 Py_INCREF(&attrgetter_type);
1750 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type); 1766 PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
1751 1767
1752 if (PyType_Ready(&methodcaller_type) < 0) 1768 if (PyType_Ready(&methodcaller_type) < 0)
1753 return NULL; 1769 return NULL;
1754 Py_INCREF(&methodcaller_type); 1770 Py_INCREF(&methodcaller_type);
1755 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type); 1771 PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
1756 return m; 1772 return m;
1757 } 1773 }
OLDNEW
« no previous file with comments | « Lib/test/test_sys.py ('k') | Objects/abstract.c » ('j') | Objects/abstract.c » ('J')

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