Mercurial > paraspace
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. |