File: | experimental/jitclass/_box.c |
Warning: | line 176, column 24 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | Implements jitclass Box type in python c-api level. | |||
3 | */ | |||
4 | #include "../../_pymodule.h" | |||
5 | ||||
6 | typedef struct { | |||
7 | PyObject_HEADPyObject ob_base; | |||
8 | void *meminfoptr, *dataptr; | |||
9 | } BoxObject; | |||
10 | ||||
11 | ||||
12 | /* Store function defined in numba.core.runtime._nrt_python for use in box_dealloc. | |||
13 | * It points to a function is code segment that does not need user deallocation | |||
14 | * and does not disappear while the process is stil running. | |||
15 | */ | |||
16 | static void (*MemInfo_release)(void*) = NULL((void*)0); | |||
17 | ||||
18 | ||||
19 | /* | |||
20 | * Box.__init__() | |||
21 | * Takes no arguments. | |||
22 | * meminfoptr and dataptr are set to NULL. | |||
23 | */ | |||
24 | static | |||
25 | int Box_init(BoxObject *self, PyObject *args, PyObject *kwds) { | |||
26 | static char *keywords[] = {NULL((void*)0)}; | |||
27 | if (!PyArg_ParseTupleAndKeywords_PyArg_ParseTupleAndKeywords_SizeT(args, kwds, "", keywords)) | |||
28 | { | |||
29 | return -1; | |||
30 | } | |||
31 | /* Initialize attributes to NULL */ | |||
32 | self->meminfoptr = NULL((void*)0); | |||
33 | self->dataptr = NULL((void*)0); | |||
34 | return 0; | |||
35 | } | |||
36 | ||||
37 | /* | |||
38 | * Box destructor | |||
39 | * Release MemInfo pointed by meminfoptr. | |||
40 | * Free the instance. | |||
41 | */ | |||
42 | static | |||
43 | void box_dealloc(BoxObject *box) | |||
44 | { | |||
45 | if (box->meminfoptr) MemInfo_release((void*)box->meminfoptr); | |||
46 | Py_TYPE(box)(((PyObject*)(box))->ob_type)->tp_free((PyObject *) box); | |||
47 | } | |||
48 | ||||
49 | ||||
50 | static const char Box_doc[] = "A box for numba created jit-class instance"; | |||
51 | ||||
52 | ||||
53 | static PyTypeObject BoxType = { | |||
54 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, | |||
55 | "_box.Box", /*tp_name*/ | |||
56 | sizeof(BoxObject), /*tp_basicsize*/ | |||
57 | 0, /*tp_itemsize*/ | |||
58 | (destructor)box_dealloc, /*tp_dealloc*/ | |||
59 | 0, /*tp_print*/ | |||
60 | 0, /*tp_getattr*/ | |||
61 | 0, /*tp_setattr*/ | |||
62 | 0, /*tp_compare*/ | |||
63 | 0, /*tp_repr*/ | |||
64 | 0, /*tp_as_number*/ | |||
65 | 0, /*tp_as_sequence*/ | |||
66 | 0, /*tp_as_mapping*/ | |||
67 | 0, /*tp_hash */ | |||
68 | 0, /*tp_call*/ | |||
69 | 0, /*tp_str*/ | |||
70 | 0, /*tp_getattro*/ | |||
71 | 0, /*tp_setattro*/ | |||
72 | 0, /*tp_as_buffer*/ | |||
73 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0) | Py_TPFLAGS_BASETYPE(1UL << 10), /*tp_flags*/ | |||
74 | Box_doc, /* tp_doc */ | |||
75 | 0, /* tp_traverse */ | |||
76 | 0, /* tp_clear */ | |||
77 | 0, /* tp_richcompare */ | |||
78 | 0, /* tp_weaklistoffset */ | |||
79 | 0, /* tp_iter */ | |||
80 | 0, /* tp_iternext */ | |||
81 | 0, /* tp_methods */ | |||
82 | 0, /* tp_members */ | |||
83 | 0, /* tp_getset */ | |||
84 | 0, /* tp_base */ | |||
85 | 0, /* tp_dict */ | |||
86 | 0, /* tp_descr_get */ | |||
87 | 0, /* tp_descr_set */ | |||
88 | 0, /* tp_dictoffset */ | |||
89 | (initproc)Box_init, /* tp_init */ | |||
90 | 0, /* tp_alloc */ | |||
91 | PyType_GenericNew, /* tp_new */ | |||
92 | }; | |||
93 | ||||
94 | ||||
95 | /* Import MemInfo_Release from numba.core.runtime._nrt_python once for use in | |||
96 | * Box_dealloc. | |||
97 | */ | |||
98 | static void * | |||
99 | import_meminfo_release(void) { | |||
100 | PyObject *nrtmod = NULL((void*)0); | |||
101 | PyObject *helperdct = NULL((void*)0); | |||
102 | PyObject *mi_rel_fn = NULL((void*)0); | |||
103 | void *fnptr = NULL((void*)0); | |||
104 | /* from numba.core.runtime import _nrt_python */ | |||
105 | nrtmod = PyImport_ImportModule("numba.core.runtime._nrt_python"); | |||
106 | if (!nrtmod) goto cleanup; | |||
107 | /* helperdct = _nrt_python.c_helpers */ | |||
108 | helperdct = PyObject_GetAttrString(nrtmod, "c_helpers"); | |||
109 | if (!helperdct) goto cleanup; | |||
110 | /* helperdct['MemInfo_release'] */ | |||
111 | mi_rel_fn = PyDict_GetItemString(helperdct, "MemInfo_release"); | |||
112 | if (!mi_rel_fn) goto cleanup; | |||
113 | fnptr = PyLong_AsVoidPtr(mi_rel_fn); | |||
114 | ||||
115 | cleanup: | |||
116 | Py_XDECREF(nrtmod)_Py_XDECREF(((PyObject*)(nrtmod))); | |||
117 | Py_XDECREF(helperdct)_Py_XDECREF(((PyObject*)(helperdct))); | |||
118 | return fnptr; | |||
119 | } | |||
120 | ||||
121 | /* Debug utils. | |||
122 | * Get internal dataptr field from Box. | |||
123 | */ | |||
124 | static | |||
125 | PyObject* box_get_dataptr(PyObject *self, PyObject *args) { | |||
126 | BoxObject *box; | |||
127 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &BoxType, (PyObject*)&box)) | |||
128 | return NULL((void*)0); | |||
129 | return PyLong_FromVoidPtr(box->dataptr); | |||
130 | } | |||
131 | ||||
132 | /* Debug utils. | |||
133 | * Get internal meminfoptr field from Box. | |||
134 | */ | |||
135 | static | |||
136 | PyObject* box_get_meminfoptr(PyObject *self, PyObject *args) { | |||
137 | BoxObject *box; | |||
138 | if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!", &BoxType, (PyObject*)&box)) | |||
139 | return NULL((void*)0); | |||
140 | return PyLong_FromVoidPtr(box->meminfoptr); | |||
141 | } | |||
142 | ||||
143 | ||||
144 | static PyMethodDef ext_methods[] = { | |||
145 | #define declmethod(func) { #func , ( PyCFunction )func , METH_VARARGS0x0001 , NULL((void*)0) } | |||
146 | declmethod(box_get_dataptr), | |||
147 | declmethod(box_get_meminfoptr), | |||
148 | { NULL((void*)0) }, | |||
149 | #undef declmethod | |||
150 | }; | |||
151 | ||||
152 | ||||
153 | MOD_INIT(_box)PyObject* PyInit__box(void) { | |||
154 | PyObject *m; | |||
155 | ||||
156 | MOD_DEF(m, "_box", "No docs", ext_methods){ static struct PyModuleDef moduledef = { { { 1, ((void*)0) } , ((void*)0), 0, ((void*)0), }, "_box", "No docs", -1, ext_methods , ((void*)0), ((void*)0), ((void*)0), ((void*)0) }; m = PyModule_Create2 (&moduledef, 1013); } | |||
157 | if (m == NULL((void*)0)) | |||
| ||||
158 | return MOD_ERROR_VAL((void*)0); | |||
159 | ||||
160 | /* init BoxType */ | |||
161 | if (PyType_Ready(&BoxType)) | |||
162 | return MOD_ERROR_VAL((void*)0); | |||
163 | ||||
164 | /* import and cache NRT_MemInfo_release function pointer */ | |||
165 | MemInfo_release = import_meminfo_release(); | |||
166 | if (!MemInfo_release) return MOD_ERROR_VAL((void*)0); | |||
167 | ||||
168 | /* bind BoxType */ | |||
169 | Py_INCREF(&BoxType)_Py_INCREF(((PyObject*)(&BoxType))); | |||
170 | PyModule_AddObject(m, "Box", (PyObject *) (&BoxType)); | |||
171 | ||||
172 | /* bind address to direct access utils */; | |||
173 | PyModule_AddObject(m, "box_meminfoptr_offset", | |||
174 | PyLong_FromSsize_t(offsetof(BoxObject, meminfoptr)__builtin_offsetof(BoxObject, meminfoptr))); | |||
175 | PyModule_AddObject(m, "box_dataptr_offset", | |||
176 | PyLong_FromSsize_t(offsetof(BoxObject, dataptr)__builtin_offsetof(BoxObject, dataptr))); | |||
| ||||
177 | ||||
178 | return MOD_SUCCESS_VAL(m)m; | |||
179 | } |
1 | #ifndef PyLong_FromSsize_t |
2 | PyObject* clang_analyzer_PyObject_New_Reference(); |
3 | PyObject* PyLong_FromSsize_t(Py_ssize_t v) { |
4 | return clang_analyzer_PyObject_New_Reference(); |
5 | } |
6 | #else |
7 | #warning "API PyLong_FromSsize_t is defined as a macro." |
8 | #endif |