[squeak-dev] Re: Advice from Plugin gurus

Andreas Raab andreas.raab at gmx.de
Mon Sep 22 18:19:33 UTC 2008


 > What I'd like to know is what experts think of this... like, will it
 > break anything, like the garbage collector?

Yes, it will. The reason is here:

   anArray at: i put: (interpreterProxy positive32BitIntegerFor: element)

This can cause an allocation and things go downhill from there. You 
can't just store "wild values" in the array - if it gets processed by 
the GC it will crash (GC trying to trace the references). Even if you 
fix that, you'll also have to remap the array to protect from being 
moved by the allocation (pushRemappableOop/popRemappableOop). Finally 
you'll have to mark the array as root if it's old (i.e., using 
storePointer:ofObject:withValue:).

As you can see, doing this kind of munging with existing structures is a 
pain. I would recommend you do what Eliot suggested - alloca() a copy of 
the array and operate on that.

Cheers,
   - Andreas

Gerardo Richarte wrote:
> Hi all, I'm working on a plugin (for SqueakNOS), and I have a primitive
> for which I had coded a first version, and I wanted to hear comments
> from people with deeper Squeak VM and plugin knowledge. I think it's
> ugly, but I'm more worried on whether it's dangerous or not.
> 
> some context:
> 
>     There's a native function I need to call (I called it 'aPrintf' in
> the code below) with a specific calling convention:
> 
>     It takes only one argument: an array
>     the first entry in the array is apointer to a C string
>     the other elements are determined by the first element.
> 
>     What I want is to provide a generic interface to this aPrintf.
> 
>     The code below will walk the array, converting every element in the
> array to either an integer (integerValueOf) or a direct pointer
> (firstIndexableField).
> 
> And I want to be able to read the results left in the array.
> 
> I understand that I won't be able to read non-integer elements from the
> array after coming back from this primitive, but that's fine. I plan to
> keep a copy of all non-integer elements in Smalltalk variables,
> including strings and other buffers.
> 
> What I'd like to know is what experts think of this... like, will it
> break anything, like the garbage collector? is there any other simple
> way of doing this?
>   
> The primitive is:
> primitiveaPrintf: anArray
>     | answer length element |
>     self primitive: 'primitiveOFWCallout' parameters: #(Array).
> 
>     length := interpreterProxy slotSizeOf: anArray cPtrAsOop.
> 
>     answer := 0.
> 
>     "convert everything to native format"
>     0 to: length-1 do: [:i |
>         element := anArray at: i.
>         (interpreterProxy isIntegerObject: element)
>             ifTrue: [anArray at: i put: (interpreterProxy
> integerValueOf: element)]
>             ifFalse: [anArray at: i put: (interpreterProxy
> firstIndexableField: element)]
>     ].
> 
>     self cCode: 'printf(anArray)'.
> 
>     "convert everything to integers. oops will be lost, but that's fine.
> The client should mantain a reference"
>     0 to: length-1 do: [:i |
>         element := anArray at: i.
>         anArray at: i put: (interpreterProxy positive32BitIntegerFor:
> element)
>     ].
> 
>     answer = 0
>         ifTrue: [^ self]
>         ifFalse: [interpreterProxy primitiveFail].
> 
> 
>     thanks a lot!
>     richie
> 
> 




More information about the Squeak-dev mailing list