On Wed, Sep 7, 2016 at 9:09 PM, Esteban Lorenzano <esteba...@gmail.com> wrote:
>
> On 07 Sep 2016, at 14:56, Ben Coman <b...@openinworld.com> wrote:
>
> On Tue, Sep 6, 2016 at 8:08 PM, Esteban Lorenzano <esteba...@gmail.com>
> wrote:
>
> Hi,
>
> sorry for arriving so late to this, but I was on holidays :)
> this is how autoRelease works:
>
> 1) #autoRelease of an object registers object for finalisation with a
> particular executor. Then behaviour is divided:
>
> 2.1.1) for ExternalAddresses, it just registers in regular way, who will
> call #finalize on GC
> 2.1.2) finalize will just call a free assuming ExternalAddress was allocated
> (which is a malloc)
>
> 2.2.1) for all FFIExternalReference, it will register for finalisation what
> #resourceData answers (normally, the handle of the object)
> 2.2.2) finalisation process will call the object
> class>>#finalizeResourceData: method, with the #resourceData result as
> parameter
> 2.2.3) each kind of external reference can decide how to free that data (by
> default is also just freeing).
>
> An example of this is how CairoFontFace works (or AthensCairoSurface).
>
>
>
> At the bottom of FFIExternalResourceExecutor class comment I read...
>    "Note that in #finalizeResourceData: you cannot
>     access any other properties of your instance,
>     since it is already garbage collected."
>
> But in my experiments it seems okay to access instance variables in
> #finalize.
> For example...
>
> CXString >> autoRelease
>   self class finalizationRegistry add: self
>
> CXString >> finalize
>    Transcript crShow: 'Finalizing CXString ' ; show: self private_flags.
>    self dispose.
>    Transcript show: ', done!'.
>
> CXString >>private_flags
>    "This method was automatically generated"
>    ^handle unsignedLongAt: 5
>
> Libclang getClangVersion autoRelease.
> Smalltalk garbageCollect.
> "==> Finalizing CXString 1, done! "
>
>
> Is this an unlucky coincidence?   Or maybe something changed from NB
> to UFFI?  (There is a reference to NB there)
>
>
> yes, is a coincidence.
> the idea of using #finalizeResourceData: is that you keep minimal
> information (in general, just the handle)… this way we ensure instances will
> be collected because we will not have circular references (preventing the
> weakregistry to work).
>
> In general, you can always implement as you did it, but I would prefer the
> #finalizeResourceData: approach, even for structures.
> The only reason it is not implemented is because I didn’t reach the
> necessity, then I just skipped it (not in purpose, it was not in my head
> :P), but now is a good moment to implement it… if you want it :)

Thanks for the offer, but hold off for the moment.  I think I actually
need more than just finalization session management.  To get a real
displayable string requires calling the clang_getCString() library
function.  I imagine I'd like to call this from  CXString>>printOn: --
but this of course this would break after restarting the image.

extern "C" {
const char *clang_getCString(CXString string) {
   ....
   return static_cast<const char *>(string.data);
}}

typedef struct {
  const void *data;
  unsigned private_flags;
} CXString;

So I think I need to register CXString with SessionManager to set *data <-- 0
on startup.

An alternative might be adding a session variable to CXString,
    FFIExternalStructure subclass: #CXString
        instanceVariableNames: 'session'
        classVariableNames: ''
        poolDictionaries: 'CXStringFlag'
        package: 'Libclang'

except doing so crashes when calling....
getClangVersion
   ^ self ffiCall: #( CXString clang_getClangVersion () ) module: Libclang

cheers -ben

Reply via email to