Hm. I may misunderstand, but I'm not sure that's an improvement over
the problem you're trying to solve. How about something like this?
(Please forgive any accent; I don't speak snake fluently.)
class Pet(object):
@staticmethod
def new():
# Create a 'free' pet. It can later become owned, but not to more
than one owner.
return Pet(_core.LLVMCreatePet(), None)
def __init__(self, ptr, owner):
self.ptr = ptr
self.owner = owner
def __del__(self):
# Do not call the dtor if something else has committed to do so
for us!
if !self.owner:
_core.LLVMDisposePet(self.ptr)
class Owner(pet):
@staticmethod
def new():
if pet.owner:
raise OwnershipError("Pet already owned!")
return Owner(_core.LLVMCreateOwner(pet.ptr), pet)
def __init__(self, ptr, kid):
self.ptr = ptr
pet.owner = self
def add(self, pet):
if (pet.owner)
raise OwnershipError("Pet already owned!")
_core.LLVMAddPet(pet.ptr)
pet.owner = self
@property
def first_pet(self):
# Create an 'owned' pet.
return Pet(_core.LLVMGetFirstPet(self.ptr), self)
def __del__(self):
_core.LLVMDisposeOwner(pet.owner)
This will create gobs of child->parent references. Don't remember
whether that's a problem in Python. This pattern is composable, which
is an important property; Owner could play the role of Pet to some
OtherOwner.
But this is really delving into the realm of excessively elaborate, so
I think I'll bow out now. Do whatever you think best. :)
On May 13, 2008, at 04:31, Mahadevan R wrote:
> On Tue, May 13, 2008 at 1:22 PM, Gordon Henriksen
> <gordonhenriksen at mac.com> wrote:
>> On 2008-05-13, at 02:12, Mahadevan R wrote:
>>
>>>>> That's not how the object works...
>>>
>>> Gordon, I think I can make it work if we have the following
>>> additional
>>> function in LLVM-C:
>>>
>>> LLVMModuleRef LLVMGetModule(LLVMModuleProviderRef MP) {
>>> return wrap(unwrap(MP)->getModule());
>>> }
>>
>> Can I ask, how general is your solution? I only intended to use this
>> particular example as a proxy for the general problem of interaction
>> between GC and manual memory management being complex. Will you
>> require changing your Module bindings if another kind of object can
>> take ownership of a Module?
>
> Well, the root cause (in this case) was that the concept of the
> ownership
> of the module getting transferred to the module provider was not
> reflected
> in the design. Initially, there was a module, which owned a
> LLVMModuleRef:
>
> module_obj has-a LLVMModuleRef
>
> After transferring ownership to the module provider, the situation
> becomes:
>
> mp_obj has-a LLVMModuleProviderRef
> mp_obj has-a module_obj
> module_obj belongs-to-a mp_obj
>
> and also:
> LLVMModuleProviderRef has-a LLVMModuleRef
>
> All relations are necessary to satisfy the use cases. The only way
> for the
> module_obj to get the LLVMModuleRef *should* be via
> mp_obj->LLVMModuleProviderRef->getModule.
>
> Like so:
>
> class ModuleProvider(object):
>
> def __init__(self, ptr, module):
> self.ptr = ptr
> self.module = module
> module._attach_to_provider(self)
>
> @property
> def module_ptr_non_owning:
> return _core.LLVMGetModule(self.ptr)
>
>
> class Module(object):
>
> def __init__(self, ptr):
> self._ptr = ptr
> self.provider = None
>
> def _attach_to_provider(self, provider):
> self.provider = provider
> self._ptr = None
>
> @property
> def ptr(self):
> if self.provider:
> return self.provider.module_ptr_non_owning
> else:
> assert self._ptr
> return self._ptr
>
> # Use self.ptr temporarily, for making LLVM*() calls that
> # require a LLVMModuleRef.
>
> I've to admit assuming that only ModuleProviders own Modules.
> The concept of non-owned wrapping objects are also missing.
> The design will have to evolve as I cover more APIs, I guess.
>
> Regards,
> -Mahadevan.
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
— Gordon