diff --git a/llvm/_core.c b/llvm/_core.c index e7667a2..c55beec 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -1001,6 +1001,19 @@ _wLLVMLoadLibraryPermanently(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/* Expose the void* inside a PyCObject as a PyLong. This allows us to + * use it as a unique ID. */ +static PyObject * +_wPyCObjectVoidPtrToPyLong(PyObject *self, PyObject *args) +{ + void *p; + + if (!(p = get_object_arg(args))) + return NULL; + + return PyLong_FromVoidPtr(p); +} + /*===----------------------------------------------------------------------===*/ /* Python member method table */ @@ -1441,6 +1454,7 @@ static PyMethodDef core_methods[] = { /* Misc */ _method( LLVMGetIntrinsic ) _method( LLVMLoadLibraryPermanently ) + _method( PyCObjectVoidPtrToPyLong ) { NULL } }; diff --git a/llvm/core.py b/llvm/core.py index 6f9fa90..bf90098 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -37,6 +37,7 @@ in-memory intermediate representation (IR) data structures.""" import llvm # top-level, for common stuff import llvm._core as _core # C wrappers from llvm._util import * # utility functions +import weakref # global list of modules #===----------------------------------------------------------------------=== @@ -802,6 +803,17 @@ def _to_int(v): else: return 0 +__all_modules = weakref.WeakValueDictionary() + +def _report_new_module(ptr, obj): + __all_modules[_core.PyCObjectVoidPtrToPyLong(ptr)] = obj + +def _module_from_ptr(ptr): + i = _core.PyCObjectVoidPtrToPyLong(ptr) + if i not in __all_modules: + raise llvm.LLVMException, "module not found in internal list" + return __all_modules[i] + #===----------------------------------------------------------------------=== # Module @@ -865,6 +877,7 @@ class Module(llvm.Ownable): Use the static method `Module.new' instead. """ llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule) + _report_new_module(ptr, self) def __str__(self): """Text representation of a module. @@ -1937,10 +1950,12 @@ class BasicBlock(Value): _core.LLVMDeleteBasicBlock(self.ptr) self.ptr = None - #-- disabled till we find a proper way to do it -- - #@property - #def function(self): - # return Function(_core.LLVMGetBasicBlockParent(self.ptr)) + @property + def function(self): + func_ptr = _core.LLVMGetBasicBlockParent(self.ptr) + module_ptr = _core.LLVMGetGlobalParent(func_ptr) + module_obj = _module_from_ptr(module_ptr) + return Function(func_ptr, module_obj) @property def instructions(self): diff --git a/test/testall.py b/test/testall.py index c883fb9..ca4e0e4 100644 --- a/test/testall.py +++ b/test/testall.py @@ -349,8 +349,9 @@ def do_basicblock(): s = list(b.instructions) b2 = b.insert_before('before') b2.delete() - # ff = b.function - # ^ not working yet! + ff = b.function + m2 = ff.module + t = m == m2 def _do_builder_mrv():