2005-01-23 16:47:28 -05:00
|
|
|
! Copyright (C) 2004, 2005 Slava Pestov.
|
2005-01-30 15:57:25 -05:00
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2004-09-25 16:18:11 -04:00
|
|
|
IN: alien
|
2005-06-14 05:01:07 -04:00
|
|
|
USING: assembler compiler compiler-backend compiler-frontend
|
|
|
|
errors generic hashtables inference kernel lists math namespaces
|
|
|
|
sequences stdio strings unparser words ;
|
2005-03-26 20:12:14 -05:00
|
|
|
|
|
|
|
! ! ! WARNING ! ! !
|
|
|
|
! Reloading this file into a running Factor instance on Win32
|
|
|
|
! or Unix with FFI I/O will bomb the runtime, since I/O words
|
|
|
|
! would become uncompiled, and FFI calls can only be made from
|
|
|
|
! compiled code.
|
|
|
|
|
|
|
|
! USAGE:
|
|
|
|
!
|
|
|
|
! Command line parameters given to the runtime specify libraries
|
|
|
|
! to load.
|
2004-12-25 15:52:08 -05:00
|
|
|
!
|
2005-02-10 17:32:39 -05:00
|
|
|
! -libraries:<foo>:name=<soname> -- define a library <foo>, to be
|
2004-12-25 15:52:08 -05:00
|
|
|
! loaded from the <soname> DLL.
|
|
|
|
!
|
2005-02-10 17:32:39 -05:00
|
|
|
! -libraries:<foo>:abi=stdcall -- define a library using the
|
2004-12-25 15:52:08 -05:00
|
|
|
! stdcall ABI. This ABI is usually used on Win32. Any other abi
|
|
|
|
! parameter, or a missing abi parameter indicates the cdecl ABI
|
|
|
|
! should be used, which is common on Unix.
|
2004-09-25 16:18:11 -04:00
|
|
|
|
2005-04-23 19:34:54 -04:00
|
|
|
! FFI code does not run in the interpreter.
|
|
|
|
|
2005-04-30 00:43:39 -04:00
|
|
|
TUPLE: alien-error symbol library ;
|
2005-04-23 19:34:54 -04:00
|
|
|
|
2005-04-30 00:43:39 -04:00
|
|
|
C: alien-error ( lib sym -- )
|
|
|
|
[ set-alien-error-symbol ] keep
|
|
|
|
[ set-alien-error-library ] keep ;
|
2005-04-23 19:34:54 -04:00
|
|
|
|
|
|
|
M: alien-error error. ( error -- )
|
|
|
|
[
|
2005-04-30 00:43:39 -04:00
|
|
|
"C library interface words cannot be interpreted. " %
|
|
|
|
"Either the compiler is disabled, " %
|
|
|
|
"or the " % dup alien-error-library unparse %
|
|
|
|
" library does not define the " %
|
|
|
|
alien-error-symbol unparse %
|
|
|
|
" symbol." %
|
2005-04-23 19:34:54 -04:00
|
|
|
] make-string print ;
|
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: alien-invoke ( ... return library function parameters -- ... )
|
2005-04-23 19:34:54 -04:00
|
|
|
#! Call a C library function.
|
2005-05-17 16:13:08 -04:00
|
|
|
#! 'return' is a type spec, and 'parameters' is a list of
|
2005-04-23 19:34:54 -04:00
|
|
|
#! type specs. 'library' is an entry in the "libraries"
|
|
|
|
#! namespace.
|
2005-04-30 00:43:39 -04:00
|
|
|
drop <alien-error> throw ;
|
2005-04-23 19:34:54 -04:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
TUPLE: alien-node return parameters ;
|
|
|
|
C: alien-node make-node ;
|
2005-04-23 19:34:54 -04:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: set-alien-return ( return node -- )
|
|
|
|
2dup set-alien-node-return
|
|
|
|
swap "void" = [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
[ object ] produce-d 1 0 rot node-outputs
|
|
|
|
] ifte ;
|
2004-12-25 15:52:08 -05:00
|
|
|
|
|
|
|
: set-alien-parameters ( parameters node -- )
|
2005-05-17 16:13:08 -04:00
|
|
|
2dup set-alien-node-parameters
|
|
|
|
>r [ drop object ] map dup dup ensure-d
|
|
|
|
length 0 r> node-inputs consume-d ;
|
2004-12-25 15:52:08 -05:00
|
|
|
|
2005-05-05 03:12:37 -04:00
|
|
|
: ensure-dlsym ( symbol library -- ) load-library dlsym drop ;
|
2005-03-29 19:11:10 -05:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: alien-node ( return params function library -- )
|
2005-03-20 19:05:57 -05:00
|
|
|
#! We should fail if the library does not exist, so that
|
|
|
|
#! compilation does not keep trying to compile FFI words
|
|
|
|
#! over and over again if the library is not loaded.
|
2005-03-29 19:11:10 -05:00
|
|
|
2dup ensure-dlsym
|
2005-05-17 16:13:08 -04:00
|
|
|
cons param-node <alien-node>
|
2004-12-25 15:52:08 -05:00
|
|
|
[ set-alien-parameters ] keep
|
2005-05-17 16:13:08 -04:00
|
|
|
[ set-alien-return ] keep
|
|
|
|
node, ;
|
2004-12-25 15:52:08 -05:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: parameters alien-node-parameters reverse ;
|
2005-04-23 19:34:06 -04:00
|
|
|
|
2005-06-14 20:54:11 -04:00
|
|
|
: c-aligned c-size cell align ;
|
|
|
|
|
2005-04-23 19:34:06 -04:00
|
|
|
: stack-space ( parameters -- n )
|
2005-06-14 20:54:11 -04:00
|
|
|
0 swap [ c-aligned + ] each ;
|
2005-04-23 19:34:06 -04:00
|
|
|
|
2005-06-14 19:10:48 -04:00
|
|
|
: unbox-parameter ( n parameter -- node )
|
|
|
|
c-type [ "unboxer" get "reg-class" get ] bind %unbox ;
|
2004-12-13 19:14:03 -05:00
|
|
|
|
2005-06-14 20:54:11 -04:00
|
|
|
: unbox-parameters ( params -- )
|
|
|
|
[ stack-space ] keep
|
|
|
|
[ [ c-aligned - dup ] keep unbox-parameter ] map nip % ;
|
2005-06-14 19:10:48 -04:00
|
|
|
|
|
|
|
: load-parameter ( n parameter -- node )
|
|
|
|
c-type "reg-class" swap hash
|
|
|
|
[ class dup get dup 1 + rot set ] keep
|
|
|
|
%parameter ;
|
|
|
|
|
|
|
|
: load-parameters ( params -- )
|
|
|
|
[
|
|
|
|
0 int-regs set
|
|
|
|
0 float-regs set
|
|
|
|
reverse 0 swap
|
2005-06-14 20:54:11 -04:00
|
|
|
[ 2dup load-parameter >r c-aligned + r> ] map nip
|
2005-06-14 19:10:48 -04:00
|
|
|
] with-scope % ;
|
2005-06-14 05:01:07 -04:00
|
|
|
|
|
|
|
: linearize-parameters ( parameters -- )
|
2005-04-23 19:34:06 -04:00
|
|
|
#! Generate code for boxing a list of C types, then generate
|
|
|
|
#! code for moving these parameters to register on
|
|
|
|
#! architectures where parameters are passed in registers
|
|
|
|
#! (PowerPC).
|
2005-06-14 05:01:07 -04:00
|
|
|
dup stack-space %parameters ,
|
2005-06-14 20:54:11 -04:00
|
|
|
dup unbox-parameters load-parameters ;
|
2004-12-13 19:14:03 -05:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
: linearize-return ( return -- )
|
|
|
|
alien-node-return dup "void" = [
|
2004-12-13 19:14:03 -05:00
|
|
|
drop
|
|
|
|
] [
|
2005-06-14 05:01:07 -04:00
|
|
|
c-type [ "boxer" get "reg-class" get ] bind %box ,
|
2004-12-13 19:14:03 -05:00
|
|
|
] ifte ;
|
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
M: alien-node linearize-node* ( node -- )
|
2005-06-14 05:01:07 -04:00
|
|
|
dup parameters linearize-parameters
|
|
|
|
dup node-param dup uncons %alien-invoke ,
|
|
|
|
cdr library-abi "stdcall" =
|
|
|
|
[ dup parameters stack-space %cleanup , ] unless
|
2005-05-17 16:13:08 -04:00
|
|
|
linearize-return ;
|
2005-03-29 19:11:10 -05:00
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
\ alien-invoke [ [ string object string general-list ] [ ] ]
|
2005-03-29 19:11:10 -05:00
|
|
|
"infer-effect" set-word-prop
|
|
|
|
|
2005-05-17 16:13:08 -04:00
|
|
|
\ alien-invoke [
|
2005-05-14 00:23:00 -04:00
|
|
|
pop-literal nip
|
2005-05-17 16:13:08 -04:00
|
|
|
pop-literal nip >r
|
2005-05-14 00:23:00 -04:00
|
|
|
pop-literal nip
|
|
|
|
pop-literal nip -rot
|
2005-05-17 16:13:08 -04:00
|
|
|
r> swap alien-node
|
|
|
|
] "infer" set-word-prop
|
2005-05-13 20:37:28 -04:00
|
|
|
|
2004-12-13 19:14:03 -05:00
|
|
|
global [
|
|
|
|
"libraries" get [ <namespace> "libraries" set ] unless
|
|
|
|
] bind
|