Mercurial > paraspace
comparison paraspace/injection.py @ 135:b488ca519709
Make sure elements are absolute incremental for sorted arrays when injecting.
- All sorted array of DEXFile must be absolute incremental.
- If injected one is the same order as one already in the array, the one
in array are used to replace injected one.
- All references to clone and injected one refer to ones already in array
instead.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 09 Aug 2011 21:28:13 +0800 |
parents | 3dee4d929e1f |
children | 987fead83ce3 |
comparison
equal
deleted
inserted
replaced
134:3dee4d929e1f | 135:b488ca519709 |
---|---|
75 # | 75 # |
76 def dex_append_obj_list(dex, obj): | 76 def dex_append_obj_list(dex, obj): |
77 from paraspace.dex_deptracker import _dex_tree_get_child | 77 from paraspace.dex_deptracker import _dex_tree_get_child |
78 from paraspace.dex_deptracker import _dex_tree_set_child | 78 from paraspace.dex_deptracker import _dex_tree_set_child |
79 from paraspace.dexfile import _DEX_TypeList, _DEX_TypeList_align | 79 from paraspace.dexfile import _DEX_TypeList, _DEX_TypeList_align |
80 from paraspace.dexfile import array_sorted | |
80 | 81 |
81 if isinstance(obj, _DEX_TypeList): | 82 if isinstance(obj, _DEX_TypeList): |
82 wrapper = _DEX_TypeList_align() | 83 wrapper = _DEX_TypeList_align() |
83 wrapper.value = obj | 84 wrapper.value = obj |
84 obj = wrapper | 85 obj = wrapper |
89 attr = type_2_attr[obj.__class__] | 90 attr = type_2_attr[obj.__class__] |
90 except KeyError: | 91 except KeyError: |
91 return | 92 return |
92 | 93 |
93 array = getattr(dex, attr) | 94 array = getattr(dex, attr) |
95 | |
96 if isinstance(array, array_sorted): | |
97 if obj in array.items: | |
98 idx = array.items.index(obj) | |
99 return array.items[idx] | |
100 pass | |
101 | |
94 array.items.append(obj) | 102 array.items.append(obj) |
95 | 103 |
96 count_name = array.count_name | 104 count_name = array.count_name |
97 if count_name: | 105 if count_name: |
98 count = _dex_tree_get_child(dex, count_name) | 106 count = _dex_tree_get_child(dex, count_name) |
99 _dex_tree_set_child(dex, count_name, count + 1) | 107 _dex_tree_set_child(dex, count_name, count + 1) |
100 pass | 108 pass |
101 pass | 109 |
110 return obj | |
102 | 111 |
103 | 112 |
104 ## \brief Clone a composite object. | 113 ## \brief Clone a composite object. |
105 # | 114 # |
106 # \param dex is the DEXFile that the composite object is cloning for. | 115 # \param dex is the DEXFile that the composite object is cloning for. |
186 | 195 |
187 merge_unique_strdata() | 196 merge_unique_strdata() |
188 merge_unique_strid() | 197 merge_unique_strid() |
189 merge_unique_typeid() | 198 merge_unique_typeid() |
190 | 199 |
191 for obj in visit_log.values(): | 200 relink_list = [] |
201 for key, obj in visit_log.items(): | |
202 if isinstance(obj, (_DEX_StringDataItem, | |
203 _DEX_StringId, | |
204 _DEX_TypeId)): | |
205 continue | |
206 r = dex_append_obj_list(dex, obj) | |
207 if r and r is not obj: | |
208 visit_log[key] = r | |
209 else: | |
210 relink_list.append(obj) | |
211 pass | |
212 pass | |
213 | |
214 for obj in relink_list: | |
192 if isinstance(obj, (_DEX_StringDataItem, | 215 if isinstance(obj, (_DEX_StringDataItem, |
193 _DEX_StringId, | 216 _DEX_StringId, |
194 _DEX_TypeId)): | 217 _DEX_TypeId)): |
195 continue | 218 continue |
196 relink_dependencies(obj) | 219 relink_dependencies(obj) |
197 dex_append_obj_list(dex, obj) | |
198 pass | 220 pass |
199 | 221 |
200 clone = visit_log[id(comobj)] | 222 clone = visit_log[id(comobj)] |
201 return clone | 223 return clone |
202 | 224 |
658 # | 680 # |
659 # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, | 681 # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, |
660 # and redirect all invoking of type, given by redir_classname, to | 682 # and redirect all invoking of type, given by redir_classname, to |
661 # the injected one. | 683 # the injected one. |
662 # | 684 # |
663 def inject_redir(src_linked, inj_classname, | 685 def inject_redir_no_restore(src_linked, inj_classname, |
664 dst_linked, redir_classname, decls): | 686 dst_linked, redir_classname, decls): |
665 from paraspace.dex_deptracker import dex_sort_sorted_arrays | |
666 from paraspace.dex_deptracker import restore_dependencies | |
667 | |
668 inj_classdef = src_linked.find_class_name(inj_classname) | 687 inj_classdef = src_linked.find_class_name(inj_classname) |
669 injected_classdefs = inject_classdefs(dst_linked, src_linked, | 688 injected_classdefs = inject_classdefs(dst_linked, src_linked, |
670 [inj_classdef]) | 689 [inj_classdef]) |
671 | 690 |
672 redir_typeid = dst_linked.find_typeid_name(redir_classname) | 691 redir_typeid = dst_linked.find_typeid_name(redir_classname) |
680 | 699 |
681 injected_typeidxs = [dst_linked.get_idx_classdef(classdef) | 700 injected_typeidxs = [dst_linked.get_idx_classdef(classdef) |
682 for classdef in injected_classdefs] | 701 for classdef in injected_classdefs] |
683 dexfile_redirect_types(dst_linked, typeidxs_redir, methodidxs_redir, | 702 dexfile_redirect_types(dst_linked, typeidxs_redir, methodidxs_redir, |
684 excludes=injected_typeidxs) | 703 excludes=injected_typeidxs) |
685 | 704 pass |
705 | |
706 | |
707 ## \brief Inject and redirect a _DEX_ClassDef from one linked to another. | |
708 # | |
709 # The _DEX_ClassDef given by inj_classname would be inserted to dst_linked, | |
710 # and redirect all invoking of type, given by redir_classname, to | |
711 # the injected one. | |
712 # | |
713 def inject_redir(src_linked, inj_classname, | |
714 dst_linked, redir_classname, decls): | |
715 from paraspace.dex_deptracker import dex_sort_sorted_arrays | |
716 from paraspace.dex_deptracker import restore_dependencies | |
717 | |
718 inject_redir_no_restore(src_linked, inj_classname, | |
719 dst_linked, redir_classname, decls) | |
686 dex_sort_sorted_arrays(dst_linked) | 720 dex_sort_sorted_arrays(dst_linked) |
687 restore_dependencies(dst_linked, decls) | 721 restore_dependencies(dst_linked, decls) |
688 pass | 722 pass |