3
^2>                 @   s   d Z ddlZddlZddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZ errddlmZ ddlmZ nddlmZ ejejejefZd	d
 Zdd Zdd Zdd ZdddZdd ZG dd deZdd Z dS )zyPython bytecode and instruction classes
Extracted from Python 3 dis module but generalized to
allow running on Python 2.
    N)PYTHON3)get_code_objectformat_code_infoinstruction_sizeop_has_argument)Instruction)code2numnum2code)StringIO)reducec             C   s
   || j > S )N)ZEXTENDED_ARG_SHIFT)opcval r   J/home/psgendb/BIRCHDEV/python/lib/python3.6/site-packages/xdis/bytecode.pyextended_arg_val&   s    r   c             C   s   t |dks| |d d k r dS d}t |d }|| d d }x\||kr|| d | krd|d }n&|| d | k r~|d }n|| d S || d d }qBW |t |kr|t |d  d S || d S )a  linestarts is expected to be a *list) of (offset, line number)
    where both offset and line number are in increasing order.
    Return the closes line number at or below the offset.
    If offset is less than the first line number given in linestarts,
    return line number 0.
    r         )len)offset
linestartslowhighZmidr   r   r   offset2line)   s     


r   c             C   sN   | }|dk	r||  }t |trBt|tddddgkrB|d| fS |t|fS )zHelper to get optional details about const references

       Returns the dereferenced constant and its repr if the constant
       list is defined.
       Otherwise returns the constant index and its repr().
    Nnanz-naninfz-infzfloat('%s'))
isinstancefloatstr	frozensetrepr)const_index
const_listargvalr   r   r   _get_const_infoC   s    "r#   c             C   s6   | }|dk	r&| t |k r&||  }|}nt|}||fS )zHelper to get optional details about named references

       Returns the dereferenced name as both value and repr if the name
       list is defined.
       Otherwise returns the name index and its repr().
    N)r   r   )
name_index	name_listr"   argreprr   r   r   _get_name_infoU   s    r'   c             c   s&  |j | |}d}	|jdkrdnd}
d}t| }d}d}d}	t|j|}x||k r t| |}|}|dk	r|j|d}|dk	r||7 }||krd}nd}|d7 }d}d}d}t||}d}|r|
rt| ||	B }||jkr|d> nd}	|d7 }n@t| |t| |d d	  |	 }|d
7 }||jkr.|d nd}	|}||jkrXt	||\}}d}n"||j
krzt||\}}d}n ||jkr|| }dt| }d}n||jkr|}dt| }d}n||jkrt||\}}d}n||jkr|j| }|}d}nx||jkr"t||\}}d}nX||jkrjd}|
pD|j| dkszdt| |d
 t| |d f }n||jkrzd}t|dr|j| |jkr|j|j|  |}n|
r|d7 }|j| }t||||  }||jk}t||||||||||||dkV  ||jkr|d nd}qJW dS )a&  Iterate over the instructions in a bytecode string.

    Generates a sequence of Instruction namedtuples giving the details of each
    opcode.  Additional information about the code's runtime environment
    (e.g. variable names, constants) can be specified using optional
    arguments.

    r   g@TFNr          r   i   constnamezto ZjrelZjabslocalZcomparefreenargsRAISE_VARARGSDUP_TOPXMAKE_FUNCTIONz%d positional, %d namedZvargsopcode_arg_fmt)r0   r1   r2   )
findlabelspython_versionr   r   EXTENDED_ARGr   getr   	CONST_OPSr#   ZNAME_OPSr'   ZJREL_OPSr   ZJABS_OPSZ	LOCAL_OPSZCOMPARE_OPScmp_opZFREE_OPSZ	NARGS_OPSopnameZ	VARGS_OPShasattrr3   Znofollowr   )bytecoder   varnamesnames	constantscellsr   line_offsetlabelsextended_argZ	python_36starts_lineniZextended_arg_countZextended_arg_sizeopr   is_jump_targetargr"   r&   has_argZoptyper:   Z	inst_sizeZfallthroughr   r   r   get_instructions_bytesg   s    



 
 

rK   c             C   s   |t | | S )N)r   )rG   r   r   r   r   r   next_offset   s    rL   c            
   @   s|   e Zd ZdZdddZdd Zdd	 Zed
d Zdd Z	dddZ
dddZddddddejdddf
ddZdddZdS )BytecodezBytecode operations involving a Python code object.

    Instantiate this with a function, method, string of code, or a code object
    (as returned by compile()).

    Iterating over this yields the bytecode operations as Instruction instances.
    NTc             C   s   t | | _}d| _f | _|jdkr`|d kr6|j| _n|| _||j | _|jdkr`|j|j | _t	|j
