factor/library/alien/compiler.factor

172 lines
5.0 KiB
Factor
Raw Normal View History

2005-01-23 16:47:28 -05:00
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2004-09-25 16:18:11 -04:00
IN: alien
USING: assembler compiler compiler-backend compiler-frontend
errors generic hashtables inference io kernel lists math
2005-08-24 10:19:09 -04:00
namespaces prettyprint sequences strings words parser ;
! ! ! 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
!
! -libraries:<foo>:name=<soname> -- define a library <foo>, to be
2004-12-25 15:52:08 -05:00
! loaded from the <soname> DLL.
!
! -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-08-23 15:50:32 -04:00
TUPLE: alien-error library symbol ;
2005-04-23 19:34:54 -04:00
M: alien-error error. ( error -- )
"C library interface words cannot be interpreted. " write
"Either the compiler is disabled, " write
"or the " write dup alien-error-library pprint
" library does not define the " write
alien-error-symbol pprint " symbol." print ;
2005-04-23 19:34:54 -04:00
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.
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 -- )
#! 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
: 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-15 23:27:28 -04:00
: incr-param ( reg-class -- )
#! OS X is so ugly.
dup class inc dup float-regs? [
2005-06-15 23:27:28 -04:00
os "macosx" = [
int-regs [ swap float-regs-size 4 / + ] change
] [
drop
] ifte
] [
drop
] ifte ;
: load-parameter ( n parameter -- node )
c-type "reg-class" swap hash
2005-06-15 23:27:28 -04:00
[ [ class get ] keep incr-param ] 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
] with-scope % ;
: 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).
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
] [
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 -- )
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-08-24 10:19:09 -04:00
: unpair ( seq -- odds evens )
2 swap group flip dup empty?
[ drop { } { } ] [ 2unseq ] ifte ;
: parse-arglist ( lst -- types stack effect )
unpair [
" " % [ "," ?tail drop % " " % ] each "-- " %
2005-08-25 15:27:38 -04:00
] "" make ;
2005-08-24 10:19:09 -04:00
: (define-c-word) ( type lib func types stack-effect -- )
>r over create-in >r
[ alien-invoke ] cons cons cons cons r> swap define-compound
word r> "stack-effect" set-word-prop ;
: define-c-word ( type lib func function-args -- )
[ "()" subseq? not ] subset parse-arglist (define-c-word) ;
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 [
pop-literal nip
2005-05-17 16:13:08 -04:00
pop-literal nip >r
pop-literal nip
pop-literal nip -rot
2005-05-17 16:13:08 -04:00
r> swap alien-node
] "infer" set-word-prop
2004-12-13 19:14:03 -05:00
global [
2005-08-25 15:27:38 -04:00
"libraries" get [ {{ }} clone "libraries" set ] unless
2004-12-13 19:14:03 -05:00
] bind
M: compound (uncrossref)
dup word-def \ alien-invoke swap member? [
drop
] [
2005-08-21 23:35:50 -04:00
dup { "infer-effect" "base-case" "no-effect" }
reset-props decompile
] ifte ;