Fix some problems with callbacks
parent
40c1529ce8
commit
ae3c4ae1b6
|
@ -332,9 +332,12 @@ M: #terminate emit-node
|
||||||
[ alien-parameters parameter-sizes drop >>params ] bi
|
[ alien-parameters parameter-sizes drop >>params ] bi
|
||||||
dup [ params>> ] [ return>> ] bi + >>size ;
|
dup [ params>> ] [ return>> ] bi + >>size ;
|
||||||
|
|
||||||
|
: alien-stack-frame ( params -- )
|
||||||
|
<alien-stack-frame> ##stack-frame ;
|
||||||
|
|
||||||
: emit-alien-node ( node quot -- next )
|
: emit-alien-node ( node quot -- next )
|
||||||
[ params>> ] dip
|
finalize-phantoms
|
||||||
[ drop <alien-stack-frame> ##stack-frame ] [ call ] 2bi
|
[ params>> ] dip [ drop alien-stack-frame ] [ call ] 2bi
|
||||||
iterate-next ; inline
|
iterate-next ; inline
|
||||||
|
|
||||||
M: #alien-invoke emit-node
|
M: #alien-invoke emit-node
|
||||||
|
@ -347,7 +350,10 @@ M: #alien-callback emit-node
|
||||||
dup params>> xt>> dup
|
dup params>> xt>> dup
|
||||||
[
|
[
|
||||||
init-phantoms
|
init-phantoms
|
||||||
[ ##alien-callback ] emit-alien-node drop
|
##prologue
|
||||||
|
dup [ ##alien-callback ] emit-alien-node drop
|
||||||
|
##epilogue
|
||||||
|
params>> ##callback-return
|
||||||
] with-cfg-builder
|
] with-cfg-builder
|
||||||
iterate-next ;
|
iterate-next ;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ INSN: ##gc ;
|
||||||
INSN: ##alien-invoke params ;
|
INSN: ##alien-invoke params ;
|
||||||
INSN: ##alien-indirect params ;
|
INSN: ##alien-indirect params ;
|
||||||
INSN: ##alien-callback params ;
|
INSN: ##alien-callback params ;
|
||||||
|
INSN: ##callback-return params ;
|
||||||
|
|
||||||
GENERIC: defs-vregs ( insn -- seq )
|
GENERIC: defs-vregs ( insn -- seq )
|
||||||
GENERIC: uses-vregs ( insn -- seq )
|
GENERIC: uses-vregs ( insn -- seq )
|
||||||
|
|
|
@ -428,23 +428,14 @@ TUPLE: callback-context ;
|
||||||
|
|
||||||
: %unnest-stacks ( -- ) "unnest_stacks" f %alien-invoke ;
|
: %unnest-stacks ( -- ) "unnest_stacks" f %alien-invoke ;
|
||||||
|
|
||||||
: callback-unwind ( params -- n )
|
M: ##callback-return generate-insn
|
||||||
{
|
|
||||||
{ [ dup abi>> "stdcall" = ] [ <alien-stack-frame> size>> ] }
|
|
||||||
{ [ dup return>> large-struct? ] [ drop 4 ] }
|
|
||||||
[ drop 0 ]
|
|
||||||
} cond ;
|
|
||||||
|
|
||||||
: %callback-return ( params -- )
|
|
||||||
#! All the extra book-keeping for %unwind is only for x86.
|
#! All the extra book-keeping for %unwind is only for x86.
|
||||||
#! On other platforms its an alias for %return.
|
#! On other platforms its an alias for %return.
|
||||||
dup alien-return
|
params>> %callback-return ;
|
||||||
[ %unnest-stacks ] [ %callback-value ] if-void
|
|
||||||
callback-unwind %unwind ;
|
|
||||||
|
|
||||||
M: ##alien-callback generate-insn
|
M: ##alien-callback generate-insn
|
||||||
params>>
|
params>>
|
||||||
[ registers>objects ]
|
[ registers>objects ]
|
||||||
[ wrap-callback-quot %alien-callback ]
|
[ wrap-callback-quot %alien-callback ]
|
||||||
[ %callback-return ]
|
[ alien-return [ %unnest-stacks ] [ %callback-value ] if-void ]
|
||||||
tri ;
|
tri ;
|
||||||
|
|
|
@ -137,14 +137,18 @@ M: object %prepare-var-args ;
|
||||||
|
|
||||||
HOOK: %alien-invoke cpu ( function library -- )
|
HOOK: %alien-invoke cpu ( function library -- )
|
||||||
|
|
||||||
HOOK: %cleanup cpu ( alien-node -- )
|
HOOK: %cleanup cpu ( params -- )
|
||||||
|
|
||||||
|
M: object %cleanup ( params -- ) drop ;
|
||||||
|
|
||||||
HOOK: %alien-callback cpu ( quot -- )
|
HOOK: %alien-callback cpu ( quot -- )
|
||||||
|
|
||||||
HOOK: %callback-value cpu ( ctype -- )
|
HOOK: %callback-value cpu ( ctype -- )
|
||||||
|
|
||||||
! Return to caller with stdcall unwinding (only for x86)
|
! Return to caller with stdcall unwinding (only for x86)
|
||||||
HOOK: %unwind cpu ( n -- )
|
HOOK: %callback-return cpu ( params -- )
|
||||||
|
|
||||||
|
M: object %callback-return drop %return ;
|
||||||
|
|
||||||
HOOK: %prepare-alien-indirect cpu ( -- )
|
HOOK: %prepare-alien-indirect cpu ( -- )
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,6 @@ M: ppc %dispatch-label ( word -- )
|
||||||
|
|
||||||
M: ppc %return ( -- ) %epilogue-later BLR ;
|
M: ppc %return ( -- ) %epilogue-later BLR ;
|
||||||
|
|
||||||
M: ppc %unwind drop %return ;
|
|
||||||
|
|
||||||
M: ppc %peek ( vreg loc -- )
|
M: ppc %peek ( vreg loc -- )
|
||||||
>r v>operand r> loc>operand LWZ ;
|
>r v>operand r> loc>operand LWZ ;
|
||||||
|
|
||||||
|
@ -267,8 +265,6 @@ M: ppc %callback-value ( ctype -- )
|
||||||
! Unbox former top of data stack to return registers
|
! Unbox former top of data stack to return registers
|
||||||
unbox-return ;
|
unbox-return ;
|
||||||
|
|
||||||
M: ppc %cleanup ( alien-node -- ) drop ;
|
|
||||||
|
|
||||||
: %untag ( src dest -- ) 0 0 31 tag-bits get - RLWINM ;
|
: %untag ( src dest -- ) 0 0 31 tag-bits get - RLWINM ;
|
||||||
|
|
||||||
: %tag-fixnum ( src dest -- ) tag-bits get SLWI ;
|
: %tag-fixnum ( src dest -- ) tag-bits get SLWI ;
|
||||||
|
|
|
@ -244,7 +244,7 @@ M: x86.32 %callback-value ( ctype -- )
|
||||||
! Unbox EAX
|
! Unbox EAX
|
||||||
unbox-return ;
|
unbox-return ;
|
||||||
|
|
||||||
M: x86.32 %cleanup ( alien-node -- )
|
M: x86.32 %cleanup ( params -- )
|
||||||
#! a) If we just called an stdcall function in Windows, it
|
#! a) If we just called an stdcall function in Windows, it
|
||||||
#! cleaned up the stack frame for us. But we don't want that
|
#! cleaned up the stack frame for us. But we don't want that
|
||||||
#! so we 'undo' the cleanup since we do that in %epilogue.
|
#! so we 'undo' the cleanup since we do that in %epilogue.
|
||||||
|
@ -261,7 +261,16 @@ M: x86.32 %cleanup ( alien-node -- )
|
||||||
[ drop ]
|
[ drop ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
M: x86.32 %unwind ( n -- ) RET ;
|
M: x86.32 %callback-return ( n -- )
|
||||||
|
#! a) If the callback is stdcall, we have to clean up the
|
||||||
|
#! caller's stack frame.
|
||||||
|
#! b) If the callback is returning a large struct, we have
|
||||||
|
#! to fix ESP.
|
||||||
|
{
|
||||||
|
{ [ dup abi>> "stdcall" = ] [ <alien-stack-frame> size>> ] }
|
||||||
|
{ [ dup return>> large-struct? ] [ drop 4 ] }
|
||||||
|
[ drop 0 ]
|
||||||
|
} cond RET ;
|
||||||
|
|
||||||
os windows? [
|
os windows? [
|
||||||
cell "longlong" c-type (>>align)
|
cell "longlong" c-type (>>align)
|
||||||
|
|
|
@ -222,10 +222,6 @@ M: x86.64 %callback-value ( ctype -- )
|
||||||
! Unbox former top of data stack to return registers
|
! Unbox former top of data stack to return registers
|
||||||
unbox-return ;
|
unbox-return ;
|
||||||
|
|
||||||
M: x86.64 %cleanup ( alien-node -- ) drop ;
|
|
||||||
|
|
||||||
M: x86.64 %unwind ( n -- ) drop 0 RET ;
|
|
||||||
|
|
||||||
USE: cpu.x86.intrinsics
|
USE: cpu.x86.intrinsics
|
||||||
|
|
||||||
! On 64-bit systems, the result of reading 4 bytes from memory
|
! On 64-bit systems, the result of reading 4 bytes from memory
|
||||||
|
|
|
@ -100,7 +100,7 @@ M:: x86 %box-alien ( dst src temp -- )
|
||||||
dst 3 alien@ src MOV
|
dst 3 alien@ src MOV
|
||||||
"end" get JMP
|
"end" get JMP
|
||||||
"f" resolve-label
|
"f" resolve-label
|
||||||
\ f tag-number MOV
|
dst \ f tag-number MOV
|
||||||
"end" resolve-label
|
"end" resolve-label
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ M: x86 small-enough? ( n -- ? )
|
||||||
|
|
||||||
: %tag-fixnum ( reg -- ) tag-bits get SHL ;
|
: %tag-fixnum ( reg -- ) tag-bits get SHL ;
|
||||||
|
|
||||||
M: x86 %return ( -- ) 0 %unwind ;
|
M: x86 %return ( -- ) 0 RET ;
|
||||||
|
|
||||||
! Alien intrinsics
|
! Alien intrinsics
|
||||||
M: x86 %unbox-byte-array ( dst src -- )
|
M: x86 %unbox-byte-array ( dst src -- )
|
||||||
|
|
Loading…
Reference in New Issue