~jtaylor/ubuntu/precise/python-numpy/multiarch-fix-818867

« back to all changes in this revision

Viewing changes to numpy/core/src/multiarray/refcount.c

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-10-07 10:19:13 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101007101913-8b1kmt8ho4upcl9s
Tags: 1:1.4.1-5
* debian/patches/10_use_local_python.org_object.inv_sphinx.diff
  - fixed small typo in description
* debian/patches/changeset_r8364.diff
  - fix memory corruption (double free); thanks to Joseph Barillari for the
    report and to Michael Gilbert for pushing resolution; Closes: #581058

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This module corresponds to the `Special functions for PyArray_OBJECT`
 
3
 * section in the numpy reference for C-API.
 
4
 */
 
5
 
 
6
#define PY_SSIZE_T_CLEAN
 
7
#include <Python.h>
 
8
#include "structmember.h"
 
9
 
 
10
#define _MULTIARRAYMODULE
 
11
#define NPY_NO_PREFIX
 
12
#include "numpy/arrayobject.h"
 
13
#include "numpy/arrayscalars.h"
 
14
 
 
15
#include "npy_config.h"
 
16
 
 
17
static void
 
18
_fillobject(char *optr, PyObject *obj, PyArray_Descr *dtype);
 
19
 
 
20
/* Incref all objects found at this record */
 
21
/*NUMPY_API
 
22
 */
 
23
NPY_NO_EXPORT void
 
24
PyArray_Item_INCREF(char *data, PyArray_Descr *descr)
 
25
{
 
26
    PyObject *temp;
 
27
 
 
28
    if (!PyDataType_REFCHK(descr)) {
 
29
        return;
 
30
    }
 
31
    if (descr->type_num == PyArray_OBJECT) {
 
32
        NPY_COPY_PYOBJECT_PTR(&temp, data);
 
33
        Py_XINCREF(temp);
 
34
    }
 
35
    else if (PyDescr_HASFIELDS(descr)) {
 
36
        PyObject *key, *value, *title = NULL;
 
37
        PyArray_Descr *new;
 
38
        int offset;
 
39
        Py_ssize_t pos = 0;
 
40
 
 
41
        while (PyDict_Next(descr->fields, &pos, &key, &value)) {
 
42
            if NPY_TITLE_KEY(key, value) {
 
43
                continue;
 
44
            }
 
45
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
46
                                  &title)) {
 
47
                return;
 
48
            }
 
49
            PyArray_Item_INCREF(data + offset, new);
 
50
        }
 
51
    }
 
52
    return;
 
53
}
 
54
 
 
55
/* XDECREF all objects found at this record */
 
56
/*NUMPY_API
 
57
 */
 
58
NPY_NO_EXPORT void
 
59
PyArray_Item_XDECREF(char *data, PyArray_Descr *descr)
 
60
{
 
61
    PyObject *temp;
 
62
 
 
63
    if (!PyDataType_REFCHK(descr)) {
 
64
        return;
 
65
    }
 
66
 
 
67
    if (descr->type_num == PyArray_OBJECT) {
 
68
        NPY_COPY_PYOBJECT_PTR(&temp, data);
 
69
        Py_XDECREF(temp);
 
70
    }
 
71
    else if PyDescr_HASFIELDS(descr) {
 
72
            PyObject *key, *value, *title = NULL;
 
73
            PyArray_Descr *new;
 
74
            int offset;
 
75
            Py_ssize_t pos = 0;
 
76
 
 
77
            while (PyDict_Next(descr->fields, &pos, &key, &value)) {
 
78
                if NPY_TITLE_KEY(key, value) {
 
79
                    continue;
 
80
                }
 
81
                if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset,
 
82
                                      &title)) {
 
83
                    return;
 
84
                }
 
85
                PyArray_Item_XDECREF(data + offset, new);
 
86
            }
 
87
        }
 
88
    return;
 
89
}
 
90
 
 
91
/* Used for arrays of python objects to increment the reference count of */
 
92
/* every python object in the array. */
 
93
/*NUMPY_API
 
94
  For object arrays, increment all internal references.
 
95
*/
 
96
NPY_NO_EXPORT int
 
97
PyArray_INCREF(PyArrayObject *mp)
 
98
{
 
99
    intp i, n;
 
100
    PyObject **data;
 
101
    PyObject *temp;
 
102
    PyArrayIterObject *it;
 
103
 
 
104
    if (!PyDataType_REFCHK(mp->descr)) {
 
105
        return 0;
 
106
    }
 
107
    if (mp->descr->type_num != PyArray_OBJECT) {
 
108
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
109
        if (it == NULL) {
 
110
            return -1;
 
111
        }
 
112
        while(it->index < it->size) {
 
113
            PyArray_Item_INCREF(it->dataptr, mp->descr);
 
114
            PyArray_ITER_NEXT(it);
 
115
        }
 
116
        Py_DECREF(it);
 
117
        return 0;
 
118
    }
 
119
 
 
120
    if (PyArray_ISONESEGMENT(mp)) {
 
121
        data = (PyObject **)mp->data;
 
122
        n = PyArray_SIZE(mp);
 
123
        if (PyArray_ISALIGNED(mp)) {
 
124
            for (i = 0; i < n; i++, data++) {
 
125
                Py_XINCREF(*data);
 
126
            }
 
127
        }
 
128
        else {
 
129
            for( i = 0; i < n; i++, data++) {
 
130
                NPY_COPY_PYOBJECT_PTR(&temp, data);
 
131
                Py_XINCREF(temp);
 
132
            }
 
133
        }
 
134
    }
 
135
    else { /* handles misaligned data too */
 
136
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
137
        if (it == NULL) {
 
138
            return -1;
 
139
        }
 
140
        while(it->index < it->size) {
 
141
            NPY_COPY_PYOBJECT_PTR(&temp, it->dataptr);
 
142
            Py_XINCREF(temp);
 
143
            PyArray_ITER_NEXT(it);
 
144
        }
 
145
        Py_DECREF(it);
 
146
    }
 
147
    return 0;
 
148
}
 
