B
    Ꮚ\                 @   s  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	 dd Z
e
d	Ze
d
Ze
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZe
dZG dd deZG dd deZej !e"Z#ej$dkr&ej%d   d!e# 7  < e Z&ye 'ej (e#e&Z)W nV e*k
r Z+ z6ye 'e&Z)W n" e*k
r   e	re+ Y nX W ddZ+[+X Y nX ee)Z)G d"d# d#eZ,G d$d% d%eZ-G d&d' d'eZ.dS )(    N   )_decode_string_is_shutting_down   )get_library_name)PY2c             C   s   t | tjfi }t|S )N)typectypesZ	StructureZPOINTER)nameZnewcls r   3lib/python3.7/site-packages/llvmlite/binding/ffi.py_make_opaque_ref
   s    r   ZLLVMContextZ
LLVMModuleZ	LLVMValueZLLVMTypeZLLVMExecutionEngineZLLVMPassManagerBuilderZLLVMPassManagerZLLVMTargetDataZLLVMTargetLibraryInfoZ
LLVMTargetZLLVMTargetMachineZLLVMMemoryBufferLLVMGlobalsIteratorLLVMFunctionsIteratorLLVMTypesIteratorZLLVMObjectCacheZLLVMObjectFileZLLVMSectionIteratorc               @   sB   e Zd ZdZdddgZdd Zdd Zed	d
 Zedd Z	dS )_lib_wrapperz{Wrap libllvmlite with a lock such that only one thread may access it at
    a time.

    This class duck-types a CDLL.
    _lib_fntab_lockc             C   s   || _ i | _t | _d S )N)r   r   	threadingRLockr   )selflibr   r   r   __init__+   s    z_lib_wrapper.__init__c             C   sF   y
| j | S  tk
r@   t| j|}t| j|}|| j |< |S X d S )N)r   KeyErrorgetattrr   _lib_fn_wrapperr   )r   r
   cfnwrappedr   r   r   __getattr__2   s    

z_lib_wrapper.__getattr__c             C   s   | j jS )zgThe name of the library passed in the CDLL constructor.

        For duck-typing a ctypes.CDLL
        )r   _name)r   r   r   r   r    <   s    z_lib_wrapper._namec             C   s   | j jS )z]The system handle used to access the library.

        For duck-typing a ctypes.CDLL
        )r   _handle)r   r   r   r   r!   D   s    z_lib_wrapper._handleN)
__name__
__module____qualname____doc__	__slots__r   r   propertyr    r!   r   r   r   r   r   #   s   

r   c               @   s\   e Zd ZdZddgZdd Zedd Zejdd Zed	d
 Z	e	jdd
 Z	dd Z
dS )r   zWraps and duck-types a ctypes.CFUNCTYPE to provide
    automatic locking when the wrapped function is called.

    TODO: we can add methods to mark the function as threadsafe
          and remove the locking-step on call when marked.
    r   _cfnc             C   s   || _ || _d S )N)r   r(   )r   lockr   r   r   r   r   V   s    z_lib_fn_wrapper.__init__c             C   s   | j jS )N)r(   argtypes)r   r   r   r   r*   Z   s    z_lib_fn_wrapper.argtypesc             C   s   || j _d S )N)r(   r*   )r   r*   r   r   r   r*   ^   s    c             C   s   | j jS )N)r(   restype)r   r   r   r   r+   b   s    z_lib_fn_wrapper.restypec             C   s   || j _d S )N)r(   r+   )r   r+   r   r   r   r+   f   s    c          	   O   s   | j  | j||S Q R X d S )N)r   r(   )r   argskwargsr   r   r   __call__j   s    z_lib_fn_wrapper.__call__N)r"   r#   r$   r%   r&   r   r'   r*   setterr+   r.   r   r   r   r   r   M   s   r   ntPATH;c               @   s   e Zd ZdZdS )_DeadPointerz:
    Dummy class to make error messages more helpful.
    N)r"   r#   r$   r%   r   r   r   r   r3      s   r3   c               @   sX   e Zd ZdZe ZdddZdd Zdd Zd	d
 Z	e
