1 USING: alien alien.complex help.syntax help.markup libc kernel.private
2 byte-arrays strings hashtables alien.syntax alien.strings sequences
3 io.encodings.string debugger destructors vocabs.loader
9 { $values { "seq" "A byte array or float array" } { "n" "a non-negative integer" } }
10 { $contract "Outputs the size of the byte array, struct, or specialized array data in bytes." } ;
13 { $values { "name" "a C type name" } { "size" math:integer } }
14 { $description "Outputs the number of bytes needed for a heap-allocated value of this C type." }
16 { $example "USING: alien alien.c-types prettyprint ;\nint heap-size ." "4" }
18 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
21 { $values { "name" "a C type name" } { "size" math:integer } }
22 { $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." }
23 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
26 { $values { "c-type" c-type } }
27 { $description "Creates a prototypical C type. User code should use higher-level facilities to define C types; see " { $link "c-data" } "." } ;
30 { $values { "name" "a C type name" } }
31 { $description "Throws a " { $link no-c-type } " error." }
32 { $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 { $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." } ;
38 { $values { "name" "a C type" } { "c-type" c-type } }
39 { $description "Looks up a C type by name." }
40 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
43 { $values { "name" "a C type" } { "quot" { $quotation "( c-ptr n -- obj )" } } }
44 { $description "Outputs a quotation which reads values of this C type from a C structure." }
45 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
48 { $values { "name" "a C type" } { "quot" { $quotation "( obj c-ptr n -- )" } } }
49 { $description "Outputs a quotation which writes values of this C type to a C structure." }
50 { $errors "Throws an error if the type does not exist." } ;
53 { $values { "n" math:integer } { "c-type" "a C type" } }
54 { $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." }
55 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
58 { $values { "c-type" "a C type" } }
59 { $description "Generates code for converting a C value stored in return registers into a Factor object to be pushed on the data stack." }
60 { $notes "This is an internal word used by the compiler when compiling alien calls." } ;
63 { $values { "c-type" "a C type" } }
64 { $description "Generates code for converting a Factor value on the data stack into a C value to be stored in the return registers." }
65 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
68 { $values { "name" "a word name" } }
69 { $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." }
70 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
73 { $values { "name" "a word name" } }
74 { $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." }
75 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
78 { $description "This C type represents a one-byte signed integer type. Input values will be converted to " { $link math:integer } "s and truncated to eight bits; output values will be returned as " { $link math:fixnum } "s." } ;
80 { $description "This C type represents a one-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to eight bits; output values will be returned as " { $link math:fixnum } "s." } ;
82 { $description "This C type represents a two-byte signed integer type. Input values will be converted to " { $link math:integer } "s and truncated to sixteen bits; output values will be returned as " { $link math:fixnum } "s." } ;
84 { $description "This C type represents a two-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to sixteen bits; output values will be returned as " { $link math:fixnum } "s." } ;
86 { $description "This C type represents a four-byte signed integer type. Input values will be converted to " { $link math:integer } "s and truncated to 32 bits; output values will be returned as " { $link math:integer } "s." } ;
88 { $description "This C type represents a four-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to 32 bits; output values will be returned as " { $link math:integer } "s." } ;
90 { $description "This C type represents a four- or eight-byte signed integer type. On Windows and on 32-bit Unix platforms, it will be four bytes. On 64-bit Unix platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
92 { $description "This C type represents a four- or eight-byte unsigned integer type. On Windows and on 32-bit Unix platforms, it will be four bytes. On 64-bit Unix platforms, it will be eight bytes. Input values will be converted to " { $link math:integer } "s and truncated to 32 or 64 bits; output values will be returned as " { $link math:integer } "s." } ;
94 { $description "This C type represents an eight-byte signed integer type. Input values will be converted to " { $link math:integer } "s and truncated to 64 bits; output values will be returned as " { $link math:integer } "s." } ;
96 { $description "This C type represents an eight-byte unsigned integer type. Input values will be converted to " { $link math:integer } "s and truncated to 64 bits; output values will be returned as " { $link math:integer } "s." } ;
98 { $description "This symbol is not a valid C type, but it can be used as the return type for a " { $link POSTPONE: FUNCTION: } " or " { $link POSTPONE: CALLBACK: } " definition, or an " { $link alien-invoke } " or " { $link alien-callback } " call." } ;
100 { $description "This C type represents a pointer to C memory. " { $link byte-array } " and " { $link alien } " values can be passed as inputs, but see " { $link "byte-arrays-gc" } " for notes about passing byte arrays into C functions. Output values are returned as " { $link alien } "s." } ;
102 { $description "This C type represents a pointer to a C string. See " { $link "c-strings" } " for details about using strings with the FFI." } ;
104 { $description "This C type represents a single-precision IEEE 754 floating-point type. Input values will be converted to Factor " { $link math:float } "s and demoted to single-precision; output values will be returned as Factor " { $link math:float } "s." } ;
106 { $description "This C type represents a double-precision IEEE 754 floating-point type. Input values will be converted to Factor " { $link math:float } "s; output values will be returned as Factor " { $link math:float } "s." } ;
108 { $description "This C type represents a single-precision IEEE 754 floating-point complex type. Input values will be converted from Factor " { $link math:complex } " objects into a single-precision complex float type; output values will be returned as Factor " { $link math:complex } " objects." } ;
110 { $description "This C type represents a double-precision IEEE 754 floating-point complex type. Input values will be converted from Factor " { $link math:complex } " objects into a double-precision complex float type; output values will be returned as Factor " { $link math:complex } " objects." } ;
113 ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
114 "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."
116 "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:"
118 "the C function returns"
119 "the C function calls Factor code via a callback"
121 "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."
123 "If this condition is not satisfied, " { $link "malloc" } " must be used instead."
124 { $warning "Failure to comply with these requirements can lead to crashes, data corruption, and security exploits." } ;
126 ARTICLE: "c-out-params" "Output parameters in C"
127 "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."
129 "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:"
130 { $subsection <char> }
131 { $subsection <uchar> }
132 { $subsection <short> }
133 { $subsection <ushort> }
134 { $subsection <int> }
135 { $subsection <uint> }
136 { $subsection <long> }
137 { $subsection <ulong> }
138 { $subsection <longlong> }
139 { $subsection <ulonglong> }
140 { $subsection <float> }
141 { $subsection <double> }
142 { $subsection <void*> }
143 "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:"
144 { $subsection *char }
145 { $subsection *uchar }
146 { $subsection *short }
147 { $subsection *ushort }
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 "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." ;
159 ARTICLE: "c-types-specs" "C type specifiers"
160 "C types are identified by special words, and type names occur as parameters to the " { $link alien-invoke } ", " { $link alien-indirect } " and " { $link alien-callback } " words. New C types can be defined by the words " { $link POSTPONE: STRUCT: } ", " { $link POSTPONE: UNION-STRUCT: } ", " { $link POSTPONE: CALLBACK: } ", and " { $link POSTPONE: TYPEDEF: } "."
162 "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:"
165 { { $link char } "always 1 byte" }
166 { { $link uchar } { } }
167 { { $link short } "always 2 bytes" }
168 { { $link ushort } { } }
169 { { $link int } "always 4 bytes" }
170 { { $link uint } { } }
171 { { $link long } { "same size as CPU word size and " { $link void* } ", except on 64-bit Windows, where it is 4 bytes" } }
172 { { $link ulong } { } }
173 { { $link longlong } "always 8 bytes" }
174 { { $link ulonglong } { } }
175 { { $link float } { "single-precision float (not the same as Factor's " { $link math:float } " class!)" } }
176 { { $link double } { "double-precision float (the same format as Factor's " { $link math:float } " objects)" } }
177 { { $link complex-float } { "C99 or Fortran " { $snippet "complex float" } " type, converted to and from Factor " { $link math:complex } " values" } }
178 { { $link complex-double } { "C99 or Fortran " { $snippet "complex double" } " type, converted to and from Factor " { $link math:complex } " values" } }
180 "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."
182 "Pointer types are specified by suffixing a C type with " { $snippet "*" } ", for example " { $snippet "float*" } ". One special case is " { $link void* } ", which denotes a generic pointer; " { $link 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."
184 "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:"
185 { $code "int[3][4]" }
186 "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."
188 "Structure and union types are specified by the name of the structure or union." ;