llvmpy/newbinding/capsule.py
Siu Kwan Lam a12c4da93d Init commit for work on new binding
This contains the foundation for the new binding as well as early work on Module and Type.
2013-02-05 13:47:32 -06:00

74 lines
1.7 KiB
Python

import _capsule
from weakref import WeakValueDictionary
_pyclasses = {}
_addr2obj = WeakValueDictionary()
def _sentry(ptr):
assert _capsule.check(ptr)
def classof(cap):
cls = _capsule.getClassName(cap)
return _pyclasses[cls]
def wrap(cap):
'''Wrap a PyCapsule with the corresponding Wrapper class.
If `cap` is not a PyCapsule, returns `cap`
'''
if not _capsule.check(cap): # bypass if cap is not a PyCapsule
return cap
addr = _capsule.getPointer(cap)
try:
# find cached object by pointer address
obj = _addr2obj[addr]
except KeyError:
# create new object and cache it
cls = classof(cap)
obj = cls(cap)
_addr2obj[addr] = obj # cache object by address
# set destructor if cls.delete is defined
if hasattr(cls, '_delete_'):
_capsule.setDestructor(cap, cls._delete_)
else:
assert classof(obj._ptr) is classof(cap)
# Unset destructor for capsules that are repeated
_capsule.setDestructor(cap, None)
return obj
def unwrap(obj):
'''Unwrap a Wrapper instance into the underlying PyCapsule.
If `obj` is not a Wrapper instance, returns `obj`.
'''
if isinstance(obj, Wrapper):
return obj._ptr
else:
return obj
def register_class(cls):
clsname = cls.__name__
_pyclasses['llvm::%s' % clsname] = cls
return cls
class Wrapper(object):
__slots__ = '__ptr'
def __init__(self, ptr):
_sentry(ptr)
self.__ptr = ptr
@property
def _ptr(self):
return self.__ptr
def _release_ownership(self):
_capsule.setDestructor(self._ptr, None)