[Pharo-project] [NativeBoost] not happy with too many references to NBFFICallout & its public API
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.
Igor your proposal looks nice. 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.
On 25 November 2012 21:59, Stéphane Ducasse <stephane.ducasse@inria.fr> 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.
And don't forget to make the primitive declaration automatic, nobody can remember that cryptic string :) On 2012-11-25, at 18:20, Igor Stasenko <siguctua@gmail.com> wrote:
On 25 November 2012 21:59, Stéphane Ducasse <stephane.ducasse@inria.fr> 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.
On 25 November 2012 23:11, Camillo Bruni <camillobruni@gmail.com> 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 <siguctua@gmail.com> wrote:
On 25 November 2012 21:59, Stéphane Ducasse <stephane.ducasse@inria.fr> 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.
On 2012-11-25, at 21:28, Igor Stasenko <siguctua@gmail.com> wrote:
On 25 November 2012 23:11, Camillo Bruni <camillobruni@gmail.com> 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.
no need to hack the compiler - on the first call check if there is the primitive - if there is none, check if the method contains any other primitive - if not, add the primitive to the second line of the method sources - recompile the method with the same primitive - call that method again so you got a solution that works already now, I don't see what opal will add you here?
On 26 November 2012 01:35, Camillo Bruni <camillobruni@gmail.com> wrote:
On 2012-11-25, at 21:28, Igor Stasenko <siguctua@gmail.com> wrote:
On 25 November 2012 23:11, Camillo Bruni <camillobruni@gmail.com> 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.
no need to hack the compiler - on the first call check if there is the primitive - if there is none, check if the method contains any other primitive - if not, add the primitive to the second line of the method sources - recompile the method with the same primitive - call that method again
so you got a solution that works already now, I don't see what opal will add you here?
what i was wanted to say that instead of using long cryptic string, with opal i could use a very simple pragma , like <native>. modifying source code is a slippery road, with a lot of pitfalls down the sides.... i am one, who thinks that automatic tools should not interfere with what author(s) wanted to say. i prefer to leave source as it was written, but we can instruct the compiler to insert primitive once we discover that it is not there but without modifying source code. -- Best regards, Igor Stasenko.
no need to hack the compiler - on the first call check if there is the primitive - if there is none, check if the method contains any other primitive - if not, add the primitive to the second line of the method sources - recompile the method with the same primitive - call that method again
so you got a solution that works already now, I don't see what opal will add you here?
what i was wanted to say that instead of using long cryptic string, with opal i could use a very simple pragma , like <native>.
modifying source code is a slippery road, with a lot of pitfalls down the sides.... i am one, who thinks that automatic tools should not interfere with what author(s) wanted to say.
sure, but it's a solution that works for now and that can and should be changed once our infrastructure is ready. waiting for perfect solution is silly when you have something around the corner that will work....
i prefer to leave source as it was written, but we can instruct the compiler to insert primitive once we discover that it is not there but without modifying source code.
it's funny to see, but even when you gave your demo even you couldn't type the pragma definition yourself, so how do you except this to affect newcomers?
On 26 November 2012 04:20, Camillo Bruni <camillobruni@gmail.com> wrote:
no need to hack the compiler - on the first call check if there is the primitive - if there is none, check if the method contains any other primitive - if not, add the primitive to the second line of the method sources - recompile the method with the same primitive - call that method again
so you got a solution that works already now, I don't see what opal will add you here?
what i was wanted to say that instead of using long cryptic string, with opal i could use a very simple pragma , like <native>.
modifying source code is a slippery road, with a lot of pitfalls down the sides.... i am one, who thinks that automatic tools should not interfere with what author(s) wanted to say.
sure, but it's a solution that works for now and that can and should be changed once our infrastructure is ready.
waiting for perfect solution is silly when you have something around the corner that will work....
i prefer to leave source as it was written, but we can instruct the compiler to insert primitive once we discover that it is not there but without modifying source code.
it's funny to see, but even when you gave your demo even you couldn't type the pragma definition yourself, so how do you except this to affect newcomers?
no need to convince me. of course i can type it.. but most of the time you copy/paster it from method to method. -- Best regards, Igor Stasenko.
it's funny to see, but even when you gave your demo even you couldn't type the pragma definition yourself, so how do you except this to affect newcomers?
no need to convince me. of course i can type it.. but most of the time you copy/paster it from method to method.
of course you can copy paste it, but if you can avoid it at all, why would you even bother copy pasting? besides your opal solution will be ready in > 2 months. Actually we simply have to add a proper UI handler for the exception you throw when there is no primitive installed. You let the programmer decide what to do => 100% safe
On 26 November 2012 16:27, Camillo Bruni <camillobruni@gmail.com> wrote:
it's funny to see, but even when you gave your demo even you couldn't type the pragma definition yourself, so how do you except this to affect newcomers?
no need to convince me. of course i can type it.. but most of the time you copy/paster it from method to method.
of course you can copy paste it, but if you can avoid it at all, why would you even bother copy pasting?
besides your opal solution will be ready in > 2 months. Actually we simply have to add a proper UI handler for the exception you throw when there is no primitive installed. You let the programmer decide what to do => 100% safe
it is your call. do it if you want it so badly :) -- Best regards, Igor Stasenko.
On 2012-11-26, at 12:45, Igor Stasenko <siguctua@gmail.com> wrote:
On 26 November 2012 16:27, Camillo Bruni <camillobruni@gmail.com> wrote:
it's funny to see, but even when you gave your demo even you couldn't type the pragma definition yourself, so how do you except this to affect newcomers?
no need to convince me. of course i can type it.. but most of the time you copy/paster it from method to method.
of course you can copy paste it, but if you can avoid it at all, why would you even bother copy pasting?
besides your opal solution will be ready in > 2 months. Actually we simply have to add a proper UI handler for the exception you throw when there is no primitive installed. You let the programmer decide what to do => 100% safe
it is your call. do it if you want it so badly :)
yup I put it on ym todo
I don't know exactly why... but I tend to agree with Igor with this one... It's not that I like copy/paste, or that the <..> pragma is sexy but it seems to me that there will be too much going on under the hood but ... well I hope at least that the user will see the pragma to understand that something funky is going on -- Ciprian On Mon, Nov 26, 2012 at 5:57 PM, Camillo Bruni <camillobruni@gmail.com>wrote:
On 2012-11-26, at 12:45, Igor Stasenko <siguctua@gmail.com> wrote:
On 26 November 2012 16:27, Camillo Bruni <camillobruni@gmail.com> wrote:
it's funny to see, but even when you gave your demo even you couldn't
type
the pragma definition yourself, so how do you except this to affect newcomers?
no need to convince me. of course i can type it.. but most of the time you copy/paster it from method to method.
of course you can copy paste it, but if you can avoid it at all, why would you even bother copy pasting?
besides your opal solution will be ready in > 2 months. Actually we simply have to add a proper UI handler for the exception you throw when there is no primitive installed. You let the programmer decide what to do => 100% safe
it is your call. do it if you want it so badly :)
yup I put it on ym todo
-- Dr. Ciprian TEODOROV Ingénieur Développement CAO tél : 06 08 54 73 48 mail : ciprian.teodorov@gmail.com www.teodorov.ro
Apart from this, there is new primitive: 220. If Camillo will make changes, then it will be either plugin primitive or 220. I am in favor of migrating stuff to 220 (because it is much faster) but before we will have fully functional prim220 code generator support, i think we should keep both. because then i can tell which prim i wanna use by putting either: <primitive:220 error: errorCode> or <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode> and code may vary because convention is different. So, i do not see how you can safely assume that "everything which does not have primitive pragma, should use one of these" On 26 November 2012 21:42, Ciprian Teodorov <ciprian.teodorov@gmail.com> wrote:
I don't know exactly why... but I tend to agree with Igor with this one... It's not that I like copy/paste, or that the <..> pragma is sexy but it seems to me that there will be too much going on under the hood
:) yeah.. what can i say.. jumping from high level to very low level penetrating multiple layers of abstraction.. what you expected? :) But the fun part is that it demonstrates quite clearly: you can use high-level language for low-level stuff quite easy and efficient.
but ... well I hope at least that the user will see the pragma to understand that something funky is going on
-- Ciprian
On Mon, Nov 26, 2012 at 5:57 PM, Camillo Bruni <camillobruni@gmail.com> wrote:
-- Best regards, Igor Stasenko.
participants (4)
-
Camillo Bruni -
Ciprian Teodorov -
Igor Stasenko -
Stéphane Ducasse