alien: improve documentation
parent
685c4143c9
commit
77fa16c76f
|
@ -1,12 +0,0 @@
|
|||
USING: help.syntax help.markup byte-arrays alien.c-types alien.data ;
|
||||
IN: alien.arrays
|
||||
|
||||
ARTICLE: "c-arrays" "C arrays"
|
||||
"C arrays are allocated in the same manner as other C data; see " { $link "c-byte-arrays" } " and " { $link "malloc" } "."
|
||||
$nl
|
||||
"C type specifiers for array types are documented in " { $link "c-types-specs" } "."
|
||||
$nl
|
||||
"Specialized sequences are provided for accessing memory as an array of primitive type values. These sequences are implemented in the " { $vocab-link "specialized-arrays" } " vocabulary set. They can also be loaded and constructed through their primitive C types:"
|
||||
{ $subsection require-c-array }
|
||||
{ $subsection <c-array> }
|
||||
{ $subsection <c-direct-array> } ;
|
|
@ -10,7 +10,7 @@ HELP: byte-length
|
|||
{ $contract "Outputs the size of the byte array, struct, or specialized array data in bytes." } ;
|
||||
|
||||
HELP: heap-size
|
||||
{ $values { "type" string } { "size" math:integer } }
|
||||
{ $values { "name" "a C type name" } { "size" math:integer } }
|
||||
{ $description "Outputs the number of bytes needed for a heap-allocated value of this C type." }
|
||||
{ $examples
|
||||
{ $example "USING: alien alien.c-types prettyprint ;\nint heap-size ." "4" }
|
||||
|
@ -18,16 +18,16 @@ HELP: heap-size
|
|||
{ $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
|
||||
|
||||
HELP: stack-size
|
||||
{ $values { "type" string } { "size" math:integer } }
|
||||
{ $values { "name" "a C type name" } { "size" math:integer } }
|
||||
{ $description "Outputs the number of bytes to reserve on the C stack by a value of this C type. In most cases this is equal to " { $link heap-size } ", except on some platforms where C structs are passed by invisible reference, in which case a C struct type only uses as much space as a pointer on the C stack." }
|
||||
{ $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
|
||||
|
||||
HELP: <c-type>
|
||||
{ $values { "type" hashtable } }
|
||||
{ $values { "c-type" c-type } }
|
||||
{ $description "Creates a prototypical C type. User code should use higher-level facilities to define C types; see " { $link "c-data" } "." } ;
|
||||
|
||||
HELP: no-c-type
|
||||
{ $values { "type" string } }
|
||||
{ $values { "name" "a C type name" } }
|
||||
{ $description "Throws a " { $link no-c-type } " error." }
|
||||
{ $error-description "Thrown by " { $link c-type } " if a given string does not name a C type. When thrown during compile time, indicates a typo in an " { $link alien-invoke } " or " { $link alien-callback } " form." } ;
|
||||
|
||||
|
@ -35,32 +35,32 @@ HELP: c-types
|
|||
{ $var-description "Global variable holding a hashtable mapping C type names to C types. Use the " { $link c-type } " word to look up C types." } ;
|
||||
|
||||
HELP: c-type
|
||||
{ $values { "name" string } { "type" hashtable } }
|
||||
{ $values { "name" "a C type" } { "c-type" c-type } }
|
||||
{ $description "Looks up a C type by name." }
|
||||
{ $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
|
||||
|
||||
HELP: c-getter
|
||||
{ $values { "name" string } { "quot" { $quotation "( c-ptr n -- obj )" } } }
|
||||
{ $values { "name" "a C type" } { "quot" { $quotation "( c-ptr n -- obj )" } } }
|
||||
{ $description "Outputs a quotation which reads values of this C type from a C structure." }
|
||||
{ $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
|
||||
|
||||
HELP: c-setter
|
||||
{ $values { "name" string } { "quot" { $quotation "( obj c-ptr n -- )" } } }
|
||||
{ $values { "name" "a C type" } { "quot" { $quotation "( obj c-ptr n -- )" } } }
|
||||
{ $description "Outputs a quotation which writes values of this C type to a C structure." }
|
||||
{ $errors "Throws an error if the type does not exist." } ;
|
||||
|
||||
HELP: box-parameter
|
||||
{ $values { "n" math:integer } { "ctype" string } }
|
||||
{ $values { "n" math:integer } { "c-type" "a C type" } }
|
||||
{ $description "Generates code for converting a C value stored at offset " { $snippet "n" } " from the top of the stack into a Factor object to be pushed on the data stack." }
|
||||
{ $notes "This is an internal word used by the compiler when compiling callbacks." } ;
|
||||
|
||||
HELP: box-return
|
||||
{ $values { "ctype" string } }
|
||||
{ $values { "c-type" "a C type" } }
|
||||
{ $description "Generates code for converting a C value stored in return registers into a Factor object to be pushed on the data stack." }
|
||||
{ $notes "This is an internal word used by the compiler when compiling alien calls." } ;
|
||||
|
||||
HELP: unbox-return
|
||||
{ $values { "ctype" string } }
|
||||
{ $values { "c-type" "a C type" } }
|
||||
{ $description "Generates code for converting a Factor value on the data stack into a C value to be stored in the return registers." }
|
||||
{ $notes "This is an internal word used by the compiler when compiling callbacks." } ;
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ unboxer
|
|||
{ rep initial: int-rep }
|
||||
stack-align? ;
|
||||
|
||||
: <c-type> ( -- type )
|
||||
\ c-type new ;
|
||||
: <c-type> ( -- c-type )
|
||||
\ c-type new ; inline
|
||||
|
||||
SYMBOL: c-types
|
||||
|
||||
|
@ -56,13 +56,14 @@ PREDICATE: c-type-word < word
|
|||
UNION: c-type-name string word ;
|
||||
|
||||
! C type protocol
|
||||
GENERIC: c-type ( name -- type ) foldable
|
||||
GENERIC: c-type ( name -- c-type ) foldable
|
||||
|
||||
GENERIC: resolve-pointer-type ( name -- c-type )
|
||||
|
||||
M: word resolve-pointer-type
|
||||
dup "pointer-c-type" word-prop
|
||||
[ ] [ drop void* ] ?if ;
|
||||
|
||||
M: string resolve-pointer-type
|
||||
dup "*" append dup c-types get at
|
||||
[ nip ] [
|
||||
|
@ -71,14 +72,14 @@ M: string resolve-pointer-type
|
|||
[ resolve-pointer-type ] [ drop void* ] if
|
||||
] if ;
|
||||
|
||||
: resolve-typedef ( name -- type )
|
||||
: resolve-typedef ( name -- c-type )
|
||||
dup c-type-name? [ c-type ] when ;
|
||||
|
||||
: parse-array-type ( name -- dims type )
|
||||
: parse-array-type ( name -- dims c-type )
|
||||
"[" split unclip
|
||||
[ [ "]" ?tail drop string>number ] map ] dip ;
|
||||
|
||||
M: string c-type ( name -- type )
|
||||
M: string c-type ( name -- c-type )
|
||||
CHAR: ] over member? [
|
||||
parse-array-type prefix
|
||||
] [
|
||||
|
@ -93,7 +94,7 @@ M: word c-type
|
|||
: void? ( c-type -- ? )
|
||||
{ void "void" } member? ;
|
||||
|
||||
GENERIC: c-struct? ( type -- ? )
|
||||
GENERIC: c-struct? ( c-type -- ? )
|
||||
|
||||
M: object c-struct?
|
||||
drop f ;
|
||||
|
@ -169,33 +170,33 @@ M: c-type c-type-stack-align? stack-align?>> ;
|
|||
|
||||
M: c-type-name c-type-stack-align? c-type c-type-stack-align? ;
|
||||
|
||||
: c-type-box ( n type -- )
|
||||
: c-type-box ( n c-type -- )
|
||||
[ c-type-rep ] [ c-type-boxer [ "No boxer" throw ] unless* ] bi
|
||||
%box ;
|
||||
|
||||
: c-type-unbox ( n ctype -- )
|
||||
: c-type-unbox ( n c-type -- )
|
||||
[ c-type-rep ] [ c-type-unboxer [ "No unboxer" throw ] unless* ] bi
|
||||
%unbox ;
|
||||
|
||||
GENERIC: box-parameter ( n ctype -- )
|
||||
GENERIC: box-parameter ( n c-type -- )
|
||||
|
||||
M: c-type box-parameter c-type-box ;
|
||||
|
||||
M: c-type-name box-parameter c-type box-parameter ;
|
||||
|
||||
GENERIC: box-return ( ctype -- )
|
||||
GENERIC: box-return ( c-type -- )
|
||||
|
||||
M: c-type box-return f swap c-type-box ;
|
||||
|
||||
M: c-type-name box-return c-type box-return ;
|
||||
|
||||
GENERIC: unbox-parameter ( n ctype -- )
|
||||
GENERIC: unbox-parameter ( n c-type -- )
|
||||
|
||||
M: c-type unbox-parameter c-type-unbox ;
|
||||
|
||||
M: c-type-name unbox-parameter c-type unbox-parameter ;
|
||||
|
||||
GENERIC: unbox-return ( ctype -- )
|
||||
GENERIC: unbox-return ( c-type -- )
|
||||
|
||||
M: c-type unbox-return f swap c-type-unbox ;
|
||||
|
||||
|
@ -203,13 +204,13 @@ M: c-type-name unbox-return c-type unbox-return ;
|
|||
|
||||
: little-endian? ( -- ? ) 1 <int> *char 1 = ; foldable
|
||||
|
||||
GENERIC: heap-size ( type -- size ) foldable
|
||||
GENERIC: heap-size ( name -- size ) foldable
|
||||
|
||||
M: c-type-name heap-size c-type heap-size ;
|
||||
|
||||
M: abstract-c-type heap-size size>> ;
|
||||
|
||||
GENERIC: stack-size ( type -- size ) foldable
|
||||
GENERIC: stack-size ( name -- size ) foldable
|
||||
|
||||
M: c-type-name stack-size c-type stack-size ;
|
||||
|
||||
|
@ -236,7 +237,7 @@ MIXIN: value-type
|
|||
[ "Cannot write struct fields with this type" throw ]
|
||||
] unless* ;
|
||||
|
||||
: array-accessor ( type quot -- def )
|
||||
: array-accessor ( c-type quot -- def )
|
||||
[
|
||||
\ swap , [ heap-size , [ * >fixnum ] % ] [ % ] bi*
|
||||
] [ ] make ;
|
||||
|
@ -262,19 +263,19 @@ M: word typedef ( old new -- )
|
|||
|
||||
TUPLE: long-long-type < c-type ;
|
||||
|
||||
: <long-long-type> ( -- type )
|
||||
: <long-long-type> ( -- c-type )
|
||||
long-long-type new ;
|
||||
|
||||
M: long-long-type unbox-parameter ( n type -- )
|
||||
M: long-long-type unbox-parameter ( n c-type -- )
|
||||
c-type-unboxer %unbox-long-long ;
|
||||
|
||||
M: long-long-type unbox-return ( type -- )
|
||||
M: long-long-type unbox-return ( c-type -- )
|
||||
f swap unbox-parameter ;
|
||||
|
||||
M: long-long-type box-parameter ( n type -- )
|
||||
M: long-long-type box-parameter ( n c-type -- )
|
||||
c-type-boxer %box-long-long ;
|
||||
|
||||
M: long-long-type box-return ( type -- )
|
||||
M: long-long-type box-return ( c-type -- )
|
||||
f swap box-parameter ;
|
||||
|
||||
: define-deref ( name -- )
|
||||
|
@ -286,13 +287,13 @@ M: long-long-type box-return ( type -- )
|
|||
[ dup c-setter '[ _ heap-size <byte-array> [ 0 @ ] keep ] ] bi
|
||||
(( value -- c-ptr )) define-inline ;
|
||||
|
||||
: define-primitive-type ( type name -- )
|
||||
: define-primitive-type ( c-type name -- )
|
||||
[ typedef ]
|
||||
[ name>> define-deref ]
|
||||
[ name>> define-out ]
|
||||
tri ;
|
||||
|
||||
: if-void ( type true false -- )
|
||||
: if-void ( c-type true false -- )
|
||||
pick void? [ drop nip call ] [ nip call ] if ; inline
|
||||
|
||||
CONSTANT: primitive-types
|
||||
|
|
|
@ -1,6 +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 ;
|
||||
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 ;
|
||||
IN: alien.data
|
||||
|
||||
HELP: <c-array>
|
||||
|
@ -26,7 +27,7 @@ HELP: byte-array>memory
|
|||
{ $warning "This word is unsafe. Improper use can corrupt memory." } ;
|
||||
|
||||
HELP: malloc-array
|
||||
{ $values { "n" "a non-negative integer" } { "type" "a C type" } { "alien" alien } }
|
||||
{ $values { "n" "a non-negative integer" } { "type" "a C type" } { "array" "a specialized array" } }
|
||||
{ $description "Allocates an unmanaged memory block large enough to hold " { $snippet "n" } " values of a C type, then wraps the memory in a sequence object using " { $link <c-direct-array> } "." }
|
||||
{ $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. The vocabulary can be loaded with the " { $link require-c-array } " word. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." }
|
||||
{ $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
|
||||
|
@ -53,8 +54,8 @@ ARTICLE: "malloc" "Manual memory management"
|
|||
$nl
|
||||
"Allocating a C datum with a fixed address:"
|
||||
{ $subsection malloc-object }
|
||||
{ $subsection malloc-array }
|
||||
{ $subsection malloc-byte-array }
|
||||
{ $subsection malloc-file-contents }
|
||||
"There is a set of words in the " { $vocab-link "libc" } " vocabulary which directly call C standard library memory management functions:"
|
||||
{ $subsection malloc }
|
||||
{ $subsection calloc }
|
||||
|
@ -73,26 +74,31 @@ $nl
|
|||
"You can copy a byte array to memory unsafely:"
|
||||
{ $subsection byte-array>memory } ;
|
||||
|
||||
|
||||
ARTICLE: "c-byte-arrays" "Passing data in byte arrays"
|
||||
"Instances of the " { $link byte-array } " class can be passed to C functions; the C function receives a pointer to the first element of the array."
|
||||
$nl
|
||||
"Byte arrays can be allocated directly with a byte count using the " { $link <byte-array> } " word. However in most cases, instead of computing a size in bytes directly, it is easier to use a higher-level word which expects C type and outputs a byte array large enough to hold that type:"
|
||||
{ $subsection <c-object> }
|
||||
{ $subsection <c-array> }
|
||||
ARTICLE: "c-pointers" "Passing pointers to C functions"
|
||||
"The following Factor objects may be passed to C function parameters with pointer types:"
|
||||
{ $list
|
||||
{ "Instances of " { $link alien } "." }
|
||||
{ "Instances of " { $link f } "; this is interpreted as a null pointer." }
|
||||
{ "Instances of " { $link byte-array } "; the C function receives a pointer to the first element of the array." }
|
||||
{ "Any data type which defines a method on " { $link >c-ptr } " that returns an instance of one of the above. This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." }
|
||||
}
|
||||
"The class of primitive C pointer types:"
|
||||
{ $subsection c-ptr }
|
||||
"A generic word for converting any object to a C pointer; user-defined types may add methods to this generic word:"
|
||||
{ $subsection >c-ptr }
|
||||
"More about the " { $link alien } " type:"
|
||||
{ $subsection "aliens" }
|
||||
{ $warning
|
||||
"The Factor garbage collector can move byte arrays around, and code passing byte arrays to C must obey important guidelines. See " { $link "byte-arrays-gc" } "." }
|
||||
{ $see-also "c-arrays" } ;
|
||||
"The Factor garbage collector can move byte arrays around, and code passing byte arrays, or objects backed by byte arrays, must obey important guidelines. See " { $link "byte-arrays-gc" } "." } ;
|
||||
|
||||
ARTICLE: "c-data" "Passing data between Factor and C"
|
||||
"Two defining characteristics of Factor are dynamic typing and automatic memory management, which are somewhat incompatible with the machine-level data model exposed by C. Factor's C library interface defines its own set of C data types, distinct from Factor language types, together with automatic conversion between Factor values and C types. For example, C integer types must be declared and are fixed-width, whereas Factor supports arbitrary-precision integers."
|
||||
$nl
|
||||
"Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
|
||||
{ $subsection "c-types-specs" }
|
||||
{ $subsection "c-byte-arrays" }
|
||||
{ $subsection "c-pointers" }
|
||||
{ $subsection "malloc" }
|
||||
{ $subsection "c-strings" }
|
||||
{ $subsection "c-arrays" }
|
||||
{ $subsection "c-out-params" }
|
||||
"Important guidelines for passing data in byte arrays:"
|
||||
{ $subsection "byte-arrays-gc" }
|
||||
|
@ -100,12 +106,10 @@ $nl
|
|||
{ $subsection POSTPONE: C-ENUM: }
|
||||
"C types can be aliased for convenience and consitency with native library documentation:"
|
||||
{ $subsection POSTPONE: TYPEDEF: }
|
||||
"New C types can be defined:"
|
||||
{ $subsection "c-structs" }
|
||||
{ $subsection "c-unions" }
|
||||
"A utility for defining " { $link "destructors" } " for deallocating memory:"
|
||||
{ $subsection "alien.destructors" }
|
||||
{ $see-also "aliens" } ;
|
||||
"C struct and union types can be defined with " { $link POSTPONE: STRUCT: } " and " { $link POSTPONE: UNION: } ". See " { $link "classes.struct" } " for details. For passing arrays to and from C, use the " { $link "specialized-arrays" } " vocabulary." ;
|
||||
|
||||
HELP: malloc-string
|
||||
{ $values { "string" string } { "encoding" "an encoding descriptor" } { "alien" c-ptr } }
|
||||
{ $description "Encodes a string together with a trailing null code point using the given encoding, and stores the resulting bytes in a freshly-allocated unmanaged memory block." }
|
||||
|
|
|
@ -29,7 +29,7 @@ GENERIC: <c-direct-array> ( alien len c-type -- array )
|
|||
M: c-type-name <c-direct-array>
|
||||
c-direct-array-constructor execute( alien len -- array ) ; inline
|
||||
|
||||
: malloc-array ( n type -- alien )
|
||||
: malloc-array ( n type -- array )
|
||||
[ heap-size calloc ] [ <c-direct-array> ] 2bi ; inline
|
||||
|
||||
: (malloc-array) ( n type -- alien )
|
||||
|
|
|
@ -7,7 +7,7 @@ ARTICLE: "bit-arrays" "Bit arrays"
|
|||
$nl
|
||||
"Bit array words are in the " { $vocab-link "bit-arrays" } " vocabulary."
|
||||
$nl
|
||||
"Bit arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-byte-arrays" } "."
|
||||
"Bit arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-pointers" } "."
|
||||
$nl
|
||||
"Bit arrays form a class of objects:"
|
||||
{ $subsection bit-array }
|
||||
|
|
|
@ -95,9 +95,36 @@ HELP: struct
|
|||
HELP: struct-class
|
||||
{ $class-description "The metaclass of all " { $link struct } " classes." } ;
|
||||
|
||||
ARTICLE: "classes.struct" "Struct classes"
|
||||
{ $link struct } " classes are similar to " { $link tuple } "s, but their slots exhibit value semantics, and they are backed by a contiguous structured block of memory. Structs can be used for structured access to C memory or Factor byte arrays and for passing struct values in and out of the FFI. Struct types are defined using a syntax similar to tuple syntax:"
|
||||
ARTICLE: "classes.struct.examples" "Struct class examples"
|
||||
"A struct with a variety of fields:"
|
||||
{ $code
|
||||
"USING: alien.c-types classes.struct ;"
|
||||
""
|
||||
"STRUCT: test-struct"
|
||||
" { i int }"
|
||||
" { chicken char[16] }"
|
||||
" { data void* } ;"
|
||||
}
|
||||
"Creating a new instance of this struct, and printing out:"
|
||||
{ $code "test-struct <struct> ." }
|
||||
"Creating a new instance with slots initialized from the stack:"
|
||||
{ $code
|
||||
"USING: libc specialized-arrays ;"
|
||||
"SPECIALIZED-ARRAY: char"
|
||||
""
|
||||
"42"
|
||||
"\"Hello, chicken.\" >char-array"
|
||||
"1024 malloc"
|
||||
"test-struct <struct-boa> ."
|
||||
} ;
|
||||
|
||||
ARTICLE: "classes.struct.define" "Defining struct classes"
|
||||
"Struct classes are defined using a syntax similar to the " { $link POSTPONE: TUPLE: } " syntax for defining tuple classes:"
|
||||
{ $subsection POSTPONE: STRUCT: }
|
||||
"Union structs are also supported, which behave like structs but share the same memory for all the slots."
|
||||
{ $subsection POSTPONE: UNION-STRUCT: } ;
|
||||
|
||||
ARTICLE: "classes.struct.create" "Creating instances of structs"
|
||||
"Structs can be allocated with " { $link new } "- and " { $link boa } "-like constructor words. Additional words are provided for building structs from C memory and from existing buffers:"
|
||||
{ $subsection <struct> }
|
||||
{ $subsection <struct-boa> }
|
||||
|
@ -106,10 +133,40 @@ ARTICLE: "classes.struct" "Struct classes"
|
|||
"When the contents of a struct will be immediately reset, faster primitive words are available that will create a struct without initializing its contents:"
|
||||
{ $subsection (struct) }
|
||||
{ $subsection (malloc-struct) }
|
||||
"Structs have literal syntax like tuples:"
|
||||
{ $subsection POSTPONE: S{ }
|
||||
"Union structs are also supported, which behave like structs but share the same memory for all the type's slots."
|
||||
{ $subsection POSTPONE: UNION-STRUCT: }
|
||||
;
|
||||
"Structs have literal syntax, similar to " { $link POSTPONE: T{ } " for tuples:"
|
||||
{ $subsection POSTPONE: S{ } ;
|
||||
|
||||
ARTICLE: "classes.struct.c" "Passing structs to C functions"
|
||||
"Structs can be passed and returned by value, or by reference."
|
||||
$nl
|
||||
"If a parameter is declared with a struct type, the parameter is passed by value. To pass a struct by reference, declare a parameter with a pointer to struct type."
|
||||
$nl
|
||||
"If a C function is declared as returning a struct type, the struct is returned by value, and wrapped in an instance of the correct struct class automatically. If a C function is declared as returning a pointer to a struct, it will return an " { $link alien } " instance. This is because there is no way to distinguish between a pointer to a single struct and a pointer to an array of zero or more structs. It is up to the caller to wrap it in a struct, or a specialized array of structs, respectively."
|
||||
$nl
|
||||
"An example of a struct declaration:"
|
||||
{ $code
|
||||
"USING: alien.c-types classes.struct ;"
|
||||
""
|
||||
"STRUCT: Point"
|
||||
" { x int }"
|
||||
" { y int }"
|
||||
" { z int } ;"
|
||||
}
|
||||
"A C function which returns a struct by value:"
|
||||
{ $code
|
||||
"USING: alien.syntax ;"
|
||||
"FUNCTION: Point give_me_a_point ( char* description ) ;"
|
||||
}
|
||||
"A C function which takes a struct parameter by reference:"
|
||||
{ $code
|
||||
"FUNCTION: void print_point ( Point* p ) ;"
|
||||
} ;
|
||||
|
||||
ARTICLE: "classes.struct" "Struct classes"
|
||||
{ $link struct } " classes are similar to " { $link tuple } "s, but their slots exhibit value semantics, and they are backed by a contiguous structured block of memory. Structs can be used for structured access to C memory or Factor byte arrays and for passing struct values in and out of the FFI."
|
||||
{ $subsection "classes.struct.examples" }
|
||||
{ $subsection "classes.struct.define" }
|
||||
{ $subsection "classes.struct.create" }
|
||||
{ $subsection "classes.struct.c" } ;
|
||||
|
||||
ABOUT: "classes.struct"
|
||||
|
|
|
@ -311,7 +311,7 @@ HELP: textual-list
|
|||
{ $values { "seq" "a sequence" } { "quot" { $quotation "( elt -- )" } } }
|
||||
{ $description "Applies the quotation to each element of the sequence, printing a comma between each pair of elements." }
|
||||
{ $examples
|
||||
{ $example "USING: help.markup io ;" "{ \"fish\" \"chips\" \"salt\" } [ write ] textual-list" "fish, chips, salt" }
|
||||
{ $example "USING: help.markup io namespaces ;" "last-element off" "{ \"fish\" \"chips\" \"salt\" } [ write ] textual-list" "fish, chips, salt" }
|
||||
} ;
|
||||
|
||||
HELP: $links
|
||||
|
|
|
@ -21,6 +21,45 @@ ARTICLE: "specialized-array-words" "Specialized array words"
|
|||
"Behind the scenes, these words are placed in a vocabulary named " { $snippet "specialized-arrays.instances.T" } ", however this vocabulary should not be placed in a " { $link POSTPONE: USING: } " form directly. Instead, always use " { $link POSTPONE: SPECIALIZED-ARRAY: } ". This ensures that the vocabulary can get generated the first time it is needed." ;
|
||||
|
||||
ARTICLE: "specialized-array-c" "Passing specialized arrays to C functions"
|
||||
"If a C function is declared as taking a parameter with a pointer or an array type (for example, " { $snippet "float*" } " or " { $snippet "int[3]" } "), instances of the relevant specialized array can be passed in."
|
||||
$nl
|
||||
"C type specifiers for array types are documented in " { $link "c-types-specs" } "."
|
||||
$nl
|
||||
"Here is an example; as is common with C functions, the array length is passed in separately, since C does not offer a runtime facility to determine the array length of a base pointer:"
|
||||
{ $code
|
||||
"USING: alien.syntax specialized-arrays ;"
|
||||
"SPECIALIZED-ARRAY: int"
|
||||
"FUNCTION: void process_data ( int* data, int len ) ;"
|
||||
"int-array{ 10 20 30 } dup length process_data"
|
||||
}
|
||||
"Literal specialized arrays, as well as specialized arrays created with " { $snippet "<T-array>" } " and " { $snippet ">T-array" } " are backed by a " { $link byte-array } " in the Factor heap, and can move as a result of garbage collection. If this is unsuitable, the array can be allocated in unmanaged memory instead."
|
||||
$nl
|
||||
"In the following example, it is presumed that the C library holds on to a pointer to the array's data after the " { $snippet "init_with_data()" } " call returns; this is one situation where unmanaged memory has to be used instead. Note the use of destructors to ensure the memory is deallocated after the block ends:"
|
||||
{ $code
|
||||
"USING: alien.syntax specialized-arrays ;"
|
||||
"SPECIALIZED-ARRAY: float"
|
||||
"FUNCTION: void init_with_data ( float* data, int len ) ;"
|
||||
"FUNCTION: float compute_result ( ) ;"
|
||||
"["
|
||||
" 100 malloc-float-array &free"
|
||||
" dup length init_with_data"
|
||||
" compute_result"
|
||||
"] with-destructors"
|
||||
}
|
||||
"Finally, sometimes a C library returns a pointer to an array in unmanaged memory, together with a length. In this case, a specialized array can be constructed to view this memory using " { $snippet "<direct-T-array>" } ":"
|
||||
{ $code
|
||||
"USING: alien.c-types classes.struct ;"
|
||||
""
|
||||
"STRUCT: device_info"
|
||||
" { id int }"
|
||||
" { name char* } ;"
|
||||
""
|
||||
"FUNCTION: void get_device_info ( int* length ) ;"
|
||||
""
|
||||
"0 <int> [ get_device_info ] keep <direct-int-array> ."
|
||||
}
|
||||
"For a full discussion of Factor heap allocation versus unmanaged memory allocation, see " { $link "byte-arrays-gc" } "."
|
||||
$nl
|
||||
"Each specialized array has a " { $slot "underlying" } " slot holding a " { $link byte-array } " with the raw data. Passing a specialized array as a parameter to a C function call will automatically extract the underlying data. To get at the underlying data directly, call the " { $link >c-ptr } " word on a specialized array." ;
|
||||
|
||||
ARTICLE: "specialized-array-math" "Vector arithmetic with specialized arrays"
|
||||
|
@ -42,7 +81,7 @@ ARTICLE: "specialized-arrays" "Specialized arrays"
|
|||
$nl
|
||||
"A specialized array type needs to be generated for each element type. This is done with a parsing word:"
|
||||
{ $subsection POSTPONE: SPECIALIZED-ARRAY: }
|
||||
"This parsing word adds new words to the search path:"
|
||||
"This parsing word adds new words to the search path, documented in the next section."
|
||||
{ $subsection "specialized-array-words" }
|
||||
{ $subsection "specialized-array-c" }
|
||||
{ $subsection "specialized-array-math" }
|
||||
|
|
|
@ -261,7 +261,6 @@ $nl
|
|||
"C library interface words are found in the " { $vocab-link "alien" } " vocabulary."
|
||||
{ $warning "C does not perform runtime type checking, automatic memory management or array bounds checks. Incorrect usage of C library functions can lead to crashes, data corruption, and security exploits." }
|
||||
{ $subsection "loading-libs" }
|
||||
{ $subsection "aliens" }
|
||||
{ $subsection "alien-invoke" }
|
||||
{ $subsection "alien-callback" }
|
||||
{ $subsection "c-data" }
|
||||
|
|
|
@ -6,7 +6,7 @@ ARTICLE: "byte-arrays" "Byte arrays"
|
|||
$nl
|
||||
"Byte array words are in the " { $vocab-link "byte-arrays" } " vocabulary."
|
||||
$nl
|
||||
"Byte arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-byte-arrays" } "."
|
||||
"Byte arrays play a special role in the C library interface; they can be used to pass binary data back and forth between Factor and C. See " { $link "c-pointers" } "."
|
||||
$nl
|
||||
"Byte arrays form a class of objects."
|
||||
{ $subsection byte-array }
|
||||
|
|
Loading…
Reference in New Issue