§
    2@Äj‹  ã                   ó°   — d Z ddlZddlZddlZddlmZmZ ddlmZ ddl	m
Z
mZ d„ Zd„ Zd„ Zd	„ Z G d
„ de¦  «        Zedk    r ej        ¦   «          dS dS )aB  
Regression test for issue #5611 / PR #10482.

CFGraph._find_topo_order must be stack-based (not recursive) so that
functions with large control-flow graphs do not exhaust the Python call
stack.

The test is run in a subprocess so that sys.setrecursionlimit manipulation
is completely isolated from the rest of the suite.
é    N)ÚCFGraphÚControlFlowAnalysis)ÚTestCase)ÚFunctionIdentityÚByteCodec                 óê   — dg}t          | ¦  «        D ]7}|                     d|› d�¦  «         |                     d|› d|› d�¦  «         Œ8|                     d¦  «         d                     |¦  «        S )	z/ Source for function with unusually large CFG. zdef _large_cfg_func(x):z    dep_z = 1 if True else 0z    val_z = x if dep_z else 0z    return xú
)ÚrangeÚappendÚjoin)ÚcountÚlinesÚis      úMC:\Projects\Historical\venv\Lib\site-packages\numba/tests/test_controlflow.pyÚ_generate_large_cfg_sourcer      sŠ   € à&Ð'€EÝ�5‰\Œ\ð ;ð ;ˆØ�ŠÐ6 Ð6Ð6Ð6Ñ7Ô7Ð7Ø�ŠÐ9 Ð9Ð9¨qÐ9Ð9Ð9Ñ:Ô:Ð:Ð:Ø	‡L‚L�Ñ Ô Ð Ø�9Š9�UÑÔÐó    c                 óœ   — t          j        | ¦  «        }t          |¦  «        }t          |¦  «        }|                     ¦   «          |j        S )z;Create a CFGraph from a Python function for direct testing.)r   Úfrom_functionr   r   ÚrunÚgraph)ÚfuncÚfunc_idÚbcÚcfas       r   Ú_create_cfg_from_functionr   #   sA   € åÔ,¨TÑ2Ô2€GÝ	�'Ñ	Ô	€BÝ
˜bÑ
!Ô
!€CØ‡G‚G�I„I€IØŒ9Ðr   c                 ó&   — d}|r| nd}d}|r| nd}| S )z7 Test function for probing stack depth during compile. Té   r   © )ÚxÚdep_0Úval_0Údep_1Úval_1s        r   Ú_complex_funcr$   ,   s-   € à€EØÐˆAˆA˜A€EØ€EØÐˆAˆA˜A€EØ€Hr   c                  óæ   ‡‡— dgŠt          t          ¦  «        } t          j        Šˆˆfd„}|t          _        	 |                      ¦   «          ‰t          _        n# ‰t          _        w xY w‰d         S )zj
    Return the Python frame depth at CFGraph._find_topo_order during a trivial
    njit compilation.
    r   c                 ó†   •— t          j        ¦   «         }d}|�|dz  }|j        }|­|‰d         k    r|‰d<    ‰| ¦  «        S ©Nr   r   ©ÚsysÚ	_getframeÚf_back)ÚselfÚfÚdÚdepth_sampleÚoriginals      €€r   Ú_probing_topo_orderz;_measure_trivial_compile_depth.<locals>._probing_topo_order>   sW   ø€ ÝŒM‰OŒOˆØˆØˆmØ�‰FˆAØ”ˆAð ˆmð ˆ|˜AŒÒÐØˆL˜‰OØˆx˜‰~Œ~Ðr   )r   r$   r   Ú_find_topo_orderÚprocess)Úcfgr1   r/   r0   s     @@r   Ú_measure_trivial_compile_depthr5   5   s‡   øø€ ð
 �3€LÝ
#¥MÑ
2Ô
2€CÝÔ'€Hðð ð ð ð ð ð  3…GÔð#Ø×ÒÑÔÐà"�Œˆø˜(�ŒÐ"Ð"Ð"Ð"à˜Œ?Ðs   ¹A ÁA(c                   ó.   — e Zd Zej        d„ ¦   «         ZdS )ÚTestCFGTopoOrderNonRecursivec                 ó¢  — t          t          ¦   «         dz   ¦  «        }d„ }t           |¦   «         ¦  «        }t          d¦  «        }i }t	          t          |dd¦  «        |¦  «         t          |d         ¦  «        }t          j        ¦   «         }t          j	        ||z   ¦  «         d}	 | 
                    ¦   «          n# t          $ r}	|	}Y d}	~	nd}	~	ww xY wt          j	        |¦  «         n# t          j	        |¦  «         w xY w|€dS dd	                     t          j        |j        ¦  «        ¦  «        z   }
|                      |
¦  «         dS )
a
  
        Regression tests for PR #10482: _find_topo_order must not use recursive
        Python calls, so that large CFGs cannot exhaust the stack.

        Steps
        -----
        1.  Measure the frame depth at CFGraph.topo_order() during a trivial
            njit compilation by patching the method to walk the frame
            chain once; call this bsize. Add 2 for headroom.
        1a. Determine current frame_depth
        2.  Lower sys.setrecursionlimit to bsize + frame_depth
        3.  Attempt to compile a function with 100 ternary-expression
            pairs.
        4.  Catch any RecursionError.
        5.  Restore sys.setrecursionlimit unconditionally.
        6.  Fail the test and print the traceback if a RecursionError was
            raised.
        é   c               3   óT   K  — t          j        d¦  «        } | �| j        } dV — | ­d S d S r'   r(   )r-   s    r   ÚframeszVTestCFGTopoOrderNonRecursive.test_topo_order_no_recursion_in_large_cfg.<locals>.framesp   s9   è è € Ý”˜aÑ Ô ˆAØ�-Ø”H�Ø���ð �-�-�-�-�-r   éd   z<generated_large_cfg>ÚexecÚ_large_cfg_funcNzeUnexpected RecursionError.Potential regression related to finding toplogical order.

Full traceback:
Ú )Úintr5   Úsumr   r=   Úcompiler   r)   ÚgetrecursionlimitÚsetrecursionlimitr2   ÚRecursionErrorr   Ú	tracebackÚ	format_tbÚ__traceback__Úfail)r,   Úbsizer;   Úframe_depthÚfunÚenvr4   Úoriginal_limitÚ
caught_excÚexcÚmsgs              r   Ú)test_topo_order_no_recursion_in_large_cfgzFTestCFGTopoOrderNonRecursive.test_topo_order_no_recursion_in_large_cfgX   s†  € õ, Õ2Ñ4Ô4°qÑ8Ñ9Ô9ˆð	ð 	ð 	õ ˜&˜&™(œ(‘m”mˆå(¨Ñ-Ô-ˆØˆÝÝØØ'Øñô ð
 ñ	
ô 	
ð 	
õ (¨Ð,=Ô(>Ñ?Ô?ˆõ Ô.Ñ0Ô0ˆÝÔ˜e kÑ1Ñ2Ô2Ð2ð ˆ
ð	2Ø× Ò Ñ"Ô"Ð"Ð"øÝð 	ð 	ð 	ØˆJˆJˆJˆJˆJˆJøøøøð	øøøõ Ô! .Ñ1Ô1Ð1Ð1ø�CÔ! .Ñ1Ô1Ð1Ð1øøøð ÐàˆFð$ð —'’'�)Ô-¨jÔ.FÑGÔGÑHÔHñIð ð
 �IŠI�c‰NŒNˆNˆNˆNs0   Â+C  Â?C. Ã 
CÃ
CÃC. ÃCÃC. Ã.DN)Ú__name__Ú
__module__Ú__qualname__r   Úrun_test_in_subprocessrR   r   r   r   r7   r7   V   s6   € € € € € àÔ$ðDð Dñ %Ô$ðDð Dð Dr   r7   Ú__main__)Ú__doc__r)   rF   ÚunittestÚnumba.core.controlflowr   r   Únumba.tests.supportr   Únumba.core.bytecoder   r   r   r   r$   r5   r7   rS   Úmainr   r   r   ú<module>r^      s  ðð	ð 	ð €
€
€
Ø Ð Ð Ð Ø €€€à ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø (Ð (Ð (Ð (Ð (Ð (Ø :Ð :Ð :Ð :Ð :Ð :Ð :Ð :ðð ð ðð ð ðð ð ðð ð ðBGð Gð Gð Gð G 8ñ Gô Gð GðT ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   