some FFI cleanups

cvs
Slava Pestov 2004-12-25 20:52:08 +00:00
parent 4b92b047ed
commit 0deedd48f9
8 changed files with 95 additions and 45 deletions

View File

@ -38,6 +38,17 @@ USE: namespaces
USE: parser USE: parser
USE: words USE: words
USE: hashtables USE: hashtables
USE: strings
! Command line parameters specify libraries to load.
!
! -library:<foo>:name=<soname> -- define a library <foo>, to be
! loaded from the <soname> DLL.
!
! -library:<foo>:abi=stdcall -- define a library using the
! 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.
BUILTIN: dll 15 BUILTIN: dll 15
BUILTIN: alien 16 BUILTIN: alien 16
@ -56,8 +67,8 @@ M: alien = ( obj obj -- ? )
2drop f 2drop f
] ifte ; ] ifte ;
: (library) ( name -- object ) : library ( name -- object )
"libraries" get hash ; dup [ "libraries" get hash ] when ;
: load-dll ( library -- dll ) : load-dll ( library -- dll )
"dll" get dup [ "dll" get dup [
@ -72,7 +83,6 @@ M: alien = ( obj obj -- ? )
] extend put ] extend put
] bind ; ] bind ;
SYMBOL: #c-invoke ( C ABI -- Unix and some Windows libs )
SYMBOL: #cleanup ( unwind stack by parameter ) SYMBOL: #cleanup ( unwind stack by parameter )
SYMBOL: #c-call ( jump to raw address ) SYMBOL: #c-call ( jump to raw address )
@ -80,74 +90,81 @@ SYMBOL: #c-call ( jump to raw address )
SYMBOL: #unbox ( move top of datastack to C stack ) SYMBOL: #unbox ( move top of datastack to C stack )
SYMBOL: #box ( move EAX to datastack ) SYMBOL: #box ( move EAX to datastack )
SYMBOL: #std-invoke ( stdcall ABI -- Win32 ) : library-abi ( library -- abi )
library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ;
: abi ( -- abi ) : alien-symbol ( function library -- address )
"abi" get "stdcall" = #std-invoke #c-invoke ? ; library [ [ load-dll ] bind dlsym ] [ dlsym-self ] ifte* ;
: alien-function ( function library -- address abi ) SYMBOL: #alien-invoke
[
(library) [ load-dll dlsym abi ] bind
] [
dlsym-self #c-invoke
] ifte* ;
! These are set in the #c-invoke and #std-invoke dataflow IR ! These are set in the #alien-invoke dataflow IR node.
! nodes.
SYMBOL: alien-returns SYMBOL: alien-returns
SYMBOL: alien-parameters SYMBOL: alien-parameters
: set-alien-returns ( returns node -- )
[ dup alien-returns set ] bind
"void" = [
[ object ] produce-d 1 0 node-outputs
] unless ;
: set-alien-parameters ( parameters node -- )
[ dup alien-parameters set ] bind
[ drop object ] map dup dup ensure-d
length 0 node-inputs consume-d ;
: alien-node ( returns params function library -- )
cons #alien-invoke dataflow,
[ set-alien-parameters ] keep
set-alien-returns ;
: infer-alien ( -- ) : infer-alien ( -- )
[ object object object object ] ensure-d [ object object object object ] ensure-d
dataflow-drop, pop-d literal-value dataflow-drop, pop-d literal-value
dataflow-drop, pop-d literal-value >r
dataflow-drop, pop-d literal-value dataflow-drop, pop-d literal-value
dataflow-drop, pop-d literal-value alien-function >r dataflow-drop, pop-d literal-value -rot
dataflow-drop, pop-d literal-value swap r> swap alien-node ;
r> dataflow, [
alien-returns set
alien-parameters set
] bind ;
: unbox-parameter ( function -- ) : box-parameter
dlsym-self #unbox swons , ; c-type [
"width" get cell align
"unboxer" get
] bind #unbox swons , ;
: linearize-parameters ( params -- count ) : linearize-parameters ( params -- count )
#! Generate code for boxing a list of C types. #! Generate code for boxing a list of C types.
#! Return amount stack must be unwound by. #! Return amount stack must be unwound by.
[ alien-parameters get reverse ] bind 0 swap [ [ alien-parameters get reverse ] bind 0 swap [
c-type [ box-parameter +
"width" get cell align +
"unboxer" get
] bind unbox-parameter
] each ; ] each ;
: box-parameter ( function -- )
dlsym-self #box swons , ;
: linearize-returns ( returns -- ) : linearize-returns ( returns -- )
[ alien-returns get ] bind dup "void" = [ [ alien-returns get ] bind dup "void" = [
drop drop
] [ ] [
c-type [ "boxer" get ] bind box-parameter c-type [ "boxer" get ] bind #box swons ,
] ifte ; ] ifte ;
: linearize-alien ( node -- ) : linearize-alien ( node -- )
dup linearize-parameters >r dup linearize-parameters >r
dup [ node-param get ] bind #c-call swons , dup [ node-param get ] bind #c-call swons ,
dup [ node-op get #c-invoke = ] bind dup [ node-param get car "stdcall" = ] bind
r> swap [ #cleanup swons , ] [ drop ] ifte r> swap [ drop ] [ #cleanup swons , ] ifte
linearize-returns ; linearize-returns ;
#c-invoke [ linearize-alien ] "linearizer" set-word-property #alien-invoke [ linearize-alien ] "linearizer" set-word-property
#std-invoke [ linearize-alien ] "linearizer" set-word-property
: alien-invoke ( ... returns library function parameters -- ... ) : alien-invoke ( ... returns library function parameters -- ... )
#! Call a C library function. #! Call a C library function.
#! 'returns' is a type spec, and 'parameters' is a list of #! 'returns' is a type spec, and 'parameters' is a list of
#! type specs. 'library' is an entry in the "libraries" #! type specs. 'library' is an entry in the "libraries"
#! namespace. #! namespace.
"alien-invoke cannot be interpreted." throw ; [
"alien-invoke cannot be interpreted. " ,
"Either the compiler is disabled, " ,
"or the ``" , rot , "'' library is missing. " ,
] make-string throw ;
\ alien-invoke [ [ object object object object ] [ ] ] \ alien-invoke [ [ object object object object ] [ ] ]
"infer-effect" set-word-property "infer-effect" set-word-property
@ -157,4 +174,3 @@ SYMBOL: alien-parameters
global [ global [
"libraries" get [ <namespace> "libraries" set ] unless "libraries" get [ <namespace> "libraries" set ] unless
] bind ] bind

View File

@ -28,6 +28,7 @@
IN: compiler IN: compiler
USE: inference USE: inference
USE: errors USE: errors
USE: generic
USE: hashtables USE: hashtables
USE: kernel USE: kernel
USE: lists USE: lists
@ -56,7 +57,11 @@ USE: words
] when ] when
dup word-parameter ; dup word-parameter ;
: (compile) ( word -- ) GENERIC: (compile) ( word -- )
M: word (compile) drop ;
M: compound (compile) ( word -- )
#! Should be called inside the with-compiler scope. #! Should be called inside the with-compiler scope.
compiling dataflow optimize linearize simplify generate ; compiling dataflow optimize linearize simplify generate ;

