> The test constructs an NSRect with x=1.0, y=2.0, w=101.0, h=102.0,  
> and sends it through a message call to a Factor-defined objc class.  
> On the other end it shows up with x=101.0, y=102.0, w=101.0,  
> h=102.0. I observed this same behavior while debugging calls into  
> AppKit; NSView frame rects were showing up with the origin equal to  
> the size, so the problem appears to be on the alien invocation side.

Actually, I take that back--the problem is in the callback mechanism.  
I was able to reproduce it with this non-cocoa-specific test case:
-- 8< --
USING: alien.c-types alien.syntax alien ;

C-STRUCT: foo { "double" "a" } { "double" "b" } { "double" "c" }  
{ "double" "d" } ;

: <foo> ( a b c d -- foo )
     "foo" <c-object>
     { [ set-foo-d ] [ set-foo-c ] [ set-foo-b ] [ set-foo-a ] [ ] }  
cleave ;

: >foo< ( foo -- a b c d )
     { [ foo-a ] [ foo-b ] [ foo-c ] [ foo-d ] } cleave ;

: foo-callback ( -- alien )
     "void" { "void*" "void*" "foo" } "cdecl"
     [ "example" set-global 2drop ] alien-callback ;
: foo-frob ( arg -- arg' )
     f f rot
     foo-callback
     "void" { "void*" "void*" "foo" } "cdecl" alien-indirect
     "example" get-global ;

[ 1.0 2.0 3.0 4.0 ]
[ 1.0 2.0 3.0 4.0 <foo> foo-frob >foo< ] unit-test # Gives 3.0 4.0 3.0  
4.0 on x86-64
-- 8< --

Going back to the "cocoa" test suite, I walked through the -[Foo foo:]  
callback in gdb. A disassembly is at the end of this message. At  
0x0000000108ed7933, it copies the NSRect struct off of the calling  
stack frame ( 0x50(%rsp) ) to 0x10(%rsp). This is the proper location  
of the NSRect parameter in the stack. However, at 0x0000000108ed7995  
it's passing 0x60(%rsp) as an argument to some function call, which is  
0x10 offset from the actual position of the parameter in the stack.

I'm not too familiar with the internals of the Factor code generator,  
but I'm guessing that one of the following two things is happening here:

- It's taking into account the size of the callback's "self" and  
"method" arguments when calculating the offset of "rect", even though  
the former two arguments are passed by register on x86-64, or
- It should be referencing relative to the stack frame that the  
generated code builds at (%rsp), where the register parameters have  
been included on the stack alongside the stack parameters, but is  
mistakenly reaching at the original stack frame at 0x50(%rsp) while  
applying the offset as if it were looking in (%rsp).

-Joe

Here's the disassembly referenced above:

0x0000000108ed7920:     pushq  $0x50
0x0000000108ed7925:     push   %rbx
0x0000000108ed7926:     sub    $0x38,%rsp
0x0000000108ed792a:     mov    %rdi,(%rsp)
0x0000000108ed792e:     mov    %rsi,0x8(%rsp)
0x0000000108ed7933:     mov    0x50(%rsp),%rbx
0x0000000108ed7938:     mov    %rbx,0x10(%rsp)
0x0000000108ed793d:     mov    0x58(%rsp),%rbx
0x0000000108ed7942:     mov    %rbx,0x18(%rsp)
0x0000000108ed7947:     mov    0x60(%rsp),%rbx
0x0000000108ed794c:     mov    %rbx,0x20(%rsp)
0x0000000108ed7951:     mov    0x68(%rsp),%rbx
0x0000000108ed7956:     mov    %rbx,0x28(%rsp)
0x0000000108ed795b:     mov    $0x100018660,%rbx
0x0000000108ed7965:     rex.W callq  *%rbx
0x0000000108ed7968:     mov    (%rsp),%rdi
0x0000000108ed796c:     mov    $0x100006810,%rbx
0x0000000108ed7976:     rex.W callq  *%rbx
0x0000000108ed7979:     mov    0x8(%rsp),%rdi
0x0000000108ed797e:     mov    $0x100006810,%rbx
0x0000000108ed7988:     rex.W callq  *%rbx
0x0000000108ed798b:     mov    $0x20,%rsi
0x0000000108ed7995:     lea    0x60(%rsp),%rdi
0x0000000108ed799a:     mov    $0x100006010,%rbx
0x0000000108ed79a4:     rex.W callq  *%rbx
0x0000000108ed79a7:     mov    0x6a(%rip),%rdi        # 0x108ed7a18
0x0000000108ed79ae:     mov    $0x100005fcc,%rbx
0x0000000108ed79b8:     rex.W callq  *%rbx
0x0000000108ed79bb:     mov    $0x100018370,%rbx
0x0000000108ed79c5:     rex.W callq  *%rbx
0x0000000108ed79c8:     add    $0x48,%rsp
0x0000000108ed79cc:     retq


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Factor-talk mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/factor-talk

Reply via email to