1#===- common.py - Python LLVM Bindings -----------------------*- python -*--===# 2# 3# The LLVM Compiler Infrastructure 4# 5# This file is distributed under the University of Illinois Open Source 6# License. See LICENSE.TXT for details. 7# 8#===------------------------------------------------------------------------===# 9 10from ctypes import POINTER 11from ctypes import c_void_p 12from ctypes import cdll 13 14import ctypes.util 15 16__all__ = [ 17 'c_object_p', 18 'find_library', 19 'get_library', 20] 21 22c_object_p = POINTER(c_void_p) 23 24class LLVMObject(object): 25 """Base class for objects that are backed by an LLVM data structure. 26 27 This class should never be instantiated outside of this package. 28 """ 29 def __init__(self, ptr, ownable=True, disposer=None): 30 assert isinstance(ptr, c_object_p) 31 32 self._ptr = self._as_parameter_ = ptr 33 34 self._self_owned = True 35 self._ownable = ownable 36 self._disposer = disposer 37 38 self._owned_objects = [] 39 40 def take_ownership(self, obj): 41 """Take ownership of another object. 42 43 When you take ownership of another object, you are responsible for 44 destroying that object. In addition, a reference to that object is 45 placed inside this object so the Python garbage collector will not 46 collect the object while it is still alive in libLLVM. 47 48 This method should likely only be called from within modules inside 49 this package. 50 """ 51 assert isinstance(obj, LLVMObject) 52 53 self._owned_objects.append(obj) 54 obj._self_owned = False 55 56 def from_param(self): 57 """ctypes function that converts this object to a function parameter.""" 58 return self._as_parameter_ 59 60 def __del__(self): 61 if not hasattr(self, '_self_owned') or not hasattr(self, '_disposer'): 62 return 63 64 if self._self_owned and self._disposer: 65 self._disposer(self) 66 67class CachedProperty(object): 68 """Decorator that caches the result of a property lookup. 69 70 This is a useful replacement for @property. It is recommended to use this 71 decorator on properties that invoke C API calls for which the result of the 72 call will be idempotent. 73 """ 74 def __init__(self, wrapped): 75 self.wrapped = wrapped 76 try: 77 self.__doc__ = wrapped.__doc__ 78 except: # pragma: no cover 79 pass 80 81 def __get__(self, instance, instance_type=None): 82 if instance is None: 83 return self 84 85 value = self.wrapped(instance) 86 setattr(instance, self.wrapped.__name__, value) 87 88 return value 89 90def find_library(): 91 # FIXME should probably have build system define absolute path of shared 92 # library at install time. 93 for lib in ['LLVM-3.1svn', 'libLLVM-3.1svn', 'LLVM', 'libLLVM']: 94 result = ctypes.util.find_library(lib) 95 if result: 96 return result 97 98 return None 99 100def get_library(): 101 """Obtain a reference to the llvm library.""" 102 lib = find_library() 103 if not lib: 104 raise Exception('LLVM shared library not found!') 105 106 return cdll.LoadLibrary(lib) 107