From 77fa16c76f3f7f109a8166cb42939ea64f9ecc26 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 26 Sep 2009 21:28:11 -0500 Subject: [PATCH] alien: improve documentation --- basis/alien/arrays/arrays-docs.factor | 12 ---- basis/alien/c-types/c-types-docs.factor | 20 +++--- basis/alien/c-types/c-types.factor | 47 ++++++------ basis/alien/data/data-docs.factor | 44 ++++++------ basis/alien/data/data.factor | 2 +- basis/bit-arrays/bit-arrays-docs.factor | 2 +- basis/classes/struct/struct-docs.factor | 71 +++++++++++++++++-- basis/help/help-docs.factor | 2 +- .../specialized-arrays-docs.factor | 41 ++++++++++- core/alien/alien-docs.factor | 1 - core/byte-arrays/byte-arrays-docs.factor | 2 +- 11 files changed, 166 insertions(+), 78 deletions(-) delete mode 100755 basis/alien/arrays/arrays-docs.factor diff --git a/basis/alien/arrays/arrays-docs.factor b/basis/alien/arrays/arrays-docs.factor deleted file mode 100755 index 74174485fe..0000000000 --- a/basis/alien/arrays/arrays-docs.factor +++ /dev/null @@ -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 } -{ $subsection } ; diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor index 8b5a526e82..4f70836737 100755 --- a/basis/alien/c-types/c-types-docs.factor +++ b/basis/alien/c-types/c-types-docs.factor @@ -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: -{ $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." } ; diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor index 9aea6fe252..984fa4e36e 100755 --- a/basis/alien/c-types/c-types.factor +++ b/basis/alien/c-types/c-types.factor @@ -39,8 +39,8 @@ unboxer { rep initial: int-rep } stack-align? ; -: ( -- type ) - \ c-type new ; +: ( -- 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 *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 ; -: ( -- 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 [ 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 diff --git a/basis/alien/data/data-docs.factor b/basis/alien/data/data-docs.factor index 685639beed..71433dd652 100644 --- a/basis/alien/data/data-docs.factor +++ b/basis/alien/data/data-docs.factor @@ -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: @@ -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 } "." } { $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 } " 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 } -{ $subsection } +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." } diff --git a/basis/alien/data/data.factor b/basis/alien/data/data.factor index 1f2c5160e1..6f4bbe991a 100644 --- a/basis/alien/data/data.factor +++ b/basis/alien/data/data.factor @@ -29,7 +29,7 @@ GENERIC: ( alien len c-type -- array ) M: c-type-name c-direct-array-constructor execute( alien len -- array ) ; inline -: malloc-array ( n type -- alien ) +: malloc-array ( n type -- array ) [ heap-size calloc ] [ ] 2bi ; inline : (malloc-array) ( n type -- alien ) diff --git a/basis/bit-arrays/bit-arrays-docs.factor b/basis/bit-arrays/bit-arrays-docs.factor index fab2a62062..3878735702 100644 --- a/basis/bit-arrays/bit-arrays-docs.factor +++ b/basis/bit-arrays/bit-arrays-docs.factor @@ -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 } diff --git a/basis/classes/struct/struct-docs.factor b/basis/classes/struct/struct-docs.factor index 8a67f00354..a38bd3c588 100644 --- a/basis/classes/struct/struct-docs.factor +++ b/basis/classes/struct/struct-docs.factor @@ -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 ." } +"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 ." +} ; + +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 } { $subsection } @@ -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" diff --git a/basis/help/help-docs.factor b/basis/help/help-docs.factor index 32d60851bd..56796f630f 100644 --- a/basis/help/help-docs.factor +++ b/basis/help/help-docs.factor @@ -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 diff --git a/basis/specialized-arrays/specialized-arrays-docs.factor b/basis/specialized-arrays/specialized-arrays-docs.factor index bb5c7d38d6..f3148e04d9 100755 --- a/basis/specialized-arrays/specialized-arrays-docs.factor +++ b/basis/specialized-arrays/specialized-arrays-docs.factor @@ -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 "" } " 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 "" } ":" +{ $code + "USING: alien.c-types classes.struct ;" + "" + "STRUCT: device_info" + " { id int }" + " { name char* } ;" + "" + "FUNCTION: void get_device_info ( int* length ) ;" + "" + "0 [ get_device_info ] keep ." +} +"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" } diff --git a/core/alien/alien-docs.factor b/core/alien/alien-docs.factor index b310345464..7bbd8542e5 100644 --- a/core/alien/alien-docs.factor +++ b/core/alien/alien-docs.factor @@ -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" } diff --git a/core/byte-arrays/byte-arrays-docs.factor b/core/byte-arrays/byte-arrays-docs.factor index f1d94a46f7..6c1aa1fde5 100644 --- a/core/byte-arrays/byte-arrays-docs.factor +++ b/core/byte-arrays/byte-arrays-docs.factor @@ -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 }