]> gitweb.factorcode.org Git - factor.git/commitdiff
alien: improve documentation
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 27 Sep 2009 02:28:11 +0000 (21:28 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Sun, 27 Sep 2009 02:28:11 +0000 (21:28 -0500)
basis/alien/arrays/arrays-docs.factor [deleted file]
basis/alien/c-types/c-types-docs.factor
basis/alien/c-types/c-types.factor
basis/alien/data/data-docs.factor
basis/alien/data/data.factor
basis/bit-arrays/bit-arrays-docs.factor
basis/classes/struct/struct-docs.factor
basis/help/help-docs.factor
basis/specialized-arrays/specialized-arrays-docs.factor
core/alien/alien-docs.factor
core/byte-arrays/byte-arrays-docs.factor

diff --git a/basis/alien/arrays/arrays-docs.factor b/basis/alien/arrays/arrays-docs.factor
deleted file mode 100755 (executable)
index 7417448..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-USING: help.syntax help.markup byte-arrays alien.c-types alien.data ;\r
-IN: alien.arrays\r
-\r
-ARTICLE: "c-arrays" "C arrays"\r
-"C arrays are allocated in the same manner as other C data; see " { $link "c-byte-arrays" } " and " { $link "malloc" } "."\r
-$nl\r
-"C type specifiers for array types are documented in " { $link "c-types-specs" } "."\r
-$nl\r
-"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:"\r
-{ $subsection require-c-array }\r
-{ $subsection <c-array> }\r
-{ $subsection <c-direct-array> } ;\r
index 8b5a526e827d386655a2c5985987607aa371dcdd..4f7083673726f6b5e824a5ca7731378d6a1a52d2 100755 (executable)
@@ -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." } ;
 
index 9aea6fe252e6b92774072a2dec4539033c83dd4f..984fa4e36ef970db90149561240dd02e25032259 100755 (executable)
@@ -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
index 685639beed7c9b67b6c2840887493491890dbbed..71433dd652ec4fa3eeacb09d2c090c97e5f9fc21 100644 (file)
@@ -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." }
index 1f2c5160e113c7b5a647b93e70daadbb9e0c2603..6f4bbe991a5fbb2e4191ec332c972a98e3d3f167 100644 (file)
@@ -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 )
index fab2a62062fb234debd7f00d1d47e97a6955fdad..387873570224eeef31880e7cb382d1c5e9a77af6 100644 (file)
@@ -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 }
index 8a67f00354e39f4f96392d2c117280dfecf21556..a38bd3c588c2920cb7c82de0ffa9bfbc2103a6ab 100644 (file)
@@ -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"
index 32d60851bd7697e3acd611f3568bb294349a44bc..56796f630f53e9d832226ee9bbbee65311a5ccd7 100644 (file)
@@ -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
index bb5c7d38d6d67cefe56c1884fa6804a44c5b67df..f3148e04d972b02955666331b1a131b45f1eb139 100755 (executable)
@@ -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" }
index b310345464fbef1062215e2d0813cfd95ceac795..7bbd8542e531a4bfd9cd06548759b45ee95a7705 100644 (file)
@@ -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" }
index f1d94a46f70bc6009af6f88c0024edb6976a1cce..6c1aa1fde536fd5b6f5d96166c721b290f4571fe 100644 (file)
@@ -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 }