comparison paraspace/injection.py @ 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
comparison
equal deleted inserted replaced
145:c4324c3461e8 146:032877e14560
300 # \param dex_dst is a DEXFile_linked where the cloning one is inserted. 300 # \param dex_dst is a DEXFile_linked where the cloning one is inserted.
301 # \param dex_src is a DEXFile_linked where the cloned one is from. 301 # \param dex_src is a DEXFile_linked where the cloned one is from.
302 # \param typeid is a _DEX_TypeId that is cloned. 302 # \param typeid is a _DEX_TypeId that is cloned.
303 # \return the cloning _DEX_TypeId. 303 # \return the cloning _DEX_TypeId.
304 # 304 #
305 def dexfile_insert_typeid(dex_dst, dex_src, typeid): 305 def dexfile_insert_or_merge_typeid(dex_dst, dex_src, typeid):
306 from paraspace.dexfile import _DEX_TypeId, DEXFile_linked 306 from paraspace.dexfile import _DEX_TypeId, DEXFile_linked, _DEX_MethodId
307 307
308 assert isinstance(typeid, _DEX_TypeId) 308 assert isinstance(typeid, _DEX_TypeId)
309 309
310 cloning = _clone_composite(dex_dst, typeid) 310 def typeid_not_in_dst(typeid):
311 311 typename = DEXFile_linked.get_typeid_name(typeid)
312 methodids = dex_src.find_methodids_typeid(dex_src, typeid) 312 try:
313 for methodid in methodids: 313 dex_dst.find_typeid_name(typename)
314 _clone_composite(dex_dst, methodid) 314 except ValueError:
315 pass 315 return True
316 return False
317
318 if typeid_not_in_dst(typeid):
319 cloning = _clone_composite(dex_dst, typeid)
320
321 methodids = dex_src.find_methodids_typeid(dex_src, typeid)
322 for methodid in methodids:
323 _clone_composite(dex_dst, methodid)
324 pass
325 pass
326 else:
327 typename = DEXFile_linked.get_typeid_name(typeid)
328 cloning = dex_dst.find_typeid_name(typename)
329
330 methodids = dex_src.find_methodids_typeid(typeid)
331 for methodid in methodids:
332 methodname = DEXFile_linked.get_methodid_name(methodid)
333 try:
334 dex_dst.find_methodid_name_proto(methodname, methodid.protoIdx,
335 cloning)
336 except ValueError:
337 temp_methodid = _DEX_MethodId()
338 temp_methodid.classIdx = None
339 temp_methodid.protoIdx = methodid.protoIdx
340 temp_methodid.nameIdx = methodid.nameIdx
341 cloning_methodid = _clone_composite(dex_dst, methodid)
342 cloning_methodid.classIdx = cloning
343 pass
344 pass
316 345
317 return cloning 346 return cloning
318 347
319 348
320 ## \brief Clone and insert a list of _DEX_TypeId objects to a DEXFile_linked. 349 ## \brief Clone and insert a list of _DEX_TypeId objects to a DEXFile_linked.
321 def dexfile_insert_typeids(dex_dst, dex_src, typeids): 350 def dexfile_insert_or_merge_typeids(dex_dst, dex_src, typeids):
322 clones = [dexfile_insert_typeid(dex_dst, dex_src, typeid) 351 clones = [dexfile_insert_or_merge_typeid(dex_dst, dex_src, typeid)
323 for typeid in typeids] 352 for typeid in typeids]
324 return clones 353 return clones
325 354
326 355
327 ## \brief Collects relative type IDs and classes definition for given class. 356 ## \brief Collects relative type IDs and classes definition for given class.
358 dex_dst.find_class_name(classname) 387 dex_dst.find_class_name(classname)
359 except ValueError: 388 except ValueError:
360 return True 389 return True
361 return False 390 return False
362 391
363 def typeid_not_in_dst(typeid):
364 typename = DEXFile_linked.get_typeid_name(typeid)
365 try:
366 dex_dst.find_typeid_name(typename)
367 except ValueError:
368 return True
369 return False
370
371 relative_classdefs, relative_typeids = \ 392 relative_classdefs, relative_typeids = \
372 collect_classdefs_relative(dex_src, classdefs) 393 collect_classdefs_relative(dex_src, classdefs)
373 394
374 for classdef in relative_classdefs: 395 for classdef in relative_classdefs:
375 if classdef_not_in_dst(classdef): 396 if classdef_not_in_dst(classdef):
376 continue 397 continue
377 raise ValueError, '%s is already in DEX %s: can not insert it' % \ 398 raise ValueError, '%s is already in DEX %s: can not insert it' % \
378 (repr(classdef), repr(dex_dst)) 399 (repr(classdef), repr(dex_dst))
379 400
380 inserting_typeids = filter(typeid_not_in_dst, relative_typeids)
381
382 cloning_classdefs = \ 401 cloning_classdefs = \
383 dexfile_insert_classdefs(dex_dst, dex_src, relative_classdefs) 402 dexfile_insert_classdefs(dex_dst, dex_src, relative_classdefs)
384 cloning_typeids = \ 403 cloning_typeids = \
385 dexfile_insert_typeids(dex_dst, dex_src, inserting_typeids) 404 dexfile_insert_or_merge_typeids(dex_dst, dex_src, relative_typeids)
386 405
387 return cloning_classdefs, cloning_typeids 406 return cloning_classdefs, cloning_typeids
388 407
389 408
390 ## \brief Redirect types, methods and strings for the code of given method. 409 ## \brief Redirect types, methods and strings for the code of given method.