~meliae-dev/meliae/0.2

« back to all changes in this revision

Viewing changes to meliae/_loader.pyx

  • Committer: John Arbash Meinel
  • Date: 2009-12-23 17:13:12 UTC
  • Revision ID: john@arbash-meinel.com-20091223171312-7rhhmmdb2p7sldqt
Change the internals of _loader a fair amount.

Rather than trying to pack things into C long types, we go ahead
and keep the reference to them. Should be interesting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
    PyObject *PyDict_GetItem(object d, object key)
25
25
    int PyDict_SetItem(object d, object key, object val) except -1
 
26
    void Py_INCREF(PyObject*)
 
27
    void Py_DECREF(PyObject*)
26
28
 
27
29
 
28
30
cdef object _set_default(object d, object val):
41
43
    return val
42
44
 
43
45
 
44
 
cdef object _ref_list_to_list(long *ref_list):
 
46
cdef object _ref_list_to_list(PyObject **ref_list):
45
47
    """Convert the notation of [len, items, ...] into [items].
46
48
 
47
49
    :param ref_list: A pointer to NULL, or to a list of longs. The list should
48
50
        start with the count of items
49
51
    """
50
 
    cdef long i
 
52
    cdef long i, size
51
53
    # TODO: Always return a tuple, we already know the width, and this prevents
52
54
    #       double malloc()
53
55
 
54
56
    if ref_list == NULL:
55
57
        return ()
 
58
    size = <long>(ref_list[0])
56
59
    refs = []
57
 
    for i from 1 <= i <= ref_list[0]:
58
 
        refs.append(ref_list[i])
 
60
    for i from 1 <= i <= size:
 
61
        refs.append(<object>(ref_list[i]))
59
62
    return refs
60
63
 
61
64
 
62
 
cdef long *_list_to_ref_list(object refs) except? NULL:
63
 
    cdef long i, num_refs, *ref_list
64
 
    cdef unsigned long temp
 
65
cdef PyObject **_list_to_ref_list(object refs) except? NULL:
 
66
    cdef long i, num_refs
 
67
    cdef PyObject **ref_list
65
68
 
66
69
    num_refs = len(refs)
67
70
    if num_refs == 0:
68
71
        return NULL
69
 
    ref_list = <long*>PyMem_Malloc(sizeof(long)*(num_refs+1))
70
 
    ref_list[0] = num_refs
 
72
    ref_list = <PyObject**>PyMem_Malloc(sizeof(PyObject*)*(num_refs+1))
 
73
    ref_list[0] = <PyObject*>(num_refs)
71
74
    i = 1
72
75
    for ref in refs:
73
 
        # refs often come in as unsigned integers, internally, we just track
74
 
        # them as ints. Note that we don't support processing a 64-bit dump
75
 
        # on 32-bit platforms. We *could* but it isn't really worth the memory
76
 
        # overhead (yet).
77
 
        temp = ref
78
 
        ref_list[i] = <long>temp
 
76
        # TODO: we *should* incref here, but I'm cheating
 
77
        ref_list[i] = <PyObject*>ref
 
78
        Py_INCREF(ref_list[i])
79
79
        i = i + 1
80
80
    return ref_list
81
81
 
82
82
 
83
 
cdef object _format_list(long *ref_list):
 
83
cdef object _format_list(PyObject **ref_list):
84
84
    cdef long i, num_refs, max_refs
85
85
 
86
86
    if ref_list == NULL:
87
87
        return ''
88
 
    num_refs = ref_list[0]
 
88
    num_refs = <long>ref_list[0]
89
89
    max_refs = num_refs
90
90
    if max_refs > 10:
91
91
        max_refs = 10
92
92
    ref_str = ['[']
93
93
    for i from 0 <= i < max_refs:
94
94
        if i == 0:
95
 
            ref_str.append('%d' % ref_list[i+1])
 
95
            ref_str.append('%d' % (<object>ref_list[i+1]))
96
96
        else:
97
 
            ref_str.append(', %d' % ref_list[i+1])
 
97
            ref_str.append(', %d' % (<object>ref_list[i+1]))
98
98
    if num_refs > 10:
99
99
        ref_str.append(', ...]')
100
100
    else:
130
130
    cdef readonly object type_str # pointer to a PyString, this is expected to be shared
131
131
                                  # with many other instances, but longer than 4 bytes
132
132
    cdef public long size
133
 
    cdef long *_ref_list # An array of addresses that this object
134
 
                         # referenced. May be NULL if len() == 0
135
 
                         # If not null, the first item is the length of the
136
 
                         # list
 
133
    cdef PyObject **_ref_list # An array of addresses that this object
 
134
                              # referenced. May be NULL if len() == 0
 
135
                              # If not null, the first item is the length of the
 
136
                              # list
137
137
    cdef readonly int length # Object length (ob_size), aka len(object)
138
138
    cdef public object value    # May be None, a PyString or a PyInt
139
139
    cdef readonly object name     # Name of this object (only valid for
140
140
                                  # modules, etc)
141
 
    cdef long *_referrer_list # An array of addresses that refer to this,
142
 
                              # if not null, the first item indicates the
143
 
                              # length of the list
 
141
    cdef PyObject **_referrer_list # An array of addresses that refer to this,
 
142
                                   # if not null, the first item indicates the
 
143
                                   # length of the list
144
144
 
145
145
    cdef public unsigned long total_size # Size of everything referenced from
146
146
                                         # this object
176
176
        def __get__(self):
177
177
            if self._ref_list == NULL:
178
178
                return 0
179
 
            return self._ref_list[0]
 
179
            return <long>self._ref_list[0]
180
180
 
181
181
    property referrers:
182
182
        """The list of objects that reference this object.
197
197
        def __get__(self):
198
198
            if self._referrer_list == NULL:
199
199
                return 0
200
 
            return self._referrer_list[0]
 
200
            return <long>self._referrer_list[0]
201
201
 
202
202
    def __dealloc__(self):
 
203
        cdef long i, size
203
204
        if self._ref_list != NULL:
 
205
            size = <long>self._ref_list[0]
 
206
            for i from 1 <= i < size:
 
207
                Py_DECREF(self._ref_list[i])
204
208
            PyMem_Free(self._ref_list)
205
209
            self._ref_list = NULL
206
210
        if self._referrer_list != NULL:
 
211
            size = <long>self._referrer_list[0]
 
212
            for i from 1 <= i < size:
 
213
                Py_DECREF(self._referrer_list[i])
207
214
            PyMem_Free(self._referrer_list)
208
215
            self._referrer_list = NULL
209
216
 
219
226
            ref_space = ''
220
227
            ref_str = ''
221
228
        else:
222
 
            num_refs = self._ref_list[0]
 
229
            num_refs = <long>self._ref_list[0]
223
230
            ref_str = _format_list(self._ref_list)
224
231
            ref_space = ' '
225
232
        if self._referrer_list == NULL:
226
233
            referrer_str = ''
227
234
        else:
228
 
            referrer_str = ', %d referrers %s' % (self._referrer_list[0],
 
235
            referrer_str = ', %d referrers %s' % (
 
236
                <long>self._referrer_list[0],
229
237
                _format_list(self._referrer_list))
230
238
        if self.value is None:
231
239
            value_str = ''