1 ! Copyright (C) 2004, 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays assembler compiler errors generic hashtables
5 inference io kernel kernel-internals math namespaces parser
6 prettyprint sequences strings words ;
8 TUPLE: alien-invoke library function return parameters ;
9 C: alien-invoke make-node ;
11 : alien-invoke-stack ( node -- )
12 dup alien-invoke-parameters length over consume-values
13 dup alien-invoke-return "void" = 0 1 ? swap produce-values ;
15 : alien-invoke-dlsym ( node -- symbol dll )
16 dup alien-invoke-function swap alien-invoke-library
19 TUPLE: alien-invoke-error library symbol ;
21 M: alien-invoke-error summary
22 drop "Words calling ``alien-invoke'' cannot run in the interpreter. Compile the caller word and try again." ;
24 : alien-invoke ( ... return library function parameters -- ... )
25 pick pick <alien-invoke-error> throw ;
27 : ensure-dlsym ( node -- )
28 [ alien-invoke-dlsym dlsym drop ]
29 [ inference-warning ] recover ;
31 \ alien-invoke [ string object string object ] [ ] <effect>
32 "infer-effect" set-word-prop
35 empty-node <alien-invoke> dup node,
36 pop-literal nip over set-alien-invoke-parameters
37 pop-literal nip over set-alien-invoke-function
38 pop-literal nip over set-alien-invoke-library
39 pop-literal nip over set-alien-invoke-return
42 ] "infer" set-word-prop
44 : unbox-parameter ( stack# type -- )
45 c-type [ "reg-class" get "unboxer" get call ] bind ;
47 : unbox-parameters ( parameters -- )
48 [ unbox-parameter ] reverse-each-parameter ;
50 : objects>registers ( parameters -- )
51 #! Generate code for boxing a list of C types, then generate
52 #! code for moving these parameters to register on
53 #! architectures where parameters are passed in registers
56 "save_stacks" f %alien-invoke
57 \ %stack>freg move-parameters ;
59 : box-return ( ctype -- )
60 [ ] [ f swap box-parameter ] if-void ;
62 : generate-invoke-cleanup ( node -- )
63 dup alien-invoke-library library-abi "stdcall" = [
66 alien-invoke-parameters stack-space %cleanup
69 M: alien-invoke generate-node
70 end-basic-block compile-gc
71 dup alien-invoke-parameters objects>registers
72 dup alien-invoke-dlsym %alien-invoke
73 dup generate-invoke-cleanup
74 alien-invoke-return box-return
77 M: alien-invoke stack-reserve*
78 alien-invoke-parameters stack-space ;
80 : parse-arglist ( return seq -- types effect )
82 rot dup "void" = [ drop { } ] [ 1array ] if <effect> ;
84 : (define-c-word) ( type lib func types stack-effect -- )
85 >r over create-in dup reset-generic >r
86 [ alien-invoke ] curry curry curry curry
87 r> swap define-compound word r>
88 "declared-effect" set-word-prop ;
90 : define-c-word ( return library function parameters -- )
91 [ "()" subseq? not ] subset >r pick r> parse-arglist