Bug Summary

File:_typeof.c
Warning:line 345, column 33
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name _typeof.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/numba/csa-scan,ctu-index-name=/tmp/pyrefcon/numba/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/numba/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/numba -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -I /usr/lib/python3/dist-packages/numpy/core/include -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wsign-compare -Wall -Wformat -Werror=format-security -Wformat -Werror=format-security -Wdate-time -fdebug-compilation-dir=/tmp/pyrefcon/numba -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/numba/csa-scan/reports -x c numba/_typeof.c

numba/_typeof.c

1#include "_pymodule.h"
2
3#include <string.h>
4#include <time.h>
5#include <assert.h>
6
7#include "_numba_common.h"
8#include "_typeof.h"
9#include "_hashtable.h"
10#include "_devicearray.h"
11#include "pyerrors.h"
12
13#define NPY_NO_DEPRECATED_API0x00000007 NPY_1_7_API_VERSION0x00000007
14#include <numpy/ndarrayobject.h>
15
16
17/* Cached typecodes for basic scalar types */
18static int tc_int8;
19static int tc_int16;
20static int tc_int32;
21static int tc_int64;
22static int tc_uint8;
23static int tc_uint16;
24static int tc_uint32;
25static int tc_uint64;
26static int tc_float32;
27static int tc_float64;
28static int tc_complex64;
29static int tc_complex128;
30static int BASIC_TYPECODES[12];
31
32static int tc_intp;
33
34/* The type object for the numba .dispatcher.OmittedArg class
35 * that wraps omitted arguments.
36 */
37static PyObject *omittedarg_type;
38
39static PyObject *typecache;
40static PyObject *ndarray_typecache;
41static PyObject *structured_dtypes;
42
43static PyObject *str_typeof_pyval = NULL((void*)0);
44static PyObject *str_value = NULL((void*)0);
45static PyObject *str_numba_type = NULL((void*)0);
46
47/* CUDA device array API */
48void **DeviceArray_API;
49
50/*
51 * Type fingerprint computation.
52 */
53
54typedef struct {
55 /* A buffer the fingerprint will be written to */
56 char *buf;
57 size_t n;
58 size_t allocated;
59 /* A preallocated buffer, sufficient to fit the fingerprint for most types */
60 char static_buf[40];
61} string_writer_t;
62
63static void
64string_writer_init(string_writer_t *w)
65{
66 w->buf = w->static_buf;
67 w->n = 0;
68 w->allocated = sizeof(w->static_buf) / sizeof(unsigned char);
69}
70
71static void
72string_writer_clear(string_writer_t *w)
73{
74 if (w->buf != w->static_buf)
75 free(w->buf);
76}
77
78static void
79string_writer_move(string_writer_t *dest, const string_writer_t *src)
80{
81 dest->n = src->n;
82 dest->allocated = src->allocated;
83 if (src->buf == src->static_buf) {
84 dest->buf = dest->static_buf;
85 memcpy(dest->buf, src->buf, src->n);
86 }
87 else {
88 dest->buf = src->buf;
89 }
90}
91
92/* Ensure at least *bytes* can be appended to the string writer's buffer. */
93static int
94string_writer_ensure(string_writer_t *w, size_t bytes)
95{
96 size_t newsize;
97 bytes += w->n;
98 if (bytes <= w->allocated)
99 return 0;
100 newsize = (w->allocated << 2) + 1;
101 if (newsize < bytes)
102 newsize = bytes;
103 if (w->buf == w->static_buf)
104 w->buf = malloc(newsize);
105 else
106 w->buf = realloc(w->buf, newsize);
107 if (w->buf) {
108 w->allocated = newsize;
109 return 0;
110 }
111 else {
112 PyErr_NoMemory();
113 return -1;
114 }
115}
116
117static int
118string_writer_put_char(string_writer_t *w, unsigned char c)
119{
120 if (string_writer_ensure(w, 1))
121 return -1;
122 w->buf[w->n++] = c;
123 return 0;
124}
125
126static int
127string_writer_put_int32(string_writer_t *w, unsigned int v)
128{
129 if (string_writer_ensure(w, 4))
130 return -1;
131 w->buf[w->n] = v & 0xff;
132 w->buf[w->n + 1] = (v >> 8) & 0xff;
133 w->buf[w->n + 2] = (v >> 16) & 0xff;
134 w->buf[w->n + 3] = (v >> 24) & 0xff;
135 w->n += 4;
136 return 0;
137}
138
139static int
140string_writer_put_intp(string_writer_t *w, npy_intp v)
141{
142 if (string_writer_ensure(w, NPY_SIZEOF_PY_INTPTR_T8))
143 return -1;
144 w->buf[w->n] = v & 0xff;
145 w->buf[w->n + 1] = (v >> 8) & 0xff;
146 w->buf[w->n + 2] = (v >> 16) & 0xff;
147 w->buf[w->n + 3] = (v >> 24) & 0xff;
148#if NPY_SIZEOF_PY_INTPTR_T8 == 8
149 w->buf[w->n + 4] = (v >> 32) & 0xff;
150 w->buf[w->n + 5] = (v >> 40) & 0xff;
151 w->buf[w->n + 6] = (v >> 48) & 0xff;
152 w->buf[w->n + 7] = (v >> 56) & 0xff;
153#endif
154 w->n += NPY_SIZEOF_PY_INTPTR_T8;
155 return 0;
156}
157
158static int
159string_writer_put_string(string_writer_t *w, const char *s)
160{
161 if (s == NULL((void*)0)) {
162 return string_writer_put_char(w, 0);
163 }
164 else {
165 size_t N = strlen(s) + 1;
166 if (string_writer_ensure(w, N))
167 return -1;
168 memcpy(w->buf + w->n, s, N);
169 w->n += N;
170 return 0;
171 }
172}
173
174enum opcode {
175 OP_START_TUPLE = '(',
176 OP_END_TUPLE = ')',
177 OP_INT = 'i',
178 OP_FLOAT = 'f',
179 OP_COMPLEX = 'c',
180 OP_BOOL = '?',
181 OP_OMITTED = '!',
182
183 OP_BYTEARRAY = 'a',
184 OP_BYTES = 'b',
185 OP_NONE = 'n',
186 OP_LIST = '[',
187 OP_SET = '{',
188
189 OP_BUFFER = 'B',
190 OP_NP_SCALAR = 'S',
191 OP_NP_ARRAY = 'A',
192 OP_NP_DTYPE = 'D'
193};
194
195#define TRY(func, w, arg)do { if (func(w, arg)) return -1; } while (0) \
196 do { \
197 if (func(w, arg)) return -1; \
198 } while (0)
199
200
201static int
202fingerprint_unrecognized(void)
203{
204 PyErr_SetString(PyExc_NotImplementedError,
205 "cannot compute type fingerprint for value");
206 return -1;
207}
208
209static int
210compute_dtype_fingerprint(string_writer_t *w, PyArray_Descr *descr)
211{
212 int typenum = descr->type_num;
213 if (typenum < NPY_OBJECT)
214 return string_writer_put_char(w, (char) typenum);
215 if (typenum == NPY_VOID) {
216 /* Structured dtype: serialize the dtype pointer. Unfortunately,
217 * some structured dtypes can be ephemeral, so we have to
218 * intern them to avoid pointer reuse and fingerprint collisions.
219 * (e.g. np.recarray(dtype=some_dtype) creates a new dtype
220 * equal to some_dtype)
221 */
222 PyObject *interned = PyDict_GetItem(structured_dtypes,
223 (PyObject *) descr);
224 if (interned == NULL((void*)0)) {
225 interned = (PyObject *) descr;
226 if (PyDict_SetItem(structured_dtypes, interned, interned))
227 return -1;
228 }
229 TRY(string_writer_put_char, w, (char) typenum)do { if (string_writer_put_char(w, (char) typenum)) return -1
; } while (0)
;
230 return string_writer_put_intp(w, (npy_intp) interned);
231 }
232#if NPY_API_VERSION0x0000000D >= 0x00000007
233 if (PyTypeNum_ISDATETIME(typenum)(((typenum) >=NPY_DATETIME) && ((typenum) <=NPY_TIMEDELTA
))
) {
234 PyArray_DatetimeMetaData *md;
235 md = &(((PyArray_DatetimeDTypeMetaData *)descr->c_metadata)->meta);
236 TRY(string_writer_put_char, w, (char) typenum)do { if (string_writer_put_char(w, (char) typenum)) return -1
; } while (0)
;
237 TRY(string_writer_put_char, w, (char) md->base)do { if (string_writer_put_char(w, (char) md->base)) return
-1; } while (0)
;
238 return string_writer_put_int32(w, (char) md->num);
239 }
240#endif
241
242 return fingerprint_unrecognized();
243}
244
245static int
246compute_fingerprint(string_writer_t *w, PyObject *val)
247{
248 /*
249 * Implementation note: for performance, we start with common
250 * types that can be tested with fast checks.
251 */
252 if (val == Py_None(&_Py_NoneStruct))
1
Assuming the condition is false
2
Taking false branch
253 return string_writer_put_char(w, OP_NONE);
254 if (PyBool_Check(val)((((PyObject*)(val))->ob_type) == &PyBool_Type))
3
Assuming the condition is false
4
Taking false branch
255 return string_writer_put_char(w, OP_BOOL);
256 /* Note we avoid matching int subclasses such as IntEnum */
257 if (PyInt_CheckExact(val)((((PyObject*)(val))->ob_type) == &PyLong_Type) || PyLong_CheckExact(val)((((PyObject*)(val))->ob_type) == &PyLong_Type))
5
Assuming the condition is false
6
Assuming the condition is false
7
Taking false branch
258 return string_writer_put_char(w, OP_INT);
259 if (PyFloat_Check(val)((((PyObject*)(val))->ob_type) == (&PyFloat_Type) || PyType_IsSubtype
((((PyObject*)(val))->ob_type), (&PyFloat_Type)))
)
8
Assuming the condition is false
9
Assuming the condition is false
10
Taking false branch
260 return string_writer_put_char(w, OP_FLOAT);
261 if (PyComplex_CheckExact(val)((((PyObject*)(val))->ob_type) == &PyComplex_Type))
11
Assuming the condition is false
12
Taking false branch
262 return string_writer_put_char(w, OP_COMPLEX);
263 if (PyTuple_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL
<< 26))) != 0)
) {
13
Assuming the condition is false
14
Taking false branch
264 if(PyTuple_CheckExact(val)((((PyObject*)(val))->ob_type) == &PyTuple_Type)) {
265 Py_ssize_t i, n;
266 n = PyTuple_GET_SIZE(val)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(val))))->
ob_size)
;
267 TRY(string_writer_put_char, w, OP_START_TUPLE)do { if (string_writer_put_char(w, OP_START_TUPLE)) return -1
; } while (0)
;
268 for (i = 0; i < n; i++)
269 TRY(compute_fingerprint, w, PyTuple_GET_ITEM(val, i))do { if (compute_fingerprint(w, ((((void) (0)), (PyTupleObject
*)(val))->ob_item[i]))) return -1; } while (0)
;
270 TRY(string_writer_put_char, w, OP_END_TUPLE)do { if (string_writer_put_char(w, OP_END_TUPLE)) return -1; }
while (0)
;
271 return 0;
272 }
273 /* as per typeof.py, check "_asdict" for namedtuple. */
274 else if(PyObject_HasAttrString(val, "_asdict"))
275 {
276 /*
277 * This encodes the class name and field names of a namedtuple into
278 * the fingerprint on the condition that the number of fields is
279 * small (<10) and that the class name and field names are encodable
280 * as ASCII.
281 */
282 PyObject * clazz = NULL((void*)0);
283 PyObject * name = NULL((void*)0);
284 PyObject * _fields = PyObject_GetAttrString(val, "_fields");
285 PyObject * field = NULL((void*)0);
286 PyObject * ascii_str = NULL((void*)0);
287 Py_ssize_t i, n, j, flen;
288 char * buf = NULL((void*)0);
289 int ret;
290
291 clazz = PyObject_GetAttrString(val, "__class__");
292 if (clazz == NULL((void*)0))
293 return -1;
294
295 name = PyObject_GetAttrString(clazz, "__name__");
296 Py_DECREF(clazz)_Py_DECREF(((PyObject*)(clazz)));
297 if (name == NULL((void*)0))
298 return -1;
299
300 ascii_str = PyUnicode_AsEncodedString(name, "ascii", "ignore");
301 Py_DECREF(name)_Py_DECREF(((PyObject*)(name)));
302 if (ascii_str == NULL((void*)0))
303 return -1;
304 ret = PyBytes_AsStringAndSize(ascii_str, &buf, &flen);
305
306 if (ret == -1)
307 return -1;
308 for(j = 0; j < flen; j++) {
309 TRY(string_writer_put_char, w, buf[j])do { if (string_writer_put_char(w, buf[j])) return -1; } while
(0)
;
310 }
311 Py_DECREF(ascii_str)_Py_DECREF(((PyObject*)(ascii_str)));
312
313 if (_fields == NULL((void*)0))
314 return -1;
315
316 n = PyTuple_GET_SIZE(val)(((PyVarObject*)((((void) (0)), (PyTupleObject *)(val))))->
ob_size)
;
317
318 TRY(string_writer_put_char, w, OP_START_TUPLE)do { if (string_writer_put_char(w, OP_START_TUPLE)) return -1
; } while (0)
;
319 for (i = 0; i < n; i++) {
320 field = PyTuple_GET_ITEM(_fields, i)((((void) (0)), (PyTupleObject *)(_fields))->ob_item[i]);
321 if (field == NULL((void*)0))
322 return -1;
323 ascii_str = PyUnicode_AsEncodedString(field, "ascii", "ignore");
324 if (ascii_str == NULL((void*)0))
325 return -1;
326 ret = PyBytes_AsStringAndSize(ascii_str, &buf, &flen);
327 if (ret == -1)
328 return -1;
329 for(j = 0; j < flen; j++) {
330 TRY(string_writer_put_char, w, buf[j])do { if (string_writer_put_char(w, buf[j])) return -1; } while
(0)
;
331 }
332 Py_DECREF(ascii_str)_Py_DECREF(((PyObject*)(ascii_str)));
333 TRY(compute_fingerprint, w, PyTuple_GET_ITEM(val, i))do { if (compute_fingerprint(w, ((((void) (0)), (PyTupleObject
*)(val))->ob_item[i]))) return -1; } while (0)
;
334 }
335 TRY(string_writer_put_char, w, OP_END_TUPLE)do { if (string_writer_put_char(w, OP_END_TUPLE)) return -1; }
while (0)
;
336 Py_DECREF(_fields)_Py_DECREF(((PyObject*)(_fields)));
337 return 0;
338 }
339 }
340 if (PyBytes_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL
<< 27))) != 0)
)
15
Assuming the condition is false
16
Taking false branch
341 return string_writer_put_char(w, OP_BYTES);
342 if (PyByteArray_Check(val)((((PyObject*)(val))->ob_type) == (&PyByteArray_Type) ||
PyType_IsSubtype((((PyObject*)(val))->ob_type), (&PyByteArray_Type
)))
)
17
Assuming the condition is false
18
Assuming the condition is false
19
Taking false branch
343 return string_writer_put_char(w, OP_BYTEARRAY);
344 if ((PyObject *) Py_TYPE(val)(((PyObject*)(val))->ob_type) == omittedarg_type) {
20
Assuming 'omittedarg_type' is equal to field 'ob_type'
21
Taking true branch
345 PyObject *default_val = PyObject_GetAttr(val, str_value);
22
Calling 'PyObject_GetAttr'
24
Returning from 'PyObject_GetAttr'
28
PyObject ownership leak with reference count of 1
346 if (default_val == NULL((void*)0))
25
Assuming 'default_val' is not equal to NULL
26
Taking false branch
347 return -1;
348 TRY(string_writer_put_char, w, OP_OMITTED)do { if (string_writer_put_char(w, OP_OMITTED)) return -1; } while
(0)
;
27
Taking true branch
349 TRY(compute_fingerprint, w, default_val)do { if (compute_fingerprint(w, default_val)) return -1; } while
(0)
;
350 Py_DECREF(default_val)_Py_DECREF(((PyObject*)(default_val)));
351 return 0;
352 }
353 if (PyArray_IsScalar(val, Generic)(((((PyObject*)(val))->ob_type) == (&(*(PyTypeObject *
)PyArray_API[10])) || PyType_IsSubtype((((PyObject*)(val))->
ob_type), (&(*(PyTypeObject *)PyArray_API[10])))))
) {
354 /* Note: PyArray_DescrFromScalar() may be a bit slow on
355 non-trivial types. */
356 PyArray_Descr *descr = PyArray_DescrFromScalar(*(PyArray_Descr * (*)(PyObject *)) PyArray_API[57])(val);
357 if (descr == NULL((void*)0))
358 return -1;
359 TRY(string_writer_put_char, w, OP_NP_SCALAR)do { if (string_writer_put_char(w, OP_NP_SCALAR)) return -1; }
while (0)
;
360 TRY(compute_dtype_fingerprint, w, descr)do { if (compute_dtype_fingerprint(w, descr)) return -1; } while
(0)
;
361 Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr)));
362 return 0;
363 }
364 if (PyArray_Check(val)((((PyObject*)(val))->ob_type) == (&(*(PyTypeObject *)
PyArray_API[2])) || PyType_IsSubtype((((PyObject*)(val))->
ob_type), (&(*(PyTypeObject *)PyArray_API[2]))))
) {
365 PyArrayObject *ary = (PyArrayObject *) val;
366 int ndim = PyArray_NDIM(ary);
367
368 TRY(string_writer_put_char, w, OP_NP_ARRAY)do { if (string_writer_put_char(w, OP_NP_ARRAY)) return -1; }
while (0)
;
369 TRY(string_writer_put_int32, w, ndim)do { if (string_writer_put_int32(w, ndim)) return -1; } while
(0)
;
370 if (PyArray_IS_C_CONTIGUOUS(ary)PyArray_CHKFLAGS((ary), 0x0001))
371 TRY(string_writer_put_char, w, 'C')do { if (string_writer_put_char(w, 'C')) return -1; } while (
0)
;
372 else if (PyArray_IS_F_CONTIGUOUS(ary)PyArray_CHKFLAGS((ary), 0x0002))
373 TRY(string_writer_put_char, w, 'F')do { if (string_writer_put_char(w, 'F')) return -1; } while (
0)
;
374 else
375 TRY(string_writer_put_char, w, 'A')do { if (string_writer_put_char(w, 'A')) return -1; } while (
0)
;
376 if (PyArray_ISWRITEABLE(ary)PyArray_CHKFLAGS((ary), 0x0400))
377 TRY(string_writer_put_char, w, 'W')do { if (string_writer_put_char(w, 'W')) return -1; } while (
0)
;
378 else
379 TRY(string_writer_put_char, w, 'R')do { if (string_writer_put_char(w, 'R')) return -1; } while (
0)
;
380 return compute_dtype_fingerprint(w, PyArray_DESCR(ary));
381 }
382 if (PyList_Check(val)((((((PyObject*)(val))->ob_type))->tp_flags & ((1UL
<< 25))) != 0)
) {
383 Py_ssize_t n = PyList_GET_SIZE(val)(((void) (0)), (((PyVarObject*)(val))->ob_size));
384 if (n == 0) {
385 PyErr_SetString(PyExc_ValueError,
386 "cannot compute fingerprint of empty list");
387 return -1;
388 }
389 /* Only the first item is considered, as in typeof.py */
390 TRY(string_writer_put_char, w, OP_LIST)do { if (string_writer_put_char(w, OP_LIST)) return -1; } while
(0)
;
391 TRY(compute_fingerprint, w, PyList_GET_ITEM(val, 0))do { if (compute_fingerprint(w, (((PyListObject *)(val))->
ob_item[0]))) return -1; } while (0)
;
392 return 0;
393 }
394 /* Note we only accept sets, not frozensets */
395 if (Py_TYPE(val)(((PyObject*)(val))->ob_type) == &PySet_Type) {
396 Py_hash_t h;
397 PyObject *item;
398 Py_ssize_t pos = 0;
399 /* Only one item is considered, as in typeof.py */
400 if (!_PySet_NextEntry(val, &pos, &item, &h)) {
401 /* Empty set */
402 PyErr_SetString(PyExc_ValueError,
403 "cannot compute fingerprint of empty set");
404 return -1;
405 }
406 TRY(string_writer_put_char, w, OP_SET)do { if (string_writer_put_char(w, OP_SET)) return -1; } while
(0)
;
407 TRY(compute_fingerprint, w, item)do { if (compute_fingerprint(w, item)) return -1; } while (0);
408 return 0;
409 }
410 if (PyObject_CheckBuffer(val)(((val)->ob_type->tp_as_buffer != ((void*)0)) &&
((val)->ob_type->tp_as_buffer->bf_getbuffer != ((void
*)0)))
) {
411 Py_buffer buf;
412 int flags = PyBUF_ND0x0008 | PyBUF_STRIDES(0x0010 | 0x0008) | PyBUF_FORMAT0x0004;
413 char contig;
414 int ndim;
415 char readonly;
416
417 /* Attempt to get a writable buffer, then fallback on read-only */
418 if (PyObject_GetBuffer(val, &buf, flags | PyBUF_WRITABLE0x0001)) {
419 PyErr_Clear();
420 if (PyObject_GetBuffer(val, &buf, flags))
421 goto _unrecognized;
422 }
423 if (PyBuffer_IsContiguous(&buf, 'C'))
424 contig = 'C';
425 else if (PyBuffer_IsContiguous(&buf, 'F'))
426 contig = 'F';
427 else
428 contig = 'A';
429 ndim = buf.ndim;
430 readonly = buf.readonly ? 'R' : 'W';
431 if (string_writer_put_char(w, OP_BUFFER) ||
432 string_writer_put_int32(w, ndim) ||
433 string_writer_put_char(w, contig) ||
434 string_writer_put_char(w, readonly) ||
435 string_writer_put_string(w, buf.format) ||
436 /* We serialize the object's Python type as well, to
437 distinguish between types which have Numba specializations
438 (e.g. array.array() vs. memoryview)
439 */
440 string_writer_put_intp(w, (npy_intp) Py_TYPE(val)(((PyObject*)(val))->ob_type))) {
441 PyBuffer_Release(&buf);
442 return -1;
443 }
444 PyBuffer_Release(&buf);
445 return 0;
446 }
447 if (NUMBA_PyArray_DescrCheck(val)((((PyObject*)(val))->ob_type) == (&(*(PyTypeObject *)
PyArray_API[3])) || PyType_IsSubtype((((PyObject*)(val))->
ob_type), (&(*(PyTypeObject *)PyArray_API[3]))))
) {
448 TRY(string_writer_put_char, w, OP_NP_DTYPE)do { if (string_writer_put_char(w, OP_NP_DTYPE)) return -1; }
while (0)
;
449 return compute_dtype_fingerprint(w, (PyArray_Descr *) val);
450 }
451
452_unrecognized:
453 /* Type not recognized */
454 return fingerprint_unrecognized();
455}
456
457PyObject *
458typeof_compute_fingerprint(PyObject *val)
459{
460 PyObject *res;
461 string_writer_t w;
462
463 string_writer_init(&w);
464
465 if (compute_fingerprint(&w, val))
466 goto error;
467 res = PyBytes_FromStringAndSize(w.buf, w.n);
468
469 string_writer_clear(&w);
470 return res;
471
472error:
473 string_writer_clear(&w);
474 return NULL((void*)0);
475}
476
477/*
478 * Getting the typecode from a Type object.
479 */
480static int
481_typecode_from_type_object(PyObject *tyobj) {
482 int typecode;
483 PyObject *tmpcode = PyObject_GetAttrString(tyobj, "_code");
484 if (tmpcode == NULL((void*)0)) {
485 return -1;
486 }
487 typecode = PyLong_AsLong(tmpcode);
488 Py_DECREF(tmpcode)_Py_DECREF(((PyObject*)(tmpcode)));
489 return typecode;
490}
491
492/* When we want to cache the type's typecode for later lookup, we need to
493 keep a reference to the returned type object so that it cannot be
494 deleted. This is because of the following events occurring when first
495 using a @jit function for a given set of types:
496
497 1. typecode_fallback requests a new typecode for an arbitrary Python value;
498 this implies creating a Numba type object (on the first dispatcher call);
499 the typecode cache is then populated.
500 2. matching of the typecode list in _dispatcherimpl.cpp fails, since the
501 typecode is new.
502 3. we have to compile: compile_and_invoke() is called, it will invoke
503 Dispatcher_Insert to register the new signature.
504
505 The reference to the Numba type object returned in step 1 is deleted as
506 soon as we call Py_DECREF() on it, since we are holding the only
507 reference. If this happens and we use the typecode we got to populate the
508 cache, then the cache won't ever return the correct typecode, and the
509 dispatcher will never successfully match the typecodes with those of
510 some already-compiled instance. So we need to make sure that we don't
511 call Py_DECREF() on objects whose typecode will be used to populate the
512 cache. This is ensured by calling _typecode_fallback with
513 retain_reference == 0.
514
515 Note that technically we are leaking the reference, since we do not continue
516 to hold a pointer to the type object that we get back from typeof_pyval.
517 However, we don't need to refer to it again, we just need to make sure that
518 it is never deleted.
519*/
520static int
521_typecode_fallback(PyObject *dispatcher, PyObject *val,
522 int retain_reference) {
523 PyObject *numba_type;
524 int typecode;
525
526 /*
527 * For values that define "_numba_type_", which holds a numba Type
528 * instance that should be used as the type of the value.
529 * Note this is done here, not in typeof_typecode(), so that
530 * some values can still benefit from fingerprint caching.
531 */
532 if (PyObject_HasAttr(val, str_numba_type)) {
533 numba_type = PyObject_GetAttrString(val, "_numba_type_");
534 if (!numba_type)
535 return -1;
536 }
537 else {
538 // Go back to the interpreter
539 numba_type = PyObject_CallMethodObjArgs((PyObject *) dispatcher,
540 str_typeof_pyval, val, NULL((void*)0));
541 }
542 if (!numba_type)
543 return -1;
544 typecode = _typecode_from_type_object(numba_type);
545 if (!retain_reference)
546 Py_DECREF(numba_type)_Py_DECREF(((PyObject*)(numba_type)));
547 return typecode;
548}
549
550/* Variations on _typecode_fallback for convenience */
551
552static
553int typecode_fallback(PyObject *dispatcher, PyObject *val) {
554 return _typecode_fallback(dispatcher, val, 0);
555}
556
557static
558int typecode_fallback_keep_ref(PyObject *dispatcher, PyObject *val) {
559 return _typecode_fallback(dispatcher, val, 1);
560}
561
562
563/* A cache mapping fingerprints (string_writer_t *) to typecodes (int). */
564static _Numba_hashtable_t *fingerprint_hashtable = NULL((void*)0);
565
566static Py_uhash_t
567hash_writer(const void *key)
568{
569 string_writer_t *writer = (string_writer_t *) key;
570 Py_uhash_t x = 0;
571
572 /* The old FNV algorithm used by Python 2 */
573 if (writer->n > 0) {
574 unsigned char *p = (unsigned char *) writer->buf;
575 Py_ssize_t len = writer->n;
576 x ^= *p << 7;
577 while (--len >= 0)
578 x = (1000003*x) ^ *p++;
579 x ^= writer->n;
580 if (x == (Py_uhash_t) -1)
581 x = -2;
582 }
583 return x;
584}
585
586static int
587compare_writer(const void *key, const _Numba_hashtable_entry_t *entry)
588{
589 string_writer_t *v = (string_writer_t *) key;
590 string_writer_t *w = (string_writer_t *) entry->key;
591 if (v->n != w->n)
592 return 0;
593 return memcmp(v->buf, w->buf, v->n) == 0;
594}
595
596/* Try to compute *val*'s typecode using its fingerprint and the
597 * fingerprint->typecode cache.
598 */
599static int
600typecode_using_fingerprint(PyObject *dispatcher, PyObject *val)
601{
602 int typecode;
603 string_writer_t w;
604
605 string_writer_init(&w);
606
607 if (compute_fingerprint(&w, val)) {
608 string_writer_clear(&w);
609 if (PyErr_ExceptionMatches(PyExc_NotImplementedError)) {
610 /* Can't compute a type fingerprint for the given value,
611 fall back on typeof() without caching. */
612 PyErr_Clear();
613 return typecode_fallback(dispatcher, val);
614 }
615 return -1;
616 }
617 if (_Numba_HASHTABLE_GET(fingerprint_hashtable, &w, typecode)_Numba_hashtable_get(fingerprint_hashtable, &w, &(typecode
), sizeof(typecode))
> 0) {
618 /* Cache hit */
619 string_writer_clear(&w);
620 return typecode;
621 }
622
623 /* Not found in cache: invoke pure Python typeof() and cache result.
624 * Note we have to keep the type alive forever as explained
625 * above in _typecode_fallback().
626 */
627 typecode = typecode_fallback_keep_ref(dispatcher, val);
628 if (typecode >= 0) {
629 string_writer_t *key = (string_writer_t *) malloc(sizeof(string_writer_t));
630 if (key == NULL((void*)0)) {
631 string_writer_clear(&w);
632 PyErr_NoMemory();
633 return -1;
634 }
635 /* Ownership of the string writer's buffer will be transferred
636 * to the hash table.
637 */
638 string_writer_move(key, &w);
639 if (_Numba_HASHTABLE_SET(fingerprint_hashtable, key, typecode)_Numba_hashtable_set(fingerprint_hashtable, key, &(typecode
), sizeof(typecode))
) {
640 string_writer_clear(&w);
641 PyErr_NoMemory();
642 return -1;
643 }
644 }
645 return typecode;
646}
647
648
649/*
650 * Direct lookup table for extra-fast typecode resolution of simple array types.
651 */
652
653#define N_DTYPES12 12
654#define N_NDIM5 5 /* Fast path for up to 5D array */
655#define N_LAYOUT3 3
656static int cached_arycode[N_NDIM5][N_LAYOUT3][N_DTYPES12];
657
658/* Convert a Numpy dtype number to an internal index into cached_arycode.
659 The returned value must also be a valid index into BASIC_TYPECODES. */
660static int dtype_num_to_typecode(int type_num) {
661 int dtype;
662 switch(type_num) {
663 case NPY_INT8NPY_BYTE:
664 dtype = 0;
665 break;
666 case NPY_INT16NPY_SHORT:
667 dtype = 1;
668 break;
669 case NPY_INT32NPY_INT:
670 dtype = 2;
671 break;
672 case NPY_INT64NPY_LONG:
673 dtype = 3;
674 break;
675 case NPY_UINT8NPY_UBYTE:
676 dtype = 4;
677 break;
678 case NPY_UINT16NPY_USHORT:
679 dtype = 5;
680 break;
681 case NPY_UINT32NPY_UINT:
682 dtype = 6;
683 break;
684 case NPY_UINT64NPY_ULONG:
685 dtype = 7;
686 break;
687 case NPY_FLOAT32NPY_FLOAT:
688 dtype = 8;
689 break;
690 case NPY_FLOAT64NPY_DOUBLE:
691 dtype = 9;
692 break;
693 case NPY_COMPLEX64NPY_CFLOAT:
694 dtype = 10;
695 break;
696 case NPY_COMPLEX128NPY_CDOUBLE:
697 dtype = 11;
698 break;
699 default:
700 /* Type not included in the global lookup table */
701 dtype = -1;
702 }
703 return dtype;
704}
705
706static
707int get_cached_typecode(PyArray_Descr* descr) {
708 PyObject* tmpobject = PyDict_GetItem(typecache, (PyObject*)descr);
709 if (tmpobject == NULL((void*)0))
710 return -1;
711
712 return PyLong_AsLong(tmpobject);
713}
714
715static
716void cache_typecode(PyArray_Descr* descr, int typecode) {
717 PyObject* value = PyLong_FromLong(typecode);
718 PyDict_SetItem(typecache, (PyObject*)descr, value);
719 Py_DECREF(value)_Py_DECREF(((PyObject*)(value)));
720}
721
722static
723PyObject* ndarray_key(int ndim, int layout, PyArray_Descr* descr) {
724 PyObject* tmpndim = PyLong_FromLong(ndim);
725 PyObject* tmplayout = PyLong_FromLong(layout);
726 PyObject* key = PyTuple_Pack(3, tmpndim, tmplayout, descr);
727 Py_DECREF(tmpndim)_Py_DECREF(((PyObject*)(tmpndim)));
728 Py_DECREF(tmplayout)_Py_DECREF(((PyObject*)(tmplayout)));
729 return key;
730}
731
732static
733int get_cached_ndarray_typecode(int ndim, int layout, PyArray_Descr* descr) {
734 PyObject* key = ndarray_key(ndim, layout, descr);
735 PyObject *tmpobject = PyDict_GetItem(ndarray_typecache, key);
736 if (tmpobject == NULL((void*)0))
737 return -1;
738
739 Py_DECREF(key)_Py_DECREF(((PyObject*)(key)));
740 return PyLong_AsLong(tmpobject);
741}
742
743static
744void cache_ndarray_typecode(int ndim, int layout, PyArray_Descr* descr,
745 int typecode) {
746 PyObject* key = ndarray_key(ndim, layout, descr);
747 PyObject* value = PyLong_FromLong(typecode);
748 PyDict_SetItem(ndarray_typecache, key, value);
749 Py_DECREF(key)_Py_DECREF(((PyObject*)(key)));
750 Py_DECREF(value)_Py_DECREF(((PyObject*)(value)));
751}
752
753static
754int typecode_ndarray(PyObject *dispatcher, PyArrayObject *ary) {
755 int typecode;
756 int dtype;
757 int ndim = PyArray_NDIM(ary);
758 int layout = 0;
759
760 /* The order in which we check for the right contiguous-ness is important.
761 The order must match the order by numba.numpy_support.map_layout.
762 Further, only *contiguous-ness* is checked, not alignment, byte order or
763 write permissions.
764 */
765 if (PyArray_IS_C_CONTIGUOUS(ary)PyArray_CHKFLAGS((ary), 0x0001)){
766 layout = 1;
767 } else if (PyArray_IS_F_CONTIGUOUS(ary)PyArray_CHKFLAGS((ary), 0x0002)) {
768 layout = 2;
769 }
770
771 /* the typecode cache by convention is for "behaved" arrays (aligned and
772 * writeable), all others must be forced to the fall back */
773 if (!PyArray_ISBEHAVED(ary)(PyArray_CHKFLAGS(ary, (0x0100 | 0x0400)) && ((PyArray_DESCR
(ary)->byteorder) != '>'))
) goto FALLBACK;
774
775 if (ndim <= 0 || ndim > N_NDIM5) goto FALLBACK;
776
777 dtype = dtype_num_to_typecode(PyArray_TYPE(ary));
778 if (dtype == -1) goto FALLBACK;
779
780 /* Fast path, using direct table lookup */
781 assert(layout < N_LAYOUT)((void) (0));
782 assert(ndim <= N_NDIM)((void) (0));
783 assert(dtype < N_DTYPES)((void) (0));
784
785 typecode = cached_arycode[ndim - 1][layout][dtype];
786 if (typecode == -1) {
787 /* First use of this table entry, so it requires populating */
788 typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
789 cached_arycode[ndim - 1][layout][dtype] = typecode;
790 }
791 return typecode;
792
793FALLBACK:
794 /* Slower path, for non-trivial array types */
795
796 /* If this isn't a structured array then we can't use the cache */
797 if (PyArray_TYPE(ary) != NPY_VOID)
798 return typecode_using_fingerprint(dispatcher, (PyObject *) ary);
799
800 /* Check type cache */
801 typecode = get_cached_ndarray_typecode(ndim, layout, PyArray_DESCR(ary));
802 if (typecode == -1) {
803 /* First use of this type, use fallback and populate the cache */
804 typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
805 cache_ndarray_typecode(ndim, layout, PyArray_DESCR(ary), typecode);
806 }
807 return typecode;
808}
809
810static
811int typecode_arrayscalar(PyObject *dispatcher, PyObject* aryscalar) {
812 int typecode;
813 PyArray_Descr *descr;
814 descr = PyArray_DescrFromScalar(*(PyArray_Descr * (*)(PyObject *)) PyArray_API[57])(aryscalar);
815 if (!descr)
816 return typecode_using_fingerprint(dispatcher, aryscalar);
817
818 /* Is it a structured scalar? */
819 if (descr->type_num == NPY_VOID) {
820 typecode = get_cached_typecode(descr);
821 if (typecode == -1) {
822 /* Resolve through fallback then populate cache */
823 typecode = typecode_fallback_keep_ref(dispatcher, aryscalar);
824 cache_typecode(descr, typecode);
825 }
826 Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr)));
827 return typecode;
828 }
829
830 /* Is it one of the well-known basic types? */
831 typecode = dtype_num_to_typecode(descr->type_num);
832 Py_DECREF(descr)_Py_DECREF(((PyObject*)(descr)));
833 if (typecode == -1)
834 return typecode_using_fingerprint(dispatcher, aryscalar);
835 return BASIC_TYPECODES[typecode];
836}
837
838static
839int typecode_devicendarray(PyObject *dispatcher, PyObject *ary)
840{
841 int typecode;
842 int dtype;
843 int ndim;
844 int layout = 0;
845
846 PyObject* flags = PyObject_GetAttrString(ary, "flags");
847 if (flags == NULL((void*)0))
848 {
849 PyErr_Clear();
850 goto FALLBACK;
851 }
852
853 if (PyDict_GetItemString(flags, "C_CONTIGUOUS") == Py_True((PyObject *) &_Py_TrueStruct)) {
854 layout = 1;
855 } else if (PyDict_GetItemString(flags, "F_CONTIGUOUS") == Py_True((PyObject *) &_Py_TrueStruct)) {
856 layout = 2;
857 }
858
859 Py_DECREF(flags)_Py_DECREF(((PyObject*)(flags)));
860
861 PyObject *ndim_obj = PyObject_GetAttrString(ary, "ndim");
862 if (ndim_obj == NULL((void*)0)) {
863 /* If there's no ndim, try to proceed by clearing the error and using the
864 * fallback. */
865 PyErr_Clear();
866 goto FALLBACK;
867 }
868
869 ndim = PyLong_AsLong(ndim_obj);
870 Py_DECREF(ndim_obj)_Py_DECREF(((PyObject*)(ndim_obj)));
871
872 if (PyErr_Occurred()) {
873 /* ndim wasn't an integer for some reason - unlikely to happen, but try
874 * the fallback. */
875 PyErr_Clear();
876 goto FALLBACK;
877 }
878
879 if (ndim <= 0 || ndim > N_NDIM5)
880 goto FALLBACK;
881
882 PyObject* dtype_obj = PyObject_GetAttrString(ary, "dtype");
883 if (dtype_obj == NULL((void*)0)) {
884 /* No dtype: try the fallback. */
885 PyErr_Clear();
886 goto FALLBACK;
887 }
888
889 PyObject* num_obj = PyObject_GetAttrString(dtype_obj, "num");
890 Py_DECREF(dtype_obj)_Py_DECREF(((PyObject*)(dtype_obj)));
891
892 if (num_obj == NULL((void*)0)) {
893 /* This strange dtype has no num - try the fallback. */
894 PyErr_Clear();
895 goto FALLBACK;
896 }
897
898 int dtype_num = PyLong_AsLong(num_obj);
899 Py_DECREF(num_obj)_Py_DECREF(((PyObject*)(num_obj)));
900
901 if (PyErr_Occurred()) {
902 /* num wasn't an integer for some reason - unlikely to happen, but try
903 * the fallback. */
904 PyErr_Clear();
905 goto FALLBACK;
906 }
907
908 dtype = dtype_num_to_typecode(dtype_num);
909 if (dtype == -1) {
910 /* Not a dtype we have in the global lookup table. */
911 goto FALLBACK;
912 }
913
914 /* Fast path, using direct table lookup */
915 assert(layout < N_LAYOUT)((void) (0));
916 assert(ndim <= N_NDIM)((void) (0));
917 assert(dtype < N_DTYPES)((void) (0));
918 typecode = cached_arycode[ndim - 1][layout][dtype];
919
920 if (typecode == -1) {
921 /* First use of this table entry, so it requires populating */
922 typecode = typecode_fallback_keep_ref(dispatcher, (PyObject*)ary);
923 cached_arycode[ndim - 1][layout][dtype] = typecode;
924 }
925
926 return typecode;
927
928FALLBACK:
929 /* Slower path, for non-trivial array types. At present this always uses
930 the fingerprinting to get the typecode. Future optimization might
931 implement a cache, but this would require some fast equivalent of
932 PyArray_DESCR for a device array. */
933
934 return typecode_using_fingerprint(dispatcher, (PyObject *) ary);
935}
936
937int
938typeof_typecode(PyObject *dispatcher, PyObject *val)
939{
940 PyTypeObject *tyobj = Py_TYPE(val)(((PyObject*)(val))->ob_type);
941 int subtype_attr;
942 /* This needs to be kept in sync with Dispatcher.typeof_pyval(),
943 * otherwise funny things may happen.
944 */
945 if (tyobj == &PyInt_TypePyLong_Type || tyobj == &PyLong_Type) {
946#if SIZEOF_VOID_P8 < 8
947 /* On 32-bit platforms, choose between tc_intp (32-bit) and tc_int64 */
948 PY_LONG_LONGlong long ll = PyLong_AsLongLong(val);
949 if (ll == -1 && PyErr_Occurred()) {
950 /* The integer is too large, let us truncate it */
951 PyErr_Clear();
952 return tc_int64;
953 }
954 if ((ll & 0xffffffff) != ll)
955 return tc_int64;
956#endif
957 return tc_intp;
958 }
959 else if (tyobj == &PyFloat_Type)
960 return tc_float64;
961 else if (tyobj == &PyComplex_Type)
962 return tc_complex128;
963 /* Array scalar handling */
964 else if (PyArray_CheckScalar(val)((((((PyObject*)(val))->ob_type) == (&(*(PyTypeObject *
)PyArray_API[10])) || PyType_IsSubtype((((PyObject*)(val))->
ob_type), (&(*(PyTypeObject *)PyArray_API[10]))))) || (((
((PyObject*)(val))->ob_type) == (&(*(PyTypeObject *)PyArray_API
[2])) || PyType_IsSubtype((((PyObject*)(val))->ob_type), (
&(*(PyTypeObject *)PyArray_API[2])))) && (PyArray_NDIM
((PyArrayObject *)val) == 0)))
) {
965 return typecode_arrayscalar(dispatcher, val);
966 }
967 /* Array handling */
968 else if (tyobj == &PyArray_Type(*(PyTypeObject *)PyArray_API[2])) {
969 return typecode_ndarray(dispatcher, (PyArrayObject*)val);
970 }
971 /* Subtype of CUDA device array */
972 else if (PyType_IsSubtype(tyobj, &DeviceArrayType(*(PyTypeObject*)DeviceArray_API[0]))) {
973 return typecode_devicendarray(dispatcher, val);
974 }
975 /* Subtypes of Array handling */
976 else if (PyType_IsSubtype(tyobj, &PyArray_Type(*(PyTypeObject *)PyArray_API[2]))) {
977 /* By default, Numba will treat all numpy.ndarray subtypes as if they
978 were the base numpy.ndarray type. In this way, ndarray subtypes
979 can easily use all of the support that Numba has for ndarray
980 methods.
981 EXPERIMENTAL: There may be cases where a programmer would NOT want
982 ndarray subtypes to be treated exactly like the base numpy.ndarray.
983 For this purpose, a currently experimental feature allows a
984 programmer to add an attribute named
985 __numba_array_subtype_dispatch__ to their ndarray subtype. This
986 attribute can have any value as Numba only checks for the presence
987 of the attribute and not its value. When present, a ndarray subtype
988 will NOT be typed by Numba as a regular ndarray but this code will
989 fallthrough to the typecode_using_fingerprint call, which will
990 create a new unique Numba typecode for this ndarray subtype. This
991 behavior has several significant effects. First, since this
992 ndarray subtype will be treated as a different type by Numba,
993 the Numba dispatcher would then specialize on this type. So, if
994 there was a function that had several parameters that were
995 expected to be either numpy.ndarray or a subtype of ndarray, then
996 Numba would compile a custom version of this function for each
997 combination of base and subtypes that were actually passed to the
998 function. Second, because this subtype would now be treated as
999 a totally separate type, it will cease to function in Numba unless
1000 an implementation of that type is provided to Numba through the
1001 Numba type extension mechanisms (e.g., overload). This would
1002 typically start with defining a Numba type corresponding to the
1003 ndarray subtype. This is the same concept as how Numba has a
1004 corollary of numpy.ndarray in its type system as types.Array.
1005 Next, one would typically defining boxing and unboxing routines
1006 and the associated memory model. Then, overloads for NumPy
1007 functions on that type would be created. However,
1008 if the same default array memory model is used then there are tricks
1009 one can do to look at Numba's internal types.Array registries and
1010 to quickly apply those to the subtype as well. In this manner,
1011 only those cases where the base ndarray and the ndarray subtype
1012 behavior differ would new custom functions need to be written for
1013 the subtype. Finally,
1014 after adding support for the new type, you would have a separate
1015 ndarray subtype that could operate with other objects of the same
1016 subtype but would not support interoperation with regular NumPy
1017 ndarrays. In standard Python, this interoperation is provided
1018 through the __array_ufunc__ magic method in the ndarray subtype
1019 class and in that case the function operates on ndarrays or their
1020 subtypes. This idea is extended into Numba such that
1021 __array_ufunc__ can be present in a Numba array type object.
1022 In this case, this function is consulted during Numba typing and
1023 so the arguments to __array_ufunc__ are Numba types instead of
1024 ndarray subtypes. The array type __array_ufunc__ returns the
1025 type of the output of the given ufunc.
1026 */
1027 subtype_attr = PyObject_HasAttrString(val, "__numba_array_subtype_dispatch__");
1028 if (!subtype_attr) {
1029 return typecode_ndarray(dispatcher, (PyArrayObject*)val);
1030 }
1031 }
1032
1033 return typecode_using_fingerprint(dispatcher, val);
1034}
1035
1036
1037static
1038void* wrap_import_array(void) {
1039 import_array(){if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(
PyExc_ImportError, "numpy.core.multiarray failed to import");
return ((void*)0); } }
; /* import array returns NULL on failure */
1040 return (void*)1;
1041}
1042
1043
1044static
1045int init_numpy(void) {
1046 return wrap_import_array() != NULL((void*)0);
1047}
1048
1049
1050/*
1051 * typeof_init(omittedarg_type, typecode_dict)
1052 * (called from dispatcher.py to fill in missing information)
1053 */
1054PyObject *
1055typeof_init(PyObject *self, PyObject *args)
1056{
1057 PyObject *tmpobj;
1058 PyObject *dict;
1059 int index = 0;
1060
1061 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "O!O!:typeof_init",
1062 &PyType_Type, &omittedarg_type,
1063 &PyDict_Type, &dict))
1064 return NULL((void*)0);
1065
1066 /* Initialize Numpy API */
1067 if ( ! init_numpy() ) {
1068 return NULL((void*)0);
1069 }
1070
1071 #define UNWRAP_TYPE(S) \
1072 if(!(tmpobj = PyDict_GetItemString(dict, #S))) return NULL((void*)0); \
1073 else { tc_##S = PyLong_AsLong(tmpobj); \
1074 BASIC_TYPECODES[index++] = tc_##S; }
1075
1076 UNWRAP_TYPE(int8)
1077 UNWRAP_TYPE(int16)
1078 UNWRAP_TYPE(int32)
1079 UNWRAP_TYPE(int64)
1080
1081 UNWRAP_TYPE(uint8)
1082 UNWRAP_TYPE(uint16)
1083 UNWRAP_TYPE(uint32)
1084 UNWRAP_TYPE(uint64)
1085
1086 UNWRAP_TYPE(float32)
1087 UNWRAP_TYPE(float64)
1088
1089 UNWRAP_TYPE(complex64)
1090 UNWRAP_TYPE(complex128)
1091
1092 switch(sizeof(void*)) {
1093 case 4:
1094 tc_intp = tc_int32;
1095 break;
1096 case 8:
1097 tc_intp = tc_int64;
1098 break;
1099 default:
1100 PyErr_SetString(PyExc_AssertionError, "sizeof(void*) != {4, 8}");
1101 return NULL((void*)0);
1102 }
1103
1104 #undef UNWRAP_TYPE
1105
1106 typecache = PyDict_New();
1107 ndarray_typecache = PyDict_New();
1108 structured_dtypes = PyDict_New();
1109 if (typecache == NULL((void*)0) || ndarray_typecache == NULL((void*)0) ||
1110 structured_dtypes == NULL((void*)0)) {
1111 PyErr_SetString(PyExc_RuntimeError, "failed to create type cache");
1112 return NULL((void*)0);
1113 }
1114
1115 fingerprint_hashtable = _Numba_hashtable_new(sizeof(int),
1116 hash_writer,
1117 compare_writer);
1118 if (fingerprint_hashtable == NULL((void*)0)) {
1119 PyErr_NoMemory();
1120 return NULL((void*)0);
1121 }
1122
1123 /* initialize cached_arycode to all ones (in bits) */
1124 memset(cached_arycode, 0xFF, sizeof(cached_arycode));
1125
1126 str_typeof_pyval = PyString_InternFromStringPyUnicode_InternFromString("typeof_pyval");
1127 str_value = PyString_InternFromStringPyUnicode_InternFromString("value");
1128 str_numba_type = PyString_InternFromStringPyUnicode_InternFromString("_numba_type_");
1129 if (!str_value || !str_typeof_pyval || !str_numba_type)
1130 return NULL((void*)0);
1131
1132 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
1133}

/opt/pyrefcon/lib/pyrefcon/models/models/PyObject_GetAttr.model

1#ifndef PyObject_GetAttr
2PyObject* clang_analyzer_PyObject_New_Reference();
3PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) {
4 return clang_analyzer_PyObject_New_Reference();
23
Setting reference count to 1
5}
6#else
7#warning "API PyObject_GetAttr is defined as a macro."
8#endif