<s> from __future__ import print_function , absolute_import <EOL> import collections <EOL> import os <EOL> from ctypes import ( POINTER , c_char_p , c_longlong , c_int , c_size_t , <EOL> c_void_p , string_at , byref ) <EOL> from . import ffi <EOL> from . common import _decode_string , _encode_string <EOL> def get_process_triple ( ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_GetProcessTriple ( out ) <EOL> return str ( out ) <EOL> class FeatureMap ( dict ) : <EOL> """<STR_LIT>""" <EOL> def flatten ( self , sort = True ) : <EOL> """<STR_LIT>""" <EOL> iterator = sorted ( self . items ( ) ) if sort else iter ( self . items ( ) ) <EOL> flag_map = { True : '<STR_LIT:+>' , False : '<STR_LIT:->' } <EOL> return '<STR_LIT:U+002C>' . join ( '<STR_LIT>' . format ( flag_map [ v ] , k ) <EOL> for k , v in iterator ) <EOL> def get_host_cpu_features ( ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_GetHostCPUFeatures ( out ) <EOL> outdict = FeatureMap ( ) <EOL> flag_map = { '<STR_LIT:+>' : True , '<STR_LIT:->' : False } <EOL> for feat in str ( out ) . split ( '<STR_LIT:U+002C>' ) : <EOL> outdict [ feat [ <NUM_LIT:1> : ] ] = flag_map [ feat [ <NUM_LIT:0> ] ] <EOL> return outdict <EOL> def get_default_triple ( ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_GetDefaultTargetTriple ( out ) <EOL> return str ( out ) <EOL> def get_host_cpu_name ( ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_GetHostCPUName ( out ) <EOL> return str ( out ) <EOL> _object_formats = { <EOL> <NUM_LIT:1> : "<STR_LIT>" , <EOL> <NUM_LIT:2> : "<STR_LIT>" , <EOL> <NUM_LIT:3> : "<STR_LIT>" , <EOL> } <EOL> def get_object_format ( triple = None ) : <EOL> """<STR_LIT>""" <EOL> if triple is None : <EOL> triple = get_default_triple ( ) <EOL> res = ffi . lib . LLVMPY_GetTripleObjectFormat ( _encode_string ( triple ) ) <EOL> return _object_formats [ res ] <EOL> def create_target_data ( layout ) : <EOL> """<STR_LIT>""" <EOL> return TargetData ( ffi . lib . LLVMPY_CreateTargetData ( _encode_string ( layout ) ) ) <EOL> class TargetData ( ffi . ObjectRef ) : <EOL> """<STR_LIT>""" <EOL> def __str__ ( self ) : <EOL> if self . _closed : <EOL> return "<STR_LIT>" <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_CopyStringRepOfTargetData ( self , out ) <EOL> return str ( out ) <EOL> def _dispose ( self ) : <EOL> self . _capi . LLVMPY_DisposeTargetData ( self ) <EOL> def get_abi_size ( self , ty ) : <EOL> """<STR_LIT>""" <EOL> return ffi . lib . LLVMPY_ABISizeOfType ( self , ty ) <EOL> def get_pointee_abi_size ( self , ty ) : <EOL> """<STR_LIT>""" <EOL> size = ffi . lib . LLVMPY_ABISizeOfElementType ( self , ty ) <EOL> if size == - <NUM_LIT:1> : <EOL> raise RuntimeError ( "<STR_LIT>" % ( ty , ) ) <EOL> return size <EOL> def get_pointee_abi_alignment ( self , ty ) : <EOL> """<STR_LIT>""" <EOL> size = ffi . lib . LLVMPY_ABIAlignmentOfElementType ( self , ty ) <EOL> if size == - <NUM_LIT:1> : <EOL> raise RuntimeError ( "<STR_LIT>" % ( ty , ) ) <EOL> return size <EOL> def add_pass ( self , pm ) : <EOL> """<STR_LIT>""" <EOL> target_data = create_target_data ( str ( self ) ) <EOL> ffi . lib . LLVMPY_AddTargetData ( target_data , pm ) <EOL> RELOC = frozenset ( [ '<STR_LIT:default>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> CODEMODEL = frozenset ( [ '<STR_LIT:default>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> class Target ( ffi . ObjectRef ) : <EOL> _triple = '<STR_LIT>' <EOL> @ classmethod <EOL> def from_default_triple ( cls ) : <EOL> """<STR_LIT>""" <EOL> triple = get_default_triple ( ) <EOL> return cls . from_triple ( triple ) <EOL> @ classmethod <EOL> def from_triple ( cls , triple ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as outerr : <EOL> target = ffi . lib . LLVMPY_GetTargetFromTriple ( triple . encode ( '<STR_LIT:utf8>' ) , <EOL> outerr ) <EOL> if not target : <EOL> raise RuntimeError ( str ( outerr ) ) <EOL> target = cls ( target ) <EOL> target . _triple = triple <EOL> return target <EOL> @ property <EOL> def name ( self ) : <EOL> s = ffi . lib . LLVMPY_GetTargetName ( self ) <EOL> return _decode_string ( s ) <EOL> @ property <EOL> def description ( self ) : <EOL> s = ffi . lib . LLVMPY_GetTargetDescription ( self ) <EOL> return _decode_string ( s ) <EOL> @ property <EOL> def triple ( self ) : <EOL> return self . _triple <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" . format ( self . name , self . description ) <EOL> def create_target_machine ( self , cpu = '<STR_LIT>' , features = '<STR_LIT>' , <EOL> opt = <NUM_LIT:2> , reloc = '<STR_LIT:default>' , codemodel = '<STR_LIT>' , <EOL> jitdebug = False , printmc = False ) : <EOL> """<STR_LIT>""" <EOL> assert <NUM_LIT:0> <= opt <= <NUM_LIT:3> <EOL> assert reloc in RELOC <EOL> assert codemodel in CODEMODEL <EOL> triple = self . _triple <EOL> if os . name == '<STR_LIT>' and codemodel == '<STR_LIT>' : <EOL> triple += '<STR_LIT>' <EOL> tm = ffi . lib . LLVMPY_CreateTargetMachine ( self , <EOL> _encode_string ( triple ) , <EOL> _encode_string ( cpu ) , <EOL> _encode_string ( features ) , <EOL> opt , <EOL> _encode_string ( reloc ) , <EOL> _encode_string ( codemodel ) , <EOL> int ( jitdebug ) , <EOL> int ( printmc ) , <EOL> ) <EOL> if tm : <EOL> return TargetMachine ( tm ) <EOL> else : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> class TargetMachine ( ffi . ObjectRef ) : <EOL> def _dispose ( self ) : <EOL> self . _capi . LLVMPY_DisposeTargetMachine ( self ) <EOL> def add_analysis_passes ( self , pm ) : <EOL> """<STR_LIT>""" <EOL> ffi . lib . LLVMPY_AddAnalysisPasses ( self , pm ) <EOL> def emit_object ( self , module ) : <EOL> """<STR_LIT>""" <EOL> return self . _emit_to_memory ( module , use_object = True ) <EOL> def emit_assembly ( self , module ) : <EOL> """<STR_LIT>""" <EOL> return _decode_string ( self . _emit_to_memory ( module , use_object = False ) ) <EOL> def _emit_to_memory ( self , module , use_object = False ) : <EOL> """<STR_LIT>""" <EOL> with ffi . OutputString ( ) as outerr : <EOL> mb = ffi . lib . LLVMPY_TargetMachineEmitToMemory ( self , module , <EOL> int ( use_object ) , <EOL> outerr ) <EOL> if not mb : <EOL> raise RuntimeError ( str ( outerr ) ) <EOL> bufptr = ffi . lib . LLVMPY_GetBufferStart ( mb ) <EOL> bufsz = ffi . lib . LLVMPY_GetBufferSize ( mb ) <EOL> try : <EOL> return string_at ( bufptr , bufsz ) <EOL> finally : <EOL> ffi . lib . LLVMPY_DisposeMemoryBuffer ( mb ) <EOL> @ property <EOL> def target_data ( self ) : <EOL> return TargetData ( ffi . lib . LLVMPY_CreateTargetMachineData ( self ) ) <EOL> @ property <EOL> def triple ( self ) : <EOL> with ffi . OutputString ( ) as out : <EOL> ffi . lib . LLVMPY_GetTargetMachineTriple ( self , out ) <EOL> return str ( out ) <EOL> ffi . lib . LLVMPY_GetProcessTriple . argtypes = [ POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_GetHostCPUFeatures . argtypes = [ POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_GetDefaultTargetTriple . argtypes = [ POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_GetHostCPUName . argtypes = [ POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_GetTripleObjectFormat . argtypes = [ c_char_p ] <EOL> ffi . lib . LLVMPY_GetTripleObjectFormat . restype = c_int <EOL> ffi . lib . LLVMPY_CreateTargetData . argtypes = [ c_char_p ] <EOL> ffi . lib . LLVMPY_CreateTargetData . restype = ffi . LLVMTargetDataRef <EOL> ffi . lib . LLVMPY_CopyStringRepOfTargetData . argtypes = [ <EOL> ffi . LLVMTargetDataRef , <EOL> POINTER ( c_char_p ) , <EOL> ] <EOL> ffi . lib . LLVMPY_DisposeTargetData . argtypes = [ <EOL> ffi . LLVMTargetDataRef , <EOL> ] <EOL> ffi . lib . LLVMPY_AddTargetData . argtypes = [ ffi . LLVMTargetDataRef , <EOL> ffi . LLVMPassManagerRef ] <EOL> ffi . lib . LLVMPY_ABISizeOfType . argtypes = [ ffi . LLVMTargetDataRef , <EOL> ffi . LLVMTypeRef ] <EOL> ffi . lib . LLVMPY_ABISizeOfType . restype = c_longlong <EOL> ffi . lib . LLVMPY_ABISizeOfElementType . argtypes = [ ffi . LLVMTargetDataRef , <EOL> ffi . LLVMTypeRef ] <EOL> ffi . lib . LLVMPY_ABISizeOfElementType . restype = c_longlong <EOL> ffi . lib . LLVMPY_ABIAlignmentOfElementType . argtypes = [ ffi . LLVMTargetDataRef , <EOL> ffi . LLVMTypeRef ] <EOL> ffi . lib . LLVMPY_ABIAlignmentOfElementType . restype = c_longlong <EOL> ffi . lib . LLVMPY_GetTargetFromTriple . argtypes = [ c_char_p , POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_GetTargetFromTriple . restype = ffi . LLVMTargetRef <EOL> ffi . lib . LLVMPY_GetTargetName . argtypes = [ ffi . LLVMTargetRef ] <EOL> ffi . lib . LLVMPY_GetTargetName . restype = c_char_p <EOL> ffi . lib . LLVMPY_GetTargetDescription . argtypes = [ ffi . LLVMTargetRef ] <EOL> ffi . lib . LLVMPY_GetTargetDescription . restype = c_char_p <EOL> ffi . lib . LLVMPY_CreateTargetMachine . argtypes = [ <EOL> ffi . LLVMTargetRef , <EOL> c_char_p , <EOL> c_char_p , <EOL> c_char_p , <EOL> c_int , <EOL> c_char_p , <EOL> c_char_p , <EOL> ] <EOL> ffi . lib . LLVMPY_CreateTargetMachine . restype = ffi . LLVMTargetMachineRef <EOL> ffi . lib . LLVMPY_DisposeTargetMachine . argtypes = [ ffi . LLVMTargetMachineRef ] <EOL> ffi . lib . LLVMPY_GetTargetMachineTriple . argtypes = [ ffi . LLVMTargetMachineRef , <EOL> POINTER ( c_char_p ) ] <EOL> ffi . lib . LLVMPY_AddAnalysisPasses . argtypes = [ <EOL> ffi . LLVMTargetMachineRef , <EOL> ffi . LLVMPassManagerRef , <EOL> ] <EOL> ffi . lib . LLVMPY_TargetMachineEmitToMemory . argtypes = [ <EOL> ffi . LLVMTargetMachineRef , <EOL> ffi . LLVMModuleRef , <EOL> c_int , <EOL> POINTER ( c_char_p ) , <EOL> ] <EOL> ffi . lib . LLVMPY_TargetMachineEmitToMemory . restype = ffi . LLVMMemoryBufferRef <EOL> ffi . lib . LLVMPY_GetBufferStart . argtypes = [ ffi . LLVMMemoryBufferRef ] <EOL> ffi . lib . LLVMPY_GetBufferStart . restype = c_void_p <EOL> ffi . lib . LLVMPY_GetBufferSize . argtypes = [ ffi . LLVMMemoryBufferRef ] <EOL> ffi . lib . LLVMPY_GetBufferSize . restype = c_size_t <EOL> ffi . lib . LLVMPY_DisposeMemoryBuffer . argtypes = [ ffi . LLVMMemoryBufferRef ] <EOL> ffi . lib . LLVMPY_CreateTargetMachineData . argtypes = [ <EOL> ffi . LLVMTargetMachineRef , <EOL> ] <EOL> ffi . lib . LLVMPY_CreateTargetMachineData . restype = ffi . LLVMTargetDataRef </s>
