On Thu, Mar 1, 2012 at 6:45 PM, Schwab,Wilhelm K <[email protected]>wrote:
> Eliot, > > I've unearthed some code from Dolphin, and might want to use something > like this: > > vectorStarVoidStarMatrixStarRetInt: callbackContext sp: spAlien > <signature: 'int (*) (Gsl_vector *, void *, Gsl_matrix *)' abi: > 'IA32'> > ^callbackContext wordResult:( > block > value: (Alien forPointer:( spAlien unsignedLongAt: 1)) > value: (Alien forPointer: (spAlien unsignedLongAt: 5)) > value: (Alien forPointer:( spAlien unsignedLongAt: 9)) > ). > > Am I at all on the right track? The vector and matrix are structs. > Yes, exactly. The next level is to create Alien subclasses for Gsl_vector and Gsl_matrix and use these in place of the simple Aliens. These e.g. GslMatrixIA32Alien and GslVectorIA32Alien classes would define higher-level accessors so that your callback can access their members by name, not by offset. Of course these classes should be auto-generated by parsing e.g. a C header file using the rules of the platform's ABI. You've got it. > Bill > > > > > ------------------------------ > *From:* [email protected] [ > [email protected]] on behalf of Eliot Miranda [ > [email protected]] > *Sent:* Thursday, March 01, 2012 5:38 PM > > *To:* [email protected] > *Subject:* Re: [Pharo-project] Alien signature: first attempt > > > > On Thu, Mar 1, 2012 at 1:52 PM, Schwab,Wilhelm K <[email protected]>wrote: > >> Eliot, >> >> That helps a bit; it's still unfamiliar territory. I am a little >> bothered by #wordResult: and #floatResult. There are times when one is >> expected to return 16 bit values (rare) and either a float or a double >> (common). Does that flexibility exist? >> > > Yes, the flexibility exists. But the mechanism needed to provide the > flexibility is less than one might expect. For example, on x86 there are > three fundamental return conventions, one for integral values, one for > floating-point values, and one for structure values. See e.g. chapter 3 of > the Sys V ABI for 386 (in my reply to Nicolas). Read it; it's good for the > soul; makes one value Smalltalk's simplicity. > > Integral values are returned in %eax, %edx. edx is not used if the > value fits in 32-bits. So the same sequence can be used to answer all > integral values from 1 byte to 8 bytes, irrespective of sign. That said, I > use two sequences, one for 32-bits or less and one for 33 to 64 bits. In > your example of answering 16 bits one simply answers either the > sign-extension of 16-bits (if signed) to 32-bits or the zero-extension of > 16-bits to 32-bits (if unsigned). In any case, the result is answered in > %eax, and it is up to the caller to access the result correctly. > > Float values are returned on the top of the floating point register > stack (%st(0)). The same machine-code sequence can be used to answer > single, double and extended precision floats, since on the fp stack, they > are all represented in the same extended format. > > So on x86 the callback implementation supports 4 return mechanisms, > retword, retword64, retdouble and retstruct. So far only two of these are > fleshed out in Smalltalk code. But look at > http://www.squeakvm.org/svn/squeak/branches/Cog/src/vm/vmCallback.h & > http://squeakvm.org/svn/squeak/trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.cand > you'll see the other two. > > cheers, > Eliot > > >> >> Bill >> >> >> >> >> ------------------------------ >> *From:* [email protected] [ >> [email protected]] on behalf of Eliot Miranda [ >> [email protected]] >> *Sent:* Thursday, March 01, 2012 3:26 PM >> *To:* [email protected] >> *Subject:* Re: [Pharo-project] Alien signature: first attempt >> >> >> >> On Thu, Mar 1, 2012 at 10:57 AM, Schwab,Wilhelm K >> <[email protected]>wrote: >> >>> Esteban, >>> >>> Will this work? Even if so, is there a better way to define it? >>> >> >> No it won't work, because you don't understand what it does. >> >> >>> >>> longVoidStarLongRetInt: callbackContext sp: spAlien >>> <signature: 'int (*) (long, void *, long)' abi: 'IA32'> >>> ^callbackContext wordResult: >>> (block >>> value: (Alien newC:4) >>> value: (Alien forPointer: (spAlien >>> unsignedLongAt: 5)) >>> value: (Alien newC:4) >>> ) >>> >> >> The above takes only one parameter's value from the spAlien (the void * >> value) and passes garbage for the other parameters. The spAlien is a >> pointer to the incoming C callback stack frame, i.e. a pointer to the >> callback's parameters. So spAlien unsignedLongAt: 5 gets the four-byte >> pointer for the void * parameter, wraps it up in a convenient pointer Alien >> (so the callback block can e.g. indirect through it to get at the data the >> pointer is pointing to), and passes it as the second argument of the >> callback block. But the two Alien newC: 4's are entirely bogus, passing >> effectively uninitialized data for the first and third parameters of the >> callback block. They're just empty Aliens, when in fact you want to pass >> two longs to the block for the first and third parameters. >> >> So to pass values in you need something like: >> >> longVoidStarLongRetInt: callbackContext sp: spAlien >> <signature: 'int (*) (long, void *, long)' abi: 'IA32'> >> ^callbackContext wordResult: >> (block >> value: (spAlien signedLongAt: 1) >> value: (Alien forPointer: (spAlien unsignedLongAt: >> 5)) >> value: (spAlien signedLongAt: 9) >> ) >> >> You might also need to consider passing the result of the block back >> out. If you only want to use it to answer integers then the above is fine. >> But take a look at the intcharstarRetint:sp: signature: >> >> intcharstarRetint: callbackContext sp: spAlien >> <signature: 'int (*)(int, char *)' abi: 'IA32'> >> ^callbackContext wordResult: >> ((block >> value: (spAlien signedLongAt: 1) ~= 0 >> value: (Alien forPointer: (spAlien unsignedLongAt: 5)) strcpyUTF8) >> ifNil: [0] >> ifNotNil: >> [:result| >> result isInteger >> ifTrue: [result] >> ifFalse: [result == true ifTrue: [1] ifFalse: [0]]]) >> >> Analogously it passes a signed integer as the first argument and a UTF8 >> string derived from the second char * parameter. (The method should >> probably be called intcharstarasUTF8Retint:sp: or some such; forgive me, >> we're getting there). >> >> But on return it takes the result of the callback block and passes it >> to the ifNil:ifNotNil: which >> - maps a nil result form the block to 0 (ifNil: [0]) >> - maps integers to integers (which will only deal correctly with integers >> in the 32-bit range), and >> - maps true to 1, mapping all other results to 0. >> >> Does what's going on now make more sense? >> >> HTH, >> Eliot >> >> >>> Bill >>> >>> ________________________________________ >>> From: [email protected] [ >>> [email protected]] on behalf of >>> Schwab,Wilhelm K [[email protected]] >>> Sent: Thursday, March 01, 2012 12:15 AM >>> To: [email protected] >>> Subject: Re: [Pharo-project] FFI on 1.3: compile fields >>> >>> thanks!!!!! >>> >>> >>> >>> >>> ________________________________________ >>> From: [email protected] [ >>> [email protected]] on behalf of Esteban >>> Lorenzano [[email protected]] >>> Sent: Wednesday, February 29, 2012 10:18 PM >>> To: [email protected] >>> Subject: Re: [Pharo-project] FFI on 1.3: compile fields >>> >>> you need to define a signature... not at home now, but wait 'til >>> tomorrow and I'll send an example >>> >>> best, >>> Esteban >>> >>> El 29/02/2012, a las 11:21p.m., Schwab,Wilhelm K escribió: >>> >>> > What does "cannot find callback signature" mean from >>> #signature:block:? I'm stuck. >>> > >>> > >>> > >>> > >>> > ________________________________________ >>> > From: [email protected] [ >>> [email protected]] on behalf of Esteban >>> Lorenzano [[email protected]] >>> > Sent: Wednesday, February 29, 2012 6:54 PM >>> > To: [email protected] >>> > Subject: Re: [Pharo-project] FFI on 1.3: compile fields >>> > >>> > yeah... sorry about that >>> > is a bug on FFI... I managed to worked around it for HPDF, for a >>> customer's project... but of course is not a good and definitive solution. >>> > >>> > best, >>> > Esteban >>> > >>> > El 29/02/2012, a las 8:37p.m., Schwab,Wilhelm K escribió: >>> > >>> >> This is gonna take a while... I had structs flying around as void* >>> and was moderately happy. Nonetheless, your suggestion worked, provided I >>> add a lot getHandle asInteger and change the void* to long :( >>> >> >>> >> >>> >> >>> >> >>> >> ________________________________________ >>> >> From: [email protected] [ >>> [email protected]] on behalf of Esteban >>> Lorenzano [[email protected]] >>> >> Sent: Wednesday, February 29, 2012 6:23 PM >>> >> To: [email protected] >>> >> Subject: Re: [Pharo-project] FFI on 1.3: compile fields >>> >> >>> >> I also found some problems using void* in linux... maybe you want to >>> use long (which has same size)... I "fixed" my problems that way. >>> >> >>> >> yes... maybe we need to look at FFI to see why void* has problems >>> some times, but well, that can help you atm (sorry for not having a better >>> answer) >>> >> >>> >> Esteban >>> >> >>> >> El 29/02/2012, a las 8:11p.m., Igor Stasenko escribió: >>> >> >>> >>> On 1 March 2012 00:58, Schwab,Wilhelm K <[email protected]> >>> wrote: >>> >>>> Another glitch: is there any problem passing things as void*? I'm >>> getting failure to coerce errors that did not arise before. >>> >>>> >>> >>> No idea. As you may suspect, i stopped using FFI/Alien once i got >>> >>> NativeBoost toy to play with. >>> >>> >>> >>> Please file the issue, describing the problem. so we can look over it >>> >>> and fix it. >>> >>> >>> >>>> >>> >>>> >>> >>>> ________________________________________ >>> >>>> From: [email protected] [ >>> [email protected]] on behalf of Igor Stasenko >>> [[email protected]] >>> >>>> Sent: Wednesday, February 29, 2012 5:51 PM >>> >>>> To: [email protected] >>> >>>> Subject: Re: [Pharo-project] FFI on 1.3: compile fields >>> >>>> >>> >>>> On 1 March 2012 00:37, Schwab,Wilhelm K <[email protected]> >>> wrote: >>> >>>>> Does 1.3 by default not create field accessors? Why is that? I >>> thought >>> >>>>> nothing was happening. >>> >>>>> >>> >>>> >>> >>>> Good question, i'd like to know the answer too. >>> >>>> It is related to MC final 'installation' phase, >>> >>>> where it initializing all classes. >>> >>>> >>> >>>> In NativeBoost i was also using >>> >>>> >>> >>>> noteCompilationOf: aSelector meta: isMeta >>> >>>> "A hook allowing some classes to react to recompilation of >>> certain selectors" >>> >>>> >>> >>>> but there was a big question, at which point this hook is triggered, >>> >>>> and looks like some changes in MC stop triggering it/triggering at >>> >>>> wrong time (not all methods get into a class/ class not initialized >>> >>>> etc), >>> >>>> which makes it not very useful. >>> >>>> >>> >>>> So i ended up creating a DNU handler on instance side, then on DNU i >>> >>>> check if i have field accessors and if not, >>> >>>> compile them on the fly. >>> >>>> >>> >>>> >>> >>>>> Bill >>> >>>>> >>> >>>> >>> >>>> >>> >>>> -- >>> >>>> Best regards, >>> >>>> Igor Stasenko. >>> >>>> >>> >>>> >>> >>> >>> >>> >>> >>> >>> >>> -- >>> >>> Best regards, >>> >>> Igor Stasenko. >>> >>> >>> >> >>> >> >>> >> >>> > >>> > >>> > >>> >>> >>> >>> >>> >> >> >> -- >> best, >> Eliot >> >> > > > -- > best, > Eliot > > -- best, Eliot
