3
^8                 @   s   d dl mZmZmZmZ dd Zd%ddZd&ddZd	d
 Zdd Z	e	Z
dd ZeZd'ddZdd Zd(ddZd)ddZdd Zdd Zdd Zd*ddZd d! Zed"krd d#lmZ ed$kre  dS )+    )COMPILER_FLAG_NAMESPYPY_COMPILER_FLAG_NAMESbetter_reprcode2numc             C   s6   yt | |d}W n  tk
r0   t | |d}Y nX |S )zAttempts to compile the given source, first as an expression and
       then as a statement if the first approach fails.

       Utility function to accept strings in functions that otherwise
       expect code objects
    evalexec)compileSyntaxError)sourcenamec r   K/home/psgendb/BIRCHDEV/python/lib/python3.6/site-packages/xdis/cross_dis.py_try_compile   s
    r   Fc             c   s  | j }t|tr4x|j D ]\}}||fV  qW n^t|dkrPd| jfV  nBt|d trt| j ddd }t| j ddd }n4dd | j ddd D }dd | j ddd D }t| j}d}| j}d}	xt	||D ]x\}
}|
r>||ks|r(d|
  k odk n  r(|	|fV  |}|	|kr6dS |	|
7 }	|d	krP|d
8 }||7 }qW ||ks|rd|
  k odk n  r|	|fV  dS )zFind the offsets in a byte code which are start of lines in the source.

    Generate pairs (offset, lineno) as described in Python/compile.c.
    r   N      c             S   s   g | ]}t |qS r   )ord).0r   r   r   r   
<listcomp>A   s    z"findlinestarts.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r   )r   r   r   r   r   r   B   s             )
	co_lnotab
isinstancedictitemslenco_firstlinenointlistco_codezip)codeZ	dup_linesZlineno_tableaddrlinenobyte_incrementsline_incrementsZbytecode_len
lastlinenooffset	byte_incr	line_incrr   r   r   findlinestarts+   s8    

,


,r+   c             C   s   t t| ||dS )z1Formatted details of methods, functions, or code.)is_pypy)format_code_infoget_code_object)xversionr,   r   r   r   	code_info\   s    r1   c             C   s   t | dr| j} t | dr"| j} nFt | dr4| j} n4t | drF| j} n"t | drX| j} nt | drh| j} t| tr|t| d} t | dr| S t	d	t
| j d
S )zMHelper to handle methods, functions, generators, strings and raw code objects__func____code__	func_codegi_codeag_codecr_codez<disassembly>r    z(don't know how to disassemble %s objectsN)hasattrr2   r3   r5   r6   r7   r   strr   	TypeErrortype__name__)r/   r   r   r   r.   a   s"    








r.   c             C   sx   g }xnt | |D ]`\}}}|dk	rd}||jkrHt||}|| | }n||jkrV|}|dkr||kr|j| qW |S )zReturns a list of instruction offsets in the supplied bytecode
    which are the targets of some sort of jump instruction.
    Nr   r   )unpack_opargs_bytecodeJREL_OPSop_sizeJABS_OPSappend)r"   opcZoffsetsr(   opargjump_offsetop_lenr   r   r   get_jump_targetsx   s    


rH   c             C   s2   | |j k r|jdkrdS dS |jdkr*dS dS dS )a(  For a given opcode, `op`, in opcode module `opc`,
    return the size, in bytes, of an `op` instruction.

    This is the size of the opcode (1 byte) and any operand it has. In
    Python before version 3.6 this will be either 1 or 3 bytes.  In
    Python 3.6 or later, it is 2 bytes or a "word".g@r   r      N)HAVE_ARGUMENTr0   )rD   rC   r   r   r   instruction_size   s    
rK   Nc             C   s4   |dkrt t| ||d n|jt| |d  dS )z}Print details of methods, functions, or code to *file*.

    If *file* is not provided, the output is printed on stdout.
    N)r,   
)printr1   write)cor0   filer,   r   r   r   	show_code   s    rQ   c             C   s
   | |j kS )N)rJ   )rD   rC   r   r   r   op_has_argument   s    rR   c             C   s   g }d|  }xlt dD ]R}d|> }| |@ r|jtj|t| |rZ|jtj|t| | |N } | sP qW |jt|  |j  d|dj|f S )z+Return pretty representation of code flags.z0x%08x    r   z%s (%s)z | )rangerB   r   gethexr   reversejoin)flagsr,   namesresultiflagr   r   r   pretty_flags   s    r^   c       
      C   s  |s
| j }g }|jd|  |jd| j  |dkrD|jd| j  |dkrft| drf|jd| j  |dkrt| d	r|jd
| j  | j}|dkr|jd| j  |dkr|jd| j  |dkr|jdt	| j
|d  |dkr|jd| j  | jr8|jd x.t| jD ] \}}|jd|t|f  qW | jrn|jd x"t| jD ]}|jd|  qVW | jr|jd |jddj| j  |dkr|jd |jddj| jd |   t| j|kr|jd x6t| j|d  D ] \}}	|jd|| |	f  qW |dkr| jrZ|jd x"t| jD ]}|jd|  qBW | jr|jd x"t| jD ]}|jd|  qxW dj|S )Nz# Method Name:       %sz# Filename:          %sg?z# Argument count:    %sgffffff@co_posonlyargcountz"# Position-only argument count: %sg      @co_kwonlyargcountz# Keyword-only arguments: %sz# Number of locals:  %sg      ?z# Stack size:        %sz# Flags:             %s)r,   z# First Line:        %sz# Constants:z	# %4d: %sz# Names:z# Varnames:z#	%sz, r   z# Positional arguments:z# Local variables:g       @z# Free variables:z# Cell variables:rL   )co_namerB   co_filenameco_argcountr8   r_   r`   
co_nlocalsco_stacksizer^   co_flagsr   	co_consts	enumerater   co_namesco_varnamesrX   r   co_freevarsco_cellvars)
rO   r0   r   r,   linesZpos_argcr\   r   i_nnr   r   r   r-      sf    








