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 ;)
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.