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

Répondre à