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

Delta Between Two Patch Sets: Objects/typeobject.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 /* Type object implementation */ 1 /* Type object implementation */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "frameobject.h" 4 #include "frameobject.h"
5 #include "structmember.h" 5 #include "structmember.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 8
9 9
10 /* Support type attribute cache */ 10 /* Support type attribute cache */
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 if ((*doc == *SIGNATURE_END_MARKER) && 114 if ((*doc == *SIGNATURE_END_MARKER) &&
115 !strncmp(doc, SIGNATURE_END_MARKER, SIGNATURE_END_MARKER_LENGTH)) 115 !strncmp(doc, SIGNATURE_END_MARKER, SIGNATURE_END_MARKER_LENGTH))
116 return doc + SIGNATURE_END_MARKER_LENGTH; 116 return doc + SIGNATURE_END_MARKER_LENGTH;
117 if ((*doc == '\n') && (doc[1] == '\n')) 117 if ((*doc == '\n') && (doc[1] == '\n'))
118 return NULL; 118 return NULL;
119 doc++; 119 doc++;
120 } 120 }
121 return NULL; 121 return NULL;
122 } 122 }
123 123
124 #ifdef Py_DEBUG
125 static int
126 _PyType_CheckConsistency(PyTypeObject *type)
127 {
128 if (!(type->tp_flags & Py_TPFLAGS_READY)) {
129 /* don't check types before PyType_Ready() */
130 return 1;
131 }
132
133 assert(!(type->tp_flags & Py_TPFLAGS_READYING));
134 assert(type->tp_mro != NULL && PyTuple_Check(type->tp_mro));
135 assert(type->tp_dict != NULL);
136 return 1;
137 }
138 #endif
139
124 static const char * 140 static const char *
125 _PyType_DocWithoutSignature(const char *name, const char *internal_doc) 141 _PyType_DocWithoutSignature(const char *name, const char *internal_doc)
126 { 142 {
127 const char *doc = find_signature(name, internal_doc); 143 const char *doc = find_signature(name, internal_doc);
128 144
129 if (doc) { 145 if (doc) {
130 doc = skip_signature(doc); 146 doc = skip_signature(doc);
131 if (doc) 147 if (doc)
132 return doc; 148 return doc;
133 } 149 }
134 return internal_doc; 150 return internal_doc;
135 } 151 }
136 152
137 PyObject * 153 PyObject *
138 _PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc) 154 _PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc)
139 { 155 {
140 const char *doc = _PyType_DocWithoutSignature(name, internal_doc); 156 const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
141 157
142 if (!doc || *doc == '\0') { 158 if (!doc || *doc == '\0') {
143 Py_INCREF(Py_None); 159 Py_RETURN_NONE;
144 return Py_None;
145 } 160 }
146 161
147 return PyUnicode_FromString(doc); 162 return PyUnicode_FromString(doc);
148 } 163 }
149 164
150 PyObject * 165 PyObject *
151 _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_d oc) 166 _PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_d oc)
152 { 167 {
153 const char *start = find_signature(name, internal_doc); 168 const char *start = find_signature(name, internal_doc);
154 const char *end; 169 const char *end;
155 170
156 if (start) 171 if (start)
157 end = skip_signature(start); 172 end = skip_signature(start);
158 else 173 else
159 end = NULL; 174 end = NULL;
160 if (!end) { 175 if (!end) {
161 Py_INCREF(Py_None); 176 Py_RETURN_NONE;
162 return Py_None;
163 } 177 }
164 178
165 /* back "end" up until it points just past the final ')' */ 179 /* back "end" up until it points just past the final ')' */
166 end -= SIGNATURE_END_MARKER_LENGTH - 1; 180 end -= SIGNATURE_END_MARKER_LENGTH - 1;
167 assert((end - start) >= 2); /* should be "()" at least */ 181 assert((end - start) >= 2); /* should be "()" at least */
168 assert(end[-1] == ')'); 182 assert(end[-1] == ')');
169 assert(end[0] == '\n'); 183 assert(end[0] == '\n');
170 return PyUnicode_FromStringAndSize(start, end - start); 184 return PyUnicode_FromStringAndSize(start, end - start);
171 } 185 }
172 186
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 /* for now, sod that: just remove from all old_bases, 728 /* for now, sod that: just remove from all old_bases,
715 add to all new_bases */ 729 add to all new_bases */
716 remove_all_subclasses(type, old_bases); 730 remove_all_subclasses(type, old_bases);
717 res = add_all_subclasses(type, new_bases); 731 res = add_all_subclasses(type, new_bases);
718 update_all_slots(type); 732 update_all_slots(type);
719 } 733 }
720 734
721 Py_DECREF(old_bases); 735 Py_DECREF(old_bases);
722 Py_DECREF(old_base); 736 Py_DECREF(old_base);
723 737
738 assert(_PyType_CheckConsistency(type));
724 return res; 739 return res;
725 740
726 undo: 741 undo:
727 for (i = PyList_GET_SIZE(temp) - 1; i >= 0; i--) { 742 for (i = PyList_GET_SIZE(temp) - 1; i >= 0; i--) {
728 PyTypeObject *cls; 743 PyTypeObject *cls;
729 PyObject *new_mro, *old_mro = NULL; 744 PyObject *new_mro, *old_mro = NULL;
730 745
731 PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), 746 PyArg_UnpackTuple(PyList_GET_ITEM(temp, i),
732 "", 2, 3, &cls, &new_mro, &old_mro); 747 "", 2, 3, &cls, &new_mro, &old_mro);
733 /* Do not rollback if cls has a newer version of MRO. */ 748 /* Do not rollback if cls has a newer version of MRO. */
(...skipping 13 matching lines...) Expand all
747 type->tp_base = old_base; 762 type->tp_base = old_base;
748 763
749 Py_DECREF(new_bases); 764 Py_DECREF(new_bases);
750 Py_DECREF(new_base); 765 Py_DECREF(new_base);
751 } 766 }
752 else { 767 else {
753 Py_DECREF(old_bases); 768 Py_DECREF(old_bases);
754 Py_DECREF(old_base); 769 Py_DECREF(old_base);
755 } 770 }
756 771
772 assert(_PyType_CheckConsistency(type));
757 return -1; 773 return -1;
758 } 774 }
759 775
760 static PyObject * 776 static PyObject *
761 type_dict(PyTypeObject *type, void *context) 777 type_dict(PyTypeObject *type, void *context)
762 { 778 {
763 if (type->tp_dict == NULL) { 779 if (type->tp_dict == NULL) {
764 Py_INCREF(Py_None); 780 Py_RETURN_NONE;
765 return Py_None;
766 } 781 }
767 return PyDictProxy_New(type->tp_dict); 782 return PyDictProxy_New(type->tp_dict);
768 } 783 }
769 784
770 static PyObject * 785 static PyObject *
771 type_get_doc(PyTypeObject *type, void *context) 786 type_get_doc(PyTypeObject *type, void *context)
772 { 787 {
773 PyObject *result; 788 PyObject *result;
774 if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { 789 if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) {
775 return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); 790 return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc);
(...skipping 2254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3030 /* Give up */ 3045 /* Give up */
3031 PyErr_Format(PyExc_AttributeError, 3046 PyErr_Format(PyExc_AttributeError,
3032 "type object '%.50s' has no attribute '%U'", 3047 "type object '%.50s' has no attribute '%U'",
3033 type->tp_name, name); 3048 type->tp_name, name);
3034 return NULL; 3049 return NULL;
3035 } 3050 }
3036 3051
3037 static int 3052 static int
3038 type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) 3053 type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
3039 { 3054 {
3055 int res;
3040 if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { 3056 if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
3041 PyErr_Format( 3057 PyErr_Format(
3042 PyExc_TypeError, 3058 PyExc_TypeError,
3043 "can't set attributes of built-in/extension type '%s'", 3059 "can't set attributes of built-in/extension type '%s'",
3044 type->tp_name); 3060 type->tp_name);
3045 return -1; 3061 return -1;
3046 } 3062 }
3047 if (_PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL) < 0) 3063 if (_PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL) < 0)
3048 return -1; 3064 return -1;
3049 return update_slot(type, name); 3065 res = update_slot(type, name);
3066 assert(_PyType_CheckConsistency(type));
3067 return res;
3050 } 3068 }
3051 3069
3052 extern void 3070 extern void
3053 _PyDictKeys_DecRef(PyDictKeysObject *keys); 3071 _PyDictKeys_DecRef(PyDictKeysObject *keys);
3054 3072
3055 static void 3073 static void
3056 type_dealloc(PyTypeObject *type) 3074 type_dealloc(PyTypeObject *type)
3057 { 3075 {
3058 PyHeapTypeObject *et; 3076 PyHeapTypeObject *et;
3059 PyObject *tp, *val, *tb; 3077 PyObject *tp, *val, *tb;
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after
4665 _Py_IDENTIFIER(__eq__); 4683 _Py_IDENTIFIER(__eq__);
4666 4684
4667 assert(dict != NULL); 4685 assert(dict != NULL);
4668 if (_PyDict_GetItemId(dict, &PyId___eq__) != NULL) 4686 if (_PyDict_GetItemId(dict, &PyId___eq__) != NULL)
4669 return 1; 4687 return 1;
4670 if (_PyDict_GetItemId(dict, &PyId___hash__) != NULL) 4688 if (_PyDict_GetItemId(dict, &PyId___hash__) != NULL)
4671 return 1; 4689 return 1;
4672 return 0; 4690 return 0;
4673 } 4691 }
4674 4692
4675 /* tp_call slot which calls tp_fastcall */ 4693 /* tp_call slot calling tp_fastcall */
4676 static PyObject * 4694 static PyObject *
4677 fastcall_wrapper(PyObject *callable, PyObject *args_tuple, PyObject *kwargs) 4695 fastcall_wrapper(PyObject *callable, PyObject *args_tuple, PyObject *kwargs)
4678 { 4696 {
4679 fastternaryfunc fastcall;
4680 PyTypeObject *type; 4697 PyTypeObject *type;
4681 PyObject *result; 4698 PyObject *result;
4682 4699
4683 type = Py_TYPE(callable); 4700 type = Py_TYPE(callable);
4684 while (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)) { 4701 while (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
4702 || type->tp_fastcall == NULL) {
4685 PyTypeObject *base = type->tp_base; 4703 PyTypeObject *base = type->tp_base;
4686 if (base == type || base == NULL) { 4704 if (base == type || base == NULL) {
4687 PyErr_SetString(PyExc_SystemError, 4705 PyErr_SetString(PyExc_SystemError,
4688 "unable to find a fastcall in a base class"); 4706 "unable to find tp_fastcall in a base classes");
4689 return NULL; 4707 return NULL;
4690 } 4708 }
4691 type = base; 4709 type = base;
4692 } 4710 }
4693 4711
4694 fastcall = type->tp_fastcall;
4695 assert(fastcall != NULL);
4696
4697 result = _Py_RawFastCallDict(callable, 4712 result = _Py_RawFastCallDict(callable,
4698 fastcall, 4713 type->tp_fastcall,
4699 &PyTuple_GET_ITEM(args_tuple, 0), 4714 &PyTuple_GET_ITEM(args_tuple, 0),
4700 PyTuple_GET_SIZE(args_tuple), 4715 PyTuple_GET_SIZE(args_tuple),
4701 kwargs); 4716 kwargs);
4702 4717
4703 result = _Py_CheckFunctionResult(callable, result, NULL); 4718 result = _Py_CheckFunctionResult(callable, result, NULL);
4704 return result; 4719 return result;
4705 } 4720 }
4706 4721
4707 static void 4722 static void
4708 inherit_slots(PyTypeObject *type, PyTypeObject *base) 4723 inherit_slots(PyTypeObject *type, PyTypeObject *base)
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
4821 type->tp_getattro = base->tp_getattro; 4836 type->tp_getattro = base->tp_getattro;
4822 } 4837 }
4823 if (type->tp_setattr == NULL && type->tp_setattro == NULL) { 4838 if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
4824 type->tp_setattr = base->tp_setattr; 4839 type->tp_setattr = base->tp_setattr;
4825 type->tp_setattro = base->tp_setattro; 4840 type->tp_setattro = base->tp_setattro;
4826 } 4841 }
4827 /* tp_reserved is ignored */ 4842 /* tp_reserved is ignored */
4828 COPYSLOT(tp_repr); 4843 COPYSLOT(tp_repr);
4829 /* tp_hash see tp_richcompare */ 4844 /* tp_hash see tp_richcompare */
4830 4845
4831 if ((type->tp_flags & Py_TPFLAGS_HAVE_FASTCALL) 4846 if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
4832 && (base->tp_flags & Py_TPFLAGS_HAVE_FASTCALL) 4847 && PyType_HasFeature(base, Py_TPFLAGS_HAVE_FASTCALL)
4833 /* don't inherit tp_fastcall if tp_call is defined */ 4848 /* don't inherit tp_fastcall if tp_call is defined */
4834 && (type->tp_call == NULL || type->tp_call != fastcall_wrapper)) { 4849 && (type->tp_call == NULL || type->tp_call != fastcall_wrapper)) {
4835 COPYSLOT(tp_fastcall); 4850 COPYSLOT(tp_fastcall);
4836 } 4851 }
4837 4852
4838 if (type->tp_call != fastcall_wrapper) { 4853 if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
4854 || type->tp_call != fastcall_wrapper) {
4839 COPYSLOT(tp_call); 4855 COPYSLOT(tp_call);
4840 } 4856 }
4841 4857
4842 COPYSLOT(tp_str); 4858 COPYSLOT(tp_str);
4843 { 4859 {
4844 /* Copy comparison-related slots only when 4860 /* Copy comparison-related slots only when
4845 not overriding them anywhere */ 4861 not overriding them anywhere */
4846 if (type->tp_richcompare == NULL && 4862 if (type->tp_richcompare == NULL &&
4847 type->tp_hash == NULL && 4863 type->tp_hash == NULL &&
4848 !overrides_hash(type)) 4864 !overrides_hash(type))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4890 static int add_operators(PyTypeObject *); 4906 static int add_operators(PyTypeObject *);
4891 4907
4892 int 4908 int
4893 PyType_Ready(PyTypeObject *type) 4909 PyType_Ready(PyTypeObject *type)
4894 { 4910 {
4895 PyObject *dict, *bases; 4911 PyObject *dict, *bases;
4896 PyTypeObject *base; 4912 PyTypeObject *base;
4897 Py_ssize_t i, n; 4913 Py_ssize_t i, n;
4898 4914
4899 if (type->tp_flags & Py_TPFLAGS_READY) { 4915 if (type->tp_flags & Py_TPFLAGS_READY) {
4900 assert(type->tp_dict != NULL); 4916 assert(_PyType_CheckConsistency(type));
4901 return 0; 4917 return 0;
4902 } 4918 }
4903 assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); 4919 assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
4904 4920
4905 type->tp_flags |= Py_TPFLAGS_READYING; 4921 type->tp_flags |= Py_TPFLAGS_READYING;
4906 4922
4907 #ifdef Py_TRACE_REFS 4923 #ifdef Py_TRACE_REFS
4908 /* PyType_Ready is the closest thing we have to a choke point 4924 /* PyType_Ready is the closest thing we have to a choke point
4909 * for type objects, so is the best place I can think of to try 4925 * for type objects, so is the best place I can think of to try
4910 * to get type objects into the doubly-linked list of all objects. 4926 * to get type objects into the doubly-linked list of all objects.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
5093 bases = type->tp_bases; 5109 bases = type->tp_bases;
5094 n = PyTuple_GET_SIZE(bases); 5110 n = PyTuple_GET_SIZE(bases);
5095 for (i = 0; i < n; i++) { 5111 for (i = 0; i < n; i++) {
5096 PyObject *b = PyTuple_GET_ITEM(bases, i); 5112 PyObject *b = PyTuple_GET_ITEM(bases, i);
5097 if (PyType_Check(b) && 5113 if (PyType_Check(b) &&
5098 add_subclass((PyTypeObject *)b, type) < 0) 5114 add_subclass((PyTypeObject *)b, type) < 0)
5099 goto error; 5115 goto error;
5100 } 5116 }
5101 5117
5102 /* All done -- set the ready flag */ 5118 /* All done -- set the ready flag */
5103 assert(type->tp_dict != NULL);
5104 type->tp_flags = 5119 type->tp_flags =
5105 (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; 5120 (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
5121 assert(_PyType_CheckConsistency(type));
5106 return 0; 5122 return 0;
5107 5123
5108 error: 5124 error:
5109 type->tp_flags &= ~Py_TPFLAGS_READYING; 5125 type->tp_flags &= ~Py_TPFLAGS_READYING;
5110 return -1; 5126 return -1;
5111 } 5127 }
5112 5128
5113 static int 5129 static int
5114 add_subclass(PyTypeObject *base, PyTypeObject *type) 5130 add_subclass(PyTypeObject *base, PyTypeObject *type)
5115 { 5131 {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
5375 PyObject *arg, *value; 5391 PyObject *arg, *value;
5376 5392
5377 if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value)) 5393 if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
5378 return NULL; 5394 return NULL;
5379 i = getindex(self, arg); 5395 i = getindex(self, arg);
5380 if (i == -1 && PyErr_Occurred()) 5396 if (i == -1 && PyErr_Occurred())
5381 return NULL; 5397 return NULL;
5382 res = (*func)(self, i, value); 5398 res = (*func)(self, i, value);
5383 if (res == -1 && PyErr_Occurred()) 5399 if (res == -1 && PyErr_Occurred())
5384 return NULL; 5400 return NULL;
5385 Py_INCREF(Py_None); 5401 Py_RETURN_NONE;
5386 return Py_None;
5387 } 5402 }
5388 5403
5389 static PyObject * 5404 static PyObject *
5390 wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped) 5405 wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
5391 { 5406 {
5392 ssizeobjargproc func = (ssizeobjargproc)wrapped; 5407 ssizeobjargproc func = (ssizeobjargproc)wrapped;
5393 Py_ssize_t i; 5408 Py_ssize_t i;
5394 int res; 5409 int res;
5395 PyObject *arg; 5410 PyObject *arg;
5396 5411
5397 if (!check_num_args(args, 1)) 5412 if (!check_num_args(args, 1))
5398 return NULL; 5413 return NULL;
5399 arg = PyTuple_GET_ITEM(args, 0); 5414 arg = PyTuple_GET_ITEM(args, 0);
5400 i = getindex(self, arg); 5415 i = getindex(self, arg);
5401 if (i == -1 && PyErr_Occurred()) 5416 if (i == -1 && PyErr_Occurred())
5402 return NULL; 5417 return NULL;
5403 res = (*func)(self, i, NULL); 5418 res = (*func)(self, i, NULL);
5404 if (res == -1 && PyErr_Occurred()) 5419 if (res == -1 && PyErr_Occurred())
5405 return NULL; 5420 return NULL;
5406 Py_INCREF(Py_None); 5421 Py_RETURN_NONE;
5407 return Py_None;
5408 } 5422 }
5409 5423
5410 /* XXX objobjproc is a misnomer; should be objargpred */ 5424 /* XXX objobjproc is a misnomer; should be objargpred */
5411 static PyObject * 5425 static PyObject *
5412 wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped) 5426 wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
5413 { 5427 {
5414 objobjproc func = (objobjproc)wrapped; 5428 objobjproc func = (objobjproc)wrapped;
5415 int res; 5429 int res;
5416 PyObject *value; 5430 PyObject *value;
5417 5431
(...skipping 12 matching lines...) Expand all
5430 { 5444 {
5431 objobjargproc func = (objobjargproc)wrapped; 5445 objobjargproc func = (objobjargproc)wrapped;
5432 int res; 5446 int res;
5433 PyObject *key, *value; 5447 PyObject *key, *value;
5434 5448
5435 if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value)) 5449 if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
5436 return NULL; 5450 return NULL;
5437 res = (*func)(self, key, value); 5451 res = (*func)(self, key, value);
5438 if (res == -1 && PyErr_Occurred()) 5452 if (res == -1 && PyErr_Occurred())
5439 return NULL; 5453 return NULL;
5440 Py_INCREF(Py_None); 5454 Py_RETURN_NONE;
5441 return Py_None;
5442 } 5455 }
5443 5456
5444 static PyObject * 5457 static PyObject *
5445 wrap_delitem(PyObject *self, PyObject *args, void *wrapped) 5458 wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
5446 { 5459 {
5447 objobjargproc func = (objobjargproc)wrapped; 5460 objobjargproc func = (objobjargproc)wrapped;
5448 int res; 5461 int res;
5449 PyObject *key; 5462 PyObject *key;
5450 5463
5451 if (!check_num_args(args, 1)) 5464 if (!check_num_args(args, 1))
5452 return NULL; 5465 return NULL;
5453 key = PyTuple_GET_ITEM(args, 0); 5466 key = PyTuple_GET_ITEM(args, 0);
5454 res = (*func)(self, key, NULL); 5467 res = (*func)(self, key, NULL);
5455 if (res == -1 && PyErr_Occurred()) 5468 if (res == -1 && PyErr_Occurred())
5456 return NULL; 5469 return NULL;
5457 Py_INCREF(Py_None); 5470 Py_RETURN_NONE;
5458 return Py_None;
5459 } 5471 }
5460 5472
5461 /* Helper to check for object.__setattr__ or __delattr__ applied to a type. 5473 /* Helper to check for object.__setattr__ or __delattr__ applied to a type.
5462 This is called the Carlo Verre hack after its discoverer. */ 5474 This is called the Carlo Verre hack after its discoverer. */
5463 static int 5475 static int
5464 hackcheck(PyObject *self, setattrofunc func, const char *what) 5476 hackcheck(PyObject *self, setattrofunc func, const char *what)
5465 { 5477 {
5466 PyTypeObject *type = Py_TYPE(self); 5478 PyTypeObject *type = Py_TYPE(self);
5467 while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE) 5479 while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
5468 type = type->tp_base; 5480 type = type->tp_base;
(...skipping 16 matching lines...) Expand all
5485 int res; 5497 int res;
5486 PyObject *name, *value; 5498 PyObject *name, *value;
5487 5499
5488 if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value)) 5500 if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
5489 return NULL; 5501 return NULL;
5490 if (!hackcheck(self, func, "__setattr__")) 5502 if (!hackcheck(self, func, "__setattr__"))
5491 return NULL; 5503 return NULL;
5492 res = (*func)(self, name, value); 5504 res = (*func)(self, name, value);
5493 if (res < 0) 5505 if (res < 0)
5494 return NULL; 5506 return NULL;
5495 Py_INCREF(Py_None); 5507 Py_RETURN_NONE;
5496 return Py_None;
5497 } 5508 }
5498 5509
5499 static PyObject * 5510 static PyObject *
5500 wrap_delattr(PyObject *self, PyObject *args, void *wrapped) 5511 wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
5501 { 5512 {
5502 setattrofunc func = (setattrofunc)wrapped; 5513 setattrofunc func = (setattrofunc)wrapped;
5503 int res; 5514 int res;
5504 PyObject *name; 5515 PyObject *name;
5505 5516
5506 if (!check_num_args(args, 1)) 5517 if (!check_num_args(args, 1))
5507 return NULL; 5518 return NULL;
5508 name = PyTuple_GET_ITEM(args, 0); 5519 name = PyTuple_GET_ITEM(args, 0);
5509 if (!hackcheck(self, func, "__delattr__")) 5520 if (!hackcheck(self, func, "__delattr__"))
5510 return NULL; 5521 return NULL;
5511 res = (*func)(self, name, NULL); 5522 res = (*func)(self, name, NULL);
5512 if (res < 0) 5523 if (res < 0)
5513 return NULL; 5524 return NULL;
5514 Py_INCREF(Py_None); 5525 Py_RETURN_NONE;
5515 return Py_None;
5516 } 5526 }
5517 5527
5518 static PyObject * 5528 static PyObject *
5519 wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) 5529 wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
5520 { 5530 {
5521 hashfunc func = (hashfunc)wrapped; 5531 hashfunc func = (hashfunc)wrapped;
5522 Py_hash_t res; 5532 Py_hash_t res;
5523 5533
5524 if (!check_num_args(args, 0)) 5534 if (!check_num_args(args, 0))
5525 return NULL; 5535 return NULL;
5526 res = (*func)(self); 5536 res = (*func)(self);
5527 if (res == -1 && PyErr_Occurred()) 5537 if (res == -1 && PyErr_Occurred())
5528 return NULL; 5538 return NULL;
5529 return PyLong_FromSsize_t(res); 5539 return PyLong_FromSsize_t(res);
5530 } 5540 }
5531 5541
5532 static PyObject * 5542 static PyObject *
5533 wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) 5543 wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
5534 { 5544 {
5535 ternaryfunc func = (ternaryfunc)wrapped; 5545 ternaryfunc func = (ternaryfunc)wrapped;
5536 5546
5537 return (*func)(self, args, kwds); 5547 return (*func)(self, args, kwds);
5548 }
5549
5550 static PyObject *
5551 wrap_fastcall(PyObject *self, void *wrapped,
5552 PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
5553 {
5554 fastternaryfunc func = (fastternaryfunc)wrapped;
5555
5556 return (*func)(self, args, nargs, kwnames);
5538 } 5557 }
5539 5558
5540 static PyObject * 5559 static PyObject *
5541 wrap_del(PyObject *self, PyObject *args, void *wrapped) 5560 wrap_del(PyObject *self, PyObject *args, void *wrapped)
5542 { 5561 {
5543 destructor func = (destructor)wrapped; 5562 destructor func = (destructor)wrapped;
5544 5563
5545 if (!check_num_args(args, 0)) 5564 if (!check_num_args(args, 0))
5546 return NULL; 5565 return NULL;
5547 5566
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5616 { 5635 {
5617 descrsetfunc func = (descrsetfunc)wrapped; 5636 descrsetfunc func = (descrsetfunc)wrapped;
5618 PyObject *obj, *value; 5637 PyObject *obj, *value;
5619 int ret; 5638 int ret;
5620 5639
5621 if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value)) 5640 if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
5622 return NULL; 5641 return NULL;
5623 ret = (*func)(self, obj, value); 5642 ret = (*func)(self, obj, value);
5624 if (ret < 0) 5643 if (ret < 0)
5625 return NULL; 5644 return NULL;
5626 Py_INCREF(Py_None); 5645 Py_RETURN_NONE;
5627 return Py_None;
5628 } 5646 }
5629 5647
5630 static PyObject * 5648 static PyObject *
5631 wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) 5649 wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
5632 { 5650 {
5633 descrsetfunc func = (descrsetfunc)wrapped; 5651 descrsetfunc func = (descrsetfunc)wrapped;
5634 PyObject *obj; 5652 PyObject *obj;
5635 int ret; 5653 int ret;
5636 5654
5637 if (!check_num_args(args, 1)) 5655 if (!check_num_args(args, 1))
5638 return NULL; 5656 return NULL;
5639 obj = PyTuple_GET_ITEM(args, 0); 5657 obj = PyTuple_GET_ITEM(args, 0);
5640 ret = (*func)(self, obj, NULL); 5658 ret = (*func)(self, obj, NULL);
5641 if (ret < 0) 5659 if (ret < 0)
5642 return NULL; 5660 return NULL;
5643 Py_INCREF(Py_None); 5661 Py_RETURN_NONE;
5644 return Py_None;
5645 } 5662 }
5646 5663
5647 static PyObject * 5664 static PyObject *
5648 wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) 5665 wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
5649 { 5666 {
5650 initproc func = (initproc)wrapped; 5667 initproc func = (initproc)wrapped;
5651 5668
5652 if (func(self, args, kwds) < 0) 5669 if (func(self, args, kwds) < 0)
5653 return NULL; 5670 return NULL;
5654 Py_INCREF(Py_None); 5671 Py_RETURN_NONE;
5655 return Py_None;
5656 } 5672 }
5657 5673
5658 static PyObject * 5674 static PyObject *
5659 tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) 5675 tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
5660 { 5676 {
5661 PyTypeObject *type, *subtype, *staticbase; 5677 PyTypeObject *type, *subtype, *staticbase;
5662 PyObject *arg0, *res; 5678 PyObject *arg0, *res;
5663 5679
5664 if (self == NULL || !PyType_Check(self)) 5680 if (self == NULL || !PyType_Check(self))
5665 Py_FatalError("__new__() called with non-type 'self'"); 5681 Py_FatalError("__new__() called with non-type 'self'");
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
6200 res = PyObject_Call(meth, args, kwds); 6216 res = PyObject_Call(meth, args, kwds);
6201 6217
6202 Py_DECREF(meth); 6218 Py_DECREF(meth);
6203 return res; 6219 return res;
6204 } 6220 }
6205 6221
6206 static PyObject * 6222 static PyObject *
6207 slot_tp_fastcall(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kw names) 6223 slot_tp_fastcall(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kw names)
6208 { 6224 {
6209 _Py_IDENTIFIER(__call__); 6225 _Py_IDENTIFIER(__call__);
6210 PyObject *meth = lookup_method(self, &PyId___call__); 6226 PyObject *meth = lookup_method(self, &PyId___call__);
inada.naoki 2017/01/26 10:10:38 slot_tp_call has _Py_IDENTIFIER(__call__) too. Let
6211 PyObject *res; 6227 PyObject *res;
6212 6228
6213 if (meth == NULL) 6229 if (meth == NULL)
6214 return NULL; 6230 return NULL;
6215 6231
6216 res = _PyObject_FastCallKeywords(meth, args, nargs, kwnames); 6232 res = _PyObject_FastCallKeywords(meth, args, nargs, kwnames);
6217 6233
6218 Py_DECREF(meth); 6234 Py_DECREF(meth);
6219 return res; 6235 return res;
6220 } 6236 }
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
6565 #undef ETSLOT 6581 #undef ETSLOT
6566 #undef SQSLOT 6582 #undef SQSLOT
6567 #undef MPSLOT 6583 #undef MPSLOT
6568 #undef NBSLOT 6584 #undef NBSLOT
6569 #undef UNSLOT 6585 #undef UNSLOT
6570 #undef IBSLOT 6586 #undef IBSLOT
6571 #undef BINSLOT 6587 #undef BINSLOT
6572 #undef RBINSLOT 6588 #undef RBINSLOT
6573 6589
6574 #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6590 #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6575 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ 6591 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, NULL, \
6576 PyDoc_STR(DOC)} 6592 PyDoc_STR(DOC)}
6577 #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ 6593 #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \
6578 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ 6594 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, NULL, \
6595 PyDoc_STR(DOC), FLAGS}
6596 #define FLSLOT_FAST(NAME, SLOT, FUNCTION, WRAPPER, FAST_WRAPPER, DOC, FLAGS) \
6597 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, FAST_WRAPP ER, \
6579 PyDoc_STR(DOC), FLAGS} 6598 PyDoc_STR(DOC), FLAGS}
6580 #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6599 #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6581 {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ 6600 {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, NULL, \
6582 PyDoc_STR(DOC)} 6601 PyDoc_STR(DOC)}
6583 #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6602 #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6584 ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) 6603 ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC)
6585 #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6604 #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6586 ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) 6605 ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
6587 #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6606 #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6588 ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC) 6607 ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
6589 #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6608 #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6590 ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) 6609 ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
6591 #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6610 #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
(...skipping 17 matching lines...) Expand all
6609 6628
6610 static slotdef slotdefs[] = { 6629 static slotdef slotdefs[] = {
6611 TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), 6630 TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
6612 TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), 6631 TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
6613 TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), 6632 TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
6614 TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), 6633 TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
6615 TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, 6634 TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
6616 "__repr__($self, /)\n--\n\nReturn repr(self)."), 6635 "__repr__($self, /)\n--\n\nReturn repr(self)."),
6617 TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, 6636 TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
6618 "__hash__($self, /)\n--\n\nReturn hash(self)."), 6637 "__hash__($self, /)\n--\n\nReturn hash(self)."),
6619 FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, 6638 FLSLOT_FAST("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, wrap_ fastcall,
6620 "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function." , 6639 "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function." ,
6621 PyWrapperFlag_KEYWORDS), 6640 PyWrapperFlag_KEYWORDS),
6622 TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, 6641 TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
6623 "__str__($self, /)\n--\n\nReturn str(self)."), 6642 "__str__($self, /)\n--\n\nReturn str(self)."),
6624 TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, 6643 TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
6625 wrap_binaryfunc, 6644 wrap_binaryfunc,
6626 "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)." ), 6645 "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)." ),
6627 TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), 6646 TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
6628 TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, 6647 TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
6629 "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, na me, value)."), 6648 "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, na me, value)."),
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
6883 the slot.) Return a pointer to the next slotdef with a different offset, 6902 the slot.) Return a pointer to the next slotdef with a different offset,
6884 because that's convenient for fixup_slot_dispatchers(). */ 6903 because that's convenient for fixup_slot_dispatchers(). */
6885 static slotdef * 6904 static slotdef *
6886 update_one_slot(PyTypeObject *type, slotdef *p) 6905 update_one_slot(PyTypeObject *type, slotdef *p)
6887 { 6906 {
6888 PyObject *descr; 6907 PyObject *descr;
6889 PyWrapperDescrObject *d; 6908 PyWrapperDescrObject *d;
6890 void *generic = NULL, *specific = NULL; 6909 void *generic = NULL, *specific = NULL;
6891 int use_generic = 0; 6910 int use_generic = 0;
6892 int offset = p->offset; 6911 int offset = p->offset;
6893 void **ptr = slotptr(type, offset); 6912 void **ptr = slotptr(type, offset), **ptr2 = NULL;
6894 6913
6895 if (ptr == NULL) { 6914 if (ptr == NULL) {
6896 do { 6915 do {
6897 ++p; 6916 ++p;
6898 } while (p->offset == offset); 6917 } while (p->offset == offset);
6899 return p; 6918 return p;
6900 } 6919 }
6920
6901 do { 6921 do {
6902 descr = _PyType_Lookup(type, p->name_strobj); 6922 descr = _PyType_Lookup(type, p->name_strobj);
6903 if (descr == NULL) { 6923 if (descr == NULL) {
6904 if (ptr == (void**)&type->tp_iternext) { 6924 if (ptr == (void**)&type->tp_iternext) {
6925 ptr2 = NULL;
6905 specific = (void *)_PyObject_NextNotImplemented; 6926 specific = (void *)_PyObject_NextNotImplemented;
6906 } 6927 }
6907 continue; 6928 continue;
6908 } 6929 }
6909 if (Py_TYPE(descr) == &PyWrapperDescr_Type && 6930 if (Py_TYPE(descr) == &PyWrapperDescr_Type &&
6910 ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_stro bj) { 6931 ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_stro bj) {
6911 void **tptr = resolve_slotdups(type, p->name_strobj); 6932 void **tptr = resolve_slotdups(type, p->name_strobj);
6933 int same_wrapper;
6934
6912 if (tptr == NULL || tptr == ptr) 6935 if (tptr == NULL || tptr == ptr)
6913 generic = p->function; 6936 generic = p->function;
6914 d = (PyWrapperDescrObject *)descr; 6937 d = (PyWrapperDescrObject *)descr;
6915 if (d->d_base->wrapper == p->wrapper && 6938
6939 if (d->d_use_fastwrapper) {
6940 same_wrapper = (d->d_base->fastwrapper == p->fastwrapper);
6941
6942 assert(p->wrapper == (void *)wrap_call);
6943 ptr2 = (void **)&type->tp_fastcall;
6944 }
6945 else {
6946 same_wrapper = (d->d_base->wrapper == p->wrapper);
6947 }
6948
6949 if (same_wrapper &&
6916 PyType_IsSubtype(type, PyDescr_TYPE(d))) 6950 PyType_IsSubtype(type, PyDescr_TYPE(d)))
6917 { 6951 {
6918 if (specific == NULL || 6952 if (specific == NULL ||
6919 specific == d->d_wrapped) 6953 specific == d->d_wrapped)
6920 specific = d->d_wrapped; 6954 specific = d->d_wrapped;
6921 else 6955 else
6922 use_generic = 1; 6956 use_generic = 1;
6923 } 6957 }
6924 } 6958 }
6925 else if (Py_TYPE(descr) == &PyCFunction_Type && 6959 else if (Py_TYPE(descr) == &PyCFunction_Type &&
6926 PyCFunction_GET_FUNCTION(descr) == 6960 PyCFunction_GET_FUNCTION(descr) ==
6927 (PyCFunction)tp_new_wrapper && 6961 (PyCFunction)tp_new_wrapper &&
6928 ptr == (void**)&type->tp_new) 6962 ptr == (void**)&type->tp_new)
6929 { 6963 {
6930 /* The __new__ wrapper is not a wrapper descriptor, 6964 /* The __new__ wrapper is not a wrapper descriptor,
6931 so must be special-cased differently. 6965 so must be special-cased differently.
6932 If we don't do this, creating an instance will 6966 If we don't do this, creating an instance will
6933 always use slot_tp_new which will look up 6967 always use slot_tp_new which will look up
6934 __new__ in the MRO which will call tp_new_wrapper 6968 __new__ in the MRO which will call tp_new_wrapper
6935 which will look through the base classes looking 6969 which will look through the base classes looking
6936 for a static base and call its tp_new (usually 6970 for a static base and call its tp_new (usually
6937 PyType_GenericNew), after performing various 6971 PyType_GenericNew), after performing various
6938 sanity checks and constructing a new argument 6972 sanity checks and constructing a new argument
6939 list. Cut all that nonsense short -- this speeds 6973 list. Cut all that nonsense short -- this speeds
6940 up instance creation tremendously. */ 6974 up instance creation tremendously. */
6975
6941 specific = (void *)type->tp_new; 6976 specific = (void *)type->tp_new;
6977 ptr2 = NULL;
6978
6942 /* XXX I'm not 100% sure that there isn't a hole 6979 /* XXX I'm not 100% sure that there isn't a hole
6943 in this reasoning that requires additional 6980 in this reasoning that requires additional
6944 sanity checks. I'll buy the first person to 6981 sanity checks. I'll buy the first person to
6945 point out a bug in this reasoning a beer. */ 6982 point out a bug in this reasoning a beer. */
6946 } 6983 }
6947 else if (descr == Py_None && 6984 else if (descr == Py_None &&
6948 ptr == (void**)&type->tp_hash) { 6985 ptr == (void**)&type->tp_hash) {
6949 /* We specifically allow __hash__ to be set to None 6986 /* We specifically allow __hash__ to be set to None
6950 to prevent inheritance of the default 6987 to prevent inheritance of the default
6951 implementation from object.__hash__ */ 6988 implementation from object.__hash__ */
6952 specific = (void *)PyObject_HashNotImplemented; 6989 specific = (void *)PyObject_HashNotImplemented;
6990 ptr2 = NULL;
6953 } 6991 }
6954 else { 6992 else {
6955 use_generic = 1; 6993 use_generic = 1;
6956 generic = p->function; 6994 generic = p->function;
6957 } 6995 }
6958 } while ((++p)->offset == offset); 6996 } while ((++p)->offset == offset);
6959 if (specific && !use_generic) 6997
6998 if (specific && !use_generic) {
6999 if (ptr2 != NULL) {
7000 ptr = ptr2;
7001 }
6960 *ptr = specific; 7002 *ptr = specific;
6961 else 7003 }
7004 else {
6962 *ptr = generic; 7005 *ptr = generic;
7006 }
7007
7008 if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)) {
7009 /* synchronize tp_call and tp_fastcall slots */
7010 if (ptr == (void **)&type->tp_call) {
7011 if (type->tp_call == slot_tp_call) {
7012 type->tp_fastcall = slot_tp_fastcall;
7013 }
7014 }
7015 else if (ptr == (void **)&type->tp_fastcall) {
7016 type->tp_call = fastcall_wrapper;
7017 }
7018 }
7019
6963 return p; 7020 return p;
6964 } 7021 }
6965 7022
6966 /* In the type, update the slots whose slotdefs are gathered in the pp array. 7023 /* In the type, update the slots whose slotdefs are gathered in the pp array.
6967 This is a callback for update_subclasses(). */ 7024 This is a callback for update_subclasses(). */
6968 static int 7025 static int
6969 update_slots_callback(PyTypeObject *type, void *data) 7026 update_slots_callback(PyTypeObject *type, void *data)
6970 { 7027 {
6971 slotdef **pp = (slotdef **)data; 7028 slotdef **pp = (slotdef **)data;
6972 7029
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
7044 7101
7045 /* Store the proper functions in the slot dispatches at class (type) 7102 /* Store the proper functions in the slot dispatches at class (type)
7046 definition time, based upon which operations the class overrides in its 7103 definition time, based upon which operations the class overrides in its
7047 dict. */ 7104 dict. */
7048 static void 7105 static void
7049 fixup_slot_dispatchers(PyTypeObject *type) 7106 fixup_slot_dispatchers(PyTypeObject *type)
7050 { 7107 {
7051 slotdef *p; 7108 slotdef *p;
7052 7109
7053 init_slotdefs(); 7110 init_slotdefs();
7054 for (p = slotdefs; p->name; ) 7111 for (p = slotdefs; p->name; ) {
7055 p = update_one_slot(type, p); 7112 p = update_one_slot(type, p);
7056
7057 if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
7058 && type->tp_call == slot_tp_call && type->tp_fastcall == NULL) {
7059 type->tp_fastcall = slot_tp_fastcall;
7060 } 7113 }
7061 } 7114 }
7062 7115
7063 static void 7116 static void
7064 update_all_slots(PyTypeObject* type) 7117 update_all_slots(PyTypeObject* type)
7065 { 7118 {
7066 slotdef *p; 7119 slotdef *p;
7067 7120
7068 init_slotdefs(); 7121 init_slotdefs();
7069 for (p = slotdefs; p->name; p++) { 7122 for (p = slotdefs; p->name; p++) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
7230 if (PyDict_GetItem(dict, p->name_strobj)) 7283 if (PyDict_GetItem(dict, p->name_strobj))
7231 continue; 7284 continue;
7232 if (*ptr == (void *)PyObject_HashNotImplemented) { 7285 if (*ptr == (void *)PyObject_HashNotImplemented) {
7233 /* Classes may prevent the inheritance of the tp_hash 7286 /* Classes may prevent the inheritance of the tp_hash
7234 slot by storing PyObject_HashNotImplemented in it. Make it 7287 slot by storing PyObject_HashNotImplemented in it. Make it
7235 visible as a None value for the __hash__ attribute. */ 7288 visible as a None value for the __hash__ attribute. */
7236 if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0) 7289 if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0)
7237 return -1; 7290 return -1;
7238 } 7291 }
7239 else { 7292 else {
7240 descr = PyDescr_NewWrapper(type, p, *ptr); 7293 int use_fastwrapper;
7294 void *wrapped;
7295
7296 if (*ptr == fastcall_wrapper) {
7297 /* A wrapper must not call fastcall_wrapper() but the specific
7298 tp_fastcall. fastcall_wrapper() is called with an instance.
7299 From an instance, it's not possible to find the specific
7300 function. */
haypo 2017/01/26 03:35:21 This comment should be rephrased.
7301 use_fastwrapper = 1;
7302 wrapped = type->tp_fastcall;
7303 }
7304 else {
7305 use_fastwrapper = 0;
7306 wrapped = *ptr;
7307 }
7308 assert(wrapped != NULL);
7309
7310 descr = _PyDescr_NewWrapperEx(type, p, wrapped, use_fastwrapper);
7241 if (descr == NULL) 7311 if (descr == NULL)
7242 return -1; 7312 return -1;
7243 if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) { 7313 if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) {
7244 Py_DECREF(descr); 7314 Py_DECREF(descr);
7245 return -1; 7315 return -1;
7246 } 7316 }
7247 Py_DECREF(descr); 7317 Py_DECREF(descr);
7248 } 7318 }
7249 } 7319 }
7250 if (type->tp_new != NULL) { 7320 if (type->tp_new != NULL) {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
7639 0, /* tp_base */ 7709 0, /* tp_base */
7640 0, /* tp_dict */ 7710 0, /* tp_dict */
7641 super_descr_get, /* tp_descr_get */ 7711 super_descr_get, /* tp_descr_get */
7642 0, /* tp_descr_set */ 7712 0, /* tp_descr_set */
7643 0, /* tp_dictoffset */ 7713 0, /* tp_dictoffset */
7644 super_init, /* tp_init */ 7714 super_init, /* tp_init */
7645 PyType_GenericAlloc, /* tp_alloc */ 7715 PyType_GenericAlloc, /* tp_alloc */
7646 PyType_GenericNew, /* tp_new */ 7716 PyType_GenericNew, /* tp_new */
7647 PyObject_GC_Del, /* tp_free */ 7717 PyObject_GC_Del, /* tp_free */
7648 }; 7718 };
LEFTRIGHT

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