alien.data: document with-scoped-allocation and with-out-parameters, and add initial: syntax

db4
Slava Pestov 2010-07-16 17:13:38 -04:00
parent 60ddbd9d9b
commit 5b31cbcb3c
3 changed files with 83 additions and 6 deletions

View File

@ -1,7 +1,7 @@
USING: alien alien.c-types help.syntax help.markup libc
kernel.private byte-arrays math strings hashtables alien.syntax
alien.strings sequences io.encodings.string debugger destructors
vocabs.loader classes.struct ;
vocabs.loader classes.struct quotations ;
IN: alien.data
HELP: <c-array>
@ -44,6 +44,49 @@ HELP: malloc-byte-array
{ string>alien alien>string malloc-string } related-words
HELP: with-scoped-allocation
{ $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } }
{ $description "Allocates values on the call stack, calls the quotation, then deallocates the values as soon as the quotation returns."
$nl
"A scoped allocation specifier is either:"
{ $list
"a C type name,"
{ "or a triple with shape " { $snippet "{ c-type initial: initial }" } ", where " { $snippet "c-type" } " is a C type name and " { $snippet "initial" } " is a literal value." }
}
"If no initial value is specified, the contents of the allocated memory are undefined." }
{ $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." }
{ $examples
{ $example
"USING: accessors alien.c-types alien.data
classes.struct kernel math math.functions
prettyprint ;
IN: scratchpad
STRUCT: point { x int } { y int } ;
: scoped-allocation-test ( -- x )
{ point } [
3 >>x 4 >>y
[ x>> sq ] [ y>> sq ] bi + sqrt
] with-scoped-allocation ;
scoped-allocation-test ."
"5.0"
}
} ;
HELP: with-out-parameters
{ $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } { "finish" quotation } { "values..." "zero or more values" } }
{ $description "Allocates values on the call stack, calls the quotation, then copies all stack allocated values to the data heap after the quotation returns."
$nl
"A scoped allocation specifier is either:"
{ $list
"a C type name,"
{ "or a triple with shape " { $snippet "{ c-type initial: initial }" } ", where " { $snippet "c-type" } " is a C type name and " { $snippet "initial" } " is a literal value." }
}
"If no initial value is specified, the contents of the allocated memory are undefined." }
{ $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." } ;
ARTICLE: "malloc" "Manual memory management"
"Sometimes data passed to C functions must be allocated at a fixed address. See " { $link "byte-arrays-gc" } " for an explanation of when this is the case."
$nl

View File

@ -2,7 +2,8 @@
USING: accessors alien alien.c-types alien.arrays alien.strings
arrays byte-arrays cpu.architecture fry io io.encodings.binary
io.files io.streams.memory kernel libc math math.functions
sequences words macros combinators generalizations ;
sequences words macros combinators generalizations
stack-checker.dependencies combinators.short-circuit ;
QUALIFIED: math
IN: alien.data
@ -88,13 +89,34 @@ ERROR: local-allocation-error ;
! to still be abl to access scope-allocated data.
;
MACRO: (simple-local-allot) ( c-type -- quot )
[ depends-on-c-type ]
[ dup '[ _ heap-size _ c-type-align (local-allot) ] ] bi ;
: [hairy-local-allot] ( c-type initial -- quot )
over '[ _ (simple-local-allot) _ over 0 _ set-alien-value ] ;
: hairy-local-allot? ( obj -- ? )
{
[ array? ]
[ length 3 = ]
[ second initial: eq? ]
} 1&& ;
MACRO: (hairy-local-allot) ( obj -- quot )
dup hairy-local-allot?
[ first3 nip [hairy-local-allot] ]
[ '[ _ (simple-local-allot) ] ]
if ;
MACRO: (local-allots) ( c-types -- quot )
[ '[ _ [ heap-size ] [ c-type-align ] bi (local-allot) ] ] map [ ] join ;
[ '[ _ (hairy-local-allot) ] ] map [ ] join ;
MACRO: box-values ( c-types -- quot )
[ c-type-boxer-quot ] map '[ _ spread ] ;
MACRO: out-parameters ( c-types -- quot )
[ dup hairy-local-allot? [ first ] when ] map
[ length ] [ [ '[ 0 _ alien-value ] ] map ] bi
'[ _ nkeep _ spread ] ;
@ -104,7 +126,7 @@ PRIVATE>
[ [ (local-allots) ] [ box-values ] bi ] dip call
(cleanup-allot) ; inline
: with-out-parameters ( c-types quot finish -- values )
: with-out-parameters ( c-types quot finish -- values... )
[ [ drop (local-allots) ] [ swap out-parameters ] 2bi ] dip call
(cleanup-allot) ; inline

View File

@ -776,10 +776,22 @@ mingw? [
[ 3 ] [ blah ] unit-test
: out-param-test ( -- b )
: out-param-test-1 ( -- b )
{ int } [ [ 12 ] dip 0 int set-alien-value ] [ ] with-out-parameters ;
[ 12 ] [ out-param-test ] unit-test
[ 12 ] [ out-param-test-1 ] unit-test
: out-param-test-2 ( -- b )
{ { int initial: 12 } } [ drop ] [ ] with-out-parameters ;
[ 12 ] [ out-param-test-2 ] unit-test
: out-param-test-3 ( -- x y )
{ { RECT initial: S{ RECT { x 3 } { y 4 } } } } [ drop ]
[ clone ] with-out-parameters
[ x>> ] [ y>> ] bi ;
[ 3.0 4.0 ] [ out-param-test-3 ] unit-test
: out-param-callback ( -- a )
void { int pointer: int } cdecl