factor/library/compiler/alien.factor

177 lines
5.1 KiB
Factor
Raw Normal View History

2004-09-25 16:18:11 -04:00
! :folding=indent:collapseFolds=1:
! $Id$
!
! Copyright (C) 2004 Slava Pestov.
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions are met:
!
! 1. Redistributions of source code must retain the above copyright notice,
! this list of conditions and the following disclaimer.
!
! 2. Redistributions in binary form must reproduce the above copyright notice,
! this list of conditions and the following disclaimer in the documentation
! and/or other materials provided with the distribution.
!
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
IN: alien
USE: compiler
USE: errors
USE: generic
2004-12-13 19:14:03 -05:00
USE: inference
USE: interpreter
USE: kernel
2004-09-25 16:18:11 -04:00
USE: lists
USE: math
USE: namespaces
USE: parser
USE: words
2004-12-18 00:38:51 -05:00
USE: hashtables
2004-12-25 15:52:08 -05:00
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.
2004-09-25 16:18:11 -04:00
BUILTIN: dll 15
BUILTIN: alien 16
2004-12-23 01:14:07 -05:00
M: alien hashcode ( obj -- n )
alien-address ;
M: alien = ( obj obj -- ? )
over alien? [
over local-alien? over local-alien? or [
eq?
] [
alien-address swap alien-address =
] ifte
] [
2drop f
] ifte ;
2004-12-25 15:52:08 -05:00
: library ( name -- object )
dup [ "libraries" get hash ] when ;
2004-09-25 16:18:11 -04:00
2004-12-18 00:38:51 -05:00
: load-dll ( library -- dll )
"dll" get dup [
drop "name" get dlopen dup "dll" set
] unless ;
2004-12-23 06:51:42 -05:00
: add-library ( library name abi -- )
"libraries" get [
<namespace> [
"abi" set
"name" set
] extend put
] bind ;
2004-12-13 19:14:03 -05:00
SYMBOL: #cleanup ( unwind stack by parameter )
SYMBOL: #c-call ( jump to raw address )
SYMBOL: #unbox ( move top of datastack to C stack )
SYMBOL: #box ( move EAX to datastack )
2004-12-25 15:52:08 -05:00
: library-abi ( library -- abi )
library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ;
2004-12-13 19:14:03 -05:00
2004-12-25 15:52:08 -05:00
: alien-symbol ( function library -- address )
library [ [ load-dll ] bind dlsym ] [ dlsym-self ] ifte* ;
2004-12-18 00:38:51 -05:00
2004-12-25 15:52:08 -05:00
SYMBOL: #alien-invoke
2004-12-18 00:38:51 -05:00
2004-12-25 15:52:08 -05:00
! These are set in the #alien-invoke dataflow IR node.
2004-12-13 19:14:03 -05:00
SYMBOL: alien-returns
SYMBOL: alien-parameters
2004-12-25 15:52:08 -05:00
: 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 ;
2004-12-18 00:38:51 -05:00
: infer-alien ( -- )
2004-12-23 01:14:07 -05:00
[ object object object object ] ensure-d
2004-12-22 22:30:50 -05:00
dataflow-drop, pop-d literal-value
2004-12-25 15:52:08 -05:00
dataflow-drop, pop-d literal-value >r
2004-12-22 22:30:50 -05:00
dataflow-drop, pop-d literal-value
2004-12-25 15:52:08 -05:00
dataflow-drop, pop-d literal-value -rot
r> swap alien-node ;
2004-12-13 19:14:03 -05:00
2004-12-25 15:52:08 -05:00
: box-parameter
c-type [
"width" get cell align
"unboxer" get
] bind #unbox swons , ;
2004-12-13 19:14:03 -05:00
: linearize-parameters ( params -- count )
#! Generate code for boxing a list of C types.
#! Return amount stack must be unwound by.
2004-12-16 19:57:03 -05:00
[ alien-parameters get reverse ] bind 0 swap [
2004-12-25 15:52:08 -05:00
box-parameter +
2004-12-13 19:14:03 -05:00
] each ;
: linearize-returns ( returns -- )
[ alien-returns get ] bind dup "void" = [
drop
] [
2004-12-25 15:52:08 -05:00
c-type [ "boxer" get ] bind #box swons ,
2004-12-13 19:14:03 -05:00
] ifte ;
: linearize-alien ( node -- )
dup linearize-parameters >r
dup [ node-param get ] bind #c-call swons ,
2004-12-25 15:52:08 -05:00
dup [ node-param get car "stdcall" = ] bind
r> swap [ drop ] [ #cleanup swons , ] ifte
2004-12-13 19:14:03 -05:00
linearize-returns ;
2004-12-25 15:52:08 -05:00
#alien-invoke [ linearize-alien ] "linearizer" set-word-property
2004-12-13 19:14:03 -05:00
: alien-invoke ( ... returns library function parameters -- ... )
2004-12-18 00:38:51 -05:00
#! Call a C library function.
#! 'returns' is a type spec, and 'parameters' is a list of
#! type specs. 'library' is an entry in the "libraries"
#! namespace.
2004-12-25 15:52:08 -05:00
[
"alien-invoke cannot be interpreted. " ,
"Either the compiler is disabled, " ,
"or the ``" , rot , "'' library is missing. " ,
] make-string throw ;
2004-12-24 17:29:16 -05:00
\ alien-invoke [ [ object object object object ] [ ] ]
"infer-effect" set-word-property
2004-12-18 00:38:51 -05:00
\ alien-invoke [ infer-alien ] "infer" set-word-property
2004-12-13 19:14:03 -05:00
global [
"libraries" get [ <namespace> "libraries" set ] unless
] bind