Hi, I'm trying to mimic the following C/C++ example in NativeBoots to allow random number generation on windows: https://gist.github.com/kbjorklu/6317361 When I combine the flags in Pharo using "|" in the same way like in the first function call of the example: acquireContextExample1 NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) module: #advapi32 I get an error 'comma expected'. Looks like the NBFnSpecParser does not allow expression evaluation like CRYPT_VERIFYCONTEXT | CRYPT_SILENT. Will this be possible in future versions? Nonetheless I tried to continue and since I defined: CRYPT_VERIFYCONTEXT := 16rF0000000. CRYPT_SILENT := 16r00000040. I evaluated manually and tried to use the harcoded value directly: acquireContextExample2 "Retrieves information about the current console font." <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'> ^ NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, 16rF0000040)) module: #advapi32 but this returns another error when converting using #asDWord: (16rF0000040 i4) exceeds doubleword (32bit) range in an AJImmediate but 16rF0000040. Looks like it is treated as unsiged since 16rF0000040 asUImm32 asDWord works. How to specifiy the number directly but as unsigned? To reproduce: - take a fresh Pharo3.0 Latest update: #30759 - load "OSWindows" from config browser to get the core and other packages - load "OS-Windows-Cryptography" package/mcz from smalltalkhub.com/#!/~OS/OS-Windows - evaluate WinCryptoProvider new acquireContextExample2 or WinCryptoProvider new acquireContextExample1 Any helping hand in converting the example would be appreciated. Thx T.
On 16 February 2014 23:37, Torsten Bergmann <astares@gmx.de> wrote:
Hi,
I'm trying to mimic the following C/C++ example in NativeBoots to allow random number generation on windows:
https://gist.github.com/kbjorklu/6317361
When I combine the flags in Pharo using "|" in the same way like in the first function call of the example:
acquireContextExample1 NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) module: #advapi32
I get an error 'comma expected'. Looks like the NBFnSpecParser does not allow expression evaluation like CRYPT_VERIFYCONTEXT | CRYPT_SILENT. Will this be possible in future versions?
Nonetheless I tried to continue and since I defined: CRYPT_VERIFYCONTEXT := 16rF0000000. CRYPT_SILENT := 16r00000040.
I evaluated manually and tried to use the harcoded value directly:
acquireContextExample2
"Retrieves information about the current console font." <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'>
^ NBFFICallout stdcall: #(BOOL CryptAcquireContextA(HCRYPTPROV self, 0, 0, PROV_RSA_FULL, 16rF0000040)) module: #advapi32
but this returns another error when converting using #asDWord:
(16rF0000040 i4) exceeds doubleword (32bit) range
in an AJImmediate but 16rF0000040. Looks like it is treated as unsiged since
16rF0000040 asUImm32 asDWord
works. How to specifiy the number directly but as unsigned?
To reproduce: - take a fresh Pharo3.0 Latest update: #30759 - load "OSWindows" from config browser to get the core and other packages - load "OS-Windows-Cryptography" package/mcz from smalltalkhub.com/#!/~OS/OS-Windows - evaluate WinCryptoProvider new acquireContextExample2 or WinCryptoProvider new acquireContextExample1
Any helping hand in converting the example would be appreciated.
Thx T.
Yes, i am aware of this problem. (16rF0000040 i4) exceeds doubleword (32bit) range i4 means signed integer 4 bytes.. the mantissa 16rF0000040 , simply don't fits, because it is > 2^31-1, which is max for 32-bit integer. The class responsible for passing constants is NBFFIConst: Integer>>asNBExternalType: gen "integer value in callout argument description array are pushed directly on stack #( 100 ) - an integer value argument = 100 " ^ NBFFIConst value: (self ) the code generator, uses: emitPush: gen gen asm push: ((gen asm imm: value) size: 4) and #imm: sends #asImm to the value, which by default turns integer into a signed immediate: Integer>>asImm "Convert integer value into a signed immediate operand" ^ AJImmediate new ivalue: self unfortunately, there is no easy way to work around this: if you change it to unsigned (uvalue:), then you have another problem, but now with all negative integer constants (like -1). But you can work that around: use a 32-bit complement of unsigned 16rF0000040 to signed one, which ends up with identical 32-bit value: 16rF0000040 - 16r100000000 => -268435392 test: (16r100000000 - 268435392) hex '16rF0000040' -- Best regards, Igor Stasenko.
Other solution, is to change NBFFIConst and be more forgiving about constants range (so if it sees large positive integer which don't fits into 32-bit signed integer range, assume it is unsigned 32-but integer and use proper immediate type during code generation). I know this could be 'least surprising behavior' , only because this is how C works by not caring about signed/unsigned value assignments. But when i was doing it i decided to be more strict, because implicit conversions have one big downside: - if there's a malfunction in your code, you often find yourself in a position to wonder, whether it breaks because implicit conversion _applied_ in a place where you didn't expected or it is because it is _not applied_ in a place where you actually expected. :) -- Best regards, Igor Stasenko.
participants (2)
-
Igor Stasenko -
Torsten Bergmann