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 { "type" string } { "size" math:integer } }
14 { $description "Outputs the number of bytes needed for a heap-allocated value of this C type." }
16 "On a 32-bit system, you will get the following output:"
17 { $unchecked-example "USE: alien\n\"void*\" heap-size ." "4" }
19 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
22 { $values { "type" string } { "size" math:integer } }
23 { $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." }
24 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
27 { $values { "type" hashtable } }
28 { $description "Creates a prototypical C type. User code should use higher-level facilities to define C types; see " { $link "c-data" } "." } ;
31 { $values { "type" string } }
32 { $description "Throws a " { $link no-c-type } " error." }
33 { $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." } ;
36 { $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." } ;
39 { $values { "name" string } { "type" hashtable } }
40 { $description "Looks up a C type by name." }
41 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
44 { $values { "name" string } { "quot" { $quotation "( c-ptr n -- obj )" } } }
45 { $description "Outputs a quotation which reads values of this C type from a C structure." }
46 { $errors "Throws a " { $link no-c-type } " error if the type does not exist." } ;
49 { $values { "name" string } { "quot" { $quotation "( obj c-ptr n -- )" } } }
50 { $description "Outputs a quotation which writes values of this C type to a C structure." }
51 { $errors "Throws an error if the type does not exist." } ;
54 { $values { "n" math:integer } { "ctype" string } }
55 { $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." }
56 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
59 { $values { "ctype" string } }
60 { $description "Generates code for converting a C value stored in return registers into a Factor object to be pushed on the data stack." }
61 { $notes "This is an internal word used by the compiler when compiling alien calls." } ;
64 { $values { "ctype" string } }
65 { $description "Generates code for converting a Factor value on the data stack into a C value to be stored in the return registers." }
66 { $notes "This is an internal word used by the compiler when compiling callbacks." } ;
69 { $values { "name" "a word name" } }
70 { $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." }
71 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
74 { $values { "name" "a word name" } }
75 { $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." }
76 { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ;
78 ARTICLE: "byte-arrays-gc" "Byte arrays and the garbage collector"
79 "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."
81 "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:"
83 "the C function returns"
84 "the C function calls Factor code via a callback"
86 "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."
88 "If this condition is not satisfied, " { $link "malloc" } " must be used instead."
89 { $warning "Failure to comply with these requirements can lead to crashes, data corruption, and security exploits." } ;
91 ARTICLE: "c-out-params" "Output parameters in C"
92 "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."
94 "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:"
95 { $subsection <char> }
96 { $subsection <uchar> }
97 { $subsection <short> }
98 { $subsection <ushort> }
100 { $subsection <uint> }
101 { $subsection <long> }
102 { $subsection <ulong> }
103 { $subsection <longlong> }
104 { $subsection <ulonglong> }
105 { $subsection <float> }
106 { $subsection <double> }
107 { $subsection <void*> }
108 "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:"
109 { $subsection *char }
110 { $subsection *uchar }
111 { $subsection *short }
112 { $subsection *ushort }
114 { $subsection *uint }
115 { $subsection *long }
116 { $subsection *ulong }
117 { $subsection *longlong }
118 { $subsection *ulonglong }
119 { $subsection *float }
120 { $subsection *double }
121 { $subsection *void* }
122 "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." ;
124 ARTICLE: "c-types-specs" "C type specifiers"
125 "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: } "."
127 "The following numerical types are available; a " { $snippet "u" } " prefix denotes an unsigned type:"
130 { { $link char } "always 1 byte" }
131 { { $link uchar } { } }
132 { { $link short } "always 2 bytes" }
133 { { $link ushort } { } }
134 { { $link int } "always 4 bytes" }
135 { { $link uint } { } }
136 { { $link long } { "same size as CPU word size and " { $link void* } ", except on 64-bit Windows, where it is 4 bytes" } }
137 { { $link ulong } { } }
138 { { $link longlong } "always 8 bytes" }
139 { { $link ulonglong } { } }
140 { { $link float } { "single-precision float (not the same as Factor's " { $link math:float } " class!)" } }
141 { { $link double } { "double-precision float (the same format as Factor's " { $link math:float } " objects)" } }
142 { { $link complex-float } { "C99 or Fortran " { $snippet "complex float" } " type, converted to and from Factor " { $link math:complex } " values" } }
143 { { $link complex-double } { "C99 or Fortran " { $snippet "complex double" } " type, converted to and from Factor " { $link math:complex } " values" } }
145 "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."
147 "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."
149 "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:"
150 { $code "int[3][4]" }
151 "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."
153 "Structure and union types are specified by the name of the structure or union." ;