149
 
 
150
/*NUMPY_API
 
151
  Decrement all internal references for object arrays.
 
152
  (or arrays with object fields)
 
153
*/
 
154
NPY_NO_EXPORT int
 
155
PyArray_XDECREF(PyArrayObject *mp)
 
156
{
 
157
    intp i, n;
 
158
    PyObject **data;
 
159
    PyObject *temp;
 
160
    PyArrayIterObject *it;
 
161
 
 
162
    if (!PyDataType_REFCHK(mp->descr)) {
 
163
        return 0;
 
164
    }
 
165
    if (mp->descr->type_num != PyArray_OBJECT) {
 
166
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
167
        if (it == NULL) {
 
168
            return -1;
 
169
        }
 
170
        while(it->index < it->size) {
 
171
            PyArray_Item_XDECREF(it->dataptr, mp->descr);
 
172
            PyArray_ITER_NEXT(it);
 
173
        }
 
174
        Py_DECREF(it);
 
175
        return 0;
 
176
    }
 
177
 
 
178
    if (PyArray_ISONESEGMENT(mp)) {
 
179
        data = (PyObject **)mp->data;
 
180
        n = PyArray_SIZE(mp);
 
181
        if (PyArray_ISALIGNED(mp)) {
 
182
            for (i = 0; i < n; i++, data++) Py_XDECREF(*data);
 
183
        }
 
184
        else {
 
185
            for (i = 0; i < n; i++, data++) {
 
186
                NPY_COPY_PYOBJECT_PTR(&temp, data);
 
187
                Py_XDECREF(temp);
 
188
            }
 
189
        }
 
190
    }
 
191
    else { /* handles misaligned data too */
 
192
        it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)mp);
 
193
        if (it == NULL) {
 
194
            return -1;
 
195
        }
 
196
        while(it->index < it->size) {
 
197
            NPY_COPY_PYOBJECT_PTR(&temp, it->dataptr);
 
198
            Py_XDECREF(temp);
 
199
            PyArray_ITER_NEXT(it);
 
200
        }
 
201
        Py_DECREF(it);
 
202
    }
 
203
    return 0;
 
204
}
 
205
 
 
206
/*NUMPY_API
 
207
 * Assumes contiguous
 
208
 */
 
209
NPY_NO_EXPORT void
 
210
PyArray_FillObjectArray(PyArrayObject *arr, PyObject *obj)
 
211
{
 
212
    intp i,n;
 
213
    n = PyArray_SIZE(arr);
 
214
    if (arr->descr->type_num == PyArray_OBJECT) {
 
215
        PyObject **optr;
 
216
        optr = (PyObject **)(arr->data);
 
217
        n = PyArray_SIZE(arr);
 
218
        if (obj == NULL) {
 
219
            for (i = 0; i < n; i++) {
 
220
                *optr++ = NULL;
 
221
            }
 
222
        }
 
223
        else {
 
224
            for (i = 0; i < n; i++) {
 
225
                Py_INCREF(obj);
 
226
                *optr++ = obj;
 
227
            }
 
228
        }
 
229
    }
 
230
    else {
 
231
        char *optr;
 
232
        optr = arr->data;
 
233
        for (i = 0; i < n; i++) {
 
234
            _fillobject(optr, obj, arr->descr);
 
235
            optr += arr->descr->elsize;
 
236
        }
 
237
    }
 
238
}
 
239
 
 
240
static void
 
241
_fillobject(char *optr, PyObject *obj, PyArray_Descr *dtype)
 
242
{
 
243
    if (!PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)) {
 
244
        if ((obj == Py_None) || (PyInt_Check(obj) && PyInt_AsLong(obj)==0)) {
 
245
            return;
 
246
        }
 
247
        else {
 
248
            PyObject *arr;
 
249
            Py_INCREF(dtype);
 
250
            arr = PyArray_NewFromDescr(&PyArray_Type, dtype,
 
251
                                       0, NULL, NULL, NULL,
 
252
                                       0, NULL);
 
253
            if (arr!=NULL) {
 
254
                dtype->f->setitem(obj, optr, arr);
 
255
            }
 
256
            Py_XDECREF(arr);
 
257
        }
 
258
    }
 
259
    else if (PyDescr_HASFIELDS(dtype)) {
 
260
        PyObject *key, *value, *title = NULL;
 
261
        PyArray_Descr *new;
 
262
        int offset;
 
263
        Py_ssize_t pos = 0;
 
264
 
 
265
        while (PyDict_Next(dtype->fields, &pos, &key, &value)) {
 
266
            if NPY_TITLE_KEY(key, value) {
 
267
                continue;
 
268
            }
 
269
            if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset, &title)) {
 
270
                return;
 
271
            }
 
272
            _fillobject(optr + offset, obj, new);
 
273
        }
 
274
    }
 
275
    else {
 
276
        Py_XINCREF(obj);
 
277
        NPY_COPY_PYOBJECT_PTR(optr, &obj);
 
278
        return;
 
279
    }
 
280
}
 
281