#===- common.py - Python LLVM Bindings -----------------------*- python -*--===# # # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # #===------------------------------------------------------------------------===# from ctypes import POINTER from ctypes import c_void_p from ctypes import cdll import ctypes.util __all__ = [ 'c_object_p', 'find_library', 'get_library', ] c_object_p = POINTER(c_void_p) class LLVMObject(object): """Base class for objects that are backed by an LLVM data structure. This class should never be instantiated outside of this package. """ def __init__(self, ptr, ownable=True, disposer=None): assert isinstance(ptr, c_object_p) self._ptr = self._as_parameter_ = ptr self._self_owned = True self._ownable = ownable self._disposer = disposer self._owned_objects = [] def take_ownership(self, obj): """Take ownership of another object. When you take ownership of another object, you are responsible for destroying that object. In addition, a reference to that object is placed inside this object so the Python garbage collector will not collect the object while it is still alive in libLLVM. This method should likely only be called from within modules inside this package. """ assert isinstance(obj, LLVMObject) self._owned_objects.append(obj) obj._self_owned = False def from_param(self): """ctypes function that converts this object to a function parameter.""" return self._as_parameter_ def __del__(self): if self._self_owned and self._disposer: self._disposer(self) class CachedProperty(object): """Decorator that caches the result of a property lookup. This is a useful replacement for @property. It is recommended to use this decorator on properties that invoke C API calls for which the result of the call will be idempotent. """ def __init__(self, wrapped): self.wrapped = wrapped try: self.__doc__ = wrapped.__doc__ except: # pragma: no cover pass def __get__(self, instance, instance_type=None): if instance is None: return self value = self.wrapped(instance) setattr(instance, self.wrapped.__name__, value) return value def find_library(): # FIXME should probably have build system define absolute path of shared # library at install time. for lib in ['LLVM-3.1svn', 'libLLVM-3.1svn', 'LLVM', 'libLLVM']: result = ctypes.util.find_library(lib) if result: return result return None def get_library(): """Obtain a reference to the llvm library.""" lib = find_library() if not lib: raise Exception('LLVM shared library not found!') return cdll.LoadLibrary(lib)