On 9 January 2013 09:10, Igor Stasenko <[email protected]> wrote:
> On 8 January 2013 19:38, Eliot Miranda <[email protected]> wrote:
>>
>>
>>
>> On Fri, Jan 4, 2013 at 12:37 AM, Igor Stasenko <[email protected]> wrote:
>>>
>>> On 4 January 2013 08:54, Torsten Bergmann <[email protected]> wrote:
>>> > When one deploys an image one usually requires ONLY
>>> > the image - not the source or changes file. An "image locker"
>>> > code would look like this:
>>> >
>>> > SmalltalkImage checkSourcesFileAvailability: false.
>>> > SmalltalkImage checkChangesFileAvailability: false
>>> >
>>> > do disable acording warnings when source/changefile is removed.
>>> >
>>> > If one uses NativeBoost in such a deployment scenario, for
>>> > instance the
>>> >
>>> > NBWin32Shell shellBrowse: 'http://www.google.de'
>>> >
>>> > functionality the internal code (due to missing source) now
>>> > looks like this
>>> >
>>> > shellExecute: t1 file: t2 parameters: t3 directory: t4 show: t5
>>> > <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'>
>>> > ^ self nbCall: #(#HINSTANCE #ShellExecuteA #(0 #, #LPCTSTR
>>> > #lpOperation #, #LPCTSTR #lpFile #, #LPCTSTR #lpParameters #, #LPCTSTR
>>> > #lpDirectory #, #INT #nShowCmd ) ) module: 'Shell32.dll'
>>> >
>>> > Hence the t1 ... t5 parameters.
>>> >
>>> > NativeBoost is in this situation not able to match the
>>> > FFI parameters and throws an error "Could not find accessor for variable
>>> > ..."
>>> >
>>> > Try yourself without a changes and source file. This makes
>>> > NativeBoost not very deployment friendly and unusable in
>>> > such a "minimal deployment" scenario ...
>>> >
>>> > Any comments?
>>> >
>>>
>>> yes it needs sources (indirectly) to bind method's argument names
>>> during code generation.
>>> To avoid that, i can imagine that one must modify a compiler to detect
>>> if compiled method
>>> primitive requires arg names, and store them in method properties.
>>> Like that later code generator can use them without need to access the
>>> source code.
>>
>>
>> Indeed. If a pragma were used then the whole thing could look a lot nicer,
>> not be dependent on source, and include support for an error code. e.g.
>>
>> shellExecute: lpOperation file: lpFile parameters: lpParameters directory:
>> lpDirectory show: nShowCmd
>>
>> <nbCall: #(#HINSTANCE #ShellExecuteA #(0 #, #LPCTSTR #lpOperation #,
>> #LPCTSTR #lpFile #, #LPCTSTR #lpParameters #, #LPCTSTR #lpDirectory #, #INT
>> #nShowCmd ) )
>> module: 'Shell32.dll'
>> errorCode: ec>
>>
>> ^self nbCallFailedWith: ec
>>
>> It's pretty trivial to add such pragma compilers to the compiler. There is
>> an example for the FFI. It also frees one to use a nicer syntax, e.g.
>>
>> shellExecute: lpOperation file: lpFile parameters: lpParameters directory:
>> lpDirectory show: nShowCmd
>> <nbCall: 'HINSTANCE ShellExecuteA(0, LPCTSTR lpOperation, LPCTSTR
>> lpFile, LPCTSTR lpParameters, LPCTSTR lpDirectory, INT nShowCmd)'
>> module: 'Shell32.dll'
>> errorCode: ec>
>>
>> ^self nbCallFailedWith: ec
>>
>
> i do not see how encoding function signature in pragma could help with
> binding argument names.
> Yes, you need to get some control at compile time to be able to encode
> method arg names somewhere in method properties for later use.. but
> not at cost of moving everything into pragma.
>
> And 'nice' syntax is actually already there .. nothing prevents you
> from using strings for function signature, e.g.
>
> self nbCall: 'int foo()'
> equivalent to
> self nbCall: #(int foo() )
>
> (i don't know why Torsten gave code in such form, that could leave an
> impression that syntax is horrible ;)
ah, yes.. it is because he shows decompiled method source.
The original source code looks much better:
shellExecute: lpOperation file: lpFile parameters: lpParameters
directory: lpDirectory show: nShowCmd
<primitive: #primitiveNativeCall module: #NativeBoostPlugin>
^ self nbCall: #(
HINSTANCE ShellExecuteA(
0,
LPCTSTR lpOperation,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd)) module: 'Shell32.dll'
>
> And besides, how you suppose to "pragmatize" following:
>
> storeDouble: aDouble at: address
> " This method stores a double floating point value at given memory
> address.
> an address can be an instance of NBExternalAddress, or
> simple ByteArray with at least 8 bytes long, which will hold a 64bit
> floating-point value"
>
> <primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin' error:
> errorCode>
>
> ^ self nbCallout
> options: #(
> - optCoerceNilToNull
> + optAllowByteArraysPtr
> + optAllowExternalAddressPtr
> );
> function: #( void (void * address, double aDouble) )
> emit: [:gen | | asm |
> asm := gen asm.
>
> "Here , we expecting that an address value is on top
> of the stack"
> asm
> pop: EDX; "load an address value into EDX
> register by popping it
> from a stack"
>
> "now copy the floating point value (which is
> 8-bytes long) to the
> given address"
> mov: ESP ptr to: EAX;
> mov: EAX to: EDX ptr; " store first 32bit
> part of 64bit double value"
>
> mov: ESP ptr + 4 to: EAX;
> mov: EAX to: EDX ptr + 4. " store second
> 32bit part of 64bit double value"
>
> ]
>
>
>
>
> --
> Best regards,
> Igor Stasenko.
--
Best regards,
Igor Stasenko.