||d| _|| _|| _|j| _|| _d S )Nr   g      ?g       @)	dup_lines)r   codeobj_line_offset_cell_namesversionco_firstlineno
first_lineco_cellvarsco_freevarsdictfindlinestarts_linestarts_original_objectr   r:   Zopnamescurrent_offset)selfxr   rT   r[   rN   cor   r   r   __init__   s    


zBytecode.__init__c          
   C   s.   | j }t|j| j|j|j|j| j| j| j	dS )N)rA   )
rO   rK   co_coder   co_varnamesco_names	co_constsrQ   rY   rP   )r\   r^   r   r   r   __iter__   s
    zBytecode.__iter__c             C   s   dj | jj| jS )Nz{}({!r}))format	__class____name__rZ   )r\   r   r   r   __repr__  s    
zBytecode.__repr__c             C   s$   x|j r|j }qW | |jj|jdS )z/ Construct a Bytecode from the given traceback )r[   )tb_nexttb_framef_codetb_lasti)clstbr   r   r   from_traceback  s    
zBytecode.from_tracebackc             C   s   t | j| jjS )z3Return formatted information about the code object.)r   rO   r   rR   )r\   r   r   r   info  s    zBytecode.infoFc             C   sv   | j }| jdk	r| j}nd}t }| jjdkr<| j}| j}nd}d}| j|j|j	|j
|j||| j||||d |j S )z3Return a formatted view of the bytecode operations.Nr   g       @)
r=   r>   r?   r@   r   rA   filelasti
asm_format
show_bytes)rO   r[   r
   r   rR   rQ   rY   disassemble_bytesr`   ra   rb   rc   rP   getvalue)r\   rs   rt   r^   r   outputr@   r   r   r   r   dis  s(    
zBytecode.disc             C   sX   |dkrBy
t j}W n tk
r.   tdY nX x|jr@|j}q2W | j|jj|j dS )z2Disassemble a traceback (default: last traceback).Nz no last traceback to disassemble)	syslast_tracebackAttributeErrorRuntimeErrorri   disassemblerj   rk   rl   )r\   rn   r   r   r   distb*  s    
 
zBytecode.distbr   r   c          
   C   s   |d k	}|rdnd}xlt || j||||||	dD ]N}|oJ|jd k	oJ|jdk}|rZ|jd |j|k}|j|j|||
|d  q0W d S )N   r   )rA   
)rK   r   rD   r   writer~   )r\   coderr   r=   r>   r?   r@   r   rq   rA   rs   rt   show_linenolineno_widthinstrnew_source_lineis_current_instrr   r   r   rv   4  s     



zBytecode.disassemble_bytesc          	   C   s\   t |}|j|j }t| jj|}|dk	r8||j }nd}t|j| j|j	|j
|j|||S )a  Iterator for the opcodes in methods, functions or code

        Generates a series of Instruction named tuples giving the details of
        each operations in the supplied code.

        If *first_line* is not None, it indicates the line number that should
        be reported for the first source line in the disassembled code.
        Otherwise, the source line information (if any) is taken directly from
        the disassembled code object.
        Nr   )r   rU   rV   rW   r   rX   rS   rK   r`   ra   rb   rc   )r\   r]   rT   r^   
cell_namesr   rA   r   r   r   get_instructionsK  s    zBytecode.get_instructions)NNT)FF)Nru   )N)rg   
__module____qualname____doc__r_   rd   rh   classmethodro   rp   ry   r   rz   stdoutrv   r   r   r   r   r   rM      s    



rM   c                s   g }xt | D ]\}}|d }|dd  ||jkrFtd|| f |j| }|j| t|   fdd D }	xL|	D ]D}
||jkr|n|j|
}|dkrtd|| f q||t|7 }q|W qW |j	dk rt
d	d
 |dS trt|S tt|S dS )z^Convert list/tuple of list/tuples to bytecode
    _names_ contains a list of name objects
    r   r   Nz+error at item %d [%s, %s], opcode not validc             3   s   | ]} r|V  qd S )Nr   ).0j)operandsr   r   	<genexpr>p  s    z list2bytecode.<locals>.<genexpr>z'operand %s [%s, %s], not found in namesg      @c             S   s   | t | S )N)chr)abr   r   r   <lambda>}  s    zlist2bytecode.<locals>.<lambda>r(   ru   )	enumerater:   	TypeErroropmapappendprintr8   indexr	   r5   r   r   bytes	bytearray)lr   r=   ZconstsZbcrF   Zopcodesr:   opcodegenr   kr   )r   r   list2bytecodea  s4    





r   )NNNNNr   )!r   rz   typesZxdis.version_infor   Zxdis.cross_disr   r   r   r   Zxdis.instructionr   Z	xdis.utilr   r	   ior
   	functoolsr   
MethodTypeFunctionTypeCodeTypetype
_have_coder   r   r#   r'   rK   rL   objectrM   r   r   r   r   r   <module>   s(    
q 