| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,6 +49,7 @@ PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult( | |||
| 49 | 49 | or _PyObject_FastCallDict() (both forms are supported), | |
| 50 | 50 | except that nargs is plainly the number of arguments without flags. */ | |
| 51 | 51 | PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( | |
| 52 | + PyThreadState *tstate, | ||
| 52 | 53 | PyObject *callable, | |
| 53 | 54 | PyObject *const *args, Py_ssize_t nargs, | |
| 54 | 55 | PyObject *keywords); | |
@@ -95,22 +96,31 @@ _PyVectorcall_Function(PyObject *callable) | |||
| 95 | 96 | Return the result on success. Raise an exception and return NULL on | |
| 96 | 97 | error. */ | |
| 97 | 98 | static inline PyObject * | |
| 98 | - _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, | ||
| 99 | - size_t nargsf, PyObject *kwnames) | ||
| 99 | + _PyObject_VectorcallTstate(PyThreadState *tstate, PyObject *callable, | ||
| 100 | + PyObject *const *args, size_t nargsf, | ||
| 101 | + PyObject *kwnames) | ||
| 100 | 102 | { | |
| 101 | 103 | assert(kwnames == NULL || PyTuple_Check(kwnames)); | |
| 102 | 104 | assert(args != NULL || PyVectorcall_NARGS(nargsf) == 0); | |
| 103 | 105 | ||
| 104 | - PyThreadState *tstate = PyThreadState_GET(); | ||
| 105 | 106 | vectorcallfunc func = _PyVectorcall_Function(callable); | |
| 106 | 107 | if (func == NULL) { | |
| 107 | 108 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | |
| 108 | - return _PyObject_MakeTpCall(callable, args, nargs, kwnames); | ||
| 109 | + return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames); | ||
| 109 | 110 | } | |
| 110 | 111 | PyObject *res = func(callable, args, nargsf, kwnames); | |
| 111 | 112 | return _Py_CheckFunctionResult(tstate, callable, res, NULL); | |
| 112 | 113 | } | |
| 113 | 114 | ||
| 115 | + static inline PyObject * | ||
| 116 | + _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, | ||
| 117 | + size_t nargsf, PyObject *kwnames) | ||
| 118 | + { | ||
| 119 | + PyThreadState *tstate = PyThreadState_GET(); | ||
| 120 | + return _PyObject_VectorcallTstate(tstate, callable, | ||
| 121 | + args, nargsf, kwnames); | ||
| 122 | + } | ||
| 123 | + | ||
| 114 | 124 | /* Same as _PyObject_Vectorcall except that keyword arguments are passed as | |
| 115 | 125 | dict, which may be NULL if there are no keyword arguments. */ | |
| 116 | 126 | PyAPI_FUNC(PyObject *) _PyObject_FastCallDict( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -132,21 +132,25 @@ partial_dealloc(partialobject *pto) | |||
| 132 | 132 | * if we would need to do that, we stop using vectorcall and fall back | |
| 133 | 133 | * to using partial_call() instead. */ | |
| 134 | 134 | _Py_NO_INLINE static PyObject * | |
| 135 | - partial_vectorcall_fallback(partialobject *pto, PyObject *const *args, | ||
| 136 | - size_t nargsf, PyObject *kwnames) | ||
| 135 | + partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, | ||
| 136 | + PyObject *const *args, size_t nargsf, | ||
| 137 | + PyObject *kwnames) | ||
| 137 | 138 | { | |
| 138 | 139 | pto->vectorcall = NULL; | |
| 139 | 140 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | |
| 140 | - return _PyObject_MakeTpCall((PyObject *)pto, args, nargs, kwnames); | ||
| 141 | + return _PyObject_MakeTpCall(tstate, (PyObject *)pto, | ||
| 142 | + args, nargs, kwnames); | ||
| 141 | 143 | } | |
| 142 | 144 | ||
| 143 | 145 | static PyObject * | |
| 144 | 146 | partial_vectorcall(partialobject *pto, PyObject *const *args, | |
| 145 | 147 | size_t nargsf, PyObject *kwnames) | |
| 146 | 148 | { | |
| 149 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 150 | + | ||
| 147 | 151 | /* pto->kw is mutable, so need to check every time */ | |
| 148 | 152 | if (PyDict_GET_SIZE(pto->kw)) { | |
| 149 | - return partial_vectorcall_fallback(pto, args, nargsf, kwnames); | ||
| 153 | + return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); | ||
| 150 | 154 | } | |
| 151 | 155 | ||
| 152 | 156 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | |
@@ -160,7 +164,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, | |||
| 160 | 164 | ||
| 161 | 165 | /* Fast path if we're called without arguments */ | |
| 162 | 166 | if (nargs_total == 0) { | |
| 163 | - return _PyObject_Vectorcall(pto->fn, pto_args, pto_nargs, NULL); | ||
| 167 | + return _PyObject_VectorcallTstate(tstate, pto->fn, | ||
| 168 | + pto_args, pto_nargs, NULL); | ||
| 164 | 169 | } | |
| 165 | 170 | ||
| 166 | 171 | /* Fast path using PY_VECTORCALL_ARGUMENTS_OFFSET to prepend a single | |
@@ -169,7 +174,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, | |||
| 169 | 174 | PyObject **newargs = (PyObject **)args - 1; | |
| 170 | 175 | PyObject *tmp = newargs[0]; | |
| 171 | 176 | newargs[0] = pto_args[0]; | |
| 172 | - PyObject *ret = _PyObject_Vectorcall(pto->fn, newargs, nargs + 1, kwnames); | ||
| 177 | + PyObject *ret = _PyObject_VectorcallTstate(tstate, pto->fn, | ||
| 178 | + newargs, nargs + 1, kwnames); | ||
| 173 | 179 | newargs[0] = tmp; | |
| 174 | 180 | return ret; | |
| 175 | 181 | } | |
@@ -195,7 +201,8 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, | |||
| 195 | 201 | memcpy(stack, pto_args, pto_nargs * sizeof(PyObject*)); | |
| 196 | 202 | memcpy(stack + pto_nargs, args, nargs_total * sizeof(PyObject*)); | |
| 197 | 203 | ||
| 198 | - ret = _PyObject_Vectorcall(pto->fn, stack, pto_nargs + nargs, kwnames); | ||
| 204 | + ret = _PyObject_VectorcallTstate(tstate, pto->fn, | ||
| 205 | + stack, pto_nargs + nargs, kwnames); | ||
| 199 | 206 | if (stack != small_stack) { | |
| 200 | 207 | PyMem_Free(stack); | |
| 201 | 208 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,7 +104,7 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, | |||
| 104 | 104 | vectorcallfunc func = _PyVectorcall_Function(callable); | |
| 105 | 105 | if (func == NULL) { | |
| 106 | 106 | /* Use tp_call instead */ | |
| 107 | - return _PyObject_MakeTpCall(callable, args, nargs, kwargs); | ||
| 107 | + return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwargs); | ||
| 108 | 108 | } | |
| 109 | 109 | ||
| 110 | 110 | PyObject *res; | |
@@ -129,10 +129,10 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, | |||
| 129 | 129 | ||
| 130 | 130 | ||
| 131 | 131 | PyObject * | |
| 132 | - _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) | ||
| 132 | + _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, | ||
| 133 | + PyObject *const *args, Py_ssize_t nargs, | ||
| 134 | + PyObject *keywords) | ||
| 133 | 135 | { | |
| 134 | - PyThreadState *tstate = _PyThreadState_GET(); | ||
| 135 | - | ||
| 136 | 136 | /* Slow path: build a temporary tuple for positional arguments and a | |
| 137 | 137 | * temporary dictionary for keyword arguments (if any) */ | |
| 138 | 138 | ternaryfunc call = Py_TYPE(callable)->tp_call; | |
@@ -774,6 +774,7 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, | |||
| 774 | 774 | assert(args != NULL); | |
| 775 | 775 | assert(PyVectorcall_NARGS(nargsf) >= 1); | |
| 776 | 776 | ||
| 777 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 777 | 778 | PyObject *callable = NULL; | |
| 778 | 779 | /* Use args[0] as "self" argument */ | |
| 779 | 780 | int unbound = _PyObject_GetMethod(args[0], name, &callable); | |
@@ -792,7 +793,8 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, | |||
| 792 | 793 | args++; | |
| 793 | 794 | nargsf--; | |
| 794 | 795 | } | |
| 795 | - PyObject *result = _PyObject_Vectorcall(callable, args, nargsf, kwnames); | ||
| 796 | + PyObject *result = _PyObject_VectorcallTstate(tstate, callable, | ||
| 797 | + args, nargsf, kwnames); | ||
| 796 | 798 | Py_DECREF(callable); | |
| 797 | 799 | return result; | |
| 798 | 800 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | #include "Python.h" | |
| 4 | 4 | #include "pycore_object.h" | |
| 5 | + #include "pycore_pyerrors.h" | ||
| 5 | 6 | #include "pycore_pymem.h" | |
| 6 | 7 | #include "pycore_pystate.h" | |
| 7 | 8 | #include "structmember.h" | |
@@ -37,25 +38,28 @@ method_vectorcall(PyObject *method, PyObject *const *args, | |||
| 37 | 38 | size_t nargsf, PyObject *kwnames) | |
| 38 | 39 | { | |
| 39 | 40 | assert(Py_TYPE(method) == &PyMethod_Type); | |
| 40 | - PyObject *self, *func, *result; | ||
| 41 | - self = PyMethod_GET_SELF(method); | ||
| 42 | - func = PyMethod_GET_FUNCTION(method); | ||
| 41 | + | ||
| 42 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 43 | + PyObject *self = PyMethod_GET_SELF(method); | ||
| 44 | + PyObject *func = PyMethod_GET_FUNCTION(method); | ||
| 43 | 45 | Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | |
| 44 | 46 | ||
| 47 | + PyObject *result; | ||
| 45 | 48 | if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { | |
| 46 | 49 | /* PY_VECTORCALL_ARGUMENTS_OFFSET is set, so we are allowed to mutate the vector */ | |
| 47 | 50 | PyObject **newargs = (PyObject**)args - 1; | |
| 48 | 51 | nargs += 1; | |
| 49 | 52 | PyObject *tmp = newargs[0]; | |
| 50 | 53 | newargs[0] = self; | |
| 51 | - result = _PyObject_Vectorcall(func, newargs, nargs, kwnames); | ||
| 54 | + result = _PyObject_VectorcallTstate(tstate, func, newargs, | ||
| 55 | + nargs, kwnames); | ||
| 52 | 56 | newargs[0] = tmp; | |
| 53 | 57 | } | |
| 54 | 58 | else { | |
| 55 | 59 | Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); | |
| 56 | 60 | Py_ssize_t totalargs = nargs + nkwargs; | |
| 57 | 61 | if (totalargs == 0) { | |
| 58 | - return _PyObject_Vectorcall(func, &self, 1, NULL); | ||
| 62 | + return _PyObject_VectorcallTstate(tstate, func, &self, 1, NULL); | ||
| 59 | 63 | } | |
| 60 | 64 | ||
| 61 | 65 | PyObject *newargs_stack[_PY_FASTCALL_SMALL_STACK]; | |
@@ -66,7 +70,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, | |||
| 66 | 70 | else { | |
| 67 | 71 | newargs = PyMem_Malloc((totalargs+1) * sizeof(PyObject *)); | |
| 68 | 72 | if (newargs == NULL) { | |
| 69 | - PyErr_NoMemory(); | ||
| 73 | + _PyErr_NoMemory(tstate); | ||
| 70 | 74 | return NULL; | |
| 71 | 75 | } | |
| 72 | 76 | } | |
@@ -77,7 +81,8 @@ method_vectorcall(PyObject *method, PyObject *const *args, | |||
| 77 | 81 | * undefined behaviour. */ | |
| 78 | 82 | assert(args != NULL); | |
| 79 | 83 | memcpy(newargs + 1, args, totalargs * sizeof(PyObject *)); | |
| 80 | - result = _PyObject_Vectorcall(func, newargs, nargs+1, kwnames); | ||
| 84 | + result = _PyObject_VectorcallTstate(tstate, func, | ||
| 85 | + newargs, nargs+1, kwnames); | ||
| 81 | 86 | if (newargs != newargs_stack) { | |
| 82 | 87 | PyMem_Free(newargs); | |
| 83 | 88 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1445,7 +1445,7 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound) | |||
| 1445 | 1445 | ||
| 1446 | 1446 | ||
| 1447 | 1447 | static inline PyObject* | |
| 1448 | - vectorcall_unbound(int unbound, PyObject *func, | ||
| 1448 | + vectorcall_unbound(PyThreadState *tstate, int unbound, PyObject *func, | ||
| 1449 | 1449 | PyObject *const *args, Py_ssize_t nargs) | |
| 1450 | 1450 | { | |
| 1451 | 1451 | size_t nargsf = nargs; | |
@@ -1455,7 +1455,7 @@ vectorcall_unbound(int unbound, PyObject *func, | |||
| 1455 | 1455 | args++; | |
| 1456 | 1456 | nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; | |
| 1457 | 1457 | } | |
| 1458 | - return _PyObject_Vectorcall(func, args, nargsf, NULL); | ||
| 1458 | + return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); | ||
| 1459 | 1459 | } | |
| 1460 | 1460 | ||
| 1461 | 1461 | static PyObject* | |
@@ -1479,24 +1479,27 @@ vectorcall_method(_Py_Identifier *name, | |||
| 1479 | 1479 | PyObject *const *args, Py_ssize_t nargs) | |
| 1480 | 1480 | { | |
| 1481 | 1481 | assert(nargs >= 1); | |
| 1482 | + | ||
| 1483 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 1482 | 1484 | int unbound; | |
| 1483 | 1485 | PyObject *self = args[0]; | |
| 1484 | 1486 | PyObject *func = lookup_method(self, name, &unbound); | |
| 1485 | 1487 | if (func == NULL) { | |
| 1486 | 1488 | return NULL; | |
| 1487 | 1489 | } | |
| 1488 | - PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); | ||
| 1490 | + PyObject *retval = vectorcall_unbound(tstate, unbound, func, args, nargs); | ||
| 1489 | 1491 | Py_DECREF(func); | |
| 1490 | 1492 | return retval; | |
| 1491 | 1493 | } | |
| 1492 | 1494 | ||
| 1493 | 1495 | /* Clone of vectorcall_method() that returns NotImplemented | |
| 1494 | 1496 | * when the lookup fails. */ | |
| 1495 | 1497 | static PyObject * | |
| 1496 | - vectorcall_maybe(_Py_Identifier *name, | ||
| 1498 | + vectorcall_maybe(PyThreadState *tstate, _Py_Identifier *name, | ||
| 1497 | 1499 | PyObject *const *args, Py_ssize_t nargs) | |
| 1498 | 1500 | { | |
| 1499 | 1501 | assert(nargs >= 1); | |
| 1502 | + | ||
| 1500 | 1503 | int unbound; | |
| 1501 | 1504 | PyObject *self = args[0]; | |
| 1502 | 1505 | PyObject *func = lookup_maybe_method(self, name, &unbound); | |
@@ -1505,7 +1508,7 @@ vectorcall_maybe(_Py_Identifier *name, | |||
| 1505 | 1508 | Py_RETURN_NOTIMPLEMENTED; | |
| 1506 | 1509 | return NULL; | |
| 1507 | 1510 | } | |
| 1508 | - PyObject *retval = vectorcall_unbound(unbound, func, args, nargs); | ||
| 1511 | + PyObject *retval = vectorcall_unbound(tstate, unbound, func, args, nargs); | ||
| 1509 | 1512 | Py_DECREF(func); | |
| 1510 | 1513 | return retval; | |
| 1511 | 1514 | } | |
@@ -6177,6 +6180,7 @@ static PyObject * \ | |||
| 6177 | 6180 | FUNCNAME(PyObject *self, PyObject *other) \ | |
| 6178 | 6181 | { \ | |
| 6179 | 6182 | PyObject* stack[2]; \ | |
| 6183 | + PyThreadState *tstate = _PyThreadState_GET(); \ | ||
| 6180 | 6184 | _Py_static_string(op_id, OPSTR); \ | |
| 6181 | 6185 | _Py_static_string(rop_id, ROPSTR); \ | |
| 6182 | 6186 | int do_other = Py_TYPE(self) != Py_TYPE(other) && \ | |
@@ -6193,7 +6197,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ | |||
| 6193 | 6197 | if (ok) { \ | |
| 6194 | 6198 | stack[0] = other; \ | |
| 6195 | 6199 | stack[1] = self; \ | |
| 6196 | - r = vectorcall_maybe(&rop_id, stack, 2); \ | ||
| 6200 | + r = vectorcall_maybe(tstate, &rop_id, stack, 2); \ | ||
| 6197 | 6201 | if (r != Py_NotImplemented) \ | |
| 6198 | 6202 | return r; \ | |
| 6199 | 6203 | Py_DECREF(r); \ | |
@@ -6202,7 +6206,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ | |||
| 6202 | 6206 | } \ | |
| 6203 | 6207 | stack[0] = self; \ | |
| 6204 | 6208 | stack[1] = other; \ | |
| 6205 | - r = vectorcall_maybe(&op_id, stack, 2); \ | ||
| 6209 | + r = vectorcall_maybe(tstate, &op_id, stack, 2); \ | ||
| 6206 | 6210 | if (r != Py_NotImplemented || \ | |
| 6207 | 6211 | Py_TYPE(other) == Py_TYPE(self)) \ | |
| 6208 | 6212 | return r; \ | |
@@ -6211,7 +6215,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ | |||
| 6211 | 6215 | if (do_other) { \ | |
| 6212 | 6216 | stack[0] = other; \ | |
| 6213 | 6217 | stack[1] = self; \ | |
| 6214 | - return vectorcall_maybe(&rop_id, stack, 2); \ | ||
| 6218 | + return vectorcall_maybe(tstate, &rop_id, stack, 2); \ | ||
| 6215 | 6219 | } \ | |
| 6216 | 6220 | Py_RETURN_NOTIMPLEMENTED; \ | |
| 6217 | 6221 | } | |
@@ -6293,6 +6297,7 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) | |||
| 6293 | 6297 | static int | |
| 6294 | 6298 | slot_sq_contains(PyObject *self, PyObject *value) | |
| 6295 | 6299 | { | |
| 6300 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 6296 | 6301 | PyObject *func, *res; | |
| 6297 | 6302 | int result = -1, unbound; | |
| 6298 | 6303 | _Py_IDENTIFIER(__contains__); | |
@@ -6307,7 +6312,7 @@ slot_sq_contains(PyObject *self, PyObject *value) | |||
| 6307 | 6312 | } | |
| 6308 | 6313 | if (func != NULL) { | |
| 6309 | 6314 | PyObject *args[2] = {self, value}; | |
| 6310 | - res = vectorcall_unbound(unbound, func, args, 2); | ||
| 6315 | + res = vectorcall_unbound(tstate, unbound, func, args, 2); | ||
| 6311 | 6316 | Py_DECREF(func); | |
| 6312 | 6317 | if (res != NULL) { | |
| 6313 | 6318 | result = PyObject_IsTrue(res); | |
@@ -6682,6 +6687,7 @@ static _Py_Identifier name_op[] = { | |||
| 6682 | 6687 | static PyObject * | |
| 6683 | 6688 | slot_tp_richcompare(PyObject *self, PyObject *other, int op) | |
| 6684 | 6689 | { | |
| 6690 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 6685 | 6691 | int unbound; | |
| 6686 | 6692 | PyObject *func, *res; | |
| 6687 | 6693 | ||
@@ -6692,7 +6698,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op) | |||
| 6692 | 6698 | } | |
| 6693 | 6699 | ||
| 6694 | 6700 | PyObject *stack[2] = {self, other}; | |
| 6695 | - res = vectorcall_unbound(unbound, func, stack, 2); | ||
| 6701 | + res = vectorcall_unbound(tstate, unbound, func, stack, 2); | ||
| 6696 | 6702 | Py_DECREF(func); | |
| 6697 | 6703 | return res; | |
| 6698 | 6704 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments