o
    8ήcR0                     @   st   d Z ddlZddlZddlmZ ddlmZ ddlm	Z	 G dd de
ZG dd	 d	Ze Z[dd
dZdd ZdS )z
Provides wrapper functions for "glueing" together Numba implementations that are
written in the "old" style of a separate typing and lowering implementation.
    N)RLock)defaultdict)errorsc                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )_OverloadWrapperzbThis class does all the work of assembling and registering wrapped split
    implementations.
    Nc                 C   s8   |d usJ || _ || _t | _d | _d | _|   d S N)	_function_typing_keydict_BIND_TYPES	_selector_TYPER_build)selffunction
typing_key r   ?/tmp/pip-target-vg8gfxp4/lib/python/numba/core/overload_glue.py__init__   s   z_OverloadWrapper.__init__c                 C   s   dd }|j }g |j}|| t|}|g}t|}ddlm}	 |	jdkr-||j ||j	 ||j
| |j|j|j|j|jt||j|j|j|j|j|jg tj| }
t|
d|i}|S )zThis generates a function based on the argnames provided in
        "varnames", the "body_func" is the function that'll type the overloaded
        function and then work out which lowering to returnc                 S   s   t | S r   )body)tyctxr   r   r   stub"   s   z._OverloadWrapper._stub_generator.<locals>.stubr   )utils)      r   )__code__co_varnamesextendlen
numba.corer   	PYVERSIONappendco_posonlyargcountco_kwonlyargcount
co_nlocalsco_stacksizeco_flagsco_code	co_constsco_namestupleco_filenameco_nameco_firstlineno	co_lnotabco_freevarsco_cellvarspytypesCodeTypeFunctionType)r   	body_funcvarnamesr   	stub_codenew_varnamesco_argcountco_argsadditional_co_nlocalsr   new_codenew_funcr   r   r   _stub_generator   s8   



z _OverloadWrapper._stub_generatorc                    s*   j du r	j nj   fdd}|S )z
        Use this to replace @infer_global, it records the decorated function
        as a typer for the argument `concrete_function`.
        Nc                    sB   t | j} |d< td  | j|}|_t    | S )Nkeycloned_template_for_)r	   __dict__type	__bases__r   _overload_glueadd_no_deferr   )typing_class
clazz_dictclonedr=   r   r   r   innerP   s   

z+_OverloadWrapper.wrap_typing.<locals>.inner)r   r   )r   rH   r   rG   r   wrap_typingF   s
   
z_OverloadWrapper.wrap_typingc                    s    j dusJ  fdd}|S )zw
        Use this to replace @lower*, it records the decorated function as the
        lowering implementation
        Nc                    s   | j  < | S r   )r
   )lowererargsr   r   r   rH   f   s   
z)_OverloadWrapper.wrap_impl.<locals>.inner)r   )r   rL   rH   r   rK   r   	wrap_impl_   s   z_OverloadWrapper.wrap_implc                 C   sv   ddl m} | jdu r| j}n| j}t| | | _d| j }| js(J || j D ]\}}| j	|| q-dS )zgAssembles the OverloadSelector definitions from the registered
        typing to lowering map.
        r   )OverloadSelectorNz+No entries in the typing->lowering map for )
numba.core.baserN   r   r   rB   flush_deferred_loweringr   r
   itemsr    )r   rN   r=   msgsigimplr   r   r   	_assemblek   s   

z_OverloadWrapper._assemblec                    s6   ddl m}m  |jdddid fdd}d S )	Nr   )overload	intrinsicFforceinlineT)strictjit_optionsc                     st   fdd}ddl m}m}m} |||  }|jj}|}| }	|	s/t	d|	j
rn|	j
j}
dd |
 D }g }|
 D ]\}}|j|ju rU|| qE|| d|j  qEd	|}d	|
 }nd
d tt D }r}J d	|}|}||}|}tj}ddd |D }td|||}i }d|i}t||| |d| S )Nc                    s   dj  }jd u rt|| }| }|d u r!d S jd u r*  j|j}d| dj  f}|d u rDt|||fS )NzNo typer registered for z'Could not find implementation to lower z for )	r   r   r   InternalErrorapplyr   rU   findrL   )r   rR   typingrS   lowering)ol_args	ol_kwargsr   r   r   r      s    





