2009-03-22 18:47:48 -04:00
|
|
|
! Copyright (C) 2004, 2009 Slava Pestov.
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-07-06 23:49:39 -04:00
|
|
|
USING: accessors alien.c-types alien.marshall
|
|
|
|
|
alien.structs.fields arrays assocs byte-arrays classes.tuple
|
|
|
|
|
combinators cpu.architecture destructors fry generalizations
|
|
|
|
|
generic hashtables kernel kernel.private libc locals math
|
|
|
|
|
math.order namespaces parser quotations sequences slots strings
|
|
|
|
|
words ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: alien.structs
|
|
|
|
|
|
2009-01-28 02:58:57 -05:00
|
|
|
TUPLE: struct-type
|
|
|
|
|
size
|
|
|
|
|
align
|
|
|
|
|
fields
|
|
|
|
|
{ boxer-quot callable }
|
|
|
|
|
{ unboxer-quot callable }
|
|
|
|
|
{ getter callable }
|
2009-02-12 07:25:07 -05:00
|
|
|
{ setter callable }
|
2009-02-12 09:10:21 -05:00
|
|
|
return-in-registers? ;
|
|
|
|
|
|
|
|
|
|
M: struct-type c-type ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-08-31 08:45:33 -04:00
|
|
|
M: struct-type heap-size size>> ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2009-02-12 10:20:32 -05:00
|
|
|
M: struct-type c-type-class drop byte-array ;
|
2008-11-29 05:59:29 -05:00
|
|
|
|
2008-08-31 08:45:33 -04:00
|
|
|
M: struct-type c-type-align align>> ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
M: struct-type c-type-stack-align? drop f ;
|
|
|
|
|
|
2009-02-06 05:02:00 -05:00
|
|
|
M: struct-type c-type-boxer-quot boxer-quot>> ;
|
|
|
|
|
|
|
|
|
|
M: struct-type c-type-unboxer-quot unboxer-quot>> ;
|
|
|
|
|
|
2008-11-17 14:34:37 -05:00
|
|
|
: if-value-struct ( ctype true false -- )
|
|
|
|
|
[ dup value-struct? ] 2dip '[ drop "void*" @ ] if ; inline
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-11-17 14:34:37 -05:00
|
|
|
M: struct-type unbox-parameter
|
|
|
|
|
[ %unbox-large-struct ] [ unbox-parameter ] if-value-struct ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
M: struct-type box-parameter
|
2008-11-17 14:34:37 -05:00
|
|
|
[ %box-large-struct ] [ box-parameter ] if-value-struct ;
|
|
|
|
|
|
|
|
|
|
: if-small-struct ( c-type true false -- ? )
|
2009-02-12 07:25:07 -05:00
|
|
|
[ dup return-struct-in-registers? ] 2dip '[ f swap @ ] if ; inline
|
2008-11-17 14:34:37 -05:00
|
|
|
|
|
|
|
|
M: struct-type unbox-return
|
|
|
|
|
[ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
M: struct-type box-return
|
2008-11-17 14:34:37 -05:00
|
|
|
[ %box-small-struct ] [ %box-large-struct ] if-small-struct ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
M: struct-type stack-size
|
2008-11-17 14:34:37 -05:00
|
|
|
[ heap-size ] [ stack-size ] if-value-struct ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
: c-struct? ( type -- ? ) (c-type) struct-type? ;
|
|
|
|
|
|
2008-11-14 21:18:16 -05:00
|
|
|
: (define-struct) ( name size align fields -- )
|
2008-11-29 14:37:38 -05:00
|
|
|
[ [ align ] keep ] dip
|
2009-02-06 05:02:00 -05:00
|
|
|
struct-type new
|
2009-03-22 18:47:48 -04:00
|
|
|
swap >>fields
|
|
|
|
|
swap >>align
|
|
|
|
|
swap >>size
|
|
|
|
|
swap typedef ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-12-02 01:24:00 -05:00
|
|
|
: make-fields ( name vocab fields -- fields )
|
2008-11-17 14:34:37 -05:00
|
|
|
[ first2 <field-spec> ] with with map ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
: compute-struct-align ( types -- n )
|
2009-02-03 01:27:34 -05:00
|
|
|
[ c-type-align ] [ max ] map-reduce ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
|
: define-struct ( name vocab fields -- )
|
2009-03-22 18:47:48 -04:00
|
|
|
[ 2drop ] [ make-fields ] 3bi
|
|
|
|
|
[ struct-offsets ] keep
|
|
|
|
|
[ [ type>> ] map compute-struct-align ] keep
|
|
|
|
|
[ (define-struct) ] keep
|
|
|
|
|
[ define-field ] each ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-12-02 01:24:00 -05:00
|
|
|
: define-union ( name members -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
[ expand-constants ] map
|
2009-02-03 01:27:34 -05:00
|
|
|
[ [ heap-size ] [ max ] map-reduce ] keep
|
2007-09-20 18:09:08 -04:00
|
|
|
compute-struct-align f (define-struct) ;
|
2009-02-05 19:51:50 -05:00
|
|
|
|
|
|
|
|
: offset-of ( field struct -- offset )
|
|
|
|
|
c-types get at fields>>
|
|
|
|
|
[ name>> = ] with find nip offset>> ;
|
2009-07-06 23:49:39 -04:00
|
|
|
|
|
|
|
|
TUPLE: struct-wrapper < alien-wrapper disposed ;
|
|
|
|
|
|
|
|
|
|
M: struct-wrapper dispose* underlying>> free ;
|
|
|
|
|
|
|
|
|
|
: define-struct-accessor ( class name quot -- )
|
|
|
|
|
[ "accessors" create create-method dup make-inline ] dip define ;
|
|
|
|
|
|
|
|
|
|
: define-struct-getter ( class name word type -- )
|
|
|
|
|
[ ">>" append \ underlying>> ] 2dip
|
|
|
|
|
unmarshaller \ call 4array >quotation
|
|
|
|
|
define-struct-accessor ;
|
|
|
|
|
|
|
|
|
|
: define-struct-setter ( class name word type -- )
|
|
|
|
|
[ "(>>" prepend ")" append ] 2dip
|
|
|
|
|
marshaller [ underlying>> ] \ bi* roll 4array >quotation
|
|
|
|
|
define-struct-accessor ;
|
|
|
|
|
|
|
|
|
|
: define-struct-accessors ( class name type reader writer -- )
|
|
|
|
|
[ dup define-protocol-slot ] 3dip
|
|
|
|
|
[ drop swap define-struct-getter ]
|
|
|
|
|
[ nip swap define-struct-setter ] 5 nbi ;
|
|
|
|
|
|
|
|
|
|
:: define-struct-tuple ( name -- )
|
|
|
|
|
name create-in :> class
|
|
|
|
|
class struct-wrapper { } define-tuple-class
|
|
|
|
|
name c-type fields>> [
|
|
|
|
|
class swap
|
|
|
|
|
{
|
|
|
|
|
[ name>> { { CHAR: space CHAR: - } } substitute ]
|
|
|
|
|
[ type>> ] [ reader>> ] [ writer>> ]
|
|
|
|
|
} cleave define-struct-accessors
|
|
|
|
|
] each ;
|