pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil is this valid pragma syntax: <apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'> our (pharo) parser can not parse this (does not recognizes the "selector parts" (apicall:module:) right) Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'> nicolai
Hi Nicolai, On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <nicolaihess@gmail.com> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
is this valid pragma syntax:
<apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
As others have said this is not a valid pragma. A valid pragma is a message expression (a message with no receiver) that has only literal arguments. There is one exception, to accept a variable name for the error code in a primitive invocation. And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above. And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference). So for example, the heapsort declaration from the standard C library: int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)) could be written as a pragma via e.g. <ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))> in which case it is equal to <ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))> which, while a massive hack, is pretty neat. The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,. So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String). I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling. This would easily allow extensions such as <ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character> to guide a marshalling engine in providing automatic checks and conversions. [Slightly OT] Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails). So a Callback for heapsort above looks like voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #IA32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5))) or voidstarvoidstarRetintARM32: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #ARM32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2))) Hmmm, if Callback had subclasses for each ABI then the above would become IA32Callback methods for signature voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5))) ARM32Callback methods for signatures voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2))) Much nicer. I shall make it so. our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)
Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
nicolai
_,,,^..^,,,_ best, Eliot
2016-01-10 16:57 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Hi Nicolai,
On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <nicolaihess@gmail.com> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
is this valid pragma syntax:
<apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
As others have said this is not a valid pragma. A valid pragma is a message expression (a message with no receiver) that has only literal arguments. There is one exception, to accept a variable name for the error code in a primitive invocation.
And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.
Thanks Eliot. I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax
And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference). So for example, the heapsort declaration from the standard C library:
int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
could be written as a pragma via e.g.
<ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>
in which case it is equal to
<ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>
which, while a massive hack, is pretty neat. The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.
So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String). I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.
This would easily allow extensions such as
<ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>
to guide a marshalling engine in providing automatic checks and conversions.
[Slightly OT] Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails). So a Callback for heapsort above looks like
voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #IA32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
or voidstarvoidstarRetintARM32: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #ARM32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Hmmm, if Callback had subclasses for each ABI then the above would become
IA32Callback methods for signature voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
ARM32Callback methods for signatures voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Much nicer. I shall make it so.
our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)
Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
nicolai
_,,,^..^,,,_ best, Eliot
well⦠UnifiedFFI, UFFI or whatever it will be called already does that⦠as you know. Currently we are using âolderâ NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. But final objective is to provide a pragma and solve it in compilation time. Then we can 100% deprecate the invalid pragma old FFI uses today. At least, thatâs what we have talk :) Esteban
On 12 Jan 2016, at 20:06, Nicolai Hess <nicolaihess@gmail.com> wrote:
2016-01-10 16:57 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>>:
Hi Nicolai,
On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <nicolaihess@gmail.com <mailto:nicolaihess@gmail.com>> wrote: pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
is this valid pragma syntax:
<apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
As others have said this is not a valid pragma. A valid pragma is a message expression (a message with no receiver) that has only literal arguments. There is one exception, to accept a variable name for the error code in a primitive invocation.
And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.
Thanks Eliot.
I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax
And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference). So for example, the heapsort declaration from the standard C library:
int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
could be written as a pragma via e.g.
<ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>
in which case it is equal to
<ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>
which, while a massive hack, is pretty neat. The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.
So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String). I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.
This would easily allow extensions such as
<ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>
to guide a marshalling engine in providing automatic checks and conversions.
[Slightly OT] Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails). So a Callback for heapsort above looks like
voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #IA32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
or voidstarvoidstarRetintARM32: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #ARM32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Hmmm, if Callback had subclasses for each ABI then the above would become
IA32Callback methods for signature voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
ARM32Callback methods for signatures voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Much nicer. I shall make it so.
our (pharo) parser can not parse this (does not recognizes the "selector parts" (apicall:module:) right)
Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
nicolai
_,,,^..^,,,_ best, Eliot
2016-01-12 20:57 GMT+01:00 Esteban Lorenzano <estebanlm@gmail.com>:
well⦠UnifiedFFI, UFFI or whatever it will be called already does that⦠as you know. Currently we are using âolderâ NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. But final objective is to provide a pragma and solve it in compilation time.
Then we can 100% deprecate the invalid pragma old FFI uses today.
But how do we solve the issue?
At least, thatâs what we have talk :)
Esteban
On 12 Jan 2016, at 20:06, Nicolai Hess <nicolaihess@gmail.com> wrote:
2016-01-10 16:57 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Hi Nicolai,
On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <nicolaihess@gmail.com> wrote:
pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
is this valid pragma syntax:
<apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
As others have said this is not a valid pragma. A valid pragma is a message expression (a message with no receiver) that has only literal arguments. There is one exception, to accept a variable name for the error code in a primitive invocation.
And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.
Thanks Eliot.
I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax
And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference). So for example, the heapsort declaration from the standard C library:
int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
could be written as a pragma via e.g.
<ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>
in which case it is equal to
<ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>
which, while a massive hack, is pretty neat. The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.
So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String). I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.
This would easily allow extensions such as
<ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>
to guide a marshalling engine in providing automatic checks and conversions.
[Slightly OT] Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails). So a Callback for heapsort above looks like
voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #IA32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
or voidstarvoidstarRetintARM32: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #ARM32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Hmmm, if Callback had subclasses for each ABI then the above would become
IA32Callback methods for signature voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
ARM32Callback methods for signatures voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Much nicer. I shall make it so.
our (pharo) parser can not parse this (does not recognizes the
"selector parts" (apicall:module:) right)
Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
nicolai
_,,,^..^,,,_ best, Eliot
On 12 Jan 2016, at 21:12, Nicolai Hess <nicolaihess@gmail.com> wrote:
2016-01-12 20:57 GMT+01:00 Esteban Lorenzano <estebanlm@gmail.com <mailto:estebanlm@gmail.com>>:
well⦠UnifiedFFI, UFFI or whatever it will be called already does that⦠as you know. Currently we are using âolderâ NB way: as a method call, then solving it in first call. This is nice because is compatible and easies some stuff. But final objective is to provide a pragma and solve it in compilation time.
Then we can 100% deprecate the invalid pragma old FFI uses today.
But how do we solve the issue?
Well, we should add an #visitFFIPragmaNode: who can deal with it, in the mean time :) Esteban
At least, thatâs what we have talk :)
Esteban
On 12 Jan 2016, at 20:06, Nicolai Hess <nicolaihess@gmail.com <mailto:nicolaihess@gmail.com>> wrote:
2016-01-10 16:57 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>>:
Hi Nicolai,
On Sun, Jan 10, 2016 at 3:16 AM, Nicolai Hess <nicolaihess@gmail.com <mailto:nicolaihess@gmail.com>> wrote: pharo fogbugz issue: 17359 MessageNotUnderstood: receiver of "keywords" is nil
is this valid pragma syntax:
<apicall: bool 'SetCursorPos' (long long) module: 'user32.dll'>
As others have said this is not a valid pragma. A valid pragma is a message expression (a message with no receiver) that has only literal arguments. There is one exception, to accept a variable name for the error code in a primitive invocation.
And as Levente has said it is a goal of the new FFI to get rid of the old syntax you show above.
Thanks Eliot.
I think I will wait what Esteban will say to this, he put those classes in the image, maybe he had a plan for the new ffi/apicall syntax
And as Igor Stasenko discovered /any/ C signature can be written as a literal Array, providing we allow underscores in Symbols (which is a preference). So for example, the heapsort declaration from the standard C library:
int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *))
could be written as a pragma via e.g.
<ffiCCall: #(int heapsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)))>
in which case it is equal to
<ffiCCall: #(#int #heapsort #( #void #* #base #, #size_t #nel #, #size_t #width #, #int #( #* #compar ) #( #const #void #*, #const #void #*)))>
which, while a massive hack, is pretty neat. The only difficulty in parsing the above s that void *, is #void #*, not #void #* #,.
So for me, the natural pragma syntax for the new FFI should be a single keyword starting with ffi that includes the language with which to parse the pragma's argument, followed by a literal Array containing the signature (rather than e.g. a String). I'd also provide a special-purpose pretty-printer for literal arrays that would be used to pretty-print the above, e.g. when decompiling.
This would easily allow extensions such as
<ffiCcall: #(wchar_t * wcschr(const wchar_t *s, wchar_t c)) arg1is: #UnicodeString arg2is: Character>
to guide a marshalling engine in providing automatic checks and conversions.
[Slightly OT] Note that I'm already using this syntax in Alien callbacks because one thing it does is to normalize the signature, eliminating the significance of most whitespace (the #*, above being one example where it fails). So a Callback for heapsort above looks like
voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #IA32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
or voidstarvoidstarRetintARM32: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *)) abi: #ARM32> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Hmmm, if Callback had subclasses for each ABI then the above would become
IA32Callback methods for signature voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien unsignedLongAt: 1)) value: (Alien forPointer: (spAlien unsignedLongAt: 5)))
ARM32Callback methods for signatures voidstarvoidstarRetint: callbackContext sp: spAlien <signature: #(int (*)(const void *, const void *))> ^callbackContext wordResult: (block value: (Alien forPointer: (spAlien registerAt: 1)) value: (Alien forPointer: (spAlien registerAt: 2)))
Much nicer. I shall make it so.
our (pharo) parser can not parse this (does not recognizes the "selector parts" (apicall:module:) right)
Any recommendations how to fix this - fix RBParser or - change this pragma, for example, like this <apicall: #(bool SetCursorPos (long long)) module: 'user32.dll'>
nicolai
_,,,^..^,,,_ best, Eliot
participants (3)
-
Eliot Miranda -
Esteban Lorenzano -
Nicolai Hess