Is there something against that ? It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect. Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 3 July 2013 11:48, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Is there something against that ?
It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect.
NB callout needs argument names (which it can only get right now by accessing method's source). We plan to change that after introducing pluggable mechanism in opal to use it to run additional code on certain pragma to handle it in custom way (like remembering argument names in method's properties).
Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
-- Best regards, Igor Stasenko.
On Jul 3, 2013, at 12:20 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 3 July 2013 11:48, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Is there something against that ?
It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect.
NB callout needs argument names (which it can only get right now by accessing method's source). We plan to change that after introducing pluggable mechanism in opal to use it to run additional code on certain pragma to handle it in custom way (like remembering argument names in method's properties).
We need a high level code model. The design we have right now is from 1978. But now it is 2013. There is no need to have a code model that does not store the names of temps. Marcus
Le 03/07/2013 11:59, Igor Stasenko a écrit :
On 3 July 2013 11:48, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Is there something against that ?
It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect.
NB callout needs argument names (which it can only get right now by accessing method's source). We plan to change that after introducing pluggable mechanism in opal to use it to run additional code on certain pragma to handle it in custom way (like remembering argument names in method's properties).
If it is like that, I have to give up any chance of correcting the file permissions problem on Pharo 2.0. Any chance that we could use arguments positions instead ? Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 3 July 2013 14:19, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 03/07/2013 11:59, Igor Stasenko a écrit :
On 3 July 2013 11:48, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Is there something against that ?
It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect.
NB callout needs argument names (which it can only get right now by accessing method's source). We plan to change that after introducing pluggable mechanism in opal to use it to run additional code on certain pragma to handle it in custom way (like remembering argument names in method's properties).
If it is like that, I have to give up any chance of correcting the file permissions problem on Pharo 2.0.
Any chance that we could use arguments positions instead ?
I don't know.. look: realloc: flags mem: lpMem size: dwBytes <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode> ^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) ) here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function. now if you don't use argument names , how the above should look like? realloc: flags mem: lpMem size: dwBytes <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode> ^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ? potentially , you can change the signature parser to accept such syntax.. but as to me, that's really ugly, counter intuitive and error prone. -- Best regards, Igor Stasenko.
Le 03/07/2013 14:25, Igor Stasenko a écrit :
On 3 July 2013 14:19, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 03/07/2013 11:59, Igor Stasenko a écrit :
On 3 July 2013 11:48, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Is there something against that ?
It seems as if NB is used to check file existence / isReadable, then, upon startup, the vm is unable to open the changes file and all NB calls becomes incorrect.
NB callout needs argument names (which it can only get right now by accessing method's source). We plan to change that after introducing pluggable mechanism in opal to use it to run additional code on certain pragma to handle it in custom way (like remembering argument names in method's properties).
If it is like that, I have to give up any chance of correcting the file permissions problem on Pharo 2.0.
Any chance that we could use arguments positions instead ?
I don't know.. look:
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) )
here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function.
now if you don't use argument names , how the above should look like?
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ?
potentially , you can change the signature parser to accept such syntax.. but as to me, that's really ugly, counter intuitive and error prone.
I'm doing that at the moment because it sounds inacceptable in 2.0 to have the following true: No use of NativeBoost if you start the VM without sources and changes. Just wait until someone deploys 2.0 in production without the sources and is unable to load environment variables... (for my own use, I'll hack either OSProcess to extend FileSystem and get correct file permissions, the ChangeFile opening to force it even if NB isn't working, or NB itself. But I don't have yet a need to deploy without the sources). Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
I don't know.. look:
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) )
here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function.
now if you don't use argument names , how the above should look like?
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ?
Igor I understand your concerns but also the problem thierry is facing and it looks to me like a valid scenario. Stef
Hi Stephane, I worked around it... as long as I don't make FileReference>>exists as a NB call, then the Changes file will open correctly and NB calls will work after that (Changes opening doesn't use isReadable or isWriteable, which is interesting in itself ;))... But it makes my solution fragile. However, if you make the Changes file not readable (still owned by you, still writeable), many interesting things happen, starting with a nbGetEnv failure and a total unability to quit Pharo apart from a killall pharo. I tried to: - Get NB to accept positional arguments instead of named ones (by catching names like _1, _2). Easy, since apparently the NB generated code just takes an offset on the pointer stack finally (i.e. names are only used to get the index in the arguments array). Seemed to work. - Change all NB calls with numbers above to be able to have NB working before / without the Changes file. Ended with a segfault on startup (globalSymbolLoading for GetEnv again), and I gave up. Igor, would there be a way to write the call with the effective arguments instead of #symbols, so that by looking at the bytecode you would get the position in the arguments stack? Or would it be possible to store by hand the source of the methods (triggered by the <pragma>) inside a source cache inside NB for the time being? Or is there an event for NB correct start (with Changes and all ready) so that we can write NB code with a fallback if NB isn't able to work? NB made it so easy to do simple and usefull calls to external libs that I really want it to work! Thierry ________________________________________ De : Pharo-dev [pharo-dev-bounces@lists.pharo.org] de la part de Stéphane Ducasse [stephane.ducasse@inria.fr] Date d'envoi : mercredi 3 juillet 2013 21:51 à : Pharo Development List Objet : Re: [Pharo-dev] NativeBoost with no access to sources
I don't know.. look:
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) )
here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function.
now if you don't use argument names , how the above should look like?
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ?
Igor I understand your concerns but also the problem thierry is facing and it looks to me like a valid scenario. Stef
On 3 July 2013 23:04, GOUBIER Thierry <thierry.goubier@cea.fr> wrote:
Hi Stephane,
I worked around it... as long as I don't make FileReference>>exists as a NB call, then the Changes file will open correctly and NB calls will work after that (Changes opening doesn't use isReadable or isWriteable, which is interesting in itself ;))... But it makes my solution fragile.
However, if you make the Changes file not readable (still owned by you, still writeable), many interesting things happen, starting with a nbGetEnv failure and a total unability to quit Pharo apart from a killall pharo.
I tried to: - Get NB to accept positional arguments instead of named ones (by catching names like _1, _2). Easy, since apparently the NB generated code just takes an offset on the pointer stack finally (i.e. names are only used to get the index in the arguments array). Seemed to work.
can you share this code? i think it doesn't hurts being able to refer to method argument by number , not by name, if author wants to.
- Change all NB calls with numbers above to be able to have NB working before / without the Changes file. Ended with a segfault on startup (globalSymbolLoading for GetEnv again), and I gave up.
Igor, would there be a way to write the call with the effective arguments instead of #symbols, so that by looking at the bytecode you would get the position in the arguments stack? Or would it be possible to store by hand the source of the methods (triggered by the <pragma>) inside a source cache inside NB for the time being? Or is there an event for NB correct start (with Changes and all ready) so that we can write NB code with a fallback if NB isn't able to work?
i wanna change it, so that when you compile method with NB primitive, it remembers the arg names.
NB made it so easy to do simple and usefull calls to external libs that I really want it to work!
Thierry
________________________________________ De : Pharo-dev [pharo-dev-bounces@lists.pharo.org] de la part de Stéphane Ducasse [stephane.ducasse@inria.fr] Date d'envoi : mercredi 3 juillet 2013 21:51 à : Pharo Development List Objet : Re: [Pharo-dev] NativeBoost with no access to sources
I don't know.. look:
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) )
here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function.
now if you don't use argument names , how the above should look like?
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ?
Igor I understand your concerns but also the problem thierry is facing and it looks to me like a valid scenario.
Stef
-- Best regards, Igor Stasenko.
Le 04/07/2013 11:58, Igor Stasenko a écrit :
On 3 July 2013 23:04, GOUBIER Thierry <thierry.goubier@cea.fr> wrote:
Hi Stephane,
I worked around it... as long as I don't make FileReference>>exists as a NB call, then the Changes file will open correctly and NB calls will work after that (Changes opening doesn't use isReadable or isWriteable, which is interesting in itself ;))... But it makes my solution fragile.
However, if you make the Changes file not readable (still owned by you, still writeable), many interesting things happen, starting with a nbGetEnv failure and a total unability to quit Pharo apart from a killall pharo.
I tried to: - Get NB to accept positional arguments instead of named ones (by catching names like _1, _2). Easy, since apparently the NB generated code just takes an offset on the pointer stack finally (i.e. names are only used to get the index in the arguments array). Seemed to work.
can you share this code? i think it doesn't hurts being able to refer to method argument by number , not by name, if author wants to.
I wondered if it could be both (name and number), but went for the shortest path, that is the simplest solution: NBFFICallout>>loaderFromMethodArgsNamed: argName methodArgs ifNotNil: [ | index | (argName first = $_ and: [ argName allButFirst isAllDigits ]) ifTrue: [ ^ NBSTMethodArgument new stackIndex: methodArgs size - argName asUnsignedInteger ]. index := methodArgs indexOf: argName ifAbsent: [ nil ]. index ifNotNil: [ "ok, this is a method argument" ^ NBSTMethodArgument new stackIndex: methodArgs size - index ] ]. ^ nil Then I tried to change all calls to use numbers, but it ended in a Segfault (not in NB itself, but somewhere else as if I had a corrupted heap). The end result with all changes is there: http://ss3.gemstone.com/ss/PharoInbox/SLICE-Issue-11102-FileSystemError-Path... If you see where I missed something, I'd be happy to know.
- Change all NB calls with numbers above to be able to have NB working before / without the Changes file. Ended with a segfault on startup (globalSymbolLoading for GetEnv again), and I gave up.
Igor, would there be a way to write the call with the effective arguments instead of #symbols, so that by looking at the bytecode you would get the position in the arguments stack? Or would it be possible to store by hand the source of the methods (triggered by the <pragma>) inside a source cache inside NB for the time being? Or is there an event for NB correct start (with Changes and all ready) so that we can write NB code with a fallback if NB isn't able to work?
i wanna change it, so that when you compile method with NB primitive, it remembers the arg names.
Yes, I suspect it would be the best solution. Trap on <primitive: ? If you track the MethodAdded / MethodRemoved events, you can note all uses of <primitive:> and cache the info there ?
NB made it so easy to do simple and usefull calls to external libs that I really want it to work!
Thierry
________________________________________ De : Pharo-dev [pharo-dev-bounces@lists.pharo.org] de la part de Stéphane Ducasse [stephane.ducasse@inria.fr] Date d'envoi : mercredi 3 juillet 2013 21:51 à : Pharo Development List Objet : Re: [Pharo-dev] NativeBoost with no access to sources
I don't know.. look:
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD flags, LPVOID lpMem, SIZE_T dwBytes) )
here, see: flags, lpMem, dwBytes names is in function signature same as in your method. That's how NB knows which argument from method corresponds to argument passed to function.
now if you don't use argument names , how the above should look like?
realloc: flags mem: lpMem size: dwBytes
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode>
^ self nbCall: #( LPVOID HeapReAlloc (self, DWORD @1, LPVOID @2, SIZE_T @3) ) ?
Igor I understand your concerns but also the problem thierry is facing and it looks to me like a valid scenario.
Stef
-- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 4 July 2013 13:07, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 04/07/2013 11:58, Igor Stasenko a écrit :
On 3 July 2013 23:04, GOUBIER Thierry <thierry.goubier@cea.fr> wrote:
Hi Stephane,
I worked around it... as long as I don't make FileReference>>exists as a NB call, then the Changes file will open correctly and NB calls will work after that (Changes opening doesn't use isReadable or isWriteable, which is interesting in itself ;))... But it makes my solution fragile.
However, if you make the Changes file not readable (still owned by you, still writeable), many interesting things happen, starting with a nbGetEnv failure and a total unability to quit Pharo apart from a killall pharo.
I tried to: - Get NB to accept positional arguments instead of named ones (by catching names like _1, _2). Easy, since apparently the NB generated code just takes an offset on the pointer stack finally (i.e. names are only used to get the index in the arguments array). Seemed to work.
can you share this code? i think it doesn't hurts being able to refer to method argument by number , not by name, if author wants to.
I wondered if it could be both (name and number), but went for the shortest path, that is the simplest solution:
NBFFICallout>>loaderFromMethodArgsNamed: argName
methodArgs ifNotNil: [ | index | (argName first = $_ and: [ argName allButFirst isAllDigits ]) ifTrue: [ ^ NBSTMethodArgument new stackIndex: methodArgs size - argName asUnsignedInteger ]. index := methodArgs indexOf: argName ifAbsent: [ nil ]. index ifNotNil: [ "ok, this is a method argument" ^ NBSTMethodArgument new stackIndex: methodArgs size - index ] ]. ^ nil
This looks fine , and i will add it into NB.
Then I tried to change all calls to use numbers, but it ended in a Segfault (not in NB itself, but somewhere else as if I had a corrupted heap). The end result with all changes is there:
http://ss3.gemstone.com/ss/PharoInbox/SLICE-Issue-11102-FileSystemError-Path...
If you see where I missed something, I'd be happy to know.
you probably made a mistake somewhere. ;) because counting the argument index, instead of putting its name is error prone.
- Change all NB calls with numbers above to be able to have NB working before / without the Changes file. Ended with a segfault on startup (globalSymbolLoading for GetEnv again), and I gave up.
Igor, would there be a way to write the call with the effective arguments instead of #symbols, so that by looking at the bytecode you would get the position in the arguments stack? Or would it be possible to store by hand the source of the methods (triggered by the <pragma>) inside a source cache inside NB for the time being? Or is there an event for NB correct start (with Changes and all ready) so that we can write NB code with a fallback if NB isn't able to work?
i wanna change it, so that when you compile method with NB primitive, it remembers the arg names.
Yes, I suspect it would be the best solution. Trap on <primitive: ? If you track the MethodAdded / MethodRemoved events, you can note all uses of <primitive:> and cache the info there ?
not cache, just put it into method's attributes, so i can access them later. And not when method added/removed, but at compilation time.
-- Best regards, Igor Stasenko.
Le 04/07/2013 19:11, Igor Stasenko a écrit :
On 4 July 2013 13:07, Goubier Thierry <thierry.goubier@cea.fr> wrote:
I wondered if it could be both (name and number), but went for the shortest path, that is the simplest solution:
NBFFICallout>>loaderFromMethodArgsNamed: argName
methodArgs ifNotNil: [ | index | (argName first = $_ and: [ argName allButFirst isAllDigits ]) ifTrue: [ ^ NBSTMethodArgument new stackIndex: methodArgs size - argName asUnsignedInteger ]. index := methodArgs indexOf: argName ifAbsent: [ nil ]. index ifNotNil: [ "ok, this is a method argument" ^ NBSTMethodArgument new stackIndex: methodArgs size - index ] ]. ^ nil
This looks fine , and i will add it into NB.
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :) (it would then both handle startup related errors and unreadable sources as well). And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
Then I tried to change all calls to use numbers, but it ended in a Segfault (not in NB itself, but somewhere else as if I had a corrupted heap). The end result with all changes is there:
http://ss3.gemstone.com/ss/PharoInbox/SLICE-Issue-11102-FileSystemError-Path...
If you see where I missed something, I'd be happy to know.
you probably made a mistake somewhere. ;) because counting the argument index, instead of putting its name is error prone.
Well, in almost all cases, arguments were used in the order they were given, which should have been almost foolproof ;)
not cache, just put it into method's attributes, so i can access them later. And not when method added/removed, but at compilation time.
Is there a real, practical difference between "at compilation time" and "when receiving MethodAdded event"? i.e. is the complexity added in the compilation process worthwhile? Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 04/07/2013 19:11, Igor Stasenko a écrit :
On 4 July 2013 13:07, Goubier Thierry <thierry.goubier@cea.fr> wrote:
I wondered if it could be both (name and number), but went for the shortest path, that is the simplest solution:
NBFFICallout>>loaderFromMethodArgsNamed: argName
methodArgs ifNotNil: [ | index | (argName first = $_ and: [ argName allButFirst isAllDigits ]) ifTrue: [ ^ NBSTMethodArgument new stackIndex: methodArgs size - argName asUnsignedInteger ]. index := methodArgs indexOf: argName ifAbsent: [ nil ]. index ifNotNil: [ "ok, this is a method argument" ^ NBSTMethodArgument new stackIndex: methodArgs size - index ] ]. ^ nil
This looks fine , and i will add it into NB.
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.: foo: bar ^ self nbCall: #( void foo (int baz) ) will give same error (unable to find binding for name 'baz' in given context). If its fine to you, i can do it.
Then I tried to change all calls to use numbers, but it ended in a Segfault (not in NB itself, but somewhere else as if I had a corrupted heap). The end result with all changes is there:
http://ss3.gemstone.com/ss/PharoInbox/SLICE-Issue-11102-FileSystemError-Path...
If you see where I missed something, I'd be happy to know.
you probably made a mistake somewhere. ;) because counting the argument index, instead of putting its name is error prone.
Well, in almost all cases, arguments were used in the order they were given, which should have been almost foolproof ;)
that's why there is separate words in english for 'all' and 'almost' :)
not cache, just put it into method's attributes, so i can access them later. And not when method added/removed, but at compilation time.
Is there a real, practical difference between "at compilation time" and "when receiving MethodAdded event"? i.e. is the complexity added in the compilation process worthwhile?
the problem is that you may not always receive MethodAdded event, because different tools putting different meaning into "this should be compiled silently". This is outstanding issue in Pharo.. and that's the main reason why i would go with compiler (like that i have guarantee that instance of CompiledMethod is well-formed, and don't need to rely on 3-rd party toolchain to deliver notification to me. and besides, we need such hook mechanism in Compiler anyways (for many other use cases) and so, it will be not "renting a Boeing for single passenger"
Thierry
-- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
-- Best regards, Igor Stasenko.
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 04/07/2013 19:11, Igor Stasenko a écrit :
On 4 July 2013 13:07, Goubier Thierry <thierry.goubier@cea.fr> wrote:
I wondered if it could be both (name and number), but went for the shortest path, that is the simplest solution:
NBFFICallout>>loaderFromMethodArgsNamed: argName
methodArgs ifNotNil: [ | index | (argName first = $_ and: [ argName allButFirst isAllDigits ]) ifTrue: [ ^ NBSTMethodArgument new stackIndex: methodArgs size - argName asUnsignedInteger ]. index := methodArgs indexOf: argName ifAbsent: [ nil ]. index ifNotNil: [ "ok, this is a method argument" ^ NBSTMethodArgument new stackIndex: methodArgs size - index ] ]. ^ nil
This looks fine , and i will add it into NB.
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
If its fine to you, i can do it.
Then I tried to change all calls to use numbers, but it ended in a Segfault (not in NB itself, but somewhere else as if I had a corrupted heap). The end result with all changes is there:
http://ss3.gemstone.com/ss/PharoInbox/SLICE-Issue-11102-FileSystemError-Path...
If you see where I missed something, I'd be happy to know.
you probably made a mistake somewhere. ;) because counting the argument index, instead of putting its name is error prone.
Well, in almost all cases, arguments were used in the order they were given, which should have been almost foolproof ;)
that's why there is separate words in english for 'all' and 'almost' :)
not cache, just put it into method's attributes, so i can access them later. And not when method added/removed, but at compilation time.
Is there a real, practical difference between "at compilation time" and "when receiving MethodAdded event"? i.e. is the complexity added in the compilation process worthwhile?
the problem is that you may not always receive MethodAdded event, because different tools putting different meaning into "this should be compiled silently". This is outstanding issue in Pharo.. and that's the main reason why i would go with compiler (like that i have guarantee that instance of CompiledMethod is well-formed, and don't need to rely on 3-rd party toolchain to deliver notification to me.
and besides, we need such hook mechanism in Compiler anyways (for many other use cases) and so, it will be not "renting a Boeing for single passenger"
oh.. and i forgot about most important aspect of it: i don't wanna see <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode > in code, instead if wanna use <native> (or similar), which admit, much more concise, elegant and user-friendly, and hides unnecessary implementation detail.
Thierry
-- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
Le 05/07/2013 15:31, Igor Stasenko a écrit :
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
Of course. I could do with having the same error for both and knowing that when developping and testing I would get it for stupid syntax errors and in production to handle a real situation.
If its fine to you, i can do it.
Maybe I can try myself to see if I can write, before entering that loader stuff, a correct test which raises an error if the method source isn't available.
Is there a real, practical difference between "at compilation time" and "when receiving MethodAdded event"? i.e. is the complexity added in the compilation process worthwhile?
the problem is that you may not always receive MethodAdded event, because different tools putting different meaning into "this should be compiled silently". This is outstanding issue in Pharo.. and that's the main reason why i would go with compiler (like that i have guarantee that instance of CompiledMethod is well-formed, and don't need to rely on 3-rd party toolchain to deliver notification to me.
You mean that hacking support into the third party compiler isn't 3rd party toolchain :)
and besides, we need such hook mechanism in Compiler anyways (for many other use cases) and so, it will be not "renting a Boeing for single passenger"
oh.. and i forgot about most important aspect of it: i don't wanna see <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode > in code, instead if wanna use
<native> (or similar), which admit, much more concise, elegant and user-friendly, and hides unnecessary implementation detail.
I remember seeing people introducing syntax extensions inside smalltalk methods in VisualWorks, would that work as well ? Customize on a per class / per method which compiler we should use. Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 5 July 2013 16:09, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 05/07/2013 15:31, Igor Stasenko a écrit :
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
Of course. I could do with having the same error for both and knowing that when developping and testing I would get it for stupid syntax errors and in production to handle a real situation.
If its fine to you, i can do it.
Maybe I can try myself to see if I can write, before entering that loader stuff, a correct test which raises an error if the method source isn't available.
Is there a real, practical difference between "at compilation time" and "when receiving MethodAdded event"? i.e. is the complexity added in the compilation process worthwhile?
the problem is that you may not always receive MethodAdded event, because different tools putting different meaning into "this should be compiled silently". This is outstanding issue in Pharo.. and that's the main reason why i would go with compiler (like that i have guarantee that instance of CompiledMethod is well-formed, and don't need to rely on 3-rd party toolchain to deliver notification to me.
You mean that hacking support into the third party compiler isn't 3rd party toolchain :)
well, to me the compiler's behavior is much much more predictable comparing to chances that when you loading code with broken Monticello/RPackage or running test, you won't receive the event you expecting.
and besides, we need such hook mechanism in Compiler anyways (for many other use cases) and so, it will be not "renting a Boeing for single passenger"
oh.. and i forgot about most important aspect of it: i don't wanna see <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode > in code, instead if wanna use
<native> (or similar), which admit, much more concise, elegant and user-friendly, and hides unnecessary implementation detail.
I remember seeing people introducing syntax extensions inside smalltalk methods in VisualWorks, would that work as well ? Customize on a per class / per method which compiler we should use.
yes. But i don't wanna extend syntax in case of NB , obviously :)
Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
-- Best regards, Igor Stasenko.
On 5 July 2013 16:09, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 05/07/2013 15:31, Igor Stasenko a écrit :
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
Of course. I could do with having the same error for both and knowing that when developping and testing I would get it for stupid syntax errors and in production to handle a real situation.
If its fine to you, i can do it.
Maybe I can try myself to see if I can write, before entering that loader stuff, a correct test which raises an error if the method source isn't available.
well, all you need is basicaly replace this: Error signal: 'Could not find accessor for variable named "' , argName , '" in ' , method name with: NBArgumentNotFound signal: argName .. or NBCannotBindName.. what name for exception? -- Best regards, Igor Stasenko.
Le 05/07/2013 16:36, Igor Stasenko a écrit :
On 5 July 2013 16:09, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 05/07/2013 15:31, Igor Stasenko a écrit :
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
Of course. I could do with having the same error for both and knowing that when developping and testing I would get it for stupid syntax errors and in production to handle a real situation.
If its fine to you, i can do it.
Maybe I can try myself to see if I can write, before entering that loader stuff, a correct test which raises an error if the method source isn't available.
well, all you need is basicaly replace this:
Error signal: 'Could not find accessor for variable named "' , argName , '" in ' , method name
with:
NBArgumentNotFound signal: argName
.. or NBCannotBindName..
what name for exception?
I believe the proper way would be to have : NBCannotBindName (for the errors you already handle at the moment) and, somewhere in there, a NBMethodSourceNotAvailable triggered in NBFFICallout>>sender: if the source code is decompiledCode (but, as far as I can see, there is no method to test a CompiledMethod for that :)) Something like CompiledMethod>>hasSourceCode "Say false if we have to reconstruct the code." | trailer source | trailer := self trailer. trailer sourceCode ifNotNil: [:code | ^ true ]. trailer hasSourcePointer ifFalse: [ ^ false]. "Situation normal; read the sourceCode from the file" source := [self getSourceFromFile] on: Error do: [ :ex | ex return: nil]. source isEmptyOrNil ifTrue: [ ^ false ]. ^ true and, in sender: aSenderContext method hasSourceCode ifFalse: [NBMethodSourceNotAvailable signal: method printString] What do you think ? Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
On 5 July 2013 16:55, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 05/07/2013 16:36, Igor Stasenko a écrit :
On 5 July 2013 16:09, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Le 05/07/2013 15:31, Igor Stasenko a écrit :
On 5 July 2013 15:22, Igor Stasenko <siguctua@gmail.com> wrote:
On 5 July 2013 11:03, Goubier Thierry <thierry.goubier@cea.fr> wrote:
Could you rather test for unability to get the source of the method and raise a NB-defined error? So that I could write a fallback on non-NB code with a on: do:. Please :)
(it would then both handle startup related errors and unreadable sources as well).
And with a backport to 2.0, because the odds of seeing an Opal based solution on 2.0 are fairly low.
the problem is that you will get same error when you put wrong name into signature or when no sources avail e.g.:
foo: bar ^ self nbCall: #( void foo (int baz) )
will give same error (unable to find binding for name 'baz' in given context).
Of course. I could do with having the same error for both and knowing that when developping and testing I would get it for stupid syntax errors and in production to handle a real situation.
If its fine to you, i can do it.
Maybe I can try myself to see if I can write, before entering that loader stuff, a correct test which raises an error if the method source isn't available.
well, all you need is basicaly replace this:
Error signal: 'Could not find accessor for variable named "' , argName , '" in ' , method name
with:
NBArgumentNotFound signal: argName
.. or NBCannotBindName..
what name for exception?
I believe the proper way would be to have :
NBCannotBindName (for the errors you already handle at the moment)
and, somewhere in there, a
NBMethodSourceNotAvailable
triggered in NBFFICallout>>sender: if the source code is decompiledCode (but, as far as I can see, there is no method to test a CompiledMethod for that :))
Something like
CompiledMethod>>hasSourceCode "Say false if we have to reconstruct the code."
| trailer source | trailer := self trailer. trailer sourceCode ifNotNil: [:code | ^ true ]. trailer hasSourcePointer ifFalse: [ ^ false]. "Situation normal; read the sourceCode from the file" source := [self getSourceFromFile] on: Error do: [ :ex | ex return: nil]. source isEmptyOrNil ifTrue: [ ^ false ]. ^ true
and, in sender:
aSenderContext method hasSourceCode ifFalse: [NBMethodSourceNotAvailable signal: method printString]
What do you think ?
I think it is not responsibility of NB to deal with availability of source code. NB simply using reflection protocol of system to get what it wants to get, and where it come (from source code, or from something else) is completely irrelevant. Yes, with current implementation, it ends up with getting & parsing source code, but it is not what NB is asking for: the intent is to simply ask a compiled method to provide the argument names. That's why i totally agree with introduction of NBCannotBindName exception, but i cannot see place for NBMethodSourceNotAvailable. Otherwise similar tools with similar requirements will need to (re)implement same? This should be a responsibility of kernel/system.. but not NB itself.
Thierry -- Thierry Goubier CEA list Laboratoire des Fondations des Systèmes Temps Réel Embarqués 91191 Gif sur Yvette Cedex France Phone/Fax: +33 (0) 1 69 08 32 92 / 83 95
-- Best regards, Igor Stasenko.
Here is another quick and dirty recipe 4U: - make a extension method in CompiledMethod nbEnsureTempNames self propertyValueAt: #tempNames ifAbsent: [ self propertyValueAt: #tempNames put: self tempNames ] nbTempNames ^ self propertyValueAt: #tempNames NativeBoost class>>prepareForProduction CompiledMethod allInstancesDo: [:aMethod | ((aMethod primitive = 117) and: [ | lit | lit := aMethod literalAt: 1. lit first = #NativeBoostPlugin and: [ lit second == #primitiveNativeCall]]) ifTrue: [ aMethod nbEnsureTempNames ]. ] (and then sure thing, make sure to use #nbTempNames instead of tempNames). but for the future, i want a clear protocol in CompiledMethod to do that, and do not make it depend on system changes. Because if i do, the stuff which works in 2.0 (or 3.0) will suddenly stop working in next version, because of changes in system.. that's why i against even thinking that NB having something to do with method's source code. It needs method's argument names, and nothing else, period. -- Best regards, Igor Stasenko.
Now with Opal in and the API rationalisation we will get stable. I agree that we should avoid core code in external packages. Stef
Here is another quick and dirty recipe 4U:
- make a extension method in CompiledMethod
nbEnsureTempNames
self propertyValueAt: #tempNames ifAbsent: [ self propertyValueAt: #tempNames put: self tempNames ]
nbTempNames ^ self propertyValueAt: #tempNames
NativeBoost class>>prepareForProduction
CompiledMethod allInstancesDo: [:aMethod | ((aMethod primitive = 117) and: [ | lit | lit := aMethod literalAt: 1. lit first = #NativeBoostPlugin and: [ lit second == #primitiveNativeCall]]) ifTrue: [ aMethod nbEnsureTempNames ]. ]
(and then sure thing, make sure to use #nbTempNames instead of tempNames).
but for the future, i want a clear protocol in CompiledMethod to do that, and do not make it depend on system changes. Because if i do, the stuff which works in 2.0 (or 3.0) will suddenly stop working in next version, because of changes in system.. that's why i against even thinking that NB having something to do with method's source code. It needs method's argument names, and nothing else, period.
-- Best regards, Igor Stasenko.
You don't consider NB to be core ? Thierry ________________________________________ De : Pharo-dev [pharo-dev-bounces@lists.pharo.org] de la part de Stéphane Ducasse [stephane.ducasse@inria.fr] Date d'envoi : samedi 6 juillet 2013 11:04 à : Pharo Development List Objet : Re: [Pharo-dev] NativeBoost with no access to sources Now with Opal in and the API rationalisation we will get stable. I agree that we should avoid core code in external packages. Stef
Here is another quick and dirty recipe 4U:
- make a extension method in CompiledMethod
nbEnsureTempNames
self propertyValueAt: #tempNames ifAbsent: [ self propertyValueAt: #tempNames put: self tempNames ]
nbTempNames ^ self propertyValueAt: #tempNames
NativeBoost class>>prepareForProduction
CompiledMethod allInstancesDo: [:aMethod | ((aMethod primitive = 117) and: [ | lit | lit := aMethod literalAt: 1. lit first = #NativeBoostPlugin and: [ lit second == #primitiveNativeCall]]) ifTrue: [ aMethod nbEnsureTempNames ]. ]
(and then sure thing, make sure to use #nbTempNames instead of tempNames).
but for the future, i want a clear protocol in CompiledMethod to do that, and do not make it depend on system changes. Because if i do, the stuff which works in 2.0 (or 3.0) will suddenly stop working in next version, because of changes in system.. that's why i against even thinking that NB having something to do with method's source code. It needs method's argument names, and nothing else, period.
-- Best regards, Igor Stasenko.
This is very usefull for production deployment. I'll make a try and provide a slice if I succeed. Thierry ________________________________________ De : Pharo-dev [pharo-dev-bounces@lists.pharo.org] de la part de Igor Stasenko [siguctua@gmail.com] Date d'envoi : vendredi 5 juillet 2013 17:29 Ã : Pharo Development List Objet : Re: [Pharo-dev] NativeBoost with no access to sources Here is another quick and dirty recipe 4U: - make a extension method in CompiledMethod nbEnsureTempNames self propertyValueAt: #tempNames ifAbsent: [ self propertyValueAt: #tempNames put: self tempNames ] nbTempNames ^ self propertyValueAt: #tempNames NativeBoost class>>prepareForProduction CompiledMethod allInstancesDo: [:aMethod | ((aMethod primitive = 117) and: [ | lit | lit := aMethod literalAt: 1. lit first = #NativeBoostPlugin and: [ lit second == #primitiveNativeCall]]) ifTrue: [ aMethod nbEnsureTempNames ]. ] (and then sure thing, make sure to use #nbTempNames instead of tempNames). but for the future, i want a clear protocol in CompiledMethod to do that, and do not make it depend on system changes. Because if i do, the stuff which works in 2.0 (or 3.0) will suddenly stop working in next version, because of changes in system.. that's why i against even thinking that NB having something to do with method's source code. It needs method's argument names, and nothing else, period. -- Best regards, Igor Stasenko.
participants (5)
-
GOUBIER Thierry -
Goubier Thierry -
Igor Stasenko -
Marcus Denker -
Stéphane Ducasse