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

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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 895
881 if (type->tp_new == NULL) { 896 if (type->tp_new == NULL) {
882 PyErr_Format(PyExc_TypeError, 897 PyErr_Format(PyExc_TypeError,
883 "cannot create '%.100s' instances", 898 "cannot create '%.100s' instances",
884 type->tp_name); 899 type->tp_name);
885 return NULL; 900 return NULL;
886 } 901 }
887 902
888 #ifdef Py_DEBUG 903 #ifdef Py_DEBUG
889 /* type_call() must not be called with an exception set, 904 /* type_call() must not be called with an exception set,
890 because it may clear it (directly or indirectly) and so the 905 because it can clear it (directly or indirectly) and so the
891 caller loses its exception */ 906 caller loses its exception */
892 assert(!PyErr_Occurred()); 907 assert(!PyErr_Occurred());
893 #endif 908 #endif
894 909
895 obj = type->tp_new(type, args, kwds); 910 obj = type->tp_new(type, args, kwds);
896 obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL); 911 obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
897 if (obj == NULL) 912 if (obj == NULL)
898 return NULL; 913 return NULL;
899 914
900 /* Ugly exception: when the call was type(something), 915 /* Ugly exception: when the call was type(something),
(...skipping 2129 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 fastcall = type->tp_fastcall;
4694 4711
4695 result = _Py_RawFastCallDict(callable, 4712 result = _Py_RawFastCallDict(callable,
4696 fastcall, 4713 type->tp_fastcall,
4697 &PyTuple_GET_ITEM(args_tuple, 0), 4714 &PyTuple_GET_ITEM(args_tuple, 0),
4698 PyTuple_GET_SIZE(args_tuple), 4715 PyTuple_GET_SIZE(args_tuple),
4699 kwargs); 4716 kwargs);
4700 4717
4701 result = _Py_CheckFunctionResult(callable, result, NULL); 4718 result = _Py_CheckFunctionResult(callable, result, NULL);
4702 return result; 4719 return result;
4703 } 4720 }
4704 4721
4705 static void 4722 static void
4706 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
4819 type->tp_getattro = base->tp_getattro; 4836 type->tp_getattro = base->tp_getattro;
4820 } 4837 }
4821 if (type->tp_setattr == NULL && type->tp_setattro == NULL) { 4838 if (type->tp_setattr == NULL && type->tp_setattro == NULL) {
4822 type->tp_setattr = base->tp_setattr; 4839 type->tp_setattr = base->tp_setattr;
4823 type->tp_setattro = base->tp_setattro; 4840 type->tp_setattro = base->tp_setattro;
4824 } 4841 }
4825 /* tp_reserved is ignored */ 4842 /* tp_reserved is ignored */
4826 COPYSLOT(tp_repr); 4843 COPYSLOT(tp_repr);
4827 /* tp_hash see tp_richcompare */ 4844 /* tp_hash see tp_richcompare */
4828 4845
4829 if ((type->tp_flags & Py_TPFLAGS_HAVE_FASTCALL) 4846 if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
4830 && (base->tp_flags & Py_TPFLAGS_HAVE_FASTCALL)) { 4847 && PyType_HasFeature(base, Py_TPFLAGS_HAVE_FASTCALL)
4848 /* don't inherit tp_fastcall if tp_call is defined */
4849 && (type->tp_call == NULL || type->tp_call != fastcall_wrapper)) {
4831 COPYSLOT(tp_fastcall); 4850 COPYSLOT(tp_fastcall);
4832 } 4851 }
4833 4852
4834 if (type->tp_call != fastcall_wrapper) { 4853 if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
4854 || type->tp_call != fastcall_wrapper) {
4835 COPYSLOT(tp_call); 4855 COPYSLOT(tp_call);
4836 } 4856 }
4837 4857
4838 COPYSLOT(tp_str); 4858 COPYSLOT(tp_str);
4839 { 4859 {
4840 /* Copy comparison-related slots only when 4860 /* Copy comparison-related slots only when
4841 not overriding them anywhere */ 4861 not overriding them anywhere */
4842 if (type->tp_richcompare == NULL && 4862 if (type->tp_richcompare == NULL &&
4843 type->tp_hash == NULL && 4863 type->tp_hash == NULL &&
4844 !overrides_hash(type)) 4864 !overrides_hash(type))
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4886 static int add_operators(PyTypeObject *); 4906 static int add_operators(PyTypeObject *);
4887 4907
4888 int 4908 int
4889 PyType_Ready(PyTypeObject *type) 4909 PyType_Ready(PyTypeObject *type)
4890 { 4910 {
4891 PyObject *dict, *bases; 4911 PyObject *dict, *bases;
4892 PyTypeObject *base; 4912 PyTypeObject *base;
4893 Py_ssize_t i, n; 4913 Py_ssize_t i, n;
4894 4914
4895 if (type->tp_flags & Py_TPFLAGS_READY) { 4915 if (type->tp_flags & Py_TPFLAGS_READY) {
4896 assert(type->tp_dict != NULL); 4916 assert(_PyType_CheckConsistency(type));
4897 return 0; 4917 return 0;
4898 } 4918 }
4899 assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); 4919 assert((type->tp_flags & Py_TPFLAGS_READYING) == 0);
4900 4920
4901 type->tp_flags |= Py_TPFLAGS_READYING; 4921 type->tp_flags |= Py_TPFLAGS_READYING;
4902 4922
4903 #ifdef Py_TRACE_REFS 4923 #ifdef Py_TRACE_REFS
4904 /* 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
4905 * 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
4906 * 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
5089 bases = type->tp_bases; 5109 bases = type->tp_bases;
5090 n = PyTuple_GET_SIZE(bases); 5110 n = PyTuple_GET_SIZE(bases);
5091 for (i = 0; i < n; i++) { 5111 for (i = 0; i < n; i++) {
5092 PyObject *b = PyTuple_GET_ITEM(bases, i); 5112 PyObject *b = PyTuple_GET_ITEM(bases, i);
5093 if (PyType_Check(b) && 5113 if (PyType_Check(b) &&
5094 add_subclass((PyTypeObject *)b, type) < 0) 5114 add_subclass((PyTypeObject *)b, type) < 0)
5095 goto error; 5115 goto error;
5096 } 5116 }
5097 5117
5098 /* All done -- set the ready flag */ 5118 /* All done -- set the ready flag */
5099 assert(type->tp_dict != NULL);
5100 type->tp_flags = 5119 type->tp_flags =
5101 (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; 5120 (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY;
5121 assert(_PyType_CheckConsistency(type));
5102 return 0; 5122 return 0;
5103 5123
5104 error: 5124 error:
5105 type->tp_flags &= ~Py_TPFLAGS_READYING; 5125 type->tp_flags &= ~Py_TPFLAGS_READYING;
5106 return -1; 5126 return -1;
5107 } 5127 }
5108 5128
5109 static int 5129 static int
5110 add_subclass(PyTypeObject *base, PyTypeObject *type) 5130 add_subclass(PyTypeObject *base, PyTypeObject *type)
5111 { 5131 {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
5371 PyObject *arg, *value; 5391 PyObject *arg, *value;
5372 5392
5373 if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value)) 5393 if (!PyArg_UnpackTuple(args, "", 2, 2, &arg, &value))
5374 return NULL; 5394 return NULL;
5375 i = getindex(self, arg); 5395 i = getindex(self, arg);
5376 if (i == -1 && PyErr_Occurred()) 5396 if (i == -1 && PyErr_Occurred())
5377 return NULL; 5397 return NULL;
5378 res = (*func)(self, i, value); 5398 res = (*func)(self, i, value);
5379 if (res == -1 && PyErr_Occurred()) 5399 if (res == -1 && PyErr_Occurred())
5380 return NULL; 5400 return NULL;
5381 Py_INCREF(Py_None); 5401 Py_RETURN_NONE;
5382 return Py_None;
5383 } 5402 }
5384 5403
5385 static PyObject * 5404 static PyObject *
5386 wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped) 5405 wrap_sq_delitem(PyObject *self, PyObject *args, void *wrapped)
5387 { 5406 {
5388 ssizeobjargproc func = (ssizeobjargproc)wrapped; 5407 ssizeobjargproc func = (ssizeobjargproc)wrapped;
5389 Py_ssize_t i; 5408 Py_ssize_t i;
5390 int res; 5409 int res;
5391 PyObject *arg; 5410 PyObject *arg;
5392 5411
5393 if (!check_num_args(args, 1)) 5412 if (!check_num_args(args, 1))
5394 return NULL; 5413 return NULL;
5395 arg = PyTuple_GET_ITEM(args, 0); 5414 arg = PyTuple_GET_ITEM(args, 0);
5396 i = getindex(self, arg); 5415 i = getindex(self, arg);
5397 if (i == -1 && PyErr_Occurred()) 5416 if (i == -1 && PyErr_Occurred())
5398 return NULL; 5417 return NULL;
5399 res = (*func)(self, i, NULL); 5418 res = (*func)(self, i, NULL);
5400 if (res == -1 && PyErr_Occurred()) 5419 if (res == -1 && PyErr_Occurred())
5401 return NULL; 5420 return NULL;
5402 Py_INCREF(Py_None); 5421 Py_RETURN_NONE;
5403 return Py_None;
5404 } 5422 }
5405 5423
5406 /* XXX objobjproc is a misnomer; should be objargpred */ 5424 /* XXX objobjproc is a misnomer; should be objargpred */
5407 static PyObject * 5425 static PyObject *
5408 wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped) 5426 wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
5409 { 5427 {
5410 objobjproc func = (objobjproc)wrapped; 5428 objobjproc func = (objobjproc)wrapped;
5411 int res; 5429 int res;
5412 PyObject *value; 5430 PyObject *value;
5413 5431
(...skipping 12 matching lines...) Expand all
5426 { 5444 {
5427 objobjargproc func = (objobjargproc)wrapped; 5445 objobjargproc func = (objobjargproc)wrapped;
5428 int res; 5446 int res;
5429 PyObject *key, *value; 5447 PyObject *key, *value;
5430 5448
5431 if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value)) 5449 if (!PyArg_UnpackTuple(args, "", 2, 2, &key, &value))
5432 return NULL; 5450 return NULL;
5433 res = (*func)(self, key, value); 5451 res = (*func)(self, key, value);
5434 if (res == -1 && PyErr_Occurred()) 5452 if (res == -1 && PyErr_Occurred())
5435 return NULL; 5453 return NULL;
5436 Py_INCREF(Py_None); 5454 Py_RETURN_NONE;
5437 return Py_None;
5438 } 5455 }
5439 5456
5440 static PyObject * 5457 static PyObject *
5441 wrap_delitem(PyObject *self, PyObject *args, void *wrapped) 5458 wrap_delitem(PyObject *self, PyObject *args, void *wrapped)
5442 { 5459 {
5443 objobjargproc func = (objobjargproc)wrapped; 5460 objobjargproc func = (objobjargproc)wrapped;
5444 int res; 5461 int res;
5445 PyObject *key; 5462 PyObject *key;
5446 5463
5447 if (!check_num_args(args, 1)) 5464 if (!check_num_args(args, 1))
5448 return NULL; 5465 return NULL;
5449 key = PyTuple_GET_ITEM(args, 0); 5466 key = PyTuple_GET_ITEM(args, 0);
5450 res = (*func)(self, key, NULL); 5467 res = (*func)(self, key, NULL);
5451 if (res == -1 && PyErr_Occurred()) 5468 if (res == -1 && PyErr_Occurred())
5452 return NULL; 5469 return NULL;
5453 Py_INCREF(Py_None); 5470 Py_RETURN_NONE;
5454 return Py_None;
5455 } 5471 }
5456 5472
5457 /* 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.
5458 This is called the Carlo Verre hack after its discoverer. */ 5474 This is called the Carlo Verre hack after its discoverer. */
5459 static int 5475 static int
5460 hackcheck(PyObject *self, setattrofunc func, const char *what) 5476 hackcheck(PyObject *self, setattrofunc func, const char *what)
5461 { 5477 {
5462 PyTypeObject *type = Py_TYPE(self); 5478 PyTypeObject *type = Py_TYPE(self);
5463 while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE) 5479 while (type && type->tp_flags & Py_TPFLAGS_HEAPTYPE)
5464 type = type->tp_base; 5480 type = type->tp_base;
(...skipping 16 matching lines...) Expand all
5481 int res; 5497 int res;
5482 PyObject *name, *value; 5498 PyObject *name, *value;
5483 5499
5484 if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value)) 5500 if (!PyArg_UnpackTuple(args, "", 2, 2, &name, &value))
5485 return NULL; 5501 return NULL;
5486 if (!hackcheck(self, func, "__setattr__")) 5502 if (!hackcheck(self, func, "__setattr__"))
5487 return NULL; 5503 return NULL;
5488 res = (*func)(self, name, value); 5504 res = (*func)(self, name, value);
5489 if (res < 0) 5505 if (res < 0)
5490 return NULL; 5506 return NULL;
5491 Py_INCREF(Py_None); 5507 Py_RETURN_NONE;
5492 return Py_None;
5493 } 5508 }
5494 5509
5495 static PyObject * 5510 static PyObject *
5496 wrap_delattr(PyObject *self, PyObject *args, void *wrapped) 5511 wrap_delattr(PyObject *self, PyObject *args, void *wrapped)
5497 { 5512 {
5498 setattrofunc func = (setattrofunc)wrapped; 5513 setattrofunc func = (setattrofunc)wrapped;
5499 int res; 5514 int res;
5500 PyObject *name; 5515 PyObject *name;
5501 5516
5502 if (!check_num_args(args, 1)) 5517 if (!check_num_args(args, 1))
5503 return NULL; 5518 return NULL;
5504 name = PyTuple_GET_ITEM(args, 0); 5519 name = PyTuple_GET_ITEM(args, 0);
5505 if (!hackcheck(self, func, "__delattr__")) 5520 if (!hackcheck(self, func, "__delattr__"))
5506 return NULL; 5521 return NULL;
5507 res = (*func)(self, name, NULL); 5522 res = (*func)(self, name, NULL);
5508 if (res < 0) 5523 if (res < 0)
5509 return NULL; 5524 return NULL;
5510 Py_INCREF(Py_None); 5525 Py_RETURN_NONE;
5511 return Py_None;
5512 } 5526 }
5513 5527
5514 static PyObject * 5528 static PyObject *
5515 wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped) 5529 wrap_hashfunc(PyObject *self, PyObject *args, void *wrapped)
5516 { 5530 {
5517 hashfunc func = (hashfunc)wrapped; 5531 hashfunc func = (hashfunc)wrapped;
5518 Py_hash_t res; 5532 Py_hash_t res;
5519 5533
5520 if (!check_num_args(args, 0)) 5534 if (!check_num_args(args, 0))
5521 return NULL; 5535 return NULL;
5522 res = (*func)(self); 5536 res = (*func)(self);
5523 if (res == -1 && PyErr_Occurred()) 5537 if (res == -1 && PyErr_Occurred())
5524 return NULL; 5538 return NULL;
5525 return PyLong_FromSsize_t(res); 5539 return PyLong_FromSsize_t(res);
5526 } 5540 }
5527 5541
5528 static PyObject * 5542 static PyObject *
5529 wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) 5543 wrap_call(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
5530 { 5544 {
5531 ternaryfunc func = (ternaryfunc)wrapped; 5545 ternaryfunc func = (ternaryfunc)wrapped;
5532 5546
5533 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);
5534 } 5557 }
5535 5558
5536 static PyObject * 5559 static PyObject *
5537 wrap_del(PyObject *self, PyObject *args, void *wrapped) 5560 wrap_del(PyObject *self, PyObject *args, void *wrapped)
5538 { 5561 {
5539 destructor func = (destructor)wrapped; 5562 destructor func = (destructor)wrapped;
5540 5563
5541 if (!check_num_args(args, 0)) 5564 if (!check_num_args(args, 0))
5542 return NULL; 5565 return NULL;
5543 5566
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5612 { 5635 {
5613 descrsetfunc func = (descrsetfunc)wrapped; 5636 descrsetfunc func = (descrsetfunc)wrapped;
5614 PyObject *obj, *value; 5637 PyObject *obj, *value;
5615 int ret; 5638 int ret;
5616 5639
5617 if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value)) 5640 if (!PyArg_UnpackTuple(args, "", 2, 2, &obj, &value))
5618 return NULL; 5641 return NULL;
5619 ret = (*func)(self, obj, value); 5642 ret = (*func)(self, obj, value);
5620 if (ret < 0) 5643 if (ret < 0)
5621 return NULL; 5644 return NULL;
5622 Py_INCREF(Py_None); 5645 Py_RETURN_NONE;
5623 return Py_None;
5624 } 5646 }
5625 5647
5626 static PyObject * 5648 static PyObject *
5627 wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) 5649 wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped)
5628 { 5650 {
5629 descrsetfunc func = (descrsetfunc)wrapped; 5651 descrsetfunc func = (descrsetfunc)wrapped;
5630 PyObject *obj; 5652 PyObject *obj;
5631 int ret; 5653 int ret;
5632 5654
5633 if (!check_num_args(args, 1)) 5655 if (!check_num_args(args, 1))
5634 return NULL; 5656 return NULL;
5635 obj = PyTuple_GET_ITEM(args, 0); 5657 obj = PyTuple_GET_ITEM(args, 0);
5636 ret = (*func)(self, obj, NULL); 5658 ret = (*func)(self, obj, NULL);
5637 if (ret < 0) 5659 if (ret < 0)
5638 return NULL; 5660 return NULL;
5639 Py_INCREF(Py_None); 5661 Py_RETURN_NONE;
5640 return Py_None;
5641 } 5662 }
5642 5663
5643 static PyObject * 5664 static PyObject *
5644 wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds) 5665 wrap_init(PyObject *self, PyObject *args, void *wrapped, PyObject *kwds)
5645 { 5666 {
5646 initproc func = (initproc)wrapped; 5667 initproc func = (initproc)wrapped;
5647 5668
5648 if (func(self, args, kwds) < 0) 5669 if (func(self, args, kwds) < 0)
5649 return NULL; 5670 return NULL;
5650 Py_INCREF(Py_None); 5671 Py_RETURN_NONE;
5651 return Py_None;
5652 } 5672 }
5653 5673
5654 static PyObject * 5674 static PyObject *
5655 tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) 5675 tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
5656 { 5676 {
5657 PyTypeObject *type, *subtype, *staticbase; 5677 PyTypeObject *type, *subtype, *staticbase;
5658 PyObject *arg0, *res; 5678 PyObject *arg0, *res;
5659 5679
5660 if (self == NULL || !PyType_Check(self)) 5680 if (self == NULL || !PyType_Check(self))
5661 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
6196 res = PyObject_Call(meth, args, kwds); 6216 res = PyObject_Call(meth, args, kwds);
6197 6217
6198 Py_DECREF(meth); 6218 Py_DECREF(meth);
6199 return res; 6219 return res;
6200 } 6220 }
6201 6221
6202 static PyObject * 6222 static PyObject *
6203 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)
6204 { 6224 {
6205 _Py_IDENTIFIER(__call__); 6225 _Py_IDENTIFIER(__call__);
6206 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
6207 PyObject *res; 6227 PyObject *res;
6208 6228
6209 if (meth == NULL) 6229 if (meth == NULL)
6210 return NULL; 6230 return NULL;
6211 6231
6212 res = _PyObject_FastCallKeywords(meth, args, nargs, kwnames); 6232 res = _PyObject_FastCallKeywords(meth, args, nargs, kwnames);
6213 6233
6214 Py_DECREF(meth); 6234 Py_DECREF(meth);
6215 return res; 6235 return res;
6216 } 6236 }
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
6561 #undef ETSLOT 6581 #undef ETSLOT
6562 #undef SQSLOT 6582 #undef SQSLOT
6563 #undef MPSLOT 6583 #undef MPSLOT
6564 #undef NBSLOT 6584 #undef NBSLOT
6565 #undef UNSLOT 6585 #undef UNSLOT
6566 #undef IBSLOT 6586 #undef IBSLOT
6567 #undef BINSLOT 6587 #undef BINSLOT
6568 #undef RBINSLOT 6588 #undef RBINSLOT
6569 6589
6570 #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6590 #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6571 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ 6591 {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, NULL, \
6572 PyDoc_STR(DOC)} 6592 PyDoc_STR(DOC)}
6573 #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ 6593 #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \
6574 {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, \
6575 PyDoc_STR(DOC), FLAGS} 6598 PyDoc_STR(DOC), FLAGS}
6576 #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6599 #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6577 {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ 6600 {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, NULL, \
6578 PyDoc_STR(DOC)} 6601 PyDoc_STR(DOC)}
6579 #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6602 #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6580 ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) 6603 ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC)
6581 #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6604 #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6582 ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC) 6605 ETSLOT(NAME, as_sequence.SLOT, FUNCTION, WRAPPER, DOC)
6583 #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6606 #define MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6584 ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC) 6607 ETSLOT(NAME, as_mapping.SLOT, FUNCTION, WRAPPER, DOC)
6585 #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6608 #define NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
6586 ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) 6609 ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
6587 #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ 6610 #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
(...skipping 17 matching lines...) Expand all
6605 6628
6606 static slotdef slotdefs[] = { 6629 static slotdef slotdefs[] = {
6607 TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), 6630 TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
6608 TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), 6631 TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""),
6609 TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), 6632 TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
6610 TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), 6633 TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
6611 TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, 6634 TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
6612 "__repr__($self, /)\n--\n\nReturn repr(self)."), 6635 "__repr__($self, /)\n--\n\nReturn repr(self)."),
6613 TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, 6636 TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
6614 "__hash__($self, /)\n--\n\nReturn hash(self)."), 6637 "__hash__($self, /)\n--\n\nReturn hash(self)."),
6615 FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, 6638 FLSLOT_FAST("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, wrap_ fastcall,
6616 "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function." , 6639 "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function." ,
6617 PyWrapperFlag_KEYWORDS), 6640 PyWrapperFlag_KEYWORDS),
6618 TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, 6641 TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
6619 "__str__($self, /)\n--\n\nReturn str(self)."), 6642 "__str__($self, /)\n--\n\nReturn str(self)."),
6620 TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, 6643 TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
6621 wrap_binaryfunc, 6644 wrap_binaryfunc,
6622 "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)." ), 6645 "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)." ),
6623 TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), 6646 TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
6624 TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, 6647 TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
6625 "__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
6879 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,
6880 because that's convenient for fixup_slot_dispatchers(). */ 6903 because that's convenient for fixup_slot_dispatchers(). */
6881 static slotdef * 6904 static slotdef *
6882 update_one_slot(PyTypeObject *type, slotdef *p) 6905 update_one_slot(PyTypeObject *type, slotdef *p)
6883 { 6906 {
6884 PyObject *descr; 6907 PyObject *descr;
6885 PyWrapperDescrObject *d; 6908 PyWrapperDescrObject *d;
6886 void *generic = NULL, *specific = NULL; 6909 void *generic = NULL, *specific = NULL;
6887 int use_generic = 0; 6910 int use_generic = 0;
6888 int offset = p->offset; 6911 int offset = p->offset;
6889 void **ptr = slotptr(type, offset); 6912 void **ptr = slotptr(type, offset), **ptr2 = NULL;
6890 6913
6891 if (ptr == NULL) { 6914 if (ptr == NULL) {
6892 do { 6915 do {
6893 ++p; 6916 ++p;
6894 } while (p->offset == offset); 6917 } while (p->offset == offset);
6895 return p; 6918 return p;
6896 } 6919 }
6920
6897 do { 6921 do {
6898 descr = _PyType_Lookup(type, p->name_strobj); 6922 descr = _PyType_Lookup(type, p->name_strobj);
6899 if (descr == NULL) { 6923 if (descr == NULL) {
6900 if (ptr == (void**)&type->tp_iternext) { 6924 if (ptr == (void**)&type->tp_iternext) {
6925 ptr2 = NULL;
6901 specific = (void *)_PyObject_NextNotImplemented; 6926 specific = (void *)_PyObject_NextNotImplemented;
6902 } 6927 }
6903 continue; 6928 continue;
6904 } 6929 }
6905 if (Py_TYPE(descr) == &PyWrapperDescr_Type && 6930 if (Py_TYPE(descr) == &PyWrapperDescr_Type &&
6906 ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_stro bj) { 6931 ((PyWrapperDescrObject *)descr)->d_base->name_strobj == p->name_stro bj) {
6907 void **tptr = resolve_slotdups(type, p->name_strobj); 6932 void **tptr = resolve_slotdups(type, p->name_strobj);
6933 int same_wrapper;
6934
6908 if (tptr == NULL || tptr == ptr) 6935 if (tptr == NULL || tptr == ptr)
6909 generic = p->function; 6936 generic = p->function;
6910 d = (PyWrapperDescrObject *)descr; 6937 d = (PyWrapperDescrObject *)descr;
6911 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 &&
6912 PyType_IsSubtype(type, PyDescr_TYPE(d))) 6950 PyType_IsSubtype(type, PyDescr_TYPE(d)))
6913 { 6951 {
6914 if (specific == NULL || 6952 if (specific == NULL ||
6915 specific == d->d_wrapped) 6953 specific == d->d_wrapped)
6916 specific = d->d_wrapped; 6954 specific = d->d_wrapped;
6917 else 6955 else
6918 use_generic = 1; 6956 use_generic = 1;
6919 } 6957 }
6920 } 6958 }
6921 else if (Py_TYPE(descr) == &PyCFunction_Type && 6959 else if (Py_TYPE(descr) == &PyCFunction_Type &&
6922 PyCFunction_GET_FUNCTION(descr) == 6960 PyCFunction_GET_FUNCTION(descr) ==
6923 (PyCFunction)tp_new_wrapper && 6961 (PyCFunction)tp_new_wrapper &&
6924 ptr == (void**)&type->tp_new) 6962 ptr == (void**)&type->tp_new)
6925 { 6963 {
6926 /* The __new__ wrapper is not a wrapper descriptor, 6964 /* The __new__ wrapper is not a wrapper descriptor,
6927 so must be special-cased differently. 6965 so must be special-cased differently.
6928 If we don't do this, creating an instance will 6966 If we don't do this, creating an instance will
6929 always use slot_tp_new which will look up 6967 always use slot_tp_new which will look up
6930 __new__ in the MRO which will call tp_new_wrapper 6968 __new__ in the MRO which will call tp_new_wrapper
6931 which will look through the base classes looking 6969 which will look through the base classes looking
6932 for a static base and call its tp_new (usually 6970 for a static base and call its tp_new (usually
6933 PyType_GenericNew), after performing various 6971 PyType_GenericNew), after performing various
6934 sanity checks and constructing a new argument 6972 sanity checks and constructing a new argument
6935 list. Cut all that nonsense short -- this speeds 6973 list. Cut all that nonsense short -- this speeds
6936 up instance creation tremendously. */ 6974 up instance creation tremendously. */
6975
6937 specific = (void *)type->tp_new; 6976 specific = (void *)type->tp_new;
6977 ptr2 = NULL;
6978
6938 /* 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
6939 in this reasoning that requires additional 6980 in this reasoning that requires additional
6940 sanity checks. I'll buy the first person to 6981 sanity checks. I'll buy the first person to
6941 point out a bug in this reasoning a beer. */ 6982 point out a bug in this reasoning a beer. */
6942 } 6983 }
6943 else if (descr == Py_None && 6984 else if (descr == Py_None &&
6944 ptr == (void**)&type->tp_hash) { 6985 ptr == (void**)&type->tp_hash) {
6945 /* We specifically allow __hash__ to be set to None 6986 /* We specifically allow __hash__ to be set to None
6946 to prevent inheritance of the default 6987 to prevent inheritance of the default
6947 implementation from object.__hash__ */ 6988 implementation from object.__hash__ */
6948 specific = (void *)PyObject_HashNotImplemented; 6989 specific = (void *)PyObject_HashNotImplemented;
6990 ptr2 = NULL;
6949 } 6991 }
6950 else { 6992 else {
6951 use_generic = 1; 6993 use_generic = 1;
6952 generic = p->function; 6994 generic = p->function;
6953 } 6995 }
6954 } while ((++p)->offset == offset); 6996 } while ((++p)->offset == offset);
6955 if (specific && !use_generic) 6997
6998 if (specific && !use_generic) {
6999 if (ptr2 != NULL) {
7000 ptr = ptr2;
7001 }
6956 *ptr = specific; 7002 *ptr = specific;
6957 else 7003 }
7004 else {
6958 *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
6959 return p; 7020 return p;
6960 } 7021 }
6961 7022
6962 /* 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.
6963 This is a callback for update_subclasses(). */ 7024 This is a callback for update_subclasses(). */
6964 static int 7025 static int
6965 update_slots_callback(PyTypeObject *type, void *data) 7026 update_slots_callback(PyTypeObject *type, void *data)
6966 { 7027 {
6967 slotdef **pp = (slotdef **)data; 7028 slotdef **pp = (slotdef **)data;
6968 7029
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
7040 7101
7041 /* Store the proper functions in the slot dispatches at class (type) 7102 /* Store the proper functions in the slot dispatches at class (type)
7042 definition time, based upon which operations the class overrides in its 7103 definition time, based upon which operations the class overrides in its
7043 dict. */ 7104 dict. */
7044 static void 7105 static void
7045 fixup_slot_dispatchers(PyTypeObject *type) 7106 fixup_slot_dispatchers(PyTypeObject *type)
7046 { 7107 {
7047 slotdef *p; 7108 slotdef *p;
7048 7109
7049 init_slotdefs(); 7110 init_slotdefs();
7050 for (p = slotdefs; p->name; ) 7111 for (p = slotdefs; p->name; ) {
7051 p = update_one_slot(type, p); 7112 p = update_one_slot(type, p);
7052
7053 if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_FASTCALL)
7054 && type->tp_call == slot_tp_call && type->tp_fastcall == NULL) {
7055 type->tp_fastcall = slot_tp_fastcall;
7056 } 7113 }
7057 } 7114 }
7058 7115
7059 static void 7116 static void
7060 update_all_slots(PyTypeObject* type) 7117 update_all_slots(PyTypeObject* type)
7061 { 7118 {
7062 slotdef *p; 7119 slotdef *p;
7063 7120
7064 init_slotdefs(); 7121 init_slotdefs();
7065 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
7226 if (PyDict_GetItem(dict, p->name_strobj)) 7283 if (PyDict_GetItem(dict, p->name_strobj))
7227 continue; 7284 continue;
7228 if (*ptr == (void *)PyObject_HashNotImplemented) { 7285 if (*ptr == (void *)PyObject_HashNotImplemented) {
7229 /* Classes may prevent the inheritance of the tp_hash 7286 /* Classes may prevent the inheritance of the tp_hash
7230 slot by storing PyObject_HashNotImplemented in it. Make it 7287 slot by storing PyObject_HashNotImplemented in it. Make it
7231 visible as a None value for the __hash__ attribute. */ 7288 visible as a None value for the __hash__ attribute. */
7232 if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0) 7289 if (PyDict_SetItem(dict, p->name_strobj, Py_None) < 0)
7233 return -1; 7290 return -1;
7234 } 7291 }
7235 else { 7292 else {
7236 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);
7237 if (descr == NULL) 7311 if (descr == NULL)
7238 return -1; 7312 return -1;
7239 if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) { 7313 if (PyDict_SetItem(dict, p->name_strobj, descr) < 0) {
7240 Py_DECREF(descr); 7314 Py_DECREF(descr);
7241 return -1; 7315 return -1;
7242 } 7316 }
7243 Py_DECREF(descr); 7317 Py_DECREF(descr);
7244 } 7318 }
7245 } 7319 }
7246 if (type->tp_new != NULL) { 7320 if (type->tp_new != NULL) {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
7635 0, /* tp_base */ 7709 0, /* tp_base */
7636 0, /* tp_dict */ 7710 0, /* tp_dict */
7637 super_descr_get, /* tp_descr_get */ 7711 super_descr_get, /* tp_descr_get */
7638 0, /* tp_descr_set */ 7712 0, /* tp_descr_set */
7639 0, /* tp_dictoffset */ 7713 0, /* tp_dictoffset */
7640 super_init, /* tp_init */ 7714 super_init, /* tp_init */
7641 PyType_GenericAlloc, /* tp_alloc */ 7715 PyType_GenericAlloc, /* tp_alloc */
7642 PyType_GenericNew, /* tp_new */ 7716 PyType_GenericNew, /* tp_new */
7643 PyObject_GC_Del, /* tp_free */ 7717 PyObject_GC_Del, /* tp_free */
7644 }; 7718 };
LEFTRIGHT

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