1 USING: alien alien.c-types help.syntax help.markup libc
2 kernel.private byte-arrays math strings hashtables alien.syntax
3 alien.strings sequences io.encodings.string debugger destructors
4 vocabs.loader classes.struct quotations ;
8 { $values { "len" "a non-negative integer" } { "c-type" "a C type" } { "array" byte-array } }
9 { $description "Creates a byte array large enough to hold " { $snippet "n" } " values of a C type." }
10 { $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." }
11 { $errors "Throws an error if the type does not exist, the necessary specialized array vocabulary is not loaded, or the requested size is negative." } ;
14 { $values { "type" "a C type" } { "array" byte-array } }
15 { $description "Creates a byte array suitable for holding a value with the given C type." }
16 { $errors "Throws an " { $link no-c-type } " error if the type does not exist." } ;
18 { <c-object> malloc-object } related-words
20 HELP: memory>byte-array
21 { $values { "alien" c-ptr } { "len" "a non-negative integer" } { "byte-array" byte-array } }
22 { $description "Reads " { $snippet "len" } " bytes starting from " { $snippet "base" } " and stores them in a new byte array." } ;
25 { $values { "n" "a non-negative integer" } { "type" "a C type" } { "array" "a specialized array" } }
26 { $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> } "." }
27 { $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." }
28 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
29 { $errors "Throws an error if the type does not exist, if the requested size is negative, if a direct specialized array class appropriate to the type is not loaded, or if memory allocation fails." } ;
32 { $values { "type" "a C type" } { "alien" alien } }
33 { $description "Allocates an unmanaged memory block large enough to hold a value of a C type." }
34 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
35 { $errors "Throws an error if the type does not exist or if memory allocation fails." } ;
37 HELP: malloc-byte-array
38 { $values { "byte-array" byte-array } { "alien" alien } }
39 { $description "Allocates an unmanaged memory block of the same size as the byte array, and copies the contents of the byte array there." }
40 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
41 { $errors "Throws an error if memory allocation fails." } ;
43 { <c-array> <c-direct-array> malloc-array } related-words
45 { string>alien alien>string malloc-string } related-words
47 HELP: with-scoped-allocation
48 { $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } }
49 { $description "Allocates values on the call stack, calls the quotation, then deallocates the values as soon as the quotation returns."
51 "A scoped allocation specifier is either:"
54 { "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." }
56 "If no initial value is specified, the contents of the allocated memory are undefined." }
57 { $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." }
60 "USING: accessors alien.c-types alien.data
61 classes.struct kernel math math.functions
65 STRUCT: point { x int } { y int } ;
67 : scoped-allocation-test ( -- x )
70 [ x>> sq ] [ y>> sq ] bi + sqrt
71 ] with-scoped-allocation ;
73 scoped-allocation-test ."
78 HELP: with-out-parameters
79 { $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } { "values..." "zero or more values" } }
80 { $description "Allocates values on the call stack, calls the quotation, then copies all stack allocated values to the data heap after the quotation returns."
82 "A scoped allocation specifier is either:"
85 { "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." }
87 "If no initial value is specified, the contents of the allocated memory are undefined." }
88 { $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." } ;
90 ARTICLE: "malloc" "Manual memory management"
91 "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."
93 "Allocating a C datum with a fixed address:"
98 "The " { $vocab-link "libc" } " vocabulary defines several words which directly call C standard library memory management functions:"
104 "You must always free pointers returned by any of the above words when the block of memory is no longer in use:"
105 { $subsections free }
106 "The above words record memory allocations, to help catch double frees and track down memory leaks with " { $link "tools.destructors" } ". To free memory allocated by a C library, another word can be used:"
107 { $subsections (free) }
108 "Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
113 "The " { $link &free } " and " { $link |free } " words are generated using " { $link "alien.destructors" } "."
115 "You can unsafely copy a range of bytes from one memory location to another:"
116 { $subsections memcpy }
117 "You can copy a range of bytes from memory into a byte array:"
118 { $subsections memory>byte-array } ;
120 ARTICLE: "c-pointers" "Passing pointers to C functions"
121 "The following Factor objects may be passed to C function parameters with pointer types:"
123 { "Instances of " { $link alien } "." }
124 { "Instances of " { $link f } "; this is interpreted as a null pointer." }
125 { "Instances of " { $link byte-array } "; the C function receives a pointer to the first element of the array." }
126 { "Any data type which defines a method on " { $link >c-ptr } ". This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." }
128 "The class of primitive C pointer types:"
129 { $subsections c-ptr }
130 "A generic word for converting any object to a C pointer; user-defined types may add methods to this generic word:"
131 { $subsections >c-ptr }
132 "More about the " { $link alien } " type:"
133 { $subsections "aliens" }
135 "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" } "." } ;
137 ARTICLE: "c-data" "Passing data between Factor and C"
138 "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."
140 "Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
148 "Important guidelines for passing data in byte arrays:"
149 { $subsections "byte-arrays-gc" }
150 "C-style enumerated types are supported:"
151 { $subsections "alien.enums" POSTPONE: ENUM: }
152 "C types can be aliased for convenience and consistency with native library documentation:"
153 { $subsections POSTPONE: TYPEDEF: }
154 "A utility for defining " { $link "destructors" } " for deallocating memory:"
155 { $subsections "alien.destructors" }
156 "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." ;
159 { $values { "string" string } { "encoding" "an encoding descriptor" } { "alien" c-ptr } }
160 { $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." }
161 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
162 { $errors "Throws an error if one of the following conditions occurs:"
164 "the string contains null code points"
165 "the string contains characters not representable using the encoding specified"
166 "memory allocation fails"
170 HELP: require-c-array
171 { $values { "c-type" "a C type" } }
172 { $description "Generates a specialized array of " { $snippet "c-type" } " using the " { $link <c-array> } " or " { $link <c-direct-array> } " vocabularies." }
173 { $notes "This word must be called inside a compilation unit. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence types loaded." } ;
175 HELP: <c-direct-array>
176 { $values { "alien" c-ptr } { "len" integer } { "c-type" "a C type" } { "array" "a specialized direct array" } }
177 { $description "Constructs a new specialized array of length " { $snippet "len" } " and element type " { $snippet "c-type" } " over the range of memory referenced by " { $snippet "alien" } "." }
178 { $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." } ;
180 ARTICLE: "c-strings" "C strings"
181 "C string types are arrays with shape " { $snippet "{ c-string encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $link c-string } " is an alias for " { $snippet "{ c-string utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors. In " { $link POSTPONE: TYPEDEF: } ", " { $link POSTPONE: FUNCTION: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: STRUCT: } " definitions, the shorthand syntax " { $snippet "c-string[encoding]" } " can be used to specify the string encoding."
183 "Passing a Factor string to a C function expecting a " { $link c-string } " allocates a " { $link byte-array } " in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function."
185 "If the conversion fails, for example if the string contains null bytes or characters with values higher than 255, a " { $link c-string-error. } " is thrown."
187 "Care must be taken if the C function expects a pointer to a string with its length represented by another parameter rather than a null terminator. Passing the result of calling " { $link length } " on the string object will not suffice. This is because a Factor string of " { $emphasis "n" } " characters will not necessarily encode to " { $emphasis "n" } " bytes. The correct idiom for C functions which take a string with a length is to first encode the string using " { $link encode } ", and then pass the resulting byte array together with the length of this byte array."
189 "Sometimes a C function has a parameter type of " { $link void* } ", and various data types, among them strings, can be passed in. In this case, strings are not automatically converted to aliens, and instead you must call one of these words:"
194 "The first allocates " { $link byte-array } "s, and the latter allocates manually-managed memory which is not moved by the garbage collector and has to be explicitly freed by calling " { $link free } ". See " { $link "byte-arrays-gc" } " for a discussion of the two approaches."
196 "The C type " { $snippet "char*" } " represents a generic pointer to " { $snippet "char" } "; arguments with this type will expect and return " { $link alien } "s, and won't perform any implicit string conversion."
198 "A word to read strings from arbitrary addresses:"
199 { $subsections alien>string }
200 "For example, if a C function returns a " { $link c-string } " but stipulates that the caller must deallocate the memory afterward, you must define the function as returning " { $snippet "char*" } " and call " { $link (free) } " yourself." ;