changeset 146:032877e14560

Merge typeid and methodids if injected type is already in destinate
author Thinker K.F. Li <thinker@codemud.net>
date Mon, 15 Aug 2011 17:26:46 +0800
parents c4324c3461e8
children a95b69de2e22
files paraspace/injection.py
diffstat 1 files changed, 38 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- 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