View File

@ -128,16 +128,18 @@ USE: math
compiled-offset 0 compile-cell 0 defer-xt rel-address compiled-offset 0 compile-cell 0 defer-xt rel-address
] "generator" set-word-property ] "generator" set-word-property
#c-call [ CALL JUMP-FIXUP ] "generator" set-word-property #c-call [
uncons alien-symbol CALL JUMP-FIXUP
] "generator" set-word-property
#unbox [ #unbox [
CALL JUMP-FIXUP dlsym-self CALL JUMP-FIXUP
EAX PUSH-R EAX PUSH-R
] "generator" set-word-property ] "generator" set-word-property
#box [ #box [
EAX PUSH-R EAX PUSH-R
CALL JUMP-FIXUP dlsym-self CALL JUMP-FIXUP
4 ESP R+I 4 ESP R+I
] "generator" set-word-property ] "generator" set-word-property

View File

@ -81,7 +81,7 @@ SYMBOL: relocation-table
dup [ compile-cell ] vector-each dup [ compile-cell ] vector-each
vector-length cell * ; vector-length cell * ;
: generate ( word linear -- ) : (generate) ( word linear -- )
#! Compile a word definition from linear IR. #! Compile a word definition from linear IR.
100 <vector> relocation-table set 100 <vector> relocation-table set
begin-assembly swap >r >r begin-assembly swap >r >r
@ -90,4 +90,18 @@ SYMBOL: relocation-table
r> set-compiled-cell r> set-compiled-cell
r> set-compiled-cell ; r> set-compiled-cell ;
SYMBOL: previous-offset
: generate ( word linear -- )
#! If generation fails, reset compiled offset.
[
compiled-offset previous-offset set
(generate)
] [
[
previous-offset get set-compiled-offset
rethrow
] when*
] catch ;
#label [ save-xt ] "generator" set-word-property #label [ save-xt ] "generator" set-word-property

