On 25 November 2012 23:11, Camillo Bruni <[email protected]> wrote: > And don't forget to make the primitive declaration automatic, nobody can > remember that cryptic string :) > once we'll have opal on board.. not before that. i don't want to hack current compiler.
> > On 2012-11-25, at 18:20, Igor Stasenko <[email protected]> wrote: > >> On 25 November 2012 21:59, Stéphane Ducasse <[email protected]> >> wrote: >>> Igor your proposal looks nice. >>> >> it's not a proposal anymore.. >> i already made the changes :) >> >>> Stef >>> >>> On Nov 22, 2012, at 2:47 PM, Igor Stasenko wrote: >>> >>>> Hi, >>>> >>>> i am thinking about redesign of FFI top-level api, because it not very >>>> good. >>>> >>>> First thing is that NBFFICallout referenced in too many places (187 in >>>> my image). >>>> So, from one side, we should encourage using a convenience syntax, using >>>> >>>> self nbCall: .. >>>> instead of >>>> NBFFICallout ... >>>> >>>> but there's one more thing: >>>> - a code generator has many different ways of use, and i actually >>>> going to add another one, >>>> but i see that it will explode the protocol(s) without make it >>>> convenient to use. >>>> >>>> Imagine that you want to generate a callout to function, which address >>>> cannot be obtained directly from external library. >>>> This is actually a real issue, which Esteban met when implementing >>>> bindings to Chipmunk library: >>>> - some functions are not exposed directly by dynamic library, but >>>> indirectly: >>>> the symbol(s) which library exports is not direct pointer(s) to >>>> functions but instead >>>> a pointers to variable, where the function pointer is stored. >>>> So, in order to get function pointer , one needs first to get a >>>> pointer to symbol, and then read the pointer value at that address. >>>> >>>> So, i thought that i would simply add new protocol to NBFFICallout: >>>> >>>> call: anonFunctionSignature convention: callConvention >>>> functionAddress: aFunctionAddressBlock >>>> >>>> Then, one could use it like: >>>> >>>> myMethod >>>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin >>>> error: errorCode > >>>> >>>> ^ NBFFICallout >>>> call: #( int () ) >>>> convention: #cdecl functionAddress: [ self >>>> getPointerTo: 'functionname' ] >>>> >>>> but it is too elaborate.. >>>> you can imagine that if one would like to implement a more convenient >>>> form, he could just do: >>>> >>>> myMethod >>>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin >>>> error: errorCode > >>>> >>>> ^ self indirectCall: #( int () ) name: 'functionname' >>>> >>>> or even: >>>> >>>> myMethod >>>> <primitive: #primitiveNativeCall module: #NativeBoostPlugin >>>> error: errorCode > >>>> >>>> ^ self indirectCall: #( int functionname () ) >>>> >>>> now the problem is that you cannot wrap the NBFFICallout method in >>>> order to implement convenience method, because of use of thisContext. >>>> >>>> I also concerned about exploding NBFFICallout public API.. which imo >>>> doesn't makes much sense, because we should encourage the use of >>>> convenience methods. >>>> >>>> So, i looking for improving public API: >>>> >>>> - First thing is getting rid of direct references to NBFFICallout.. >>>> - second thing is avoid tying public API with thisContext (so you can >>>> create own convenience methods without much hassle). >>>> >>>> So, lets imagine what and how we can do it: >>>> >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ NBFFICallout cdecl: #( int foo() ) module: 'bar' >>>> >>>> 1. getting rid of global: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self nbCallout cdecl: #( int foo() ) module: 'bar' >>>> >>>> 2. separating the call convention from signature: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self nbCallout cdecl call: #( int foo() ) module: 'bar' >>>> >>>> 3. as a bonus, since cdecl is most used, we can assume it is default: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self nbCallout call: #( int foo() ) module: 'bar' >>>> >>>> 4. avoid hardcoding module: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self nbCallout call: #( int foo() ) module: self module >>>> >>>> 5. pass code generation options as a separate message, instead of >>>> additional keyword: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self nbCallout >>>> options: #( +optFoo - optBar); >>>> call: #( int foo() ) module: self module >>>> >>>> 6. finally users would want to do it in most convenient way: >>>> >>>> foo >>>> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> >>>> >>>> ^ self call: #( int foo() ) >>>> >>>> Which means that #call: is convenience method which they implement by >>>> themselves. >>>> Here how i think it should look like: >>>> >>>> call: fnSpec >>>> >>>> ^ (self nbCalloutIn: thisContext sender) >>>> cdecl; >>>> options: #(+optFoo - optBar); >>>> call: fnSpec module: self module. >>>> >>>> If you look at current implementation of Object>>nbCall: >>>> >>>> nbCall: fnSpec >>>> " you can override this method if you need to" >>>> >>>> | sender | >>>> sender := thisContext sender. >>>> >>>> ^ NBFFICallout >>>> handleFailureIn: sender >>>> nativeCode: [ :gen | >>>> gen >>>> sender: sender; >>>> callType: self nbCallingConvention; >>>> generateCall: fnSpec module: self >>>> nbLibraryNameOrHandle] >>>> >>>> it is almost the same, except from cryptic use of blocks, and private >>>> internal NBFFICallout methods which doing the job. >>>> >>>> So, basicly, i want to get rid of NBFFICallout class >> >>>> [cdecl/stdcall]: module: [options:] >>>> [cdecl/stdcall]: emitCall: [options:] >>>> >>>> and replace them with #call:module: and #call: emit: >>>> and also add new one: >>>> #call:address: >>>> >>>> which can be used for passing a function pointer directly. >>>> >>>> And any future extensions to public API will be a single method. Not >>>> 2,3 or more, like today.. >>>> >>>> >>>> -- >>>> Best regards, >>>> Igor Stasenko. >>>> >>> >>> >> >> >> >> -- >> Best regards, >> Igor Stasenko. >> > > -- Best regards, Igor Stasenko.