z;_OverloadWrapper._build.<locals>.ol_generated.<locals>.bodyr   )dispatcher_registryresolve_target_strcurrent_targetzNo matchc                 S   s   g | ]}|qS r   r   .0xr   r   r   
<listcomp>   s    zA_OverloadWrapper._build.<locals>.ol_generated.<locals>.<listcomp>z = z, c                 S   s   g | ]}d | qS )tmpr   re   r   r   r   rh      s     c                 S   s   g | ]
}|d vr
|ndqS )>   . -<>_r   re   r   r   r   rh      s    zS
            def jit_wrapper_{}({}):
                return intrin({})
            intrinzjit_wrapper_{})numba.core.target_extensionrb   rc   rd   targetdescrtyping_contextr   r\   r   TypingErrorpysig
parameterskeysrQ   defaultemptyr    joinranger   r<   strr   textwrapdedentformatexec)r`   ra   r   rb   rc   rd   disprt   r^   rS   pysig_paramsgen_var_namesbufkvcall_str_specificcall_strr   rq   namegenlgrW   r   )r`   ra   r   ol_generated   sF   






z-_OverloadWrapper._build.<locals>.ol_generated)numba.core.extendingrV   rW   r   )r   rV   r   r   r   r   r   ~   s
   z_OverloadWrapper._buildr   )
__name__
__module____qualname____doc__r   r<   rI   rM   rU   r   r   r   r   r   r      s    
(r   c                   @   s:   e Zd ZdZdd ZdddZdd Zd	d
 Zdd ZdS )_GluerzThis is a helper class to make sure that each concrete overload has only
    one wrapper as the code relies on the wrapper being a singleton.c                 C   s&   t  | _t | _t | _tt| _d S r   )	r	   _registeredr   _lockset	_no_deferr   list	_deferred)r   r   r   r   r      s   z_Gluer.__init__Nc                 C   sx   | j / |d u r|}n|}|| jv r| j| W  d    S t||d}|| j|< |W  d    S 1 s5w   Y  d S )Nr   )r   r   r   )r   funcr   r=   wrapperr   r   r   __call__   s   

$z_Gluer.__call__c                 C   s^   | j " || jv r|  n| j| | W d   dS W d   dS 1 s(w   Y  dS )z?Defer lowering of the given key and lowering function.
        N)r   r   r   r    )r   r=   lower_fnr   r   r   defer_lowering   s   
"z_Gluer.defer_loweringc                 C   s8   | j  | j| W d   dS 1 sw   Y  dS )z8Stop lowering to be deferred for the given key.
        N)r   r   add)r   r=   r   r   r   rC     s   "z_Gluer.add_no_deferc                 C   sJ   | j  | j|g }|D ]}|  qW d   dS 1 sw   Y  dS )z7Flush the deferred lowering for the given key.
        N)r   r   pop)r   r=   deferredcbr   r   r   rP     s   "z_Gluer.flush_deferred_loweringr   )	r   r   r   r   r   r   r   rC   rP   r   r   r   r   r      s    

r   c                 C   s   t | |d S )zThis is a decorator for wrapping the typing part for a concrete function
    'concrete_function', it's a text-only replacement for '@infer_global'r   )rB   rI   )concrete_functionr   r   r   r   glue_typing  s
   r   c                     s    fdd}|S )a   This is a decorator for wrapping the implementation (lowering) part for
    a concrete function. 'args[0]' is the concrete_function, 'args[1:]' are the
    types the lowering will accept. This acts as a text-only replacement for
    '@lower/@lower_builtin'c                    s(   d  fdd}t |  S )Nr   c                     s&   t  d d} | j dd   S )Nr   r      )rB   rM   )glue)rL   fnr=   r   r   	real_call.  s   z.glue_lowering.<locals>.wrap.<locals>.real_call)rB   r   )r   r   rL   )r   r=   r   wrap+  s   zglue_lowering.<locals>.wrapr   )rL   r   r   r   r   glue_lowering%  s   	r   r   )r   typesr0   r~   	threadingr   collectionsr   r   r   objectr   r   rB   r   r   r   r   r   r   <module>   s     Z4
