Mercurial > paraspace
diff paraspace/dex_deptracker.py @ 53:705356005362
Fix bug of install marker through ref
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 22 Jun 2011 20:22:03 +0800 |
parents | 67aa8ca8fff3 |
children | 870312703ba1 |
line wrap: on
line diff
--- a/paraspace/dex_deptracker.py Tue Jun 21 18:36:45 2011 +0800 +++ b/paraspace/dex_deptracker.py Wed Jun 22 20:22:03 2011 +0800 @@ -10,6 +10,10 @@ obj = dexfile parent = None for name in name_path.split('.'): + while isinstance(obj, _marker): + obj = obj.back_type + pass + if isinstance(parent, dexfile.array) and obj == list: # array.items.<num> obj = parent.child_type @@ -253,6 +257,20 @@ return dex_types +def _all_dex_type_to_names(): + def check_marker(value, name): + while isinstance(value, _marker): + value = value.back_type + pass + return value, name + + dex_types = dict([check_marker(value, name) + for name, value in dexfile.__dict__.items() + if name.startswith('_DEX_')]) + dex_types[dexfile.DEXFile] = 'DEXFile' + return dex_types + + def collect_all_dep_decls(): dex_types = _all_dex_types() @@ -267,6 +285,10 @@ class _marker(dexfile.null_relocatable): back_type = None + + def set_marker(self, obj, off): + raise NotImplementedError, \ + 'The marker does not implement set_marker()' pass class _uid_marker(_marker): @@ -283,7 +305,8 @@ value.data_uid = _uid_marker.uid_seq except AttributeError: raise AttributeError, \ - 'can not depend on non-instance (%s)' % (self.name_path) + 'can not depend on non-instance (%s/%s)' % \ + (self.name_path, repr(value)) _uid_marker.uid_seq = _uid_marker.uid_seq + 1 return value @@ -315,6 +338,9 @@ def __call__(self, *args, **kws): return self.back_type(*args, **kws) + + def set_marker(self, obj, off): + pass pass @@ -336,6 +362,10 @@ assert obj.data_offset not in id_item_map id_item_map[obj.data_offset] = obj pass + + def set_marker(self, obj, off): + obj.data_offset = off + pass pass @@ -387,6 +417,10 @@ pass raise RuntimeError, 'can not find relative offset depend' + + def set_marker(self, obj, off): + obj.data_offset = off + pass pass @@ -411,13 +445,17 @@ id_item_map[idx] = item pass pass + + def set_marker(self, obj, off): + pass pass def _install_offset_marker(name_path): obj, parent = _resolve_name_path(name_path) - while isinstance(parent, dexfile.ref): - obj, parent = _resolve_name_path(parent.target_path) + while isinstance(obj, dexfile.ref): + name_path = obj.target_path + obj, parent = _resolve_name_path(name_path) pass marker = _offset_marker(obj, name_path) name = name_path.split('.')[-1] @@ -427,8 +465,9 @@ def _install_rel_offset_marker(name_path): obj, parent = _resolve_name_path(name_path) - while isinstance(parent, dexfile.ref): - obj, parent = _resolve_name_path(parent.target_path) + while isinstance(obj, dexfile.ref): + name_path = obj.target_path + obj, parent = _resolve_name_path(name_path) pass marker = _rel_offset_marker(obj, name_path) name = name_path.split('.')[-1] @@ -438,8 +477,9 @@ def _install_uid_marker(name_path): obj, parent = _resolve_name_path(name_path) - while isinstance(parent, dexfile.ref): - obj, parent = _resolve_name_path(parent.target_path) + while isinstance(obj, dexfile.ref): + name_path = obj.target_path + obj, parent = _resolve_name_path(name_path) pass marker = _uid_marker(obj, name_path) name = name_path.split('.')[-1] @@ -449,8 +489,9 @@ def _install_idx_marker(name_path): obj, parent = _resolve_name_path(name_path) - while isinstance(parent, dexfile.ref): - obj, parent = _resolve_name_path(parent.target_path) + while isinstance(obj, dexfile.ref): + name_path = obj.target_path + obj, parent = _resolve_name_path(name_path) pass marker = _idx_marker(obj, name_path) name = name_path.split('.')[-1] @@ -630,6 +671,9 @@ continue marker, dummy_parent = _resolve_name_path(name_path) + while isinstance(marker, dexfile.ref): + marker, dummy = _resolve_name_path(marker.target_path) + pass marker.link_prepare(obj, name_path, parents, markers_info) pass @@ -677,6 +721,8 @@ def _build_depon_dep_map(all_dep_decls): + from itertools import chain + def _build_sub_depon_dep(from_path, dep): depon1 = dep[1] sub = [(depon1, from_path)] @@ -692,32 +738,55 @@ for from_path, dep in all_dep_decls.items()] depon_dep_lst = chain(*depon_dep_lsts) depon_dep_map = dict(depon_dep_lst) - pass + return depon_dep_map def update_offset(dexroot, all_dep_decls): from dexfile import man_off + + depon_dep_map = _build_depon_dep_map(all_dep_decls) + dex_type_names = _all_dex_type_to_names() + + def make_path(obj, path_parts, obj_name): + if isinstance(obj, dexfile.composite): + type_name = dex_type_names[obj.__class__] + return [type_name] + return path_parts + [obj_name] moff = man_off(0) - queue = [dexroot] + queue = [(dexroot, ['DEXFile'])] while queue: - obj = queue.pop() - if isinstance(obj, _marker): - obj.set_marker(moff()) + obj, path_parts = queue.pop() + name_path = '.'.join(path_parts) + + if name_path in depon_dep_map: + marker, dummy = _resolve_name_path(name_path) + marker.set_marker(obj, moff()) pass - if isinstance(obj, dexfile.relocatable): - moff(obj.sizeof()) - pass + + if isinstance(obj, (tuple, list)): + attrs = [(elt, path_parts + [str(idx)]) + for idx, elt in enumerate(obj)] + attrs.reverse() + queue = queue + attrs + continue if isinstance(obj, dexfile.ref): continue + if not isinstance(obj, dexfile.relocatable): + clazz, parent = _resolve_name_path(name_path) + moff(clazz.sizeof(obj)) continue - children = list(obj.children()) - attrs = [_dex_tree_get_child(obj, child) - for child in children] + moff(obj.sizeof(obj)) + + children = obj.children() + attr_n_names = [(_dex_tree_get_child(obj, child_name), child_name) + for child_name in children] + attrs = [(attr, make_path(attr, path_parts, attr_name)) + for attr, attr_name in attr_n_names] attrs.reverse() queue = queue + attrs pass