fddZdd Zdd ZeZdS )OutputStringz<
    Object for managing the char* output of LLVM APIs.
    Tc             C   s$   t d | _t | j| _|| _d S )N)r	   Zc_char_p_ptrZbyref_as_parameter__owned)r   Zownedr   r   r   r      s    zOutputString.__init__c             C   s*   | j d k	r&| jrt| j  d | _ | `d S )N)r5   r7   r   ZLLVMPY_DisposeStringr6   )r   r   r   r   close   s
    
zOutputString.closec             C   s   | S )Nr   )r   r   r   r   	__enter__   s    zOutputString.__enter__c             C   s   |    d S )N)r8   )r   exc_typeexc_valexc_tbr   r   r   __exit__   s    zOutputString.__exit__c             C   s   | s| j d k	r|    d S )N)r8   )r   r   r   r   r   __del__   s    
zOutputString.__del__c             C   s*   | j d krdS | j j}|d k	s"tt|S )Nz<dead OutputString>)r5   valueAssertionErrorr   )r   sr   r   r   __str__   s
    
zOutputString.__str__c             C   s
   t | jS )N)boolr5   )r   r   r   r   __bool__   s    zOutputString.__bool__N)T)r"   r#   r$   r%   r3   r6   r   r8   r9   r=   r   r>   rB   rD   __nonzero__r   r   r   r   r4      s   
r4   c               @   s   e Zd ZdZdZe ZdZdd Zdd Z	dd Z
d	d
 Zedd Zdd Zdd ZefddZdd Zdd ZeZdd ZdS )	ObjectRefzJ
    A wrapper around a ctypes pointer to a LLVM object ("resource").
    Fc             C   s&   |d krt d|| _|| _t| _d S )NzNULL pointer)
ValueErrorr5   r6   r   Z_capi)r   Zptrr   r   r   r      s
    zObjectRef.__init__c             C   s(   z| j s| js|   W d|   X dS )zI
        Close this object and do any required clean-up actions.
        N)_closedr7   _disposedetach)r   r   r   r   r8      s    zObjectRef.closec             C   s   | j s| `d| _ d| _dS )zN
        Detach the underlying LLVM resource without disposing of it.
        TN)rH   r6   r5   )r   r   r   r   rJ      s    zObjectRef.detachc             C   s   dS )z
        Dispose of the underlying LLVM resource.  Should be overriden
        by subclasses.  Automatically called by close(), __del__() and
        __exit__() (unless the resource has been detached).
        Nr   )r   r   r   r   rI      s    zObjectRef._disposec             C   s   | j S )zf
        Whether this object has been closed.  A closed object can't
        be used anymore.
        )rH   )r   r   r   r   closed   s    zObjectRef.closedc             C   s(   t | dst| jr$td| jf | S )Nr8   z%s instance already closed)hasattrr@   rH   RuntimeError	__class__)r   r   r   r   r9      s    zObjectRef.__enter__c             C   s   |    d S )N)r8   )r   r:   r;   r<   r   r   r   r=      s    zObjectRef.__exit__c             C   s   | s| j d k	r|    d S )N)r8   )r   r   r   r   r   r>      s    
zObjectRef.__del__c             C   s
   t | jS )N)rC   r5   )r   r   r   r   rD      s    zObjectRef.__bool__c             C   s.   t |dsdS t| jd t|jd kS )Nr5   Fr   )rL   r	   Z	addressofr5   )r   otherr   r   r   __eq__   s    
zObjectRef.__eq__c             C   s   t t| jtjjS )N)hashr	   castr5   Zc_void_pr?   )r   r   r   r   __hash__  s    zObjectRef.__hash__N)r"   r#   r$   r%   rH   r3   r6   r7   r   r8   rJ   rI   r'   rK   r9   r=   r   r>   rD   rP   rE   rS   r   r   r   r   rF      s    
	rF   )/r	   osr   commonr   r   Zutilsr   Zsixr   r   ZLLVMContextRefZLLVMModuleRefZLLVMValueRefZLLVMTypeRefZLLVMExecutionEngineRefZLLVMPassManagerBuilderRefZLLVMPassManagerRefZLLVMTargetDataRefZLLVMTargetLibraryInfoRefZLLVMTargetRefZLLVMTargetMachineRefZLLVMMemoryBufferRefr   r   r   ZLLVMObjectCacheRefZLLVMObjectFileRefZLLVMSectionIteratorRefobjectr   r   pathdirname__file__Z_lib_dirr
   environZ	_lib_nameZCDLLjoinr   OSErrorer3   r4   rF   r   r   r   r   <module>   sV   *",