1 USING: alien alien.c-types alien.strings alien.syntax
2 byte-arrays classes.struct destructors help.markup help.syntax
3 io.encodings.string kernel libc math quotations sequences
8 { $values { "seq" sequence } { "c-type" "a C type" } { "array" byte-array } }
9 { $description "Outputs a freshly allocated byte-array whose elements are C type values from the given sequence." }
10 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. 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 "USING: alien.c-types alien.data prettyprint ;"
15 "{ 1.0 2.0 3.0 } alien.c-types:float >c-array ."
16 "float-array{ 1.0 2.0 3.0 }"
21 { $values { "len" "a non-negative integer" } { "c-type" "a C type" } { "array" byte-array } }
22 { $description "Creates a byte array large enough to hold " { $snippet "n" } " values of a C type." }
23 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." }
24 { $errors "Throws an error if the type does not exist, the necessary specialized array vocabulary is not loaded, or the requested size is negative." }
27 "USING: alien.c-types alien.data prettyprint ;"
28 "10 void* <c-array> ."
29 "void*-array{ f f f f f f f f f f }"
34 { $description "Literal syntax, consists of a C-type followed by a series of values terminated by " { $snippet "}" } }
35 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." }
36 { $errors "Throws an error if the type does not exist, the necessary specialized array vocabulary is not loaded, or the requested size is negative." } ;
38 HELP: memory>byte-array
39 { $values { "alien" c-ptr } { "len" "a non-negative integer" } { "byte-array" byte-array } }
40 { $description "Reads " { $snippet "len" } " bytes starting from " { $snippet "base" } " and stores them in a new byte array." } ;
43 { $values { "byte-array" byte-array } { "c-type" "a C type" } { "array" "a specialized array" } }
44 { $description "Converts a " { $link byte-array } " into a specialized array by interpreting the bytes in it as machine-specific values. Code using this word is unportable." }
45 { $notes "The appropriate specialized array vocabulary must be loaded, otherwise an error will be thrown. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." }
46 { $errors "Throws an error if the type does not exist, the necessary specialized array vocabulary is not loaded, or the requested size is negative." } ;
49 { $values { "n" "a non-negative integer" } { "c-type" "a C type" } { "array" "a specialized array" } }
50 { $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> } "." }
51 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." }
52 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
53 { $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." } ;
55 HELP: malloc-byte-array
56 { $values { "byte-array" byte-array } { "alien" alien } }
57 { $description "Allocates an unmanaged memory block of the same size as the byte array, and copies the contents of the byte array there." }
58 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
59 { $errors "Throws an error if memory allocation fails." } ;
61 { <c-array> <c-direct-array> malloc-array } related-words
63 { string>alien alien>string malloc-string } related-words
65 HELP: with-scoped-allocation
66 { $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } }
67 { $description "Allocates values on the call stack, calls the quotation, then deallocates the values as soon as the quotation returns."
69 "A scoped allocation specifier is either:"
72 { "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." }
74 "If no initial value is specified, the contents of the allocated memory are undefined." }
75 { $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." }
78 "USING: accessors alien.c-types alien.data
79 classes.struct kernel math math.functions
83 STRUCT: test-point { x int } { y int } ;
85 : scoped-allocation-test ( -- x )
88 [ x>> sq ] [ y>> sq ] bi + sqrt
89 ] with-scoped-allocation ;
91 scoped-allocation-test ."
96 HELP: with-out-parameters
97 { $values { "c-types" "a list of scoped allocation specifiers" } { "quot" quotation } { "values..." "zero or more values" } }
98 { $description "Allocates values on the call stack, calls the quotation, then copies all stack allocated values to the data heap after the quotation returns."
100 "A scoped allocation specifier is either:"
103 { "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." }
105 "If no initial value is specified, the contents of the allocated memory are undefined." }
106 { $warning "Reading or writing a scoped allocation buffer outside of the given quotation will cause memory corruption." } ;
108 ARTICLE: "malloc" "Manual memory management"
109 "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."
111 "Allocating a C datum with a fixed address:"
115 "The " { $vocab-link "libc" } " vocabulary defines several words which directly call C standard library memory management functions:"
121 "You must always free pointers returned by any of the above words when the block of memory is no longer in use:"
122 { $subsections free }
123 "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:"
124 { $subsections (free) }
125 "Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
130 "The " { $link &free } " and " { $link |free } " words are generated using " { $link "alien.destructors" } "."
132 "You can unsafely copy a range of bytes from one memory location to another:"
133 { $subsections memcpy }
134 "You can copy a range of bytes from memory into a byte array:"
135 { $subsections memory>byte-array } ;
137 ARTICLE: "c-pointers" "Passing pointers to C functions"
138 "The following Factor objects may be passed to C function parameters with pointer types:"
140 { "Instances of " { $link alien } "." }
141 { "Instances of " { $link f } "; this is interpreted as a null pointer." }
142 { "Instances of " { $link byte-array } "; the C function receives a pointer to the first element of the array." }
143 { "Any data type which defines a method on " { $link >c-ptr } ". This includes " { $link "classes.struct" } " and " { $link "specialized-arrays" } "." }
145 "The class of primitive C pointer types:"
146 { $subsections c-ptr }
147 "A generic word for converting any object to a C pointer; user-defined types may add methods to this generic word:"
148 { $subsections >c-ptr }
149 "More about the " { $link alien } " type:"
150 { $subsections "aliens" }
152 "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" } "." } ;
154 ARTICLE: "c-boxes" "C value boxes"
155 "Sometimes it is useful to create a byte array storing a single C value, like a struct with a single field. A pair of utility words exist to make this more convenient:"
156 { $subsections <ref> deref }
157 "These words can be used to in conjunction with, or instead of, " { $link with-out-parameters } " to handle \"out-parameters\". For example, if a function is declared in the following way:"
159 "FUNCTION: int do_foo ( int* a )"
161 "and writes to the pointer 'a', then it can be called like this:"
163 "1234 int <ref> [ do_foo ] keep int deref"
165 "The stack will then contain the two integers emitted by the 'do_foo' function." ;
167 ARTICLE: "c-data" "Passing data between Factor and C"
168 "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."
170 "Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
179 "Important guidelines for passing data in byte arrays:"
180 { $subsections "byte-arrays-gc" }
181 "C-style enumerated types are supported:"
182 { $subsections "alien.enums" }
183 "A utility for defining " { $link "destructors" } " for deallocating memory:"
184 { $subsections "alien.destructors" }
185 "C struct and union types can be defined with " { $link POSTPONE: STRUCT: } " and " { $link POSTPONE: UNION-STRUCT: } ". See " { $link "classes.struct" } " for details. For passing arrays to and from C, use the " { $link "specialized-arrays" } " vocabulary." ;
188 { $values { "string" string } { "encoding" "an encoding descriptor" } { "alien" c-ptr } }
189 { $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." }
190 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
191 { $errors "Throws an error if one of the following conditions occurs:"
193 "the string contains null code points"
194 "the string contains characters not representable using the encoding specified"
195 "memory allocation fails"
199 HELP: <c-direct-array>
200 { $values { "alien" c-ptr } { "len" integer } { "c-type" "a C type" } { "array" "a specialized direct array" } }
201 { $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" } "." }
202 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, an error will be thrown. See the " { $vocab-link "specialized-arrays" } " vocabulary for details on the underlying sequence type constructed." } ;
204 ARTICLE: "c-strings" "C strings"
205 "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."
207 "Using C string types triggers automatic conversions:"
210 "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 encoded to the requested encoding and a raw pointer is passed to the function. "
211 "Passing an already encoded " { $link byte-array } " also works and performs no conversion."
213 { "Returning a C string from a C function allocates a Factor string in the Factor heap; the memory pointed to by the returned pointer is then decoded with the requested encoding into the Factor string." }
214 { "Reading " { $link c-string } " slots of " { $link POSTPONE: STRUCT: } " or " { $link POSTPONE: UNION-STRUCT: } " returns Factor strings." }
217 "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."
219 "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:"
224 "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."
226 "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."
228 "A word to read strings from arbitrary addresses:"
229 { $subsections alien>string }
230 "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." ;
233 { $values { "value" object } { "c-type" "a C type" } { "c-ptr" c-ptr } }
234 { $description "Creates a new byte array to store a Factor object as a C value." }
236 { $example "USING: alien.c-types alien.data prettyprint sequences ;" "123 int <ref> length ." "4" }
240 { $values { "c-ptr" c-ptr } { "c-type" "a C type" } { "value" object } }
241 { $description "Loads a C value from a byte array." }
244 "USING: alien.c-types alien.data prettyprint sequences ;"
245 "321 int <ref> int deref ."
249 ARTICLE: "c-out-params" "Output parameters in C"
250 "A frequently-occurring idiom in C code is the \"out parameter\". If a C function returns more than one value, the caller passes pointers of the correct type, and the C function writes its return values to those locations."
251 { $subsection with-out-parameters }
252 "The idiom is commonly used for passing back an error message if the function calls fails. For example, if a function is declared in the following way:"
254 "FUNCTION: int do_frob ( int arg1, char** errptr )"
256 "Then it could return 1 on error and 0 otherwise. A correct way to call it would be:"
258 "1234 { c-string } [ do_frob ] with-out-parameters"
260 "which would put the function's return value and error string on the stack." ;