diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor index 64827ec139..a69f7609b1 100755 --- a/basis/alien/arrays/arrays.factor +++ b/basis/alien/arrays/arrays.factor @@ -1,11 +1,11 @@ ! Copyright (C) 2008, 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien alien.strings alien.c-types alien.accessors alien.structs +USING: alien alien.strings alien.c-types alien.accessors arrays words sequences math kernel namespaces fry libc cpu.architecture io.encodings.utf8 accessors ; IN: alien.arrays -UNION: value-type array struct-type ; +INSTANCE: array value-type M: array c-type ; @@ -40,15 +40,6 @@ M: array c-type-boxer-quot M: array c-type-unboxer-quot drop [ >c-ptr ] ; -M: value-type c-type-rep drop int-rep ; - -M: value-type c-type-getter - drop [ swap ] ; - -M: value-type c-type-setter ( type -- quot ) - [ c-type-getter ] [ c-type-unboxer-quot ] [ heap-size ] tri - '[ @ swap @ _ memcpy ] ; - PREDICATE: string-type < pair first2 [ "char*" = ] [ word? ] bi* and ; diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor index b177ab35d4..35a9627d50 100755 --- a/basis/alien/c-types/c-types.factor +++ b/basis/alien/c-types/c-types.factor @@ -71,6 +71,13 @@ M: string c-type ( name -- type ) ] ?if ] if ; +GENERIC: c-struct? ( type -- ? ) + +M: object c-struct? + drop f ; +M: string c-struct? + dup "void" = [ drop f ] [ c-type c-struct? ] if ; + ! These words being foldable means that words need to be ! recompiled if a C type is redefined. Even so, folding the ! size facilitates some optimizations. @@ -215,6 +222,17 @@ M: string stack-size c-type stack-size ; M: c-type stack-size size>> cell align ; +MIXIN: value-type + +M: value-type c-type-rep drop int-rep ; + +M: value-type c-type-getter + drop [ swap ] ; + +M: value-type c-type-setter ( type -- quot ) + [ c-type-getter ] [ c-type-unboxer-quot ] [ heap-size ] tri + '[ @ swap @ _ memcpy ] ; + GENERIC: byte-length ( seq -- n ) flushable M: byte-array byte-length length ; inline diff --git a/basis/alien/complex/complex.factor b/basis/alien/complex/complex.factor index b0229358d1..65c4095e25 100644 --- a/basis/alien/complex/complex.factor +++ b/basis/alien/complex/complex.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien.c-types alien.structs alien.complex.functor accessors +USING: alien.c-types alien.complex.functor accessors sequences kernel ; IN: alien.complex diff --git a/basis/alien/complex/functor/functor.factor b/basis/alien/complex/functor/functor.factor index b1f9c2be85..1faa64be61 100644 --- a/basis/alien/complex/functor/functor.factor +++ b/basis/alien/complex/functor/functor.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors alien alien.structs alien.c-types classes.struct math +USING: accessors alien alien.c-types classes.struct math math.functions sequences arrays kernel functors vocabs.parser namespaces quotations ; IN: alien.complex.functor diff --git a/basis/alien/fortran/fortran-docs.factor b/basis/alien/fortran/fortran-docs.factor index 8027020c75..7778500bf1 100644 --- a/basis/alien/fortran/fortran-docs.factor +++ b/basis/alien/fortran/fortran-docs.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009 Joe Groff ! See http://factorcode.org/license.txt for BSD license. -USING: help.markup help.syntax kernel quotations sequences strings words.symbol ; +USING: help.markup help.syntax kernel quotations sequences strings words.symbol classes.struct ; QUALIFIED-WITH: alien.syntax c IN: alien.fortran @@ -25,7 +25,7 @@ ARTICLE: "alien.fortran-types" "Fortran types" { { $snippet "DOUBLE-COMPLEX" } " specifies a double-precision floating-point complex value. The alias " { $snippet "COMPLEX*16" } " is also recognized." } { { $snippet "CHARACTER(n)" } " specifies a character string of length " { $snippet "n" } ". The Fortran 77 syntax " { $snippet "CHARACTER*n" } " is also recognized." } { "Fortran arrays can be specified by suffixing a comma-separated set of dimensions in parentheses, e.g. " { $snippet "REAL(2,3,4)" } ". Arrays of unspecified length can be specified using " { $snippet "*" } " as a dimension. Arrays are passed in as flat " { $link "specialized-arrays" } "." } - { "Fortran records defined by " { $link POSTPONE: RECORD: } " and C structs defined by " { $link POSTPONE: c:C-STRUCT: } " are also supported as parameter and return types." } + { "Struct classes defined by " { $link POSTPONE: STRUCT: } " are also supported as parameter and return types." } } "When declaring the parameters of Fortran functions, an output argument can be specified by prefixing an exclamation point to the type name. This will cause the function word to leave the final value of the parameter on the stack." ; @@ -42,10 +42,6 @@ HELP: LIBRARY: { $values { "name" "a logical library name" } } { $description "Sets the logical library for subsequent " { $link POSTPONE: FUNCTION: } " and " { $link POSTPONE: SUBROUTINE: } " definitions. The given library name must have been opened with a previous call to " { $link add-fortran-library } "." } ; -HELP: RECORD: -{ $syntax "RECORD: NAME { \"TYPE\" \"SLOT\" } ... ;" } -{ $description "Defines a Fortran record type with the given slots. The record is defined as the corresponding C struct and can be used as a type for subsequent Fortran or C function declarations." } ; - HELP: add-fortran-library { $values { "name" string } { "soname" string } { "fortran-abi" symbol } } { $description "Opens the shared library in the file specified by " { $snippet "soname" } " under the logical name " { $snippet "name" } " so that it may be used in subsequent " { $link POSTPONE: LIBRARY: } " and " { $link fortran-invoke } " calls. Functions and subroutines from the library will be defined using the specified " { $snippet "fortran-abi" } ", which must be one of the supported " { $link "alien.fortran-abis" } "." } @@ -66,7 +62,6 @@ ARTICLE: "alien.fortran" "Fortran FFI" { $subsection POSTPONE: LIBRARY: } { $subsection POSTPONE: FUNCTION: } { $subsection POSTPONE: SUBROUTINE: } -{ $subsection POSTPONE: RECORD: } { $subsection fortran-invoke } ; diff --git a/basis/alien/fortran/fortran-tests.factor b/basis/alien/fortran/fortran-tests.factor index 177d1077c2..9d893b95c4 100644 --- a/basis/alien/fortran/fortran-tests.factor +++ b/basis/alien/fortran/fortran-tests.factor @@ -1,6 +1,6 @@ ! (c) 2009 Joe Groff, see BSD license USING: accessors alien alien.c-types alien.complex -alien.fortran alien.fortran.private alien.strings alien.structs +alien.fortran alien.fortran.private alien.strings classes.struct arrays assocs byte-arrays combinators fry generalizations io.encodings.ascii kernel macros macros.expander namespaces sequences shuffle tools.test ; @@ -8,10 +8,10 @@ IN: alien.fortran.tests << intel-unix-abi "(alien.fortran-tests)" (add-fortran-library) >> LIBRARY: (alien.fortran-tests) -RECORD: FORTRAN_TEST_RECORD - { "INTEGER" "FOO" } - { "REAL(2)" "BAR" } - { "CHARACTER*4" "BAS" } ; +STRUCT: FORTRAN_TEST_RECORD + { FOO int } + { BAR double[2] } + { BAS char[4] } ; intel-unix-abi fortran-abi [ @@ -168,29 +168,6 @@ intel-unix-abi fortran-abi [ [ "complex" { "character*17" "character" "integer" } fortran-sig>c-sig ] unit-test - ! fortran-record>c-struct - - [ { - { "double" "ex" } - { "float" "wye" } - { "int" "zee" } - { "char[20]" "woo" } - } ] [ - { - { "DOUBLE-PRECISION" "EX" } - { "REAL" "WYE" } - { "INTEGER" "ZEE" } - { "CHARACTER(20)" "WOO" } - } fortran-record>c-struct - ] unit-test - - ! RECORD: - - [ 16 ] [ "fortran_test_record" heap-size ] unit-test - [ 0 ] [ "foo" "fortran_test_record" offset-of ] unit-test - [ 4 ] [ "bar" "fortran_test_record" offset-of ] unit-test - [ 12 ] [ "bas" "fortran_test_record" offset-of ] unit-test - ! (fortran-invoke) [ [ diff --git a/basis/alien/fortran/fortran.factor b/basis/alien/fortran/fortran.factor index 013c4d6f6a..52d69fd193 100644 --- a/basis/alien/fortran/fortran.factor +++ b/basis/alien/fortran/fortran.factor @@ -1,6 +1,6 @@ ! (c) 2009 Joe Groff, see BSD license USING: accessors alien alien.c-types alien.complex alien.parser -alien.strings alien.structs alien.syntax arrays ascii assocs +alien.strings alien.syntax arrays ascii assocs byte-arrays combinators combinators.short-circuit fry generalizations kernel lexer macros math math.parser namespaces parser sequences splitting stack-checker vectors vocabs.parser words locals @@ -415,14 +415,6 @@ PRIVATE> : fortran-sig>c-sig ( fortran-return fortran-args -- c-return c-args ) [ fortran-ret-type>c-type ] [ fortran-arg-types>c-types ] bi* append ; -: fortran-record>c-struct ( record -- struct ) - [ first2 [ fortran-type>c-type ] [ >lower ] bi* 2array ] map ; - -: define-fortran-record ( name vocab fields -- ) - [ >lower ] [ ] [ fortran-record>c-struct ] tri* define-struct ; - -SYNTAX: RECORD: scan current-vocab parse-definition define-fortran-record ; - : set-fortran-abi ( library -- ) library-fortran-abis get-global at fortran-abi set ; diff --git a/basis/alien/structs/structs.factor b/basis/alien/structs/structs.factor index a80adf5137..80837e9a01 100755 --- a/basis/alien/structs/structs.factor +++ b/basis/alien/structs/structs.factor @@ -8,6 +8,8 @@ IN: alien.structs TUPLE: struct-type < abstract-c-type fields return-in-registers? ; +INSTANCE: struct-type value-type + M: struct-type c-type ; M: struct-type c-type-stack-align? drop f ; @@ -33,7 +35,7 @@ M: struct-type box-return M: struct-type stack-size [ heap-size ] [ stack-size ] if-value-struct ; -: c-struct? ( type -- ? ) (c-type) struct-type? ; +M: struct-type c-struct? drop t ; : (define-struct) ( name size align fields class -- ) [ [ align ] keep ] 2dip new diff --git a/basis/classes/struct/prettyprint/prettyprint.factor b/basis/classes/struct/prettyprint/prettyprint.factor index e88834530c..8bda9dc5f9 100644 --- a/basis/classes/struct/prettyprint/prettyprint.factor +++ b/basis/classes/struct/prettyprint/prettyprint.factor @@ -1,18 +1,13 @@ ! (c)Joe Groff bsd license USING: accessors alien alien.c-types arrays assocs classes classes.struct combinators combinators.short-circuit continuations -fry kernel libc make math math.parser mirrors prettyprint.backend -prettyprint.custom prettyprint.sections see.private sequences -slots strings summary words ; +definitions fry kernel libc make math math.parser mirrors +prettyprint.backend prettyprint.custom prettyprint.sections +see see.private sequences slots strings summary words ; IN: classes.struct.prettyprint = - [ second offset>> 0 = \ UNION-STRUCT: \ STRUCT: ? ] - [ drop \ STRUCT: ] if ; - : struct>assoc ( struct -- assoc ) [ class struct-slots ] [ struct-slot-values ] bi zip ; @@ -39,8 +34,14 @@ IN: classes.struct.prettyprint PRIVATE> +M: struct-class definer + struct-slots dup length 2 >= + [ second offset>> 0 = \ UNION-STRUCT: \ STRUCT: ? ] + [ drop \ STRUCT: ] if + \ ; ; + M: struct-class see-class* - pprint-; block> ; diff --git a/basis/classes/struct/struct-tests.factor b/basis/classes/struct/struct-tests.factor index 8508230bb2..62fce7f353 100755 --- a/basis/classes/struct/struct-tests.factor +++ b/basis/classes/struct/struct-tests.factor @@ -1,5 +1,5 @@ ! (c)Joe Groff bsd license -USING: accessors alien alien.c-types alien.structs.fields ascii +USING: accessors alien alien.c-types ascii assocs byte-arrays classes.struct classes.tuple.private combinators compiler.tree.debugger compiler.units destructors io.encodings.utf8 io.pathnames io.streams.string kernel libc @@ -196,41 +196,46 @@ UNION-STRUCT: struct-test-float-and-bits [ [ struct-test-float-and-bits see ] with-string-writer ] unit-test [ { - T{ field-spec + T{ struct-slot-spec { name "x" } { offset 0 } + { class fixnum } { type "char" } { reader x>> } { writer (>>x) } } - T{ field-spec + T{ struct-slot-spec { name "y" } { offset 4 } + { class $[ cell 8 = fixnum integer ? ] } { type "int" } { reader y>> } { writer (>>y) } } - T{ field-spec + T{ struct-slot-spec { name "z" } { offset 8 } { type "bool" } + { class boolean } { reader z>> } { writer (>>z) } } } ] [ "struct-test-foo" c-type fields>> ] unit-test [ { - T{ field-spec + T{ struct-slot-spec { name "f" } { offset 0 } { type "float" } + { class float } { reader f>> } { writer (>>f) } } - T{ field-spec + T{ struct-slot-spec { name "bits" } { offset 0 } { type "uint" } + { class $[ cell 8 = fixnum integer ? ] } { reader bits>> } { writer (>>bits) } } diff --git a/basis/classes/struct/struct.factor b/basis/classes/struct/struct.factor index 893bc5a257..1de221d2aa 100755 --- a/basis/classes/struct/struct.factor +++ b/basis/classes/struct/struct.factor @@ -1,14 +1,12 @@ ! (c)Joe Groff bsd license -USING: accessors alien alien.c-types alien.structs -alien.structs.fields arrays byte-arrays classes classes.parser -classes.tuple classes.tuple.parser classes.tuple.private -combinators combinators.short-circuit combinators.smart -definitions functors.backend fry generalizations generic.parser -kernel kernel.private lexer libc locals macros make math -math.order parser quotations sequences slots slots.private -specialized-arrays vectors words summary namespaces assocs -compiler.tree.propagation.transforms ; -FROM: slots => reader-word writer-word ; +USING: accessors alien alien.c-types arrays byte-arrays classes +classes.parser classes.tuple classes.tuple.parser +classes.tuple.private combinators combinators.short-circuit +combinators.smart cpu.architecture definitions functors.backend +fry generalizations generic.parser kernel kernel.private lexer +libc locals macros make math math.order parser quotations +sequences slots slots.private specialized-arrays vectors words +summary namespaces assocs ; IN: classes.struct SPECIALIZED-ARRAY: uchar @@ -22,7 +20,7 @@ TUPLE: struct { (underlying) c-ptr read-only } ; TUPLE: struct-slot-spec < slot-spec - c-type ; + type ; PREDICATE: struct-class < tuple-class superclass \ struct eq? ; @@ -86,11 +84,11 @@ MACRO: ( class -- quot: ( ... -- struct ) ) [ struct-slots [ initial>> ] map over length tail append ] keep ; : (reader-quot) ( slot -- quot ) - [ c-type>> c-type-getter-boxer ] + [ type>> c-type-getter-boxer ] [ offset>> [ >c-ptr ] swap suffix ] bi prepend ; : (writer-quot) ( slot -- quot ) - [ c-type>> c-setter ] + [ type>> c-setter ] [ offset>> [ >c-ptr ] swap suffix ] bi prepend ; : (boxer-quot) ( class -- quot ) @@ -117,6 +115,39 @@ M: struct-class writer-quot ! c-types +TUPLE: struct-c-type < abstract-c-type + fields + return-in-registers? ; + +INSTANCE: struct-c-type value-type + +M: struct-c-type c-type ; + +M: struct-c-type c-type-stack-align? drop f ; + +: if-value-struct ( ctype true false -- ) + [ dup value-struct? ] 2dip '[ drop "void*" @ ] if ; inline + +M: struct-c-type unbox-parameter + [ %unbox-large-struct ] [ unbox-parameter ] if-value-struct ; + +M: struct-c-type box-parameter + [ %box-large-struct ] [ box-parameter ] if-value-struct ; + +: if-small-struct ( c-type true false -- ? ) + [ dup return-struct-in-registers? ] 2dip '[ f swap @ ] if ; inline + +M: struct-c-type unbox-return + [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ; + +M: struct-c-type box-return + [ %box-small-struct ] [ %box-large-struct ] if-small-struct ; + +M: struct-c-type stack-size + [ heap-size ] [ stack-size ] if-value-struct ; + +M: struct-c-type c-struct? drop t ; + struct [ ] 3sequence ] bi define-inline-method ; -: slot>field ( slot -- field ) - field-spec new swap { - [ name>> >>name ] - [ offset>> >>offset ] - [ c-type>> >>type ] - [ name>> reader-word >>reader ] - [ name>> writer-word >>writer ] +: c-type-for-class ( class -- c-type ) + struct-c-type new swap { + [ drop byte-array >>class ] + [ >>boxed-class ] + [ struct-slots >>fields ] + [ "struct-size" word-prop >>size ] + [ "struct-align" word-prop >>align ] + [ (unboxer-quot) >>unboxer-quot ] + [ (boxer-quot) >>boxer-quot ] } cleave ; - -: define-struct-for-class ( class -- ) - [ - { - [ name>> ] - [ "struct-size" word-prop ] - [ "struct-align" word-prop ] - [ struct-slots [ slot>field ] map ] - } cleave - struct-type (define-struct) - ] [ - { - [ name>> c-type ] - [ (unboxer-quot) >>unboxer-quot ] - [ (boxer-quot) >>boxer-quot ] - [ >>boxed-class ] - } cleave drop - ] bi ; - + : align-offset ( offset class -- offset' ) c-type-align align ; : struct-offsets ( slots -- size ) 0 [ - [ c-type>> align-offset ] keep - [ (>>offset) ] [ c-type>> heap-size + ] 2bi + [ type>> align-offset ] keep + [ (>>offset) ] [ type>> heap-size + ] 2bi ] reduce ; : union-struct-offsets ( slots -- size ) - [ 0 >>offset c-type>> heap-size ] [ max ] map-reduce ; + [ 0 >>offset type>> heap-size ] [ max ] map-reduce ; : struct-align ( slots -- align ) - [ c-type>> c-type-align ] [ max ] map-reduce ; + [ type>> c-type-align ] [ max ] map-reduce ; PRIVATE> M: struct-class c-type name>> c-type ; @@ -228,7 +243,7 @@ M: struct byte-length class "struct-size" word-prop ; foldable [ (struct-methods) ] tri ; : check-struct-slots ( slots -- ) - [ c-type>> c-type drop ] each ; + [ type>> c-type drop ] each ; : redefine-struct-tuple-class ( class -- ) [ dup class? [ forget-class ] [ drop ] if ] [ struct f define-tuple-class ] bi ; @@ -244,7 +259,7 @@ M: struct byte-length class "struct-size" word-prop ; foldable [ check-struct-slots ] _ [ struct-align [ align ] keep ] tri (struct-word-props) ] - [ drop define-struct-for-class ] 2tri ; inline + [ drop [ c-type-for-class ] [ name>> ] bi typedef ] 2tri ; inline PRIVATE> : define-struct-class ( class slots -- ) @@ -265,7 +280,7 @@ ERROR: invalid-struct-slot token ; : ( name c-type attributes -- slot-spec ) [ struct-slot-spec new ] 3dip [ >>name ] - [ [ >>c-type ] [ struct-slot-class >>class ] bi ] + [ [ >>type ] [ struct-slot-class >>class ] bi ] [ [ dup empty? ] [ peel-off-attributes ] until drop ] tri* ; >rep) >> heap-size cell align cell /i "__stack_value" c-type ; -M: struct-type flatten-value-type ( type -- seq ) +: flatten-struct ( c-type -- seq ) dup heap-size 16 > [ flatten-large-struct ] [ flatten-small-struct ] if ; +M: alien.structs:struct-type flatten-value-type ( type -- seq ) + flatten-struct ; +M: classes.struct:struct-c-type flatten-value-type ( type -- seq ) + flatten-struct ; + M: x86.64 return-struct-in-registers? ( c-type -- ? ) heap-size 2 cells <= ; diff --git a/extra/gpu/render/render.factor b/extra/gpu/render/render.factor index c0dca56551..0ee9ab78c5 100644 --- a/extra/gpu/render/render.factor +++ b/extra/gpu/render/render.factor @@ -1,5 +1,5 @@ ! (c)2009 Joe Groff bsd license -USING: accessors alien alien.c-types alien.structs arrays +USING: accessors alien alien.c-types arrays assocs classes classes.mixin classes.parser classes.singleton classes.tuple classes.tuple.private combinators combinators.tuple destructors fry generic generic.parser gpu gpu.buffers gpu.framebuffers