Hi Mahieu,
On 13 Apr 2011, at 13:04, Mathieu Suen wrote:
> Hi David
>
> Sorry I think I was not understandable.
No problem.
> For example in Smalltalk I want to send the message
> #initWithContentRectPointer:styleMask:backing:defer:
> to a NSWindow
>
> So in smalltalk I have something similar to:
>
> nsWindowClass := Objc.ObjcRuntime at: 'NSWindow'.
Okay, this is a little bit weird. Why are you not simply bridging Objective-C
classes to Smalltalk classes? I would expect every Objective-C object to be
implemented as a proxy on the Smalltalk side, and vice versa (at least, that's
how Damien and I did it).
> nsWindow := nsWindowClass alloc.
> nsWindow send: #initWithContentRectPointer:styleMask:backing:defer:
> with: {nsRect. 15. Objc.ObjcAppKit nsBackingStoreBuffered. 1}.
The same with the messaging, but I guess this is jut an early prototype?
> The method #send:with: is just calling the function LKSendMessage.
> In gnu-smalltalk the c-call-out mechanism transform the Smallinteger to the
> C-integer (unsing right-shift...)
Okay, this is the problem, and it's not limited to integers. The LKSendMessage
code is expected to be called from LanguageKit code, where everything is an
object. It expects every parameter to be an Objective-C object (in the
interpreter, there are no SmallInts, they are currently only used by the
compiler), so it expects to be able to send messages to everything that it
receives.
> But LKSendMessage is unboxing each parameter before doing the ffi call to the
> objc runtime:
>
> for (i = 0; i < argc; i++)
> {
> const char *objCType = [sig getArgumentTypeAtIndex: i + 2];
> UnboxValue(args[i], unboxedArgumentsBuffer[i + 2], objCType);
> unboxedArguments[i + 2] = unboxedArgumentsBuffer[i + 2];
> }
>
> So the first parameter "args[i]" of the UnboxValue call is an plain
> c-integer
> which is not what UnboxValue is expecting.
> The call to [value unsignedIntValue] fail.
The same call will fail on every other message send from the Objective-C code.
For example, what happens when you try to pass a smalltalk object as the
argument to -setDelegate:?
The problem that you are encountering is that you have started at the end, not
the beginning. The absolute first thing that you need to do when bridging
Objective-C and Smalltalk is work out how you are going to map between
Objective-C and Smalltalk objects. In Pragmatic Smalltalk, this is easy - we
use the same underlying representation for both, so any object can receive
messages sent in the same way, irrespective of whether those messages are
implemented by methods written in Objective-C[++], Smalltalk, EScript, OMeta,
or whatever.
In your case, since you are trying to use two semantically similar but distinct
object models in the same code, you probably need to generate Objective-C
proxies for everything that's passed from the Smalltalk side, and Smalltalk
proxies for everything passed from the Objective-C side. Once this is done,
the message sending is the easy part. Your Smalltalk proxy just implements
#doesNotUnderstand: and calls LKMessageSend, generating Objective-C proxies for
all of the objects that are passed across[1]. The Objective-C proxy just
implements -forwardInvocation: and calls into GST, generating Smalltalk proxies
for each of the arguments.
David
[1] You may want some special casing here for SmallInts, so they're actually
passed as SmallInts can can be handled by boxing in the ObjC side. You also
need some kind of dictionary on both sides ensuring that the same object being
passed twice gives the same proxy.
_______________________________________________
Etoile-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-discuss