2 USING: alien help.syntax help.markup libc kernel.private
3 byte-arrays math strings hashtables alien.syntax
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" "a quotation with stack effect " { $snippet "( 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" "a quotation with stack effect " { $snippet "( 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 { "n" "a non-negative integer" } { "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 { $errors "Throws an error if the type does not exist or the requested size is negative." } ;
56 { <c-array> malloc-array } related-words
59 { $values { "type" "a C type" } { "array" byte-array } }
60 { $description "Creates a byte array suitable for holding a value with the given C type." }
61 { $errors "Throws an " { $link no-c-type } " error if the type does not exist." } ;
63 { <c-object> malloc-object } related-words
65 HELP: memory>byte-array
66 { $values { "alien" c-ptr } { "len" "a non-negative integer" } { "byte-array" byte-array } }
67 { $description "Reads " { $snippet "len" } " bytes starting from " { $snippet "base" } " and stores them in a new byte array." } ;
69 HELP: byte-array>memory
70 { $values { "byte-array" byte-array } { "base" c-ptr } }
71 { $description "Writes a byte array to memory starting from the " { $snippet "base" } " address." }
72 { $warning "This word is unsafe. Improper use can corrupt memory." } ;
75 { $values { "n" "a non-negative integer" } { "type" "a C type" } { "alien" alien } }
76 { $description "Allocates an unmanaged memory block large enough to hold " { $snippet "n" } " values of a C type." }
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, 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." } ;
93 { $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
94 { $description "Defines a word " { $snippet { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( n c-ptr -- value )" } " for reading the value with C type " { $snippet "name" } " stored at an alien pointer, displaced by a multiple of the C type's size." }
95 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
98 { $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
99 { $description "Defines a word " { $snippet "set-" { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( value n c-ptr -- )" } " for writing the value with C type " { $snippet "name" } " to an alien pointer, displaced by a multiple of the C type's size." }
100 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
103 { $values { "n" integer } { "ctype" string } }
104 { $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." }
105 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
108 { $values { "ctype" string } }
109 { $description "Generates code for converting a C value stored in return registers into a Factor object to be pushed on the data stack." }
110 { $notes "This is an internal word used by the compiler when compiling alien calls." } ;
113 { $values { "ctype" string } }
114 { $description "Generates code for converting a Factor value on the data stack into a C value to be stored in the return registers." }
115 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
118 { $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
119 { $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." }
120 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
123 { $values { "name" "a word name" } { "vocab" "a vocabulary name" } }
124 { $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." }
125 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
127 ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
128 "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."
130 "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:"
132 "the C function returns"
133 "the C function calls Factor code via a callback"
135 "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."
137 "If this condition is not satisfied, " { $link "malloc" } " must be used instead."
138 { $warning "Failure to comply with these requirements can lead to crashes, data corruption, and security exploits." } ;
140 ARTICLE: "c-out-params" "Output parameters in C"
141 "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."
143 "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:"
144 { $subsection <char> }
145 { $subsection <uchar> }
146 { $subsection <short> }
147 { $subsection <ushort> }
148 { $subsection <int> }
149 { $subsection <uint> }
150 { $subsection <long> }
151 { $subsection <ulong> }
152 { $subsection <longlong> }
153 { $subsection <ulonglong> }
154 { $subsection <float> }
155 { $subsection <double> }
156 { $subsection <void*> }
157 "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:"
158 { $subsection *char }
159 { $subsection *uchar }
160 { $subsection *short }
161 { $subsection *ushort }
163 { $subsection *uint }
164 { $subsection *long }
165 { $subsection *ulong }
166 { $subsection *longlong }
167 { $subsection *ulonglong }
168 { $subsection *float }
169 { $subsection *double }
170 { $subsection *void* }
171 "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." ;
173 ARTICLE: "c-types-specs" "C type specifiers"
174 "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: } "."
176 "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:"
179 { { $snippet "char" } "always 1 byte" }
180 { { $snippet "uchar" } { } }
181 { { $snippet "short" } "always 2 bytes" }
182 { { $snippet "ushort" } { } }
183 { { $snippet "int" } "always 4 bytes" }
184 { { $snippet "uint" } { } }
185 { { $snippet "long" } { "same size as CPU word size and " { $snippet "void*" } ", except on 64-bit Windows, where it is 4 bytes" } }
186 { { $snippet "ulong" } { } }
187 { { $snippet "longlong" } "always 8 bytes" }
188 { { $snippet "ulonglong" } { } }
189 { { $snippet "float" } { } }
190 { { $snippet "double" } { "same format as " { $link float } " objects" } }
192 "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."
194 "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."
196 "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:"
197 { $code "int[3][4]" }
198 "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."
200 "Structure and union types are specified by the name of the structure or union." ;
202 ARTICLE: "c-byte-arrays" "Passing data in byte arrays"
203 "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."
205 "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:"
206 { $subsection <c-object> }
207 { $subsection <c-array> }
209 "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" } "." }
210 { $see-also "c-arrays" } ;
212 ARTICLE: "malloc" "Manual memory management"
213 "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."
215 "Allocating a C datum with a fixed address:"
216 { $subsection malloc-object }
217 { $subsection malloc-array }
218 { $subsection malloc-byte-array }
219 "There is a set of words in the " { $vocab-link "libc" } " vocabulary which directly call C standard library memory management functions:"
220 { $subsection malloc }
221 { $subsection calloc }
222 { $subsection realloc }
223 "You must always free pointers returned by any of the above words when the block of memory is no longer in use:"
225 "Utilities for automatically freeing memory in conjunction with " { $link with-destructors } ":"
226 { $subsection &free }
227 { $subsection |free }
228 "You can unsafely copy a range of bytes from one memory location to another:"
229 { $subsection memcpy }
230 "You can copy a range of bytes from memory into a byte array:"
231 { $subsection memory>byte-array }
232 "You can copy a byte array to memory unsafely:"
233 { $subsection byte-array>memory }
234 "A wrapper for temporarily allocating a block of memory:"
235 { $subsection with-malloc } ;
237 ARTICLE: "c-data" "Passing data between Factor and C"
238 "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."
240 "Furthermore, Factor's garbage collector can move objects in memory; for a discussion of the consequences, see " { $link "byte-arrays-gc" } "."
241 { $subsection "c-types-specs" }
242 { $subsection "c-byte-arrays" }
243 { $subsection "malloc" }
244 { $subsection "c-strings" }
245 { $subsection "c-arrays" }
246 { $subsection "c-out-params" }
247 "Important guidelines for passing data in byte arrays:"
248 { $subsection "byte-arrays-gc" }
249 "C-style enumerated types are supported:"
250 { $subsection POSTPONE: C-ENUM: }
251 "C types can be aliased for convenience and consitency with native library documentation:"
252 { $subsection POSTPONE: TYPEDEF: }
253 "New C types can be defined:"
254 { $subsection "c-structs" }
255 { $subsection "c-unions" }
256 { $see-also "aliens" } ;