# HG changeset patch # User Thinker K.F. Li # Date 1313400406 -28800 # Node ID 032877e14560e08dea3a7e323d7b435c73efcc04 # Parent c4324c3461e8349ef6eb6076c23487beee7972ca Merge typeid and methodids if injected type is already in destinate diff -r c4324c3461e8 -r 032877e14560 paraspace/injection.py --- a/paraspace/injection.py Mon Aug 15 15:25:39 2011 +0800 +++ b/paraspace/injection.py Mon Aug 15 17:26:46 2011 +0800 @@ -302,24 +302,53 @@ # \param typeid is a _DEX_TypeId that is cloned. # \return the cloning _DEX_TypeId. # -def dexfile_insert_typeid(dex_dst, dex_src, typeid): - from paraspace.dexfile import _DEX_TypeId, DEXFile_linked +def dexfile_insert_or_merge_typeid(dex_dst, dex_src, typeid): + from paraspace.dexfile import _DEX_TypeId, DEXFile_linked, _DEX_MethodId assert isinstance(typeid, _DEX_TypeId) - cloning = _clone_composite(dex_dst, typeid) + def typeid_not_in_dst(typeid): + typename = DEXFile_linked.get_typeid_name(typeid) + try: + dex_dst.find_typeid_name(typename) + except ValueError: + return True + return False - methodids = dex_src.find_methodids_typeid(dex_src, typeid) - for methodid in methodids: - _clone_composite(dex_dst, methodid) + if typeid_not_in_dst(typeid): + cloning = _clone_composite(dex_dst, typeid) + + methodids = dex_src.find_methodids_typeid(dex_src, typeid) + for methodid in methodids: + _clone_composite(dex_dst, methodid) + pass pass + else: + typename = DEXFile_linked.get_typeid_name(typeid) + cloning = dex_dst.find_typeid_name(typename) + + methodids = dex_src.find_methodids_typeid(typeid) + for methodid in methodids: + methodname = DEXFile_linked.get_methodid_name(methodid) + try: + dex_dst.find_methodid_name_proto(methodname, methodid.protoIdx, + cloning) + except ValueError: + temp_methodid = _DEX_MethodId() + temp_methodid.classIdx = None + temp_methodid.protoIdx = methodid.protoIdx + temp_methodid.nameIdx = methodid.nameIdx + cloning_methodid = _clone_composite(dex_dst, methodid) + cloning_methodid.classIdx = cloning + pass + pass return cloning ## \brief Clone and insert a list of _DEX_TypeId objects to a DEXFile_linked. -def dexfile_insert_typeids(dex_dst, dex_src, typeids): - clones = [dexfile_insert_typeid(dex_dst, dex_src, typeid) +def dexfile_insert_or_merge_typeids(dex_dst, dex_src, typeids): + clones = [dexfile_insert_or_merge_typeid(dex_dst, dex_src, typeid) for typeid in typeids] return clones @@ -360,14 +389,6 @@ return True return False - def typeid_not_in_dst(typeid): - typename = DEXFile_linked.get_typeid_name(typeid) - try: - dex_dst.find_typeid_name(typename) - except ValueError: - return True - return False - relative_classdefs, relative_typeids = \ collect_classdefs_relative(dex_src, classdefs) @@ -377,12 +398,10 @@ raise ValueError, '%s is already in DEX %s: can not insert it' % \ (repr(classdef), repr(dex_dst)) - inserting_typeids = filter(typeid_not_in_dst, relative_typeids) - cloning_classdefs = \ dexfile_insert_classdefs(dex_dst, dex_src, relative_classdefs) cloning_typeids = \ - dexfile_insert_typeids(dex_dst, dex_src, inserting_typeids) + dexfile_insert_or_merge_typeids(dex_dst, dex_src, relative_typeids) return cloning_classdefs, cloning_typeids