r-   c             C   s
   || j > S )N)ZEXTENDED_ARG_SHIFT)rC   valr   r   r   extended_arg_val  s    rq   c             c   s   d}yt | }W n" tk
r2   | j} t | }Y nX d}xl||k r|}t| |}|d7 }t||rt| ||B }||jkrt||nd}|d7 }nd }|||fV  q:W d S )Nr   r   r   )r   r:   r    r   rR   EXTENDED_ARGrq   )r"   rC   extended_argro   r(   prev_offsetrD   rE   r   r   r   r>   	  s"    



r>   c       
      C   s   i }d}xt | |D ]\}}}|dkrD|j|g }|j| |||< ||jkrTd}n|}|dk	rd}||jkrt||}	||	 | }n||jkr|}|dkr|j|g }|j| |||< qW |S )am  Returns a dictionary where the key is an offset and the values are
    a list of instruction offsets which can get run before that
    instruction. This includes jump instructions as well as non-jump
    instructions. Therefore, the keys of the dictionary are reachable
    instructions. The values of the dictionary may be useful in control-flow
    analysis.
    r   r   Nr=   r=   r=   )r>   rU   rB   ZNOFOLLOWr?   r@   rA   )
r"   rC   Zoffset2prevrt   r(   rD   rE   Z	prev_listrF   rG   r   r   r   get_jump_target_maps  s,    





ru   c             C   s  |j |  |j|   }}|j|  }|dkrB|jdkr>dd|  S n|dkr\|jdkr\|| S |dkr|jd	kr|d
krzdS dS  n|dkr|jdkrVd|  kodkn  r|jdk rdddddddddd d!d"g| S |jdkrd#d$d%d&d'd(d)d*d+d,d-d.g| S ndS nD|dkrV|jdkrVd|  ko<dkn  rRd/d0d1g| S dS |dkrr|dkrr|| S |dk r| |jkr|| |d  S | |jkr| | | S d2S )3aw  Compute the stack effect of opcode with argument oparg, using
    oppush and oppop tables in opc.

    If the code has a jump target and jump is True, stack_effect()
    will return the stack effect of jumping. If jump is False, it will
    return the stack effect of not jumping. And if jump is None
    (default), it will return the maximal stack effect of both cases.
    	BUILD_MAPg      @r   r   UNPACK_SEQUENCE	UNPACK_EXg      @BUILD_SLICEg@rI   MAKE_FUNCTIONr   
      g@NCALL_FUNCTION_EXd   )rv   )rw   rx   r=   r=   r   r   r   r   r   r   r   r   r   r=   r   r   r   r   r   r   r   r   r   r   r   r=   r   r=   i)ZoppopZoppushopnamer0   Z	VARGS_OPSZ	NARGS_OPS)opcoderC   ZopargZjumppoppushr   r   r   r   xstack_effectB  sB    	


 "

r   c              C   s  dd l } ddlm} ddlm} |r*d}nd}|d |}x|jj D ]\}}|dkrVqD||g}|g}t||r|jd |jd t	dkr||j
kr|dkr|jd |jd t| }	| j| }
|	dkrtd|||
f  qD|
|	krqDtd|||	|
f  qDW d S )Nr   )IS_PYPY)get_opcode_moduleZpypy rr   NOPg@JUMP_IF_FALSE_OR_POPJUMP_IF_TRUE_OR_POPPOP_JUMP_IF_FALSEPOP_JUMP_IF_TRUESETUP_FINALLYr~   z9%d (%s) needs adjusting; should be: should have effect %dz!%d (%s) not okay; effect %d vs %d)rr   r   )r   r   r   r   r   i)disxdisr   Zxdis.op_importsr   opmapr   rR   rB   PYTHON_VERSIONZCONDITION_OPSr   stack_effectrM   )r   r   r   ZvariantrC   r   r   Z	xdis_argsZdis_argsZeffectZcheck_effectr   r   r   check_stack_effectr  sL    




    


r   __main__)r   g333333@)F)F)NF)F)NF)NN)Z	xdis.utilr   r   r   r   r   r+   r1   r.   rH   
findlabelsrK   r@   rQ   rR   r^   r-   rq   r>   ru   r   r   r<   r   r   r   r   r   r   <module>   s*   
1



C#
05