diff --git a/llvm/__init__.py b/llvm/__init__.py index 395e698..318ba9d 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -6,9 +6,7 @@ __version__ = '0.9.1' from weakref import WeakValueDictionary -from llvm._utils.finalizer import track as track_resource -from llvm._utils.finalizer import OwnerMixin as _OwnerMixin -from llvm import _core +import _core #===----------------------------------------------------------------------=== # LLVM Version @@ -33,26 +31,11 @@ class LLVMException(Exception): Exception.__init__(self, msg) -#===----------------------------------------------------------------------=== -# Resource Handle -#===----------------------------------------------------------------------=== - -class Handle(_OwnerMixin): - _finalizer = NotImplemented - - def __init__(self, ptr): - self.ptr = ptr - self._finalizer_track(self.ptr) - - @classmethod - def _finalize(cls, ptr): - cls._finalizer(ptr) - #===----------------------------------------------------------------------=== # Ownables #===----------------------------------------------------------------------=== -class Ownable(Handle): +class Ownable(object): """Objects that can be owned. Modules and Module Providers can be owned, i.e., the responsibility of @@ -61,21 +44,25 @@ class Ownable(Handle): is NOT intended for public use. """ - def __init__(self, ptr): - Handle.__init__(self, ptr) + def __init__(self, ptr, del_fn): + self.ptr = ptr self.owner = None + self.del_fn = del_fn def _own(self, owner): if self.owner: raise LLVMException("object already owned") self.owner = owner - self._finalizer_untrack(self.ptr) def _disown(self): if not self.owner: raise LLVMException("not owned") self.owner = None - self._finalizer_track(self.ptr) + + def __del__(self): + if not self.owner: + self.del_fn(self.ptr) + #===----------------------------------------------------------------------=== # Dummy owner, will not delete ownee. Be careful. diff --git a/llvm/_utils/__init__.py b/llvm/_utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/llvm/_utils/finalizer.py b/llvm/_utils/finalizer.py deleted file mode 100644 index 56df5b7..0000000 --- a/llvm/_utils/finalizer.py +++ /dev/null @@ -1,58 +0,0 @@ -''' -Modified C-level finalizer by Benjamin Peterson -Available at http://code.activestate.com/recipes/577242-calling-c-level-finalizers-without-__del__/ -''' -import sys -import traceback -import weakref - -class OwnerRef(weakref.ref): - """A simple weakref.ref subclass, so attributes can be added.""" - pass - -def _run_finalizer(ref): - """Internal weakref callback to run finalizers""" - del _finalize_refs[ref.owner] - for item, finalizer in ref.items: - try: - finalizer(item) - except Exception: - print>>sys.stderr, "Exception running {}:".format(finalizer) - traceback.print_exc() - -_finalize_refs = {} - -def track(owner, item, finalizer): - """Register an object for finalization. - - ``owner`` is the the object which is responsible for ``item``. - ``finalizer`` will be called with ``item`` as its only argument when - ``owner`` is destroyed by the garbage collector. - """ - if id(owner) in _finalize_refs: - ref = _finalize_refs[id(owner)] - else: - ref = OwnerRef(owner, _run_finalizer) - ref.owner = id(owner) - ref.items = [] - ref.items.append((item, finalizer)) - _finalize_refs[id(owner)] = ref - -def untrack(owner, item): - ref = _finalize_refs[id(owner)] - # search and remove the item from the ref - for i, (item_i, _) in enumerate(ref.items): - if item_i is item: - del ref.items[i] - # remove the ref if it is empty - if not ref.items: - del _finalize_refs[id(owner)] - -class OwnerMixin(object): - def _finalizer_track(self, item): - if not hasattr(self, '_finalize'): - raise AttributeError("%s must define a _finalize method" % self) - track(self, item, type(self)._finalize) - - def _finalizer_untrack(self, item): - untrack(self, item) diff --git a/llvm/core.py b/llvm/core.py index a6f7147..ba74ec2 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -397,9 +397,7 @@ class Module(llvm.Ownable, llvm.Cacheable): Use the static method `Module.new' instead. """ - llvm.Ownable.__init__(self, ptr) - - _finalizer = _core.LLVMDisposeModule + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeModule) def __str__(self): """Text representation of a module. @@ -1801,7 +1799,7 @@ def _make_value(ptr): # Builder #===----------------------------------------------------------------------=== -class Builder(llvm.Handle): +class Builder(object): @staticmethod def new(basic_block): @@ -1811,9 +1809,10 @@ class Builder(llvm.Handle): return b def __init__(self, ptr): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr - _finalizer = _core.LLVMDisposeBuilder + def __del__(self): + _core.LLVMDisposeBuilder(self.ptr) def position_at_beginning(self, bblk): """Position the builder at the beginning of the given block. @@ -2302,7 +2301,7 @@ class Builder(llvm.Handle): # Memory buffer #===----------------------------------------------------------------------=== -class MemoryBuffer(llvm.Handle): +class MemoryBuffer(object): @staticmethod def from_file(fname): @@ -2323,9 +2322,10 @@ class MemoryBuffer(llvm.Handle): return (obj, "") def __init__(self, ptr): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr - _finalizer = _core.LLVMDisposeMemoryBuffer + def __del__(self): + _core.LLVMDisposeMemoryBuffer(self.ptr) #===----------------------------------------------------------------------=== diff --git a/llvm/ee.py b/llvm/ee.py index 8d778df..4e1f97b 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -63,7 +63,7 @@ CM_LARGE = 5 # Generic value #===----------------------------------------------------------------------=== -class GenericValue(llvm.Handle): +class GenericValue(object): @staticmethod def int(ty, intval): @@ -106,9 +106,10 @@ class GenericValue(llvm.Handle): return GenericValue(ptr) def __init__(self, ptr): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr - _finalizer = _core.LLVMDisposeGenericValue + def __del__(self): + _core.LLVMDisposeGenericValue(self.ptr) def as_int(self): return _core.LLVMGenericValueToInt(self.ptr, 0) @@ -134,7 +135,7 @@ def _unpack_generic_values(objlist): # Engine builder #===----------------------------------------------------------------------=== -class EngineBuilder(llvm.Handle): +class EngineBuilder(object): @staticmethod def new(module): core.check_is_module(module) @@ -143,10 +144,11 @@ class EngineBuilder(llvm.Handle): return EngineBuilder(obj, module) def __init__(self, ptr, module): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr self._module = module - _finalizer = _core.LLVMDisposeEngineBuilder + def __del__(self): + _core.LLVMDisposeEngineBuilder(self.ptr) def force_jit(self): _core.LLVMEngineBuilderForceJIT(self.ptr) @@ -199,7 +201,7 @@ class EngineBuilder(llvm.Handle): # Execution engine #===----------------------------------------------------------------------=== -class ExecutionEngine(llvm.Handle): +class ExecutionEngine(object): @staticmethod def new(module, force_interpreter=False): @@ -211,10 +213,11 @@ class ExecutionEngine(llvm.Handle): return ExecutionEngine(ret, module) def __init__(self, ptr, module): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr module._own(self) - _finalizer = _core.LLVMDisposeExecutionEngine + def __del__(self): + _core.LLVMDisposeExecutionEngine(self.ptr) def run_function(self, fn, args): core.check_is_function(fn) @@ -313,9 +316,7 @@ class TargetMachine(llvm.Ownable): return TargetMachine(ptr) def __init__(self, ptr): - llvm.Ownable.__init__(self, ptr) - - _finalizer = _core.LLVMDisposeTargetMachine + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposeTargetMachine) def emit_assembly(self, module): '''returns byte string of the module as assembly code of the target machine diff --git a/llvm/passes.py b/llvm/passes.py index 7cc2b31..2b50aca 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -45,15 +45,16 @@ import warnings # Pass manager builder #===----------------------------------------------------------------------=== -class PassManagerBuilder(llvm.Handle): +class PassManagerBuilder(object): @staticmethod def new(): return PassManagerBuilder(_core.LLVMPassManagerBuilderCreate()) def __init__(self, ptr): - llvm.Handle.__init__(self, ptr) + self.ptr = ptr - _finalizer = _core.LLVMPassManagerBuilderDispose + def __del__(self): + _core.LLVMPassManagerBuilderDispose(self.ptr) def populate(self, pm): if isinstance(pm, FunctionPassManager): @@ -141,7 +142,7 @@ class PassManagerBuilder(llvm.Handle): # Pass manager #===----------------------------------------------------------------------=== -class PassManager(llvm.Handle): +class PassManager(object): @staticmethod def new(): @@ -150,7 +151,8 @@ class PassManager(llvm.Handle): def __init__(self, ptr): self.ptr = ptr - _finalizer = _core.LLVMDisposePassManager + def __del__(self): + _core.LLVMDisposePassManager(self.ptr) def add(self, pass_obj): '''Add a pass to the pass manager. @@ -206,11 +208,9 @@ class Pass(llvm.Ownable): '''Pass Inferface ''' def __init__(self, ptr): - llvm.Ownable.__init__(self, ptr) + llvm.Ownable.__init__(self, ptr, _core.LLVMDisposePass) self.__name = '' - _finalizer = _core.LLVMDisposePass - @staticmethod def new(name): '''Create a new pass by name. diff --git a/setup.py b/setup.py index d6d6a3b..94c9f95 100644 --- a/setup.py +++ b/setup.py @@ -131,7 +131,7 @@ setup( maintainer = 'Continuum Analytics, Inc.', maintainer_email = 'llvmpy@continuum.io', url = 'http://www.llvmpy.org/', - packages = ['llvm', 'llvm_cbuilder', 'llpython', 'llvm._utils'], + packages = ['llvm', 'llvm_cbuilder', 'llpython'], py_modules = ['llvm.core'], license = "BSD", classifiers = [