2019-10-18 09:05:04 -04:00
|
|
|
! Copyright (C) 2006, 2007 Slava Pestov.
|
2006-02-11 02:30:18 -05:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
|
IN: alien
|
2019-10-18 09:05:06 -04:00
|
|
|
USING: generator errors generic hashtables inference
|
2019-10-18 09:05:04 -04:00
|
|
|
kernel namespaces sequences strings words parser prettyprint
|
2019-10-18 09:05:06 -04:00
|
|
|
kernel-internals threads libc math ;
|
2006-02-11 02:30:18 -05:00
|
|
|
|
2006-10-16 18:06:34 -04:00
|
|
|
! Callbacks are registered in a global hashtable. If you clear
|
|
|
|
|
! this hashtable, they will all be blown away by code GC, beware
|
|
|
|
|
SYMBOL: callbacks
|
|
|
|
|
|
|
|
|
|
H{ } clone callbacks set-global
|
|
|
|
|
|
|
|
|
|
: register-callback ( word -- ) dup callbacks get set-hash ;
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
TUPLE: alien-callback return parameters abi quot xt ;
|
|
|
|
|
|
2006-02-11 02:30:18 -05:00
|
|
|
C: alien-callback make-node ;
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
M: alien-callback alien-node-parameters alien-callback-parameters ;
|
|
|
|
|
M: alien-callback alien-node-return alien-callback-return ;
|
|
|
|
|
M: alien-callback alien-node-abi alien-callback-abi ;
|
|
|
|
|
|
2006-02-11 02:30:18 -05:00
|
|
|
TUPLE: alien-callback-error ;
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: alien-callback ( return parameters abi quot -- alien )
|
2006-02-11 02:30:18 -05:00
|
|
|
<alien-callback-error> throw ;
|
|
|
|
|
|
2006-09-06 18:06:11 -04:00
|
|
|
M: alien-callback-error summary
|
|
|
|
|
drop "Words calling ``alien-callback'' cannot run in the interpreter. Compile the caller word and try again." ;
|
|
|
|
|
|
2006-02-11 02:30:18 -05:00
|
|
|
: callback-bottom ( node -- )
|
|
|
|
|
alien-callback-xt [ word-xt <alien> ] curry infer-quot ;
|
|
|
|
|
|
|
|
|
|
\ alien-callback [
|
2019-10-18 09:05:06 -04:00
|
|
|
4 ensure-values
|
2006-09-14 16:14:27 -04:00
|
|
|
empty-node <alien-callback> dup node,
|
2006-02-13 17:16:34 -05:00
|
|
|
pop-literal nip over set-alien-callback-quot
|
2019-10-18 09:05:06 -04:00
|
|
|
pop-literal nip over set-alien-callback-abi
|
2006-02-11 02:30:18 -05:00
|
|
|
pop-literal nip over set-alien-callback-parameters
|
|
|
|
|
pop-literal nip over set-alien-callback-return
|
2006-10-16 18:06:34 -04:00
|
|
|
gensym dup register-callback over set-alien-callback-xt
|
2006-02-11 02:30:18 -05:00
|
|
|
callback-bottom
|
|
|
|
|
] "infer" set-word-prop
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: box-parameters ( node -- )
|
|
|
|
|
alien-node-parameters* [ box-parameter ] each-parameter ;
|
2006-02-13 22:20:39 -05:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: registers>objects ( node -- )
|
|
|
|
|
[
|
|
|
|
|
dup \ %save-param-reg move-parameters
|
|
|
|
|
"nest_stacks" f %alien-invoke
|
|
|
|
|
box-parameters
|
|
|
|
|
] with-param-regs ;
|
2006-02-14 23:23:08 -05:00
|
|
|
|
2019-10-18 09:05:04 -04:00
|
|
|
TUPLE: callback-context ;
|
|
|
|
|
|
|
|
|
|
: current-callback 0 getenv ;
|
|
|
|
|
|
|
|
|
|
: wait-to-return ( token -- )
|
|
|
|
|
dup current-callback eq? [
|
|
|
|
|
drop
|
|
|
|
|
] [
|
|
|
|
|
yield wait-to-return
|
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
|
|
: do-callback ( quot token -- )
|
|
|
|
|
init-error-handler
|
|
|
|
|
dup 0 setenv
|
|
|
|
|
slip
|
|
|
|
|
wait-to-return ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: prepare-callback-return ( ctype -- quot )
|
|
|
|
|
alien-node-return {
|
|
|
|
|
{ [ dup "void" = ] [ drop [ ] ] }
|
|
|
|
|
{ [ dup large-struct? ] [ heap-size [ memcpy ] curry ] }
|
|
|
|
|
{ [ t ] [ c-type c-type-prep ] }
|
|
|
|
|
} cond ;
|
|
|
|
|
|
|
|
|
|
: wrap-callback-quot ( node -- quot )
|
2006-11-03 19:05:53 -05:00
|
|
|
[
|
2019-10-18 09:05:06 -04:00
|
|
|
dup alien-callback-quot
|
|
|
|
|
swap prepare-callback-return append ,
|
|
|
|
|
[ <callback-context> do-callback ] %
|
2006-11-03 19:05:53 -05:00
|
|
|
] [ ] make ;
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: %unnest-stacks ( -- ) "unnest_stacks" f %alien-invoke ;
|
|
|
|
|
|
|
|
|
|
: callback-unwind ( node -- n )
|
|
|
|
|
{
|
|
|
|
|
{ [ dup alien-node-abi "stdcall" = ] [ alien-stack-frame ] }
|
|
|
|
|
{ [ dup alien-node-return large-struct? ] [ drop 4 ] }
|
|
|
|
|
{ [ t ] [ drop 0 ] }
|
|
|
|
|
} cond ;
|
|
|
|
|
|
|
|
|
|
: %callback-return ( node -- )
|
|
|
|
|
#! All the extra book-keeping for %unwind is only for x86.
|
|
|
|
|
#! On other platforms its an alias for %return.
|
|
|
|
|
dup alien-node-return*
|
|
|
|
|
[ %unnest-stacks ] [ %callback-value ] if-void
|
|
|
|
|
callback-unwind %unwind ;
|
|
|
|
|
|
2006-04-28 18:38:48 -04:00
|
|
|
: generate-callback ( node -- )
|
2019-10-18 09:05:06 -04:00
|
|
|
dup alien-callback-xt dup rot [
|
|
|
|
|
init-templates
|
|
|
|
|
dup registers>objects
|
|
|
|
|
dup wrap-callback-quot %alien-callback
|
|
|
|
|
%callback-return
|
2006-08-10 01:05:12 -04:00
|
|
|
] generate-1 ;
|
2006-02-11 02:30:18 -05:00
|
|
|
|
2006-08-15 03:01:24 -04:00
|
|
|
M: alien-callback generate-node
|
2006-11-03 00:48:43 -05:00
|
|
|
end-basic-block generate-callback iterate-next ;
|
2006-03-07 19:53:58 -05:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
M: alien-callback stack-frame-size* alien-stack-frame ;
|