View File

@ -83,13 +83,13 @@ PREDICATE: vector hashtable ( obj -- ? )
: hash-each ( hash code -- ) : hash-each ( hash code -- )
#! Apply the code to each key/value pair of the hashtable. #! Apply the code to each key/value pair of the hashtable.
swap [ swap dup >r each r> ] vector-each drop ; swap [ swap dup >r each r> ] vector-each drop ; inline
: hash-subset ( hash code -- hash ) : hash-subset ( hash code -- hash )
#! Return a new hashtable containing all key/value pairs #! Return a new hashtable containing all key/value pairs
#! for which the predicate yielded a true value. The #! for which the predicate yielded a true value. The
#! predicate must have stack effect ( obj -- ? ). #! predicate must have stack effect ( obj -- ? ).
swap [ swap dup >r subset r> swap ] vector-map nip ; swap [ swap dup >r subset r> swap ] vector-map nip ; inline
: hash-keys ( hash -- list ) : hash-keys ( hash -- list )
#! Push a list of keys in a hashtable. #! Push a list of keys in a hashtable.

View File

@ -39,7 +39,7 @@ USE: words
USE: hashtables USE: hashtables
USE: parser USE: parser
: with-dataflow ( param op [ in | out ] quot -- ) : with-dataflow ( param op [ intypes outtypes ] quot -- )
#! Take input parameters, execute quotation, take output #! Take input parameters, execute quotation, take output
#! parameters, add node. The quotation is called with the #! parameters, add node. The quotation is called with the
#! stack effect. #! stack effect.

View File

@ -2,6 +2,7 @@ IN: scratchpad
USE: alien USE: alien
USE: kernel USE: kernel
USE: test USE: test
USE: inference
[ t ] [ 0 <alien> 0 <alien> = ] unit-test [ t ] [ 0 <alien> 0 <alien> = ] unit-test
[ f ] [ 0 <alien> local-alien? ] unit-test [ f ] [ 0 <alien> local-alien? ] unit-test
@ -9,3 +10,13 @@ USE: test
[ f ] [ 0 <alien> 1024 <alien> = ] unit-test [ f ] [ 0 <alien> 1024 <alien> = ] unit-test
[ f ] [ "hello" 1024 <alien> = ] unit-test [ f ] [ "hello" 1024 <alien> = ] unit-test
[ t ] [ 1024 <local-alien> local-alien? ] unit-test [ t ] [ 1024 <local-alien> local-alien? ] unit-test
: alien-inference-1
"void" "foobar" "boo" [ "short" "short" ] alien-invoke ;
[ [ 2 | 0 ] ] [ [ alien-inference-1 ] infer old-effect ] unit-test
: alien-inference-2
"int" "foobar" "boo" [ "short" "short" ] alien-invoke ;
[ [ 2 | 1 ] ] [ [ alien-inference-2 ] infer old-effect ] unit-test

View File

@ -196,6 +196,8 @@ SYMBOL: sym-test
[ [ 1 | 1 ] ] [ [ get ] infer old-effect ] unit-test [ [ 1 | 1 ] ] [ [ get ] infer old-effect ] unit-test
[ [ 1 | 1 ] ] [ [ str>number ] infer old-effect ] unit-test
! Type inference ! Type inference
[ [ [ object ] [ ] ] ] [ [ drop ] infer ] unit-test [ [ [ object ] [ ] ] ] [ [ drop ] infer ] unit-test