Hi, there , i've been working last two weeks on reviewing the code in NB, and update configuration & making tests green etc.. So, here the summary: 0. New stuff: external structures (NBExternalStructure) now is normal objects (not var-byte ones), and using 'data' ivar indirection like in NBExternalArray, so you can allocate external struct on both external heap and object memory, e.g.: struct := MyStructClass externalNew. or: struct := MyStructClass new. (so, it is similar to NBExternalArray). - a function with signature MyStruct * foo () which returns a pointer to struct, now will return an instance of MyStruct with the address, so you can use it directly , e.g.: struct := self callFoo. value := struct field1. struct field2: 10 etc.. Thanks to Ciprian for introducing the change. I just polished a bit and fixed some mistakes. 1. NBExternalTypeValue>>address should not exist. You simply cannot use freely an address to object's internal field because object can move in memory. (the tests in NBFFIExternalValueTests testOutIntArg testOutValueArg testOutVoidArg is changed accordingly) 2. In NBExternalEnumerationType: pushing a pointer to this type is not allowed, since it makes no sense. But the mistake there was to generate a code which fails primitive with an error message, instead of failing much much sooner - at code generation stage, since it is already known that user specified wrong type. 3. I reverting generic pushAsPointer: to accept varbyte objects instead of just ByteArray object. - removing #specialPush:asPointer:endLabel: because it will be not used (btw, in NBExternalStructureType>>specialPush:asPointer:endLabel: , there was same mistake that it generates code to checking a pointer arity at runtime, while it is already known during code generation time: asm decorateWith: 'arity checking' during: [ |pointerArityOk| pointerArityOk := asm uniqueLabelName: 'pointerArityOk'. asm mov: pointerArity asImm32 to: asm EAX; cmp: asm EAX with: 1 asImm32; je: pointerArityOk. gen failWithMessage: 'Arity ', pointerArity printString,' not allowed for ', objectClass name, 'objects'. asm label: pointerArityOk]. since pointerArity is known, the produced code will be something like: mov: 1 to: EAX; cmp: EAX with: 1; je: pointerArityOk and makes no sense, because again it can just throw the error at code generation time. 4. Added code to capture argument names (CompiledMethod>>nbArgumentNames) and 'NativeBoost prepareForProduction', to ensure NB can work without source code accessible. 5. But the general expression, like in (1): object address gave me an interesting idea: what if we introduce a special type, say NBObjectFieldAddress. Consider the following problem: imagine that you have a big array in object memory (byte array), and you want to pass a pointer to n-th element of that array to some function. Right now, there is no way how you can do it, and you can pass only a pointer to array itself (which means it will always point to its first element). So, the idea is to introduce a special type, and special object which represents the address-of-object's-field, so you can tell: array := ByteArray new: 1000. address := array nbAddressAt: 500. "create an address object which points to 500th element of given array" (and expression 'array nbAddress' is synonym to 'array nbAddressAt: 1'). self callSomeFunctionWith: address. The signature of C function which takes a pointer like: void foo (void * ptr) then should be changed to: void foo (NBObjectFieldAddress ptr) the only question, which remains , shall it use strict type checking (so you have to change the signature), or allow to use such objects with any signatures which takes a pointer to something, e.g. extend generic NBExternalType>>pushAsPointer: to additionally check if incoming argument is instance of NBObjectFieldAddress class. P.S. to try new config , load it: Gofer new smalltalkhubUser: 'Pharo' project: 'NativeBoost'; configuration; load. ConfigurationOfNativeBoost loadDevelopment. "which should load 2.2 version of it" -- Best regards, Igor Stasenko.
Thanks for all this work, Igor! But can we do a simple system call yet?! http://forum.world.st/NB-crash-boom-td4669980.html https://pharo.fogbugz.com/f/cases/7542/NB-system-examplerun: str Sean: run: str "self run: 'open http://www.google.com'." <primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode > ^ self nbCall: #( int system (String str) ) module: NativeBoost CLibrary fails Cami: "Yes I would put that even on high-priority for NB, as it is the most important use-case that makes sense to me :D" ----- Cheers, Sean -- View this message in context: http://forum.world.st/Pharo-dev-NB-Review-fixes-ideas-tp4698514p4698563.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
On 13 July 2013 02:04, Sean P. DeNigris <sean@clipperadams.com> wrote:
Thanks for all this work, Igor! But can we do a simple system call yet?!
yes this is strange thing.. once it was worked, but then suddently VM start crashing. the answer is in VM, not NB.
http://forum.world.st/NB-crash-boom-td4669980.html https://pharo.fogbugz.com/f/cases/7542/NB-system-examplerun: str
Sean: run: str "self run: 'open http://www.google.com'."
<primitive: #primitiveNativeCall module: #NativeBoostPlugin error: errorCode > ^ self nbCall: #( int system (String str) ) module: NativeBoost CLibrary fails
Cami: "Yes I would put that even on high-priority for NB, as it is the most important use-case that makes sense to me :D"
----- Cheers, Sean -- View this message in context: http://forum.world.st/Pharo-dev-NB-Review-fixes-ideas-tp4698514p4698563.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
-- Best regards, Igor Stasenko.
On 13 July 2013 19:20, Igor Stasenko <siguctua@gmail.com> wrote:
On 13 July 2013 02:04, Sean P. DeNigris <sean@clipperadams.com> wrote:
Thanks for all this work, Igor! But can we do a simple system call yet?!
yes this is strange thing.. once it was worked, but then suddently VM start crashing. the answer is in VM, not NB.
btw it works, in at least latest Mac VM. And i did nothing to fix it, so the problem may reoccur. -- Best regards, Igor Stasenko.
Igor you should add that to a class comment and into the wiki of NB. On Jul 12, 2013, at 5:43 PM, Igor Stasenko <siguctua@gmail.com> wrote:
Hi, there , i've been working last two weeks on reviewing the code in NB, and update configuration & making tests green etc.. So, here the summary:
0. New stuff:
external structures (NBExternalStructure) now is normal objects (not var-byte ones), and using 'data' ivar indirection like in NBExternalArray, so you can allocate external struct on both external heap and object memory, e.g.:
struct := MyStructClass externalNew. or: struct := MyStructClass new. (so, it is similar to NBExternalArray).
- a function with signature
MyStruct * foo ()
which returns a pointer to struct, now will return an instance of MyStruct with the address, so you can use it directly , e.g.:
struct := self callFoo.
value := struct field1. struct field2: 10
etc..
Thanks to Ciprian for introducing the change. I just polished a bit and fixed some mistakes.
1. NBExternalTypeValue>>address should not exist. You simply cannot use freely an address to object's internal field because object can move in memory.
(the tests in NBFFIExternalValueTests testOutIntArg testOutValueArg testOutVoidArg
is changed accordingly)
2. In NBExternalEnumerationType: pushing a pointer to this type is not allowed, since it makes no sense.
But the mistake there was to generate a code which fails primitive with an error message, instead of failing much much sooner - at code generation stage, since it is already known that user specified wrong type.
3. I reverting generic pushAsPointer: to accept varbyte objects instead of just ByteArray object. - removing #specialPush:asPointer:endLabel: because it will be not used (btw, in NBExternalStructureType>>specialPush:asPointer:endLabel: , there was same mistake that it generates code to checking a pointer arity at runtime, while it is already known during code generation time:
asm decorateWith: 'arity checking' during: [ |pointerArityOk| pointerArityOk := asm uniqueLabelName: 'pointerArityOk'. asm mov: pointerArity asImm32 to: asm EAX; cmp: asm EAX with: 1 asImm32; je: pointerArityOk. gen failWithMessage: 'Arity ', pointerArity printString,' not allowed for ', objectClass name, 'objects'. asm label: pointerArityOk].
since pointerArity is known, the produced code will be something like:
mov: 1 to: EAX; cmp: EAX with: 1; je: pointerArityOk
and makes no sense, because again it can just throw the error at code generation time.
4. Added code to capture argument names (CompiledMethod>>nbArgumentNames) and 'NativeBoost prepareForProduction', to ensure NB can work without source code accessible.
5. But the general expression, like in (1):
object address
gave me an interesting idea: what if we introduce a special type, say NBObjectFieldAddress. Consider the following problem: imagine that you have a big array in object memory (byte array), and you want to pass a pointer to n-th element of that array to some function. Right now, there is no way how you can do it, and you can pass only a pointer to array itself (which means it will always point to its first element).
So, the idea is to introduce a special type, and special object which represents the address-of-object's-field, so you can tell:
array := ByteArray new: 1000.
address := array nbAddressAt: 500. "create an address object which points to 500th element of given array"
(and expression 'array nbAddress' is synonym to 'array nbAddressAt: 1').
self callSomeFunctionWith: address.
The signature of C function which takes a pointer like:
void foo (void * ptr)
then should be changed to:
void foo (NBObjectFieldAddress ptr)
the only question, which remains , shall it use strict type checking (so you have to change the signature), or allow to use such objects with any signatures which takes a pointer to something, e.g. extend generic NBExternalType>>pushAsPointer: to additionally check if incoming argument is instance of NBObjectFieldAddress class.
P.S. to try new config , load it:
Gofer new smalltalkhubUser: 'Pharo' project: 'NativeBoost'; configuration; load.
ConfigurationOfNativeBoost loadDevelopment. "which should load 2.2 version of it"
-- Best regards, Igor Stasenko.
what are the pros and cons? Stef
the only question, which remains , shall it use strict type checking (so you have to change the signature), or allow to use such objects with any signatures which takes a pointer to something, e.g. extend generic NBExternalType>>pushAsPointer: to additionally check if incoming argument is instance of NBObjectFieldAddress class.
On 13 July 2013 14:47, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
what are the pros and cons?
pros - you can pass is as parameter everywhere it expects a pointer cons - it will slow down all calls with pointer type because of extra check, even if you don't using it (and in most cases you don't) i think best way is to introduce it as option.
Stef
the only question, which remains , shall it use strict type checking (so you have to change the signature), or allow to use such objects with any signatures which takes a pointer to something, e.g. extend generic NBExternalType>>pushAsPointer: to additionally check if incoming argument is instance of NBObjectFieldAddress class.
-- Best regards, Igor Stasenko.
On Jul 13, 2013, at 7:23 , Igor Stasenko wrote:
On 13 July 2013 14:47, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
what are the pros and cons?
pros - you can pass is as parameter everywhere it expects a pointer cons - it will slow down all calls with pointer type because of extra check, even if you don't using it (and in most cases you don't)
i think best way is to introduce it as option.
I think there's an -optNoChecks or something already? IMHO, it's would be nice to basically treat them as asserts; leave them on by default, then have a system-wide switch in case you want to disable them for production and gain some performance at the risk of crashes rather than failures in case of running into untested incorrect usage. (Optionally with an added -optForceChecks in case you write code that depends on an error being thrown for incorrectly passed types⦠though that shouldn't really happen) Cheers, Henry PS: Sadly, summer in Norway has seen the best weather in ages :D
participants (4)
-
Henrik Johansen -
Igor Stasenko -
Sean P. DeNigris -
Stéphane Ducasse