2 USING: alien help.syntax help.markup libc kernel.private
3 byte-arrays math strings hashtables alien.syntax alien.strings sequences
4 io.encodings.string debugger destructors vocabs.loader ;
7 { $values { "type" hashtable } }
8 { $description "Creates a prototypical C type. User code should use higher-level facilities to define C types; see " { $link "c-data" } "." } ;
11 { $values { "type" string } }
12 { $description "Throws a " { $link no-c-type } " error." }
13 { $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." } ;
16 { $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." } ;
19 { $values { "name" string } { "type" hashtable } }
20 { $description "Looks up a C type by name." }
21 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
24 { $values { "type" string } { "size" integer } }
25 { $description "Outputs the number of bytes needed for a heap-allocated value of this C type." }
27 "On a 32-bit system, you will get the following output:"
28 { $unchecked-example "USE: alien\n\"void*\" heap-size ." "4" }
30 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
33 { $values { "type" string } { "size" integer } }
34 { $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." }
35 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
38 { $values { "seq" "A byte array or float array" } { "n" "a non-negative integer" } }
39 { $contract "Outputs the size of the byte array or float array data in bytes as presented to the C library interface." } ;
42 { $values { "name" string } { "quot" { $quotation "( c-ptr n -- obj )" } } }
43 { $description "Outputs a quotation which reads values of this C type from a C structure." }
44 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
47 { $values { "name" string } { "quot" { $quotation "( obj c-ptr n -- )" } } }
48 { $description "Outputs a quotation which writes values of this C type to a C structure." }
49 { $errors "Throws an error if the type does not exist." } ;
52 { $values { "len" "a non-negative integer" } { "c-type" "a C type" } { "array" byte-array } }
53 { $description "Creates a byte array large enough to hold " { $snippet "n" } " values of a C type." }
54 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, a " { $link specialized-array-vocab-not-loaded } " error will be thrown. The vocabulary can be loaded with a " { $link POSTPONE: USING: } " form as usual, or with the " { $link require-c-array } " word. See the " { $vocab-link "specialized-arrays" } " vocabulary set for details on the underlying sequence type constructed." }
55 { $errors "Throws an error if the type does not exist, the necessary specialized array vocabulary is not loaded, or the requested size is negative." } ;
58 { $values { "type" "a C type" } { "array" byte-array } }
59 { $description "Creates a byte array suitable for holding a value with the given C type." }
60 { $errors "Throws an " { $link no-c-type } " error if the type does not exist." } ;
62 { <c-object> malloc-object } related-words
64 HELP: memory>byte-array
65 { $values { "alien" c-ptr } { "len" "a non-negative integer" } { "byte-array" byte-array } }
66 { $description "Reads " { $snippet "len" } " bytes starting from " { $snippet "base" } " and stores them in a new byte array." } ;
68 HELP: byte-array>memory
69 { $values { "byte-array" byte-array } { "base" c-ptr } }
70 { $description "Writes a byte array to memory starting from the " { $snippet "base" } " address." }
71 { $warning "This word is unsafe. Improper use can corrupt memory." } ;
74 { $values { "n" "a non-negative integer" } { "type" "a C type" } { "alien" alien } }
75 { $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> } "." }
76 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, a " { $link specialized-array-vocab-not-loaded } " error will be thrown. The vocabulary can be loaded with a " { $link POSTPONE: USING: } " form as usual, or with the " { $link require-c-array } " word. See the " { $vocab-link "specialized-arrays" } " vocabulary set for details on the underlying sequence type constructed." }
77 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
78 { $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." } ;
81 { $values { "type" "a C type" } { "alien" alien } }
82 { $description "Allocates an unmanaged memory block large enough to hold a value of a C type." }
83 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
84 { $errors "Throws an error if the type does not exist or if memory allocation fails." } ;
86 HELP: malloc-byte-array
87 { $values { "byte-array" byte-array } { "alien" alien } }
88 { $description "Allocates an unmanaged memory block of the same size as the byte array, and copies the contents of the byte array there." }
89 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
90 { $errors "Throws an error if memory allocation fails." } ;
92 { <c-array> <c-direct-array> malloc-array } related-words
95 { $values { "n" integer } { "ctype" string } }
96 { $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." }
97 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
100 { $values { "ctype" string } }
101 { $description "Generates code for converting a C value stored in return registers into a Factor object to be pushed on the data stack." }
102 { $notes "This is an internal word used by the compiler when compiling alien calls." } ;
105 { $values { "ctype" string } }
106 { $description "Generates code for converting a Factor value on the data stack into a C value to be stored in the return registers." }
107 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
110 { $values { "name" "a word name" } }
111 { $description "Defines a word " { $snippet "*name" } " with stack effect " { $snippet "( c-ptr -- value )" } " for reading a value with C type " { $snippet "name" } " stored at an alien pointer." }
112 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
115 { $values { "name" "a word name" } }
116 { $description "Defines a word " { $snippet "<" { $emphasis "name" } ">" } " with stack effect " { $snippet "( value -- array )" } ". This word allocates a byte array large enough to hold a value with C type " { $snippet "name" } ", and writes the value at the top of the stack to the array." }
117 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
119 { string>alien alien>string malloc-string } related-words
122 { $values { "string" string } { "encoding" "an encoding descriptor" } { "alien" c-ptr } }
123 { $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." }
124 { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." }
125 { $errors "Throws an error if one of the following conditions occurs:"
127 "the string contains null code points"
128 "the string contains characters not representable using the encoding specified"
129 "memory allocation fails"
133 HELP: require-c-array
134 { $values { "c-type" "a C type" } }
135 { $description { $link require } "s any unloaded vocabularies needed to construct a specialized array of " { $snippet "c-type" } " using the " { $link <c-array> } " or " { $link <c-direct-array> } " vocabularies." }
136 { $notes "This word must be called inside a compilation unit. See the " { $vocab-link "specialized-arrays" } " vocabulary set for details on the underlying sequence types loaded." } ;
138 HELP: <c-direct-array>
139 { $values { "alien" c-ptr } { "len" integer } { "c-type" "a C type" } { "array" "a specialized direct array" } }
140 { $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" } "." }
141 { $notes "The appropriate specialized array vocabulary must be loaded; otherwise, a " { $link specialized-array-vocab-not-loaded } " error will be thrown. The vocabulary can be loaded with a " { $link POSTPONE: USING: } " form as usual, or with the " { $link require-c-array } " word. See the " { $vocab-link "specialized-arrays" } " vocabulary set for details on the underlying sequence type constructed." } ;
143 ARTICLE: "c-strings" "C strings"
144 "C string types are arrays with shape " { $snippet "{ \"char*\" encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $snippet "\"char*\"" } " is an alias for " { $snippet "{ \"char*\" utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors."
146 "Passing a Factor string to a C function expecting a 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."
148 "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."
150 "Care must be taken if the C function expects a " { $snippet "char*" } " with a length in bytes, rather than a null-terminated " { $snippet "char*" } "; 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."
152 "Sometimes a C function has a parameter type of " { $snippet "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:"
153 { $subsection string>alien }
154 { $subsection malloc-string }
155 "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."
157 "A word to read strings from arbitrary addresses:"
158 { $subsection alien>string }
159 "For example, if a C function returns a " { $snippet "char*" } " but stipulates that the caller must deallocate the memory afterward, you must define the function as returning " { $snippet "void*" } ", and call one of the above words before passing the pointer to " { $link free } "." ;
161 ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
162 "The Factor garbage collector can move byte arrays around, and it is only safe to pass byte arrays to C functions if the garbage collector will not run while C code still has a reference to the data."
164 "In particular, a byte array can only be passed as a parameter if the the C function does not use the parameter after one of the following occurs:"
166 "the C function returns"
167 "the C function calls Factor code via a callback"
169 "Returning from C to Factor, as well as invoking Factor code via a callback, may trigger garbage collection, and if the function had stored a pointer to the byte array somewhere, this pointer may cease to be valid."
171 "If this condition is not satisfied, " { $link "malloc" } " must be used instead."
172 { $warning "Failure to comply with these requirements can lead to crashes, data corruption, and security exploits." } ;
174 ARTICLE: "c-out-params" "Output parameters in C"
175 "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."
177 "Each numerical C type, together with " { $snippet "void*" } ", has an associated " { $emphasis "out parameter constructor" } " word which takes a Factor object as input, constructs a byte array of the correct size, and converts the Factor object to a C value stored into the byte array:"
178 { $subsection <char> }
179 { $subsection <uchar> }
180 { $subsection <short> }
181 { $subsection <ushort> }
182 { $subsection <int> }
183 { $subsection <uint> }
184 { $subsection <long> }
185 { $subsection <ulong> }
186 { $subsection <longlong> }
187 { $subsection <ulonglong> }
188 { $subsection <float> }
189 { $subsection <double> }
190 { $subsection <void*> }
191 "You call the out parameter constructor with the required initial value, then pass the byte array to the C function, which receives a pointer to the start of the byte array's data area. The C function then returns, leaving the result in the byte array; you read it back using the next set of words:"
192 { $subsection *char }
193 { $subsection *uchar }
194 { $subsection *short }
195 { $subsection *ushort }
197 { $subsection *uint }
198 { $subsection *long }
199 { $subsection *ulong }
200 { $subsection *longlong }
201 { $subsection *ulonglong }
202 { $subsection *float }
203 { $subsection *double }
204 { $subsection *void* }
205 "Note that while structure and union types do not get these words defined for them, there is no loss of generality since " { $link <void*> } " and " { $link *void* } " may be used." ;
207 ARTICLE: "c-types-specs" "C type specifiers"
208 "C types are identified by strings, and type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words, as well as " { $link POSTPONE: C-STRUCT: } ", " { $link POSTPONE: C-UNION: } " and " { $link POSTPONE: TYPEDEF: } "."
210 "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:"
213 { { $snippet "char" } "always 1 byte" }
214 { { $snippet "uchar" } { } }
215 { { $snippet "short" } "always 2 bytes" }
216 { { $snippet "ushort" } { } }
217 { { $snippet "int" } "always 4 bytes" }
218 { { $snippet "uint" } { } }
219 { { $snippet "long" } { "same size as CPU word size and " { $snippet "void*" } ", except on 64-bit Windows, where it is 4 bytes" } }
220 { { $snippet "ulong" } { } }
221 { { $snippet "longlong" } "always 8 bytes" }
222 { { $snippet "ulonglong" } { } }
223 { { $snippet "float" } { } }
224 { { $snippet "double" } { "same format as " { $link float } " objects" } }
225 { { $snippet "complex-float" } { "C99 " { $snippet "complex float" } " type, converted to and from " { $link complex } " values" } }
226 { { $snippet "complex-double" } { "C99 " { $snippet "complex double" } " type, converted to and from " { $link complex } " values" } }
228 "When making alien calls, Factor numbers are converted to and from the above types in a canonical way. Converting a Factor number to a C value may result in a loss of precision."
230 "Pointer types are specified by suffixing a C type with " { $snippet "*" } ", for example " { $snippet "float*" } ". One special case is " { $snippet "void*" } ", which denotes a generic pointer; " { $snippet "void" } " by itself is not a valid C type specifier. With the exception of strings (see " { $link "c-strings" } "), all pointer types are identical to " { $snippet "void*" } " as far as the C library interface is concerned."
232 "Fixed-size array types are supported; the syntax consists of a C type name followed by dimension sizes in brackets; the following denotes a 3 by 4 array of integers:"
233 { $code "int[3][4]" }
234 "Fixed-size arrays differ from pointers in that they are allocated inside structures and unions; however when used as function parameters they behave exactly like pointers and thus the dimensions only serve as documentation."
236 "Structure and union types are specified by the name of the structure or union." ;
238 ARTICLE: "c-byte-arrays" "Passing data in byte arrays"
239 "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."
241 "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:"
242 { $subsection <c-object> }
243 { $subsection <c-array> }
245 "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" } "." }
246 { $see-also "c-arrays" } ;
248 ARTICLE: "malloc" "Manual memory management"
249 "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."
251 "Allocating a C datum with a fixed address:"
252 { $subsection malloc-object }
253 { $subsection malloc-array }
254 { $subsection malloc-byte-array }
255 "There is a set of words in the " { $vocab-link "libc" } " vocabulary which directly call C standard library memory management functions:"
256 { $subsection malloc }
257 { $subsection calloc }
258 { $subsection realloc }
259 "You must always free pointers returned by any of the above words when the block of memory is no longer in use:"
261 "Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
262 { $subsection &free }
263 { $subsection |free }
264 "The " { $link &free } " and " { $link |free } " words are generated using " { $link "alien.destructors" } "."
266 "You can unsafely copy a range of bytes from one memory location to another:"
267 { $subsection memcpy }
268 "You can copy a range of bytes from memory into a byte array:"
269 { $subsection memory>byte-array }
270 "You can copy a byte array to memory unsafely:"
271 { $subsection byte-array>memory } ;
273 ARTICLE: "c-data" "Passing data between Factor and C"
274 "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."
276 "Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
277 { $subsection "c-types-specs" }
278 { $subsection "c-byte-arrays" }
279 { $subsection "malloc" }
280 { $subsection "c-strings" }
281 { $subsection "c-arrays" }
282 { $subsection "c-out-params" }
283 "Important guidelines for passing data in byte arrays:"
284 { $subsection "byte-arrays-gc" }
285 "C-style enumerated types are supported:"
286 { $subsection POSTPONE: C-ENUM: }
287 "C types can be aliased for convenience and consitency with native library documentation:"
288 { $subsection POSTPONE: TYPEDEF: }
289 "New C types can be defined:"
290 { $subsection "c-structs" }
291 { $subsection "c-unions" }
292 "A utility for defining " { $link "destructors" } " for deallocating memory:"
293 { $subsection "alien.destructors" }
294 { $see-also "aliens" } ;