o
    h`                     @   s   d dl Z d dlZd dlZd dlZd dlmZmZmZmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZ ddlmZ dZdZdZdZd	Zd
ZdZdZdZdZej ddG dd dZ!ej G dd dZ"dd Z#G dd dZ$dS )    N)AnyDictListOptionalTuple   )	create_call_functioncreate_call_methodcreate_dup_topcreate_instructioncreate_jump_absoluteInstructionInstructionExnTabEntrytransform_code_object	unique_id)ExactWeakKeyDictionary                @         i   T)frozenc                   @   sD   e Zd ZU dZeed< dZee ed< de	e
 fddZdd ZdS )	ReenterWithNstack_indextarget_valuescleanupc                    s$  g }| j rdd | j D }td| j   |d vr$|d   f7  < dD ]}||d vr7|d  |f7  < q&ttjdk r@dnd	}td}g |tt|d
td dtd dtdddtdtd}tjdk r{|	td|d ntd}td}	t
||	|| jd d|_|	|  fdd}
tjdk rtdtd|g|
 td}nXtjdk rtdg|
 td|d||
 td|}n9tddd}tdd d}t
|||| jd! d
|_|	g|
 td|d||
 ||td"tddd|}|| |d#d#< |S )$z
        Codegen based off of:
        load args
        enter context
        try:
            (rest)
        finally:
            exit context
        c                 S      g | ]}t d |dqS 
LOAD_CONSTargvalr   .0val r(   T/var/www/html/ai/venv/lib/python3.10/site-packages/torch/_dynamo/resume_execution.py
<listcomp>4       
z*ReenterWith.try_except.<locals>.<listcomp>___context_manager_co_varnames)	__enter____exit__co_names      NOPPUSH_EXC_INFOT
STORE_FASTr"   	LOAD_FASTLOAD_METHODr.   r   POP_TOPSETUP_FINALLYtargetr   Fc                      s:   t d dt dddt dd dt t gtdt dS )Nr7   r"   r8   r/   r!   r2   r9   )r   r
   r	   r(   ctx_namer(   r)   create_reset^   s   


z,ReenterWith.try_except.<locals>.create_resetr2   	   	POP_BLOCKBEGIN_FINALLYEND_FINALLYJUMP_FORWARDRERAISEargCOPYr2   r   
POP_EXCEPTN)r   r   r   r   sysversion_infor   lenr	   appendr   exn_tab_entry)selfcode_optionsr   	load_argsnameexcept_jump_targetcleanup_complete_jump_targetsetup_finallyexn_tab_beginexn_tab_endr?   epiloguefinally_exn_tab_endfinally_exn_tab_targetr(   r=   r)   
try_except(   s   













	
zReenterWith.try_exceptc                 C   s  g }| j rdd | j D }tjdk rEtd}td}td||tdtdg| |d	d	< g |td
t|dtd|dtdd	fS tjdk rtd}td}td}tdtdd	dtdtdtd
ddtdtd|d|td|dtd|tdtdtdtd|g| |d	d	< g |td
t|dtd|dtdd	fS td}td}dd }	td}
td}td}tddd}tddd}t|
||| jd d |
_t|||| jd d |_t|||| jd d |_||	 |	 |	 gtdd!tdtd|d|tdtd"|d||tdtddd|tdtdtd|| |d	d	< g |tt|d td#|
|fS )$zR
        Codegen based off of:
        with ctx(args):
            (rest)
        c                 S   r   r    r$   r%   r(   r(   r)   r*      r+   z(ReenterWith.__call__.<locals>.<listcomp>r@   WITH_CLEANUP_STARTrC   rB   WITH_CLEANUP_FINISHrD   NCALL_FUNCTIONrG   
SETUP_WITHr;   r9   r1   WITH_EXCEPT_STARTr4   r!   r"   DUP_TOPr2   rE   POP_JUMP_IF_TRUErF   rJ   c                   S   s   t dd dS )Nr!   r"   r$   r(   r(   r(   r)   create_load_none   s   z.ReenterWith.__call__.<locals>.create_load_noner5   r   rI   r   TFPOP_JUMP_FORWARD_IF_TRUEBEFORE_WITH)	r   rK   rL   r   rM   r   r   rO   r   )rP   rQ   r   rR   with_cleanup_startbegin_finallywith_except_startpop_top_after_with_except_startrU   rd   exn_tab_1_beginexn_tab_1_endexn_tab_1_targetexn_tab_2_endexn_tab_2_targetr(   r(   r)   __call__   s  






	
	

zReenterWith.__call__)__name__
__module____qualname__r   int__annotations__r   r   r   r   r   r\   rp   r(   r(   r(   r)   r   !   s
   
 mr   c                   @   sL   e Zd ZU ejed< dZee ed< dZ	ee
 ed< dZee
e
f ed< dS )ResumeFunctionMetadatacodeNinstructions prefix_block_target_offset_remapblock_target_offset_remap)rq   rr   rs   typesCodeTyperu   rx   r   r   ry   rt   rz   r   r(   r(   r(   r)   rv     s
   
 
rv   c                 C   sV   t |}g }zt|}| D ]}|||r|| t|}qW |S  ty*   Y |S w )z
    Two-pointer conditional filter.
    e.g. _filter_iter(insts, sorted_offsets, lambda i, o: i.offset == o)
    returns the instructions with offsets in sorted_offsets
    )iternextrN   StopIteration)l1l2conditrescurr'   r(   r(   r)   _filter_iter%  s   

r   c                   @   s   e Zd Ze Ze Zedd Zedede	e dede	e
 de	e de	e fd	d
Zedd Zedede	e fddZdS )ContinueExecutionCachec                 G   sX   || j vrt | j |< t|}|| j | vr%| j||g|R  | j | |< | j | | S N)cachedicttuplegenerate)clsrw   linenokeyr(   r(   r)   lookup<  s   
zContinueExecutionCache.lookupoffsetsetup_fn_target_offsetsnstackargnames	setup_fns
null_idxesc	                    s   d usJ |j ttB tB tB @ rJ |j t@ sJ |tjv r+| 	S t	j
dkt|r9g _dtt dtttf f 	f
dd}	t||	}
tj|
< |
S )Nr1   rx   rQ   c                    s  t | _dd tD    fddD  t|d p!g t|d p(g  }d|d  d	|d< rAd|d
  d	|d
< |d< t |d< ||d< t |d< d|d< d|d< t  fdd|d D  |d< |d ttB  @ |d< t	fdd| D }g }r|r|
tdt|d |
tddd g }dd 
D }	fddt
D }dd | D }i }	d}
tD ]a}|
tk r|
 ||
 kr|
td |
d7 }
|
tk r|
 ||
 ks|
tdd| d ||v r!||}|||\}}|| r!||}|| }j
| ||	|< qr-ttj_|r2J |
t| | D ]}|j|jkrF nd |_tjd krRd |_q;|rd|| || |	rslJ | D ]}|jr|jj|	v r|	|jj |j_qn||  | d d < d S )!Nc                 S   s   g | ]}d | qS )___stackr(   r&   ir(   r(   r)   r*   k  s    zCContinueExecutionCache.generate.<locals>.update.<locals>.<listcomp>c                 3   s    | ]	}| vr|V  qd S r   r(   r&   vargsr(   r)   	<genexpr>l  s    zBContinueExecutionCache.generate.<locals>.update.<locals>.<genexpr>co_cellvarsco_freevarsz<resume in co_name>co_qualnameco_firstlinenoco_argcountr   co_posonlyargcountco_kwonlyargcountc                    s   g | ]}| vr|qS r(   r(   r   r   r(   r)   r*   |  s    r-   co_flagsc                 3       | ]
}|j  kr|V  qd S r   r   r   r   r(   r)   r         COPY_FREE_VARSrG   RESUMEc                 S      i | ]}|j |qS r(   r   )r&   fnr(   r(   r)   
<dictcomp>      zCContinueExecutionCache.generate.<locals>.update.<locals>.<dictcomp>c                    s   i | ]
\}}|j  | qS r(   r   )r&   r   r   )r   r(   r)   r     s    
c                 S   r   r(   r   )r&   instr(   r(   r)   r     r   	PUSH_NULLr   r7   r   r"   r1   )copydeepcopyrx   rangeextendr   rM   
CO_VARARGSCO_VARKEYWORDSr~   rN   r   	enumeratepopry   listreversedr   r   starts_linerK   rL   	positionsunreachable_codesrO   r<   )rx   rQ   freevarsr<   prefixr   hookshook_target_offsetsoffset_to_instold_hook_target_remapnull_idxes_ir   hook
hook_insts
exn_targethook_target_offsetold_hook_targetr   
r   r   is_py311_plusr   metar   r   r   r   r   r   r)   updateh  s   










z/ContinueExecutionCache.generate.<locals>.update)r   CO_GENERATORCO_COROUTINECO_ITERABLE_COROUTINECO_ASYNC_GENERATORCO_OPTIMIZEDr   generated_code_metadata&generate_based_on_original_code_objectrK   rL   rv   ry   r   r   r   strr   r   )r   rw   r   r   r   r   r   r   r   r   new_coder(   r   r)   r   E  s2   

4
f
zContinueExecutionCache.generatec                 C   s   t dddt dddgS )zACodegen a `raise None` to make analysis work for unreachable coder!   Nr"   RAISE_VARARGSr   rG   r$   )rQ   r(   r(   r)   r     s   

z(ContinueExecutionCache.unreachable_codesc                    s   t j|  ddtt dtttf f fdd}t|| tj	dkrL j
sAi  _
dtt dtttf f fdd}t|| t fd	d
D t j j|g|R  S )a>  
        This handles the case of generating a resume into code generated
        to resume something else.  We want to always generate starting
        from the original code object so that if control flow paths
        converge we only generated 1 resume function (rather than 2^n
        resume functions).
        Nrx   rQ   c                    sR   fdd| D \  fddt t| tjD \} j|jks$J |jd S )Nc                 3   r   r   r   r   r   r(   r)   r     r   ziContinueExecutionCache.generate_based_on_original_code_object.<locals>.find_new_offset.<locals>.<genexpr>c                 3   s     | ]\}}| u r|V  qd S r   r(   )r&   i1i2r;   r(   r)   r     s    )zipr   rx   opcoder   )rx   rQ   
new_target)r   
new_offsetr   r;   r)   find_new_offset  s   

zVContinueExecutionCache.generate_based_on_original_code_object.<locals>.find_new_offsetr1   c                    s   g }t | D ]\}}t|tjkr n|jdkr|| qt|jD ]
\}}|j|j< q&|r8|d jnd t fddD }t	| |dd }t	tt
| t
j|dd }t||D ]\}	}
|	d jj|
j< qbd S )	Nr5   c                 3   s    | ]	}| kr|V  qd S r   r(   r&   nold_start_offsetr(   r)   r     s    zmContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsets.<locals>.<genexpr>c                 S   s
   | j |kS r   r   )r   or(   r(   r)   <lambda>!  s   
 zlContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsets.<locals>.<lambda>c                 S   s   | d |u S )Nr   r(   )v1v2r(   r(   r)   r   &  s    r   )r   rM   ry   opnamerN   r   rz   r   sortedr   r   rx   )rx   rQ   prefix_blocksidxr   r   old_inst_offsetstargetsnew_targetsnewold)r   r   r   r)   remap_block_offsets  s8   


zZContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsetsc                 3   s    | ]} j | V  qd S r   )rz   r   )r   r(   r)   r   .  s    

zPContinueExecutionCache.generate_based_on_original_code_object.<locals>.<genexpr>)r   r   r   r   r   r   r   r   rK   rL   rz   r   r   rw   )r   rw   r   r   r   r   r   r   r(   )r   r   r   r   r)   r     s6   




(
z=ContinueExecutionCache.generate_based_on_original_code_objectN)rq   rr   rs   r   r   r   classmethodr   rt   r   r   r   r   staticmethodr   r   r(   r(   r(   r)   r   8  s8    
	 
r   )%r   dataclassesrK   r{   typingr   r   r   r   r   bytecode_transformationr   r	   r
   r   r   r   r   r   r   utilsr   r   CO_NEWLOCALSr   r   	CO_NESTEDr   	CO_NOFREEr   r   r   	dataclassr   rv   r   r   r(   r(   r(   r)   <module>   s4    ,
 v 