17db96d56Sopenharmony_ci/* InterpreterID object */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#include "Python.h" 47db96d56Sopenharmony_ci#include "pycore_abstract.h" // _PyIndex_Check() 57db96d56Sopenharmony_ci#include "pycore_interp.h" // _PyInterpreterState_LookUpID() 67db96d56Sopenharmony_ci#include "pycore_interpreteridobject.h" 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_citypedef struct interpid { 107db96d56Sopenharmony_ci PyObject_HEAD 117db96d56Sopenharmony_ci int64_t id; 127db96d56Sopenharmony_ci} interpid; 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_cistatic interpid * 157db96d56Sopenharmony_cinewinterpid(PyTypeObject *cls, int64_t id, int force) 167db96d56Sopenharmony_ci{ 177db96d56Sopenharmony_ci PyInterpreterState *interp = _PyInterpreterState_LookUpID(id); 187db96d56Sopenharmony_ci if (interp == NULL) { 197db96d56Sopenharmony_ci if (force) { 207db96d56Sopenharmony_ci PyErr_Clear(); 217db96d56Sopenharmony_ci } 227db96d56Sopenharmony_ci else { 237db96d56Sopenharmony_ci return NULL; 247db96d56Sopenharmony_ci } 257db96d56Sopenharmony_ci } 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci if (interp != NULL) { 287db96d56Sopenharmony_ci if (_PyInterpreterState_IDIncref(interp) < 0) { 297db96d56Sopenharmony_ci return NULL; 307db96d56Sopenharmony_ci } 317db96d56Sopenharmony_ci } 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci interpid *self = PyObject_New(interpid, cls); 347db96d56Sopenharmony_ci if (self == NULL) { 357db96d56Sopenharmony_ci if (interp != NULL) { 367db96d56Sopenharmony_ci _PyInterpreterState_IDDecref(interp); 377db96d56Sopenharmony_ci } 387db96d56Sopenharmony_ci return NULL; 397db96d56Sopenharmony_ci } 407db96d56Sopenharmony_ci self->id = id; 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci return self; 437db96d56Sopenharmony_ci} 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_cistatic int 467db96d56Sopenharmony_ciinterp_id_converter(PyObject *arg, void *ptr) 477db96d56Sopenharmony_ci{ 487db96d56Sopenharmony_ci int64_t id; 497db96d56Sopenharmony_ci if (PyObject_TypeCheck(arg, &_PyInterpreterID_Type)) { 507db96d56Sopenharmony_ci id = ((interpid *)arg)->id; 517db96d56Sopenharmony_ci } 527db96d56Sopenharmony_ci else if (_PyIndex_Check(arg)) { 537db96d56Sopenharmony_ci id = PyLong_AsLongLong(arg); 547db96d56Sopenharmony_ci if (id == -1 && PyErr_Occurred()) { 557db96d56Sopenharmony_ci return 0; 567db96d56Sopenharmony_ci } 577db96d56Sopenharmony_ci if (id < 0) { 587db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 597db96d56Sopenharmony_ci "interpreter ID must be a non-negative int, got %R", arg); 607db96d56Sopenharmony_ci return 0; 617db96d56Sopenharmony_ci } 627db96d56Sopenharmony_ci } 637db96d56Sopenharmony_ci else { 647db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 657db96d56Sopenharmony_ci "interpreter ID must be an int, got %.100s", 667db96d56Sopenharmony_ci Py_TYPE(arg)->tp_name); 677db96d56Sopenharmony_ci return 0; 687db96d56Sopenharmony_ci } 697db96d56Sopenharmony_ci *(int64_t *)ptr = id; 707db96d56Sopenharmony_ci return 1; 717db96d56Sopenharmony_ci} 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_cistatic PyObject * 747db96d56Sopenharmony_ciinterpid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) 757db96d56Sopenharmony_ci{ 767db96d56Sopenharmony_ci static char *kwlist[] = {"id", "force", NULL}; 777db96d56Sopenharmony_ci int64_t id; 787db96d56Sopenharmony_ci int force = 0; 797db96d56Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwds, 807db96d56Sopenharmony_ci "O&|$p:InterpreterID.__init__", kwlist, 817db96d56Sopenharmony_ci interp_id_converter, &id, &force)) { 827db96d56Sopenharmony_ci return NULL; 837db96d56Sopenharmony_ci } 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci return (PyObject *)newinterpid(cls, id, force); 867db96d56Sopenharmony_ci} 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_cistatic void 897db96d56Sopenharmony_ciinterpid_dealloc(PyObject *v) 907db96d56Sopenharmony_ci{ 917db96d56Sopenharmony_ci int64_t id = ((interpid *)v)->id; 927db96d56Sopenharmony_ci PyInterpreterState *interp = _PyInterpreterState_LookUpID(id); 937db96d56Sopenharmony_ci if (interp != NULL) { 947db96d56Sopenharmony_ci _PyInterpreterState_IDDecref(interp); 957db96d56Sopenharmony_ci } 967db96d56Sopenharmony_ci else { 977db96d56Sopenharmony_ci // already deleted 987db96d56Sopenharmony_ci PyErr_Clear(); 997db96d56Sopenharmony_ci } 1007db96d56Sopenharmony_ci Py_TYPE(v)->tp_free(v); 1017db96d56Sopenharmony_ci} 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_cistatic PyObject * 1047db96d56Sopenharmony_ciinterpid_repr(PyObject *self) 1057db96d56Sopenharmony_ci{ 1067db96d56Sopenharmony_ci PyTypeObject *type = Py_TYPE(self); 1077db96d56Sopenharmony_ci const char *name = _PyType_Name(type); 1087db96d56Sopenharmony_ci interpid *id = (interpid *)self; 1097db96d56Sopenharmony_ci return PyUnicode_FromFormat("%s(%" PRId64 ")", name, id->id); 1107db96d56Sopenharmony_ci} 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_cistatic PyObject * 1137db96d56Sopenharmony_ciinterpid_str(PyObject *self) 1147db96d56Sopenharmony_ci{ 1157db96d56Sopenharmony_ci interpid *id = (interpid *)self; 1167db96d56Sopenharmony_ci return PyUnicode_FromFormat("%" PRId64 "", id->id); 1177db96d56Sopenharmony_ci} 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_cistatic PyObject * 1207db96d56Sopenharmony_ciinterpid_int(PyObject *self) 1217db96d56Sopenharmony_ci{ 1227db96d56Sopenharmony_ci interpid *id = (interpid *)self; 1237db96d56Sopenharmony_ci return PyLong_FromLongLong(id->id); 1247db96d56Sopenharmony_ci} 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_cistatic PyNumberMethods interpid_as_number = { 1277db96d56Sopenharmony_ci 0, /* nb_add */ 1287db96d56Sopenharmony_ci 0, /* nb_subtract */ 1297db96d56Sopenharmony_ci 0, /* nb_multiply */ 1307db96d56Sopenharmony_ci 0, /* nb_remainder */ 1317db96d56Sopenharmony_ci 0, /* nb_divmod */ 1327db96d56Sopenharmony_ci 0, /* nb_power */ 1337db96d56Sopenharmony_ci 0, /* nb_negative */ 1347db96d56Sopenharmony_ci 0, /* nb_positive */ 1357db96d56Sopenharmony_ci 0, /* nb_absolute */ 1367db96d56Sopenharmony_ci 0, /* nb_bool */ 1377db96d56Sopenharmony_ci 0, /* nb_invert */ 1387db96d56Sopenharmony_ci 0, /* nb_lshift */ 1397db96d56Sopenharmony_ci 0, /* nb_rshift */ 1407db96d56Sopenharmony_ci 0, /* nb_and */ 1417db96d56Sopenharmony_ci 0, /* nb_xor */ 1427db96d56Sopenharmony_ci 0, /* nb_or */ 1437db96d56Sopenharmony_ci (unaryfunc)interpid_int, /* nb_int */ 1447db96d56Sopenharmony_ci 0, /* nb_reserved */ 1457db96d56Sopenharmony_ci 0, /* nb_float */ 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci 0, /* nb_inplace_add */ 1487db96d56Sopenharmony_ci 0, /* nb_inplace_subtract */ 1497db96d56Sopenharmony_ci 0, /* nb_inplace_multiply */ 1507db96d56Sopenharmony_ci 0, /* nb_inplace_remainder */ 1517db96d56Sopenharmony_ci 0, /* nb_inplace_power */ 1527db96d56Sopenharmony_ci 0, /* nb_inplace_lshift */ 1537db96d56Sopenharmony_ci 0, /* nb_inplace_rshift */ 1547db96d56Sopenharmony_ci 0, /* nb_inplace_and */ 1557db96d56Sopenharmony_ci 0, /* nb_inplace_xor */ 1567db96d56Sopenharmony_ci 0, /* nb_inplace_or */ 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_ci 0, /* nb_floor_divide */ 1597db96d56Sopenharmony_ci 0, /* nb_true_divide */ 1607db96d56Sopenharmony_ci 0, /* nb_inplace_floor_divide */ 1617db96d56Sopenharmony_ci 0, /* nb_inplace_true_divide */ 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci (unaryfunc)interpid_int, /* nb_index */ 1647db96d56Sopenharmony_ci}; 1657db96d56Sopenharmony_ci 1667db96d56Sopenharmony_cistatic Py_hash_t 1677db96d56Sopenharmony_ciinterpid_hash(PyObject *self) 1687db96d56Sopenharmony_ci{ 1697db96d56Sopenharmony_ci interpid *id = (interpid *)self; 1707db96d56Sopenharmony_ci PyObject *obj = PyLong_FromLongLong(id->id); 1717db96d56Sopenharmony_ci if (obj == NULL) { 1727db96d56Sopenharmony_ci return -1; 1737db96d56Sopenharmony_ci } 1747db96d56Sopenharmony_ci Py_hash_t hash = PyObject_Hash(obj); 1757db96d56Sopenharmony_ci Py_DECREF(obj); 1767db96d56Sopenharmony_ci return hash; 1777db96d56Sopenharmony_ci} 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_cistatic PyObject * 1807db96d56Sopenharmony_ciinterpid_richcompare(PyObject *self, PyObject *other, int op) 1817db96d56Sopenharmony_ci{ 1827db96d56Sopenharmony_ci if (op != Py_EQ && op != Py_NE) { 1837db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 1847db96d56Sopenharmony_ci } 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci if (!PyObject_TypeCheck(self, &_PyInterpreterID_Type)) { 1877db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 1887db96d56Sopenharmony_ci } 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci interpid *id = (interpid *)self; 1917db96d56Sopenharmony_ci int equal; 1927db96d56Sopenharmony_ci if (PyObject_TypeCheck(other, &_PyInterpreterID_Type)) { 1937db96d56Sopenharmony_ci interpid *otherid = (interpid *)other; 1947db96d56Sopenharmony_ci equal = (id->id == otherid->id); 1957db96d56Sopenharmony_ci } 1967db96d56Sopenharmony_ci else if (PyLong_CheckExact(other)) { 1977db96d56Sopenharmony_ci /* Fast path */ 1987db96d56Sopenharmony_ci int overflow; 1997db96d56Sopenharmony_ci long long otherid = PyLong_AsLongLongAndOverflow(other, &overflow); 2007db96d56Sopenharmony_ci if (otherid == -1 && PyErr_Occurred()) { 2017db96d56Sopenharmony_ci return NULL; 2027db96d56Sopenharmony_ci } 2037db96d56Sopenharmony_ci equal = !overflow && (otherid >= 0) && (id->id == otherid); 2047db96d56Sopenharmony_ci } 2057db96d56Sopenharmony_ci else if (PyNumber_Check(other)) { 2067db96d56Sopenharmony_ci PyObject *pyid = PyLong_FromLongLong(id->id); 2077db96d56Sopenharmony_ci if (pyid == NULL) { 2087db96d56Sopenharmony_ci return NULL; 2097db96d56Sopenharmony_ci } 2107db96d56Sopenharmony_ci PyObject *res = PyObject_RichCompare(pyid, other, op); 2117db96d56Sopenharmony_ci Py_DECREF(pyid); 2127db96d56Sopenharmony_ci return res; 2137db96d56Sopenharmony_ci } 2147db96d56Sopenharmony_ci else { 2157db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 2167db96d56Sopenharmony_ci } 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { 2197db96d56Sopenharmony_ci Py_RETURN_TRUE; 2207db96d56Sopenharmony_ci } 2217db96d56Sopenharmony_ci Py_RETURN_FALSE; 2227db96d56Sopenharmony_ci} 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ciPyDoc_STRVAR(interpid_doc, 2257db96d56Sopenharmony_ci"A interpreter ID identifies a interpreter and may be used as an int."); 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ciPyTypeObject _PyInterpreterID_Type = { 2287db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 2297db96d56Sopenharmony_ci "InterpreterID", /* tp_name */ 2307db96d56Sopenharmony_ci sizeof(interpid), /* tp_basicsize */ 2317db96d56Sopenharmony_ci 0, /* tp_itemsize */ 2327db96d56Sopenharmony_ci (destructor)interpid_dealloc, /* tp_dealloc */ 2337db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 2347db96d56Sopenharmony_ci 0, /* tp_getattr */ 2357db96d56Sopenharmony_ci 0, /* tp_setattr */ 2367db96d56Sopenharmony_ci 0, /* tp_as_async */ 2377db96d56Sopenharmony_ci (reprfunc)interpid_repr, /* tp_repr */ 2387db96d56Sopenharmony_ci &interpid_as_number, /* tp_as_number */ 2397db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 2407db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 2417db96d56Sopenharmony_ci interpid_hash, /* tp_hash */ 2427db96d56Sopenharmony_ci 0, /* tp_call */ 2437db96d56Sopenharmony_ci (reprfunc)interpid_str, /* tp_str */ 2447db96d56Sopenharmony_ci 0, /* tp_getattro */ 2457db96d56Sopenharmony_ci 0, /* tp_setattro */ 2467db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 2477db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 2487db96d56Sopenharmony_ci interpid_doc, /* tp_doc */ 2497db96d56Sopenharmony_ci 0, /* tp_traverse */ 2507db96d56Sopenharmony_ci 0, /* tp_clear */ 2517db96d56Sopenharmony_ci interpid_richcompare, /* tp_richcompare */ 2527db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 2537db96d56Sopenharmony_ci 0, /* tp_iter */ 2547db96d56Sopenharmony_ci 0, /* tp_iternext */ 2557db96d56Sopenharmony_ci 0, /* tp_methods */ 2567db96d56Sopenharmony_ci 0, /* tp_members */ 2577db96d56Sopenharmony_ci 0, /* tp_getset */ 2587db96d56Sopenharmony_ci 0, /* tp_base */ 2597db96d56Sopenharmony_ci 0, /* tp_dict */ 2607db96d56Sopenharmony_ci 0, /* tp_descr_get */ 2617db96d56Sopenharmony_ci 0, /* tp_descr_set */ 2627db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 2637db96d56Sopenharmony_ci 0, /* tp_init */ 2647db96d56Sopenharmony_ci 0, /* tp_alloc */ 2657db96d56Sopenharmony_ci interpid_new, /* tp_new */ 2667db96d56Sopenharmony_ci}; 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ciPyObject *_PyInterpreterID_New(int64_t id) 2697db96d56Sopenharmony_ci{ 2707db96d56Sopenharmony_ci return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); 2717db96d56Sopenharmony_ci} 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_ciPyObject * 2747db96d56Sopenharmony_ci_PyInterpreterState_GetIDObject(PyInterpreterState *interp) 2757db96d56Sopenharmony_ci{ 2767db96d56Sopenharmony_ci if (_PyInterpreterState_IDInitref(interp) != 0) { 2777db96d56Sopenharmony_ci return NULL; 2787db96d56Sopenharmony_ci }; 2797db96d56Sopenharmony_ci int64_t id = PyInterpreterState_GetID(interp); 2807db96d56Sopenharmony_ci if (id < 0) { 2817db96d56Sopenharmony_ci return NULL; 2827db96d56Sopenharmony_ci } 2837db96d56Sopenharmony_ci return (PyObject *)newinterpid(&_PyInterpreterID_Type, id, 0); 2847db96d56Sopenharmony_ci} 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ciPyInterpreterState * 2877db96d56Sopenharmony_ci_PyInterpreterID_LookUp(PyObject *requested_id) 2887db96d56Sopenharmony_ci{ 2897db96d56Sopenharmony_ci int64_t id; 2907db96d56Sopenharmony_ci if (!interp_id_converter(requested_id, &id)) { 2917db96d56Sopenharmony_ci return NULL; 2927db96d56Sopenharmony_ci } 2937db96d56Sopenharmony_ci return _PyInterpreterState_LookUpID(id); 2947db96d56Sopenharmony_ci} 295