Rev 103: Change _loader.pyx to use a real PyInt for address. in http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
John Arbash Meinel
john at arbash-meinel.com
Thu Oct 22 22:47:50 BST 2009
At http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
------------------------------------------------------------
revno: 103
revision-id: john at arbash-meinel.com-20091022214742-8w54cvqz9r1vvte5
parent: john at arbash-meinel.com-20091022212953-jq44i34175i5by8f
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: trunk
timestamp: Thu 2009-10-22 16:47:42 -0500
message:
Change _loader.pyx to use a real PyInt for address.
This way we don't have to worry as much about de-duping the address.
We need a real int anyway, because we shove all of these into a dict.
As such, we should also change how ref_list, etc works. Since they
also will already have to exist...
-------------- next part --------------
=== modified file 'meliae/_loader.pyx'
--- a/meliae/_loader.pyx 2009-10-17 03:01:58 +0000
+++ b/meliae/_loader.pyx 2009-10-22 21:47:42 +0000
@@ -22,6 +22,25 @@
void *malloc(size_t)
void free(void *)
+ PyObject *PyDict_GetItem(object d, object key)
+ int PyDict_SetItem(object d, object key, object val) except -1
+
+
+cdef object _set_default(object d, object val):
+ """Either return the value in the dict, or return 'val'.
+
+ This is the same as Dict.setdefault, but without the attribute lookups. (It
+ may be slightly worse because it does 2 dict lookups?)
+ """
+ cdef PyObject *tmp
+
+ tmp = PyDict_GetItem(d, val)
+ if tmp == NULL:
+ PyDict_SetItem(d, val, val)
+ else:
+ val = <object>tmp
+ return val
+
cdef object _ref_list_to_list(long *ref_list):
"""Convert the notation of [len, items, ...] into [items].
@@ -105,7 +124,10 @@
:ivar name: Some objects have associated names, like modules, classes, etc.
"""
- cdef readonly long address
+ cdef readonly object address # We track the address by pointing to a PyInt
+ # This is valid, because we put these objects
+ # into a dict anyway, so we need a PyInt
+ # And we can just share it
cdef readonly object type_str # pointer to a PyString, this is expected to be shared
# with many other instances, but longer than 4 bytes
cdef public long size
@@ -126,9 +148,7 @@
def __init__(self, address, type_str, size, ref_list, length=None,
value=None, name=None):
- cdef unsigned long temp_address
- temp_address = address
- self.address = <long>temp_address
+ self.address = address
self.type_str = type_str
self.size = size
self._ref_list = _list_to_ref_list(ref_list)
@@ -239,7 +259,8 @@
referrer_str, value_str, total_size_str))
def _intern_from_cache(self, cache):
- self.type_str = cache.setdefault(self.type_str, self.type_str)
+ self.address = _set_default(cache, self.address)
+ self.type_str = _set_default(cache, self.type_str)
def to_json(self):
"""Convert this MemObject to json."""
=== modified file 'meliae/tests/test_loader.py'
--- a/meliae/tests/test_loader.py 2009-10-22 21:29:53 +0000
+++ b/meliae/tests/test_loader.py 2009-10-22 21:47:42 +0000
@@ -95,9 +95,13 @@
objs = loader.load([
'{"address": 1234, "type": "int", "size": 12, "value": 10'
', "refs": []}'], show_prog=False).objs
- self.assertEqual([1234], objs.keys())
+ keys = objs.keys()
+ self.assertEqual([1234], keys)
obj = objs[1234]
self.assertTrue(isinstance(obj, _loader.MemObject))
+ # The address should be exactly the same python object as the key in
+ # the objs dictionary.
+ self.assertIs(keys[0], obj.address)
def test_load_example(self):
objs = loader.load(_example_dump, show_prog=False)
More information about the bazaar-commits
mailing list