[llvm.py] Implement interface to object files
[oota-llvm.git] / bindings / python / llvm / common.py
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
10 from ctypes import POINTER
11 from ctypes import c_void_p
12 from ctypes import cdll
13
14 import ctypes.util
15
16 __all__ = [
17     'c_object_p',
18     'find_library',
19     'get_library',
20 ]
21
22 c_object_p = POINTER(c_void_p)
23
24 class 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 self._self_owned and self._disposer:
62             self._disposer(self)
63
64 class CachedProperty(object):
65     """Decorator that caches the result of a property lookup.
66
67     This is a useful replacement for @property. It is recommended to use this
68     decorator on properties that invoke C API calls for which the result of the
69     call will be idempotent.
70     """
71     def __init__(self, wrapped):
72         self.wrapped = wrapped
73         try:
74             self.__doc__ = wrapped.__doc__
75         except: # pragma: no cover
76             pass
77
78     def __get__(self, instance, instance_type=None):
79         if instance is None:
80             return self
81
82         value = self.wrapped(instance)
83         setattr(instance, self.wrapped.__name__, value)
84
85         return value
86
87 def find_library():
88     # FIXME should probably have build system define absolute path of shared
89     # library at install time.
90     for lib in ['LLVM-3.1svn', 'libLLVM-3.1svn', 'LLVM', 'libLLVM']:
91         result = ctypes.util.find_library(lib)
92         if result:
93             return result
94
95     return None
96
97 def get_library():
98     """Obtain a reference to the llvm library."""
99     lib = find_library()
100     if not lib:
101         raise Exception('LLVM shared library not found!')
102
103     return cdll.LoadLibrary(lib)